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

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

Issue 2741953002: Step #4: Run VideoProcessor integration test batch mode on task queue. (Closed)
Patch Set: tommi comments 1: Add thread safety annotations. Created 3 years, 9 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 10 matching lines...) Expand all
21 #if defined(WEBRTC_ANDROID) 21 #if defined(WEBRTC_ANDROID)
22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h" 22 #include "webrtc/modules/video_coding/codecs/test/android_test_initializer.h"
23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h" 23 #include "webrtc/sdk/android/src/jni/androidmediadecoder_jni.h"
24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h" 24 #include "webrtc/sdk/android/src/jni/androidmediaencoder_jni.h"
25 #elif defined(WEBRTC_IOS) 25 #elif defined(WEBRTC_IOS)
26 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h" 26 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_decoder.h"
27 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h" 27 #include "webrtc/sdk/objc/Framework/Classes/h264_video_toolbox_encoder.h"
28 #endif 28 #endif
29 29
30 #include "webrtc/base/checks.h" 30 #include "webrtc/base/checks.h"
31 #include "webrtc/base/event.h"
31 #include "webrtc/base/file.h" 32 #include "webrtc/base/file.h"
32 #include "webrtc/base/logging.h" 33 #include "webrtc/base/logging.h"
34 #include "webrtc/base/task_queue.h"
33 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" 35 #include "webrtc/media/engine/webrtcvideodecoderfactory.h"
34 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" 36 #include "webrtc/media/engine/webrtcvideoencoderfactory.h"
35 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" 37 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
36 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" 38 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
37 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" 39 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
38 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 40 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
39 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" 41 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
40 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" 42 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
41 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 43 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
42 #include "webrtc/modules/video_coding/include/video_coding.h" 44 #include "webrtc/modules/video_coding/include/video_coding.h"
43 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 45 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
46 #include "webrtc/system_wrappers/include/sleep.h"
44 #include "webrtc/test/gtest.h" 47 #include "webrtc/test/gtest.h"
45 #include "webrtc/test/testsupport/fileutils.h" 48 #include "webrtc/test/testsupport/fileutils.h"
46 #include "webrtc/test/testsupport/frame_reader.h" 49 #include "webrtc/test/testsupport/frame_reader.h"
47 #include "webrtc/test/testsupport/frame_writer.h" 50 #include "webrtc/test/testsupport/frame_writer.h"
48 #include "webrtc/test/testsupport/metrics/video_metrics.h" 51 #include "webrtc/test/testsupport/metrics/video_metrics.h"
49 #include "webrtc/test/testsupport/packet_reader.h" 52 #include "webrtc/test/testsupport/packet_reader.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 // Maximum number of rate updates (i.e., calls to encoder to change bitrate 57 // Maximum number of rate updates (i.e., calls to encoder to change bitrate
55 // and/or frame rate) for the current tests. 58 // and/or frame rate) for the current tests.
56 const int kMaxNumRateUpdates = 3; 59 const int kMaxNumRateUpdates = 3;
57 60
58 // Maximum number of temporal layers to use in tests. 61 // Maximum number of temporal layers to use in tests.
59 const int kMaxNumTemporalLayers = 3; 62 const int kMaxNumTemporalLayers = 3;
60 63
61 const int kPercTargetvsActualMismatch = 20; 64 const int kPercTargetvsActualMismatch = 20;
62 const int kBaseKeyFrameInterval = 3000; 65 const int kBaseKeyFrameInterval = 3000;
63 66
64 // Default sequence is foreman (CIF): may be better to use VGA for resize test. 67 // Default sequence is foreman (CIF): may be better to use VGA for resize test.
65 const int kCifWidth = 352; 68 const int kCifWidth = 352;
66 const int kCifHeight = 288; 69 const int kCifHeight = 288;
67 const char kFilenameForemanCif[] = "foreman_cif"; 70 const char kFilenameForemanCif[] = "foreman_cif";
68 71
72 const int kNumMillisecondsPerSecond = 1000;
sprang_webrtc 2017/03/20 19:36:17 use rtc::kNumMillisPerSecond instead?
brandtr 2017/03/21 09:40:54 Done.
73
69 // Codec and network settings. 74 // Codec and network settings.
70 struct CodecParams { 75 struct CodecParams {
71 VideoCodecType codec_type; 76 VideoCodecType codec_type;
72 bool hw_codec; 77 bool hw_codec;
73 bool use_single_core; 78 bool use_single_core;
74 79
75 int width; 80 int width;
76 int height; 81 int height;
77 82
78 int num_temporal_layers; 83 int num_temporal_layers;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 encoder_.reset(VP9Encoder::Create()); 234 encoder_.reset(VP9Encoder::Create());
230 decoder_.reset(VP9Decoder::Create()); 235 decoder_.reset(VP9Decoder::Create());
231 break; 236 break;
232 default: 237 default:
233 RTC_NOTREACHED(); 238 RTC_NOTREACHED();
234 break; 239 break;
235 } 240 }
236 } 241 }
237 242
238 void SetUpCodecConfig(const CodecParams& process, 243 void SetUpCodecConfig(const CodecParams& process,
244 const RateProfile& rate_profile,
239 const VisualizationParams* visualization_params) { 245 const VisualizationParams* visualization_params) {
240 CreateEncoderAndDecoder(process.hw_codec, process.codec_type); 246 CreateEncoderAndDecoder(process.hw_codec, process.codec_type);
241 247
242 // Configure input filename. 248 // Configure input filename.
243 config_.input_filename = test::ResourcePath(process.filename, "yuv"); 249 config_.input_filename = test::ResourcePath(process.filename, "yuv");
244 if (process.verbose_logging) 250 if (process.verbose_logging)
245 printf("Filename: %s\n", process.filename.c_str()); 251 printf("Filename: %s\n", process.filename.c_str());
246 // Generate an output filename in a safe way. 252 // Generate an output filename in a safe way.
247 config_.output_filename = test::TempFilename( 253 config_.output_filename = test::TempFilename(
248 test::OutputPath(), "videoprocessor_integrationtest"); 254 test::OutputPath(), "videoprocessor_integrationtest");
249 255
250 config_.frame_length_in_bytes = 256 config_.frame_length_in_bytes =
251 CalcBufferSize(kI420, process.width, process.height); 257 CalcBufferSize(kI420, process.width, process.height);
252 config_.verbose = process.verbose_logging; 258 config_.verbose = process.verbose_logging;
253 config_.use_single_core = process.use_single_core; 259 config_.use_single_core = process.use_single_core;
254 // Key frame interval and packet loss are set for each test. 260 // Key frame interval and packet loss are set for each test.
255 config_.keyframe_interval = process.key_frame_interval; 261 config_.keyframe_interval = process.key_frame_interval;
256 config_.networking_config.packet_loss_probability = 262 config_.networking_config.packet_loss_probability =
257 packet_loss_probability_; 263 process.packet_loss_probability;
258 264
259 // Configure codec settings. 265 // Configure codec settings.
260 VideoCodingModule::Codec(process.codec_type, &codec_settings_); 266 VideoCodingModule::Codec(process.codec_type, &codec_settings_);
261 config_.codec_settings = &codec_settings_; 267 config_.codec_settings = &codec_settings_;
262 config_.codec_settings->startBitrate = start_bitrate_; 268 float start_bitrate = rate_profile.target_bit_rate[0];
269 config_.codec_settings->startBitrate = start_bitrate;
263 config_.codec_settings->width = process.width; 270 config_.codec_settings->width = process.width;
264 config_.codec_settings->height = process.height; 271 config_.codec_settings->height = process.height;
265 272
266 // These features may be set depending on the test. 273 // These features may be set depending on the test.
267 switch (config_.codec_settings->codecType) { 274 switch (config_.codec_settings->codecType) {
268 case kVideoCodecH264: 275 case kVideoCodecH264:
269 config_.codec_settings->H264()->frameDroppingOn = 276 config_.codec_settings->H264()->frameDroppingOn =
270 process.frame_dropper_on; 277 process.frame_dropper_on;
271 config_.codec_settings->H264()->keyFrameInterval = 278 config_.codec_settings->H264()->keyFrameInterval =
272 kBaseKeyFrameInterval; 279 kBaseKeyFrameInterval;
(...skipping 29 matching lines...) Expand all
302 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( 309 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl(
303 config_.input_filename, config_.codec_settings->width, 310 config_.input_filename, config_.codec_settings->width,
304 config_.codec_settings->height)); 311 config_.codec_settings->height));
305 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( 312 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl(
306 config_.output_filename, config_.codec_settings->width, 313 config_.output_filename, config_.codec_settings->width,
307 config_.codec_settings->height)); 314 config_.codec_settings->height));
308 RTC_CHECK(analysis_frame_reader_->Init()); 315 RTC_CHECK(analysis_frame_reader_->Init());
309 RTC_CHECK(analysis_frame_writer_->Init()); 316 RTC_CHECK(analysis_frame_writer_->Init());
310 317
311 if (visualization_params) { 318 if (visualization_params) {
319 int start_frame_rate = rate_profile.input_frame_rate[0];
312 // clang-format off 320 // clang-format off
313 const std::string output_filename_base = 321 const std::string output_filename_base =
314 test::OutputPath() + process.filename + 322 test::OutputPath() + process.filename +
315 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") + 323 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") +
316 "_hw-" + std::to_string(process.hw_codec) + 324 "_hw-" + std::to_string(process.hw_codec) +
317 "_fr-" + std::to_string(start_frame_rate_) + 325 "_fr-" + std::to_string(start_frame_rate) +
318 "_br-" + std::to_string(static_cast<int>(start_bitrate_)); 326 "_br-" + std::to_string(static_cast<int>(start_bitrate));
319 // clang-format on 327 // clang-format on
320 if (visualization_params->save_source_y4m) { 328 if (visualization_params->save_source_y4m) {
321 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( 329 source_frame_writer_.reset(new test::Y4mFrameWriterImpl(
322 output_filename_base + "_source.y4m", config_.codec_settings->width, 330 output_filename_base + "_source.y4m", config_.codec_settings->width,
323 config_.codec_settings->height, start_frame_rate_)); 331 config_.codec_settings->height, start_frame_rate));
324 RTC_CHECK(source_frame_writer_->Init()); 332 RTC_CHECK(source_frame_writer_->Init());
325 } 333 }
326 if (visualization_params->save_encoded_ivf) { 334 if (visualization_params->save_encoded_ivf) {
327 rtc::File post_encode_file = 335 rtc::File post_encode_file =
328 rtc::File::Create(output_filename_base + "_encoded.ivf"); 336 rtc::File::Create(output_filename_base + "_encoded.ivf");
329 encoded_frame_writer_ = 337 encoded_frame_writer_ =
330 IvfFileWriter::Wrap(std::move(post_encode_file), 0); 338 IvfFileWriter::Wrap(std::move(post_encode_file), 0);
331 } 339 }
332 if (visualization_params->save_decoded_y4m) { 340 if (visualization_params->save_decoded_y4m) {
333 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( 341 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl(
334 output_filename_base + "_decoded.y4m", 342 output_filename_base + "_decoded.y4m",
335 config_.codec_settings->width, config_.codec_settings->height, 343 config_.codec_settings->width, config_.codec_settings->height,
336 start_frame_rate_)); 344 start_frame_rate));
337 RTC_CHECK(decoded_frame_writer_->Init()); 345 RTC_CHECK(decoded_frame_writer_->Init());
338 } 346 }
339 } 347 }
340 348
341 packet_manipulator_.reset(new test::PacketManipulatorImpl( 349 packet_manipulator_.reset(new test::PacketManipulatorImpl(
342 &packet_reader_, config_.networking_config, config_.verbose)); 350 &packet_reader_, config_.networking_config, config_.verbose));
343 processor_.reset(new test::VideoProcessorImpl( 351 processor_.reset(new test::VideoProcessorImpl(
344 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), 352 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(),
345 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, 353 analysis_frame_writer_.get(), packet_manipulator_.get(), config_,
346 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), 354 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(),
347 decoded_frame_writer_.get())); 355 decoded_frame_writer_.get()));
348 RTC_CHECK(processor_->Init());
349 } 356 }
350 357
351 // Reset quantities after each encoder update, update the target 358 // Reset quantities after each encoder update, update the target
352 // per-frame bandwidth. 359 // per-frame bandwidth.
353 void ResetRateControlMetrics(int num_frames_to_hit_target) { 360 void ResetRateControlMetrics(int num_frames_to_hit_target) {
354 for (int i = 0; i < num_temporal_layers_; i++) { 361 for (int i = 0; i < num_temporal_layers_; i++) {
355 num_frames_per_update_[i] = 0; 362 num_frames_per_update_[i] = 0;
356 sum_frame_size_mismatch_[i] = 0.0f; 363 sum_frame_size_mismatch_[i] = 0.0f;
357 sum_encoded_frame_size_[i] = 0.0f; 364 sum_encoded_frame_size_[i] = 0.0f;
358 encoding_bitrate_[i] = 0.0f; 365 encoding_bitrate_[i] = 0.0f;
(...skipping 13 matching lines...) Expand all
372 sum_encoded_frame_size_total_ = 0.0f; 379 sum_encoded_frame_size_total_ = 0.0f;
373 encoding_bitrate_total_ = 0.0f; 380 encoding_bitrate_total_ = 0.0f;
374 perc_encoding_rate_mismatch_ = 0.0f; 381 perc_encoding_rate_mismatch_ = 0.0f;
375 num_frames_to_hit_target_ = num_frames_to_hit_target; 382 num_frames_to_hit_target_ = num_frames_to_hit_target;
376 encoding_rate_within_target_ = false; 383 encoding_rate_within_target_ = false;
377 sum_key_frame_size_mismatch_ = 0.0; 384 sum_key_frame_size_mismatch_ = 0.0;
378 num_key_frames_ = 0; 385 num_key_frames_ = 0;
379 } 386 }
380 387
381 // For every encoded frame, update the rate control metrics. 388 // For every encoded frame, update the rate control metrics.
382 void UpdateRateControlMetrics(int frame_number) { 389 void UpdateRateControlMetrics(int frame_number,
390 FrameType frame_type,
391 size_t encoded_frame_size) {
383 RTC_CHECK_GE(frame_number, 0); 392 RTC_CHECK_GE(frame_number, 0);
384 int tl_idx = TemporalLayerIndexForFrame(frame_number); 393 int tl_idx = TemporalLayerIndexForFrame(frame_number);
385 FrameType frame_type = processor_->EncodedFrameType(frame_number); 394 float encoded_size_kbits = encoded_frame_size * 8.0f / 1000.0f;
386 float encoded_size_kbits =
387 processor_->EncodedFrameSize(frame_number) * 8.0f / 1000.0f;
388 395
389 // Update layer data. 396 // Update layer data.
390 // Update rate mismatch relative to per-frame bandwidth for delta frames. 397 // Update rate mismatch relative to per-frame bandwidth for delta frames.
391 if (frame_type == kVideoFrameDelta) { 398 if (frame_type == kVideoFrameDelta) {
392 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? 399 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
393 sum_frame_size_mismatch_[tl_idx] += 400 sum_frame_size_mismatch_[tl_idx] +=
394 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / 401 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) /
395 per_frame_bandwidth_[tl_idx]; 402 per_frame_bandwidth_[tl_idx];
396 } else { 403 } else {
397 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ 404 float target_size = (frame_number == 0) ? target_size_key_frame_initial_
(...skipping 14 matching lines...) Expand all
412 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; 419 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_;
413 perc_encoding_rate_mismatch_ = 420 perc_encoding_rate_mismatch_ =
414 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; 421 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_;
415 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && 422 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
416 !encoding_rate_within_target_) { 423 !encoding_rate_within_target_) {
417 num_frames_to_hit_target_ = num_frames_total_; 424 num_frames_to_hit_target_ = num_frames_total_;
418 encoding_rate_within_target_ = true; 425 encoding_rate_within_target_ = true;
419 } 426 }
420 } 427 }
421 428
429 void UpdateRateControlMetrics(int frame_number, rtc::TaskQueue* task_queue) {
430 FrameType frame_type;
431 size_t encoded_frame_size;
432
433 if (task_queue) {
434 rtc::Event sync_event(false, false);
435 task_queue->PostTask([this, &frame_type, &encoded_frame_size,
436 frame_number, &sync_event]() {
437 frame_type = processor_->EncodedFrameType(frame_number);
438 encoded_frame_size = processor_->EncodedFrameSize(frame_number);
439 sync_event.Set();
440 });
441 sync_event.Wait(rtc::Event::kForever);
sprang_webrtc 2017/03/20 19:36:17 nit: ASSERT_TRUE() maybe?
brandtr 2017/03/21 09:40:54 Done.
442 } else {
443 frame_type = processor_->EncodedFrameType(frame_number);
444 encoded_frame_size = processor_->EncodedFrameSize(frame_number);
445 }
446
447 UpdateRateControlMetrics(frame_number, frame_type, encoded_frame_size);
448 }
449
450 void UpdateRateControlMetrics(int frame_number) {
451 UpdateRateControlMetrics(frame_number, nullptr);
452 }
453
422 // Verify expected behavior of rate control and print out data. 454 // Verify expected behavior of rate control and print out data.
423 void VerifyRateControlMetrics(int update_index, 455 void VerifyRateControlMetrics(int update_index,
424 const RateControlThresholds& rc_expected) { 456 const RateControlThresholds& rc_expected,
425 int num_dropped_frames = processor_->NumberDroppedFrames(); 457 int num_dropped_frames,
426 int num_resize_actions = processor_->NumberSpatialResizes(); 458 int num_resize_actions) {
427 printf( 459 printf(
428 "For update #: %d,\n" 460 "For update #: %d,\n"
429 " Target Bitrate: %d,\n" 461 " Target Bitrate: %d,\n"
430 " Encoding bitrate: %f,\n" 462 " Encoding bitrate: %f,\n"
431 " Frame rate: %d \n", 463 " Frame rate: %d \n",
432 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); 464 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_);
433 printf( 465 printf(
434 " Number of frames to approach target rate: %d, \n" 466 " Number of frames to approach target rate: %d, \n"
435 " Number of dropped frames: %d, \n" 467 " Number of dropped frames: %d, \n"
436 " Number of spatial resizes: %d, \n", 468 " Number of spatial resizes: %d, \n",
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); 508 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target);
477 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); 509 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames);
478 if (rc_expected.num_spatial_resizes >= 0) { 510 if (rc_expected.num_spatial_resizes >= 0) {
479 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); 511 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions);
480 } 512 }
481 if (rc_expected.num_key_frames >= 0) { 513 if (rc_expected.num_key_frames >= 0) {
482 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); 514 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_);
483 } 515 }
484 } 516 }
485 517
518 void VerifyRateControlMetrics(int update_index,
519 const RateControlThresholds& rc_expected,
520 rtc::TaskQueue* task_queue) {
521 int num_dropped_frames;
522 int num_resize_actions;
523
524 if (task_queue) {
525 rtc::Event sync_event(false, false);
526 task_queue->PostTask(
527 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() {
528 num_dropped_frames = processor_->NumberDroppedFrames();
529 num_resize_actions = processor_->NumberSpatialResizes();
530 sync_event.Set();
531 });
532 sync_event.Wait(rtc::Event::kForever);
533 } else {
534 num_dropped_frames = processor_->NumberDroppedFrames();
535 num_resize_actions = processor_->NumberSpatialResizes();
536 }
537
538 VerifyRateControlMetrics(update_index, rc_expected, num_dropped_frames,
539 num_resize_actions);
540 }
541
542 void VerifyRateControlMetrics(int update_index,
543 const RateControlThresholds& rc_expected) {
544 VerifyRateControlMetrics(update_index, rc_expected, nullptr);
545 }
546
486 void VerifyQuality(const test::QualityMetricsResult& psnr_result, 547 void VerifyQuality(const test::QualityMetricsResult& psnr_result,
487 const test::QualityMetricsResult& ssim_result, 548 const test::QualityMetricsResult& ssim_result,
488 const QualityThresholds& quality_thresholds) { 549 const QualityThresholds& quality_thresholds) {
489 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); 550 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr);
490 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); 551 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr);
491 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); 552 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim);
492 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); 553 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim);
493 } 554 }
494 555
495 // Temporal layer index corresponding to frame number, for up to 3 layers. 556 // Temporal layer index corresponding to frame number, for up to 3 layers.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 // TODO(brandtr): Change the second last argument to be a 610 // TODO(brandtr): Change the second last argument to be a
550 // const std::vector<RateControlThresholds>&, so we can ensure that the user 611 // const std::vector<RateControlThresholds>&, so we can ensure that the user
551 // does not expect us to do mid-clip rate updates when we are not able to, 612 // does not expect us to do mid-clip rate updates when we are not able to,
552 // e.g., when we are operating in batch mode. 613 // e.g., when we are operating in batch mode.
553 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, 614 void ProcessFramesAndVerify(QualityThresholds quality_thresholds,
554 RateProfile rate_profile, 615 RateProfile rate_profile,
555 CodecParams process, 616 CodecParams process,
556 RateControlThresholds* rc_thresholds, 617 RateControlThresholds* rc_thresholds,
557 const VisualizationParams* visualization_params) { 618 const VisualizationParams* visualization_params) {
558 // Codec/config settings. 619 // Codec/config settings.
559 start_bitrate_ = rate_profile.target_bit_rate[0];
560 start_frame_rate_ = rate_profile.input_frame_rate[0];
561 packet_loss_probability_ = process.packet_loss_probability;
562 num_temporal_layers_ = process.num_temporal_layers; 620 num_temporal_layers_ = process.num_temporal_layers;
563 SetUpCodecConfig(process, visualization_params); 621 SetUpCodecConfig(process, rate_profile, visualization_params);
622
564 // Update the temporal layers and the codec with the initial rates. 623 // Update the temporal layers and the codec with the initial rates.
565 bit_rate_ = rate_profile.target_bit_rate[0]; 624 bit_rate_ = rate_profile.target_bit_rate[0];
566 frame_rate_ = rate_profile.input_frame_rate[0]; 625 frame_rate_ = rate_profile.input_frame_rate[0];
567 SetTemporalLayerRates(); 626 SetTemporalLayerRates();
568 // Set the initial target size for key frame. 627 // Set the initial target size for key frame.
569 target_size_key_frame_initial_ = 628 target_size_key_frame_initial_ =
570 0.5 * kInitialBufferSize * bit_rate_layer_[0]; 629 0.5 * kInitialBufferSize * bit_rate_layer_[0];
571 processor_->SetRates(bit_rate_, frame_rate_);
572 630
573 // Process each frame, up to |num_frames|. 631 // Process each frame, up to |num_frames|.
574 int frame_number = 0; 632 int frame_number = 0;
575 int update_index = 0; 633 int update_index = 0;
576 int num_frames = rate_profile.num_frames; 634 int num_frames = rate_profile.num_frames;
577 ResetRateControlMetrics( 635 ResetRateControlMetrics(
578 rate_profile.frame_index_rate_update[update_index + 1]); 636 rate_profile.frame_index_rate_update[update_index + 1]);
579 637
580 if (process.batch_mode) { 638 if (process.batch_mode) {
581 // In batch mode, we calculate the metrics for all frames after all frames 639 // In batch mode, we calculate the metrics for all frames after all frames
582 // have been sent for encoding. 640 // have been sent for encoding.
583 641
642 // AndroidMediaEncoder must be called on a task queue, so during the batch
643 // run we will call |processor_| on a task queue.
644 std::unique_ptr<rtc::TaskQueue> task_queue(
645 new rtc::TaskQueue("Integration test task queue."));
sprang_webrtc 2017/03/20 19:36:17 might want to choose a shorter name. think some os
brandtr 2017/03/21 09:40:54 Done.
646
647 // Initialize |processor_|, which initializes the encoder and decoder.
648 rtc::Event sync_event(false, false);
649 task_queue->PostTask([this, &sync_event]() {
650 RTC_CHECK(processor_->Init());
651 processor_->SetRates(bit_rate_, frame_rate_);
652 sync_event.Set();
653 });
654 sync_event.Wait(rtc::Event::kForever);
655
656 // Post all frames (in order) to encoder.
657 int start_frame_rate = rate_profile.input_frame_rate[0];
584 // TODO(brandtr): Refactor "frame number accounting" so we don't have to 658 // TODO(brandtr): Refactor "frame number accounting" so we don't have to
585 // call ProcessFrame num_frames+1 times here. 659 // call ProcessFrame num_frames+1 times here.
586 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { 660 for (frame_number = 0; frame_number <= num_frames; ++frame_number) {
587 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); 661 task_queue->PostTask([this, frame_number]() {
662 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
663 });
664
665 // HW codecs can get stressed out if frames are arriving to quickly,
666 // so we do some rough pacing here.
sprang_webrtc 2017/03/20 19:36:17 How do they get "stressed out"? Any other form of
brandtr 2017/03/21 09:40:54 Expanded the comment. Another approach would be t
667 if (process.hw_codec) {
668 SleepMs(kNumMillisecondsPerSecond / start_frame_rate);
669 }
588 } 670 }
589 671
672 // Give the task queue some time to finish processing the posted frames,
673 // then shut down processing and synchronize with main thread.
674 SleepMs(1 * kNumMillisecondsPerSecond);
sprang_webrtc 2017/03/20 19:36:17 drop "1 *"
brandtr 2017/03/21 09:40:54 Done.
675 sync_event.Reset();
676 task_queue->PostTask([this, &sync_event]() {
677 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
678 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
679 processor_->DeregisterCallbacks();
680 sync_event.Set();
681 });
682 sync_event.Wait(rtc::Event::kForever);
683
684 // Calculate and print rate control metrics.
590 for (frame_number = 0; frame_number < num_frames; ++frame_number) { 685 for (frame_number = 0; frame_number < num_frames; ++frame_number) {
591 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; 686 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)];
592 ++num_frames_total_; 687 ++num_frames_total_;
593 UpdateRateControlMetrics(frame_number); 688 UpdateRateControlMetrics(frame_number, task_queue.get());
594 } 689 }
690
691 VerifyRateControlMetrics(update_index, rc_thresholds[0],
692 task_queue.get());
595 } else { 693 } else {
596 // In online mode, we calculate the metrics for a given frame right after 694 // In online mode, we calculate the metrics for a given frame right after
597 // it has been sent for encoding. 695 // it has been sent for encoding.
598 696
599 if (process.hw_codec) { 697 if (process.hw_codec) {
600 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " 698 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, "
601 "since they may be pipelining."; 699 "since they may be pipelining.";
602 } 700 }
603 701
702 // Initialize |processor_| on main thread.
703 RTC_CHECK(processor_->Init());
704 processor_->SetRates(bit_rate_, frame_rate_);
705
604 while (frame_number < num_frames) { 706 while (frame_number < num_frames) {
605 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); 707 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
606 708
607 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; 709 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)];
608 ++num_frames_total_; 710 ++num_frames_total_;
609 UpdateRateControlMetrics(frame_number); 711 UpdateRateControlMetrics(frame_number);
610 712
611 ++frame_number; 713 ++frame_number;
612 714
613 // If we hit another/next update, verify stats for current state and 715 // If we hit another/next update, verify stats for current state and
614 // update layers and codec with new rates. 716 // update layers and codec with new rates.
615 if (frame_number == 717 if (frame_number ==
616 rate_profile.frame_index_rate_update[update_index + 1]) { 718 rate_profile.frame_index_rate_update[update_index + 1]) {
617 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); 719 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
618 720
619 // Update layer rates and the codec with new rates. 721 // Update layer rates and the codec with new rates.
620 ++update_index; 722 ++update_index;
621 bit_rate_ = rate_profile.target_bit_rate[update_index]; 723 bit_rate_ = rate_profile.target_bit_rate[update_index];
622 frame_rate_ = rate_profile.input_frame_rate[update_index]; 724 frame_rate_ = rate_profile.input_frame_rate[update_index];
623 SetTemporalLayerRates(); 725 SetTemporalLayerRates();
624 ResetRateControlMetrics( 726 ResetRateControlMetrics(
625 rate_profile.frame_index_rate_update[update_index + 1]); 727 rate_profile.frame_index_rate_update[update_index + 1]);
626 processor_->SetRates(bit_rate_, frame_rate_); 728 processor_->SetRates(bit_rate_, frame_rate_);
627 } 729 }
628 } 730 }
629 // TODO(brandtr): Refactor "frame number accounting" so we don't have to 731 // TODO(brandtr): Refactor "frame number accounting" so we don't have to
630 // call ProcessFrame one extra time here. 732 // call ProcessFrame one extra time here.
631 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); 733 EXPECT_TRUE(processor_->ProcessFrame(frame_number));
734
735 // Release codecs to make sure they have finished processing.
736 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
737 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
738 processor_->DeregisterCallbacks();
739
740 // Verify for final rate update.
741 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
632 } 742 }
633
634 // Verify rate control metrics for all frames (if in batch mode), or for all
635 // frames since the last rate update (if not in batch mode).
636 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]);
637 EXPECT_EQ(num_frames, frame_number); 743 EXPECT_EQ(num_frames, frame_number);
638 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); 744 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size()));
639 745
640 // Release encoder and decoder to make sure they have finished processing.
641 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
642 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
643
644 // Close the analysis files before we use them for SSIM/PSNR calculations. 746 // Close the analysis files before we use them for SSIM/PSNR calculations.
645 analysis_frame_reader_->Close(); 747 analysis_frame_reader_->Close();
646 analysis_frame_writer_->Close(); 748 analysis_frame_writer_->Close();
647 749
648 // Close visualization files. 750 // Close visualization files.
649 if (source_frame_writer_) { 751 if (source_frame_writer_) {
650 source_frame_writer_->Close(); 752 source_frame_writer_->Close();
651 } 753 }
652 if (encoded_frame_writer_) { 754 if (encoded_frame_writer_) {
653 EXPECT_TRUE(encoded_frame_writer_->Close()); 755 EXPECT_TRUE(encoded_frame_writer_->Close());
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 float encoding_bitrate_total_; 907 float encoding_bitrate_total_;
806 float perc_encoding_rate_mismatch_; 908 float perc_encoding_rate_mismatch_;
807 int num_frames_to_hit_target_; 909 int num_frames_to_hit_target_;
808 bool encoding_rate_within_target_; 910 bool encoding_rate_within_target_;
809 int bit_rate_; 911 int bit_rate_;
810 int frame_rate_; 912 int frame_rate_;
811 float target_size_key_frame_initial_; 913 float target_size_key_frame_initial_;
812 float target_size_key_frame_; 914 float target_size_key_frame_;
813 float sum_key_frame_size_mismatch_; 915 float sum_key_frame_size_mismatch_;
814 int num_key_frames_; 916 int num_key_frames_;
815 float start_bitrate_;
816 int start_frame_rate_;
817 917
818 // Codec and network settings. 918 // Codec and network settings.
819 float packet_loss_probability_;
820 int num_temporal_layers_; 919 int num_temporal_layers_;
821 }; 920 };
822 921
823 } // namespace test 922 } // namespace test
824 } // namespace webrtc 923 } // namespace webrtc
825 924
826 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_ 925 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES T_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698