Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: webrtc/modules/video_coding/codecs/test/videoprocessor_integrationtest.h

Issue 2997283002: VideoProcessorIntegrationTest: make it runnable on a task queue. (Closed)
Patch Set: asapersson comments 1. Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 20 matching lines...) Expand all
31 #include "webrtc/media/engine/internalencoderfactory.h" 31 #include "webrtc/media/engine/internalencoderfactory.h"
32 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" 32 #include "webrtc/media/engine/webrtcvideodecoderfactory.h"
33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h"
34 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" 34 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
35 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" 35 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
36 #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"
37 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 37 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
38 #include "webrtc/modules/video_coding/include/video_coding.h" 38 #include "webrtc/modules/video_coding/include/video_coding.h"
39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 39 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
40 #include "webrtc/rtc_base/checks.h" 40 #include "webrtc/rtc_base/checks.h"
41 #include "webrtc/rtc_base/event.h"
41 #include "webrtc/rtc_base/file.h" 42 #include "webrtc/rtc_base/file.h"
42 #include "webrtc/rtc_base/logging.h" 43 #include "webrtc/rtc_base/logging.h"
43 #include "webrtc/rtc_base/ptr_util.h" 44 #include "webrtc/rtc_base/ptr_util.h"
45 #include "webrtc/system_wrappers/include/sleep.h"
44 #include "webrtc/test/gtest.h" 46 #include "webrtc/test/gtest.h"
45 #include "webrtc/test/testsupport/fileutils.h" 47 #include "webrtc/test/testsupport/fileutils.h"
46 #include "webrtc/test/testsupport/frame_reader.h" 48 #include "webrtc/test/testsupport/frame_reader.h"
47 #include "webrtc/test/testsupport/frame_writer.h" 49 #include "webrtc/test/testsupport/frame_writer.h"
48 #include "webrtc/test/testsupport/metrics/video_metrics.h" 50 #include "webrtc/test/testsupport/metrics/video_metrics.h"
49 #include "webrtc/test/testsupport/packet_reader.h" 51 #include "webrtc/test/testsupport/packet_reader.h"
50 #include "webrtc/test/video_codec_settings.h" 52 #include "webrtc/test/video_codec_settings.h"
51 #include "webrtc/typedefs.h" 53 #include "webrtc/typedefs.h"
52 54
53 namespace webrtc { 55 namespace webrtc {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 18 matching lines...) Expand all
216 if (visualization_params->save_decoded_y4m) { 219 if (visualization_params->save_decoded_y4m) {
217 decoded_frame_writer_.reset(new Y4mFrameWriterImpl( 220 decoded_frame_writer_.reset(new Y4mFrameWriterImpl(
218 output_filename_base + ".y4m", config_.codec_settings.width, 221 output_filename_base + ".y4m", config_.codec_settings.width,
219 config_.codec_settings.height, initial_framerate_fps)); 222 config_.codec_settings.height, initial_framerate_fps));
220 EXPECT_TRUE(decoded_frame_writer_->Init()); 223 EXPECT_TRUE(decoded_frame_writer_->Init());
221 } 224 }
222 } 225 }
223 226
224 packet_manipulator_.reset(new PacketManipulatorImpl( 227 packet_manipulator_.reset(new PacketManipulatorImpl(
225 &packet_reader_, config_.networking_config, config_.verbose)); 228 &packet_reader_, config_.networking_config, config_.verbose));
226 processor_ = rtc::MakeUnique<VideoProcessor>( 229
227 encoder_, decoder_, analysis_frame_reader_.get(), 230 config_.codec_settings.minBitrate = 0;
228 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, 231 config_.codec_settings.startBitrate = initial_bitrate_kbps;
229 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get()); 232 config_.codec_settings.maxFramerate = initial_framerate_fps;
230 processor_->Init(); 233
234 rtc::Event sync_event(false, false);
235 task_queue->PostTask([this, &sync_event]() {
236 processor_ = rtc::MakeUnique<VideoProcessor>(
237 encoder_, decoder_, analysis_frame_reader_.get(),
238 analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
239 &stats_, encoded_frame_writer_.get(), decoded_frame_writer_.get());
240 processor_->Init();
241 sync_event.Set();
242 });
243 sync_event.Wait(rtc::Event::kForever);
231 } 244 }
232 245
233 // Reset quantities after each encoder update, update the target per-frame 246 void ReleaseAndCloseObjects(rtc::TaskQueue* task_queue) {
234 // bandwidth. 247 rtc::Event sync_event(false, false);
235 void ResetRateControlMetrics(int num_frames_to_hit_target) { 248 task_queue->PostTask([this, &sync_event]() {
236 const int num_temporal_layers = 249 processor_->Release();
237 NumberOfTemporalLayers(config_.codec_settings); 250 sync_event.Set();
238 for (int i = 0; i < num_temporal_layers; i++) { 251 });
239 num_frames_per_update_[i] = 0; 252 sync_event.Wait(rtc::Event::kForever);
240 sum_frame_size_mismatch_[i] = 0.0f; 253
241 sum_encoded_frame_size_[i] = 0.0f; 254 // The VideoProcessor must be ::Release()'d before we destroy the codecs.
242 encoding_bitrate_[i] = 0.0f; 255 DestroyEncoderAndDecoder();
243 // Update layer per-frame-bandwidth. 256
244 per_frame_bandwidth_[i] = static_cast<float>(bitrate_layer_[i]) / 257 // Close the analysis files before we use them for SSIM/PSNR calculations.
245 static_cast<float>(framerate_layer_[i]); 258 analysis_frame_reader_->Close();
259 analysis_frame_writer_->Close();
260
261 // Close visualization files.
262 if (encoded_frame_writer_) {
263 EXPECT_TRUE(encoded_frame_writer_->Close());
246 } 264 }
247 // Set maximum size of key frames, following setting in the VP8 wrapper. 265 if (decoded_frame_writer_) {
248 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * framerate_; 266 decoded_frame_writer_->Close();
249 // We don't know exact target size of the key frames (except for first one), 267 }
250 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
251 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average
252 // as reference for mismatch. Note key frames always correspond to base
253 // layer frame in this test.
254 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
255 num_frames_total_ = 0;
256 sum_encoded_frame_size_total_ = 0.0f;
257 encoding_bitrate_total_ = 0.0f;
258 perc_encoding_rate_mismatch_ = 0.0f;
259 num_frames_to_hit_target_ = num_frames_to_hit_target;
260 encoding_rate_within_target_ = false;
261 sum_key_frame_size_mismatch_ = 0.0;
262 num_key_frames_ = 0;
263 } 268 }
264 269
265 // For every encoded frame, update the rate control metrics. 270 // For every encoded frame, update the rate control metrics.
266 void UpdateRateControlMetrics(int frame_number) { 271 void UpdateRateControlMetrics(int frame_number) {
267 RTC_CHECK_GE(frame_number, 0); 272 RTC_CHECK_GE(frame_number, 0);
268 273
274 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
275 ++num_frames_per_update_[tl_idx];
276 ++num_frames_total_;
277
269 FrameType frame_type = stats_.stats_[frame_number].frame_type; 278 FrameType frame_type = stats_.stats_[frame_number].frame_type;
270 float encoded_size_kbits = 279 float encoded_size_kbits =
271 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f / 280 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f /
272 1000.0f; 281 1000.0f;
273 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
274 282
275 // Update layer data. 283 // Update layer data.
276 // Update rate mismatch relative to per-frame bandwidth for delta frames. 284 // Update rate mismatch relative to per-frame bandwidth for delta frames.
277 if (frame_type == kVideoFrameDelta) { 285 if (frame_type == kVideoFrameDelta) {
278 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? 286 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
279 sum_frame_size_mismatch_[tl_idx] += 287 sum_frame_size_mismatch_[tl_idx] +=
280 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / 288 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) /
281 per_frame_bandwidth_[tl_idx]; 289 per_frame_bandwidth_[tl_idx];
282 } else { 290 } else {
283 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ 291 float target_size = (frame_number == 0) ? target_size_key_frame_initial_
(...skipping 17 matching lines...) Expand all
301 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && 309 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
302 !encoding_rate_within_target_) { 310 !encoding_rate_within_target_) {
303 num_frames_to_hit_target_ = num_frames_total_; 311 num_frames_to_hit_target_ = num_frames_total_;
304 encoding_rate_within_target_ = true; 312 encoding_rate_within_target_ = true;
305 } 313 }
306 } 314 }
307 315
308 // Verify expected behavior of rate control and print out data. 316 // Verify expected behavior of rate control and print out data.
309 void PrintAndMaybeVerifyRateControlMetrics( 317 void PrintAndMaybeVerifyRateControlMetrics(
310 int rate_update_index, 318 int rate_update_index,
311 const std::vector<RateControlThresholds>* rc_thresholds) { 319 const std::vector<RateControlThresholds>* rc_thresholds,
312 int num_dropped_frames = processor_->NumberDroppedFrames(); 320 const std::vector<int>& num_dropped_frames,
313 int num_resize_actions = processor_->NumberSpatialResizes(); 321 const std::vector<int>& num_resize_actions) {
314 printf( 322 printf(
315 "Rate update #%d:\n" 323 "Rate update #%d:\n"
316 " Target bitrate : %d\n" 324 " Target bitrate : %d\n"
317 " Encoded bitrate : %f\n" 325 " Encoded bitrate : %f\n"
318 " Frame rate : %d\n", 326 " Frame rate : %d\n",
319 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_); 327 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_);
320 printf( 328 printf(
321 " # processed frames : %d\n" 329 " # processed frames : %d\n"
322 " # frames to convergence: %d\n" 330 " # frames to convergence: %d\n"
323 " # dropped frames : %d\n" 331 " # dropped frames : %d\n"
324 " # spatial resizes : %d\n", 332 " # spatial resizes : %d\n",
325 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, 333 num_frames_total_, num_frames_to_hit_target_,
326 num_resize_actions); 334 num_dropped_frames[rate_update_index],
335 num_resize_actions[rate_update_index]);
327 336
328 const RateControlThresholds* rc_threshold = nullptr; 337 const RateControlThresholds* rc_threshold = nullptr;
329 if (rc_thresholds) { 338 if (rc_thresholds) {
330 rc_threshold = &(*rc_thresholds)[rate_update_index]; 339 rc_threshold = &(*rc_thresholds)[rate_update_index];
331 340
332 EXPECT_LE(perc_encoding_rate_mismatch_, 341 EXPECT_LE(perc_encoding_rate_mismatch_,
333 rc_threshold->max_encoding_rate_mismatch); 342 rc_threshold->max_encoding_rate_mismatch);
334 } 343 }
335 if (num_key_frames_ > 0) { 344 if (num_key_frames_ > 0) {
336 int perc_key_frame_size_mismatch = 345 int perc_key_frame_size_mismatch =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 EXPECT_LE(perc_frame_size_mismatch, 378 EXPECT_LE(perc_frame_size_mismatch,
370 rc_threshold->max_delta_frame_size_mismatch); 379 rc_threshold->max_delta_frame_size_mismatch);
371 EXPECT_LE(perc_encoding_rate_mismatch, 380 EXPECT_LE(perc_encoding_rate_mismatch,
372 rc_threshold->max_encoding_rate_mismatch); 381 rc_threshold->max_encoding_rate_mismatch);
373 } 382 }
374 } 383 }
375 printf("\n"); 384 printf("\n");
376 385
377 if (rc_threshold) { 386 if (rc_threshold) {
378 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target); 387 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target);
379 EXPECT_LE(num_dropped_frames, rc_threshold->max_num_dropped_frames); 388 EXPECT_LE(num_dropped_frames[rate_update_index],
380 EXPECT_EQ(rc_threshold->num_spatial_resizes, num_resize_actions); 389 rc_threshold->max_num_dropped_frames);
390 EXPECT_EQ(rc_threshold->num_spatial_resizes,
391 num_resize_actions[rate_update_index]);
381 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_); 392 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_);
382 } 393 }
383 } 394 }
384 395
385 static void VerifyQuality(const QualityMetricsResult& psnr_result, 396 static void VerifyQuality(const QualityMetricsResult& psnr_result,
386 const QualityMetricsResult& ssim_result, 397 const QualityMetricsResult& ssim_result,
387 const QualityThresholds& quality_thresholds) { 398 const QualityThresholds& quality_thresholds) {
388 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); 399 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr);
389 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); 400 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr);
390 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); 401 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 tl_idx = 2; 438 tl_idx = 2;
428 } 439 }
429 break; 440 break;
430 default: 441 default:
431 RTC_NOTREACHED(); 442 RTC_NOTREACHED();
432 break; 443 break;
433 } 444 }
434 return tl_idx; 445 return tl_idx;
435 } 446 }
436 447
437 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. 448 // Reset quantities before each encoder rate update.
438 void SetTemporalLayerRates() { 449 void ResetRateControlMetrics(int rate_update_index,
450 const RateProfile& rate_profile) {
451 // Set new rates.
452 bitrate_kbps_ = rate_profile.target_bit_rate[rate_update_index];
453 framerate_ = rate_profile.input_frame_rate[rate_update_index];
439 const int num_temporal_layers = 454 const int num_temporal_layers =
440 NumberOfTemporalLayers(config_.codec_settings); 455 NumberOfTemporalLayers(config_.codec_settings);
441 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); 456 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers);
442 for (int i = 0; i < num_temporal_layers; i++) { 457 for (int i = 0; i < num_temporal_layers; i++) {
443 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; 458 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i];
444 if (i > 0) { 459 if (i > 0) {
445 float bit_rate_delta_ratio = 460 float bit_rate_delta_ratio =
446 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - 461 kVp8LayerRateAlloction[num_temporal_layers - 1][i] -
447 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; 462 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1];
448 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio; 463 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio;
449 } else { 464 } else {
450 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio; 465 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio;
451 } 466 }
452 framerate_layer_[i] = 467 framerate_layer_[i] =
453 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1)); 468 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1));
454 } 469 }
455 if (num_temporal_layers == 3) { 470 if (num_temporal_layers == 3) {
456 framerate_layer_[2] = framerate_ / 2.0f; 471 framerate_layer_[2] = framerate_ / 2.0f;
457 } 472 }
473 if (rate_update_index == 0) {
474 target_size_key_frame_initial_ =
475 0.5 * kInitialBufferSize * bitrate_layer_[0];
476 }
477
478 // Reset rate control metrics.
479 for (int i = 0; i < num_temporal_layers; i++) {
480 num_frames_per_update_[i] = 0;
481 sum_frame_size_mismatch_[i] = 0.0f;
482 sum_encoded_frame_size_[i] = 0.0f;
483 encoding_bitrate_[i] = 0.0f;
484 // Update layer per-frame-bandwidth.
485 per_frame_bandwidth_[i] = static_cast<float>(bitrate_layer_[i]) /
486 static_cast<float>(framerate_layer_[i]);
487 }
488 // Set maximum size of key frames, following setting in the VP8 wrapper.
489 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * framerate_;
490 // We don't know exact target size of the key frames (except for first one),
491 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
492 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average
493 // as reference for mismatch. Note key frames always correspond to base
494 // layer frame in this test.
495 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
496 num_frames_total_ = 0;
497 sum_encoded_frame_size_total_ = 0.0f;
498 encoding_bitrate_total_ = 0.0f;
499 perc_encoding_rate_mismatch_ = 0.0f;
500 num_frames_to_hit_target_ =
501 rate_profile.frame_index_rate_update[rate_update_index + 1];
502 encoding_rate_within_target_ = false;
503 sum_key_frame_size_mismatch_ = 0.0;
504 num_key_frames_ = 0;
458 } 505 }
459 506
460 // Processes all frames in the clip and verifies the result. 507 // Processes all frames in the clip and verifies the result.
461 void ProcessFramesAndMaybeVerify( 508 void ProcessFramesAndMaybeVerify(
462 const RateProfile& rate_profile, 509 const RateProfile& rate_profile,
463 const std::vector<RateControlThresholds>* rc_thresholds, 510 const std::vector<RateControlThresholds>* rc_thresholds,
464 const QualityThresholds* quality_thresholds, 511 const QualityThresholds* quality_thresholds,
465 const VisualizationParams* visualization_params) { 512 const VisualizationParams* visualization_params) {
466 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; 513 // The Android HW codec needs to be run on a task queue, so we simply always
467 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], 514 // run the test on a task queue.
468 rate_profile.input_frame_rate[0]); 515 rtc::TaskQueue task_queue("VidProc TQ");
516 rtc::Event sync_event(false, false);
517
518 SetUpAndInitObjects(&task_queue, rate_profile.target_bit_rate[0],
519 rate_profile.input_frame_rate[0], visualization_params);
469 520
470 // Set initial rates. 521 // Set initial rates.
471 bitrate_kbps_ = rate_profile.target_bit_rate[0]; 522 int rate_update_index = 0;
472 framerate_ = rate_profile.input_frame_rate[0]; 523 task_queue.PostTask([this, &rate_profile, rate_update_index] {
473 SetTemporalLayerRates(); 524 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index],
474 // Set the initial target size for key frame. 525 rate_profile.input_frame_rate[rate_update_index]);
475 target_size_key_frame_initial_ = 526 });
476 0.5 * kInitialBufferSize * bitrate_layer_[0];
477 processor_->SetRates(bitrate_kbps_, framerate_);
478 527
479 // Process each frame, up to |num_frames|. 528 // Process all frames.
480 int frame_number = 0; 529 int frame_number = 0;
481 int update_index = 0; 530 const int num_frames = rate_profile.num_frames;
482 int num_frames = rate_profile.num_frames; 531 RTC_DCHECK_GE(num_frames, 1);
483 ResetRateControlMetrics( 532 while (frame_number < num_frames) {
484 rate_profile.frame_index_rate_update[update_index + 1]); 533 // In order to not overwhelm the OpenMAX buffers in the Android
534 // MediaCodec API, we roughly pace the frames here. The downside
535 // of this is that the encode run will be done in real-time.
536 // TODO(brandtr): Investigate if this is needed on iOS.
537 if (config_.hw_codec) {
538 SleepMs(rtc::kNumMillisecsPerSec /
539 rate_profile.input_frame_rate[rate_update_index]);
540 }
485 541
542 task_queue.PostTask(
543 [this, frame_number] { processor_->ProcessFrame(frame_number); });
544 ++frame_number;
545
546 if (frame_number ==
547 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
548 ++rate_update_index;
549
550 task_queue.PostTask([this, &rate_profile, rate_update_index] {
551 processor_->SetRates(
552 rate_profile.target_bit_rate[rate_update_index],
553 rate_profile.input_frame_rate[rate_update_index]);
554 });
555 }
556 }
557
558 // Give the VideoProcessor pipeline some time to process the last frame,
559 // and then release the codecs.
560 if (config_.hw_codec) {
561 SleepMs(1 * rtc::kNumMillisecsPerSec);
562 }
563 ReleaseAndCloseObjects(&task_queue);
564
565 // Calculate and print rate control statistics.
566 rate_update_index = 0;
567 frame_number = 0;
568 ResetRateControlMetrics(rate_update_index, rate_profile);
569 std::vector<int> num_dropped_frames;
570 std::vector<int> num_resize_actions;
571 sync_event.Reset();
572 task_queue.PostTask(
573 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
574 num_dropped_frames = processor_->NumberDroppedFramesPerRateUpdate();
575 num_resize_actions = processor_->NumberSpatialResizesPerRateUpdate();
576 sync_event.Set();
577 });
578 sync_event.Wait(rtc::Event::kForever);
486 while (frame_number < num_frames) { 579 while (frame_number < num_frames) {
487 processor_->ProcessFrame(frame_number);
488 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
489 ++num_frames_per_update_[tl_idx];
490 ++num_frames_total_;
491 UpdateRateControlMetrics(frame_number); 580 UpdateRateControlMetrics(frame_number);
492 581
493 ++frame_number; 582 ++frame_number;
494 583
495 // If we hit another/next update, verify stats for current state and
496 // update layers and codec with new rates.
497 if (frame_number == 584 if (frame_number ==
498 rate_profile.frame_index_rate_update[update_index + 1]) { 585 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
499 PrintAndMaybeVerifyRateControlMetrics(update_index, rc_thresholds); 586 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
500 587 num_dropped_frames,
501 // Update layer rates and the codec with new rates. 588 num_resize_actions);
502 ++update_index; 589 ++rate_update_index;
503 bitrate_kbps_ = rate_profile.target_bit_rate[update_index]; 590 ResetRateControlMetrics(rate_update_index, rate_profile);
504 framerate_ = rate_profile.input_frame_rate[update_index];
505 SetTemporalLayerRates();
506 ResetRateControlMetrics(
507 rate_profile.frame_index_rate_update[update_index + 1]);
508 processor_->SetRates(bitrate_kbps_, framerate_);
509 } 591 }
510 } 592 }
593 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
594 num_dropped_frames,
595 num_resize_actions);
511 596
512 // Verify rate control metrics for all frames since the last rate update. 597 // Calculate and print other statistics.
513 PrintAndMaybeVerifyRateControlMetrics(update_index, rc_thresholds);
514 EXPECT_EQ(num_frames, frame_number);
515 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size())); 598 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size()));
599 stats_.PrintSummary();
516 600
517 // Release encoder and decoder to make sure they have finished processing. 601 // Calculate and print image quality statistics.
518 processor_->Release();
519 DestroyEncoderAndDecoder();
520
521 // Close the analysis files before we use them for SSIM/PSNR calculations.
522 analysis_frame_reader_->Close();
523 analysis_frame_writer_->Close();
524
525 // Close visualization files.
526 if (encoded_frame_writer_) {
527 EXPECT_TRUE(encoded_frame_writer_->Close());
528 }
529 if (decoded_frame_writer_) {
530 decoded_frame_writer_->Close();
531 }
532
533 // TODO(marpan): Should compute these quality metrics per SetRates update. 602 // TODO(marpan): Should compute these quality metrics per SetRates update.
534 QualityMetricsResult psnr_result, ssim_result; 603 QualityMetricsResult psnr_result, ssim_result;
535 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), 604 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(),
536 config_.output_filename.c_str(), 605 config_.output_filename.c_str(),
537 config_.codec_settings.width, 606 config_.codec_settings.width,
538 config_.codec_settings.height, 607 config_.codec_settings.height,
539 &psnr_result, &ssim_result)); 608 &psnr_result, &ssim_result));
540 if (quality_thresholds) { 609 if (quality_thresholds) {
541 VerifyQuality(psnr_result, ssim_result, *quality_thresholds); 610 VerifyQuality(psnr_result, ssim_result, *quality_thresholds);
542 } 611 }
543 stats_.PrintSummary();
544 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", 612 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n",
545 psnr_result.average, psnr_result.min, ssim_result.average, 613 psnr_result.average, psnr_result.min, ssim_result.average,
546 ssim_result.min); 614 ssim_result.min);
547 printf("\n"); 615 printf("\n");
548 616
549 // Remove analysis file. 617 // Remove analysis file.
550 if (remove(config_.output_filename.c_str()) < 0) { 618 if (remove(config_.output_filename.c_str()) < 0) {
551 fprintf(stderr, "Failed to remove temporary file!\n"); 619 fprintf(stderr, "Failed to remove temporary file!\n");
552 } 620 }
553 } 621 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 float target_size_key_frame_initial_; 755 float target_size_key_frame_initial_;
688 float target_size_key_frame_; 756 float target_size_key_frame_;
689 float sum_key_frame_size_mismatch_; 757 float sum_key_frame_size_mismatch_;
690 int num_key_frames_; 758 int num_key_frames_;
691 }; 759 };
692 760
693 } // namespace test 761 } // namespace test
694 } // namespace webrtc 762 } // namespace webrtc
695 763
696 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ 764 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698