| 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 10 matching lines...) Expand all Loading... |
| 21 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" | 21 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" |
| 22 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" | 22 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
| 23 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" | 23 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" |
| 24 #elif defined(WEBRTC_IOS) | 24 #elif defined(WEBRTC_IOS) |
| 25 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h" | 25 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h" |
| 26 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" | 26 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 #include "webrtc/base/checks.h" | 29 #include "webrtc/base/checks.h" |
| 30 #include "webrtc/base/file.h" | 30 #include "webrtc/base/file.h" |
| 31 #include "webrtc/base/logging.h" |
| 31 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" | 32 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
| 32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
| 33 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 34 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
| 34 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 35 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
| 35 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 36 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
| 36 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 37 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
| 37 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 38 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
| 38 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 39 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
| 39 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 40 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 40 #include "webrtc/modules/video_coding/include/video_coding.h" | 41 #include "webrtc/modules/video_coding/include/video_coding.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 int key_frame_interval; | 78 int key_frame_interval; |
| 78 bool error_concealment_on; | 79 bool error_concealment_on; |
| 79 bool denoising_on; | 80 bool denoising_on; |
| 80 bool frame_dropper_on; | 81 bool frame_dropper_on; |
| 81 bool spatial_resize_on; | 82 bool spatial_resize_on; |
| 82 | 83 |
| 83 float packet_loss_probability; // [0.0, 1.0]. | 84 float packet_loss_probability; // [0.0, 1.0]. |
| 84 | 85 |
| 85 std::string filename; | 86 std::string filename; |
| 86 bool verbose_logging; | 87 bool verbose_logging; |
| 88 |
| 89 // In batch mode, the VideoProcessor is fed all the frames for processing |
| 90 // before any metrics are calculated. This is useful for pipelining HW codecs, |
| 91 // for which some calculated metrics otherwise would be incorrect. The |
| 92 // downside with batch mode is that mid-test rate allocation is not supported. |
| 93 bool batch_mode; |
| 87 }; | 94 }; |
| 88 | 95 |
| 89 // Thresholds for the quality metrics. | 96 // Thresholds for the quality metrics. |
| 90 struct QualityThresholds { | 97 struct QualityThresholds { |
| 91 double min_avg_psnr; | 98 double min_avg_psnr; |
| 92 double min_min_psnr; | 99 double min_min_psnr; |
| 93 double min_avg_ssim; | 100 double min_avg_ssim; |
| 94 double min_min_ssim; | 101 double min_min_ssim; |
| 95 }; | 102 }; |
| 96 | 103 |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 processor_.reset(new test::VideoProcessorImpl( | 342 processor_.reset(new test::VideoProcessorImpl( |
| 336 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 343 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), |
| 337 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 344 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
| 338 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), | 345 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), |
| 339 decoded_frame_writer_.get())); | 346 decoded_frame_writer_.get())); |
| 340 RTC_CHECK(processor_->Init()); | 347 RTC_CHECK(processor_->Init()); |
| 341 } | 348 } |
| 342 | 349 |
| 343 // Reset quantities after each encoder update, update the target | 350 // Reset quantities after each encoder update, update the target |
| 344 // per-frame bandwidth. | 351 // per-frame bandwidth. |
| 345 void ResetRateControlMetrics(int num_frames) { | 352 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
| 346 for (int i = 0; i < num_temporal_layers_; i++) { | 353 for (int i = 0; i < num_temporal_layers_; i++) { |
| 347 num_frames_per_update_[i] = 0; | 354 num_frames_per_update_[i] = 0; |
| 348 sum_frame_size_mismatch_[i] = 0.0f; | 355 sum_frame_size_mismatch_[i] = 0.0f; |
| 349 sum_encoded_frame_size_[i] = 0.0f; | 356 sum_encoded_frame_size_[i] = 0.0f; |
| 350 encoding_bitrate_[i] = 0.0f; | 357 encoding_bitrate_[i] = 0.0f; |
| 351 // Update layer per-frame-bandwidth. | 358 // Update layer per-frame-bandwidth. |
| 352 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / | 359 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) / |
| 353 static_cast<float>(frame_rate_layer_[i]); | 360 static_cast<float>(frame_rate_layer_[i]); |
| 354 } | 361 } |
| 355 // Set maximum size of key frames, following setting in the VP8 wrapper. | 362 // Set maximum size of key frames, following setting in the VP8 wrapper. |
| 356 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; | 363 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_; |
| 357 // We don't know exact target size of the key frames (except for first one), | 364 // We don't know exact target size of the key frames (except for first one), |
| 358 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is | 365 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is |
| 359 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average | 366 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average |
| 360 // as reference for mismatch. Note key frames always correspond to base | 367 // as reference for mismatch. Note key frames always correspond to base |
| 361 // layer frame in this test. | 368 // layer frame in this test. |
| 362 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; | 369 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0]; |
| 363 num_frames_total_ = 0; | 370 num_frames_total_ = 0; |
| 364 sum_encoded_frame_size_total_ = 0.0f; | 371 sum_encoded_frame_size_total_ = 0.0f; |
| 365 encoding_bitrate_total_ = 0.0f; | 372 encoding_bitrate_total_ = 0.0f; |
| 366 perc_encoding_rate_mismatch_ = 0.0f; | 373 perc_encoding_rate_mismatch_ = 0.0f; |
| 367 num_frames_to_hit_target_ = num_frames; | 374 num_frames_to_hit_target_ = num_frames_to_hit_target; |
| 368 encoding_rate_within_target_ = false; | 375 encoding_rate_within_target_ = false; |
| 369 sum_key_frame_size_mismatch_ = 0.0; | 376 sum_key_frame_size_mismatch_ = 0.0; |
| 370 num_key_frames_ = 0; | 377 num_key_frames_ = 0; |
| 371 } | 378 } |
| 372 | 379 |
| 373 // For every encoded frame, update the rate control metrics. | 380 // For every encoded frame, update the rate control metrics. |
| 374 void UpdateRateControlMetrics(int frame_num, FrameType frame_type) { | 381 void UpdateRateControlMetrics(int frame_number) { |
| 375 float encoded_size_kbits = processor_->EncodedFrameSize() * 8.0f / 1000.0f; | 382 RTC_CHECK_GE(frame_number, 0); |
| 383 int tl_idx = TemporalLayerIndexForFrame(frame_number); |
| 384 FrameType frame_type = processor_->EncodedFrameType(frame_number); |
| 385 float encoded_size_kbits = |
| 386 processor_->EncodedFrameSize(frame_number) * 8.0f / 1000.0f; |
| 387 |
| 376 // Update layer data. | 388 // Update layer data. |
| 377 // Update rate mismatch relative to per-frame bandwidth for delta frames. | 389 // Update rate mismatch relative to per-frame bandwidth for delta frames. |
| 378 if (frame_type == kVideoFrameDelta) { | 390 if (frame_type == kVideoFrameDelta) { |
| 379 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? | 391 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? |
| 380 sum_frame_size_mismatch_[layer_] += | 392 sum_frame_size_mismatch_[tl_idx] += |
| 381 fabs(encoded_size_kbits - per_frame_bandwidth_[layer_]) / | 393 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / |
| 382 per_frame_bandwidth_[layer_]; | 394 per_frame_bandwidth_[tl_idx]; |
| 383 } else { | 395 } else { |
| 384 float target_size = (frame_num == 1) ? target_size_key_frame_initial_ | 396 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ |
| 385 : target_size_key_frame_; | 397 : target_size_key_frame_; |
| 386 sum_key_frame_size_mismatch_ += | 398 sum_key_frame_size_mismatch_ += |
| 387 fabs(encoded_size_kbits - target_size) / target_size; | 399 fabs(encoded_size_kbits - target_size) / target_size; |
| 388 num_key_frames_ += 1; | 400 num_key_frames_ += 1; |
| 389 } | 401 } |
| 390 sum_encoded_frame_size_[layer_] += encoded_size_kbits; | 402 sum_encoded_frame_size_[tl_idx] += encoded_size_kbits; |
| 391 // Encoding bitrate per layer: from the start of the update/run to the | 403 // Encoding bit rate per temporal layer: from the start of the update/run |
| 392 // current frame. | 404 // to the current frame. |
| 393 encoding_bitrate_[layer_] = sum_encoded_frame_size_[layer_] * | 405 encoding_bitrate_[tl_idx] = sum_encoded_frame_size_[tl_idx] * |
| 394 frame_rate_layer_[layer_] / | 406 frame_rate_layer_[tl_idx] / |
| 395 num_frames_per_update_[layer_]; | 407 num_frames_per_update_[tl_idx]; |
| 396 // Total encoding rate: from the start of the update/run to current frame. | 408 // Total encoding rate: from the start of the update/run to current frame. |
| 397 sum_encoded_frame_size_total_ += encoded_size_kbits; | 409 sum_encoded_frame_size_total_ += encoded_size_kbits; |
| 398 encoding_bitrate_total_ = | 410 encoding_bitrate_total_ = |
| 399 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; | 411 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; |
| 400 perc_encoding_rate_mismatch_ = | 412 perc_encoding_rate_mismatch_ = |
| 401 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; | 413 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; |
| 402 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 414 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
| 403 !encoding_rate_within_target_) { | 415 !encoding_rate_within_target_) { |
| 404 num_frames_to_hit_target_ = num_frames_total_; | 416 num_frames_to_hit_target_ = num_frames_total_; |
| 405 encoding_rate_within_target_ = true; | 417 encoding_rate_within_target_ = true; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 | 480 |
| 469 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 481 void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
| 470 const test::QualityMetricsResult& ssim_result, | 482 const test::QualityMetricsResult& ssim_result, |
| 471 const QualityThresholds& quality_thresholds) { | 483 const QualityThresholds& quality_thresholds) { |
| 472 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 484 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
| 473 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 485 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
| 474 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 486 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
| 475 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 487 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
| 476 } | 488 } |
| 477 | 489 |
| 478 // Layer index corresponding to frame number, for up to 3 layers. | 490 // Temporal layer index corresponding to frame number, for up to 3 layers. |
| 479 int LayerIndexForFrame(int frame_number) { | 491 int TemporalLayerIndexForFrame(int frame_number) { |
| 480 int layer = -1; | 492 int tl_idx = -1; |
| 481 switch (num_temporal_layers_) { | 493 switch (num_temporal_layers_) { |
| 482 case 1: | 494 case 1: |
| 483 layer = 0; | 495 tl_idx = 0; |
| 484 break; | 496 break; |
| 485 case 2: | 497 case 2: |
| 486 // layer 0: 0 2 4 ... | 498 // temporal layer 0: 0 2 4 ... |
| 487 // layer 1: 1 3 | 499 // temporal layer 1: 1 3 |
| 488 layer = (frame_number % 2 == 0) ? 0 : 1; | 500 tl_idx = (frame_number % 2 == 0) ? 0 : 1; |
| 489 break; | 501 break; |
| 490 case 3: | 502 case 3: |
| 491 // layer 0: 0 4 8 ... | 503 // temporal layer 0: 0 4 8 ... |
| 492 // layer 1: 2 6 | 504 // temporal layer 1: 2 6 |
| 493 // layer 2: 1 3 5 7 | 505 // temporal layer 2: 1 3 5 7 |
| 494 if (frame_number % 4 == 0) { | 506 if (frame_number % 4 == 0) { |
| 495 layer = 0; | 507 tl_idx = 0; |
| 496 } else if ((frame_number + 2) % 4 == 0) { | 508 } else if ((frame_number + 2) % 4 == 0) { |
| 497 layer = 1; | 509 tl_idx = 1; |
| 498 } else if ((frame_number + 1) % 2 == 0) { | 510 } else if ((frame_number + 1) % 2 == 0) { |
| 499 layer = 2; | 511 tl_idx = 2; |
| 500 } | 512 } |
| 501 break; | 513 break; |
| 502 default: | 514 default: |
| 503 RTC_NOTREACHED(); | 515 RTC_NOTREACHED(); |
| 504 break; | 516 break; |
| 505 } | 517 } |
| 506 | 518 return tl_idx; |
| 507 return layer; | |
| 508 } | 519 } |
| 509 | 520 |
| 510 // Set the bitrate and frame rate per layer, for up to 3 layers. | 521 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. |
| 511 void SetLayerRates() { | 522 void SetTemporalLayerRates() { |
| 512 RTC_DCHECK_LE(num_temporal_layers_, kMaxNumTemporalLayers); | 523 RTC_DCHECK_LE(num_temporal_layers_, kMaxNumTemporalLayers); |
| 513 for (int i = 0; i < num_temporal_layers_; i++) { | 524 for (int i = 0; i < num_temporal_layers_; i++) { |
| 514 float bit_rate_ratio = | 525 float bit_rate_ratio = |
| 515 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; | 526 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i]; |
| 516 if (i > 0) { | 527 if (i > 0) { |
| 517 float bit_rate_delta_ratio = | 528 float bit_rate_delta_ratio = |
| 518 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i] - | 529 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i] - |
| 519 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1]; | 530 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1]; |
| 520 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; | 531 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio; |
| 521 } else { | 532 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 534 RateProfile rate_profile, | 545 RateProfile rate_profile, |
| 535 CodecParams process, | 546 CodecParams process, |
| 536 RateControlThresholds* rc_thresholds, | 547 RateControlThresholds* rc_thresholds, |
| 537 const VisualizationParams* visualization_params) { | 548 const VisualizationParams* visualization_params) { |
| 538 // Codec/config settings. | 549 // Codec/config settings. |
| 539 start_bitrate_ = rate_profile.target_bit_rate[0]; | 550 start_bitrate_ = rate_profile.target_bit_rate[0]; |
| 540 start_frame_rate_ = rate_profile.input_frame_rate[0]; | 551 start_frame_rate_ = rate_profile.input_frame_rate[0]; |
| 541 packet_loss_probability_ = process.packet_loss_probability; | 552 packet_loss_probability_ = process.packet_loss_probability; |
| 542 num_temporal_layers_ = process.num_temporal_layers; | 553 num_temporal_layers_ = process.num_temporal_layers; |
| 543 SetUpCodecConfig(process, visualization_params); | 554 SetUpCodecConfig(process, visualization_params); |
| 544 // Update the layers and the codec with the initial rates. | 555 // Update the temporal layers and the codec with the initial rates. |
| 545 bit_rate_ = rate_profile.target_bit_rate[0]; | 556 bit_rate_ = rate_profile.target_bit_rate[0]; |
| 546 frame_rate_ = rate_profile.input_frame_rate[0]; | 557 frame_rate_ = rate_profile.input_frame_rate[0]; |
| 547 SetLayerRates(); | 558 SetTemporalLayerRates(); |
| 548 // Set the initial target size for key frame. | 559 // Set the initial target size for key frame. |
| 549 target_size_key_frame_initial_ = | 560 target_size_key_frame_initial_ = |
| 550 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 561 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
| 551 processor_->SetRates(bit_rate_, frame_rate_); | 562 processor_->SetRates(bit_rate_, frame_rate_); |
| 552 | 563 |
| 553 // Process each frame, up to |num_frames|. | 564 // Process each frame, up to |num_frames|. |
| 565 int frame_number = 0; |
| 566 int update_index = 0; |
| 554 int num_frames = rate_profile.num_frames; | 567 int num_frames = rate_profile.num_frames; |
| 555 int update_index = 0; | |
| 556 ResetRateControlMetrics( | 568 ResetRateControlMetrics( |
| 557 rate_profile.frame_index_rate_update[update_index + 1]); | 569 rate_profile.frame_index_rate_update[update_index + 1]); |
| 558 int frame_number = 0; | 570 |
| 559 FrameType frame_type = kVideoFrameDelta; | 571 if (process.batch_mode) { |
| 560 while (processor_->ProcessFrame(frame_number) && | 572 // In batch mode, we calculate the metrics for all frames after all frames |
| 561 frame_number < num_frames) { | 573 // have been sent for encoding. |
| 562 // Get the layer index for the frame |frame_number|. | 574 |
| 563 layer_ = LayerIndexForFrame(frame_number); | 575 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
| 564 // Get the frame_type. | 576 // call ProcessFrame num_frames+1 times here. |
| 565 frame_type = processor_->EncodedFrameType(); | 577 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
| 566 // Counter for whole sequence run. | 578 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 567 ++frame_number; | |
| 568 // Counters for each rate update. | |
| 569 ++num_frames_per_update_[layer_]; | |
| 570 ++num_frames_total_; | |
| 571 UpdateRateControlMetrics(frame_number, frame_type); | |
| 572 // If we hit another/next update, verify stats for current state and | |
| 573 // update layers and codec with new rates. | |
| 574 if (frame_number == | |
| 575 rate_profile.frame_index_rate_update[update_index + 1]) { | |
| 576 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | |
| 577 // Update layer rates and the codec with new rates. | |
| 578 ++update_index; | |
| 579 bit_rate_ = rate_profile.target_bit_rate[update_index]; | |
| 580 frame_rate_ = rate_profile.input_frame_rate[update_index]; | |
| 581 SetLayerRates(); | |
| 582 ResetRateControlMetrics( | |
| 583 rate_profile.frame_index_rate_update[update_index + 1]); | |
| 584 processor_->SetRates(bit_rate_, frame_rate_); | |
| 585 } | 579 } |
| 580 |
| 581 for (frame_number = 0; frame_number < num_frames; ++frame_number) { |
| 582 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
| 583 ++num_frames_total_; |
| 584 UpdateRateControlMetrics(frame_number); |
| 585 } |
| 586 } else { |
| 587 // In online mode, we calculate the metrics for a given frame right after |
| 588 // it has been sent for encoding. |
| 589 |
| 590 if (process.hw_codec) { |
| 591 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
| 592 "since they may be pipelining."; |
| 593 } |
| 594 |
| 595 while (frame_number < num_frames) { |
| 596 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 597 |
| 598 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
| 599 ++num_frames_total_; |
| 600 UpdateRateControlMetrics(frame_number); |
| 601 |
| 602 ++frame_number; |
| 603 |
| 604 // If we hit another/next update, verify stats for current state and |
| 605 // update layers and codec with new rates. |
| 606 if (frame_number == |
| 607 rate_profile.frame_index_rate_update[update_index + 1]) { |
| 608 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| 609 |
| 610 // Update layer rates and the codec with new rates. |
| 611 ++update_index; |
| 612 bit_rate_ = rate_profile.target_bit_rate[update_index]; |
| 613 frame_rate_ = rate_profile.input_frame_rate[update_index]; |
| 614 SetTemporalLayerRates(); |
| 615 ResetRateControlMetrics( |
| 616 rate_profile.frame_index_rate_update[update_index + 1]); |
| 617 processor_->SetRates(bit_rate_, frame_rate_); |
| 618 } |
| 619 } |
| 620 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
| 621 // call ProcessFrame one extra time here. |
| 622 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 586 } | 623 } |
| 624 |
| 625 // Verify rate control metrics for all frames (if in batch mode), or for all |
| 626 // frames since the last rate update (if not in batch mode). |
| 587 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 627 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
| 588 EXPECT_EQ(num_frames, frame_number); | 628 EXPECT_EQ(num_frames, frame_number); |
| 589 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 629 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
| 590 | 630 |
| 591 // Release encoder and decoder to make sure they have finished processing: | 631 // Release encoder and decoder to make sure they have finished processing. |
| 592 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 632 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
| 593 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 633 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); |
| 594 | 634 |
| 595 // Close the analysis files before we use them for SSIM/PSNR calculations. | 635 // Close the analysis files before we use them for SSIM/PSNR calculations. |
| 596 analysis_frame_reader_->Close(); | 636 analysis_frame_reader_->Close(); |
| 597 analysis_frame_writer_->Close(); | 637 analysis_frame_writer_->Close(); |
| 598 | 638 |
| 599 // Close visualization files. | 639 // Close visualization files. |
| 600 if (source_frame_writer_) { | 640 if (source_frame_writer_) { |
| 601 source_frame_writer_->Close(); | 641 source_frame_writer_->Close(); |
| 602 } | 642 } |
| 603 if (encoded_frame_writer_) { | 643 if (encoded_frame_writer_) { |
| 604 encoded_frame_writer_->Close(); | 644 EXPECT_TRUE(encoded_frame_writer_->Close()); |
| 605 } | 645 } |
| 606 if (decoded_frame_writer_) { | 646 if (decoded_frame_writer_) { |
| 607 decoded_frame_writer_->Close(); | 647 decoded_frame_writer_->Close(); |
| 608 } | 648 } |
| 609 | 649 |
| 610 // TODO(marpan): Should compute these quality metrics per SetRates update. | 650 // TODO(marpan): Should compute these quality metrics per SetRates update. |
| 611 test::QualityMetricsResult psnr_result, ssim_result; | 651 test::QualityMetricsResult psnr_result, ssim_result; |
| 612 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), | 652 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), |
| 613 config_.output_filename.c_str(), | 653 config_.output_filename.c_str(), |
| 614 config_.codec_settings->width, | 654 config_.codec_settings->width, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 633 float packet_loss_probability, | 673 float packet_loss_probability, |
| 634 int key_frame_interval, | 674 int key_frame_interval, |
| 635 int num_temporal_layers, | 675 int num_temporal_layers, |
| 636 bool error_concealment_on, | 676 bool error_concealment_on, |
| 637 bool denoising_on, | 677 bool denoising_on, |
| 638 bool frame_dropper_on, | 678 bool frame_dropper_on, |
| 639 bool spatial_resize_on, | 679 bool spatial_resize_on, |
| 640 int width, | 680 int width, |
| 641 int height, | 681 int height, |
| 642 const std::string& filename, | 682 const std::string& filename, |
| 643 bool verbose_logging) { | 683 bool verbose_logging, |
| 684 bool batch_mode) { |
| 644 process_settings->codec_type = codec_type; | 685 process_settings->codec_type = codec_type; |
| 645 process_settings->hw_codec = hw_codec; | 686 process_settings->hw_codec = hw_codec; |
| 646 process_settings->use_single_core = use_single_core; | 687 process_settings->use_single_core = use_single_core; |
| 647 process_settings->packet_loss_probability = packet_loss_probability; | 688 process_settings->packet_loss_probability = packet_loss_probability; |
| 648 process_settings->key_frame_interval = key_frame_interval; | 689 process_settings->key_frame_interval = key_frame_interval; |
| 649 process_settings->num_temporal_layers = num_temporal_layers, | 690 process_settings->num_temporal_layers = num_temporal_layers, |
| 650 process_settings->error_concealment_on = error_concealment_on; | 691 process_settings->error_concealment_on = error_concealment_on; |
| 651 process_settings->denoising_on = denoising_on; | 692 process_settings->denoising_on = denoising_on; |
| 652 process_settings->frame_dropper_on = frame_dropper_on; | 693 process_settings->frame_dropper_on = frame_dropper_on; |
| 653 process_settings->spatial_resize_on = spatial_resize_on; | 694 process_settings->spatial_resize_on = spatial_resize_on; |
| 654 process_settings->width = width; | 695 process_settings->width = width; |
| 655 process_settings->height = height; | 696 process_settings->height = height; |
| 656 process_settings->filename = filename; | 697 process_settings->filename = filename; |
| 657 process_settings->verbose_logging = verbose_logging; | 698 process_settings->verbose_logging = verbose_logging; |
| 699 process_settings->batch_mode = batch_mode; |
| 658 } | 700 } |
| 659 | 701 |
| 660 static void SetCodecParams(CodecParams* process_settings, | 702 static void SetCodecParams(CodecParams* process_settings, |
| 661 VideoCodecType codec_type, | 703 VideoCodecType codec_type, |
| 662 bool hw_codec, | 704 bool hw_codec, |
| 663 bool use_single_core, | 705 bool use_single_core, |
| 664 float packet_loss_probability, | 706 float packet_loss_probability, |
| 665 int key_frame_interval, | 707 int key_frame_interval, |
| 666 int num_temporal_layers, | 708 int num_temporal_layers, |
| 667 bool error_concealment_on, | 709 bool error_concealment_on, |
| 668 bool denoising_on, | 710 bool denoising_on, |
| 669 bool frame_dropper_on, | 711 bool frame_dropper_on, |
| 670 bool spatial_resize_on) { | 712 bool spatial_resize_on) { |
| 671 SetCodecParams(process_settings, codec_type, hw_codec, use_single_core, | 713 SetCodecParams(process_settings, codec_type, hw_codec, use_single_core, |
| 672 packet_loss_probability, key_frame_interval, | 714 packet_loss_probability, key_frame_interval, |
| 673 num_temporal_layers, error_concealment_on, denoising_on, | 715 num_temporal_layers, error_concealment_on, denoising_on, |
| 674 frame_dropper_on, spatial_resize_on, kCifWidth, kCifHeight, | 716 frame_dropper_on, spatial_resize_on, kCifWidth, kCifHeight, |
| 675 kFilenameForemanCif, false /* verbose_logging */); | 717 kFilenameForemanCif, false /* verbose_logging */, |
| 718 false /* batch_mode */); |
| 676 } | 719 } |
| 677 | 720 |
| 678 static void SetQualityThresholds(QualityThresholds* quality_thresholds, | 721 static void SetQualityThresholds(QualityThresholds* quality_thresholds, |
| 679 double min_avg_psnr, | 722 double min_avg_psnr, |
| 680 double min_min_psnr, | 723 double min_min_psnr, |
| 681 double min_avg_ssim, | 724 double min_avg_ssim, |
| 682 double min_min_ssim) { | 725 double min_min_ssim) { |
| 683 quality_thresholds->min_avg_psnr = min_avg_psnr; | 726 quality_thresholds->min_avg_psnr = min_avg_psnr; |
| 684 quality_thresholds->min_min_psnr = min_min_psnr; | 727 quality_thresholds->min_min_psnr = min_min_psnr; |
| 685 quality_thresholds->min_avg_ssim = min_avg_ssim; | 728 quality_thresholds->min_avg_ssim = min_avg_ssim; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 float bit_rate_layer_[kMaxNumTemporalLayers]; | 792 float bit_rate_layer_[kMaxNumTemporalLayers]; |
| 750 float frame_rate_layer_[kMaxNumTemporalLayers]; | 793 float frame_rate_layer_[kMaxNumTemporalLayers]; |
| 751 int num_frames_total_; | 794 int num_frames_total_; |
| 752 float sum_encoded_frame_size_total_; | 795 float sum_encoded_frame_size_total_; |
| 753 float encoding_bitrate_total_; | 796 float encoding_bitrate_total_; |
| 754 float perc_encoding_rate_mismatch_; | 797 float perc_encoding_rate_mismatch_; |
| 755 int num_frames_to_hit_target_; | 798 int num_frames_to_hit_target_; |
| 756 bool encoding_rate_within_target_; | 799 bool encoding_rate_within_target_; |
| 757 int bit_rate_; | 800 int bit_rate_; |
| 758 int frame_rate_; | 801 int frame_rate_; |
| 759 int layer_; | |
| 760 float target_size_key_frame_initial_; | 802 float target_size_key_frame_initial_; |
| 761 float target_size_key_frame_; | 803 float target_size_key_frame_; |
| 762 float sum_key_frame_size_mismatch_; | 804 float sum_key_frame_size_mismatch_; |
| 763 int num_key_frames_; | 805 int num_key_frames_; |
| 764 float start_bitrate_; | 806 float start_bitrate_; |
| 765 int start_frame_rate_; | 807 int start_frame_rate_; |
| 766 | 808 |
| 767 // Codec and network settings. | 809 // Codec and network settings. |
| 768 float packet_loss_probability_; | 810 float packet_loss_probability_; |
| 769 int num_temporal_layers_; | 811 int num_temporal_layers_; |
| 770 }; | 812 }; |
| 771 | 813 |
| 772 } // namespace test | 814 } // namespace test |
| 773 } // namespace webrtc | 815 } // namespace webrtc |
| 774 | 816 |
| 775 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 817 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
| OLD | NEW |