| 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(" Codec type : %s\n", |
| 67 printf(" Codec type : %s\n", | 53 CodecTypeToPayloadName(codec_settings->codecType).value_or("Unknown")); |
| 68 CodecTypeToPayloadName(config->codecType).value_or("Unknown")); | 54 printf(" Start bitrate : %d kbps\n", codec_settings->startBitrate); |
| 69 if (config->codecType == kVideoCodecVP8) { | 55 printf(" Max bitrate : %d kbps\n", codec_settings->maxBitrate); |
| 70 printf(" Denoising : %d\n", config->VP8().denoisingOn); | 56 printf(" Min bitrate : %d kbps\n", codec_settings->minBitrate); |
| 71 printf(" Error concealment: %d\n", config->VP8().errorConcealmentOn); | 57 printf(" Width : %d\n", codec_settings->width); |
| 72 printf(" Frame dropping : %d\n", config->VP8().frameDroppingOn); | 58 printf(" Height : %d\n", codec_settings->height); |
| 73 printf(" Resilience : %d\n", config->VP8().resilience); | 59 printf(" Max frame rate : %d\n", codec_settings->maxFramerate); |
| 74 } else if (config->codecType == kVideoCodecVP9) { | 60 printf(" QPmax : %d\n", codec_settings->qpMax); |
| 75 printf(" Denoising : %d\n", config->VP9().denoisingOn); | 61 if (codec_settings->codecType == kVideoCodecVP8) { |
| 76 printf(" Frame dropping : %d\n", config->VP9().frameDroppingOn); | 62 printf(" Complexity : %d\n", codec_settings->VP8().complexity); |
| 77 printf(" Resilience : %d\n", config->VP9().resilienceOn); | 63 printf(" Denoising : %d\n", codec_settings->VP8().denoisingOn); |
| 64 printf(" Error concealment : %d\n", |
| 65 codec_settings->VP8().errorConcealmentOn); |
| 66 printf(" Frame dropping : %d\n", codec_settings->VP8().frameDroppingOn); |
| 67 printf(" Resilience : %d\n", codec_settings->VP8().resilience); |
| 68 printf(" Key frame interval: %d\n", |
| 69 codec_settings->VP8().keyFrameInterval); |
| 70 } else if (codec_settings->codecType == kVideoCodecVP9) { |
| 71 printf(" Complexity : %d\n", codec_settings->VP9().complexity); |
| 72 printf(" Denoising : %d\n", codec_settings->VP9().denoisingOn); |
| 73 printf(" Frame dropping : %d\n", codec_settings->VP9().frameDroppingOn); |
| 74 printf(" Resilience : %d\n", codec_settings->VP9().resilienceOn); |
| 75 printf(" Key frame interval: %d\n", |
| 76 codec_settings->VP9().keyFrameInterval); |
| 77 printf(" Adaptive QP mode : %d\n", codec_settings->VP9().adaptiveQpMode); |
| 78 } else if (codec_settings->codecType == kVideoCodecH264) { |
| 79 printf(" Frame dropping : %d\n", |
| 80 codec_settings->H264().frameDroppingOn); |
| 81 printf(" Key frame interval: %d\n", |
| 82 codec_settings->H264().keyFrameInterval); |
| 83 printf(" Profile : %d\n", codec_settings->H264().profile); |
| 78 } | 84 } |
| 79 } | 85 } |
| 80 | 86 |
| 81 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { | 87 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { |
| 82 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; | 88 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; |
| 83 RTC_DCHECK_GE(diff_us, std::numeric_limits<int>::min()); | 89 RTC_DCHECK_GE(diff_us, std::numeric_limits<int>::min()); |
| 84 RTC_DCHECK_LE(diff_us, std::numeric_limits<int>::max()); | 90 RTC_DCHECK_LE(diff_us, std::numeric_limits<int>::max()); |
| 85 return static_cast<int>(diff_us); | 91 return static_cast<int>(diff_us); |
| 86 } | 92 } |
| 87 | 93 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 num_spatial_resizes_(0) { | 137 num_spatial_resizes_(0) { |
| 132 RTC_DCHECK(encoder); | 138 RTC_DCHECK(encoder); |
| 133 RTC_DCHECK(decoder); | 139 RTC_DCHECK(decoder); |
| 134 RTC_DCHECK(packet_manipulator); | 140 RTC_DCHECK(packet_manipulator); |
| 135 RTC_DCHECK(analysis_frame_reader); | 141 RTC_DCHECK(analysis_frame_reader); |
| 136 RTC_DCHECK(analysis_frame_writer); | 142 RTC_DCHECK(analysis_frame_writer); |
| 137 RTC_DCHECK(stats); | 143 RTC_DCHECK(stats); |
| 138 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); | 144 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); |
| 139 } | 145 } |
| 140 | 146 |
| 147 VideoProcessorImpl::~VideoProcessorImpl() { |
| 148 encoder_->RegisterEncodeCompleteCallback(nullptr); |
| 149 decoder_->RegisterDecodeCompleteCallback(nullptr); |
| 150 } |
| 151 |
| 141 void VideoProcessorImpl::Init() { | 152 void VideoProcessorImpl::Init() { |
| 142 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; | 153 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; |
| 154 RTC_DCHECK(config_.codec_settings) << "No codec settings supplied."; |
| 143 initialized_ = true; | 155 initialized_ = true; |
| 144 | 156 |
| 145 // Setup required callbacks for the encoder/decoder. | 157 // Setup required callbacks for the encoder and decoder. |
| 146 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), | 158 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), |
| 147 WEBRTC_VIDEO_CODEC_OK) | 159 WEBRTC_VIDEO_CODEC_OK) |
| 148 << "Failed to register encode complete callback"; | 160 << "Failed to register encode complete callback"; |
| 149 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), | 161 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), |
| 150 WEBRTC_VIDEO_CODEC_OK) | 162 WEBRTC_VIDEO_CODEC_OK) |
| 151 << "Failed to register decode complete callback"; | 163 << "Failed to register decode complete callback"; |
| 152 | 164 |
| 153 // Initialize the encoder and decoder. | 165 // Initialize the encoder and decoder. |
| 154 uint32_t num_cores = | 166 uint32_t num_cores = |
| 155 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); | 167 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); |
| 156 RTC_CHECK_EQ( | 168 RTC_CHECK_EQ( |
| 157 encoder_->InitEncode(config_.codec_settings, num_cores, | 169 encoder_->InitEncode(config_.codec_settings, num_cores, |
| 158 config_.networking_config.max_payload_size_in_bytes), | 170 config_.networking_config.max_payload_size_in_bytes), |
| 159 WEBRTC_VIDEO_CODEC_OK) | 171 WEBRTC_VIDEO_CODEC_OK) |
| 160 << "Failed to initialize VideoEncoder"; | 172 << "Failed to initialize VideoEncoder"; |
| 161 | 173 |
| 162 RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores), | 174 RTC_CHECK_EQ(decoder_->InitDecode(config_.codec_settings, num_cores), |
| 163 WEBRTC_VIDEO_CODEC_OK) | 175 WEBRTC_VIDEO_CODEC_OK) |
| 164 << "Failed to initialize VideoDecoder"; | 176 << "Failed to initialize VideoDecoder"; |
| 165 | 177 |
| 166 if (config_.verbose) { | 178 if (config_.verbose) { |
| 167 printf("Filename: %s\n", config_.filename.c_str()); | |
| 168 printf("Video Processor:\n"); | 179 printf("Video Processor:\n"); |
| 169 printf(" #CPU cores used : %d\n", num_cores); | 180 printf(" Filename : %s\n", config_.filename.c_str()); |
| 170 printf(" Total # of frames: %d\n", | 181 printf(" Total # of frames: %d\n", |
| 171 analysis_frame_reader_->NumberOfFrames()); | 182 analysis_frame_reader_->NumberOfFrames()); |
| 172 printf(" Codec settings:\n"); | 183 printf(" # CPU cores used : %d\n", num_cores); |
| 173 printf(" Encoder implementation name: %s\n", | 184 const char* encoder_name = encoder_->ImplementationName(); |
| 174 encoder_->ImplementationName()); | 185 printf(" Encoder implementation name: %s\n", encoder_name); |
| 175 printf(" Decoder implementation name: %s\n", | 186 const char* decoder_name = decoder_->ImplementationName(); |
| 176 decoder_->ImplementationName()); | 187 printf(" Decoder implementation name: %s\n", decoder_name); |
| 177 if (strcmp(encoder_->ImplementationName(), | 188 if (strcmp(encoder_name, decoder_name) == 0) { |
| 178 decoder_->ImplementationName()) == 0) { | 189 printf(" Codec implementation name : %s_%s\n", |
| 179 printf(" Codec implementation name: %s_%s\n", | |
| 180 CodecTypeToPayloadName(config_.codec_settings->codecType) | 190 CodecTypeToPayloadName(config_.codec_settings->codecType) |
| 181 .value_or("Unknown"), | 191 .value_or("Unknown"), |
| 182 encoder_->ImplementationName()); | 192 encoder_->ImplementationName()); |
| 183 } | 193 } |
| 184 PrintCodecSettings(config_.codec_settings); | 194 PrintCodecSettings(config_.codec_settings); |
| 195 printf("\n"); |
| 185 } | 196 } |
| 186 } | 197 } |
| 187 | 198 |
| 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) { | 199 bool VideoProcessorImpl::ProcessFrame(int frame_number) { |
| 232 RTC_DCHECK_GE(frame_number, 0); | 200 RTC_DCHECK_GE(frame_number, 0); |
| 233 RTC_DCHECK_LE(frame_number, frame_infos_.size()) | 201 RTC_DCHECK_LE(frame_number, frame_infos_.size()) |
| 234 << "Must process frames without gaps."; | 202 << "Must process frames without gaps."; |
| 235 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; | 203 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; |
| 236 | 204 |
| 237 rtc::scoped_refptr<I420BufferInterface> buffer( | 205 rtc::scoped_refptr<I420BufferInterface> buffer( |
| 238 analysis_frame_reader_->ReadFrame()); | 206 analysis_frame_reader_->ReadFrame()); |
| 239 | 207 |
| 240 if (!buffer) { | 208 if (!buffer) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 270 // Create frame statistics object used for aggregation at end of test run. | 238 // Create frame statistics object used for aggregation at end of test run. |
| 271 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); | 239 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); |
| 272 | 240 |
| 273 // For the highest measurement accuracy of the encode time, the start/stop | 241 // For the highest measurement accuracy of the encode time, the start/stop |
| 274 // time recordings should wrap the Encode call as tightly as possible. | 242 // time recordings should wrap the Encode call as tightly as possible. |
| 275 frame_info->encode_start_ns = rtc::TimeNanos(); | 243 frame_info->encode_start_ns = rtc::TimeNanos(); |
| 276 frame_stat->encode_return_code = | 244 frame_stat->encode_return_code = |
| 277 encoder_->Encode(source_frame, nullptr, &frame_types); | 245 encoder_->Encode(source_frame, nullptr, &frame_types); |
| 278 | 246 |
| 279 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { | 247 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { |
| 280 fprintf(stderr, "Failed to encode frame %d, return code: %d\n", | 248 LOG(LS_WARNING) << "Failed to encode frame " << frame_number |
| 281 frame_number, frame_stat->encode_return_code); | 249 << ", return code: " << frame_stat->encode_return_code |
| 250 << "."; |
| 282 } | 251 } |
| 283 | 252 |
| 284 return true; | 253 return true; |
| 285 } | 254 } |
| 286 | 255 |
| 256 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { |
| 257 config_.codec_settings->maxFramerate = frame_rate; |
| 258 int set_rates_result = encoder_->SetRateAllocation( |
| 259 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), |
| 260 frame_rate); |
| 261 RTC_DCHECK_GE(set_rates_result, 0) |
| 262 << "Failed to update encoder with new rate " << bit_rate; |
| 263 num_dropped_frames_ = 0; |
| 264 num_spatial_resizes_ = 0; |
| 265 } |
| 266 |
| 267 size_t VideoProcessorImpl::EncodedFrameSize(int frame_number) { |
| 268 RTC_DCHECK_LT(frame_number, frame_infos_.size()); |
| 269 return frame_infos_[frame_number].encoded_frame_size; |
| 270 } |
| 271 |
| 272 FrameType VideoProcessorImpl::EncodedFrameType(int frame_number) { |
| 273 RTC_DCHECK_LT(frame_number, frame_infos_.size()); |
| 274 return frame_infos_[frame_number].encoded_frame_type; |
| 275 } |
| 276 |
| 277 int VideoProcessorImpl::GetQpFromEncoder(int frame_number) { |
| 278 RTC_DCHECK_LT(frame_number, frame_infos_.size()); |
| 279 return frame_infos_[frame_number].qp_encoder; |
| 280 } |
| 281 |
| 282 int VideoProcessorImpl::GetQpFromBitstream(int frame_number) { |
| 283 RTC_DCHECK_LT(frame_number, frame_infos_.size()); |
| 284 return frame_infos_[frame_number].qp_bitstream; |
| 285 } |
| 286 |
| 287 int VideoProcessorImpl::NumberDroppedFrames() { |
| 288 return num_dropped_frames_; |
| 289 } |
| 290 |
| 291 int VideoProcessorImpl::NumberSpatialResizes() { |
| 292 return num_spatial_resizes_; |
| 293 } |
| 294 |
| 287 void VideoProcessorImpl::FrameEncoded( | 295 void VideoProcessorImpl::FrameEncoded( |
| 288 webrtc::VideoCodecType codec, | 296 webrtc::VideoCodecType codec, |
| 289 const EncodedImage& encoded_image, | 297 const EncodedImage& encoded_image, |
| 290 const webrtc::RTPFragmentationHeader* fragmentation) { | 298 const webrtc::RTPFragmentationHeader* fragmentation) { |
| 291 // For the highest measurement accuracy of the encode time, the start/stop | 299 // For the highest measurement accuracy of the encode time, the start/stop |
| 292 // time recordings should wrap the Encode call as tightly as possible. | 300 // time recordings should wrap the Encode call as tightly as possible. |
| 293 int64_t encode_stop_ns = rtc::TimeNanos(); | 301 int64_t encode_stop_ns = rtc::TimeNanos(); |
| 294 | 302 |
| 295 if (encoded_frame_writer_) { | 303 if (encoded_frame_writer_) { |
| 296 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); | 304 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()); | 489 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); |
| 482 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); | 490 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 483 if (decoded_frame_writer_) { | 491 if (decoded_frame_writer_) { |
| 484 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); | 492 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); |
| 485 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); | 493 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 486 } | 494 } |
| 487 | 495 |
| 488 last_decoded_frame_buffer_ = std::move(extracted_buffer); | 496 last_decoded_frame_buffer_ = std::move(extracted_buffer); |
| 489 } | 497 } |
| 490 | 498 |
| 499 uint32_t VideoProcessorImpl::FrameNumberToTimestamp(int frame_number) { |
| 500 RTC_DCHECK_GE(frame_number, 0); |
| 501 const int ticks_per_frame = |
| 502 kRtpClockRateHz / config_.codec_settings->maxFramerate; |
| 503 return (frame_number + 1) * ticks_per_frame; |
| 504 } |
| 505 |
| 506 int VideoProcessorImpl::TimestampToFrameNumber(uint32_t timestamp) { |
| 507 RTC_DCHECK_GT(timestamp, 0); |
| 508 const int ticks_per_frame = |
| 509 kRtpClockRateHz / config_.codec_settings->maxFramerate; |
| 510 RTC_DCHECK_EQ(timestamp % ticks_per_frame, 0); |
| 511 return (timestamp / ticks_per_frame) - 1; |
| 512 } |
| 513 |
| 491 } // namespace test | 514 } // namespace test |
| 492 } // namespace webrtc | 515 } // namespace webrtc |
| OLD | NEW |