| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 | 55 |
| 56 const int kPercTargetvsActualMismatch = 20; | 56 const int kPercTargetvsActualMismatch = 20; |
| 57 const int kBaseKeyFrameInterval = 3000; | 57 const int kBaseKeyFrameInterval = 3000; |
| 58 | 58 |
| 59 // Default sequence is foreman (CIF): may be better to use VGA for resize test. | 59 // Default sequence is foreman (CIF): may be better to use VGA for resize test. |
| 60 const int kCifWidth = 352; | 60 const int kCifWidth = 352; |
| 61 const int kCifHeight = 288; | 61 const int kCifHeight = 288; |
| 62 const char kFilenameForemanCif[] = "foreman_cif"; | 62 const char kFilenameForemanCif[] = "foreman_cif"; |
| 63 | 63 |
| 64 // Codec and network settings. | 64 // Codec and network settings. |
| 65 struct CodecConfigPars { | 65 struct CodecParams { |
| 66 VideoCodecType codec_type; | 66 VideoCodecType codec_type; |
| 67 bool hw_codec; | 67 bool hw_codec; |
| 68 bool use_single_core; | 68 bool use_single_core; |
| 69 float packet_loss; | 69 |
| 70 int width; |
| 71 int height; |
| 72 |
| 70 int num_temporal_layers; | 73 int num_temporal_layers; |
| 71 int key_frame_interval; | 74 int key_frame_interval; |
| 72 bool error_concealment_on; | 75 bool error_concealment_on; |
| 73 bool denoising_on; | 76 bool denoising_on; |
| 74 bool frame_dropper_on; | 77 bool frame_dropper_on; |
| 75 bool spatial_resize_on; | 78 bool spatial_resize_on; |
| 76 int width; | 79 |
| 77 int height; | 80 float packet_loss_probability; // [0.0, 1.0]. |
| 81 |
| 78 std::string filename; | 82 std::string filename; |
| 79 bool verbose_logging; | 83 bool verbose_logging; |
| 80 }; | 84 }; |
| 81 | 85 |
| 82 // Quality metrics. | 86 // Thresholds for the quality metrics. |
| 83 struct QualityMetrics { | 87 struct QualityThresholds { |
| 84 double minimum_avg_psnr; | 88 double min_avg_psnr; |
| 85 double minimum_min_psnr; | 89 double min_min_psnr; |
| 86 double minimum_avg_ssim; | 90 double min_avg_ssim; |
| 87 double minimum_min_ssim; | 91 double min_min_ssim; |
| 88 }; | 92 }; |
| 89 | 93 |
| 90 // The sequence of bitrate and frame rate changes for the encoder, the frame | 94 // The sequence of bit rate and frame rate changes for the encoder, the frame |
| 91 // number where the changes are made, and the total number of frames for the | 95 // number where the changes are made, and the total number of frames for the |
| 92 // test. | 96 // test. |
| 93 struct RateProfile { | 97 struct RateProfile { |
| 94 int target_bit_rate[kMaxNumRateUpdates]; | 98 int target_bit_rate[kMaxNumRateUpdates]; |
| 95 int input_frame_rate[kMaxNumRateUpdates]; | 99 int input_frame_rate[kMaxNumRateUpdates]; |
| 96 int frame_index_rate_update[kMaxNumRateUpdates + 1]; | 100 int frame_index_rate_update[kMaxNumRateUpdates + 1]; |
| 97 int num_frames; | 101 int num_frames; |
| 98 }; | 102 }; |
| 99 | 103 |
| 100 // Metrics for the rate control. The rate mismatch metrics are defined as | 104 // Thresholds for the rate control metrics. The rate mismatch thresholds are |
| 101 // percentages.|max_time_hit_target| is defined as number of frames, after a | 105 // defined as percentages. |max_time_hit_target| is defined as number of frames, |
| 102 // rate update is made to the encoder, for the encoder to reach within | 106 // after a rate update is made to the encoder, for the encoder to reach within |
| 103 // |kPercTargetvsActualMismatch| of new target rate. The metrics are defined for | 107 // |kPercTargetvsActualMismatch| of new target rate. The thresholds are defined |
| 104 // each rate update sequence. | 108 // for each rate update sequence. |
| 105 struct RateControlMetrics { | 109 struct RateControlThresholds { |
| 106 int max_num_dropped_frames; | 110 int max_num_dropped_frames; |
| 107 int max_key_frame_size_mismatch; | 111 int max_key_frame_size_mismatch; |
| 108 int max_delta_frame_size_mismatch; | 112 int max_delta_frame_size_mismatch; |
| 109 int max_encoding_rate_mismatch; | 113 int max_encoding_rate_mismatch; |
| 110 int max_time_hit_target; | 114 int max_time_hit_target; |
| 111 int num_spatial_resizes; | 115 int num_spatial_resizes; |
| 112 int num_key_frames; | 116 int num_key_frames; |
| 113 }; | 117 }; |
| 114 | 118 |
| 115 // Should video files be saved persistently to disk for post-run visualization? | 119 // Should video files be saved persistently to disk for post-run visualization? |
| 116 struct VisualizationParams { | 120 struct VisualizationParams { |
| 117 bool save_source_y4m; | 121 bool save_source_y4m; |
| 118 bool save_encoded_ivf; | 122 bool save_encoded_ivf; |
| 119 bool save_decoded_y4m; | 123 bool save_decoded_y4m; |
| 120 }; | 124 }; |
| 121 | 125 |
| 122 #if !defined(WEBRTC_IOS) | 126 #if !defined(WEBRTC_IOS) |
| 123 const int kNumFramesShort = 100; | 127 const int kNumFramesShort = 100; |
| 124 #endif | 128 #endif |
| 125 const int kNumFramesLong = 299; | 129 const int kNumFramesLong = 299; |
| 126 | 130 |
| 127 // Parameters from VP8 wrapper, which control target size of key frames. | 131 // Parameters from VP8 wrapper, which control target size of key frames. |
| 128 const float kInitialBufferSize = 0.5f; | 132 const float kInitialBufferSize = 0.5f; |
| 129 const float kOptimalBufferSize = 0.6f; | 133 const float kOptimalBufferSize = 0.6f; |
| 130 const float kScaleKeyFrameSize = 0.5f; | 134 const float kScaleKeyFrameSize = 0.5f; |
| 131 | 135 |
| 132 // Integration test for video processor. Encodes+decodes a clip and | 136 // Integration test for video processor. Encodes+decodes a clip and |
| 133 // writes it to the output directory. After completion, quality metrics | 137 // writes it to the output directory. After completion, quality metrics |
| 134 // (PSNR and SSIM) and rate control metrics are computed to verify that the | 138 // (PSNR and SSIM) and rate control metrics are computed and compared to given |
| 135 // quality and encoder response is acceptable. The rate control tests allow us | 139 // thresholds, to verify that the quality and encoder response is acceptable. |
| 136 // to verify the behavior for changing bitrate, changing frame rate, frame | 140 // The rate control tests allow us to verify the behavior for changing bit rate, |
| 137 // dropping/spatial resize, and temporal layers. The limits for the rate | 141 // changing frame rate, frame dropping/spatial resize, and temporal layers. |
| 138 // control metrics are set to be fairly conservative, so failure should only | 142 // The thresholds for the rate control metrics are set to be fairly |
| 139 // happen when some significant regression or breakdown occurs. | 143 // conservative, so failure should only happen when some significant regression |
| 144 // or breakdown occurs. |
| 140 class VideoProcessorIntegrationTest : public testing::Test { | 145 class VideoProcessorIntegrationTest : public testing::Test { |
| 141 protected: | 146 protected: |
| 142 VideoProcessorIntegrationTest() { | 147 VideoProcessorIntegrationTest() { |
| 143 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ | 148 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) && \ |
| 144 defined(WEBRTC_ANDROID) | 149 defined(WEBRTC_ANDROID) |
| 145 InitializeAndroidObjects(); | 150 InitializeAndroidObjects(); |
| 146 | 151 |
| 147 external_encoder_factory_.reset( | 152 external_encoder_factory_.reset( |
| 148 new webrtc_jni::MediaCodecVideoEncoderFactory()); | 153 new webrtc_jni::MediaCodecVideoEncoderFactory()); |
| 149 external_decoder_factory_.reset( | 154 external_decoder_factory_.reset( |
| 150 new webrtc_jni::MediaCodecVideoDecoderFactory()); | 155 new webrtc_jni::MediaCodecVideoDecoderFactory()); |
| 151 #endif | 156 #endif |
| 152 } | 157 } |
| 153 virtual ~VideoProcessorIntegrationTest() = default; | 158 virtual ~VideoProcessorIntegrationTest() = default; |
| 154 | 159 |
| 155 void SetUpCodecConfig(const CodecConfigPars& process, | 160 void SetUpCodecConfig(const CodecParams& process, |
| 156 const VisualizationParams* visualization_params) { | 161 const VisualizationParams* visualization_params) { |
| 157 if (process.hw_codec) { | 162 if (process.hw_codec) { |
| 158 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) | 163 #if defined(WEBRTC_VIDEOPROCESSOR_INTEGRATIONTEST_HW_CODECS_ENABLED) |
| 159 #if defined(WEBRTC_ANDROID) | 164 #if defined(WEBRTC_ANDROID) |
| 160 // In general, external codecs should be destroyed by the factories that | 165 // In general, external codecs should be destroyed by the factories that |
| 161 // allocated them. For the particular case of the Android | 166 // allocated them. For the particular case of the Android |
| 162 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is | 167 // MediaCodecVideo{En,De}coderFactory's, however, it turns out that it is |
| 163 // fine for the std::unique_ptr to destroy the owned codec directly. | 168 // fine for the std::unique_ptr to destroy the owned codec directly. |
| 164 switch (process.codec_type) { | 169 switch (process.codec_type) { |
| 165 case kVideoCodecH264: | 170 case kVideoCodecH264: |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 printf("Filename: %s\n", process.filename.c_str()); | 231 printf("Filename: %s\n", process.filename.c_str()); |
| 227 // Generate an output filename in a safe way. | 232 // Generate an output filename in a safe way. |
| 228 config_.output_filename = test::TempFilename( | 233 config_.output_filename = test::TempFilename( |
| 229 test::OutputPath(), "videoprocessor_integrationtest"); | 234 test::OutputPath(), "videoprocessor_integrationtest"); |
| 230 config_.frame_length_in_bytes = | 235 config_.frame_length_in_bytes = |
| 231 CalcBufferSize(kI420, process.width, process.height); | 236 CalcBufferSize(kI420, process.width, process.height); |
| 232 config_.verbose = process.verbose_logging; | 237 config_.verbose = process.verbose_logging; |
| 233 config_.use_single_core = process.use_single_core; | 238 config_.use_single_core = process.use_single_core; |
| 234 // Key frame interval and packet loss are set for each test. | 239 // Key frame interval and packet loss are set for each test. |
| 235 config_.keyframe_interval = process.key_frame_interval; | 240 config_.keyframe_interval = process.key_frame_interval; |
| 236 config_.networking_config.packet_loss_probability = packet_loss_; | 241 config_.networking_config.packet_loss_probability = |
| 242 packet_loss_probability_; |
| 237 | 243 |
| 238 // Configure codec settings. | 244 // Configure codec settings. |
| 239 config_.codec_settings = &codec_settings_; | 245 config_.codec_settings = &codec_settings_; |
| 240 config_.codec_settings->startBitrate = start_bitrate_; | 246 config_.codec_settings->startBitrate = start_bitrate_; |
| 241 config_.codec_settings->width = process.width; | 247 config_.codec_settings->width = process.width; |
| 242 config_.codec_settings->height = process.height; | 248 config_.codec_settings->height = process.height; |
| 243 | 249 |
| 244 // These features may be set depending on the test. | 250 // These features may be set depending on the test. |
| 245 switch (config_.codec_settings->codecType) { | 251 switch (config_.codec_settings->codecType) { |
| 246 case kVideoCodecH264: | 252 case kVideoCodecH264: |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 perc_encoding_rate_mismatch_ = | 392 perc_encoding_rate_mismatch_ = |
| 387 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; | 393 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; |
| 388 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 394 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
| 389 !encoding_rate_within_target_) { | 395 !encoding_rate_within_target_) { |
| 390 num_frames_to_hit_target_ = num_frames_total_; | 396 num_frames_to_hit_target_ = num_frames_total_; |
| 391 encoding_rate_within_target_ = true; | 397 encoding_rate_within_target_ = true; |
| 392 } | 398 } |
| 393 } | 399 } |
| 394 | 400 |
| 395 // Verify expected behavior of rate control and print out data. | 401 // Verify expected behavior of rate control and print out data. |
| 396 void VerifyRateControl(int update_index, | 402 void VerifyRateControlMetrics(int update_index, |
| 397 int max_key_frame_size_mismatch, | 403 int max_key_frame_size_mismatch, |
| 398 int max_delta_frame_size_mismatch, | 404 int max_delta_frame_size_mismatch, |
| 399 int max_encoding_rate_mismatch, | 405 int max_encoding_rate_mismatch, |
| 400 int max_time_hit_target, | 406 int max_time_hit_target, |
| 401 int max_num_dropped_frames, | 407 int max_num_dropped_frames, |
| 402 int num_spatial_resizes, | 408 int num_spatial_resizes, |
| 403 int num_key_frames) { | 409 int num_key_frames) { |
| 404 int num_dropped_frames = processor_->NumberDroppedFrames(); | 410 int num_dropped_frames = processor_->NumberDroppedFrames(); |
| 405 int num_resize_actions = processor_->NumberSpatialResizes(); | 411 int num_resize_actions = processor_->NumberSpatialResizes(); |
| 406 printf( | 412 printf( |
| 407 "For update #: %d,\n" | 413 "For update #: %d,\n" |
| 408 " Target Bitrate: %d,\n" | 414 " Target Bitrate: %d,\n" |
| 409 " Encoding bitrate: %f,\n" | 415 " Encoding bitrate: %f,\n" |
| 410 " Frame rate: %d \n", | 416 " Frame rate: %d \n", |
| 411 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); | 417 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); |
| 412 printf( | 418 printf( |
| 413 " Number of frames to approach target rate: %d, \n" | 419 " Number of frames to approach target rate: %d, \n" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch); | 453 EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch); |
| 448 EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch); | 454 EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch); |
| 449 } | 455 } |
| 450 printf("\n"); | 456 printf("\n"); |
| 451 EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target); | 457 EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target); |
| 452 EXPECT_LE(num_dropped_frames, max_num_dropped_frames); | 458 EXPECT_LE(num_dropped_frames, max_num_dropped_frames); |
| 453 EXPECT_EQ(num_resize_actions, num_spatial_resizes); | 459 EXPECT_EQ(num_resize_actions, num_spatial_resizes); |
| 454 EXPECT_EQ(num_key_frames_, num_key_frames); | 460 EXPECT_EQ(num_key_frames_, num_key_frames); |
| 455 } | 461 } |
| 456 | 462 |
| 463 void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
| 464 const test::QualityMetricsResult& ssim_result, |
| 465 const QualityThresholds& quality_thresholds) { |
| 466 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
| 467 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
| 468 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
| 469 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
| 470 } |
| 471 |
| 457 // Layer index corresponding to frame number, for up to 3 layers. | 472 // Layer index corresponding to frame number, for up to 3 layers. |
| 458 void LayerIndexForFrame(int frame_number) { | 473 void LayerIndexForFrame(int frame_number) { |
| 459 if (num_temporal_layers_ == 1) { | 474 if (num_temporal_layers_ == 1) { |
| 460 layer_ = 0; | 475 layer_ = 0; |
| 461 } else if (num_temporal_layers_ == 2) { | 476 } else if (num_temporal_layers_ == 2) { |
| 462 // layer 0: 0 2 4 ... | 477 // layer 0: 0 2 4 ... |
| 463 // layer 1: 1 3 | 478 // layer 1: 1 3 |
| 464 if (frame_number % 2 == 0) { | 479 if (frame_number % 2 == 0) { |
| 465 layer_ = 0; | 480 layer_ = 0; |
| 466 } else { | 481 } else { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 } | 513 } |
| 499 frame_rate_layer_[i] = | 514 frame_rate_layer_[i] = |
| 500 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); | 515 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); |
| 501 } | 516 } |
| 502 if (num_temporal_layers_ == 3) { | 517 if (num_temporal_layers_ == 3) { |
| 503 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 518 frame_rate_layer_[2] = frame_rate_ / 2.0f; |
| 504 } | 519 } |
| 505 } | 520 } |
| 506 | 521 |
| 507 // Processes all frames in the clip and verifies the result. | 522 // Processes all frames in the clip and verifies the result. |
| 508 void ProcessFramesAndVerify(QualityMetrics quality_metrics, | 523 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, |
| 509 RateProfile rate_profile, | 524 RateProfile rate_profile, |
| 510 CodecConfigPars process, | 525 CodecParams process, |
| 511 RateControlMetrics* rc_metrics, | 526 RateControlThresholds* rc_thresholds, |
| 512 const VisualizationParams* visualization_params) { | 527 const VisualizationParams* visualization_params) { |
| 513 // Codec/config settings. | 528 // Codec/config settings. |
| 514 start_bitrate_ = rate_profile.target_bit_rate[0]; | 529 start_bitrate_ = rate_profile.target_bit_rate[0]; |
| 515 start_frame_rate_ = rate_profile.input_frame_rate[0]; | 530 start_frame_rate_ = rate_profile.input_frame_rate[0]; |
| 516 packet_loss_ = process.packet_loss; | 531 packet_loss_probability_ = process.packet_loss_probability; |
| 517 num_temporal_layers_ = process.num_temporal_layers; | 532 num_temporal_layers_ = process.num_temporal_layers; |
| 518 SetUpCodecConfig(process, visualization_params); | 533 SetUpCodecConfig(process, visualization_params); |
| 519 // Update the layers and the codec with the initial rates. | 534 // Update the layers and the codec with the initial rates. |
| 520 bit_rate_ = rate_profile.target_bit_rate[0]; | 535 bit_rate_ = rate_profile.target_bit_rate[0]; |
| 521 frame_rate_ = rate_profile.input_frame_rate[0]; | 536 frame_rate_ = rate_profile.input_frame_rate[0]; |
| 522 SetLayerRates(); | 537 SetLayerRates(); |
| 523 // Set the initial target size for key frame. | 538 // Set the initial target size for key frame. |
| 524 target_size_key_frame_initial_ = | 539 target_size_key_frame_initial_ = |
| 525 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 540 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
| 526 processor_->SetRates(bit_rate_, frame_rate_); | 541 processor_->SetRates(bit_rate_, frame_rate_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 541 // Counter for whole sequence run. | 556 // Counter for whole sequence run. |
| 542 ++frame_number; | 557 ++frame_number; |
| 543 // Counters for each rate update. | 558 // Counters for each rate update. |
| 544 ++num_frames_per_update_[layer_]; | 559 ++num_frames_per_update_[layer_]; |
| 545 ++num_frames_total_; | 560 ++num_frames_total_; |
| 546 UpdateRateControlMetrics(frame_number, frame_type); | 561 UpdateRateControlMetrics(frame_number, frame_type); |
| 547 // If we hit another/next update, verify stats for current state and | 562 // If we hit another/next update, verify stats for current state and |
| 548 // update layers and codec with new rates. | 563 // update layers and codec with new rates. |
| 549 if (frame_number == | 564 if (frame_number == |
| 550 rate_profile.frame_index_rate_update[update_index + 1]) { | 565 rate_profile.frame_index_rate_update[update_index + 1]) { |
| 551 VerifyRateControl( | 566 VerifyRateControlMetrics( |
| 552 update_index, rc_metrics[update_index].max_key_frame_size_mismatch, | 567 update_index, |
| 553 rc_metrics[update_index].max_delta_frame_size_mismatch, | 568 rc_thresholds[update_index].max_key_frame_size_mismatch, |
| 554 rc_metrics[update_index].max_encoding_rate_mismatch, | 569 rc_thresholds[update_index].max_delta_frame_size_mismatch, |
| 555 rc_metrics[update_index].max_time_hit_target, | 570 rc_thresholds[update_index].max_encoding_rate_mismatch, |
| 556 rc_metrics[update_index].max_num_dropped_frames, | 571 rc_thresholds[update_index].max_time_hit_target, |
| 557 rc_metrics[update_index].num_spatial_resizes, | 572 rc_thresholds[update_index].max_num_dropped_frames, |
| 558 rc_metrics[update_index].num_key_frames); | 573 rc_thresholds[update_index].num_spatial_resizes, |
| 574 rc_thresholds[update_index].num_key_frames); |
| 559 // Update layer rates and the codec with new rates. | 575 // Update layer rates and the codec with new rates. |
| 560 ++update_index; | 576 ++update_index; |
| 561 bit_rate_ = rate_profile.target_bit_rate[update_index]; | 577 bit_rate_ = rate_profile.target_bit_rate[update_index]; |
| 562 frame_rate_ = rate_profile.input_frame_rate[update_index]; | 578 frame_rate_ = rate_profile.input_frame_rate[update_index]; |
| 563 SetLayerRates(); | 579 SetLayerRates(); |
| 564 ResetRateControlMetrics( | 580 ResetRateControlMetrics( |
| 565 rate_profile.frame_index_rate_update[update_index + 1]); | 581 rate_profile.frame_index_rate_update[update_index + 1]); |
| 566 processor_->SetRates(bit_rate_, frame_rate_); | 582 processor_->SetRates(bit_rate_, frame_rate_); |
| 567 } | 583 } |
| 568 } | 584 } |
| 569 VerifyRateControl(update_index, | 585 VerifyRateControlMetrics( |
| 570 rc_metrics[update_index].max_key_frame_size_mismatch, | 586 update_index, rc_thresholds[update_index].max_key_frame_size_mismatch, |
| 571 rc_metrics[update_index].max_delta_frame_size_mismatch, | 587 rc_thresholds[update_index].max_delta_frame_size_mismatch, |
| 572 rc_metrics[update_index].max_encoding_rate_mismatch, | 588 rc_thresholds[update_index].max_encoding_rate_mismatch, |
| 573 rc_metrics[update_index].max_time_hit_target, | 589 rc_thresholds[update_index].max_time_hit_target, |
| 574 rc_metrics[update_index].max_num_dropped_frames, | 590 rc_thresholds[update_index].max_num_dropped_frames, |
| 575 rc_metrics[update_index].num_spatial_resizes, | 591 rc_thresholds[update_index].num_spatial_resizes, |
| 576 rc_metrics[update_index].num_key_frames); | 592 rc_thresholds[update_index].num_key_frames); |
| 577 EXPECT_EQ(num_frames, frame_number); | 593 EXPECT_EQ(num_frames, frame_number); |
| 578 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 594 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
| 579 | 595 |
| 580 // Release encoder and decoder to make sure they have finished processing: | 596 // Release encoder and decoder to make sure they have finished processing: |
| 581 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 597 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
| 582 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 598 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); |
| 583 | 599 |
| 584 // Close the analysis files before we use them for SSIM/PSNR calculations. | 600 // Close the analysis files before we use them for SSIM/PSNR calculations. |
| 585 analysis_frame_reader_->Close(); | 601 analysis_frame_reader_->Close(); |
| 586 analysis_frame_writer_->Close(); | 602 analysis_frame_writer_->Close(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 600 test::QualityMetricsResult psnr_result, ssim_result; | 616 test::QualityMetricsResult psnr_result, ssim_result; |
| 601 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), | 617 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), |
| 602 config_.output_filename.c_str(), | 618 config_.output_filename.c_str(), |
| 603 config_.codec_settings->width, | 619 config_.codec_settings->width, |
| 604 config_.codec_settings->height, | 620 config_.codec_settings->height, |
| 605 &psnr_result, &ssim_result)); | 621 &psnr_result, &ssim_result)); |
| 606 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", | 622 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
| 607 psnr_result.average, psnr_result.min, ssim_result.average, | 623 psnr_result.average, psnr_result.min, ssim_result.average, |
| 608 ssim_result.min); | 624 ssim_result.min); |
| 609 stats_.PrintSummary(); | 625 stats_.PrintSummary(); |
| 610 EXPECT_GT(psnr_result.average, quality_metrics.minimum_avg_psnr); | 626 VerifyQuality(psnr_result, ssim_result, quality_thresholds); |
| 611 EXPECT_GT(psnr_result.min, quality_metrics.minimum_min_psnr); | |
| 612 EXPECT_GT(ssim_result.average, quality_metrics.minimum_avg_ssim); | |
| 613 EXPECT_GT(ssim_result.min, quality_metrics.minimum_min_ssim); | |
| 614 | 627 |
| 615 // Remove analysis file. | 628 // Remove analysis file. |
| 616 if (remove(config_.output_filename.c_str()) < 0) { | 629 if (remove(config_.output_filename.c_str()) < 0) { |
| 617 fprintf(stderr, "Failed to remove temporary file!\n"); | 630 fprintf(stderr, "Failed to remove temporary file!\n"); |
| 618 } | 631 } |
| 619 } | 632 } |
| 620 | 633 |
| 621 static void SetCodecParameters(CodecConfigPars* process_settings, | 634 static void SetCodecParams(CodecParams* process_settings, |
| 622 VideoCodecType codec_type, | 635 VideoCodecType codec_type, |
| 623 bool hw_codec, | 636 bool hw_codec, |
| 624 bool use_single_core, | 637 bool use_single_core, |
| 625 float packet_loss, | 638 float packet_loss_probability, |
| 626 int key_frame_interval, | 639 int key_frame_interval, |
| 627 int num_temporal_layers, | 640 int num_temporal_layers, |
| 628 bool error_concealment_on, | 641 bool error_concealment_on, |
| 629 bool denoising_on, | 642 bool denoising_on, |
| 630 bool frame_dropper_on, | 643 bool frame_dropper_on, |
| 631 bool spatial_resize_on, | 644 bool spatial_resize_on, |
| 632 int width, | 645 int width, |
| 633 int height, | 646 int height, |
| 634 const std::string& filename, | 647 const std::string& filename, |
| 635 bool verbose_logging) { | 648 bool verbose_logging) { |
| 636 process_settings->codec_type = codec_type; | 649 process_settings->codec_type = codec_type; |
| 637 process_settings->hw_codec = hw_codec; | 650 process_settings->hw_codec = hw_codec; |
| 638 process_settings->use_single_core = use_single_core; | 651 process_settings->use_single_core = use_single_core; |
| 639 process_settings->packet_loss = packet_loss; | 652 process_settings->packet_loss_probability = packet_loss_probability; |
| 640 process_settings->key_frame_interval = key_frame_interval; | 653 process_settings->key_frame_interval = key_frame_interval; |
| 641 process_settings->num_temporal_layers = num_temporal_layers, | 654 process_settings->num_temporal_layers = num_temporal_layers, |
| 642 process_settings->error_concealment_on = error_concealment_on; | 655 process_settings->error_concealment_on = error_concealment_on; |
| 643 process_settings->denoising_on = denoising_on; | 656 process_settings->denoising_on = denoising_on; |
| 644 process_settings->frame_dropper_on = frame_dropper_on; | 657 process_settings->frame_dropper_on = frame_dropper_on; |
| 645 process_settings->spatial_resize_on = spatial_resize_on; | 658 process_settings->spatial_resize_on = spatial_resize_on; |
| 646 process_settings->width = width; | 659 process_settings->width = width; |
| 647 process_settings->height = height; | 660 process_settings->height = height; |
| 648 process_settings->filename = filename; | 661 process_settings->filename = filename; |
| 649 process_settings->verbose_logging = verbose_logging; | 662 process_settings->verbose_logging = verbose_logging; |
| 650 } | 663 } |
| 651 | 664 |
| 652 static void SetCodecParameters(CodecConfigPars* process_settings, | 665 static void SetCodecParams(CodecParams* process_settings, |
| 653 VideoCodecType codec_type, | 666 VideoCodecType codec_type, |
| 654 bool hw_codec, | 667 bool hw_codec, |
| 655 bool use_single_core, | 668 bool use_single_core, |
| 656 float packet_loss, | 669 float packet_loss_probability, |
| 657 int key_frame_interval, | 670 int key_frame_interval, |
| 658 int num_temporal_layers, | 671 int num_temporal_layers, |
| 659 bool error_concealment_on, | 672 bool error_concealment_on, |
| 660 bool denoising_on, | 673 bool denoising_on, |
| 661 bool frame_dropper_on, | 674 bool frame_dropper_on, |
| 662 bool spatial_resize_on) { | 675 bool spatial_resize_on) { |
| 663 SetCodecParameters(process_settings, codec_type, hw_codec, use_single_core, | 676 SetCodecParams(process_settings, codec_type, hw_codec, use_single_core, |
| 664 packet_loss, key_frame_interval, num_temporal_layers, | 677 packet_loss_probability, key_frame_interval, |
| 665 error_concealment_on, denoising_on, frame_dropper_on, | 678 num_temporal_layers, error_concealment_on, denoising_on, |
| 666 spatial_resize_on, kCifWidth, kCifHeight, | 679 frame_dropper_on, spatial_resize_on, kCifWidth, kCifHeight, |
| 667 kFilenameForemanCif, false /* verbose_logging */); | 680 kFilenameForemanCif, false /* verbose_logging */); |
| 668 } | 681 } |
| 669 | 682 |
| 670 static void SetQualityMetrics(QualityMetrics* quality_metrics, | 683 static void SetQualityThresholds(QualityThresholds* quality_thresholds, |
| 671 double minimum_avg_psnr, | 684 double min_avg_psnr, |
| 672 double minimum_min_psnr, | 685 double min_min_psnr, |
| 673 double minimum_avg_ssim, | 686 double min_avg_ssim, |
| 674 double minimum_min_ssim) { | 687 double min_min_ssim) { |
| 675 quality_metrics->minimum_avg_psnr = minimum_avg_psnr; | 688 quality_thresholds->min_avg_psnr = min_avg_psnr; |
| 676 quality_metrics->minimum_min_psnr = minimum_min_psnr; | 689 quality_thresholds->min_min_psnr = min_min_psnr; |
| 677 quality_metrics->minimum_avg_ssim = minimum_avg_ssim; | 690 quality_thresholds->min_avg_ssim = min_avg_ssim; |
| 678 quality_metrics->minimum_min_ssim = minimum_min_ssim; | 691 quality_thresholds->min_min_ssim = min_min_ssim; |
| 679 } | 692 } |
| 680 | 693 |
| 681 static void SetRateProfilePars(RateProfile* rate_profile, | 694 static void SetRateProfile(RateProfile* rate_profile, |
| 682 int update_index, | 695 int update_index, |
| 683 int bit_rate, | 696 int bit_rate, |
| 684 int frame_rate, | 697 int frame_rate, |
| 685 int frame_index_rate_update) { | 698 int frame_index_rate_update) { |
| 686 rate_profile->target_bit_rate[update_index] = bit_rate; | 699 rate_profile->target_bit_rate[update_index] = bit_rate; |
| 687 rate_profile->input_frame_rate[update_index] = frame_rate; | 700 rate_profile->input_frame_rate[update_index] = frame_rate; |
| 688 rate_profile->frame_index_rate_update[update_index] = | 701 rate_profile->frame_index_rate_update[update_index] = |
| 689 frame_index_rate_update; | 702 frame_index_rate_update; |
| 690 } | 703 } |
| 691 | 704 |
| 692 static void SetRateControlMetrics(RateControlMetrics* rc_metrics, | 705 static void SetRateControlThresholds(RateControlThresholds* rc_thresholds, |
| 693 int update_index, | 706 int update_index, |
| 694 int max_num_dropped_frames, | 707 int max_num_dropped_frames, |
| 695 int max_key_frame_size_mismatch, | 708 int max_key_frame_size_mismatch, |
| 696 int max_delta_frame_size_mismatch, | 709 int max_delta_frame_size_mismatch, |
| 697 int max_encoding_rate_mismatch, | 710 int max_encoding_rate_mismatch, |
| 698 int max_time_hit_target, | 711 int max_time_hit_target, |
| 699 int num_spatial_resizes, | 712 int num_spatial_resizes, |
| 700 int num_key_frames) { | 713 int num_key_frames) { |
| 701 rc_metrics[update_index].max_num_dropped_frames = max_num_dropped_frames; | 714 rc_thresholds[update_index].max_num_dropped_frames = max_num_dropped_frames; |
| 702 rc_metrics[update_index].max_key_frame_size_mismatch = | 715 rc_thresholds[update_index].max_key_frame_size_mismatch = |
| 703 max_key_frame_size_mismatch; | 716 max_key_frame_size_mismatch; |
| 704 rc_metrics[update_index].max_delta_frame_size_mismatch = | 717 rc_thresholds[update_index].max_delta_frame_size_mismatch = |
| 705 max_delta_frame_size_mismatch; | 718 max_delta_frame_size_mismatch; |
| 706 rc_metrics[update_index].max_encoding_rate_mismatch = | 719 rc_thresholds[update_index].max_encoding_rate_mismatch = |
| 707 max_encoding_rate_mismatch; | 720 max_encoding_rate_mismatch; |
| 708 rc_metrics[update_index].max_time_hit_target = max_time_hit_target; | 721 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; |
| 709 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; | 722 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; |
| 710 rc_metrics[update_index].num_key_frames = num_key_frames; | 723 rc_thresholds[update_index].num_key_frames = num_key_frames; |
| 711 } | 724 } |
| 712 | 725 |
| 713 // Codecs. | 726 // Codecs. |
| 714 std::unique_ptr<VideoEncoder> encoder_; | 727 std::unique_ptr<VideoEncoder> encoder_; |
| 715 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> external_encoder_factory_; | 728 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> external_encoder_factory_; |
| 716 std::unique_ptr<VideoDecoder> decoder_; | 729 std::unique_ptr<VideoDecoder> decoder_; |
| 717 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> external_decoder_factory_; | 730 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> external_decoder_factory_; |
| 718 VideoCodec codec_settings_; | 731 VideoCodec codec_settings_; |
| 719 | 732 |
| 720 // Helper objects. | 733 // Helper objects. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 751 int frame_rate_; | 764 int frame_rate_; |
| 752 int layer_; | 765 int layer_; |
| 753 float target_size_key_frame_initial_; | 766 float target_size_key_frame_initial_; |
| 754 float target_size_key_frame_; | 767 float target_size_key_frame_; |
| 755 float sum_key_frame_size_mismatch_; | 768 float sum_key_frame_size_mismatch_; |
| 756 int num_key_frames_; | 769 int num_key_frames_; |
| 757 float start_bitrate_; | 770 float start_bitrate_; |
| 758 int start_frame_rate_; | 771 int start_frame_rate_; |
| 759 | 772 |
| 760 // Codec and network settings. | 773 // Codec and network settings. |
| 761 float packet_loss_; | 774 float packet_loss_probability_; |
| 762 int num_temporal_layers_; | 775 int num_temporal_layers_; |
| 763 }; | 776 }; |
| 764 | 777 |
| 765 } // namespace test | 778 } // namespace test |
| 766 } // namespace webrtc | 779 } // namespace webrtc |
| 767 | 780 |
| 768 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 781 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
| OLD | NEW |