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