| 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 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 CodecTypeToPayloadName(codec_settings.codecType).value_or("Unknown")); | 52 CodecTypeToPayloadName(codec_settings.codecType).value_or("Unknown")); |
| 53 printf(" Start bitrate : %d kbps\n", codec_settings.startBitrate); | 53 printf(" Start bitrate : %d kbps\n", codec_settings.startBitrate); |
| 54 printf(" Max bitrate : %d kbps\n", codec_settings.maxBitrate); | 54 printf(" Max bitrate : %d kbps\n", codec_settings.maxBitrate); |
| 55 printf(" Min bitrate : %d kbps\n", codec_settings.minBitrate); | 55 printf(" Min bitrate : %d kbps\n", codec_settings.minBitrate); |
| 56 printf(" Width : %d\n", codec_settings.width); | 56 printf(" Width : %d\n", codec_settings.width); |
| 57 printf(" Height : %d\n", codec_settings.height); | 57 printf(" Height : %d\n", codec_settings.height); |
| 58 printf(" Max frame rate : %d\n", codec_settings.maxFramerate); | 58 printf(" Max frame rate : %d\n", codec_settings.maxFramerate); |
| 59 printf(" QPmax : %d\n", codec_settings.qpMax); | 59 printf(" QPmax : %d\n", codec_settings.qpMax); |
| 60 if (codec_settings.codecType == kVideoCodecVP8) { | 60 if (codec_settings.codecType == kVideoCodecVP8) { |
| 61 printf(" Complexity : %d\n", codec_settings.VP8().complexity); | 61 printf(" Complexity : %d\n", codec_settings.VP8().complexity); |
| 62 printf(" Resilience : %d\n", codec_settings.VP8().resilience); |
| 63 printf(" # temporal layers : %d\n", |
| 64 codec_settings.VP8().numberOfTemporalLayers); |
| 62 printf(" Denoising : %d\n", codec_settings.VP8().denoisingOn); | 65 printf(" Denoising : %d\n", codec_settings.VP8().denoisingOn); |
| 63 printf(" Error concealment : %d\n", | 66 printf(" Error concealment : %d\n", |
| 64 codec_settings.VP8().errorConcealmentOn); | 67 codec_settings.VP8().errorConcealmentOn); |
| 68 printf(" Automatic resize : %d\n", |
| 69 codec_settings.VP8().automaticResizeOn); |
| 65 printf(" Frame dropping : %d\n", codec_settings.VP8().frameDroppingOn); | 70 printf(" Frame dropping : %d\n", codec_settings.VP8().frameDroppingOn); |
| 66 printf(" Resilience : %d\n", codec_settings.VP8().resilience); | |
| 67 printf(" Key frame interval: %d\n", codec_settings.VP8().keyFrameInterval); | 71 printf(" Key frame interval: %d\n", codec_settings.VP8().keyFrameInterval); |
| 68 } else if (codec_settings.codecType == kVideoCodecVP9) { | 72 } else if (codec_settings.codecType == kVideoCodecVP9) { |
| 69 printf(" Complexity : %d\n", codec_settings.VP9().complexity); | 73 printf(" Complexity : %d\n", codec_settings.VP9().complexity); |
| 74 printf(" Resilience : %d\n", codec_settings.VP9().resilienceOn); |
| 75 printf(" # temporal layers : %d\n", |
| 76 codec_settings.VP9().numberOfTemporalLayers); |
| 70 printf(" Denoising : %d\n", codec_settings.VP9().denoisingOn); | 77 printf(" Denoising : %d\n", codec_settings.VP9().denoisingOn); |
| 71 printf(" Frame dropping : %d\n", codec_settings.VP9().frameDroppingOn); | 78 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", codec_settings.VP9().keyFrameInterval); | 79 printf(" Key frame interval: %d\n", codec_settings.VP9().keyFrameInterval); |
| 74 printf(" Adaptive QP mode : %d\n", codec_settings.VP9().adaptiveQpMode); | 80 printf(" Adaptive QP mode : %d\n", codec_settings.VP9().adaptiveQpMode); |
| 81 printf(" Automatic resize : %d\n", |
| 82 codec_settings.VP9().automaticResizeOn); |
| 83 printf(" # spatial layers : %d\n", |
| 84 codec_settings.VP9().numberOfSpatialLayers); |
| 85 printf(" Flexible mode : %d\n", codec_settings.VP9().flexibleMode); |
| 75 } else if (codec_settings.codecType == kVideoCodecH264) { | 86 } else if (codec_settings.codecType == kVideoCodecH264) { |
| 76 printf(" Frame dropping : %d\n", codec_settings.H264().frameDroppingOn); | 87 printf(" Frame dropping : %d\n", codec_settings.H264().frameDroppingOn); |
| 77 printf(" Key frame interval: %d\n", | 88 printf(" Key frame interval: %d\n", |
| 78 codec_settings.H264().keyFrameInterval); | 89 codec_settings.H264().keyFrameInterval); |
| 79 printf(" Profile : %d\n", codec_settings.H264().profile); | 90 printf(" Profile : %d\n", codec_settings.H264().profile); |
| 80 } | 91 } |
| 81 } | 92 } |
| 82 | 93 |
| 83 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { | 94 int GetElapsedTimeMicroseconds(int64_t start_ns, int64_t stop_ns) { |
| 84 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; | 95 int64_t diff_us = (stop_ns - start_ns) / rtc::kNumNanosecsPerMicrosec; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 103 | 114 |
| 104 VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder, | 115 VideoProcessor::VideoProcessor(webrtc::VideoEncoder* encoder, |
| 105 webrtc::VideoDecoder* decoder, | 116 webrtc::VideoDecoder* decoder, |
| 106 FrameReader* analysis_frame_reader, | 117 FrameReader* analysis_frame_reader, |
| 107 FrameWriter* analysis_frame_writer, | 118 FrameWriter* analysis_frame_writer, |
| 108 PacketManipulator* packet_manipulator, | 119 PacketManipulator* packet_manipulator, |
| 109 const TestConfig& config, | 120 const TestConfig& config, |
| 110 Stats* stats, | 121 Stats* stats, |
| 111 IvfFileWriter* encoded_frame_writer, | 122 IvfFileWriter* encoded_frame_writer, |
| 112 FrameWriter* decoded_frame_writer) | 123 FrameWriter* decoded_frame_writer) |
| 113 : config_(config), | 124 : initialized_(false), |
| 125 config_(config), |
| 114 encoder_(encoder), | 126 encoder_(encoder), |
| 115 decoder_(decoder), | 127 decoder_(decoder), |
| 116 bitrate_allocator_(CreateBitrateAllocator(&config_)), | 128 bitrate_allocator_(CreateBitrateAllocator(&config_)), |
| 117 encode_callback_(new VideoProcessorEncodeCompleteCallback(this)), | 129 encode_callback_(this), |
| 118 decode_callback_(new VideoProcessorDecodeCompleteCallback(this)), | 130 decode_callback_(this), |
| 131 num_frames_decoded_(0), |
| 119 packet_manipulator_(packet_manipulator), | 132 packet_manipulator_(packet_manipulator), |
| 120 analysis_frame_reader_(analysis_frame_reader), | 133 analysis_frame_reader_(analysis_frame_reader), |
| 121 analysis_frame_writer_(analysis_frame_writer), | 134 analysis_frame_writer_(analysis_frame_writer), |
| 122 encoded_frame_writer_(encoded_frame_writer), | 135 encoded_frame_writer_(encoded_frame_writer), |
| 123 decoded_frame_writer_(decoded_frame_writer), | 136 decoded_frame_writer_(decoded_frame_writer), |
| 124 initialized_(false), | |
| 125 last_encoded_frame_num_(-1), | 137 last_encoded_frame_num_(-1), |
| 126 last_decoded_frame_num_(-1), | 138 last_decoded_frame_num_(-1), |
| 127 first_key_frame_has_been_excluded_(false), | 139 first_key_frame_has_been_excluded_(false), |
| 128 last_decoded_frame_buffer_(0, analysis_frame_reader->FrameLength()), | 140 last_decoded_frame_buffer_(analysis_frame_reader->FrameLength()), |
| 129 stats_(stats), | 141 stats_(stats), |
| 130 num_dropped_frames_(0), | 142 rate_update_index_(-1) { |
| 131 num_spatial_resizes_(0) { | |
| 132 RTC_DCHECK(encoder); | 143 RTC_DCHECK(encoder); |
| 133 RTC_DCHECK(decoder); | 144 RTC_DCHECK(decoder); |
| 134 RTC_DCHECK(packet_manipulator); | 145 RTC_DCHECK(packet_manipulator); |
| 135 RTC_DCHECK(analysis_frame_reader); | 146 RTC_DCHECK(analysis_frame_reader); |
| 136 RTC_DCHECK(analysis_frame_writer); | 147 RTC_DCHECK(analysis_frame_writer); |
| 137 RTC_DCHECK(stats); | 148 RTC_DCHECK(stats); |
| 138 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); | 149 frame_infos_.reserve(analysis_frame_reader->NumberOfFrames()); |
| 139 } | 150 } |
| 140 | 151 |
| 141 VideoProcessor::~VideoProcessor() = default; | 152 VideoProcessor::~VideoProcessor() = default; |
| 142 | 153 |
| 143 void VideoProcessor::Init() { | 154 void VideoProcessor::Init() { |
| 155 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 144 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; | 156 RTC_DCHECK(!initialized_) << "VideoProcessor already initialized."; |
| 145 initialized_ = true; | 157 initialized_ = true; |
| 146 | 158 |
| 147 // Setup required callbacks for the encoder and decoder. | 159 // Setup required callbacks for the encoder and decoder. |
| 148 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(encode_callback_.get()), | 160 RTC_CHECK_EQ(encoder_->RegisterEncodeCompleteCallback(&encode_callback_), |
| 149 WEBRTC_VIDEO_CODEC_OK) | 161 WEBRTC_VIDEO_CODEC_OK) |
| 150 << "Failed to register encode complete callback"; | 162 << "Failed to register encode complete callback"; |
| 151 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(decode_callback_.get()), | 163 RTC_CHECK_EQ(decoder_->RegisterDecodeCompleteCallback(&decode_callback_), |
| 152 WEBRTC_VIDEO_CODEC_OK) | 164 WEBRTC_VIDEO_CODEC_OK) |
| 153 << "Failed to register decode complete callback"; | 165 << "Failed to register decode complete callback"; |
| 154 | 166 |
| 155 // Initialize the encoder and decoder. | 167 // Initialize the encoder and decoder. |
| 156 uint32_t num_cores = | 168 uint32_t num_cores = |
| 157 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); | 169 config_.use_single_core ? 1 : CpuInfo::DetectNumberOfCores(); |
| 158 RTC_CHECK_EQ( | 170 RTC_CHECK_EQ( |
| 159 encoder_->InitEncode(&config_.codec_settings, num_cores, | 171 encoder_->InitEncode(&config_.codec_settings, num_cores, |
| 160 config_.networking_config.max_payload_size_in_bytes), | 172 config_.networking_config.max_payload_size_in_bytes), |
| 161 WEBRTC_VIDEO_CODEC_OK) | 173 WEBRTC_VIDEO_CODEC_OK) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 180 CodecTypeToPayloadName(config_.codec_settings.codecType) | 192 CodecTypeToPayloadName(config_.codec_settings.codecType) |
| 181 .value_or("Unknown"), | 193 .value_or("Unknown"), |
| 182 encoder_->ImplementationName()); | 194 encoder_->ImplementationName()); |
| 183 } | 195 } |
| 184 PrintCodecSettings(config_.codec_settings); | 196 PrintCodecSettings(config_.codec_settings); |
| 185 printf("\n"); | 197 printf("\n"); |
| 186 } | 198 } |
| 187 } | 199 } |
| 188 | 200 |
| 189 void VideoProcessor::Release() { | 201 void VideoProcessor::Release() { |
| 190 encoder_->RegisterEncodeCompleteCallback(nullptr); | 202 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 191 decoder_->RegisterDecodeCompleteCallback(nullptr); | |
| 192 | 203 |
| 193 RTC_CHECK_EQ(encoder_->Release(), WEBRTC_VIDEO_CODEC_OK); | 204 RTC_CHECK_EQ(encoder_->Release(), WEBRTC_VIDEO_CODEC_OK); |
| 194 RTC_CHECK_EQ(decoder_->Release(), WEBRTC_VIDEO_CODEC_OK); | 205 RTC_CHECK_EQ(decoder_->Release(), WEBRTC_VIDEO_CODEC_OK); |
| 195 | 206 |
| 207 encoder_->RegisterEncodeCompleteCallback(nullptr); |
| 208 decoder_->RegisterDecodeCompleteCallback(nullptr); |
| 209 |
| 196 initialized_ = false; | 210 initialized_ = false; |
| 197 } | 211 } |
| 198 | 212 |
| 199 bool VideoProcessor::ProcessFrame(int frame_number) { | 213 void VideoProcessor::ProcessFrame(int frame_number) { |
| 200 RTC_DCHECK_GE(frame_number, 0); | 214 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 201 RTC_DCHECK_LE(frame_number, frame_infos_.size()) | 215 RTC_DCHECK_EQ(frame_number, frame_infos_.size()) |
| 202 << "Must process frames without gaps."; | 216 << "Must process frames in sequence."; |
| 203 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; | 217 RTC_DCHECK(initialized_) << "VideoProcessor not initialized."; |
| 204 | 218 |
| 219 // Get frame from file. |
| 205 rtc::scoped_refptr<I420BufferInterface> buffer( | 220 rtc::scoped_refptr<I420BufferInterface> buffer( |
| 206 analysis_frame_reader_->ReadFrame()); | 221 analysis_frame_reader_->ReadFrame()); |
| 207 | 222 RTC_CHECK(buffer) << "Tried to read too many frames from the file."; |
| 208 if (!buffer) { | 223 const int64_t kNoRenderTime = 0; |
| 209 // Last frame has been reached. | 224 VideoFrame source_frame(buffer, FrameNumberToTimestamp(frame_number), |
| 210 return false; | 225 kNoRenderTime, webrtc::kVideoRotation_0); |
| 211 } | |
| 212 | |
| 213 uint32_t timestamp = FrameNumberToTimestamp(frame_number); | |
| 214 VideoFrame source_frame(buffer, timestamp, 0, webrtc::kVideoRotation_0); | |
| 215 | |
| 216 // Store frame information during the different stages of encode and decode. | |
| 217 frame_infos_.emplace_back(); | |
| 218 FrameInfo* frame_info = &frame_infos_.back(); | |
| 219 frame_info->timestamp = timestamp; | |
| 220 | 226 |
| 221 // Decide if we are going to force a keyframe. | 227 // Decide if we are going to force a keyframe. |
| 222 std::vector<FrameType> frame_types(1, kVideoFrameDelta); | 228 std::vector<FrameType> frame_types(1, kVideoFrameDelta); |
| 223 if (config_.keyframe_interval > 0 && | 229 if (config_.keyframe_interval > 0 && |
| 224 frame_number % config_.keyframe_interval == 0) { | 230 frame_number % config_.keyframe_interval == 0) { |
| 225 frame_types[0] = kVideoFrameKey; | 231 frame_types[0] = kVideoFrameKey; |
| 226 } | 232 } |
| 227 | 233 |
| 234 // Store frame information during the different stages of encode and decode. |
| 235 frame_infos_.emplace_back(); |
| 236 FrameInfo* frame_info = &frame_infos_.back(); |
| 237 |
| 228 // 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. |
| 229 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); | 239 FrameStatistic* frame_stat = &stats_->NewFrame(frame_number); |
| 230 | 240 |
| 231 // 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 |
| 232 // time recordings should wrap the Encode call as tightly as possible. | 242 // time recordings should wrap the Encode call as tightly as possible. |
| 233 frame_info->encode_start_ns = rtc::TimeNanos(); | 243 frame_info->encode_start_ns = rtc::TimeNanos(); |
| 234 frame_stat->encode_return_code = | 244 frame_stat->encode_return_code = |
| 235 encoder_->Encode(source_frame, nullptr, &frame_types); | 245 encoder_->Encode(source_frame, nullptr, &frame_types); |
| 236 | 246 |
| 237 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { | 247 if (frame_stat->encode_return_code != WEBRTC_VIDEO_CODEC_OK) { |
| 238 LOG(LS_WARNING) << "Failed to encode frame " << frame_number | 248 LOG(LS_WARNING) << "Failed to encode frame " << frame_number |
| 239 << ", return code: " << frame_stat->encode_return_code | 249 << ", return code: " << frame_stat->encode_return_code |
| 240 << "."; | 250 << "."; |
| 241 } | 251 } |
| 242 | |
| 243 return true; | |
| 244 } | 252 } |
| 245 | 253 |
| 246 void VideoProcessor::SetRates(int bit_rate, int frame_rate) { | 254 void VideoProcessor::SetRates(int bitrate_kbps, int framerate_fps) { |
| 247 config_.codec_settings.maxFramerate = frame_rate; | 255 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 256 |
| 257 config_.codec_settings.maxFramerate = framerate_fps; |
| 248 int set_rates_result = encoder_->SetRateAllocation( | 258 int set_rates_result = encoder_->SetRateAllocation( |
| 249 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), | 259 bitrate_allocator_->GetAllocation(bitrate_kbps * 1000, framerate_fps), |
| 250 frame_rate); | 260 framerate_fps); |
| 251 RTC_DCHECK_GE(set_rates_result, 0) | 261 RTC_DCHECK_GE(set_rates_result, 0) |
| 252 << "Failed to update encoder with new rate " << bit_rate; | 262 << "Failed to update encoder with new rate " << bitrate_kbps << "."; |
| 253 num_dropped_frames_ = 0; | 263 ++rate_update_index_; |
| 254 num_spatial_resizes_ = 0; | 264 num_dropped_frames_.push_back(0); |
| 265 num_spatial_resizes_.push_back(0); |
| 255 } | 266 } |
| 256 | 267 |
| 257 size_t VideoProcessor::EncodedFrameSize(int frame_number) { | 268 int VideoProcessor::NumFramesDecoded() const { |
| 258 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | 269 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 259 return frame_infos_[frame_number].encoded_frame_size; | 270 return num_frames_decoded_; |
| 260 } | 271 } |
| 261 | 272 |
| 262 FrameType VideoProcessor::EncodedFrameType(int frame_number) { | 273 int VideoProcessor::GetQpFromEncoder(int frame_number) const { |
| 263 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | 274 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 264 return frame_infos_[frame_number].encoded_frame_type; | 275 RTC_CHECK_LT(frame_number, frame_infos_.size()); |
| 265 } | |
| 266 | |
| 267 int VideoProcessor::GetQpFromEncoder(int frame_number) { | |
| 268 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | |
| 269 return frame_infos_[frame_number].qp_encoder; | 276 return frame_infos_[frame_number].qp_encoder; |
| 270 } | 277 } |
| 271 | 278 |
| 272 int VideoProcessor::GetQpFromBitstream(int frame_number) { | 279 int VideoProcessor::GetQpFromBitstream(int frame_number) const { |
| 273 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | 280 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 281 RTC_CHECK_LT(frame_number, frame_infos_.size()); |
| 274 return frame_infos_[frame_number].qp_bitstream; | 282 return frame_infos_[frame_number].qp_bitstream; |
| 275 } | 283 } |
| 276 | 284 |
| 277 int VideoProcessor::NumberDroppedFrames() { | 285 std::vector<int> VideoProcessor::NumberDroppedFramesPerRateUpdate() const { |
| 286 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 278 return num_dropped_frames_; | 287 return num_dropped_frames_; |
| 279 } | 288 } |
| 280 | 289 |
| 281 int VideoProcessor::NumberSpatialResizes() { | 290 std::vector<int> VideoProcessor::NumberSpatialResizesPerRateUpdate() const { |
| 291 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 282 return num_spatial_resizes_; | 292 return num_spatial_resizes_; |
| 283 } | 293 } |
| 284 | 294 |
| 285 void VideoProcessor::FrameEncoded( | 295 void VideoProcessor::FrameEncoded( |
| 286 webrtc::VideoCodecType codec, | 296 webrtc::VideoCodecType codec, |
| 287 const EncodedImage& encoded_image, | 297 const EncodedImage& encoded_image, |
| 288 const webrtc::RTPFragmentationHeader* fragmentation) { | 298 const webrtc::RTPFragmentationHeader* fragmentation) { |
| 299 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 300 |
| 289 // For the highest measurement accuracy of the encode time, the start/stop | 301 // For the highest measurement accuracy of the encode time, the start/stop |
| 290 // time recordings should wrap the Encode call as tightly as possible. | 302 // time recordings should wrap the Encode call as tightly as possible. |
| 291 int64_t encode_stop_ns = rtc::TimeNanos(); | 303 int64_t encode_stop_ns = rtc::TimeNanos(); |
| 292 | 304 |
| 293 if (encoded_frame_writer_) { | 305 if (encoded_frame_writer_) { |
| 294 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); | 306 RTC_CHECK(encoded_frame_writer_->WriteFrame(encoded_image, codec)); |
| 295 } | 307 } |
| 296 | 308 |
| 297 // Timestamp is proportional to frame number, so this gives us number of | 309 // Timestamp is proportional to frame number, so this gives us number of |
| 298 // dropped frames. | 310 // dropped frames. |
| 299 int frame_number = TimestampToFrameNumber(encoded_image._timeStamp); | 311 int frame_number = TimestampToFrameNumber(encoded_image._timeStamp); |
| 300 bool last_frame_missing = false; | 312 bool last_frame_missing = false; |
| 301 if (frame_number > 0) { | 313 if (frame_number > 0) { |
| 302 RTC_DCHECK_GE(last_encoded_frame_num_, 0); | 314 RTC_DCHECK_GE(last_encoded_frame_num_, 0); |
| 303 int num_dropped_from_last_encode = | 315 int num_dropped_from_last_encode = |
| 304 frame_number - last_encoded_frame_num_ - 1; | 316 frame_number - last_encoded_frame_num_ - 1; |
| 305 RTC_DCHECK_GE(num_dropped_from_last_encode, 0); | 317 RTC_DCHECK_GE(num_dropped_from_last_encode, 0); |
| 306 num_dropped_frames_ += num_dropped_from_last_encode; | 318 RTC_CHECK_GE(rate_update_index_, 0); |
| 319 num_dropped_frames_[rate_update_index_] += num_dropped_from_last_encode; |
| 307 if (num_dropped_from_last_encode > 0) { | 320 if (num_dropped_from_last_encode > 0) { |
| 308 // For dropped frames, we write out the last decoded frame to avoid | 321 // For dropped frames, we write out the last decoded frame to avoid |
| 309 // getting out of sync for the computation of PSNR and SSIM. | 322 // getting out of sync for the computation of PSNR and SSIM. |
| 310 for (int i = 0; i < num_dropped_from_last_encode; i++) { | 323 for (int i = 0; i < num_dropped_from_last_encode; i++) { |
| 311 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), | 324 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), |
| 312 analysis_frame_writer_->FrameLength()); | 325 analysis_frame_writer_->FrameLength()); |
| 313 RTC_CHECK(analysis_frame_writer_->WriteFrame( | 326 RTC_CHECK(analysis_frame_writer_->WriteFrame( |
| 314 last_decoded_frame_buffer_.data())); | 327 last_decoded_frame_buffer_.data())); |
| 315 if (decoded_frame_writer_) { | 328 if (decoded_frame_writer_) { |
| 316 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), | 329 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), |
| 317 decoded_frame_writer_->FrameLength()); | 330 decoded_frame_writer_->FrameLength()); |
| 318 RTC_CHECK(decoded_frame_writer_->WriteFrame( | 331 RTC_CHECK(decoded_frame_writer_->WriteFrame( |
| 319 last_decoded_frame_buffer_.data())); | 332 last_decoded_frame_buffer_.data())); |
| 320 } | 333 } |
| 321 } | 334 } |
| 322 } | 335 } |
| 323 | 336 |
| 324 last_frame_missing = | 337 last_frame_missing = |
| 325 (frame_infos_[last_encoded_frame_num_].manipulated_length == 0); | 338 (frame_infos_[last_encoded_frame_num_].manipulated_length == 0); |
| 326 } | 339 } |
| 327 // Ensure strict monotonicity. | 340 // Ensure strict monotonicity. |
| 328 RTC_CHECK_GT(frame_number, last_encoded_frame_num_); | 341 RTC_CHECK_GT(frame_number, last_encoded_frame_num_); |
| 329 last_encoded_frame_num_ = frame_number; | 342 last_encoded_frame_num_ = frame_number; |
| 330 | 343 |
| 331 // Frame is not dropped, so update frame information and statistics. | 344 // Frame is not dropped, so update frame information and statistics. |
| 332 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | 345 RTC_CHECK_LT(frame_number, frame_infos_.size()); |
| 333 FrameInfo* frame_info = &frame_infos_[frame_number]; | 346 FrameInfo* frame_info = &frame_infos_[frame_number]; |
| 334 frame_info->encoded_frame_size = encoded_image._length; | |
| 335 frame_info->encoded_frame_type = encoded_image._frameType; | |
| 336 frame_info->qp_encoder = encoded_image.qp_; | 347 frame_info->qp_encoder = encoded_image.qp_; |
| 337 if (codec == kVideoCodecVP8) { | 348 if (codec == kVideoCodecVP8) { |
| 338 vp8::GetQp(encoded_image._buffer, encoded_image._length, | 349 vp8::GetQp(encoded_image._buffer, encoded_image._length, |
| 339 &frame_info->qp_bitstream); | 350 &frame_info->qp_bitstream); |
| 340 } else if (codec == kVideoCodecVP9) { | 351 } else if (codec == kVideoCodecVP9) { |
| 341 vp9::GetQp(encoded_image._buffer, encoded_image._length, | 352 vp9::GetQp(encoded_image._buffer, encoded_image._length, |
| 342 &frame_info->qp_bitstream); | 353 &frame_info->qp_bitstream); |
| 343 } | 354 } |
| 344 FrameStatistic* frame_stat = &stats_->stats_[frame_number]; | 355 FrameStatistic* frame_stat = &stats_->stats_[frame_number]; |
| 345 frame_stat->encode_time_in_us = | 356 frame_stat->encode_time_in_us = |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 if (decoded_frame_writer_) { | 423 if (decoded_frame_writer_) { |
| 413 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), | 424 RTC_DCHECK_EQ(last_decoded_frame_buffer_.size(), |
| 414 decoded_frame_writer_->FrameLength()); | 425 decoded_frame_writer_->FrameLength()); |
| 415 RTC_CHECK( | 426 RTC_CHECK( |
| 416 decoded_frame_writer_->WriteFrame(last_decoded_frame_buffer_.data())); | 427 decoded_frame_writer_->WriteFrame(last_decoded_frame_buffer_.data())); |
| 417 } | 428 } |
| 418 } | 429 } |
| 419 } | 430 } |
| 420 | 431 |
| 421 void VideoProcessor::FrameDecoded(const VideoFrame& image) { | 432 void VideoProcessor::FrameDecoded(const VideoFrame& image) { |
| 433 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 434 |
| 422 // For the highest measurement accuracy of the decode time, the start/stop | 435 // For the highest measurement accuracy of the decode time, the start/stop |
| 423 // time recordings should wrap the Decode call as tightly as possible. | 436 // time recordings should wrap the Decode call as tightly as possible. |
| 424 int64_t decode_stop_ns = rtc::TimeNanos(); | 437 int64_t decode_stop_ns = rtc::TimeNanos(); |
| 425 | 438 |
| 426 // Update frame information and statistics. | 439 // Update frame information and statistics. |
| 427 int frame_number = TimestampToFrameNumber(image.timestamp()); | 440 int frame_number = TimestampToFrameNumber(image.timestamp()); |
| 428 RTC_DCHECK_LT(frame_number, frame_infos_.size()); | 441 RTC_DCHECK_LT(frame_number, frame_infos_.size()); |
| 429 FrameInfo* frame_info = &frame_infos_[frame_number]; | 442 FrameInfo* frame_info = &frame_infos_[frame_number]; |
| 430 frame_info->decoded_width = image.width(); | 443 frame_info->decoded_width = image.width(); |
| 431 frame_info->decoded_height = image.height(); | 444 frame_info->decoded_height = image.height(); |
| 432 FrameStatistic* frame_stat = &stats_->stats_[frame_number]; | 445 FrameStatistic* frame_stat = &stats_->stats_[frame_number]; |
| 433 frame_stat->decode_time_in_us = | 446 frame_stat->decode_time_in_us = |
| 434 GetElapsedTimeMicroseconds(frame_info->decode_start_ns, decode_stop_ns); | 447 GetElapsedTimeMicroseconds(frame_info->decode_start_ns, decode_stop_ns); |
| 435 frame_stat->decoding_successful = true; | 448 frame_stat->decoding_successful = true; |
| 436 | 449 |
| 437 // Check if the codecs have resized the frame since previously decoded frame. | 450 // Check if the codecs have resized the frame since previously decoded frame. |
| 438 if (frame_number > 0) { | 451 if (frame_number > 0) { |
| 439 RTC_DCHECK_GE(last_decoded_frame_num_, 0); | 452 RTC_DCHECK_GE(last_decoded_frame_num_, 0); |
| 440 const FrameInfo& last_decoded_frame_info = | 453 const FrameInfo& last_decoded_frame_info = |
| 441 frame_infos_[last_decoded_frame_num_]; | 454 frame_infos_[last_decoded_frame_num_]; |
| 442 if (static_cast<int>(image.width()) != | 455 if (static_cast<int>(image.width()) != |
| 443 last_decoded_frame_info.decoded_width || | 456 last_decoded_frame_info.decoded_width || |
| 444 static_cast<int>(image.height()) != | 457 static_cast<int>(image.height()) != |
| 445 last_decoded_frame_info.decoded_height) { | 458 last_decoded_frame_info.decoded_height) { |
| 446 ++num_spatial_resizes_; | 459 RTC_CHECK_GE(rate_update_index_, 0); |
| 460 ++num_spatial_resizes_[rate_update_index_]; |
| 447 } | 461 } |
| 448 } | 462 } |
| 449 // Ensure strict monotonicity. | 463 // Ensure strict monotonicity. |
| 450 RTC_CHECK_GT(frame_number, last_decoded_frame_num_); | 464 RTC_CHECK_GT(frame_number, last_decoded_frame_num_); |
| 451 last_decoded_frame_num_ = frame_number; | 465 last_decoded_frame_num_ = frame_number; |
| 452 | 466 |
| 453 // Check if codec size is different from the original size, and if so, | 467 // Check if codec size is different from the original size, and if so, |
| 454 // scale back to original size. This is needed for the PSNR and SSIM | 468 // scale back to original size. This is needed for the PSNR and SSIM |
| 455 // calculations. | 469 // calculations. |
| 456 size_t extracted_length; | 470 size_t extracted_length; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 477 } | 491 } |
| 478 | 492 |
| 479 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); | 493 RTC_DCHECK_EQ(extracted_length, analysis_frame_writer_->FrameLength()); |
| 480 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); | 494 RTC_CHECK(analysis_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 481 if (decoded_frame_writer_) { | 495 if (decoded_frame_writer_) { |
| 482 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); | 496 RTC_DCHECK_EQ(extracted_length, decoded_frame_writer_->FrameLength()); |
| 483 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); | 497 RTC_CHECK(decoded_frame_writer_->WriteFrame(extracted_buffer.data())); |
| 484 } | 498 } |
| 485 | 499 |
| 486 last_decoded_frame_buffer_ = std::move(extracted_buffer); | 500 last_decoded_frame_buffer_ = std::move(extracted_buffer); |
| 501 |
| 502 ++num_frames_decoded_; |
| 487 } | 503 } |
| 488 | 504 |
| 489 uint32_t VideoProcessor::FrameNumberToTimestamp(int frame_number) { | 505 uint32_t VideoProcessor::FrameNumberToTimestamp(int frame_number) const { |
| 506 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 507 |
| 490 RTC_DCHECK_GE(frame_number, 0); | 508 RTC_DCHECK_GE(frame_number, 0); |
| 491 const int ticks_per_frame = | 509 const int ticks_per_frame = |
| 492 kRtpClockRateHz / config_.codec_settings.maxFramerate; | 510 kRtpClockRateHz / config_.codec_settings.maxFramerate; |
| 493 return (frame_number + 1) * ticks_per_frame; | 511 return (frame_number + 1) * ticks_per_frame; |
| 494 } | 512 } |
| 495 | 513 |
| 496 int VideoProcessor::TimestampToFrameNumber(uint32_t timestamp) { | 514 int VideoProcessor::TimestampToFrameNumber(uint32_t timestamp) const { |
| 515 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 516 |
| 497 RTC_DCHECK_GT(timestamp, 0); | 517 RTC_DCHECK_GT(timestamp, 0); |
| 498 const int ticks_per_frame = | 518 const int ticks_per_frame = |
| 499 kRtpClockRateHz / config_.codec_settings.maxFramerate; | 519 kRtpClockRateHz / config_.codec_settings.maxFramerate; |
| 500 RTC_DCHECK_EQ(timestamp % ticks_per_frame, 0); | 520 RTC_DCHECK_EQ(timestamp % ticks_per_frame, 0); |
| 501 return (timestamp / ticks_per_frame) - 1; | 521 return (timestamp / ticks_per_frame) - 1; |
| 502 } | 522 } |
| 503 | 523 |
| 504 } // namespace test | 524 } // namespace test |
| 505 } // namespace webrtc | 525 } // namespace webrtc |
| OLD | NEW |