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/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" |
| 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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 encoder_.reset(VP9Encoder::Create()); | 233 encoder_.reset(VP9Encoder::Create()); |
230 decoder_.reset(VP9Decoder::Create()); | 234 decoder_.reset(VP9Decoder::Create()); |
231 break; | 235 break; |
232 default: | 236 default: |
233 RTC_NOTREACHED(); | 237 RTC_NOTREACHED(); |
234 break; | 238 break; |
235 } | 239 } |
236 } | 240 } |
237 | 241 |
238 void SetUpCodecConfig(const CodecParams& process, | 242 void SetUpCodecConfig(const CodecParams& process, |
| 243 const RateProfile& rate_profile, |
239 const VisualizationParams* visualization_params) { | 244 const VisualizationParams* visualization_params) { |
240 CreateEncoderAndDecoder(process.hw_codec, process.codec_type); | 245 CreateEncoderAndDecoder(process.hw_codec, process.codec_type); |
241 | 246 |
242 // Configure input filename. | 247 // Configure input filename. |
243 config_.input_filename = test::ResourcePath(process.filename, "yuv"); | 248 config_.input_filename = test::ResourcePath(process.filename, "yuv"); |
244 if (process.verbose_logging) | 249 if (process.verbose_logging) |
245 printf("Filename: %s\n", process.filename.c_str()); | 250 printf("Filename: %s\n", process.filename.c_str()); |
246 // Generate an output filename in a safe way. | 251 // Generate an output filename in a safe way. |
247 config_.output_filename = test::TempFilename( | 252 config_.output_filename = test::TempFilename( |
248 test::OutputPath(), "videoprocessor_integrationtest"); | 253 test::OutputPath(), "videoprocessor_integrationtest"); |
249 | 254 |
250 config_.frame_length_in_bytes = | 255 config_.frame_length_in_bytes = |
251 CalcBufferSize(kI420, process.width, process.height); | 256 CalcBufferSize(kI420, process.width, process.height); |
252 config_.verbose = process.verbose_logging; | 257 config_.verbose = process.verbose_logging; |
253 config_.use_single_core = process.use_single_core; | 258 config_.use_single_core = process.use_single_core; |
254 // Key frame interval and packet loss are set for each test. | 259 // Key frame interval and packet loss are set for each test. |
255 config_.keyframe_interval = process.key_frame_interval; | 260 config_.keyframe_interval = process.key_frame_interval; |
256 config_.networking_config.packet_loss_probability = | 261 config_.networking_config.packet_loss_probability = |
257 packet_loss_probability_; | 262 process.packet_loss_probability; |
258 | 263 |
259 // Configure codec settings. | 264 // Configure codec settings. |
260 VideoCodingModule::Codec(process.codec_type, &codec_settings_); | 265 VideoCodingModule::Codec(process.codec_type, &codec_settings_); |
261 config_.codec_settings = &codec_settings_; | 266 config_.codec_settings = &codec_settings_; |
262 config_.codec_settings->startBitrate = start_bitrate_; | 267 float start_bitrate = rate_profile.target_bit_rate[0]; |
| 268 config_.codec_settings->startBitrate = start_bitrate; |
263 config_.codec_settings->width = process.width; | 269 config_.codec_settings->width = process.width; |
264 config_.codec_settings->height = process.height; | 270 config_.codec_settings->height = process.height; |
265 | 271 |
266 // These features may be set depending on the test. | 272 // These features may be set depending on the test. |
267 switch (config_.codec_settings->codecType) { | 273 switch (config_.codec_settings->codecType) { |
268 case kVideoCodecH264: | 274 case kVideoCodecH264: |
269 config_.codec_settings->H264()->frameDroppingOn = | 275 config_.codec_settings->H264()->frameDroppingOn = |
270 process.frame_dropper_on; | 276 process.frame_dropper_on; |
271 config_.codec_settings->H264()->keyFrameInterval = | 277 config_.codec_settings->H264()->keyFrameInterval = |
272 kBaseKeyFrameInterval; | 278 kBaseKeyFrameInterval; |
(...skipping 29 matching lines...) Expand all Loading... |
302 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( | 308 analysis_frame_reader_.reset(new test::YuvFrameReaderImpl( |
303 config_.input_filename, config_.codec_settings->width, | 309 config_.input_filename, config_.codec_settings->width, |
304 config_.codec_settings->height)); | 310 config_.codec_settings->height)); |
305 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( | 311 analysis_frame_writer_.reset(new test::YuvFrameWriterImpl( |
306 config_.output_filename, config_.codec_settings->width, | 312 config_.output_filename, config_.codec_settings->width, |
307 config_.codec_settings->height)); | 313 config_.codec_settings->height)); |
308 RTC_CHECK(analysis_frame_reader_->Init()); | 314 RTC_CHECK(analysis_frame_reader_->Init()); |
309 RTC_CHECK(analysis_frame_writer_->Init()); | 315 RTC_CHECK(analysis_frame_writer_->Init()); |
310 | 316 |
311 if (visualization_params) { | 317 if (visualization_params) { |
| 318 int start_frame_rate = rate_profile.input_frame_rate[0]; |
312 // clang-format off | 319 // clang-format off |
313 const std::string output_filename_base = | 320 const std::string output_filename_base = |
314 test::OutputPath() + process.filename + | 321 test::OutputPath() + process.filename + |
315 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") + | 322 "_cd-" + CodecTypeToPayloadName(process.codec_type).value_or("") + |
316 "_hw-" + std::to_string(process.hw_codec) + | 323 "_hw-" + std::to_string(process.hw_codec) + |
317 "_fr-" + std::to_string(start_frame_rate_) + | 324 "_fr-" + std::to_string(start_frame_rate) + |
318 "_br-" + std::to_string(static_cast<int>(start_bitrate_)); | 325 "_br-" + std::to_string(static_cast<int>(start_bitrate)); |
319 // clang-format on | 326 // clang-format on |
320 if (visualization_params->save_source_y4m) { | 327 if (visualization_params->save_source_y4m) { |
321 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 328 source_frame_writer_.reset(new test::Y4mFrameWriterImpl( |
322 output_filename_base + "_source.y4m", config_.codec_settings->width, | 329 output_filename_base + "_source.y4m", config_.codec_settings->width, |
323 config_.codec_settings->height, start_frame_rate_)); | 330 config_.codec_settings->height, start_frame_rate)); |
324 RTC_CHECK(source_frame_writer_->Init()); | 331 RTC_CHECK(source_frame_writer_->Init()); |
325 } | 332 } |
326 if (visualization_params->save_encoded_ivf) { | 333 if (visualization_params->save_encoded_ivf) { |
327 rtc::File post_encode_file = | 334 rtc::File post_encode_file = |
328 rtc::File::Create(output_filename_base + "_encoded.ivf"); | 335 rtc::File::Create(output_filename_base + "_encoded.ivf"); |
329 encoded_frame_writer_ = | 336 encoded_frame_writer_ = |
330 IvfFileWriter::Wrap(std::move(post_encode_file), 0); | 337 IvfFileWriter::Wrap(std::move(post_encode_file), 0); |
331 } | 338 } |
332 if (visualization_params->save_decoded_y4m) { | 339 if (visualization_params->save_decoded_y4m) { |
333 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( | 340 decoded_frame_writer_.reset(new test::Y4mFrameWriterImpl( |
334 output_filename_base + "_decoded.y4m", | 341 output_filename_base + "_decoded.y4m", |
335 config_.codec_settings->width, config_.codec_settings->height, | 342 config_.codec_settings->width, config_.codec_settings->height, |
336 start_frame_rate_)); | 343 start_frame_rate)); |
337 RTC_CHECK(decoded_frame_writer_->Init()); | 344 RTC_CHECK(decoded_frame_writer_->Init()); |
338 } | 345 } |
339 } | 346 } |
340 | 347 |
341 packet_manipulator_.reset(new test::PacketManipulatorImpl( | 348 packet_manipulator_.reset(new test::PacketManipulatorImpl( |
342 &packet_reader_, config_.networking_config, config_.verbose)); | 349 &packet_reader_, config_.networking_config, config_.verbose)); |
343 processor_.reset(new test::VideoProcessorImpl( | 350 processor_.reset(new test::VideoProcessorImpl( |
344 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), | 351 encoder_.get(), decoder_.get(), analysis_frame_reader_.get(), |
345 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, | 352 analysis_frame_writer_.get(), packet_manipulator_.get(), config_, |
346 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), | 353 &stats_, source_frame_writer_.get(), encoded_frame_writer_.get(), |
347 decoded_frame_writer_.get())); | 354 decoded_frame_writer_.get())); |
348 RTC_CHECK(processor_->Init()); | |
349 } | 355 } |
350 | 356 |
351 // Reset quantities after each encoder update, update the target | 357 // Reset quantities after each encoder update, update the target |
352 // per-frame bandwidth. | 358 // per-frame bandwidth. |
353 void ResetRateControlMetrics(int num_frames_to_hit_target) { | 359 void ResetRateControlMetrics(int num_frames_to_hit_target) { |
354 for (int i = 0; i < num_temporal_layers_; i++) { | 360 for (int i = 0; i < num_temporal_layers_; i++) { |
355 num_frames_per_update_[i] = 0; | 361 num_frames_per_update_[i] = 0; |
356 sum_frame_size_mismatch_[i] = 0.0f; | 362 sum_frame_size_mismatch_[i] = 0.0f; |
357 sum_encoded_frame_size_[i] = 0.0f; | 363 sum_encoded_frame_size_[i] = 0.0f; |
358 encoding_bitrate_[i] = 0.0f; | 364 encoding_bitrate_[i] = 0.0f; |
(...skipping 13 matching lines...) Expand all Loading... |
372 sum_encoded_frame_size_total_ = 0.0f; | 378 sum_encoded_frame_size_total_ = 0.0f; |
373 encoding_bitrate_total_ = 0.0f; | 379 encoding_bitrate_total_ = 0.0f; |
374 perc_encoding_rate_mismatch_ = 0.0f; | 380 perc_encoding_rate_mismatch_ = 0.0f; |
375 num_frames_to_hit_target_ = num_frames_to_hit_target; | 381 num_frames_to_hit_target_ = num_frames_to_hit_target; |
376 encoding_rate_within_target_ = false; | 382 encoding_rate_within_target_ = false; |
377 sum_key_frame_size_mismatch_ = 0.0; | 383 sum_key_frame_size_mismatch_ = 0.0; |
378 num_key_frames_ = 0; | 384 num_key_frames_ = 0; |
379 } | 385 } |
380 | 386 |
381 // For every encoded frame, update the rate control metrics. | 387 // For every encoded frame, update the rate control metrics. |
382 void UpdateRateControlMetrics(int frame_number) { | 388 void UpdateRateControlMetrics(int frame_number, |
| 389 FrameType frame_type, |
| 390 size_t encoded_frame_size) { |
383 RTC_CHECK_GE(frame_number, 0); | 391 RTC_CHECK_GE(frame_number, 0); |
384 int tl_idx = TemporalLayerIndexForFrame(frame_number); | 392 int tl_idx = TemporalLayerIndexForFrame(frame_number); |
385 FrameType frame_type = processor_->EncodedFrameType(frame_number); | 393 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 | 394 |
389 // Update layer data. | 395 // Update layer data. |
390 // Update rate mismatch relative to per-frame bandwidth for delta frames. | 396 // Update rate mismatch relative to per-frame bandwidth for delta frames. |
391 if (frame_type == kVideoFrameDelta) { | 397 if (frame_type == kVideoFrameDelta) { |
392 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? | 398 // TODO(marpan): Should we count dropped (zero size) frames in mismatch? |
393 sum_frame_size_mismatch_[tl_idx] += | 399 sum_frame_size_mismatch_[tl_idx] += |
394 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / | 400 fabs(encoded_size_kbits - per_frame_bandwidth_[tl_idx]) / |
395 per_frame_bandwidth_[tl_idx]; | 401 per_frame_bandwidth_[tl_idx]; |
396 } else { | 402 } else { |
397 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ | 403 float target_size = (frame_number == 0) ? target_size_key_frame_initial_ |
(...skipping 14 matching lines...) Expand all Loading... |
412 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; | 418 sum_encoded_frame_size_total_ * frame_rate_ / num_frames_total_; |
413 perc_encoding_rate_mismatch_ = | 419 perc_encoding_rate_mismatch_ = |
414 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; | 420 100 * fabs(encoding_bitrate_total_ - bit_rate_) / bit_rate_; |
415 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && | 421 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch && |
416 !encoding_rate_within_target_) { | 422 !encoding_rate_within_target_) { |
417 num_frames_to_hit_target_ = num_frames_total_; | 423 num_frames_to_hit_target_ = num_frames_total_; |
418 encoding_rate_within_target_ = true; | 424 encoding_rate_within_target_ = true; |
419 } | 425 } |
420 } | 426 } |
421 | 427 |
| 428 void UpdateRateControlMetrics(int frame_number, rtc::TaskQueue* task_queue) { |
| 429 FrameType frame_type; |
| 430 size_t encoded_frame_size; |
| 431 |
| 432 if (task_queue) { |
| 433 rtc::Event sync_event(false, false); |
| 434 task_queue->PostTask([this, &frame_type, &encoded_frame_size, |
| 435 frame_number, &sync_event]() { |
| 436 frame_type = processor_->EncodedFrameType(frame_number); |
| 437 encoded_frame_size = processor_->EncodedFrameSize(frame_number); |
| 438 sync_event.Set(); |
| 439 }); |
| 440 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 441 } else { |
| 442 frame_type = processor_->EncodedFrameType(frame_number); |
| 443 encoded_frame_size = processor_->EncodedFrameSize(frame_number); |
| 444 } |
| 445 |
| 446 UpdateRateControlMetrics(frame_number, frame_type, encoded_frame_size); |
| 447 } |
| 448 |
| 449 void UpdateRateControlMetrics(int frame_number) { |
| 450 UpdateRateControlMetrics(frame_number, nullptr); |
| 451 } |
| 452 |
422 // Verify expected behavior of rate control and print out data. | 453 // Verify expected behavior of rate control and print out data. |
423 void VerifyRateControlMetrics(int update_index, | 454 void VerifyRateControlMetrics(int update_index, |
424 const RateControlThresholds& rc_expected) { | 455 const RateControlThresholds& rc_expected, |
425 int num_dropped_frames = processor_->NumberDroppedFrames(); | 456 int num_dropped_frames, |
426 int num_resize_actions = processor_->NumberSpatialResizes(); | 457 int num_resize_actions) { |
427 printf( | 458 printf( |
428 "For update #: %d,\n" | 459 "For update #: %d,\n" |
429 " Target Bitrate: %d,\n" | 460 " Target Bitrate: %d,\n" |
430 " Encoding bitrate: %f,\n" | 461 " Encoding bitrate: %f,\n" |
431 " Frame rate: %d \n", | 462 " Frame rate: %d \n", |
432 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); | 463 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_); |
433 printf( | 464 printf( |
434 " Number of frames to approach target rate: %d, \n" | 465 " Number of frames to approach target rate: %d, \n" |
435 " Number of dropped frames: %d, \n" | 466 " Number of dropped frames: %d, \n" |
436 " Number of spatial resizes: %d, \n", | 467 " Number of spatial resizes: %d, \n", |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 EXPECT_LE(num_frames_to_hit_target_, rc_expected.max_time_hit_target); | 507 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); | 508 EXPECT_LE(num_dropped_frames, rc_expected.max_num_dropped_frames); |
478 if (rc_expected.num_spatial_resizes >= 0) { | 509 if (rc_expected.num_spatial_resizes >= 0) { |
479 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); | 510 EXPECT_EQ(rc_expected.num_spatial_resizes, num_resize_actions); |
480 } | 511 } |
481 if (rc_expected.num_key_frames >= 0) { | 512 if (rc_expected.num_key_frames >= 0) { |
482 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); | 513 EXPECT_EQ(rc_expected.num_key_frames, num_key_frames_); |
483 } | 514 } |
484 } | 515 } |
485 | 516 |
| 517 void VerifyRateControlMetrics(int update_index, |
| 518 const RateControlThresholds& rc_expected, |
| 519 rtc::TaskQueue* task_queue) { |
| 520 int num_dropped_frames; |
| 521 int num_resize_actions; |
| 522 |
| 523 if (task_queue) { |
| 524 rtc::Event sync_event(false, false); |
| 525 task_queue->PostTask( |
| 526 [this, &num_dropped_frames, &num_resize_actions, &sync_event]() { |
| 527 num_dropped_frames = processor_->NumberDroppedFrames(); |
| 528 num_resize_actions = processor_->NumberSpatialResizes(); |
| 529 sync_event.Set(); |
| 530 }); |
| 531 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 532 } else { |
| 533 num_dropped_frames = processor_->NumberDroppedFrames(); |
| 534 num_resize_actions = processor_->NumberSpatialResizes(); |
| 535 } |
| 536 |
| 537 VerifyRateControlMetrics(update_index, rc_expected, num_dropped_frames, |
| 538 num_resize_actions); |
| 539 } |
| 540 |
| 541 void VerifyRateControlMetrics(int update_index, |
| 542 const RateControlThresholds& rc_expected) { |
| 543 VerifyRateControlMetrics(update_index, rc_expected, nullptr); |
| 544 } |
| 545 |
486 void VerifyQuality(const test::QualityMetricsResult& psnr_result, | 546 void VerifyQuality(const test::QualityMetricsResult& psnr_result, |
487 const test::QualityMetricsResult& ssim_result, | 547 const test::QualityMetricsResult& ssim_result, |
488 const QualityThresholds& quality_thresholds) { | 548 const QualityThresholds& quality_thresholds) { |
489 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); | 549 EXPECT_GT(psnr_result.average, quality_thresholds.min_avg_psnr); |
490 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); | 550 EXPECT_GT(psnr_result.min, quality_thresholds.min_min_psnr); |
491 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); | 551 EXPECT_GT(ssim_result.average, quality_thresholds.min_avg_ssim); |
492 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); | 552 EXPECT_GT(ssim_result.min, quality_thresholds.min_min_ssim); |
493 } | 553 } |
494 | 554 |
495 // Temporal layer index corresponding to frame number, for up to 3 layers. | 555 // Temporal layer index corresponding to frame number, for up to 3 layers. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 // TODO(brandtr): Change the second last argument to be a | 609 // TODO(brandtr): Change the second last argument to be a |
550 // const std::vector<RateControlThresholds>&, so we can ensure that the user | 610 // 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, | 611 // 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. | 612 // e.g., when we are operating in batch mode. |
553 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, | 613 void ProcessFramesAndVerify(QualityThresholds quality_thresholds, |
554 RateProfile rate_profile, | 614 RateProfile rate_profile, |
555 CodecParams process, | 615 CodecParams process, |
556 RateControlThresholds* rc_thresholds, | 616 RateControlThresholds* rc_thresholds, |
557 const VisualizationParams* visualization_params) { | 617 const VisualizationParams* visualization_params) { |
558 // Codec/config settings. | 618 // 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; | 619 num_temporal_layers_ = process.num_temporal_layers; |
563 SetUpCodecConfig(process, visualization_params); | 620 SetUpCodecConfig(process, rate_profile, visualization_params); |
| 621 |
564 // Update the temporal layers and the codec with the initial rates. | 622 // Update the temporal layers and the codec with the initial rates. |
565 bit_rate_ = rate_profile.target_bit_rate[0]; | 623 bit_rate_ = rate_profile.target_bit_rate[0]; |
566 frame_rate_ = rate_profile.input_frame_rate[0]; | 624 frame_rate_ = rate_profile.input_frame_rate[0]; |
567 SetTemporalLayerRates(); | 625 SetTemporalLayerRates(); |
568 // Set the initial target size for key frame. | 626 // Set the initial target size for key frame. |
569 target_size_key_frame_initial_ = | 627 target_size_key_frame_initial_ = |
570 0.5 * kInitialBufferSize * bit_rate_layer_[0]; | 628 0.5 * kInitialBufferSize * bit_rate_layer_[0]; |
571 processor_->SetRates(bit_rate_, frame_rate_); | |
572 | 629 |
573 // Process each frame, up to |num_frames|. | 630 // Process each frame, up to |num_frames|. |
574 int frame_number = 0; | 631 int frame_number = 0; |
575 int update_index = 0; | 632 int update_index = 0; |
576 int num_frames = rate_profile.num_frames; | 633 int num_frames = rate_profile.num_frames; |
577 ResetRateControlMetrics( | 634 ResetRateControlMetrics( |
578 rate_profile.frame_index_rate_update[update_index + 1]); | 635 rate_profile.frame_index_rate_update[update_index + 1]); |
579 | 636 |
580 if (process.batch_mode) { | 637 if (process.batch_mode) { |
581 // In batch mode, we calculate the metrics for all frames after all frames | 638 // In batch mode, we calculate the metrics for all frames after all frames |
582 // have been sent for encoding. | 639 // have been sent for encoding. |
583 | 640 |
| 641 // AndroidMediaEncoder must be called on a task queue, so during the batch |
| 642 // run we will call |processor_| on a task queue. |
| 643 rtc::TaskQueue task_queue("VidProc TQ"); |
| 644 |
| 645 // Initialize |processor_|, which initializes the encoder and decoder. |
| 646 rtc::Event sync_event(false, false); |
| 647 task_queue.PostTask([this, &sync_event]() { |
| 648 RTC_CHECK(processor_->Init()); |
| 649 processor_->SetRates(bit_rate_, frame_rate_); |
| 650 sync_event.Set(); |
| 651 }); |
| 652 ASSERT_TRUE(sync_event.Wait(rtc::Event::kForever)); |
| 653 |
| 654 // Post all frames (in order) to encoder. |
| 655 int start_frame_rate = rate_profile.input_frame_rate[0]; |
584 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 656 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
585 // call ProcessFrame num_frames+1 times here. | 657 // call ProcessFrame num_frames+1 times here. |
586 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { | 658 for (frame_number = 0; frame_number <= num_frames; ++frame_number) { |
587 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 659 task_queue.PostTask([this, frame_number]() { |
| 660 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 661 }); |
| 662 |
| 663 // Some HW codecs seem to only look at the inter-arrival times between |
| 664 // frames and not the timestamp information when doing the rate control. |
| 665 // We therefore roughly pace the frames here, in order to not cause |
| 666 // unwanted frame dropping. |
| 667 if (process.hw_codec) { |
| 668 SleepMs(rtc::kNumMillisecsPerSec / 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(rtc::kNumMillisecsPerSec); |
| 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 ASSERT_TRUE(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); |
594 } | 689 } |
| 690 |
| 691 VerifyRateControlMetrics(update_index, rc_thresholds[0], &task_queue); |
595 } else { | 692 } else { |
596 // In online mode, we calculate the metrics for a given frame right after | 693 // In online mode, we calculate the metrics for a given frame right after |
597 // it has been sent for encoding. | 694 // it has been sent for encoding. |
598 | 695 |
599 if (process.hw_codec) { | 696 if (process.hw_codec) { |
600 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " | 697 LOG(LS_WARNING) << "HW codecs should mostly be run in batch mode, " |
601 "since they may be pipelining."; | 698 "since they may be pipelining."; |
602 } | 699 } |
603 | 700 |
| 701 // Initialize |processor_| on main thread. |
| 702 RTC_CHECK(processor_->Init()); |
| 703 processor_->SetRates(bit_rate_, frame_rate_); |
| 704 |
604 while (frame_number < num_frames) { | 705 while (frame_number < num_frames) { |
605 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 706 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
606 | 707 |
607 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; | 708 ++num_frames_per_update_[TemporalLayerIndexForFrame(frame_number)]; |
608 ++num_frames_total_; | 709 ++num_frames_total_; |
609 UpdateRateControlMetrics(frame_number); | 710 UpdateRateControlMetrics(frame_number); |
610 | 711 |
611 ++frame_number; | 712 ++frame_number; |
612 | 713 |
613 // If we hit another/next update, verify stats for current state and | 714 // If we hit another/next update, verify stats for current state and |
614 // update layers and codec with new rates. | 715 // update layers and codec with new rates. |
615 if (frame_number == | 716 if (frame_number == |
616 rate_profile.frame_index_rate_update[update_index + 1]) { | 717 rate_profile.frame_index_rate_update[update_index + 1]) { |
617 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); | 718 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
618 | 719 |
619 // Update layer rates and the codec with new rates. | 720 // Update layer rates and the codec with new rates. |
620 ++update_index; | 721 ++update_index; |
621 bit_rate_ = rate_profile.target_bit_rate[update_index]; | 722 bit_rate_ = rate_profile.target_bit_rate[update_index]; |
622 frame_rate_ = rate_profile.input_frame_rate[update_index]; | 723 frame_rate_ = rate_profile.input_frame_rate[update_index]; |
623 SetTemporalLayerRates(); | 724 SetTemporalLayerRates(); |
624 ResetRateControlMetrics( | 725 ResetRateControlMetrics( |
625 rate_profile.frame_index_rate_update[update_index + 1]); | 726 rate_profile.frame_index_rate_update[update_index + 1]); |
626 processor_->SetRates(bit_rate_, frame_rate_); | 727 processor_->SetRates(bit_rate_, frame_rate_); |
627 } | 728 } |
628 } | 729 } |
629 // TODO(brandtr): Refactor "frame number accounting" so we don't have to | 730 // TODO(brandtr): Refactor "frame number accounting" so we don't have to |
630 // call ProcessFrame one extra time here. | 731 // call ProcessFrame one extra time here. |
631 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); | 732 EXPECT_TRUE(processor_->ProcessFrame(frame_number)); |
| 733 |
| 734 // Release codecs to make sure they have finished processing. |
| 735 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release()); |
| 736 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release()); |
| 737 processor_->DeregisterCallbacks(); |
| 738 |
| 739 // Verify for final rate update. |
| 740 VerifyRateControlMetrics(update_index, rc_thresholds[update_index]); |
632 } | 741 } |
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); | 742 EXPECT_EQ(num_frames, frame_number); |
638 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); | 743 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size())); |
639 | 744 |
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. | 745 // Close the analysis files before we use them for SSIM/PSNR calculations. |
645 analysis_frame_reader_->Close(); | 746 analysis_frame_reader_->Close(); |
646 analysis_frame_writer_->Close(); | 747 analysis_frame_writer_->Close(); |
647 | 748 |
648 // Close visualization files. | 749 // Close visualization files. |
649 if (source_frame_writer_) { | 750 if (source_frame_writer_) { |
650 source_frame_writer_->Close(); | 751 source_frame_writer_->Close(); |
651 } | 752 } |
652 if (encoded_frame_writer_) { | 753 if (encoded_frame_writer_) { |
653 EXPECT_TRUE(encoded_frame_writer_->Close()); | 754 EXPECT_TRUE(encoded_frame_writer_->Close()); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 float encoding_bitrate_total_; | 906 float encoding_bitrate_total_; |
806 float perc_encoding_rate_mismatch_; | 907 float perc_encoding_rate_mismatch_; |
807 int num_frames_to_hit_target_; | 908 int num_frames_to_hit_target_; |
808 bool encoding_rate_within_target_; | 909 bool encoding_rate_within_target_; |
809 int bit_rate_; | 910 int bit_rate_; |
810 int frame_rate_; | 911 int frame_rate_; |
811 float target_size_key_frame_initial_; | 912 float target_size_key_frame_initial_; |
812 float target_size_key_frame_; | 913 float target_size_key_frame_; |
813 float sum_key_frame_size_mismatch_; | 914 float sum_key_frame_size_mismatch_; |
814 int num_key_frames_; | 915 int num_key_frames_; |
815 float start_bitrate_; | |
816 int start_frame_rate_; | |
817 | 916 |
818 // Codec and network settings. | 917 // Codec and network settings. |
819 float packet_loss_probability_; | |
820 int num_temporal_layers_; | 918 int num_temporal_layers_; |
821 }; | 919 }; |
822 | 920 |
823 } // namespace test | 921 } // namespace test |
824 } // namespace webrtc | 922 } // namespace webrtc |
825 | 923 |
826 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ | 924 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_INTEGRATIONTES
T_H_ |
OLD | NEW |