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 |
11 #include <math.h> | 11 #include <math.h> |
12 | 12 |
| 13 #include <memory> |
| 14 |
13 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 15 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
14 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 16 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
15 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 17 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
16 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 18 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
17 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 19 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
18 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 20 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
19 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 21 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
20 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 22 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
21 #include "webrtc/modules/video_coding/include/video_coding.h" | 23 #include "webrtc/modules/video_coding/include/video_coding.h" |
22 #include "webrtc/test/gtest.h" | 24 #include "webrtc/test/gtest.h" |
23 #include "webrtc/test/testsupport/fileutils.h" | 25 #include "webrtc/test/testsupport/fileutils.h" |
24 #include "webrtc/test/testsupport/frame_reader.h" | 26 #include "webrtc/test/testsupport/frame_reader.h" |
25 #include "webrtc/test/testsupport/frame_writer.h" | 27 #include "webrtc/test/testsupport/frame_writer.h" |
26 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 28 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
27 #include "webrtc/test/testsupport/packet_reader.h" | 29 #include "webrtc/test/testsupport/packet_reader.h" |
28 #include "webrtc/typedefs.h" | 30 #include "webrtc/typedefs.h" |
29 | 31 |
30 namespace webrtc { | 32 namespace webrtc { |
31 | 33 namespace { |
32 // Maximum number of rate updates (i.e., calls to encoder to change bitrate | 34 // Maximum number of rate updates (i.e., calls to encoder to change bitrate |
33 // and/or frame rate) for the current tests. | 35 // and/or frame rate) for the current tests. |
34 const int kMaxNumRateUpdates = 3; | 36 const int kMaxNumRateUpdates = 3; |
35 | 37 |
36 const int kPercTargetvsActualMismatch = 20; | 38 const int kPercTargetvsActualMismatch = 20; |
37 const int kBaseKeyFrameInterval = 3000; | 39 const int kBaseKeyFrameInterval = 3000; |
38 | 40 |
39 // Codec and network settings. | 41 // Codec and network settings. |
40 struct CodecConfigPars { | 42 struct CodecConfigPars { |
41 VideoCodecType codec_type; | 43 VideoCodecType codec_type; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 #if !defined(WEBRTC_IOS) | 89 #if !defined(WEBRTC_IOS) |
88 const int kNbrFramesShort = 100; // Some tests are run for shorter sequence. | 90 const int kNbrFramesShort = 100; // Some tests are run for shorter sequence. |
89 #endif | 91 #endif |
90 const int kNbrFramesLong = 299; | 92 const int kNbrFramesLong = 299; |
91 | 93 |
92 // Parameters from VP8 wrapper, which control target size of key frames. | 94 // Parameters from VP8 wrapper, which control target size of key frames. |
93 const float kInitialBufferSize = 0.5f; | 95 const float kInitialBufferSize = 0.5f; |
94 const float kOptimalBufferSize = 0.6f; | 96 const float kOptimalBufferSize = 0.6f; |
95 const float kScaleKeyFrameSize = 0.5f; | 97 const float kScaleKeyFrameSize = 0.5f; |
96 | 98 |
| 99 void SetRateProfilePars(RateProfile* rate_profile, |
| 100 int update_index, |
| 101 int bit_rate, |
| 102 int frame_rate, |
| 103 int frame_index_rate_update) { |
| 104 rate_profile->target_bit_rate[update_index] = bit_rate; |
| 105 rate_profile->input_frame_rate[update_index] = frame_rate; |
| 106 rate_profile->frame_index_rate_update[update_index] = frame_index_rate_update; |
| 107 } |
| 108 |
| 109 void SetCodecParameters(CodecConfigPars* process_settings, |
| 110 VideoCodecType codec_type, |
| 111 float packet_loss, |
| 112 int key_frame_interval, |
| 113 int num_temporal_layers, |
| 114 bool error_concealment_on, |
| 115 bool denoising_on, |
| 116 bool frame_dropper_on, |
| 117 bool spatial_resize_on) { |
| 118 process_settings->codec_type = codec_type; |
| 119 process_settings->packet_loss = packet_loss; |
| 120 process_settings->key_frame_interval = key_frame_interval; |
| 121 process_settings->num_temporal_layers = num_temporal_layers, |
| 122 process_settings->error_concealment_on = error_concealment_on; |
| 123 process_settings->denoising_on = denoising_on; |
| 124 process_settings->frame_dropper_on = frame_dropper_on; |
| 125 process_settings->spatial_resize_on = spatial_resize_on; |
| 126 } |
| 127 |
| 128 void SetQualityMetrics(QualityMetrics* quality_metrics, |
| 129 double minimum_avg_psnr, |
| 130 double minimum_min_psnr, |
| 131 double minimum_avg_ssim, |
| 132 double minimum_min_ssim) { |
| 133 quality_metrics->minimum_avg_psnr = minimum_avg_psnr; |
| 134 quality_metrics->minimum_min_psnr = minimum_min_psnr; |
| 135 quality_metrics->minimum_avg_ssim = minimum_avg_ssim; |
| 136 quality_metrics->minimum_min_ssim = minimum_min_ssim; |
| 137 } |
| 138 |
| 139 void SetRateControlMetrics(RateControlMetrics* rc_metrics, |
| 140 int update_index, |
| 141 int max_num_dropped_frames, |
| 142 int max_key_frame_size_mismatch, |
| 143 int max_delta_frame_size_mismatch, |
| 144 int max_encoding_rate_mismatch, |
| 145 int max_time_hit_target, |
| 146 int num_spatial_resizes, |
| 147 int num_key_frames) { |
| 148 rc_metrics[update_index].max_num_dropped_frames = max_num_dropped_frames; |
| 149 rc_metrics[update_index].max_key_frame_size_mismatch = |
| 150 max_key_frame_size_mismatch; |
| 151 rc_metrics[update_index].max_delta_frame_size_mismatch = |
| 152 max_delta_frame_size_mismatch; |
| 153 rc_metrics[update_index].max_encoding_rate_mismatch = |
| 154 max_encoding_rate_mismatch; |
| 155 rc_metrics[update_index].max_time_hit_target = max_time_hit_target; |
| 156 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; |
| 157 rc_metrics[update_index].num_key_frames = num_key_frames; |
| 158 } |
| 159 } // namespace |
| 160 |
97 // Integration test for video processor. Encodes+decodes a clip and | 161 // Integration test for video processor. Encodes+decodes a clip and |
98 // writes it to the output directory. After completion, quality metrics | 162 // writes it to the output directory. After completion, quality metrics |
99 // (PSNR and SSIM) and rate control metrics are computed to verify that the | 163 // (PSNR and SSIM) and rate control metrics are computed to verify that the |
100 // quality and encoder response is acceptable. The rate control tests allow us | 164 // quality and encoder response is acceptable. The rate control tests allow us |
101 // to verify the behavior for changing bitrate, changing frame rate, frame | 165 // to verify the behavior for changing bitrate, changing frame rate, frame |
102 // dropping/spatial resize, and temporal layers. The limits for the rate | 166 // dropping/spatial resize, and temporal layers. The limits for the rate |
103 // control metrics are set to be fairly conservative, so failure should only | 167 // control metrics are set to be fairly conservative, so failure should only |
104 // happen when some significant regression or breakdown occurs. | 168 // happen when some significant regression or breakdown occurs. |
105 class VideoProcessorIntegrationTest : public testing::Test { | 169 class VideoProcessorIntegrationTest : public testing::Test { |
106 protected: | 170 protected: |
107 VideoEncoder* encoder_; | 171 std::unique_ptr<VideoEncoder> encoder_; |
108 VideoDecoder* decoder_; | 172 std::unique_ptr<VideoDecoder> decoder_; |
109 webrtc::test::FrameReader* frame_reader_; | 173 std::unique_ptr<test::FrameReader> frame_reader_; |
110 webrtc::test::FrameWriter* frame_writer_; | 174 std::unique_ptr<test::FrameWriter> frame_writer_; |
111 webrtc::test::PacketReader packet_reader_; | 175 test::PacketReader packet_reader_; |
112 webrtc::test::PacketManipulator* packet_manipulator_; | 176 std::unique_ptr<test::PacketManipulator> packet_manipulator_; |
113 webrtc::test::Stats stats_; | 177 test::Stats stats_; |
114 webrtc::test::TestConfig config_; | 178 test::TestConfig config_; |
115 VideoCodec codec_settings_; | 179 VideoCodec codec_settings_; |
116 webrtc::test::VideoProcessor* processor_; | 180 std::unique_ptr<test::VideoProcessor> processor_; |
117 TemporalLayersFactory tl_factory_; | 181 TemporalLayersFactory tl_factory_; |
118 | 182 |
119 // Quantities defined/updated for every encoder rate update. | 183 // Quantities defined/updated for every encoder rate update. |
120 // Some quantities defined per temporal layer (at most 3 layers in this test). | 184 // Some quantities defined per temporal layer (at most 3 layers in this test). |
121 int num_frames_per_update_[3]; | 185 int num_frames_per_update_[3]; |
122 float sum_frame_size_mismatch_[3]; | 186 float sum_frame_size_mismatch_[3]; |
123 float sum_encoded_frame_size_[3]; | 187 float sum_encoded_frame_size_[3]; |
124 float encoding_bitrate_[3]; | 188 float encoding_bitrate_[3]; |
125 float per_frame_bandwidth_[3]; | 189 float per_frame_bandwidth_[3]; |
126 float bit_rate_layer_[3]; | 190 float bit_rate_layer_[3]; |
(...skipping 21 matching lines...) Expand all Loading... |
148 bool error_concealment_on_; | 212 bool error_concealment_on_; |
149 bool denoising_on_; | 213 bool denoising_on_; |
150 bool frame_dropper_on_; | 214 bool frame_dropper_on_; |
151 bool spatial_resize_on_; | 215 bool spatial_resize_on_; |
152 | 216 |
153 VideoProcessorIntegrationTest() {} | 217 VideoProcessorIntegrationTest() {} |
154 virtual ~VideoProcessorIntegrationTest() {} | 218 virtual ~VideoProcessorIntegrationTest() {} |
155 | 219 |
156 void SetUpCodecConfig() { | 220 void SetUpCodecConfig() { |
157 if (codec_type_ == kVideoCodecH264) { | 221 if (codec_type_ == kVideoCodecH264) { |
158 encoder_ = H264Encoder::Create(cricket::VideoCodec("H264")); | 222 encoder_.reset(H264Encoder::Create(cricket::VideoCodec("H264"))); |
159 decoder_ = H264Decoder::Create(); | 223 decoder_.reset(H264Decoder::Create()); |
160 VideoCodingModule::Codec(kVideoCodecH264, &codec_settings_); | 224 VideoCodingModule::Codec(kVideoCodecH264, &codec_settings_); |
161 } else if (codec_type_ == kVideoCodecVP8) { | 225 } else if (codec_type_ == kVideoCodecVP8) { |
162 encoder_ = VP8Encoder::Create(); | 226 encoder_.reset(VP8Encoder::Create()); |
163 decoder_ = VP8Decoder::Create(); | 227 decoder_.reset(VP8Decoder::Create()); |
164 VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_); | 228 VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_); |
165 } else if (codec_type_ == kVideoCodecVP9) { | 229 } else if (codec_type_ == kVideoCodecVP9) { |
166 encoder_ = VP9Encoder::Create(); | 230 encoder_.reset(VP9Encoder::Create()); |
167 decoder_ = VP9Decoder::Create(); | 231 decoder_.reset(VP9Decoder::Create()); |
168 VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_); | 232 VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_); |
169 } | 233 } |
170 | 234 |
171 // CIF is currently used for all tests below. | 235 // CIF is currently used for all tests below. |
172 // Setup the TestConfig struct for processing of a clip in CIF resolution. | 236 // Setup the TestConfig struct for processing of a clip in CIF resolution. |
173 config_.input_filename = webrtc::test::ResourcePath("foreman_cif", "yuv"); | 237 config_.input_filename = webrtc::test::ResourcePath("foreman_cif", "yuv"); |
174 | 238 |
175 // Generate an output filename in a safe way. | 239 // Generate an output filename in a safe way. |
176 config_.output_filename = webrtc::test::TempFilename( | 240 config_.output_filename = webrtc::test::TempFilename( |
177 webrtc::test::OutputPath(), "videoprocessor_integrationtest"); | 241 webrtc::test::OutputPath(), "videoprocessor_integrationtest"); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 config_.codec_settings->VP9()->numberOfTemporalLayers = | 276 config_.codec_settings->VP9()->numberOfTemporalLayers = |
213 num_temporal_layers_; | 277 num_temporal_layers_; |
214 config_.codec_settings->VP9()->frameDroppingOn = frame_dropper_on_; | 278 config_.codec_settings->VP9()->frameDroppingOn = frame_dropper_on_; |
215 config_.codec_settings->VP9()->automaticResizeOn = spatial_resize_on_; | 279 config_.codec_settings->VP9()->automaticResizeOn = spatial_resize_on_; |
216 config_.codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval; | 280 config_.codec_settings->VP9()->keyFrameInterval = kBaseKeyFrameInterval; |
217 break; | 281 break; |
218 default: | 282 default: |
219 assert(false); | 283 assert(false); |
220 break; | 284 break; |
221 } | 285 } |
222 frame_reader_ = new webrtc::test::FrameReaderImpl( | 286 frame_reader_.reset(new test::FrameReaderImpl( |
223 config_.input_filename, config_.codec_settings->width, | 287 config_.input_filename, config_.codec_settings->width, |
224 config_.codec_settings->height); | 288 config_.codec_settings->height)); |
225 frame_writer_ = new webrtc::test::FrameWriterImpl( | 289 frame_writer_.reset(new test::FrameWriterImpl( |
226 config_.output_filename, config_.frame_length_in_bytes); | 290 config_.output_filename, config_.frame_length_in_bytes)); |
227 ASSERT_TRUE(frame_reader_->Init()); | 291 ASSERT_TRUE(frame_reader_->Init()); |
228 ASSERT_TRUE(frame_writer_->Init()); | 292 ASSERT_TRUE(frame_writer_->Init()); |
229 | 293 |
230 packet_manipulator_ = new webrtc::test::PacketManipulatorImpl( | 294 packet_manipulator_.reset(new test::PacketManipulatorImpl( |
231 &packet_reader_, config_.networking_config, config_.verbose); | 295 &packet_reader_, config_.networking_config, config_.verbose)); |
232 processor_ = new webrtc::test::VideoProcessorImpl( | 296 processor_.reset(new test::VideoProcessorImpl( |
233 encoder_, decoder_, frame_reader_, frame_writer_, packet_manipulator_, | 297 encoder_.get(), decoder_.get(), frame_reader_.get(), |
234 config_, &stats_); | 298 frame_writer_.get(), packet_manipulator_.get(), config_, &stats_)); |
235 ASSERT_TRUE(processor_->Init()); | 299 ASSERT_TRUE(processor_->Init()); |
236 } | 300 } |
237 | 301 |
238 // Reset quantities after each encoder update, update the target | 302 // Reset quantities after each encoder update, update the target |
239 // per-frame bandwidth. | 303 // per-frame bandwidth. |
240 void ResetRateControlMetrics(int num_frames) { | 304 void ResetRateControlMetrics(int num_frames) { |
241 for (int i = 0; i < num_temporal_layers_; i++) { | 305 for (int i = 0; i < num_temporal_layers_; i++) { |
242 num_frames_per_update_[i] = 0; | 306 num_frames_per_update_[i] = 0; |
243 sum_frame_size_mismatch_[i] = 0.0f; | 307 sum_frame_size_mismatch_[i] = 0.0f; |
244 sum_encoded_frame_size_[i] = 0.0f; | 308 sum_encoded_frame_size_[i] = 0.0f; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 int num_key_frames) { | 376 int num_key_frames) { |
313 int num_dropped_frames = processor_->NumberDroppedFrames(); | 377 int num_dropped_frames = processor_->NumberDroppedFrames(); |
314 int num_resize_actions = processor_->NumberSpatialResizes(); | 378 int num_resize_actions = processor_->NumberSpatialResizes(); |
315 printf( | 379 printf( |
316 "For update #: %d,\n " | 380 "For update #: %d,\n " |
317 " Target Bitrate: %d,\n" | 381 " Target Bitrate: %d,\n" |
318 " Encoding bitrate: %f,\n" | 382 " Encoding bitrate: %f,\n" |
319 " Frame rate: %d \n", | 383 " Frame rate: %d \n", |
320 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); | 384 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); |
321 printf( | 385 printf( |
322 " Number of frames to approach target rate = %d, \n" | 386 " Number of frames to approach target rate: %d, \n" |
323 " Number of dropped frames = %d, \n" | 387 " Number of dropped frames: %d, \n" |
324 " Number of spatial resizes = %d, \n", | 388 " Number of spatial resizes: %d, \n", |
325 num_frames_to_hit_target_, num_dropped_frames, num_resize_actions); | 389 num_frames_to_hit_target_, num_dropped_frames, num_resize_actions); |
326 EXPECT_LE(perc_encoding_rate_mismatch_, max_encoding_rate_mismatch); | 390 EXPECT_LE(perc_encoding_rate_mismatch_, max_encoding_rate_mismatch); |
327 if (num_key_frames_ > 0) { | 391 if (num_key_frames_ > 0) { |
328 int perc_key_frame_size_mismatch = | 392 int perc_key_frame_size_mismatch = |
329 100 * sum_key_frame_size_mismatch_ / num_key_frames_; | 393 100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
330 printf( | 394 printf( |
331 " Number of Key frames: %d \n" | 395 " Number of Key frames: %d \n" |
332 " Key frame rate mismatch: %d \n", | 396 " Key frame rate mismatch: %d \n", |
333 num_key_frames_, perc_key_frame_size_mismatch); | 397 num_key_frames_, perc_key_frame_size_mismatch); |
334 EXPECT_LE(perc_key_frame_size_mismatch, max_key_frame_size_mismatch); | 398 EXPECT_LE(perc_key_frame_size_mismatch, max_key_frame_size_mismatch); |
335 } | 399 } |
336 printf("\n"); | 400 printf("\n"); |
337 printf("Rates statistics for Layer data \n"); | 401 printf("Rates statistics for Layer data \n"); |
338 for (int i = 0; i < num_temporal_layers_; i++) { | 402 for (int i = 0; i < num_temporal_layers_; i++) { |
339 printf("Layer #%d \n", i); | 403 printf("Temporal layer #%d \n", i); |
340 int perc_frame_size_mismatch = | 404 int perc_frame_size_mismatch = |
341 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; | 405 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; |
342 int perc_encoding_rate_mismatch = | 406 int perc_encoding_rate_mismatch = |
343 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / | 407 100 * fabs(encoding_bitrate_[i] - bit_rate_layer_[i]) / |
344 bit_rate_layer_[i]; | 408 bit_rate_layer_[i]; |
345 printf( | 409 printf( |
346 " Target Layer Bit rate: %f \n" | 410 " Target Layer Bit rate: %f \n" |
347 " Layer frame rate: %f, \n" | 411 " Layer frame rate: %f, \n" |
348 " Layer per frame bandwidth: %f, \n" | 412 " Layer per frame bandwidth: %f, \n" |
349 " Layer Encoding bit rate: %f, \n" | 413 " Layer Encoding bit rate: %f, \n" |
350 " Layer Percent frame size mismatch: %d, \n" | 414 " Layer Percent frame size mismatch: %d, \n" |
351 " Layer Percent encoding rate mismatch = %d, \n" | 415 " Layer Percent encoding rate mismatch: %d, \n" |
352 " Number of frame processed per layer = %d \n", | 416 " Number of frame processed per layer: %d \n", |
353 bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i], | 417 bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i], |
354 encoding_bitrate_[i], perc_frame_size_mismatch, | 418 encoding_bitrate_[i], perc_frame_size_mismatch, |
355 perc_encoding_rate_mismatch, num_frames_per_update_[i]); | 419 perc_encoding_rate_mismatch, num_frames_per_update_[i]); |
356 EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch); | 420 EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch); |
357 EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch); | 421 EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch); |
358 } | 422 } |
359 printf("\n"); | 423 printf("\n"); |
360 EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target); | 424 EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target); |
361 EXPECT_LE(num_dropped_frames, max_num_dropped_frames); | 425 EXPECT_LE(num_dropped_frames, max_num_dropped_frames); |
362 EXPECT_EQ(num_resize_actions, num_spatial_resizes); | 426 EXPECT_EQ(num_resize_actions, num_spatial_resizes); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; | 470 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio; |
407 } | 471 } |
408 frame_rate_layer_[i] = | 472 frame_rate_layer_[i] = |
409 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); | 473 frame_rate_ / static_cast<float>(1 << (num_temporal_layers_ - 1)); |
410 } | 474 } |
411 if (num_temporal_layers_ == 3) { | 475 if (num_temporal_layers_ == 3) { |
412 frame_rate_layer_[2] = frame_rate_ / 2.0f; | 476 frame_rate_layer_[2] = frame_rate_ / 2.0f; |
413 } | 477 } |
414 } | 478 } |
415 | 479 |
416 void TearDown() { | |
417 delete processor_; | |
418 delete packet_manipulator_; | |
419 delete frame_writer_; | |
420 delete frame_reader_; | |
421 delete decoder_; | |
422 delete encoder_; | |
423 } | |
424 | |
425 // Processes all frames in the clip and verifies the result. | 480 // Processes all frames in the clip and verifies the result. |
426 void ProcessFramesAndVerify(QualityMetrics quality_metrics, | 481 void ProcessFramesAndVerify(QualityMetrics quality_metrics, |
427 RateProfile rate_profile, | 482 RateProfile rate_profile, |
428 CodecConfigPars process, | 483 CodecConfigPars process, |
429 RateControlMetrics* rc_metrics) { | 484 RateControlMetrics* rc_metrics) { |
430 // Codec/config settings. | 485 // Codec/config settings. |
431 codec_type_ = process.codec_type; | 486 codec_type_ = process.codec_type; |
432 start_bitrate_ = rate_profile.target_bit_rate[0]; | 487 start_bitrate_ = rate_profile.target_bit_rate[0]; |
433 packet_loss_ = process.packet_loss; | 488 packet_loss_ = process.packet_loss; |
434 key_frame_interval_ = process.key_frame_interval; | 489 key_frame_interval_ = process.key_frame_interval; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 554 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
500 | 555 |
501 // Release encoder and decoder to make sure they have finished processing: | 556 // Release encoder and decoder to make sure they have finished processing: |
502 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | 557 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
503 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | 558 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); |
504 // Close the files before we start using them for SSIM/PSNR calculations. | 559 // Close the files before we start using them for SSIM/PSNR calculations. |
505 frame_reader_->Close(); | 560 frame_reader_->Close(); |
506 frame_writer_->Close(); | 561 frame_writer_->Close(); |
507 | 562 |
508 // TODO(marpan): should compute these quality metrics per SetRates update. | 563 // TODO(marpan): should compute these quality metrics per SetRates update. |
509 webrtc::test::QualityMetricsResult psnr_result, ssim_result; | 564 test::QualityMetricsResult psnr_result, ssim_result; |
510 EXPECT_EQ( | 565 EXPECT_EQ(0, test::I420MetricsFromFiles(config_.input_filename.c_str(), |
511 0, webrtc::test::I420MetricsFromFiles( | 566 config_.output_filename.c_str(), |
512 config_.input_filename.c_str(), config_.output_filename.c_str(), | 567 config_.codec_settings->width, |
513 config_.codec_settings->width, config_.codec_settings->height, | 568 config_.codec_settings->height, |
514 &psnr_result, &ssim_result)); | 569 &psnr_result, &ssim_result)); |
515 printf("PSNR avg: %f, min: %f SSIM avg: %f, min: %f\n", | 570 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
516 psnr_result.average, psnr_result.min, ssim_result.average, | 571 psnr_result.average, psnr_result.min, ssim_result.average, |
517 ssim_result.min); | 572 ssim_result.min); |
518 stats_.PrintSummary(); | 573 stats_.PrintSummary(); |
519 EXPECT_GT(psnr_result.average, quality_metrics.minimum_avg_psnr); | 574 EXPECT_GT(psnr_result.average, quality_metrics.minimum_avg_psnr); |
520 EXPECT_GT(psnr_result.min, quality_metrics.minimum_min_psnr); | 575 EXPECT_GT(psnr_result.min, quality_metrics.minimum_min_psnr); |
521 EXPECT_GT(ssim_result.average, quality_metrics.minimum_avg_ssim); | 576 EXPECT_GT(ssim_result.average, quality_metrics.minimum_avg_ssim); |
522 EXPECT_GT(ssim_result.min, quality_metrics.minimum_min_ssim); | 577 EXPECT_GT(ssim_result.min, quality_metrics.minimum_min_ssim); |
523 if (remove(config_.output_filename.c_str()) < 0) { | 578 if (remove(config_.output_filename.c_str()) < 0) { |
524 fprintf(stderr, "Failed to remove temporary file!\n"); | 579 fprintf(stderr, "Failed to remove temporary file!\n"); |
525 } | 580 } |
526 } | 581 } |
527 }; | 582 }; |
528 | 583 |
529 void SetRateProfilePars(RateProfile* rate_profile, | |
530 int update_index, | |
531 int bit_rate, | |
532 int frame_rate, | |
533 int frame_index_rate_update) { | |
534 rate_profile->target_bit_rate[update_index] = bit_rate; | |
535 rate_profile->input_frame_rate[update_index] = frame_rate; | |
536 rate_profile->frame_index_rate_update[update_index] = frame_index_rate_update; | |
537 } | |
538 | |
539 void SetCodecParameters(CodecConfigPars* process_settings, | |
540 VideoCodecType codec_type, | |
541 float packet_loss, | |
542 int key_frame_interval, | |
543 int num_temporal_layers, | |
544 bool error_concealment_on, | |
545 bool denoising_on, | |
546 bool frame_dropper_on, | |
547 bool spatial_resize_on) { | |
548 process_settings->codec_type = codec_type; | |
549 process_settings->packet_loss = packet_loss; | |
550 process_settings->key_frame_interval = key_frame_interval; | |
551 process_settings->num_temporal_layers = num_temporal_layers, | |
552 process_settings->error_concealment_on = error_concealment_on; | |
553 process_settings->denoising_on = denoising_on; | |
554 process_settings->frame_dropper_on = frame_dropper_on; | |
555 process_settings->spatial_resize_on = spatial_resize_on; | |
556 } | |
557 | |
558 void SetQualityMetrics(QualityMetrics* quality_metrics, | |
559 double minimum_avg_psnr, | |
560 double minimum_min_psnr, | |
561 double minimum_avg_ssim, | |
562 double minimum_min_ssim) { | |
563 quality_metrics->minimum_avg_psnr = minimum_avg_psnr; | |
564 quality_metrics->minimum_min_psnr = minimum_min_psnr; | |
565 quality_metrics->minimum_avg_ssim = minimum_avg_ssim; | |
566 quality_metrics->minimum_min_ssim = minimum_min_ssim; | |
567 } | |
568 | |
569 void SetRateControlMetrics(RateControlMetrics* rc_metrics, | |
570 int update_index, | |
571 int max_num_dropped_frames, | |
572 int max_key_frame_size_mismatch, | |
573 int max_delta_frame_size_mismatch, | |
574 int max_encoding_rate_mismatch, | |
575 int max_time_hit_target, | |
576 int num_spatial_resizes, | |
577 int num_key_frames) { | |
578 rc_metrics[update_index].max_num_dropped_frames = max_num_dropped_frames; | |
579 rc_metrics[update_index].max_key_frame_size_mismatch = | |
580 max_key_frame_size_mismatch; | |
581 rc_metrics[update_index].max_delta_frame_size_mismatch = | |
582 max_delta_frame_size_mismatch; | |
583 rc_metrics[update_index].max_encoding_rate_mismatch = | |
584 max_encoding_rate_mismatch; | |
585 rc_metrics[update_index].max_time_hit_target = max_time_hit_target; | |
586 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes; | |
587 rc_metrics[update_index].num_key_frames = num_key_frames; | |
588 } | |
589 | |
590 #if defined(WEBRTC_VIDEOPROCESSOR_H264_TESTS) | 584 #if defined(WEBRTC_VIDEOPROCESSOR_H264_TESTS) |
591 | 585 |
592 // H264: Run with no packet loss and fixed bitrate. Quality should be very high. | 586 // H264: Run with no packet loss and fixed bitrate. Quality should be very high. |
593 // Note(hbos): The PacketManipulatorImpl code used to simulate packet loss in | 587 // Note(hbos): The PacketManipulatorImpl code used to simulate packet loss in |
594 // these unittests appears to drop "packets" in a way that is not compatible | 588 // these unittests appears to drop "packets" in a way that is not compatible |
595 // with H264. Therefore ProcessXPercentPacketLossH264, X != 0, unittests have | 589 // with H264. Therefore ProcessXPercentPacketLossH264, X != 0, unittests have |
596 // not been added. | 590 // not been added. |
597 TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) { | 591 TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossH264) { |
598 // Bitrate and frame rate profile. | 592 // Bitrate and frame rate profile. |
599 RateProfile rate_profile; | 593 RateProfile rate_profile; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 QualityMetrics quality_metrics; | 955 QualityMetrics quality_metrics; |
962 SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80); | 956 SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80); |
963 // Metrics for rate control. | 957 // Metrics for rate control. |
964 RateControlMetrics rc_metrics[2]; | 958 RateControlMetrics rc_metrics[2]; |
965 SetRateControlMetrics(rc_metrics, 0, 0, 20, 30, 10, 10, 0, 1); | 959 SetRateControlMetrics(rc_metrics, 0, 0, 20, 30, 10, 10, 0, 1); |
966 SetRateControlMetrics(rc_metrics, 1, 0, 0, 30, 15, 10, 0, 0); | 960 SetRateControlMetrics(rc_metrics, 1, 0, 0, 30, 15, 10, 0, 0); |
967 ProcessFramesAndVerify(quality_metrics, rate_profile, process_settings, | 961 ProcessFramesAndVerify(quality_metrics, rate_profile, process_settings, |
968 rc_metrics); | 962 rc_metrics); |
969 } | 963 } |
970 } // namespace webrtc | 964 } // namespace webrtc |
OLD | NEW |