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 |