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 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ | 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTEST_H
_ |
13 | 13 |
14 #include <math.h> | 14 #include <math.h> |
15 | 15 |
16 #include <limits> | 16 #include <limits> |
17 #include <memory> | 17 #include <memory> |
18 #include <string> | 18 #include <string> |
19 #include <utility> | 19 #include <utility> |
| 20 #include <vector> |
20 | 21 |
21 #if defined(WEBRTC_ANDROID) | 22 #if defined(WEBRTC_ANDROID) |
22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" | 23 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" |
23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" | 24 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" |
24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" | 25 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" |
25 #elif defined(WEBRTC_IOS) | 26 #elif defined(WEBRTC_IOS) |
26 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" | 27 #include "webrtc/modules/video_coding/codecs/test/objc_codec_h264_test.h" |
27 #endif | 28 #endif |
28 | 29 |
29 #include "webrtc/media/engine/internaldecoderfactory.h" | 30 #include "webrtc/media/engine/internaldecoderfactory.h" |
30 #include "webrtc/media/engine/internalencoderfactory.h" | 31 #include "webrtc/media/engine/internalencoderfactory.h" |
31 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" | 32 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
33 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 34 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
34 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 35 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
35 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 36 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
36 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 37 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
37 #include "webrtc/modules/video_coding/include/video_coding.h" | 38 #include "webrtc/modules/video_coding/include/video_coding.h" |
38 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" | 39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" |
39 #include "webrtc/rtc_base/checks.h" | 40 #include "webrtc/rtc_base/checks.h" |
| 41 #include "webrtc/rtc_base/event.h" |
40 #include "webrtc/rtc_base/file.h" | 42 #include "webrtc/rtc_base/file.h" |
41 #include "webrtc/rtc_base/logging.h" | 43 #include "webrtc/rtc_base/logging.h" |
42 #include "webrtc/rtc_base/ptr_util.h" | 44 #include "webrtc/rtc_base/ptr_util.h" |
| 45 #include "webrtc/system_wrappers/include/sleep.h" |
43 #include "webrtc/test/gtest.h" | 46 #include "webrtc/test/gtest.h" |
44 #include "webrtc/test/testsupport/fileutils.h" | 47 #include "webrtc/test/testsupport/fileutils.h" |
45 #include "webrtc/test/testsupport/frame_reader.h" | 48 #include "webrtc/test/testsupport/frame_reader.h" |
46 #include "webrtc/test/testsupport/frame_writer.h" | 49 #include "webrtc/test/testsupport/frame_writer.h" |
47 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 50 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
48 #include "webrtc/test/testsupport/packet_reader.h" | 51 #include "webrtc/test/testsupport/packet_reader.h" |
49 #include "webrtc/test/video_codec_settings.h" | 52 #include "webrtc/test/video_codec_settings.h" |
50 #include "webrtc/typedefs.h" | 53 #include "webrtc/typedefs.h" |
51 | 54 |
52 namespace webrtc { | 55 namespace webrtc { |
53 namespace test { | 56 namespace test { |
54 | 57 |
55 const int kMaxNumRateUpdates = 3; | 58 const int kMaxNumRateUpdates = 3; |
56 const int kMaxNumTemporalLayers = 3; | 59 const int kMaxNumTemporalLayers = 3; |
57 | 60 |
58 const int kPercTargetvsActualMismatch = 20; | 61 const int kPercTargetvsActualMismatch = 20; |
59 const int kBaseKeyFrameInterval = 3000; | 62 const int kBaseKeyFrameInterval = 3000; |
60 | 63 |
61 // Parameters from VP8 wrapper, which control target size of key frames. | 64 // Parameters from VP8 wrapper, which control target size of key frames. |
62 const float kInitialBufferSize = 0.5f; | 65 const float kInitialBufferSize = 0.5f; |
63 const float kOptimalBufferSize = 0.6f; | 66 const float kOptimalBufferSize = 0.6f; |
64 const float kScaleKeyFrameSize = 0.5f; | 67 const float kScaleKeyFrameSize = 0.5f; |
65 | 68 |
66 // Thresholds for the quality metrics. Defaults are maximally minimal. | 69 // Thresholds for the quality metrics. Defaults are maximally minimal. |
67 struct QualityThresholds { | 70 struct QualityThresholds { |
68 QualityThresholds() {} | |
69 QualityThresholds(double min_avg_psnr, | 71 QualityThresholds(double min_avg_psnr, |
70 double min_min_psnr, | 72 double min_min_psnr, |
71 double min_avg_ssim, | 73 double min_avg_ssim, |
72 double min_min_ssim) | 74 double min_min_ssim) |
73 : min_avg_psnr(min_avg_psnr), | 75 : min_avg_psnr(min_avg_psnr), |
74 min_min_psnr(min_min_psnr), | 76 min_min_psnr(min_min_psnr), |
75 min_avg_ssim(min_avg_ssim), | 77 min_avg_ssim(min_avg_ssim), |
76 min_min_ssim(min_min_ssim) {} | 78 min_min_ssim(min_min_ssim) {} |
77 double min_avg_psnr = std::numeric_limits<double>::min(); | 79 double min_avg_psnr; |
78 double min_min_psnr = std::numeric_limits<double>::min(); | 80 double min_min_psnr; |
79 double min_avg_ssim = 0.0; | 81 double min_avg_ssim; |
80 double min_min_ssim = 0.0; | 82 double min_min_ssim; |
81 }; | 83 }; |
82 | 84 |
83 // The sequence of bit rate and frame rate changes for the encoder, the frame | 85 // The sequence of bit rate and frame rate changes for the encoder, the frame |
84 // number where the changes are made, and the total number of frames for the | 86 // number where the changes are made, and the total number of frames for the |
85 // test. | 87 // test. |
86 struct RateProfile { | 88 struct RateProfile { |
87 int target_bit_rate[kMaxNumRateUpdates]; | 89 int target_bit_rate[kMaxNumRateUpdates]; |
88 int input_frame_rate[kMaxNumRateUpdates]; | 90 int input_frame_rate[kMaxNumRateUpdates]; |
89 int frame_index_rate_update[kMaxNumRateUpdates + 1]; | 91 int frame_index_rate_update[kMaxNumRateUpdates + 1]; |
90 int num_frames; | 92 int num_frames; |
91 }; | 93 }; |
92 | 94 |
93 // Thresholds for the rate control metrics. The rate mismatch thresholds are | 95 // Thresholds for the rate control metrics. The rate mismatch thresholds are |
94 // defined as percentages. |max_time_hit_target| is defined as number of frames, | 96 // defined as percentages. |max_time_hit_target| is defined as number of frames, |
95 // after a rate update is made to the encoder, for the encoder to reach within | 97 // after a rate update is made to the encoder, for the encoder to reach within |
96 // |kPercTargetvsActualMismatch| of new target rate. The thresholds are defined | 98 // |kPercTargetvsActualMismatch| of new target rate. The thresholds are defined |
97 // for each rate update sequence. | 99 // for each rate update sequence. |
98 struct RateControlThresholds { | 100 struct RateControlThresholds { |
99 int max_num_dropped_frames; | 101 int max_num_dropped_frames; |
100 int max_key_frame_size_mismatch; | 102 int max_key_frame_size_mismatch; |
101 int max_delta_frame_size_mismatch; | 103 int max_delta_frame_size_mismatch; |
102 int max_encoding_rate_mismatch; | 104 int max_encoding_rate_mismatch; |
103 int max_time_hit_target; | 105 int max_time_hit_target; |
104 int num_spatial_resizes; // Set to -1 to disable check. | 106 int num_spatial_resizes; |
105 int num_key_frames; // Set to -1 to disable check. | 107 int num_key_frames; |
106 }; | 108 }; |
107 | 109 |
108 // Should video files be saved persistently to disk for post-run visualization? | 110 // Should video files be saved persistently to disk for post-run visualization? |
109 struct VisualizationParams { | 111 struct VisualizationParams { |
110 bool save_encoded_ivf; | 112 bool save_encoded_ivf; |
111 bool save_decoded_y4m; | 113 bool save_decoded_y4m; |
112 }; | 114 }; |
113 | 115 |
114 // Integration test for video processor. Encodes+decodes a clip and | 116 // Integration test for video processor. Encodes+decodes a clip and |
115 // writes it to the output directory. After completion, quality metrics | 117 // writes it to the output directory. After completion, quality metrics |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 177 |
176 EXPECT_TRUE(encoder_) << "Encoder not successfully created."; | 178 EXPECT_TRUE(encoder_) << "Encoder not successfully created."; |
177 EXPECT_TRUE(decoder_) << "Decoder not successfully created."; | 179 EXPECT_TRUE(decoder_) << "Decoder not successfully created."; |
178 } | 180 } |
179 | 181 |
180 void DestroyEncoderAndDecoder() { | 182 void DestroyEncoderAndDecoder() { |
181 encoder_factory_->DestroyVideoEncoder(encoder_); | 183 encoder_factory_->DestroyVideoEncoder(encoder_); |
182 decoder_factory_->DestroyVideoDecoder(decoder_); | 184 decoder_factory_->DestroyVideoDecoder(decoder_); |
183 } | 185 } |
184 | 186 |
185 void SetUpObjects(const VisualizationParams* visualization_params, | 187 void SetUpAndInitObjects(rtc::TaskQueue* task_queue, |
186 const int initial_bitrate_kbps, | 188 const int initial_bitrate_kbps, |
187 const int initial_framerate_fps) { | 189 const int initial_framerate_fps, |
| 190 const VisualizationParams* visualization_params) { |
188 CreateEncoderAndDecoder(); | 191 CreateEncoderAndDecoder(); |
189 | 192 |
190 // Create file objects for quality analysis. | 193 // Create file objects for quality analysis. |
191 analysis_frame_reader_.reset(new YuvFrameReaderImpl( | 194 analysis_frame_reader_.reset(new YuvFrameReaderImpl( |
192 config_.input_filename, config_.codec_settings.width, | 195 config_.input_filename, config_.codec_settings.width, |
193 config_.codec_settings.height)); | 196 config_.codec_settings.height)); |
194 analysis_frame_writer_.reset(new YuvFrameWriterImpl( | 197 analysis_frame_writer_.reset(new YuvFrameWriterImpl( |
195 config_.output_filename, config_.codec_settings.width, | 198 config_.output_filename, config_.codec_settings.width, |
196 config_.codec_settings.height)); | 199 config_.codec_settings.height)); |
197 EXPECT_TRUE(analysis_frame_reader_->Init()); | 200 EXPECT_TRUE(analysis_frame_reader_->Init()); |
(...skipping 19 matching lines...) Expand all Loading... |
217 if (visualization_params->save_decoded_y4m) { | 220 if (visualization_params->save_decoded_y4m) { |
218 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( | 221 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( |
219 output_filename_base + ".y4m", config_.codec_settings.width, | 222 output_filename_base + ".y4m", config_.codec_settings.width, |
220 config_.codec_settings.height, initial_framerate_fps)); | 223 config_.codec_settings.height, initial_framerate_fps)); |
221 EXPECT_TRUE(decoded_frame_writer_->Init()); | 224 EXPECT_TRUE(decoded_frame_writer_->Init()); |
222 } | 225 } |
223 } | 226 } |
224 | 227 |
225 packet_manipulator_.reset(new PacketManipulatorImpl( | 228 packet_manipulator_.reset(new PacketManipulatorImpl( |
226 &packet_reader_, config_.networking_config, config_.verbose)); | 229 &packet_reader_, config_.networking_config, config_.verbose)); |
227 processor_ = rtc::MakeUnique<VideoProcessor>( | 230 |
228 encoder_, decoder_, analysis_frame_reader_.get(), | 231 config_.codec_settings.startBitrate = initial_bitrate_kbps; |
229 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 232 |
230 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); | 233 rtc::Event sync_event(false, false); |
231 processor_->Init(); | 234 task_queue->PostTask([this, &sync_event]() { |
| 235 processor_ = rtc::MakeUnique<VideoProcessor>( |
| 236 encoder_, decoder_, analysis_frame_reader_.get(), |
| 237 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
| 238 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); |
| 239 processor_->Init(); |
| 240 sync_event.Set(); |
| 241 }); |
| 242 sync_event.Wait(rtc::Event::kForever); |
| 243 } |
| 244 |
| 245 void ReleaseAndCloseObjects(rtc::TaskQueue* task_queue) { |
| 246 rtc::Event sync_event(false, false); |
| 247 task_queue->PostTask([this, &sync_event]() { |
| 248 processor_->Release(); |
| 249 sync_event.Set(); |
| 250 }); |
| 251 sync_event.Wait(rtc::Event::kForever); |
| 252 |
| 253 // The VideoProcessor must be ::Release()'d before we destroy the codecs. |
| 254 DestroyEncoderAndDecoder(); |
| 255 |
| 256 // Close the analysis files before we use them for SSIM/PSNR calculations. |
| 257 analysis_frame_reader_->Close(); |
| 258 analysis_frame_writer_->Close(); |
| 259 |
| 260 // Close visualization files. |
| 261 if (encoded_frame_writer_) { |
| 262 EXPECT_TRUE(encoded_frame_writer_->Close()); |
| 263 } |
| 264 if (decoded_frame_writer_) { |
| 265 decoded_frame_writer_->Close(); |
| 266 } |
232 } | 267 } |
233 | 268 |
234 // Reset quantities after each encoder update, update the target per-frame | 269 // Reset quantities after each encoder update, update the target per-frame |
235 // bandwidth. | 270 // bandwidth. |
236 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 271 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
237 const int num_temporal_layers = | 272 const int num_temporal_layers = |
238 NumberOfTemporalLayers(config_.codec_settings); | 273 NumberOfTemporalLayers(config_.codec_settings); |
239 for (int i = 0; i < num_temporal_layers; i++) { | 274 for (int i = 0; i < num_temporal_layers; i++) { |
240 num_frames_per_update_[i] = 0; | 275 num_frames_per_update_[i] = 0; |
241 sum_frame_size_mismatch_[i] = 0.0f; | 276 sum_frame_size_mismatch_[i] = 0.0f; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 perc_encoding_rate_mismatch_ = | 335 perc_encoding_rate_mismatch_ = |
301 100 * fabs(encoding_bitrate_total_ - bitrate_kbps_) / bitrate_kbps_; | 336 100 * fabs(encoding_bitrate_total_ - bitrate_kbps_) / bitrate_kbps_; |
302 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 337 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
303 !encoding_rate_within_target_) { | 338 !encoding_rate_within_target_) { |
304 num_frames_to_hit_target_ = num_frames_total_; | 339 num_frames_to_hit_target_ = num_frames_total_; |
305 encoding_rate_within_target_ = true; | 340 encoding_rate_within_target_ = true; |
306 } | 341 } |
307 } | 342 } |
308 | 343 |
309 // Verify expected behavior of rate control and print out data. | 344 // Verify expected behavior of rate control and print out data. |
310 void VerifyRateControlMetrics(int rate_update_index, | 345 void PrintAndMaybeVerifyRateControlMetrics( |
311 const RateControlThresholds& rc_expected) { | 346 int rate_update_index, |
312 int num_dropped_frames = processor_->NumberDroppedFrames(); | 347 const std::vector<RateControlThresholds>* rc_thresholds, |
313 int num_resize_actions = processor_->NumberSpatialResizes(); | 348 const std::vector<int>& num_dropped_frames, |
| 349 const std::vector<int>& num_resize_actions) { |
| 350 const RateControlThresholds* rc_threshold = nullptr; |
| 351 if (rc_thresholds) { |
| 352 rc_threshold = &(*rc_thresholds)[rate_update_index]; |
| 353 |
| 354 EXPECT_LE(perc_encoding_rate_mismatch_, |
| 355 rc_threshold->max_encoding_rate_mismatch); |
| 356 } |
| 357 |
314 printf( | 358 printf( |
315 "Rate update #%d:\n" | 359 "Rate update #%d:\n" |
316 " Target bitrate : %d\n" | 360 " Target bitrate : %d\n" |
317 " Encoded bitrate : %f\n" | 361 " Encoded bitrate : %f\n" |
318 " Frame rate : %d\n", | 362 " Frame rate : %d\n", |
319 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_); | 363 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_); |
320 printf( | 364 printf( |
321 " # processed frames : %d\n" | 365 " # processed frames : %d\n" |
322 " # frames to convergence: %d\n" | 366 " # frames to convergence: %d\n" |
323 " # dropped frames : %d\n" | 367 " # dropped frames : %d\n" |
324 " # spatial resizes : %d\n", | 368 " # spatial resizes : %d\n", |
325 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, | 369 num_frames_total_, num_frames_to_hit_target_, |
326 num_resize_actions); | 370 num_dropped_frames[rate_update_index], |
| 371 num_resize_actions[rate_update_index]); |
327 | 372 |
328 EXPECT_LE(perc_encoding_rate_mismatch_, | |
329 rc_expected.max_encoding_rate_mismatch); | |
330 if (num_key_frames_ > 0) { | 373 if (num_key_frames_ > 0) { |
331 int perc_key_frame_size_mismatch = | 374 int perc_key_frame_size_mismatch = |
332 100 * sum_key_frame_size_mismatch_ / num_key_frames_; | 375 100 * sum_key_frame_size_mismatch_ / num_key_frames_; |
333 printf( | 376 printf( |
334 " # key frames : %d\n" | 377 " # key frames : %d\n" |
335 " Key frame rate mismatch: %d\n", | 378 " Key frame rate mismatch: %d\n", |
336 num_key_frames_, perc_key_frame_size_mismatch); | 379 num_key_frames_, perc_key_frame_size_mismatch); |
337 EXPECT_LE(perc_key_frame_size_mismatch, | 380 if (rc_threshold) { |
338 rc_expected.max_key_frame_size_mismatch); | 381 EXPECT_LE(perc_key_frame_size_mismatch, |
| 382 rc_threshold->max_key_frame_size_mismatch); |
| 383 } |
339 } | 384 } |
340 | 385 |
341 const int num_temporal_layers = | 386 const int num_temporal_layers = |
342 NumberOfTemporalLayers(config_.codec_settings); | 387 NumberOfTemporalLayers(config_.codec_settings); |
343 for (int i = 0; i < num_temporal_layers; i++) { | 388 for (int i = 0; i < num_temporal_layers; i++) { |
344 int perc_frame_size_mismatch = | 389 int perc_frame_size_mismatch = |
345 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; | 390 100 * sum_frame_size_mismatch_[i] / num_frames_per_update_[i]; |
346 int perc_encoding_rate_mismatch = | 391 int perc_encoding_rate_mismatch = |
347 100 * fabs(encoding_bitrate_[i] - bitrate_layer_[i]) / | 392 100 * fabs(encoding_bitrate_[i] - bitrate_layer_[i]) / |
348 bitrate_layer_[i]; | 393 bitrate_layer_[i]; |
349 printf( | 394 printf( |
350 " Temporal layer #%d:\n" | 395 " Temporal layer #%d:\n" |
351 " Target layer bitrate : %f\n" | 396 " Target layer bitrate : %f\n" |
352 " Layer frame rate : %f\n" | 397 " Layer frame rate : %f\n" |
353 " Layer per frame bandwidth : %f\n" | 398 " Layer per frame bandwidth : %f\n" |
354 " Layer encoding bitrate : %f\n" | 399 " Layer encoding bitrate : %f\n" |
355 " Layer percent frame size mismatch : %d\n" | 400 " Layer percent frame size mismatch : %d\n" |
356 " Layer percent encoding rate mismatch: %d\n" | 401 " Layer percent encoding rate mismatch: %d\n" |
357 " # frames processed per layer : %d\n", | 402 " # frames processed per layer : %d\n", |
358 i, bitrate_layer_[i], framerate_layer_[i], per_frame_bandwidth_[i], | 403 i, bitrate_layer_[i], framerate_layer_[i], per_frame_bandwidth_[i], |
359 encoding_bitrate_[i], perc_frame_size_mismatch, | 404 encoding_bitrate_[i], perc_frame_size_mismatch, |
360 perc_encoding_rate_mismatch, num_frames_per_update_[i]); | 405 perc_encoding_rate_mismatch, num_frames_per_update_[i]); |
361 EXPECT_LE(perc_frame_size_mismatch, | 406 if (rc_threshold) { |
362 rc_expected.max_delta_frame_size_mismatch); | 407 EXPECT_LE(perc_frame_size_mismatch, |
363 EXPECT_LE(perc_encoding_rate_mismatch, | 408 rc_threshold->max_delta_frame_size_mismatch); |
364 rc_expected.max_encoding_rate_mismatch); | 409 EXPECT_LE(perc_encoding_rate_mismatch, |
| 410 rc_threshold->max_encoding_rate_mismatch); |
| 411 } |
365 } | 412 } |
366 printf("\n"); | 413 printf("\n"); |
367 | 414 |
368 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 415 if (rc_threshold) { |
369 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); | 416 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target); |
370 if (rc_expected.num_spatial_resizes >= 0) { | 417 EXPECT_LE(num_dropped_frames[rate_update_index], |
371 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 418 rc_threshold->max_num_dropped_frames); |
372 } | 419 EXPECT_EQ(rc_threshold->num_spatial_resizes, |
373 if (rc_expected.num_key_frames >= 0) { | 420 num_resize_actions[rate_update_index]); |
374 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 421 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_); |
375 } | 422 } |
376 } | 423 } |
377 | 424 |
378 static void VerifyQuality(const QualityMetricsResult& psnr_result, | 425 static void VerifyQuality(const QualityMetricsResult& psnr_result, |
379 const QualityMetricsResult& ssim_result, | 426 const QualityMetricsResult& ssim_result, |
380 const QualityThresholds& quality_thresholds) { | 427 const QualityThresholds& quality_thresholds) { |
381 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 428 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
382 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 429 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
383 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 430 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
384 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 431 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
385 } | 432 } |
386 | 433 |
387 void VerifyQpParser(int frame_number) { | |
388 if (!config_.hw_codec && | |
389 (config_.codec_settings.codecType == kVideoCodecVP8 || | |
390 config_.codec_settings.codecType == kVideoCodecVP9)) { | |
391 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), | |
392 processor_->GetQpFromBitstream(frame_number)); | |
393 } | |
394 } | |
395 | |
396 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) { | 434 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) { |
397 if (codec_settings.codecType == kVideoCodecVP8) { | 435 if (codec_settings.codecType == kVideoCodecVP8) { |
398 return codec_settings.VP8().numberOfTemporalLayers; | 436 return codec_settings.VP8().numberOfTemporalLayers; |
399 } else if (codec_settings.codecType == kVideoCodecVP9) { | 437 } else if (codec_settings.codecType == kVideoCodecVP9) { |
400 return codec_settings.VP9().numberOfTemporalLayers; | 438 return codec_settings.VP9().numberOfTemporalLayers; |
401 } else { | 439 } else { |
402 return 1; | 440 return 1; |
403 } | 441 } |
404 } | 442 } |
405 | 443 |
(...skipping 23 matching lines...) Expand all Loading... |
429 tl_idx = 2; | 467 tl_idx = 2; |
430 } | 468 } |
431 break; | 469 break; |
432 default: | 470 default: |
433 RTC_NOTREACHED(); | 471 RTC_NOTREACHED(); |
434 break; | 472 break; |
435 } | 473 } |
436 return tl_idx; | 474 return tl_idx; |
437 } | 475 } |
438 | 476 |
439 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. | 477 void UpdateRates(int rate_update_index, const RateProfile& rate_profile) { |
440 void SetTemporalLayerRates() { | 478 bitrate_kbps_ = rate_profile.target_bit_rate[rate_update_index]; |
| 479 framerate_ = rate_profile.input_frame_rate[rate_update_index]; |
| 480 |
441 const int num_temporal_layers = | 481 const int num_temporal_layers = |
442 NumberOfTemporalLayers(config_.codec_settings); | 482 NumberOfTemporalLayers(config_.codec_settings); |
443 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); | 483 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); |
444 for (int i = 0; i < num_temporal_layers; i++) { | 484 for (int i = 0; i < num_temporal_layers; i++) { |
445 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; | 485 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; |
446 if (i > 0) { | 486 if (i > 0) { |
447 float bit_rate_delta_ratio = | 487 float bit_rate_delta_ratio = |
448 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - | 488 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - |
449 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; | 489 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; |
450 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio; | 490 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio; |
451 } else { | 491 } else { |
452 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio; | 492 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio; |
453 } | 493 } |
454 framerate_layer_[i] = | 494 framerate_layer_[i] = |
455 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1)); | 495 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1)); |
456 } | 496 } |
457 if (num_temporal_layers == 3) { | 497 if (num_temporal_layers == 3) { |
458 framerate_layer_[2] = framerate_ / 2.0f; | 498 framerate_layer_[2] = framerate_ / 2.0f; |
459 } | 499 } |
460 } | 500 } |
461 | 501 |
462 // Processes all frames in the clip and verifies the result. | 502 // Processes all frames in the clip and verifies the result. |
463 // TODO(brandtr): Change the second last argument to be a | 503 void ProcessFramesAndMaybeVerify( |
464 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 504 const RateProfile& rate_profile, |
465 // does not expect us to do mid-clip rate updates when we are not able to, | 505 const std::vector<RateControlThresholds>* rc_thresholds, |
466 // e.g., when we are operating in batch mode. | 506 const QualityThresholds* quality_thresholds, |
467 void ProcessFramesAndVerify(const QualityThresholds& quality_thresholds, | 507 const VisualizationParams* visualization_params) { |
468 const RateProfile& rate_profile, | 508 // The Android HW codec needs to be run on a task queue, so we simply always |
469 RateControlThresholds* rc_thresholds, | 509 // run the test on a task queue. |
470 const VisualizationParams* visualization_params) { | 510 rtc::TaskQueue task_queue("VidProc TQ"); |
471 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; | 511 rtc::Event sync_event(false, false); |
472 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], | 512 |
473 rate_profile.input_frame_rate[0]); | 513 SetUpAndInitObjects(&task_queue, rate_profile.target_bit_rate[0], |
| 514 rate_profile.input_frame_rate[0], visualization_params); |
474 | 515 |
475 // Set initial rates. | 516 // Set initial rates. |
476 bitrate_kbps_ = rate_profile.target_bit_rate[0]; | 517 int rate_update_index = 0; |
477 framerate_ = rate_profile.input_frame_rate[0]; | 518 task_queue.PostTask([this, &rate_profile, rate_update_index] { |
478 SetTemporalLayerRates(); | 519 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index], |
479 // Set the initial target size for key frame. | 520 rate_profile.input_frame_rate[rate_update_index]); |
| 521 }); |
| 522 |
| 523 // Process all frames. |
| 524 int frame_number = 0; |
| 525 const int num_frames = rate_profile.num_frames; |
| 526 RTC_DCHECK_GE(num_frames, 1); |
| 527 while (frame_number < num_frames) { |
| 528 // In order to not overwhelm the OpenMAX buffers in the Android |
| 529 // MediaCodec API, we roughly pace the frames here. The downside |
| 530 // of this is that the encode run will be done in real-time. |
| 531 // TODO(brandtr): Investigate if this is needed on iOS. |
| 532 if (config_.hw_codec) { |
| 533 SleepMs(rtc::kNumMillisecsPerSec / |
| 534 rate_profile.input_frame_rate[rate_update_index]); |
| 535 } |
| 536 |
| 537 task_queue.PostTask( |
| 538 [this, frame_number] { processor_->ProcessFrame(frame_number); }); |
| 539 ++frame_number; |
| 540 |
| 541 if (frame_number == |
| 542 rate_profile.frame_index_rate_update[rate_update_index + 1]) { |
| 543 ++rate_update_index; |
| 544 |
| 545 task_queue.PostTask([this, &rate_profile, rate_update_index] { |
| 546 processor_->SetRates( |
| 547 rate_profile.target_bit_rate[rate_update_index], |
| 548 rate_profile.input_frame_rate[rate_update_index]); |
| 549 }); |
| 550 } |
| 551 } |
| 552 |
| 553 // TODO(brandtr): Verify the assumption that HW codecs never |
| 554 // drop frames internally. |
| 555 if (config_.hw_codec) { |
| 556 // Ensure that all the frames have been encoded and decoded. |
| 557 int last_decoded_frame_num = -1; |
| 558 int wait_count = 0; |
| 559 while (last_decoded_frame_num != (num_frames - 1) && wait_count++ < 10) { |
| 560 sync_event.Reset(); |
| 561 task_queue.PostTask([this, &last_decoded_frame_num, &sync_event]() { |
| 562 last_decoded_frame_num = processor_->LastDecodedFrameNumber(); |
| 563 sync_event.Set(); |
| 564 }); |
| 565 sync_event.Wait(rtc::Event::kForever); |
| 566 |
| 567 SleepMs(1000); |
| 568 } |
| 569 EXPECT_LT(wait_count, 10) << "Lost frames in the VideoProcessor."; |
| 570 } |
| 571 |
| 572 ReleaseAndCloseObjects(&task_queue); |
| 573 |
| 574 // Verify QP parsing. |
| 575 // TODO(brandtr): This verification is somewhat orthogonal to the rest of |
| 576 // this test, which is focused on measuring image quality and rate control |
| 577 // quality. We should create a whole separate test that verifies the QP |
| 578 // parsing. This could be done by instantiating a VideoProcessor, encoding |
| 579 // a number of frames, and then verifying the parsing. |
| 580 if (!config_.hw_codec && |
| 581 (config_.codec_settings.codecType == kVideoCodecVP8 || |
| 582 config_.codec_settings.codecType == kVideoCodecVP9)) { |
| 583 for (int frame_number = 0; frame_number < num_frames; ++frame_number) { |
| 584 task_queue.PostTask([this, frame_number] { |
| 585 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number), |
| 586 processor_->GetQpFromBitstream(frame_number)); |
| 587 }); |
| 588 } |
| 589 } |
| 590 |
| 591 // Calculate and print rate control statistics. |
| 592 rate_update_index = 0; |
| 593 frame_number = 0; |
| 594 UpdateRates(rate_update_index, rate_profile); |
| 595 ResetRateControlMetrics( |
| 596 rate_profile.frame_index_rate_update[rate_update_index + 1]); |
480 target_size_key_frame_initial_ = | 597 target_size_key_frame_initial_ = |
481 0.5 * kInitialBufferSize * bitrate_layer_[0]; | 598 0.5 * kInitialBufferSize * bitrate_layer_[0]; |
482 processor_->SetRates(bitrate_kbps_, framerate_); | 599 std::vector<int> num_dropped_frames; |
| 600 std::vector<int> num_resize_actions; |
| 601 sync_event.Reset(); |
| 602 task_queue.PostTask( |
| 603 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() { |
| 604 num_dropped_frames = processor_->NumberDroppedFramesPerRateUpdate(); |
| 605 num_resize_actions = processor_->NumberSpatialResizesPerRateUpdate(); |
| 606 sync_event.Set(); |
| 607 }); |
| 608 sync_event.Wait(rtc::Event::kForever); |
| 609 while (frame_number < num_frames) { |
| 610 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
| 611 ++num_frames_total_; |
| 612 UpdateRateControlMetrics(frame_number); |
483 | 613 |
484 // Process each frame, up to |num_frames|. | 614 ++frame_number; |
485 int frame_number = 0; | |
486 int update_index = 0; | |
487 int num_frames = rate_profile.num_frames; | |
488 ResetRateControlMetrics( | |
489 rate_profile.frame_index_rate_update[update_index + 1]); | |
490 | 615 |
491 if (config_.batch_mode) { | 616 if (frame_number == |
492 // In batch mode, we calculate the metrics for all frames after all frames | 617 rate_profile.frame_index_rate_update[rate_update_index + 1]) { |
493 // have been sent for encoding. | 618 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds, |
| 619 num_dropped_frames, |
| 620 num_resize_actions); |
| 621 ++rate_update_index; |
| 622 UpdateRates(rate_update_index, rate_profile); |
| 623 ResetRateControlMetrics( |
| 624 rate_profile.frame_index_rate_update[rate_update_index + 1]); |
| 625 } |
| 626 } |
| 627 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds, |
| 628 num_dropped_frames, |
| 629 num_resize_actions); |
494 | 630 |
495 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 631 // Calculate and print other statistics. |
496 // call ProcessFrame num_frames+1 times here. | 632 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size())); |
497 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 633 stats_.PrintSummary(); |
498 processor_->ProcessFrame(frame_number); | |
499 } | |
500 | 634 |
501 for (frame_number = 0; frame_number < num_frames; ++frame_number) { | 635 // Calculate and print image quality statistics. |
502 const int tl_idx = TemporalLayerIndexForFrame(frame_number); | |
503 ++num_frames_per_update_[tl_idx]; | |
504 ++num_frames_total_; | |
505 UpdateRateControlMetrics(frame_number); | |
506 } | |
507 } else { | |
508 // In online mode, we calculate the metrics for a given frame right after | |
509 // it has been sent for encoding. | |
510 | |
511 if (config_.hw_codec) { | |
512 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | |
513 "since they may be pipelining."; | |
514 } | |
515 | |
516 while (frame_number < num_frames) { | |
517 processor_->ProcessFrame(frame_number); | |
518 VerifyQpParser(frame_number); | |
519 const int tl_idx = TemporalLayerIndexForFrame(frame_number); | |
520 ++num_frames_per_update_[tl_idx]; | |
521 ++num_frames_total_; | |
522 UpdateRateControlMetrics(frame_number); | |
523 | |
524 ++frame_number; | |
525 | |
526 // If we hit another/next update, verify stats for current state and | |
527 // update layers and codec with new rates. | |
528 if (frame_number == | |
529 rate_profile.frame_index_rate_update[update_index + 1]) { | |
530 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | |
531 | |
532 // Update layer rates and the codec with new rates. | |
533 ++update_index; | |
534 bitrate_kbps_ = rate_profile.target_bit_rate[update_index]; | |
535 framerate_ = rate_profile.input_frame_rate[update_index]; | |
536 SetTemporalLayerRates(); | |
537 ResetRateControlMetrics( | |
538 rate_profile.frame_index_rate_update[update_index + 1]); | |
539 processor_->SetRates(bitrate_kbps_, framerate_); | |
540 } | |
541 } | |
542 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | |
543 // call ProcessFrame one extra time here. | |
544 processor_->ProcessFrame(frame_number); | |
545 } | |
546 | |
547 // Verify rate control metrics for all frames (if in batch mode), or for all | |
548 // frames since the last rate update (if not in batch mode). | |
549 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | |
550 EXPECT_EQ(num_frames, frame_number); | |
551 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | |
552 | |
553 // Release encoder and decoder to make sure they have finished processing. | |
554 processor_->Release(); | |
555 DestroyEncoderAndDecoder(); | |
556 | |
557 // Close the analysis files before we use them for SSIM/PSNR calculations. | |
558 analysis_frame_reader_->Close(); | |
559 analysis_frame_writer_->Close(); | |
560 | |
561 // Close visualization files. | |
562 if (encoded_frame_writer_) { | |
563 EXPECT_TRUE(encoded_frame_writer_->Close()); | |
564 } | |
565 if (decoded_frame_writer_) { | |
566 decoded_frame_writer_->Close(); | |
567 } | |
568 | |
569 // TODO(marpan): Should compute these quality metrics per SetRates update. | 636 // TODO(marpan): Should compute these quality metrics per SetRates update. |
570 QualityMetricsResult psnr_result, ssim_result; | 637 QualityMetricsResult psnr_result, ssim_result; |
571 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), | 638 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), |
572 config_.output_filename.c_str(), | 639 config_.output_filename.c_str(), |
573 config_.codec_settings.width, | 640 config_.codec_settings.width, |
574 config_.codec_settings.height, | 641 config_.codec_settings.height, |
575 &psnr_result, &ssim_result)); | 642 &psnr_result, &ssim_result)); |
576 VerifyQuality(psnr_result, ssim_result, quality_thresholds); | 643 if (quality_thresholds) { |
577 stats_.PrintSummary(); | 644 VerifyQuality(psnr_result, ssim_result, *quality_thresholds); |
| 645 } |
578 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", | 646 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", |
579 psnr_result.average, psnr_result.min, ssim_result.average, | 647 psnr_result.average, psnr_result.min, ssim_result.average, |
580 ssim_result.min); | 648 ssim_result.min); |
581 printf("\n"); | 649 printf("\n"); |
582 | 650 |
583 // Remove analysis file. | 651 // Remove analysis file. |
584 if (remove(config_.output_filename.c_str()) < 0) { | 652 if (remove(config_.output_filename.c_str()) < 0) { |
585 fprintf(stderr, "Failed to remove temporary file!\n"); | 653 fprintf(stderr, "Failed to remove temporary file!\n"); |
586 } | 654 } |
587 } | 655 } |
588 | 656 |
589 static void SetTestConfig(TestConfig* config, | 657 static void SetTestConfig(TestConfig* config, |
590 bool hw_codec, | 658 bool hw_codec, |
591 bool use_single_core, | 659 bool use_single_core, |
592 float packet_loss_probability, | 660 float packet_loss_probability, |
593 std::string filename, | 661 std::string filename, |
594 bool verbose_logging, | 662 bool verbose_logging) { |
595 bool batch_mode) { | |
596 config->filename = filename; | 663 config->filename = filename; |
597 config->input_filename = ResourcePath(filename, "yuv"); | 664 config->input_filename = ResourcePath(filename, "yuv"); |
598 // Generate an output filename in a safe way. | 665 // Generate an output filename in a safe way. |
599 config->output_filename = | 666 config->output_filename = |
600 TempFilename(OutputPath(), "videoprocessor_integrationtest"); | 667 TempFilename(OutputPath(), "videoprocessor_integrationtest"); |
601 config->networking_config.packet_loss_probability = packet_loss_probability; | 668 config->networking_config.packet_loss_probability = packet_loss_probability; |
602 config->use_single_core = use_single_core; | 669 config->use_single_core = use_single_core; |
603 config->verbose = verbose_logging; | 670 config->verbose = verbose_logging; |
604 config->hw_codec = hw_codec; | 671 config->hw_codec = hw_codec; |
605 config->batch_mode = batch_mode; | |
606 } | 672 } |
607 | 673 |
608 static void SetCodecSettings(TestConfig* config, | 674 static void SetCodecSettings(TestConfig* config, |
609 VideoCodecType codec_type, | 675 VideoCodecType codec_type, |
610 int num_temporal_layers, | 676 int num_temporal_layers, |
611 bool error_concealment_on, | 677 bool error_concealment_on, |
612 bool denoising_on, | 678 bool denoising_on, |
613 bool frame_dropper_on, | 679 bool frame_dropper_on, |
614 bool spatial_resize_on, | 680 bool spatial_resize_on, |
615 bool resilience_on, | 681 bool resilience_on, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 int rate_update_index, | 722 int rate_update_index, |
657 int bitrate_kbps, | 723 int bitrate_kbps, |
658 int framerate_fps, | 724 int framerate_fps, |
659 int frame_index_rate_update) { | 725 int frame_index_rate_update) { |
660 rate_profile->target_bit_rate[rate_update_index] = bitrate_kbps; | 726 rate_profile->target_bit_rate[rate_update_index] = bitrate_kbps; |
661 rate_profile->input_frame_rate[rate_update_index] = framerate_fps; | 727 rate_profile->input_frame_rate[rate_update_index] = framerate_fps; |
662 rate_profile->frame_index_rate_update[rate_update_index] = | 728 rate_profile->frame_index_rate_update[rate_update_index] = |
663 frame_index_rate_update; | 729 frame_index_rate_update; |
664 } | 730 } |
665 | 731 |
666 static void SetRateControlThresholds(RateControlThresholds* rc_thresholds, | 732 static void AddRateControlThresholds( |
667 int update_index, | 733 int max_num_dropped_frames, |
668 int max_num_dropped_frames, | 734 int max_key_frame_size_mismatch, |
669 int max_key_frame_size_mismatch, | 735 int max_delta_frame_size_mismatch, |
670 int max_delta_frame_size_mismatch, | 736 int max_encoding_rate_mismatch, |
671 int max_encoding_rate_mismatch, | 737 int max_time_hit_target, |
672 int max_time_hit_target, | 738 int num_spatial_resizes, |
673 int num_spatial_resizes, | 739 int num_key_frames, |
674 int num_key_frames) { | 740 std::vector<RateControlThresholds>* rc_thresholds) { |
675 rc_thresholds[update_index].max_num_dropped_frames = max_num_dropped_frames; | 741 RTC_DCHECK(rc_thresholds); |
676 rc_thresholds[update_index].max_key_frame_size_mismatch = | 742 |
677 max_key_frame_size_mismatch; | 743 rc_thresholds->emplace_back(); |
678 rc_thresholds[update_index].max_delta_frame_size_mismatch = | 744 RateControlThresholds* rc_threshold = &rc_thresholds->back(); |
679 max_delta_frame_size_mismatch; | 745 rc_threshold->max_num_dropped_frames = max_num_dropped_frames; |
680 rc_thresholds[update_index].max_encoding_rate_mismatch = | 746 rc_threshold->max_key_frame_size_mismatch = max_key_frame_size_mismatch; |
681 max_encoding_rate_mismatch; | 747 rc_threshold->max_delta_frame_size_mismatch = max_delta_frame_size_mismatch; |
682 rc_thresholds[update_index].max_time_hit_target = max_time_hit_target; | 748 rc_threshold->max_encoding_rate_mismatch = max_encoding_rate_mismatch; |
683 rc_thresholds[update_index].num_spatial_resizes = num_spatial_resizes; | 749 rc_threshold->max_time_hit_target = max_time_hit_target; |
684 rc_thresholds[update_index].num_key_frames = num_key_frames; | 750 rc_threshold->num_spatial_resizes = num_spatial_resizes; |
| 751 rc_threshold->num_key_frames = num_key_frames; |
685 } | 752 } |
686 | 753 |
687 // Config. | 754 // Config. |
688 TestConfig config_; | 755 TestConfig config_; |
689 | 756 |
690 // Codecs. | 757 // Codecs. |
691 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; | 758 std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory_; |
692 VideoEncoder* encoder_; | 759 VideoEncoder* encoder_; |
693 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; | 760 std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory_; |
694 VideoDecoder* decoder_; | 761 VideoDecoder* decoder_; |
(...skipping 27 matching lines...) Expand all Loading... |
722 float target_size_key_frame_initial_; | 789 float target_size_key_frame_initial_; |
723 float target_size_key_frame_; | 790 float target_size_key_frame_; |
724 float sum_key_frame_size_mismatch_; | 791 float sum_key_frame_size_mismatch_; |
725 int num_key_frames_; | 792 int num_key_frames_; |
726 }; | 793 }; |
727 | 794 |
728 } // namespace test | 795 } // namespace test |
729 } // namespace webrtc | 796 } // namespace webrtc |
730 | 797 |
731 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 798 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
OLD | NEW |