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 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 // TODO(brandtr): Generalize so that we support multiple profiles here. | 166 // TODO(brandtr): Generalize so that we support multiple profiles here. |
| 167 encoder_ = encoder_factory_->CreateVideoEncoder( | 167 encoder_ = encoder_factory_->CreateVideoEncoder( |
| 168 cricket::VideoCodec(cricket::kH264CodecName)); | 168 cricket::VideoCodec(cricket::kH264CodecName)); |
| 169 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); | 169 decoder_ = decoder_factory_->CreateVideoDecoder(kVideoCodecH264); |
| 170 break; | 170 break; |
| 171 default: | 171 default: |
| 172 RTC_NOTREACHED(); | 172 RTC_NOTREACHED(); |
| 173 break; | 173 break; |
| 174 } | 174 } |
| 175 | 175 |
| 176 RTC_CHECK(encoder_) << "Encoder not successfully created."; | 176 EXPECT_TRUE(encoder_) << "Encoder not successfully created."; |
| 177 RTC_CHECK(decoder_) << "Decoder not successfully created."; | 177 EXPECT_TRUE(decoder_) << "Decoder not successfully created."; |
| 178 } | 178 } |
| 179 | 179 |
| 180 void DestroyEncoderAndDecoder() { | 180 void DestroyEncoderAndDecoder() { |
| 181 encoder_factory_->DestroyVideoEncoder(encoder_); | 181 encoder_factory_->DestroyVideoEncoder(encoder_); |
| 182 decoder_factory_->DestroyVideoDecoder(decoder_); | 182 decoder_factory_->DestroyVideoDecoder(decoder_); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void SetUpObjects(const VisualizationParams* visualization_params, | 185 void SetUpObjects(const VisualizationParams* visualization_params, |
| 186 const int initial_bitrate_kbps, | 186 const int initial_bitrate_kbps, |
| 187 const int initial_framerate_fps) { | 187 const int initial_framerate_fps) { |
| 188 CreateEncoderAndDecoder(); | 188 CreateEncoderAndDecoder(); |
| 189 | 189 |
| 190 // Create file objects for quality analysis. | 190 // Create file objects for quality analysis. |
| 191 analysis_frame_reader_.reset(new YuvFrameReaderImpl( | 191 analysis_frame_reader_.reset(new YuvFrameReaderImpl( |
| 192 config_.input_filename, config_.codec_settings.width, | 192 config_.input_filename, config_.codec_settings.width, |
| 193 config_.codec_settings.height)); | 193 config_.codec_settings.height)); |
| 194 analysis_frame_writer_.reset(new YuvFrameWriterImpl( | 194 analysis_frame_writer_.reset(new YuvFrameWriterImpl( |
| 195 config_.output_filename, config_.codec_settings.width, | 195 config_.output_filename, config_.codec_settings.width, |
| 196 config_.codec_settings.height)); | 196 config_.codec_settings.height)); |
| 197 RTC_CHECK(analysis_frame_reader_->Init()); | 197 EXPECT_TRUE(analysis_frame_reader_->Init()); |
| 198 RTC_CHECK(analysis_frame_writer_->Init()); | 198 EXPECT_TRUE(analysis_frame_writer_->Init()); |
| 199 | 199 |
| 200 if (visualization_params) { | 200 if (visualization_params) { |
| 201 const std::string codec_name = | 201 const std::string codec_name = |
| 202 CodecTypeToPayloadName(config_.codec_settings.codecType) | 202 CodecTypeToPayloadName(config_.codec_settings.codecType) |
| 203 .value_or("unknown"); | 203 .value_or("unknown"); |
| 204 const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; | 204 const std::string implementation_type = config_.hw_codec ? "hw" : "sw"; |
| 205 // clang-format off | 205 // clang-format off |
| 206 const std::string output_filename_base = | 206 const std::string output_filename_base = |
| 207 OutputPath() + config_.filename + "-" + | 207 OutputPath() + config_.filename + "-" + |
| 208 codec_name + "-" + implementation_type + "-" + | 208 codec_name + "-" + implementation_type + "-" + |
| 209 std::to_string(initial_bitrate_kbps); | 209 std::to_string(initial_bitrate_kbps); |
| 210 // clang-format on | 210 // clang-format on |
| 211 if (visualization_params->save_encoded_ivf) { | 211 if (visualization_params->save_encoded_ivf) { |
| 212 rtc::File post_encode_file = | 212 rtc::File post_encode_file = |
| 213 rtc::File::Create(output_filename_base + "_encoded.ivf"); | 213 rtc::File::Create(output_filename_base + ".ivf"); |
| 214 encoded_frame_writer_ = | 214 encoded_frame_writer_ = |
| 215 IvfFileWriter::Wrap(std::move(post_encode_file), 0); | 215 IvfFileWriter::Wrap(std::move(post_encode_file), 0); |
| 216 } | 216 } |
| 217 if (visualization_params->save_decoded_y4m) { | 217 if (visualization_params->save_decoded_y4m) { |
| 218 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( | 218 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( |
| 219 output_filename_base + "_decoded.y4m", config_.codec_settings.width, | 219 output_filename_base + ".y4m", config_.codec_settings.width, |
| 220 config_.codec_settings.height, initial_framerate_fps)); | 220 config_.codec_settings.height, initial_framerate_fps)); |
| 221 RTC_CHECK(decoded_frame_writer_->Init()); | 221 EXPECT_TRUE(decoded_frame_writer_->Init()); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 packet_manipulator_.reset(new PacketManipulatorImpl( | 225 packet_manipulator_.reset(new PacketManipulatorImpl( |
| 226 &packet_reader_, config_.networking_config, config_.verbose)); | 226 &packet_reader_, config_.networking_config, config_.verbose)); |
| 227 processor_ = rtc::MakeUnique<VideoProcessor>( | 227 processor_ = rtc::MakeUnique<VideoProcessor>( |
| 228 encoder_, decoder_, analysis_frame_reader_.get(), | 228 encoder_, decoder_, analysis_frame_reader_.get(), |
| 229 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 229 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
| 230 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); | 230 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); |
| 231 processor_->Init(); | 231 processor_->Init(); |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Reset quantities after each encoder update, update the target per-frame | 234 // Reset quantities after each encoder update, update the target per-frame |
| 235 // bandwidth. | 235 // bandwidth. |
| 236 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 236 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
| 237 const int num_temporal_layers = | 237 const int num_temporal_layers = |
| 238 NumberOfTemporalLayers(config_.codec_settings); | 238 NumberOfTemporalLayers(config_.codec_settings); |
| 239 for (int i = 0; i < num_temporal_layers; i++) { | 239 for (int i = 0; i < num_temporal_layers; i++) { |
| 240 num_frames_per_update_[i] = 0; | 240 num_frames_per_update_[i] = 0; |
| 241 sum_frame_size_mismatch_[i] = 0.0f; | 241 sum_frame_size_mismatch_[i] = 0.0f; |
| 242 sum_encoded_frame_size_[i] = 0.0f; | 242 sum_encoded_frame_size_[i] = 0.0f; |
| 243 encoding_bitrate_[i] = 0.0f; | 243 encoding_bitrate_[i] = 0.0f; |
| 244 // Update layer per-frame-bandwidth. | 244 // Update layer per-frame-bandwidth. |
| 245 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / | 245 per_frame_bandwidth_[i] = static_cast<float>(bitrate_layer_[i]) / |
| 246 static_cast<float>(frame_rate_layer_[i]); | 246 static_cast<float>(framerate_layer_[i]); |
| 247 } | 247 } |
| 248 // Set maximum size of key frames, following setting in the VP8 wrapper. | 248 // Set maximum size of key frames, following setting in the VP8 wrapper. |
| 249 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; | 249 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * framerate_; |
| 250 // We don't know exact target size of the key frames (except for first one), | 250 // We don't know exact target size of the key frames (except for first one), |
| 251 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is | 251 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is |
| 252 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average | 252 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average |
| 253 // as reference for mismatch. Note key frames always correspond to base | 253 // as reference for mismatch. Note key frames always correspond to base |
| 254 // layer frame in this test. | 254 // layer frame in this test. |
| 255 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; | 255 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; |
| 256 num_frames_total_ = 0; | 256 num_frames_total_ = 0; |
| 257 sum_encoded_frame_size_total_ = 0.0f; | 257 sum_encoded_frame_size_total_ = 0.0f; |
| 258 encoding_bitrate_total_ = 0.0f; | 258 encoding_bitrate_total_ = 0.0f; |
| 259 perc_encoding_rate_mismatch_ = 0.0f; | 259 perc_encoding_rate_mismatch_ = 0.0f; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 284 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ | 284 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ |
| 285 : target_size_key_frame_; | 285 : target_size_key_frame_; |
| 286 sum_key_frame_size_mismatch_ += | 286 sum_key_frame_size_mismatch_ += |
| 287 fabs(encoded_size_kbits - target_size) / target_size; | 287 fabs(encoded_size_kbits - target_size) / target_size; |
| 288 num_key_frames_ += 1; | 288 num_key_frames_ += 1; |
| 289 } | 289 } |
| 290 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits; | 290 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits; |
| 291 // Encoding bit rate per temporal layer: from the start of the update/run | 291 // Encoding bit rate per temporal layer: from the start of the update/run |
| 292 // to the current frame. | 292 // to the current frame. |
| 293 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] * | 293 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] * |
| 294 frame_rate_layer_[tl_idx] / | 294 framerate_layer_[tl_idx] / |
| 295 num_frames_per_update_[tl_idx]; | 295 num_frames_per_update_[tl_idx]; |
| 296 // Total encoding rate: from the start of the update/run to current frame. | 296 // Total encoding rate: from the start of the update/run to current frame. |
| 297 sum_encoded_frame_size_total_ += encoded_size_kbits; | 297 sum_encoded_frame_size_total_ += encoded_size_kbits; |
| 298 encoding_bitrate_total_ = | 298 encoding_bitrate_total_ = |
| 299 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; | 299 sum_encoded_frame_size_total_ * framerate_ / num_frames_total_; |
| 300 perc_encoding_rate_mismatch_ = | 300 perc_encoding_rate_mismatch_ = |
| 301 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; | 301 100 * fabs(encoding_bitrate_total_ - bitrate_kbps_) / bitrate_kbps_; |
| 302 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 302 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
| 303 !encoding_rate_within_target_) { | 303 !encoding_rate_within_target_) { |
| 304 num_frames_to_hit_target_ = num_frames_total_; | 304 num_frames_to_hit_target_ = num_frames_total_; |
| 305 encoding_rate_within_target_ = true; | 305 encoding_rate_within_target_ = true; |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 | 308 |
| 309 // Verify expected behavior of rate control and print out data. | 309 // Verify expected behavior of rate control and print out data. |
| 310 void VerifyRateControlMetrics(int update_index, | 310 void VerifyRateControlMetrics(int rate_update_index, |
| 311 const RateControlThresholds& rc_expected) { | 311 const RateControlThresholds& rc_expected) { |
| 312 int num_dropped_frames = processor_->NumberDroppedFrames(); | 312 int num_dropped_frames = processor_->NumberDroppedFrames(); |
| 313 int num_resize_actions = processor_->NumberSpatialResizes(); | 313 int num_resize_actions = processor_->NumberSpatialResizes(); |
| 314 printf( | 314 printf( |
| 315 "Rate update #%d:\n" | 315 "Rate update #%d:\n" |
| 316 " Target bitrate : %d\n" | 316 " Target bitrate : %d\n" |
| 317 " Encoded bitrate : %f\n" | 317 " Encoded bitrate : %f\n" |
| 318 " Frame rate : %d\n", | 318 " Frame rate : %d\n", |
| 319 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); | 319 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_); |
| 320 printf( | 320 printf( |
| 321 " # processed frames : %d\n" | 321 " # processed frames : %d\n" |
| 322 " # frames to convergence: %d\n" | 322 " # frames to convergence: %d\n" |
| 323 " # dropped frames : %d\n" | 323 " # dropped frames : %d\n" |
| 324 " # spatial resizes : %d\n", | 324 " # spatial resizes : %d\n", |
| 325 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, | 325 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, |
| 326 num_resize_actions); | 326 num_resize_actions); |
| 327 | |
| 327 EXPECT_LE(perc_encoding_rate_mismatch_, | 328 EXPECT_LE(perc_encoding_rate_mismatch_, |
| 328 rc_expected.max_encoding_rate_mismatch); | 329 rc_expected.max_encoding_rate_mismatch); |
| 329 if (num_key_frames_ > 0) { | 330 if (num_key_frames_ > 0) { |
| 330 int perc_key_frame_size_mismatch = | 331 int perc_key_frame_size_mismatch = |
| 331 100 * sum_key_frame_size_mismatch_ / num_key_frames_; | 332 100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
| 332 printf( | 333 printf( |
| 333 " # key frames : %d\n" | 334 " # key frames : %d\n" |
| 334 " Key frame rate mismatch: %d\n", | 335 " Key frame rate mismatch: %d\n", |
| 335 num_key_frames_, perc_key_frame_size_mismatch); | 336 num_key_frames_, perc_key_frame_size_mismatch); |
| 336 EXPECT_LE(perc_key_frame_size_mismatch, | 337 EXPECT_LE(perc_key_frame_size_mismatch, |
| 337 rc_expected.max_key_frame_size_mismatch); | 338 rc_expected.max_key_frame_size_mismatch); |
| 338 } | 339 } |
| 340 | |
| 339 const int num_temporal_layers = | 341 const int num_temporal_layers = |
| 340 NumberOfTemporalLayers(config_.codec_settings); | 342 NumberOfTemporalLayers(config_.codec_settings); |
| 341 for (int i = 0; i < num_temporal_layers; i++) { | 343 for (int i = 0; i < num_temporal_layers; i++) { |
| 342 printf(" Temporal layer #%d:\n", i); | |
| 343 int perc_frame_size_mismatch = | 344 int perc_frame_size_mismatch = |
| 344 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; | 345 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; |
| 345 int perc_encoding_rate_mismatch = | 346 int perc_encoding_rate_mismatch = |
| 346 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / | 347 100 * fabs(encoding_bitrate_[i] - bitrate_layer_[i]) / |
| 347 bit_rate_layer_[i]; | 348 bitrate_layer_[i]; |
| 348 printf( | 349 printf( |
| 350 " Temporal layer #%d:\n" | |
| 349 " Target layer bitrate : %f\n" | 351 " Target layer bitrate : %f\n" |
| 350 " Layer frame rate : %f\n" | 352 " Layer frame rate : %f\n" |
| 351 " Layer per frame bandwidth : %f\n" | 353 " Layer per frame bandwidth : %f\n" |
| 352 " Layer encoding bitrate : %f\n" | 354 " Layer encoding bitrate : %f\n" |
| 353 " Layer percent frame size mismatch : %d\n" | 355 " Layer percent frame size mismatch : %d\n" |
| 354 " Layer percent encoding rate mismatch: %d\n" | 356 " Layer percent encoding rate mismatch: %d\n" |
| 355 " # frame processed per layer : %d\n", | 357 " # frames processed per layer : %d\n", |
| 356 bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i], | 358 i, bitrate_layer_[i], framerate_layer_[i], per_frame_bandwidth_[i], |
| 357 encoding_bitrate_[i], perc_frame_size_mismatch, | 359 encoding_bitrate_[i], perc_frame_size_mismatch, |
| 358 perc_encoding_rate_mismatch, num_frames_per_update_[i]); | 360 perc_encoding_rate_mismatch, num_frames_per_update_[i]); |
| 359 EXPECT_LE(perc_frame_size_mismatch, | 361 EXPECT_LE(perc_frame_size_mismatch, |
| 360 rc_expected.max_delta_frame_size_mismatch); | 362 rc_expected.max_delta_frame_size_mismatch); |
| 361 EXPECT_LE(perc_encoding_rate_mismatch, | 363 EXPECT_LE(perc_encoding_rate_mismatch, |
| 362 rc_expected.max_encoding_rate_mismatch); | 364 rc_expected.max_encoding_rate_mismatch); |
| 363 } | 365 } |
| 364 printf("\n"); | 366 printf("\n"); |
| 367 | |
| 365 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 368 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); |
| 366 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); | 369 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
| 367 if (rc_expected.num_spatial_resizes >= 0) { | 370 if (rc_expected.num_spatial_resizes >= 0) { |
| 368 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 371 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
| 369 } | 372 } |
| 370 if (rc_expected.num_key_frames >= 0) { | 373 if (rc_expected.num_key_frames >= 0) { |
| 371 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 374 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
| 372 } | 375 } |
| 373 } | 376 } |
| 374 | 377 |
| 375 void VerifyQuality(const QualityMetricsResult& psnr_result, | 378 static void VerifyQuality(const QualityMetricsResult& psnr_result, |
| 376 const QualityMetricsResult& ssim_result, | 379 const QualityMetricsResult& ssim_result, |
| 377 const QualityThresholds& quality_thresholds) { | 380 const QualityThresholds& quality_thresholds) { |
| 378 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 381 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
| 379 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 382 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
| 380 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 383 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
| 381 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 384 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
| 382 } | 385 } |
| 383 | 386 |
| 384 void VerifyQpParser(int frame_number) { | 387 void VerifyQpParser(int frame_number) { |
| 385 if (!config_.hw_codec && | 388 if (!config_.hw_codec && |
| 386 (config_.codec_settings.codecType == kVideoCodecVP8 || | 389 (config_.codec_settings.codecType == kVideoCodecVP8 || |
| 387 config_.codec_settings.codecType == kVideoCodecVP9)) { | 390 config_.codec_settings.codecType == kVideoCodecVP9)) { |
| 388 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), | 391 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), |
| 389 processor_->GetQpFromBitstream(frame_number)); | 392 processor_->GetQpFromBitstream(frame_number)); |
| 390 } | 393 } |
| 391 } | 394 } |
| 392 | 395 |
| 393 int NumberOfTemporalLayers(const VideoCodec& codec_settings) { | 396 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) { |
| 394 if (codec_settings.codecType == kVideoCodecVP8) { | 397 if (codec_settings.codecType == kVideoCodecVP8) { |
| 395 return codec_settings.VP8().numberOfTemporalLayers; | 398 return codec_settings.VP8().numberOfTemporalLayers; |
| 396 } else if (codec_settings.codecType == kVideoCodecVP9) { | 399 } else if (codec_settings.codecType == kVideoCodecVP9) { |
| 397 return codec_settings.VP9().numberOfTemporalLayers; | 400 return codec_settings.VP9().numberOfTemporalLayers; |
| 398 } else { | 401 } else { |
| 399 return 1; | 402 return 1; |
| 400 } | 403 } |
| 401 } | 404 } |
| 402 | 405 |
| 403 // Temporal layer index corresponding to frame number, for up to 3 layers. | 406 // Temporal layer index corresponding to frame number, for up to 3 layers. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 void SetTemporalLayerRates() { | 440 void SetTemporalLayerRates() { |
| 438 const int num_temporal_layers = | 441 const int num_temporal_layers = |
| 439 NumberOfTemporalLayers(config_.codec_settings); | 442 NumberOfTemporalLayers(config_.codec_settings); |
| 440 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); | 443 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); |
| 441 for (int i = 0; i < num_temporal_layers; i++) { | 444 for (int i = 0; i < num_temporal_layers; i++) { |
| 442 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; | 445 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; |
| 443 if (i > 0) { | 446 if (i > 0) { |
| 444 float bit_rate_delta_ratio = | 447 float bit_rate_delta_ratio = |
| 445 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - | 448 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - |
| 446 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; | 449 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; |
| 447 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; | 450 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio; |
| 448 } else { | 451 } else { |
| 449 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; | 452 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio; |
| 450 } | 453 } |
| 451 frame_rate_layer_[i] = | 454 framerate_layer_[i] = |
| 452 frame_rate_ / static_cast<float>(1 << (num_temporal_layers - 1)); | 455 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1)); |
| 453 } | 456 } |
| 454 if (num_temporal_layers == 3) { | 457 if (num_temporal_layers == 3) { |
| 455 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 458 framerate_layer_[2] = framerate_ / 2.0f; |
| 456 } | 459 } |
| 457 } | 460 } |
| 458 | 461 |
| 459 // Processes all frames in the clip and verifies the result. | 462 // Processes all frames in the clip and verifies the result. |
| 460 // TODO(brandtr): Change the second last argument to be a | 463 // TODO(brandtr): Change the second last argument to be a |
| 461 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 464 // const std::vector<RateControlThresholds>&, so we can ensure that the user |
| 462 // does not expect us to do mid-clip rate updates when we are not able to, | 465 // does not expect us to do mid-clip rate updates when we are not able to, |
| 463 // e.g., when we are operating in batch mode. | 466 // e.g., when we are operating in batch mode. |
| 464 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, | 467 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, |
| 465 const RateProfile& rate_profile, | 468 const RateProfile& rate_profile, |
| 466 RateControlThresholds* rc_thresholds, | 469 RateControlThresholds* rc_thresholds, |
| 467 const VisualizationParams* visualization_params) { | 470 const VisualizationParams* visualization_params) { |
| 468 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; | 471 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; |
| 469 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], | 472 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], |
| 470 rate_profile.input_frame_rate[0]); | 473 rate_profile.input_frame_rate[0]); |
| 471 | 474 |
| 472 // Set initial rates. | 475 // Set initial rates. |
| 473 bit_rate_ = rate_profile.target_bit_rate[0]; | 476 bitrate_kbps_ = rate_profile.target_bit_rate[0]; |
| 474 frame_rate_ = rate_profile.input_frame_rate[0]; | 477 framerate_ = rate_profile.input_frame_rate[0]; |
| 475 SetTemporalLayerRates(); | 478 SetTemporalLayerRates(); |
| 476 // Set the initial target size for key frame. | 479 // Set the initial target size for key frame. |
| 477 target_size_key_frame_initial_ = | 480 target_size_key_frame_initial_ = |
| 478 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 481 0.5 * kInitialBufferSize * bitrate_layer_[0]; |
| 479 processor_->SetRates(bit_rate_, frame_rate_); | 482 processor_->SetRates(bitrate_kbps_, framerate_); |
| 480 | 483 |
| 481 // Process each frame, up to |num_frames|. | 484 // Process each frame, up to |num_frames|. |
| 482 int frame_number = 0; | 485 int frame_number = 0; |
| 483 int update_index = 0; | 486 int update_index = 0; |
| 484 int num_frames = rate_profile.num_frames; | 487 int num_frames = rate_profile.num_frames; |
| 485 ResetRateControlMetrics( | 488 ResetRateControlMetrics( |
| 486 rate_profile.frame_index_rate_update[update_index + 1]); | 489 rate_profile.frame_index_rate_update[update_index + 1]); |
| 487 | 490 |
| 488 if (config_.batch_mode) { | 491 if (config_.batch_mode) { |
| 489 // In batch mode, we calculate the metrics for all frames after all frames | 492 // In batch mode, we calculate the metrics for all frames after all frames |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 ++frame_number; | 524 ++frame_number; |
| 522 | 525 |
| 523 // If we hit another/next update, verify stats for current state and | 526 // If we hit another/next update, verify stats for current state and |
| 524 // update layers and codec with new rates. | 527 // update layers and codec with new rates. |
| 525 if (frame_number == | 528 if (frame_number == |
| 526 rate_profile.frame_index_rate_update[update_index + 1]) { | 529 rate_profile.frame_index_rate_update[update_index + 1]) { |
| 527 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 530 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| 528 | 531 |
| 529 // Update layer rates and the codec with new rates. | 532 // Update layer rates and the codec with new rates. |
| 530 ++update_index; | 533 ++update_index; |
| 531 bit_rate_ = rate_profile.target_bit_rate[update_index]; | 534 bitrate_kbps_ = rate_profile.target_bit_rate[update_index]; |
| 532 frame_rate_ = rate_profile.input_frame_rate[update_index]; | 535 framerate_ = rate_profile.input_frame_rate[update_index]; |
| 533 SetTemporalLayerRates(); | 536 SetTemporalLayerRates(); |
| 534 ResetRateControlMetrics( | 537 ResetRateControlMetrics( |
| 535 rate_profile.frame_index_rate_update[update_index + 1]); | 538 rate_profile.frame_index_rate_update[update_index + 1]); |
| 536 processor_->SetRates(bit_rate_, frame_rate_); | 539 processor_->SetRates(bitrate_kbps_, framerate_); |
| 537 } | 540 } |
| 538 } | 541 } |
| 539 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 542 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
| 540 // call ProcessFrame one extra time here. | 543 // call ProcessFrame one extra time here. |
| 541 processor_->ProcessFrame(frame_number); | 544 processor_->ProcessFrame(frame_number); |
| 542 } | 545 } |
| 543 | 546 |
| 544 // Verify rate control metrics for all frames (if in batch mode), or for all | 547 // Verify rate control metrics for all frames (if in batch mode), or for all |
| 545 // frames since the last rate update (if not in batch mode). | 548 // frames since the last rate update (if not in batch mode). |
| 546 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 549 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 default: | 646 default: |
| 644 RTC_NOTREACHED(); | 647 RTC_NOTREACHED(); |
| 645 break; | 648 break; |
| 646 } | 649 } |
| 647 | 650 |
| 648 config->frame_length_in_bytes = | 651 config->frame_length_in_bytes = |
| 649 CalcBufferSize(VideoType::kI420, width, height); | 652 CalcBufferSize(VideoType::kI420, width, height); |
| 650 } | 653 } |
| 651 | 654 |
| 652 static void SetRateProfile(RateProfile* rate_profile, | 655 static void SetRateProfile(RateProfile* rate_profile, |
| 653 int update_index, | 656 int rate_update_index, |
| 654 int bit_rate, | 657 int bit_rate_kbps, |
|
åsapersson
2017/08/21 07:30:07
maybe bitrate_kbps
brandtr
2017/08/21 07:57:43
Done.
| |
| 655 int frame_rate, | 658 int frame_rate_fps, |
|
åsapersson
2017/08/21 07:30:07
and framerate_fps
brandtr
2017/08/21 07:57:43
Done.
| |
| 656 int frame_index_rate_update) { | 659 int frame_index_rate_update) { |
| 657 rate_profile->target_bit_rate[update_index] = bit_rate; | 660 rate_profile->target_bit_rate[rate_update_index] = bit_rate_kbps; |
| 658 rate_profile->input_frame_rate[update_index] = frame_rate; | 661 rate_profile->input_frame_rate[rate_update_index] = frame_rate_fps; |
| 659 rate_profile->frame_index_rate_update[update_index] = | 662 rate_profile->frame_index_rate_update[rate_update_index] = |
| 660 frame_index_rate_update; | 663 frame_index_rate_update; |
| 661 } | 664 } |
| 662 | 665 |
| 663 static void SetRateControlThresholds(RateControlThresholds* rc_thresholds, | 666 static void SetRateControlThresholds(RateControlThresholds* rc_thresholds, |
| 664 int update_index, | 667 int update_index, |
| 665 int max_num_dropped_frames, | 668 int max_num_dropped_frames, |
| 666 int max_key_frame_size_mismatch, | 669 int max_key_frame_size_mismatch, |
| 667 int max_delta_frame_size_mismatch, | 670 int max_delta_frame_size_mismatch, |
| 668 int max_encoding_rate_mismatch, | 671 int max_encoding_rate_mismatch, |
| 669 int max_time_hit_target, | 672 int max_time_hit_target, |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 699 std::unique_ptr<PacketManipulator> packet_manipulator_; | 702 std::unique_ptr<PacketManipulator> packet_manipulator_; |
| 700 Stats stats_; | 703 Stats stats_; |
| 701 std::unique_ptr<VideoProcessor> processor_; | 704 std::unique_ptr<VideoProcessor> processor_; |
| 702 | 705 |
| 703 // Quantities defined/updated for every encoder rate update. | 706 // Quantities defined/updated for every encoder rate update. |
| 704 int num_frames_per_update_[kMaxNumTemporalLayers]; | 707 int num_frames_per_update_[kMaxNumTemporalLayers]; |
| 705 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; | 708 float sum_frame_size_mismatch_[kMaxNumTemporalLayers]; |
| 706 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; | 709 float sum_encoded_frame_size_[kMaxNumTemporalLayers]; |
| 707 float encoding_bitrate_[kMaxNumTemporalLayers]; | 710 float encoding_bitrate_[kMaxNumTemporalLayers]; |
| 708 float per_frame_bandwidth_[kMaxNumTemporalLayers]; | 711 float per_frame_bandwidth_[kMaxNumTemporalLayers]; |
| 709 float bit_rate_layer_[kMaxNumTemporalLayers]; | 712 float bitrate_layer_[kMaxNumTemporalLayers]; |
| 710 float frame_rate_layer_[kMaxNumTemporalLayers]; | 713 float framerate_layer_[kMaxNumTemporalLayers]; |
| 711 int num_frames_total_; | 714 int num_frames_total_; |
| 712 float sum_encoded_frame_size_total_; | 715 float sum_encoded_frame_size_total_; |
| 713 float encoding_bitrate_total_; | 716 float encoding_bitrate_total_; |
| 714 float perc_encoding_rate_mismatch_; | 717 float perc_encoding_rate_mismatch_; |
| 715 int num_frames_to_hit_target_; | 718 int num_frames_to_hit_target_; |
| 716 bool encoding_rate_within_target_; | 719 bool encoding_rate_within_target_; |
| 717 int bit_rate_; | 720 int bitrate_kbps_; |
| 718 int frame_rate_; | 721 int framerate_; |
| 719 float target_size_key_frame_initial_; | 722 float target_size_key_frame_initial_; |
| 720 float target_size_key_frame_; | 723 float target_size_key_frame_; |
| 721 float sum_key_frame_size_mismatch_; | 724 float sum_key_frame_size_mismatch_; |
| 722 int num_key_frames_; | 725 int num_key_frames_; |
| 723 }; | 726 }; |
| 724 | 727 |
| 725 } // namespace test | 728 } // namespace test |
| 726 } // namespace webrtc | 729 } // namespace webrtc |
| 727 | 730 |
| 728 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ | 731 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ |
| OLD | NEW |