OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
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/VideoToolbox/decoder.h" | 26 #include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/decoder.h" |
27 #include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h" | 27 #include "webrtc/sdk/objc/Framework/Classes/VideoToolbox/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" |
| 35 #include "webrtc/base/timeutils.h" |
33 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" | 36 #include "webrtc/media/engine/webrtcvideodecoderfactory.h" |
34 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 37 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
35 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 38 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
36 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" | 39 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" |
37 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" | 40 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
38 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 41 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
39 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 42 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
40 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 43 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
41 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 44 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
42 #include "webrtc/modules/video_coding/include/video_coding.h" | 45 #include "webrtc/modules/video_coding/include/video_coding.h" |
43 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" | 46 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" |
| 47 #include "webrtc/system_wrappers/include/sleep.h" |
44 #include "webrtc/test/gtest.h" | 48 #include "webrtc/test/gtest.h" |
45 #include "webrtc/test/testsupport/fileutils.h" | 49 #include "webrtc/test/testsupport/fileutils.h" |
46 #include "webrtc/test/testsupport/frame_reader.h" | 50 #include "webrtc/test/testsupport/frame_reader.h" |
47 #include "webrtc/test/testsupport/frame_writer.h" | 51 #include "webrtc/test/testsupport/frame_writer.h" |
48 #include "webrtc/test/testsupport/metrics/video_metrics.h" | 52 #include "webrtc/test/testsupport/metrics/video_metrics.h" |
49 #include "webrtc/test/testsupport/packet_reader.h" | 53 #include "webrtc/test/testsupport/packet_reader.h" |
50 #include "webrtc/typedefs.h" | 54 #include "webrtc/typedefs.h" |
51 | 55 |
52 namespace webrtc { | 56 namespace webrtc { |
53 namespace test { | 57 namespace test { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 encoder_.reset(VP9Encoder::Create()); | 234 encoder_.reset(VP9Encoder::Create()); |
231 decoder_.reset(VP9Decoder::Create()); | 235 decoder_.reset(VP9Decoder::Create()); |
232 break; | 236 break; |
233 default: | 237 default: |
234 RTC_NOTREACHED(); | 238 RTC_NOTREACHED(); |
235 break; | 239 break; |
236 } | 240 } |
237 } | 241 } |
238 | 242 |
239 void SetUpCodecConfig(const CodecParams& process, | 243 void SetUpCodecConfig(const CodecParams& process, |
| 244 const RateProfile& rate_profile, |
240 const VisualizationParams* visualization_params) { | 245 const VisualizationParams* visualization_params) { |
241 CreateEncoderAndDecoder(process.hw_codec, process.codec_type); | 246 CreateEncoderAndDecoder(process.hw_codec, process.codec_type); |
242 | 247 |
243 // Configure input filename. | 248 // Configure input filename. |
244 config_.input_filename = test::ResourcePath(process.filename, "yuv"); | 249 config_.input_filename = test::ResourcePath(process.filename, "yuv"); |
245 if (process.verbose_logging) | 250 if (process.verbose_logging) |
246 printf("Filename: %s\n", process.filename.c_str()); | 251 printf("Filename: %s\n", process.filename.c_str()); |
247 // Generate an output filename in a safe way. | 252 // Generate an output filename in a safe way. |
248 config_.output_filename = test::TempFilename( | 253 config_.output_filename = test::TempFilename( |
249 test::OutputPath(), "videoprocessor_integrationtest"); | 254 test::OutputPath(), "videoprocessor_integrationtest"); |
250 | 255 |
251 config_.frame_length_in_bytes = | 256 config_.frame_length_in_bytes = |
252 CalcBufferSize(VideoType::kI420, process.width, process.height); | 257 CalcBufferSize(VideoType::kI420, process.width, process.height); |
253 config_.verbose = process.verbose_logging; | 258 config_.verbose = process.verbose_logging; |
254 config_.use_single_core = process.use_single_core; | 259 config_.use_single_core = process.use_single_core; |
255 // Key frame interval and packet loss are set for each test. | 260 // Key frame interval and packet loss are set for each test. |
256 config_.keyframe_interval = process.key_frame_interval; | 261 config_.keyframe_interval = process.key_frame_interval; |
257 config_.networking_config.packet_loss_probability = | 262 config_.networking_config.packet_loss_probability = |
258 packet_loss_probability_; | 263 process.packet_loss_probability; |
259 | 264 |
260 // Configure codec settings. | 265 // Configure codec settings. |
261 VideoCodingModule::Codec(process.codec_type, &codec_settings_); | 266 VideoCodingModule::Codec(process.codec_type, &codec_settings_); |
262 config_.codec_settings = &codec_settings_; | 267 config_.codec_settings = &codec_settings_; |
263 config_.codec_settings->startBitrate = start_bitrate_; | 268 float start_bitrate = rate_profile.target_bit_rate[0]; |
| 269 config_.codec_settings->startBitrate = start_bitrate; |
264 config_.codec_settings->width = process.width; | 270 config_.codec_settings->width = process.width; |
265 config_.codec_settings->height = process.height; | 271 config_.codec_settings->height = process.height; |
266 | 272 |
267 // These features may be set depending on the test. | 273 // These features may be set depending on the test. |
268 switch (config_.codec_settings->codecType) { | 274 switch (config_.codec_settings->codecType) { |
269 case kVideoCodecH264: | 275 case kVideoCodecH264: |
270 config_.codec_settings->H264()->frameDroppingOn = | 276 config_.codec_settings->H264()->frameDroppingOn = |
271 process.frame_dropper_on; | 277 process.frame_dropper_on; |
272 config_.codec_settings->H264()->keyFrameInterval = | 278 config_.codec_settings->H264()->keyFrameInterval = |
273 kBaseKeyFrameInterval; | 279 kBaseKeyFrameInterval; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 config_.codec_settings->height)); | 317 config_.codec_settings->height)); |
312 RTC_CHECK(analysis_frame_reader_->Init()); | 318 RTC_CHECK(analysis_frame_reader_->Init()); |
313 RTC_CHECK(analysis_frame_writer_->Init()); | 319 RTC_CHECK(analysis_frame_writer_->Init()); |
314 | 320 |
315 if (visualization_params) { | 321 if (visualization_params) { |
316 // clang-format off | 322 // clang-format off |
317 const std::string output_filename_base = | 323 const std::string output_filename_base = |
318 test::OutputPath() + process.filename + | 324 test::OutputPath() + process.filename + |
319 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") + | 325 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") + |
320 "_hw-" + std::to_string(process.hw_codec) + | 326 "_hw-" + std::to_string(process.hw_codec) + |
321 "_fr-" + std::to_string(start_frame_rate_) + | 327 "_br-" + std::to_string(static_cast<int>(start_bitrate)); |
322 "_br-" + std::to_string(static_cast<int>(start_bitrate_)); | |
323 // clang-format on | 328 // clang-format on |
| 329 int start_frame_rate = rate_profile.input_frame_rate[0]; |
324 if (visualization_params->save_source_y4m) { | 330 if (visualization_params->save_source_y4m) { |
325 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 331 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( |
326 output_filename_base + "_source.y4m", config_.codec_settings->width, | 332 output_filename_base + "_source.y4m", config_.codec_settings->width, |
327 config_.codec_settings->height, start_frame_rate_)); | 333 config_.codec_settings->height, start_frame_rate)); |
328 RTC_CHECK(source_frame_writer_->Init()); | 334 RTC_CHECK(source_frame_writer_->Init()); |
329 } | 335 } |
330 if (visualization_params->save_encoded_ivf) { | 336 if (visualization_params->save_encoded_ivf) { |
331 rtc::File post_encode_file = | 337 rtc::File post_encode_file = |
332 rtc::File::Create(output_filename_base + "_encoded.ivf"); | 338 rtc::File::Create(output_filename_base + "_encoded.ivf"); |
333 encoded_frame_writer_ = | 339 encoded_frame_writer_ = |
334 IvfFileWriter::Wrap(std::move(post_encode_file), 0); | 340 IvfFileWriter::Wrap(std::move(post_encode_file), 0); |
335 } | 341 } |
336 if (visualization_params->save_decoded_y4m) { | 342 if (visualization_params->save_decoded_y4m) { |
337 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 343 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( |
338 output_filename_base + "_decoded.y4m", | 344 output_filename_base + "_decoded.y4m", |
339 config_.codec_settings->width, config_.codec_settings->height, | 345 config_.codec_settings->width, config_.codec_settings->height, |
340 start_frame_rate_)); | 346 start_frame_rate)); |
341 RTC_CHECK(decoded_frame_writer_->Init()); | 347 RTC_CHECK(decoded_frame_writer_->Init()); |
342 } | 348 } |
343 } | 349 } |
344 | 350 |
345 packet_manipulator_.reset(new test::PacketManipulatorImpl( | 351 packet_manipulator_.reset(new test::PacketManipulatorImpl( |
346 &packet_reader_, config_.networking_config, config_.verbose)); | 352 &packet_reader_, config_.networking_config, config_.verbose)); |
347 processor_.reset(new test::VideoProcessorImpl( | 353 processor_.reset(new test::VideoProcessorImpl( |
348 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 354 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), |
349 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 355 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
350 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), | 356 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), |
351 decoded_frame_writer_.get())); | 357 decoded_frame_writer_.get())); |
352 processor_->Init(); | |
353 } | 358 } |
354 | 359 |
355 // Reset quantities after each encoder update, update the target | 360 // Reset quantities after each encoder update, update the target |
356 // per-frame bandwidth. | 361 // per-frame bandwidth. |
357 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 362 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
358 for (int i = 0; i < num_temporal_layers_; i++) { | 363 for (int i = 0; i < num_temporal_layers_; i++) { |
359 num_frames_per_update_[i] = 0; | 364 num_frames_per_update_[i] = 0; |
360 sum_frame_size_mismatch_[i] = 0.0f; | 365 sum_frame_size_mismatch_[i] = 0.0f; |
361 sum_encoded_frame_size_[i] = 0.0f; | 366 sum_encoded_frame_size_[i] = 0.0f; |
362 encoding_bitrate_[i] = 0.0f; | 367 encoding_bitrate_[i] = 0.0f; |
(...skipping 13 matching lines...) Expand all Loading... |
376 sum_encoded_frame_size_total_ = 0.0f; | 381 sum_encoded_frame_size_total_ = 0.0f; |
377 encoding_bitrate_total_ = 0.0f; | 382 encoding_bitrate_total_ = 0.0f; |
378 perc_encoding_rate_mismatch_ = 0.0f; | 383 perc_encoding_rate_mismatch_ = 0.0f; |
379 num_frames_to_hit_target_ = num_frames_to_hit_target; | 384 num_frames_to_hit_target_ = num_frames_to_hit_target; |
380 encoding_rate_within_target_ = false; | 385 encoding_rate_within_target_ = false; |
381 sum_key_frame_size_mismatch_ = 0.0; | 386 sum_key_frame_size_mismatch_ = 0.0; |
382 num_key_frames_ = 0; | 387 num_key_frames_ = 0; |
383 } | 388 } |
384 | 389 |
385 // For every encoded frame, update the rate control metrics. | 390 // For every encoded frame, update the rate control metrics. |
386 void UpdateRateControlMetrics(int frame_number) { | 391 void UpdateRateControlMetrics(int frame_number, |
| 392 FrameType frame_type, |
| 393 size_t encoded_frame_size) { |
387 RTC_CHECK_GE(frame_number, 0); | 394 RTC_CHECK_GE(frame_number, 0); |
388 int tl_idx = TemporalLayerIndexForFrame(frame_number); | 395 int tl_idx = TemporalLayerIndexForFrame(frame_number); |
389 FrameType frame_type = processor_->EncodedFrameType(frame_number); | 396 float encoded_size_kbits = encoded_frame_size * 8.0f / 1000.0f; |
390 float encoded_size_kbits = | |
391 processor_->EncodedFrameSize(frame_number) * 8.0f / 1000.0f; | |
392 | 397 |
393 // Update layer data. | 398 // Update layer data. |
394 // Update rate mismatch relative to per-frame bandwidth for delta frames. | 399 // Update rate mismatch relative to per-frame bandwidth for delta frames. |
395 if (frame_type == kVideoFrameDelta) { | 400 if (frame_type == kVideoFrameDelta) { |
396 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? | 401 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? |
397 sum_frame_size_mismatch_[tl_idx] += | 402 sum_frame_size_mismatch_[tl_idx] += |
398 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / | 403 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / |
399 per_frame_bandwidth_[tl_idx]; | 404 per_frame_bandwidth_[tl_idx]; |
400 } else { | 405 } else { |
401 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ | 406 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ |
(...skipping 14 matching lines...) Expand all Loading... |
416 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; | 421 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; |
417 perc_encoding_rate_mismatch_ = | 422 perc_encoding_rate_mismatch_ = |
418 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; | 423 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; |
419 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 424 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
420 !encoding_rate_within_target_) { | 425 !encoding_rate_within_target_) { |
421 num_frames_to_hit_target_ = num_frames_total_; | 426 num_frames_to_hit_target_ = num_frames_total_; |
422 encoding_rate_within_target_ = true; | 427 encoding_rate_within_target_ = true; |
423 } | 428 } |
424 } | 429 } |
425 | 430 |
| 431 void UpdateRateControlMetrics(int frame_number, rtc::TaskQueue* task_queue) { |
| 432 FrameType frame_type; |
| 433 size_t encoded_frame_size; |
| 434 |
| 435 if (task_queue) { |
| 436 rtc::Event sync_event(false, false); |
| 437 task_queue->PostTask([this, &frame_type, &encoded_frame_size, |
| 438 frame_number, &sync_event]() { |
| 439 frame_type = processor_->EncodedFrameType(frame_number); |
| 440 encoded_frame_size = processor_->EncodedFrameSize(frame_number); |
| 441 sync_event.Set(); |
| 442 }); |
| 443 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 444 } else { |
| 445 frame_type = processor_->EncodedFrameType(frame_number); |
| 446 encoded_frame_size = processor_->EncodedFrameSize(frame_number); |
| 447 } |
| 448 |
| 449 UpdateRateControlMetrics(frame_number, frame_type, encoded_frame_size); |
| 450 } |
| 451 |
| 452 void UpdateRateControlMetrics(int frame_number) { |
| 453 UpdateRateControlMetrics(frame_number, nullptr); |
| 454 } |
| 455 |
426 // Verify expected behavior of rate control and print out data. | 456 // Verify expected behavior of rate control and print out data. |
427 void VerifyRateControlMetrics(int update_index, | 457 void VerifyRateControlMetrics(int update_index, |
428 const RateControlThresholds& rc_expected) { | 458 const RateControlThresholds& rc_expected, |
429 int num_dropped_frames = processor_->NumberDroppedFrames(); | 459 int num_dropped_frames, |
430 int num_resize_actions = processor_->NumberSpatialResizes(); | 460 int num_resize_actions) { |
431 printf( | 461 printf( |
432 "For update #: %d,\n" | 462 "For update #: %d,\n" |
433 " Target Bitrate: %d,\n" | 463 " Target Bitrate: %d,\n" |
434 " Encoding bitrate: %f,\n" | 464 " Encoding bitrate: %f,\n" |
435 " Frame rate: %d \n", | 465 " Frame rate: %d \n", |
436 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); | 466 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); |
437 printf( | 467 printf( |
438 " Number of processed frames: %d, \n" | 468 " Number of processed frames: %d, \n" |
439 " Number of frames to approach target rate: %d, \n" | 469 " Number of frames to approach target rate: %d, \n" |
440 " Number of dropped frames: %d, \n" | 470 " Number of dropped frames: %d, \n" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 512 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); |
483 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); | 513 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
484 if (rc_expected.num_spatial_resizes >= 0) { | 514 if (rc_expected.num_spatial_resizes >= 0) { |
485 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 515 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
486 } | 516 } |
487 if (rc_expected.num_key_frames >= 0) { | 517 if (rc_expected.num_key_frames >= 0) { |
488 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 518 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
489 } | 519 } |
490 } | 520 } |
491 | 521 |
| 522 void VerifyRateControlMetrics(int update_index, |
| 523 const RateControlThresholds& rc_expected, |
| 524 rtc::TaskQueue* task_queue) { |
| 525 int num_dropped_frames; |
| 526 int num_resize_actions; |
| 527 |
| 528 if (task_queue) { |
| 529 rtc::Event sync_event(false, false); |
| 530 task_queue->PostTask( |
| 531 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() { |
| 532 num_dropped_frames = processor_->NumberDroppedFrames(); |
| 533 num_resize_actions = processor_->NumberSpatialResizes(); |
| 534 sync_event.Set(); |
| 535 }); |
| 536 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 537 } else { |
| 538 num_dropped_frames = processor_->NumberDroppedFrames(); |
| 539 num_resize_actions = processor_->NumberSpatialResizes(); |
| 540 } |
| 541 |
| 542 VerifyRateControlMetrics(update_index, rc_expected, num_dropped_frames, |
| 543 num_resize_actions); |
| 544 } |
| 545 |
| 546 void VerifyRateControlMetrics(int update_index, |
| 547 const RateControlThresholds& rc_expected) { |
| 548 VerifyRateControlMetrics(update_index, rc_expected, nullptr); |
| 549 } |
| 550 |
492 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 551 void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
493 const test::QualityMetricsResult& ssim_result, | 552 const test::QualityMetricsResult& ssim_result, |
494 const QualityThresholds& quality_thresholds) { | 553 const QualityThresholds& quality_thresholds) { |
495 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 554 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
496 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 555 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
497 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 556 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
498 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 557 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
499 } | 558 } |
500 | 559 |
501 void VerifyQpParser(const CodecParams& process, int frame_number) { | 560 void VerifyQpParser(const CodecParams& process, int frame_number) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 // TODO(brandtr): Change the second last argument to be a | 622 // TODO(brandtr): Change the second last argument to be a |
564 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 623 // const std::vector<RateControlThresholds>&, so we can ensure that the user |
565 // does not expect us to do mid-clip rate updates when we are not able to, | 624 // does not expect us to do mid-clip rate updates when we are not able to, |
566 // e.g., when we are operating in batch mode. | 625 // e.g., when we are operating in batch mode. |
567 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, | 626 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, |
568 RateProfile rate_profile, | 627 RateProfile rate_profile, |
569 CodecParams process, | 628 CodecParams process, |
570 RateControlThresholds* rc_thresholds, | 629 RateControlThresholds* rc_thresholds, |
571 const VisualizationParams* visualization_params) { | 630 const VisualizationParams* visualization_params) { |
572 // Codec/config settings. | 631 // Codec/config settings. |
573 start_bitrate_ = rate_profile.target_bit_rate[0]; | |
574 start_frame_rate_ = rate_profile.input_frame_rate[0]; | |
575 packet_loss_probability_ = process.packet_loss_probability; | |
576 num_temporal_layers_ = process.num_temporal_layers; | 632 num_temporal_layers_ = process.num_temporal_layers; |
577 SetUpCodecConfig(process, visualization_params); | 633 SetUpCodecConfig(process, rate_profile, visualization_params); |
| 634 |
578 // Update the temporal layers and the codec with the initial rates. | 635 // Update the temporal layers and the codec with the initial rates. |
579 bit_rate_ = rate_profile.target_bit_rate[0]; | 636 bit_rate_ = rate_profile.target_bit_rate[0]; |
580 frame_rate_ = rate_profile.input_frame_rate[0]; | 637 frame_rate_ = rate_profile.input_frame_rate[0]; |
581 SetTemporalLayerRates(); | 638 SetTemporalLayerRates(); |
582 // Set the initial target size for key frame. | 639 // Set the initial target size for key frame. |
583 target_size_key_frame_initial_ = | 640 target_size_key_frame_initial_ = |
584 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 641 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
585 processor_->SetRates(bit_rate_, frame_rate_); | |
586 | 642 |
587 // Process each frame, up to |num_frames|. | 643 // Process each frame, up to |num_frames|. |
588 int frame_number = 0; | 644 int frame_number = 0; |
589 int update_index = 0; | 645 int update_index = 0; |
590 int num_frames = rate_profile.num_frames; | 646 int num_frames = rate_profile.num_frames; |
591 ResetRateControlMetrics( | 647 ResetRateControlMetrics( |
592 rate_profile.frame_index_rate_update[update_index + 1]); | 648 rate_profile.frame_index_rate_update[update_index + 1]); |
593 | 649 |
594 if (process.batch_mode) { | 650 if (process.batch_mode) { |
595 // In batch mode, we calculate the metrics for all frames after all frames | 651 // In batch mode, we calculate the metrics for all frames after all frames |
596 // have been sent for encoding. | 652 // have been sent for encoding. |
597 | 653 |
| 654 // AndroidMediaEncoder must be called on a task queue, so during the batch |
| 655 // run we will call |processor_| on a task queue. |
| 656 rtc::TaskQueue task_queue("VidProc TQ"); |
| 657 |
| 658 // Initialize |processor_|, which initializes the encoder and decoder. |
| 659 rtc::Event sync_event(false, false); |
| 660 task_queue.PostTask([this, &sync_event]() { |
| 661 processor_->Init(); |
| 662 processor_->SetRates(bit_rate_, frame_rate_); |
| 663 sync_event.Set(); |
| 664 }); |
| 665 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 666 |
| 667 // Post all frames (in order) to encoder. |
| 668 int start_frame_rate = rate_profile.input_frame_rate[0]; |
598 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 669 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
599 // call ProcessFrame num_frames+1 times here. | 670 // call ProcessFrame num_frames+1 times here. |
600 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 671 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
601 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 672 task_queue.PostTask([this, frame_number]() { |
| 673 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 674 }); |
| 675 |
| 676 // In order to not overwhelm the OpenMAX buffers in the Android |
| 677 // MediaCodec API, we roughly pace the frames here. The downside |
| 678 // is that the encode run will be done in realtime. |
| 679 if (process.hw_codec) { |
| 680 SleepMs(rtc::kNumMillisecsPerSec / start_frame_rate); |
| 681 } |
602 } | 682 } |
603 | 683 |
| 684 // Give the task queue some time to finish processing the posted frames, |
| 685 // then shut down processing and synchronize with main thread. |
| 686 SleepMs(rtc::kNumMillisecsPerSec); |
| 687 sync_event.Reset(); |
| 688 task_queue.PostTask([this, &sync_event]() { |
| 689 processor_->Release(); |
| 690 sync_event.Set(); |
| 691 }); |
| 692 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 693 |
| 694 // Calculate and print rate control metrics. |
604 for (frame_number = 0; frame_number < num_frames; ++frame_number) { | 695 for (frame_number = 0; frame_number < num_frames; ++frame_number) { |
605 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 696 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
606 ++num_frames_total_; | 697 ++num_frames_total_; |
607 UpdateRateControlMetrics(frame_number); | 698 UpdateRateControlMetrics(frame_number, &task_queue); |
608 } | 699 } |
| 700 |
| 701 VerifyRateControlMetrics(update_index, rc_thresholds[0], &task_queue); |
609 } else { | 702 } else { |
610 // In online mode, we calculate the metrics for a given frame right after | 703 // In online mode, we calculate the metrics for a given frame right after |
611 // it has been sent for encoding. | 704 // it has been sent for encoding. |
612 | 705 |
613 if (process.hw_codec) { | 706 if (process.hw_codec) { |
614 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | 707 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
615 "since they may be pipelining."; | 708 "since they may be pipelining."; |
616 } | 709 } |
617 | 710 |
| 711 // Initialize |processor_| on main thread. |
| 712 processor_->Init(); |
| 713 processor_->SetRates(bit_rate_, frame_rate_); |
| 714 |
618 while (frame_number < num_frames) { | 715 while (frame_number < num_frames) { |
619 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 716 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
620 VerifyQpParser(process, frame_number); | 717 VerifyQpParser(process, frame_number); |
621 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 718 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
622 ++num_frames_total_; | 719 ++num_frames_total_; |
623 UpdateRateControlMetrics(frame_number); | 720 UpdateRateControlMetrics(frame_number); |
624 | 721 |
625 ++frame_number; | 722 ++frame_number; |
626 | 723 |
627 // If we hit another/next update, verify stats for current state and | 724 // If we hit another/next update, verify stats for current state and |
628 // update layers and codec with new rates. | 725 // update layers and codec with new rates. |
629 if (frame_number == | 726 if (frame_number == |
630 rate_profile.frame_index_rate_update[update_index + 1]) { | 727 rate_profile.frame_index_rate_update[update_index + 1]) { |
631 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 728 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
632 | 729 |
633 // Update layer rates and the codec with new rates. | 730 // Update layer rates and the codec with new rates. |
634 ++update_index; | 731 ++update_index; |
635 bit_rate_ = rate_profile.target_bit_rate[update_index]; | 732 bit_rate_ = rate_profile.target_bit_rate[update_index]; |
636 frame_rate_ = rate_profile.input_frame_rate[update_index]; | 733 frame_rate_ = rate_profile.input_frame_rate[update_index]; |
637 SetTemporalLayerRates(); | 734 SetTemporalLayerRates(); |
638 ResetRateControlMetrics( | 735 ResetRateControlMetrics( |
639 rate_profile.frame_index_rate_update[update_index + 1]); | 736 rate_profile.frame_index_rate_update[update_index + 1]); |
640 processor_->SetRates(bit_rate_, frame_rate_); | 737 processor_->SetRates(bit_rate_, frame_rate_); |
641 } | 738 } |
642 } | 739 } |
643 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 740 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
644 // call ProcessFrame one extra time here. | 741 // call ProcessFrame one extra time here. |
645 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 742 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 743 |
| 744 // Release codecs to make sure they have finished processing. |
| 745 processor_->Release(); |
| 746 |
| 747 // Verify for final rate update. |
| 748 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
646 } | 749 } |
647 | |
648 // Verify rate control metrics for all frames (if in batch mode), or for all | |
649 // frames since the last rate update (if not in batch mode). | |
650 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | |
651 EXPECT_EQ(num_frames, frame_number); | 750 EXPECT_EQ(num_frames, frame_number); |
652 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 751 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
653 | 752 |
654 // Release encoder and decoder to make sure they have finished processing. | |
655 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); | |
656 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); | |
657 | |
658 // Close the analysis files before we use them for SSIM/PSNR calculations. | 753 // Close the analysis files before we use them for SSIM/PSNR calculations. |
659 analysis_frame_reader_->Close(); | 754 analysis_frame_reader_->Close(); |
660 analysis_frame_writer_->Close(); | 755 analysis_frame_writer_->Close(); |
661 | 756 |
662 // Close visualization files. | 757 // Close visualization files. |
663 if (source_frame_writer_) { | 758 if (source_frame_writer_) { |
664 source_frame_writer_->Close(); | 759 source_frame_writer_->Close(); |
665 } | 760 } |
666 if (encoded_frame_writer_) { | 761 if (encoded_frame_writer_) { |
667 EXPECT_TRUE(encoded_frame_writer_->Close()); | 762 EXPECT_TRUE(encoded_frame_writer_->Close()); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 float encoding_bitrate_total_; | 917 float encoding_bitrate_total_; |
823 float perc_encoding_rate_mismatch_; | 918 float perc_encoding_rate_mismatch_; |
824 int num_frames_to_hit_target_; | 919 int num_frames_to_hit_target_; |
825 bool encoding_rate_within_target_; | 920 bool encoding_rate_within_target_; |
826 int bit_rate_; | 921 int bit_rate_; |
827 int frame_rate_; | 922 int frame_rate_; |
828 float target_size_key_frame_initial_; | 923 float target_size_key_frame_initial_; |
829 float target_size_key_frame_; | 924 float target_size_key_frame_; |
830 float sum_key_frame_size_mismatch_; | 925 float sum_key_frame_size_mismatch_; |
831 int num_key_frames_; | 926 int num_key_frames_; |
832 float start_bitrate_; | |
833 int start_frame_rate_; | |
834 | 927 |
835 // Codec and network settings. | 928 // Codec and network settings. |
836 float packet_loss_probability_; | |
837 int num_temporal_layers_; | 929 int num_temporal_layers_; |
838 }; | 930 }; |
839 | 931 |
840 } // namespace test | 932 } // namespace test |
841 } // namespace webrtc | 933 } // namespace webrtc |
842 | 934 |
843 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 935 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
OLD | NEW |