Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 11 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
| 12 | 12 |
| 13 #include <string.h> | 13 #include <string.h> |
| 14 | 14 |
| 15 #include <limits> | 15 #include <limits> |
| 16 #include <memory> | 16 #include <memory> |
| 17 #include <utility> | 17 #include <utility> |
| 18 #include <vector> | 18 #include <vector> |
| 19 | 19 |
| 20 #include "webrtc/api/video/i420_buffer.h" | 20 #include "webrtc/api/video/i420_buffer.h" |
| 21 #include "webrtc/common_types.h" | 21 #include "webrtc/common_types.h" |
| 22 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" | 22 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" |
| 23 #include "webrtc/modules/video_coding/include/video_codec_initializer.h" | 23 #include "webrtc/modules/video_coding/include/video_codec_initializer.h" |
| 24 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" | 24 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" |
| 25 #include "webrtc/rtc_base/checks.h" | 25 #include "webrtc/rtc_base/checks.h" |
| 26 #include "webrtc/rtc_base/logging.h" | |
| 26 #include "webrtc/rtc_base/timeutils.h" | 27 #include "webrtc/rtc_base/timeutils.h" |
| 27 #include "webrtc/system_wrappers/include/cpu_info.h" | 28 #include "webrtc/system_wrappers/include/cpu_info.h" |
| 28 | 29 |
| 29 namespace webrtc { | 30 namespace webrtc { |
| 30 namespace test { | 31 namespace test { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 // TODO(brandtr): Update this to use the real frame rate. | 35 const int kRtpClockRateHz = 90000; |
| 35 const int k90khzTimestampFrameDiff = 3000; // Assuming 30 fps. | |
| 36 | |
| 37 // Use the frame number as the basis for timestamp to identify frames. Let the | |
| 38 // first timestamp be non-zero, to not make the IvfFileWriter believe that we | |
| 39 // want to use capture timestamps in the IVF files. | |
| 40 uint32_t FrameNumberToTimestamp(int frame_number) { | |
| 41 RTC_DCHECK_GE(frame_number, 0); | |
| 42 return (frame_number + 1) * k90khzTimestampFrameDiff; | |
| 43 } | |
| 44 | |
| 45 int TimestampToFrameNumber(uint32_t timestamp) { | |
| 46 RTC_DCHECK_GT(timestamp, 0); | |
| 47 RTC_DCHECK_EQ(timestamp % k90khzTimestampFrameDiff, 0); | |
| 48 return (timestamp / k90khzTimestampFrameDiff) - 1; | |
| 49 } | |
| 50 | 36 |
| 51 std::unique_ptr<VideoBitrateAllocator> CreateBitrateAllocator( | 37 std::unique_ptr<VideoBitrateAllocator> CreateBitrateAllocator( |
| 52 const TestConfig& config) { | 38 const TestConfig& config) { |
| 53 std::unique_ptr<TemporalLayersFactory> tl_factory; | 39 std::unique_ptr<TemporalLayersFactory> tl_factory; |
| 54 if (config.codec_settings->codecType == VideoCodecType::kVideoCodecVP8) { | 40 if (config.codec_settings->codecType == VideoCodecType::kVideoCodecVP8) { |
| 55 tl_factory.reset(new TemporalLayersFactory()); | 41 tl_factory.reset(new TemporalLayersFactory()); |
| 56 config.codec_settings->VP8()->tl_factory = tl_factory.get(); | 42 config.codec_settings->VP8()->tl_factory = tl_factory.get(); |
| 57 } | 43 } |
| 58 return std::unique_ptr<VideoBitrateAllocator>( | 44 return std::unique_ptr<VideoBitrateAllocator>( |
| 59 VideoCodecInitializer::CreateBitrateAllocator(*config.codec_settings, | 45 VideoCodecInitializer::CreateBitrateAllocator(*config.codec_settings, |
| 60 std::move(tl_factory))); | 46 std::move(tl_factory))); |
| 61 } | 47 } |
| 62 | 48 |
| 63 void PrintCodecSettings(const VideoCodec* config) { | 49 void PrintCodecSettings(const VideoCodec* codec_settings) { |
| 64 printf(" Start bitrate : %d kbps\n", config->startBitrate); | 50 RTC_DCHECK(codec_settings); |
| 65 printf(" Width : %d\n", config->width); | 51 printf(" Codec settings:\n"); |
| 66 printf(" Height : %d\n", config->height); | 52 printf(" Start bitrate : %d kbps\n", codec_settings->startBitrate); |
| 67 printf(" Codec type : %s\n", | 53 printf(" Max bitrate : %d kbps\n", codec_settings->maxBitrate); |
| 68 CodecTypeToPayloadName(config->codecType).value_or("Unknown")); | 54 printf(" Min bitrate : %d kbps\n", codec_settings->minBitrate); |
|
åsapersson
2017/08/07 08:30:10
Update plot_webrtc_test_logs.py accordingly?
brandtr
2017/08/07 09:21:45
I had misread the "codec implementation name" fiel
| |
| 69 if (config->codecType == kVideoCodecVP8) { | 55 printf(" Width : %d\n", codec_settings->width); |
| 70 printf(" Denoising : %d\n", config->VP8().denoisingOn); | 56 printf(" Height : %d\n", codec_settings->height); |
| 71 printf(" Error concealment: %d\n", config->VP8().errorConcealmentOn); | 57 printf(" Max frame rate : %d\n", codec_settings->maxFramerate); |
| 72 printf(" Frame dropping : %d\n", config->VP8().frameDroppingOn); | 58 printf(" QPmax : %d\n", codec_settings->qpMax); |
| 73 printf(" Resilience : %d\n", config->VP8().resilience); | 59 if (codec_settings->codecType == kVideoCodecVP8) { |
| 74 } else if (config->codecType == kVideoCodecVP9) { | 60 printf(" Complexity : %d\n", codec_settings->VP8().complexity); |
| 75 printf(" Denoising : %d\n", config->VP9().denoisingOn); | 61 printf(" Denoising : %d\n", codec_settings->VP8().denoisingOn); |
| 76 printf(" Frame dropping : %d\n", config->VP9().frameDroppingOn); | 62 printf(" Error concealment : %d\n", |
| 77 printf(" Resilience : %d\n", config->VP9().resilienceOn); | 63 codec_settings->VP8().errorConcealmentOn); |
| 64 printf(" Frame dropping : %d\n", codec_settings->VP8().frameDroppingOn); | |
| 65 printf(" Resilience : %d\n", codec_settings->VP8().resilience); | |
| 66 printf(" Key frame interval: %d\n", | |
| 67 codec_settings->VP8().keyFrameInterval); | |
| 68 } else if (codec_settings->codecType == kVideoCodecVP9) { | |
| 69 printf(" Complexity : %d\n", codec_settings->VP9().complexity); | |
| 70 printf(" Denoising : %d\n", codec_settings->VP9().denoisingOn); | |
| 71 printf(" Frame dropping : %d\n", codec_settings->VP9().frameDroppingOn); | |
| 72 printf(" Resilience : %d\n", codec_settings->VP9().resilienceOn); | |
| 73 printf(" Key frame interval: %d\n", | |
| 74 codec_settings->VP9().keyFrameInterval); | |
| 75 printf(" Adaptive QP mode : %d\n", codec_settings->VP9().adaptiveQpMode); | |
| 76 } else if (codec_settings->codecType == kVideoCodecH264) { | |
| 77 printf(" Frame dropping : %d\n", | |
| 78 codec_settings->H264().frameDroppingOn); | |
| 79 printf(" Key frame interval: %d\n", | |
| 80 codec_settings->H264().keyFrameInterval); | |
| 81 printf(" Profile : %d\n", codec_settings->H264().profile); | |
| 78 } | 82 } |
| 79 } | 83 } |
| 80 | 84 |
| 81 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { | 85 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { |
| 82 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; | 86 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; |
| 83 RTC_DCHECK_GE(diff_us, std::numeric_limits<int>::min()); | 87 RTC_DCHECK_GE(diff_us, std::numeric_limits<int>::min()); |
| 84 RTC_DCHECK_LE(diff_us, std::numeric_limits<int>::max()); | 88 RTC_DCHECK_LE(diff_us, std::numeric_limits<int>::max()); |
| 85 return static_cast<int>(diff_us); | 89 return static_cast<int>(diff_us); |
| 86 } | 90 } |
| 87 | 91 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 num_spatial_resizes_(0) { | 135 num_spatial_resizes_(0) { |
| 132 RTC_DCHECK(encoder); | 136 RTC_DCHECK(encoder); |
| 133 RTC_DCHECK(decoder); | 137 RTC_DCHECK(decoder); |
| 134 RTC_DCHECK(packet_manipulator); | 138 RTC_DCHECK(packet_manipulator); |
| 135 RTC_DCHECK(analysis_frame_reader); | 139 RTC_DCHECK(analysis_frame_reader); |
| 136 RTC_DCHECK(analysis_frame_writer); | 140 RTC_DCHECK(analysis_frame_writer); |
| 137 RTC_DCHECK(stats); | 141 RTC_DCHECK(stats); |
| 138 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); | 142 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); |
| 139 } | 143 } |
| 140 | 144 |
| 145 VideoProcessorImpl::~VideoProcessorImpl() { | |
| 146 encoder_->RegisterEncodeCompleteCallback(nullptr); | |
| 147 decoder_->RegisterDecodeCompleteCallback(nullptr); | |
| 148 } | |
| 149 | |
| 141 void VideoProcessorImpl::Init() { | 150 void VideoProcessorImpl::Init() { |
| 142 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; | 151 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; |
| 152 RTC_DCHECK(config_.codec_settings) << "No codec settings supplied."; | |
| 143 initialized_ = true; | 153 initialized_ = true; |
| 144 | 154 |
| 145 // Setup required callbacks for the encoder/decoder. | 155 // Setup required callbacks for the encoder and decoder. |
| 146 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), | 156 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), |
| 147 WEBRTC_VIDEO_CODEC_OK) | 157 WEBRTC_VIDEO_CODEC_OK) |
| 148 << "Failed to register encode complete callback"; | 158 << "Failed to register encode complete callback"; |
| 149 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), | 159 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), |
| 150 WEBRTC_VIDEO_CODEC_OK) | 160 WEBRTC_VIDEO_CODEC_OK) |
| 151 << "Failed to register decode complete callback"; | 161 << "Failed to register decode complete callback"; |
| 152 | 162 |
| 153 // Initialize the encoder and decoder. | 163 // Initialize the encoder and decoder. |
| 154 uint32_t num_cores = | 164 uint32_t num_cores = |
| 155 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); | 165 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); |
| 156 RTC_CHECK_EQ( | 166 RTC_CHECK_EQ( |
| 157 encoder_->InitEncode(config_.codec_settings, num_cores, | 167 encoder_->InitEncode(config_.codec_settings, num_cores, |
| 158 config_.networking_config.max_payload_size_in_bytes), | 168 config_.networking_config.max_payload_size_in_bytes), |
| 159 WEBRTC_VIDEO_CODEC_OK) | 169 WEBRTC_VIDEO_CODEC_OK) |
| 160 << "Failed to initialize VideoEncoder"; | 170 << "Failed to initialize VideoEncoder"; |
| 161 | 171 |
| 162 RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores), | 172 RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores), |
| 163 WEBRTC_VIDEO_CODEC_OK) | 173 WEBRTC_VIDEO_CODEC_OK) |
| 164 << "Failed to initialize VideoDecoder"; | 174 << "Failed to initialize VideoDecoder"; |
| 165 | 175 |
| 166 if (config_.verbose) { | 176 if (config_.verbose) { |
| 167 printf("Filename: %s\n", config_.filename.c_str()); | |
| 168 printf("Video Processor:\n"); | 177 printf("Video Processor:\n"); |
| 169 printf(" #CPU cores used : %d\n", num_cores); | 178 printf(" Filename : %s\n", config_.filename.c_str()); |
| 170 printf(" Total # of frames: %d\n", | 179 printf(" Total # of frames: %d\n", |
| 171 analysis_frame_reader_->NumberOfFrames()); | 180 analysis_frame_reader_->NumberOfFrames()); |
| 172 printf(" Codec settings:\n"); | 181 printf(" # CPU cores used : %d\n", num_cores); |
| 173 printf(" Encoder implementation name: %s\n", | 182 const char* encoder_name = encoder_->ImplementationName(); |
| 174 encoder_->ImplementationName()); | 183 printf(" Encoder implementation name: %s\n", encoder_name); |
| 175 printf(" Decoder implementation name: %s\n", | 184 const char* decoder_name = decoder_->ImplementationName(); |
| 176 decoder_->ImplementationName()); | 185 printf(" Decoder implementation name: %s\n", decoder_name); |
| 177 if (strcmp(encoder_->ImplementationName(), | 186 if (strcmp(encoder_name, decoder_name) == 0) { |
| 178 decoder_->ImplementationName()) == 0) { | 187 printf(" Codec implementation name : %s_%s\n", |
| 179 printf(" Codec implementation name: %s_%s\n", | |
| 180 CodecTypeToPayloadName(config_.codec_settings->codecType) | 188 CodecTypeToPayloadName(config_.codec_settings->codecType) |
| 181 .value_or("Unknown"), | 189 .value_or("Unknown"), |
| 182 encoder_->ImplementationName()); | 190 encoder_->ImplementationName()); |
| 183 } | 191 } |
| 184 PrintCodecSettings(config_.codec_settings); | 192 PrintCodecSettings(config_.codec_settings); |
| 193 printf("\n"); | |
| 185 } | 194 } |
| 186 } | 195 } |
| 187 | 196 |
| 188 VideoProcessorImpl::~VideoProcessorImpl() { | |
| 189 encoder_->RegisterEncodeCompleteCallback(nullptr); | |
| 190 decoder_->RegisterDecodeCompleteCallback(nullptr); | |
| 191 } | |
| 192 | |
| 193 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { | |
| 194 int set_rates_result = encoder_->SetRateAllocation( | |
| 195 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), | |
| 196 frame_rate); | |
| 197 RTC_DCHECK_GE(set_rates_result, 0) | |
| 198 << "Failed to update encoder with new rate " << bit_rate; | |
| 199 num_dropped_frames_ = 0; | |
| 200 num_spatial_resizes_ = 0; | |
| 201 } | |
| 202 | |
| 203 size_t VideoProcessorImpl::EncodedFrameSize(int frame_number) { | |
| 204 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 205 return frame_infos_[frame_number].encoded_frame_size; | |
| 206 } | |
| 207 | |
| 208 FrameType VideoProcessorImpl::EncodedFrameType(int frame_number) { | |
| 209 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 210 return frame_infos_[frame_number].encoded_frame_type; | |
| 211 } | |
| 212 | |
| 213 int VideoProcessorImpl::GetQpFromEncoder(int frame_number) { | |
| 214 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 215 return frame_infos_[frame_number].qp_encoder; | |
| 216 } | |
| 217 | |
| 218 int VideoProcessorImpl::GetQpFromBitstream(int frame_number) { | |
| 219 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 220 return frame_infos_[frame_number].qp_bitstream; | |
| 221 } | |
| 222 | |
| 223 int VideoProcessorImpl::NumberDroppedFrames() { | |
| 224 return num_dropped_frames_; | |
| 225 } | |
| 226 | |
| 227 int VideoProcessorImpl::NumberSpatialResizes() { | |
| 228 return num_spatial_resizes_; | |
| 229 } | |
| 230 | |
| 231 bool VideoProcessorImpl::ProcessFrame(int frame_number) { | 197 bool VideoProcessorImpl::ProcessFrame(int frame_number) { |
| 232 RTC_DCHECK_GE(frame_number, 0); | 198 RTC_DCHECK_GE(frame_number, 0); |
| 233 RTC_DCHECK_LE(frame_number, frame_infos_.size()) | 199 RTC_DCHECK_LE(frame_number, frame_infos_.size()) |
| 234 << "Must process frames without gaps."; | 200 << "Must process frames without gaps."; |
| 235 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; | 201 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; |
| 236 | 202 |
| 237 rtc::scoped_refptr<I420BufferInterface> buffer( | 203 rtc::scoped_refptr<I420BufferInterface> buffer( |
| 238 analysis_frame_reader_->ReadFrame()); | 204 analysis_frame_reader_->ReadFrame()); |
| 239 | 205 |
| 240 if (!buffer) { | 206 if (!buffer) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 270 // Create frame statistics object used for aggregation at end of test run. | 236 // Create frame statistics object used for aggregation at end of test run. |
| 271 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); | 237 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); |
| 272 | 238 |
| 273 // For the highest measurement accuracy of the encode time, the start/stop | 239 // For the highest measurement accuracy of the encode time, the start/stop |
| 274 // time recordings should wrap the Encode call as tightly as possible. | 240 // time recordings should wrap the Encode call as tightly as possible. |
| 275 frame_info->encode_start_ns = rtc::TimeNanos(); | 241 frame_info->encode_start_ns = rtc::TimeNanos(); |
| 276 frame_stat->encode_return_code = | 242 frame_stat->encode_return_code = |
| 277 encoder_->Encode(source_frame, nullptr, &frame_types); | 243 encoder_->Encode(source_frame, nullptr, &frame_types); |
| 278 | 244 |
| 279 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { | 245 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { |
| 280 fprintf(stderr, "Failed to encode frame %d, return code: %d\n", | 246 LOG(LS_WARNING) << "Failed to encode frame " << frame_number |
| 281 frame_number, frame_stat->encode_return_code); | 247 << ", return code: " << frame_stat->encode_return_code |
| 248 << "."; | |
| 282 } | 249 } |
| 283 | 250 |
| 284 return true; | 251 return true; |
| 285 } | 252 } |
| 286 | 253 |
| 254 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { | |
| 255 config_.codec_settings->maxFramerate = frame_rate; | |
| 256 int set_rates_result = encoder_->SetRateAllocation( | |
| 257 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), | |
| 258 frame_rate); | |
| 259 RTC_DCHECK_GE(set_rates_result, 0) | |
| 260 << "Failed to update encoder with new rate " << bit_rate; | |
| 261 num_dropped_frames_ = 0; | |
| 262 num_spatial_resizes_ = 0; | |
| 263 } | |
| 264 | |
| 265 size_t VideoProcessorImpl::EncodedFrameSize(int frame_number) { | |
| 266 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 267 return frame_infos_[frame_number].encoded_frame_size; | |
| 268 } | |
| 269 | |
| 270 FrameType VideoProcessorImpl::EncodedFrameType(int frame_number) { | |
| 271 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 272 return frame_infos_[frame_number].encoded_frame_type; | |
| 273 } | |
| 274 | |
| 275 int VideoProcessorImpl::GetQpFromEncoder(int frame_number) { | |
| 276 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 277 return frame_infos_[frame_number].qp_encoder; | |
| 278 } | |
| 279 | |
| 280 int VideoProcessorImpl::GetQpFromBitstream(int frame_number) { | |
| 281 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 282 return frame_infos_[frame_number].qp_bitstream; | |
| 283 } | |
| 284 | |
| 285 int VideoProcessorImpl::NumberDroppedFrames() { | |
| 286 return num_dropped_frames_; | |
| 287 } | |
| 288 | |
| 289 int VideoProcessorImpl::NumberSpatialResizes() { | |
| 290 return num_spatial_resizes_; | |
| 291 } | |
| 292 | |
| 287 void VideoProcessorImpl::FrameEncoded( | 293 void VideoProcessorImpl::FrameEncoded( |
| 288 webrtc::VideoCodecType codec, | 294 webrtc::VideoCodecType codec, |
| 289 const EncodedImage& encoded_image, | 295 const EncodedImage& encoded_image, |
| 290 const webrtc::RTPFragmentationHeader* fragmentation) { | 296 const webrtc::RTPFragmentationHeader* fragmentation) { |
| 291 // For the highest measurement accuracy of the encode time, the start/stop | 297 // For the highest measurement accuracy of the encode time, the start/stop |
| 292 // time recordings should wrap the Encode call as tightly as possible. | 298 // time recordings should wrap the Encode call as tightly as possible. |
| 293 int64_t encode_stop_ns = rtc::TimeNanos(); | 299 int64_t encode_stop_ns = rtc::TimeNanos(); |
| 294 | 300 |
| 295 if (encoded_frame_writer_) { | 301 if (encoded_frame_writer_) { |
| 296 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); | 302 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); | 487 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); |
| 482 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); | 488 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 483 if (decoded_frame_writer_) { | 489 if (decoded_frame_writer_) { |
| 484 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); | 490 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); |
| 485 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); | 491 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 486 } | 492 } |
| 487 | 493 |
| 488 last_decoded_frame_buffer_ = std::move(extracted_buffer); | 494 last_decoded_frame_buffer_ = std::move(extracted_buffer); |
| 489 } | 495 } |
| 490 | 496 |
| 497 uint32_t VideoProcessorImpl::FrameNumberToTimestamp(int frame_number) { | |
| 498 RTC_DCHECK_GE(frame_number, 0); | |
| 499 const int ticks_per_frame = | |
| 500 kRtpClockRateHz / config_.codec_settings->maxFramerate; | |
| 501 return (frame_number + 1) * ticks_per_frame; | |
| 502 } | |
| 503 | |
| 504 int VideoProcessorImpl::TimestampToFrameNumber(uint32_t timestamp) { | |
| 505 RTC_DCHECK_GT(timestamp, 0); | |
| 506 const int ticks_per_frame = | |
| 507 kRtpClockRateHz / config_.codec_settings->maxFramerate; | |
| 508 RTC_DCHECK_EQ(timestamp % ticks_per_frame, 0); | |
| 509 return (timestamp / ticks_per_frame) - 1; | |
| 510 } | |
| 511 | |
| 491 } // namespace test | 512 } // namespace test |
| 492 } // namespace webrtc | 513 } // namespace webrtc |
| OLD | NEW |