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

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: Rebase. 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);
244 }
245
246 void ReleaseAndCloseObjects(rtc::TaskQueue* task_queue) {
247 rtc::Event sync_event(false, false);
248 task_queue->PostTask([this, &sync_event]() {
249 processor_->Release();
250 sync_event.Set();
251 });
252 sync_event.Wait(rtc::Event::kForever);
253
254 // The VideoProcessor must be ::Release()'d before we destroy the codecs.
255 DestroyEncoderAndDecoder();
256
257 // Close the analysis files before we use them for SSIM/PSNR calculations.
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());
264 }
265 if (decoded_frame_writer_) {
266 decoded_frame_writer_->Close();
267 }
231 } 268 }
232 269
233 // Reset quantities after each encoder update, update the target per-frame 270 // Reset quantities after each encoder update, update the target per-frame
234 // bandwidth. 271 // bandwidth.
235 void ResetRateControlMetrics(int num_frames_to_hit_target) { 272 void ResetRateControlMetrics(int num_frames_to_hit_target) {
236 const int num_temporal_layers = 273 const int num_temporal_layers =
237 NumberOfTemporalLayers(config_.codec_settings); 274 NumberOfTemporalLayers(config_.codec_settings);
238 for (int i = 0; i < num_temporal_layers; i++) { 275 for (int i = 0; i < num_temporal_layers; i++) {
239 num_frames_per_update_[i] = 0; 276 num_frames_per_update_[i] = 0;
240 sum_frame_size_mismatch_[i] = 0.0f; 277 sum_frame_size_mismatch_[i] = 0.0f;
(...skipping 18 matching lines...) Expand all
259 num_frames_to_hit_target_ = num_frames_to_hit_target; 296 num_frames_to_hit_target_ = num_frames_to_hit_target;
260 encoding_rate_within_target_ = false; 297 encoding_rate_within_target_ = false;
261 sum_key_frame_size_mismatch_ = 0.0; 298 sum_key_frame_size_mismatch_ = 0.0;
262 num_key_frames_ = 0; 299 num_key_frames_ = 0;
263 } 300 }
264 301
265 // For every encoded frame, update the rate control metrics. 302 // For every encoded frame, update the rate control metrics.
266 void UpdateRateControlMetrics(int frame_number) { 303 void UpdateRateControlMetrics(int frame_number) {
267 RTC_CHECK_GE(frame_number, 0); 304 RTC_CHECK_GE(frame_number, 0);
268 305
306 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
307 ++num_frames_per_update_[tl_idx];
308 ++num_frames_total_;
309
269 FrameType frame_type = stats_.stats_[frame_number].frame_type; 310 FrameType frame_type = stats_.stats_[frame_number].frame_type;
270 float encoded_size_kbits = 311 float encoded_size_kbits =
271 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f / 312 stats_.stats_[frame_number].encoded_frame_length_in_bytes * 8.0f /
272 1000.0f; 313 1000.0f;
273 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
274 314
275 // Update layer data. 315 // Update layer data.
276 // Update rate mismatch relative to per-frame bandwidth for delta frames. 316 // Update rate mismatch relative to per-frame bandwidth for delta frames.
277 if (frame_type == kVideoFrameDelta) { 317 if (frame_type == kVideoFrameDelta) {
278 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? 318 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
279 sum_frame_size_mismatch_[tl_idx] += 319 sum_frame_size_mismatch_[tl_idx] +=
280 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / 320 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) /
281 per_frame_bandwidth_[tl_idx]; 321 per_frame_bandwidth_[tl_idx];
282 } else { 322 } else {
283 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ 323 float target_size = (frame_number == 0) ? target_size_key_frame_initial_
(...skipping 17 matching lines...) Expand all
301 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && 341 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
302 !encoding_rate_within_target_) { 342 !encoding_rate_within_target_) {
303 num_frames_to_hit_target_ = num_frames_total_; 343 num_frames_to_hit_target_ = num_frames_total_;
304 encoding_rate_within_target_ = true; 344 encoding_rate_within_target_ = true;
305 } 345 }
306 } 346 }
307 347
308 // Verify expected behavior of rate control and print out data. 348 // Verify expected behavior of rate control and print out data.
309 void PrintAndMaybeVerifyRateControlMetrics( 349 void PrintAndMaybeVerifyRateControlMetrics(
310 int rate_update_index, 350 int rate_update_index,
311 const std::vector<RateControlThresholds>* rc_thresholds) { 351 const std::vector<RateControlThresholds>* rc_thresholds,
312 int num_dropped_frames = processor_->NumberDroppedFrames(); 352 const std::vector<int>& num_dropped_frames,
313 int num_resize_actions = processor_->NumberSpatialResizes(); 353 const std::vector<int>& num_resize_actions) {
314 printf( 354 printf(
315 "Rate update #%d:\n" 355 "Rate update #%d:\n"
316 " Target bitrate : %d\n" 356 " Target bitrate : %d\n"
317 " Encoded bitrate : %f\n" 357 " Encoded bitrate : %f\n"
318 " Frame rate : %d\n", 358 " Frame rate : %d\n",
319 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_); 359 rate_update_index, bitrate_kbps_, encoding_bitrate_total_, framerate_);
320 printf( 360 printf(
321 " # processed frames : %d\n" 361 " # processed frames : %d\n"
322 " # frames to convergence: %d\n" 362 " # frames to convergence: %d\n"
323 " # dropped frames : %d\n" 363 " # dropped frames : %d\n"
324 " # spatial resizes : %d\n", 364 " # spatial resizes : %d\n",
325 num_frames_total_, num_frames_to_hit_target_, num_dropped_frames, 365 num_frames_total_, num_frames_to_hit_target_,
326 num_resize_actions); 366 num_dropped_frames[rate_update_index],
367 num_resize_actions[rate_update_index]);
327 368
328 const RateControlThresholds* rc_threshold = nullptr; 369 const RateControlThresholds* rc_threshold = nullptr;
329 if (rc_thresholds) { 370 if (rc_thresholds) {
330 rc_threshold = &(*rc_thresholds)[rate_update_index]; 371 rc_threshold = &(*rc_thresholds)[rate_update_index];
331 372
332 EXPECT_LE(perc_encoding_rate_mismatch_, 373 EXPECT_LE(perc_encoding_rate_mismatch_,
333 rc_threshold->max_encoding_rate_mismatch); 374 rc_threshold->max_encoding_rate_mismatch);
334 } 375 }
335 if (num_key_frames_ > 0) { 376 if (num_key_frames_ > 0) {
336 int perc_key_frame_size_mismatch = 377 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, 410 EXPECT_LE(perc_frame_size_mismatch,
370 rc_threshold->max_delta_frame_size_mismatch); 411 rc_threshold->max_delta_frame_size_mismatch);
371 EXPECT_LE(perc_encoding_rate_mismatch, 412 EXPECT_LE(perc_encoding_rate_mismatch,
372 rc_threshold->max_encoding_rate_mismatch); 413 rc_threshold->max_encoding_rate_mismatch);
373 } 414 }
374 } 415 }
375 printf("\n"); 416 printf("\n");
376 417
377 if (rc_threshold) { 418 if (rc_threshold) {
378 EXPECT_LE(num_frames_to_hit_target_, rc_threshold->max_time_hit_target); 419 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); 420 EXPECT_LE(num_dropped_frames[rate_update_index],
380 EXPECT_EQ(rc_threshold->num_spatial_resizes, num_resize_actions); 421 rc_threshold->max_num_dropped_frames);
422 EXPECT_EQ(rc_threshold->num_spatial_resizes,
423 num_resize_actions[rate_update_index]);
381 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_); 424 EXPECT_EQ(rc_threshold->num_key_frames, num_key_frames_);
382 } 425 }
383 } 426 }
384 427
385 static void VerifyQuality(const QualityMetricsResult& psnr_result, 428 static void VerifyQuality(const QualityMetricsResult& psnr_result,
386 const QualityMetricsResult& ssim_result, 429 const QualityMetricsResult& ssim_result,
387 const QualityThresholds& quality_thresholds) { 430 const QualityThresholds& quality_thresholds) {
388 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); 431 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr);
389 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); 432 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr);
390 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); 433 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim);
391 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); 434 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim);
392 } 435 }
393 436
394 void VerifyQpParser(int frame_number) {
395 if (!config_.hw_codec &&
396 (config_.codec_settings.codecType == kVideoCodecVP8 ||
397 config_.codec_settings.codecType == kVideoCodecVP9)) {
398 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number),
399 processor_->GetQpFromBitstream(frame_number));
400 }
401 }
402
403 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) { 437 static int NumberOfTemporalLayers(const VideoCodec& codec_settings) {
404 if (codec_settings.codecType == kVideoCodecVP8) { 438 if (codec_settings.codecType == kVideoCodecVP8) {
405 return codec_settings.VP8().numberOfTemporalLayers; 439 return codec_settings.VP8().numberOfTemporalLayers;
406 } else if (codec_settings.codecType == kVideoCodecVP9) { 440 } else if (codec_settings.codecType == kVideoCodecVP9) {
407 return codec_settings.VP9().numberOfTemporalLayers; 441 return codec_settings.VP9().numberOfTemporalLayers;
408 } else { 442 } else {
409 return 1; 443 return 1;
410 } 444 }
411 } 445 }
412 446
(...skipping 23 matching lines...) Expand all
436 tl_idx = 2; 470 tl_idx = 2;
437 } 471 }
438 break; 472 break;
439 default: 473 default:
440 RTC_NOTREACHED(); 474 RTC_NOTREACHED();
441 break; 475 break;
442 } 476 }
443 return tl_idx; 477 return tl_idx;
444 } 478 }
445 479
446 // Set the bit rate and frame rate per temporal layer, for up to 3 layers. 480 void UpdateRates(int rate_update_index, const RateProfile& rate_profile) {
447 void SetTemporalLayerRates() { 481 bitrate_kbps_ = rate_profile.target_bit_rate[rate_update_index];
482 framerate_ = rate_profile.input_frame_rate[rate_update_index];
483
448 const int num_temporal_layers = 484 const int num_temporal_layers =
449 NumberOfTemporalLayers(config_.codec_settings); 485 NumberOfTemporalLayers(config_.codec_settings);
450 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers); 486 RTC_DCHECK_LE(num_temporal_layers, kMaxNumTemporalLayers);
451 for (int i = 0; i < num_temporal_layers; i++) { 487 for (int i = 0; i < num_temporal_layers; i++) {
452 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i]; 488 float bit_rate_ratio = kVp8LayerRateAlloction[num_temporal_layers - 1][i];
453 if (i > 0) { 489 if (i > 0) {
454 float bit_rate_delta_ratio = 490 float bit_rate_delta_ratio =
455 kVp8LayerRateAlloction[num_temporal_layers - 1][i] - 491 kVp8LayerRateAlloction[num_temporal_layers - 1][i] -
456 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1]; 492 kVp8LayerRateAlloction[num_temporal_layers - 1][i - 1];
457 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio; 493 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_delta_ratio;
458 } else { 494 } else {
459 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio; 495 bitrate_layer_[i] = bitrate_kbps_ * bit_rate_ratio;
460 } 496 }
461 framerate_layer_[i] = 497 framerate_layer_[i] =
462 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1)); 498 framerate_ / static_cast<float>(1 << (num_temporal_layers - 1));
463 } 499 }
464 if (num_temporal_layers == 3) { 500 if (num_temporal_layers == 3) {
465 framerate_layer_[2] = framerate_ / 2.0f; 501 framerate_layer_[2] = framerate_ / 2.0f;
466 } 502 }
467 } 503 }
468 504
469 // Processes all frames in the clip and verifies the result. 505 // Processes all frames in the clip and verifies the result.
470 void ProcessFramesAndMaybeVerify( 506 void ProcessFramesAndMaybeVerify(
471 const RateProfile& rate_profile, 507 const RateProfile& rate_profile,
472 const std::vector<RateControlThresholds>* rc_thresholds, 508 const std::vector<RateControlThresholds>* rc_thresholds,
473 const QualityThresholds* quality_thresholds, 509 const QualityThresholds* quality_thresholds,
474 const VisualizationParams* visualization_params) { 510 const VisualizationParams* visualization_params) {
475 config_.codec_settings.startBitrate = rate_profile.target_bit_rate[0]; 511 // The Android HW codec needs to be run on a task queue, so we simply always
476 SetUpObjects(visualization_params, rate_profile.target_bit_rate[0], 512 // run the test on a task queue.
477 rate_profile.input_frame_rate[0]); 513 rtc::TaskQueue task_queue("VidProc TQ");
514 rtc::Event sync_event(false, false);
515
516 SetUpAndInitObjects(&task_queue, rate_profile.target_bit_rate[0],
517 rate_profile.input_frame_rate[0], visualization_params);
478 518
479 // Set initial rates. 519 // Set initial rates.
480 bitrate_kbps_ = rate_profile.target_bit_rate[0]; 520 int rate_update_index = 0;
481 framerate_ = rate_profile.input_frame_rate[0]; 521 task_queue.PostTask([this, &rate_profile, rate_update_index] {
482 SetTemporalLayerRates(); 522 processor_->SetRates(rate_profile.target_bit_rate[rate_update_index],
483 // Set the initial target size for key frame. 523 rate_profile.input_frame_rate[rate_update_index]);
524 });
525
526 // Process all frames.
527 int frame_number = 0;
528 const int num_frames = rate_profile.num_frames;
529 RTC_DCHECK_GE(num_frames, 1);
530 while (frame_number < num_frames) {
531 // In order to not overwhelm the OpenMAX buffers in the Android
532 // MediaCodec API, we roughly pace the frames here. The downside
533 // of this is that the encode run will be done in real-time.
534 // TODO(brandtr): Investigate if this is needed on iOS.
535 if (config_.hw_codec) {
536 SleepMs(rtc::kNumMillisecsPerSec /
537 rate_profile.input_frame_rate[rate_update_index]);
538 }
539
540 task_queue.PostTask(
541 [this, frame_number] { processor_->ProcessFrame(frame_number); });
542 ++frame_number;
543
544 if (frame_number ==
545 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
546 ++rate_update_index;
547
548 task_queue.PostTask([this, &rate_profile, rate_update_index] {
549 processor_->SetRates(
550 rate_profile.target_bit_rate[rate_update_index],
551 rate_profile.input_frame_rate[rate_update_index]);
552 });
553 }
554 }
555
556 // TODO(brandtr): Verify the assumption that HW codecs never
557 // drop frames internally.
558 if (config_.hw_codec) {
559 // Ensure that all the frames have been encoded and decoded.
560 int last_decoded_frame_num = -1;
561 int wait_count = 0;
562 while (last_decoded_frame_num != (num_frames - 1) && wait_count++ < 10) {
563 sync_event.Reset();
564 task_queue.PostTask([this, &last_decoded_frame_num, &sync_event]() {
565 last_decoded_frame_num = processor_->LastDecodedFrameNumber();
566 sync_event.Set();
567 });
568 sync_event.Wait(rtc::Event::kForever);
569
570 SleepMs(1000);
571 }
572 EXPECT_LT(wait_count, 10) << "Lost frames in the VideoProcessor.";
573 }
574
575 ReleaseAndCloseObjects(&task_queue);
576
577 // Verify QP parsing.
578 // TODO(brandtr): This verification is somewhat orthogonal to the rest of
579 // this test, which is focused on measuring image quality and rate control
580 // quality. We should create a whole separate test that verifies the QP
581 // parsing. This could be done by instantiating a VideoProcessor, encoding
582 // a number of frames, and then verifying the parsing.
583 if (!config_.hw_codec &&
584 (config_.codec_settings.codecType == kVideoCodecVP8 ||
585 config_.codec_settings.codecType == kVideoCodecVP9)) {
586 for (int frame_number = 0; frame_number < num_frames; ++frame_number) {
587 task_queue.PostTask([this, frame_number] {
588 EXPECT_EQ(processor_->GetQpFromEncoder(frame_number),
589 processor_->GetQpFromBitstream(frame_number));
590 });
591 }
592 }
593
594 // Calculate and print rate control statistics.
595 rate_update_index = 0;
596 frame_number = 0;
597 UpdateRates(rate_update_index, rate_profile);
598 ResetRateControlMetrics(
599 rate_profile.frame_index_rate_update[rate_update_index + 1]);
484 target_size_key_frame_initial_ = 600 target_size_key_frame_initial_ =
485 0.5 * kInitialBufferSize * bitrate_layer_[0]; 601 0.5 * kInitialBufferSize * bitrate_layer_[0];
åsapersson 2017/08/29 13:42:33 maybe move to ResetRateControlMetrics?
brandtr 2017/08/30 11:44:26 Done.
486 processor_->SetRates(bitrate_kbps_, framerate_); 602 std::vector<int> num_dropped_frames;
487 603 std::vector<int> num_resize_actions;
488 // Process each frame, up to |num_frames|. 604 sync_event.Reset();
489 int frame_number = 0; 605 task_queue.PostTask(
490 int update_index = 0; 606 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
491 int num_frames = rate_profile.num_frames; 607 num_dropped_frames = processor_->NumberDroppedFramesPerRateUpdate();
492 ResetRateControlMetrics( 608 num_resize_actions = processor_->NumberSpatialResizesPerRateUpdate();
493 rate_profile.frame_index_rate_update[update_index + 1]); 609 sync_event.Set();
494 610 });
611 sync_event.Wait(rtc::Event::kForever);
495 while (frame_number < num_frames) { 612 while (frame_number < num_frames) {
496 processor_->ProcessFrame(frame_number);
497 VerifyQpParser(frame_number);
498 const int tl_idx = TemporalLayerIndexForFrame(frame_number);
499 ++num_frames_per_update_[tl_idx];
500 ++num_frames_total_;
501 UpdateRateControlMetrics(frame_number); 613 UpdateRateControlMetrics(frame_number);
502 614
503 ++frame_number; 615 ++frame_number;
504 616
505 // If we hit another/next update, verify stats for current state and
506 // update layers and codec with new rates.
507 if (frame_number == 617 if (frame_number ==
508 rate_profile.frame_index_rate_update[update_index + 1]) { 618 rate_profile.frame_index_rate_update[rate_update_index + 1]) {
509 PrintAndMaybeVerifyRateControlMetrics(update_index, rc_thresholds); 619 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
510 620 num_dropped_frames,
511 // Update layer rates and the codec with new rates. 621 num_resize_actions);
512 ++update_index; 622 ++rate_update_index;
513 bitrate_kbps_ = rate_profile.target_bit_rate[update_index]; 623 UpdateRates(rate_update_index, rate_profile);
514 framerate_ = rate_profile.input_frame_rate[update_index];
515 SetTemporalLayerRates();
516 ResetRateControlMetrics( 624 ResetRateControlMetrics(
517 rate_profile.frame_index_rate_update[update_index + 1]); 625 rate_profile.frame_index_rate_update[rate_update_index + 1]);
åsapersson 2017/08/29 13:42:33 call ResetRateControlMetrics from UpdateRates?
brandtr 2017/08/30 11:44:26 Done: merged the two functions into one.
518 processor_->SetRates(bitrate_kbps_, framerate_);
519 } 626 }
520 } 627 }
628 PrintAndMaybeVerifyRateControlMetrics(rate_update_index, rc_thresholds,
629 num_dropped_frames,
630 num_resize_actions);
521 631
522 // Verify rate control metrics for all frames since the last rate update. 632 // Calculate and print other statistics.
523 PrintAndMaybeVerifyRateControlMetrics(update_index, rc_thresholds);
524 EXPECT_EQ(num_frames, frame_number);
525 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size())); 633 EXPECT_EQ(num_frames, static_cast<int>(stats_.stats_.size()));
634 stats_.PrintSummary();
526 635
527 // Release encoder and decoder to make sure they have finished processing. 636 // Calculate and print image quality statistics.
528 processor_->Release();
529 DestroyEncoderAndDecoder();
530
531 // Close the analysis files before we use them for SSIM/PSNR calculations.
532 analysis_frame_reader_->Close();
533 analysis_frame_writer_->Close();
534
535 // Close visualization files.
536 if (encoded_frame_writer_) {
537 EXPECT_TRUE(encoded_frame_writer_->Close());
538 }
539 if (decoded_frame_writer_) {
540 decoded_frame_writer_->Close();
541 }
542
543 // TODO(marpan): Should compute these quality metrics per SetRates update. 637 // TODO(marpan): Should compute these quality metrics per SetRates update.
544 QualityMetricsResult psnr_result, ssim_result; 638 QualityMetricsResult psnr_result, ssim_result;
545 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(), 639 EXPECT_EQ(0, I420MetricsFromFiles(config_.input_filename.c_str(),
546 config_.output_filename.c_str(), 640 config_.output_filename.c_str(),
547 config_.codec_settings.width, 641 config_.codec_settings.width,
548 config_.codec_settings.height, 642 config_.codec_settings.height,
549 &psnr_result, &ssim_result)); 643 &psnr_result, &ssim_result));
550 if (quality_thresholds) { 644 if (quality_thresholds) {
551 VerifyQuality(psnr_result, ssim_result, *quality_thresholds); 645 VerifyQuality(psnr_result, ssim_result, *quality_thresholds);
552 } 646 }
553 stats_.PrintSummary();
554 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n", 647 printf("PSNR avg: %f, min: %f\nSSIM avg: %f, min: %f\n",
555 psnr_result.average, psnr_result.min, ssim_result.average, 648 psnr_result.average, psnr_result.min, ssim_result.average,
556 ssim_result.min); 649 ssim_result.min);
557 printf("\n"); 650 printf("\n");
558 651
559 // Remove analysis file. 652 // Remove analysis file.
560 if (remove(config_.output_filename.c_str()) < 0) { 653 if (remove(config_.output_filename.c_str()) < 0) {
561 fprintf(stderr, "Failed to remove temporary file!\n"); 654 fprintf(stderr, "Failed to remove temporary file!\n");
562 } 655 }
563 } 656 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 float target_size_key_frame_initial_; 790 float target_size_key_frame_initial_;
698 float target_size_key_frame_; 791 float target_size_key_frame_;
699 float sum_key_frame_size_mismatch_; 792 float sum_key_frame_size_mismatch_;
700 int num_key_frames_; 793 int num_key_frames_;
701 }; 794 };
702 795
703 } // namespace test 796 } // namespace test
704 } // namespace webrtc 797 } // namespace webrtc
705 798
706 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ 799 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698