2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
13 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
16 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
17 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
18 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
19 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
20 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
21 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
22 #include "webrtc/test/testsupport/fileutils.h"
23 #include "webrtc/test/testsupport/frame_reader.h"
24 #include "webrtc/test/testsupport/frame_writer.h"
25 #include "webrtc/test/testsupport/gtest_disable.h"
26 #include "webrtc/test/testsupport/metrics/video_metrics.h"
27 #include "webrtc/test/testsupport/packet_reader.h"
28 #include "webrtc/typedefs.h"
32 // Maximum number of rate updates (i.e., calls to encoder to change bitrate
33 // and/or frame rate) for the current tests.
34 const int kMaxNumRateUpdates = 3;
36 const int kPercTargetvsActualMismatch = 20;
37 const int kBaseKeyFrameInterval = 3000;
39 // Codec and network settings.
40 struct CodecConfigPars {
41 VideoCodecType codec_type;
43 int num_temporal_layers;
44 int key_frame_interval;
45 bool error_concealment_on;
47 bool frame_dropper_on;
48 bool spatial_resize_on;
52 struct QualityMetrics {
53 double minimum_avg_psnr;
54 double minimum_min_psnr;
55 double minimum_avg_ssim;
56 double minimum_min_ssim;
59 // The sequence of bitrate and frame rate changes for the encoder, the frame
60 // number where the changes are made, and the total number of frames for the
63 int target_bit_rate[kMaxNumRateUpdates];
64 int input_frame_rate[kMaxNumRateUpdates];
65 int frame_index_rate_update[kMaxNumRateUpdates + 1];
69 // Metrics for the rate control. The rate mismatch metrics are defined as
70 // percentages.|max_time_hit_target| is defined as number of frames, after a
71 // rate update is made to the encoder, for the encoder to reach within
72 // |kPercTargetvsActualMismatch| of new target rate. The metrics are defined for
73 // each rate update sequence.
74 struct RateControlMetrics {
75 int max_num_dropped_frames;
76 int max_key_frame_size_mismatch;
77 int max_delta_frame_size_mismatch;
78 int max_encoding_rate_mismatch;
79 int max_time_hit_target;
80 int num_spatial_resizes;
84 // Sequence used is foreman (CIF): may be better to use VGA for resize test.
85 const int kCIFWidth = 352;
86 const int kCIFHeight = 288;
87 const int kNbrFramesShort = 100; // Some tests are run for shorter sequence.
88 const int kNbrFramesLong = 299;
90 // Parameters from VP8 wrapper, which control target size of key frames.
91 const float kInitialBufferSize = 0.5f;
92 const float kOptimalBufferSize = 0.6f;
93 const float kScaleKeyFrameSize = 0.5f;
95 // Integration test for video processor. Encodes+decodes a clip and
96 // writes it to the output directory. After completion, quality metrics
97 // (PSNR and SSIM) and rate control metrics are computed to verify that the
98 // quality and encoder response is acceptable. The rate control tests allow us
99 // to verify the behavior for changing bitrate, changing frame rate, frame
100 // dropping/spatial resize, and temporal layers. The limits for the rate
101 // control metrics are set to be fairly conservative, so failure should only
102 // happen when some significant regression or breakdown occurs.
103 class VideoProcessorIntegrationTest: public testing::Test {
105 VideoEncoder* encoder_;
106 VideoDecoder* decoder_;
107 webrtc::test::FrameReader* frame_reader_;
108 webrtc::test::FrameWriter* frame_writer_;
109 webrtc::test::PacketReader packet_reader_;
110 webrtc::test::PacketManipulator* packet_manipulator_;
111 webrtc::test::Stats stats_;
112 webrtc::test::TestConfig config_;
113 VideoCodec codec_settings_;
114 webrtc::test::VideoProcessor* processor_;
116 // Quantities defined/updated for every encoder rate update.
117 // Some quantities defined per temporal layer (at most 3 layers in this test).
118 int num_frames_per_update_[3];
119 float sum_frame_size_mismatch_[3];
120 float sum_encoded_frame_size_[3];
121 float encoding_bitrate_[3];
122 float per_frame_bandwidth_[3];
123 float bit_rate_layer_[3];
124 float frame_rate_layer_[3];
125 int num_frames_total_;
126 float sum_encoded_frame_size_total_;
127 float encoding_bitrate_total_;
128 float perc_encoding_rate_mismatch_;
129 int num_frames_to_hit_target_;
130 bool encoding_rate_within_target_;
134 float target_size_key_frame_initial_;
135 float target_size_key_frame_;
136 float sum_key_frame_size_mismatch_;
138 float start_bitrate_;
140 // Codec and network settings.
141 VideoCodecType codec_type_;
143 int num_temporal_layers_;
144 int key_frame_interval_;
145 bool error_concealment_on_;
147 bool frame_dropper_on_;
148 bool spatial_resize_on_;
151 VideoProcessorIntegrationTest() {}
152 virtual ~VideoProcessorIntegrationTest() {}
154 void SetUpCodecConfig() {
155 if (codec_type_ == kVideoCodecVP8) {
156 encoder_ = VP8Encoder::Create();
157 decoder_ = VP8Decoder::Create();
158 VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
159 } else if (codec_type_ == kVideoCodecVP9) {
160 encoder_ = VP9Encoder::Create();
161 decoder_ = VP9Decoder::Create();
162 VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_);
165 // CIF is currently used for all tests below.
166 // Setup the TestConfig struct for processing of a clip in CIF resolution.
167 config_.input_filename =
168 webrtc::test::ResourcePath("foreman_cif", "yuv");
170 // Generate an output filename in a safe way.
171 config_.output_filename = webrtc::test::TempFilename(
172 webrtc::test::OutputPath(), "videoprocessor_integrationtest");
173 config_.frame_length_in_bytes = CalcBufferSize(kI420,
174 kCIFWidth, kCIFHeight);
175 config_.verbose = false;
176 // Only allow encoder/decoder to use single core, for predictability.
177 config_.use_single_core = true;
178 // Key frame interval and packet loss are set for each test.
179 config_.keyframe_interval = key_frame_interval_;
180 config_.networking_config.packet_loss_probability = packet_loss_;
182 // Configure codec settings.
183 config_.codec_settings = &codec_settings_;
184 config_.codec_settings->startBitrate = start_bitrate_;
185 config_.codec_settings->width = kCIFWidth;
186 config_.codec_settings->height = kCIFHeight;
188 // These features may be set depending on the test.
189 switch (config_.codec_settings->codecType) {
191 config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
192 error_concealment_on_;
193 config_.codec_settings->codecSpecific.VP8.denoisingOn =
195 config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
196 num_temporal_layers_;
197 config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
199 config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
201 config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
202 kBaseKeyFrameInterval;
205 config_.codec_settings->codecSpecific.VP9.denoisingOn =
207 config_.codec_settings->codecSpecific.VP9.numberOfTemporalLayers =
208 num_temporal_layers_;
209 config_.codec_settings->codecSpecific.VP9.frameDroppingOn =
211 config_.codec_settings->codecSpecific.VP9.keyFrameInterval =
212 kBaseKeyFrameInterval;
219 new webrtc::test::FrameReaderImpl(config_.input_filename,
220 config_.frame_length_in_bytes);
222 new webrtc::test::FrameWriterImpl(config_.output_filename,
223 config_.frame_length_in_bytes);
224 ASSERT_TRUE(frame_reader_->Init());
225 ASSERT_TRUE(frame_writer_->Init());
227 packet_manipulator_ = new webrtc::test::PacketManipulatorImpl(
228 &packet_reader_, config_.networking_config, config_.verbose);
229 processor_ = new webrtc::test::VideoProcessorImpl(encoder_, decoder_,
234 ASSERT_TRUE(processor_->Init());
237 // Reset quantities after each encoder update, update the target
238 // per-frame bandwidth.
239 void ResetRateControlMetrics(int num_frames) {
240 for (int i = 0; i < num_temporal_layers_; i++) {
241 num_frames_per_update_[i] = 0;
242 sum_frame_size_mismatch_[i] = 0.0f;
243 sum_encoded_frame_size_[i] = 0.0f;
244 encoding_bitrate_[i] = 0.0f;
245 // Update layer per-frame-bandwidth.
246 per_frame_bandwidth_[i] = static_cast<float>(bit_rate_layer_[i]) /
247 static_cast<float>(frame_rate_layer_[i]);
249 // Set maximum size of key frames, following setting in the VP8 wrapper.
250 float max_key_size = kScaleKeyFrameSize * kOptimalBufferSize * frame_rate_;
251 // We don't know exact target size of the key frames (except for first one),
252 // but the minimum in libvpx is ~|3 * per_frame_bandwidth| and maximum is
253 // set by |max_key_size_ * per_frame_bandwidth|. Take middle point/average
254 // as reference for mismatch. Note key frames always correspond to base
255 // layer frame in this test.
256 target_size_key_frame_ = 0.5 * (3 + max_key_size) * per_frame_bandwidth_[0];
257 num_frames_total_ = 0;
258 sum_encoded_frame_size_total_ = 0.0f;
259 encoding_bitrate_total_ = 0.0f;
260 perc_encoding_rate_mismatch_ = 0.0f;
261 num_frames_to_hit_target_ = num_frames;
262 encoding_rate_within_target_ = false;
263 sum_key_frame_size_mismatch_ = 0.0;
267 // For every encoded frame, update the rate control metrics.
268 void UpdateRateControlMetrics(int frame_num, VideoFrameType frame_type) {
269 int encoded_frame_size = processor_->EncodedFrameSize();
270 float encoded_size_kbits = encoded_frame_size * 8.0f / 1000.0f;
271 // Update layer data.
272 // Update rate mismatch relative to per-frame bandwidth for delta frames.
273 if (frame_type == kDeltaFrame) {
274 // TODO(marpan): Should we count dropped (zero size) frames in mismatch?
275 sum_frame_size_mismatch_[layer_] += fabs(encoded_size_kbits -
276 per_frame_bandwidth_[layer_]) /
277 per_frame_bandwidth_[layer_];
279 float target_size = (frame_num == 1) ? target_size_key_frame_initial_ :
280 target_size_key_frame_;
281 sum_key_frame_size_mismatch_ += fabs(encoded_size_kbits - target_size) /
283 num_key_frames_ += 1;
285 sum_encoded_frame_size_[layer_] += encoded_size_kbits;
286 // Encoding bitrate per layer: from the start of the update/run to the
288 encoding_bitrate_[layer_] = sum_encoded_frame_size_[layer_] *
289 frame_rate_layer_[layer_] /
290 num_frames_per_update_[layer_];
291 // Total encoding rate: from the start of the update/run to current frame.
292 sum_encoded_frame_size_total_ += encoded_size_kbits;
293 encoding_bitrate_total_ = sum_encoded_frame_size_total_ * frame_rate_ /
295 perc_encoding_rate_mismatch_ = 100 * fabs(encoding_bitrate_total_ -
296 bit_rate_) / bit_rate_;
297 if (perc_encoding_rate_mismatch_ < kPercTargetvsActualMismatch &&
298 !encoding_rate_within_target_) {
299 num_frames_to_hit_target_ = num_frames_total_;
300 encoding_rate_within_target_ = true;
304 // Verify expected behavior of rate control and print out data.
305 void VerifyRateControl(int update_index,
306 int max_key_frame_size_mismatch,
307 int max_delta_frame_size_mismatch,
308 int max_encoding_rate_mismatch,
309 int max_time_hit_target,
310 int max_num_dropped_frames,
311 int num_spatial_resizes) {
312 int num_dropped_frames = processor_->NumberDroppedFrames();
313 int num_resize_actions = processor_->NumberSpatialResizes();
314 printf("For update #: %d,\n "
315 " Target Bitrate: %d,\n"
316 " Encoding bitrate: %f,\n"
317 " Frame rate: %d \n",
318 update_index, bit_rate_, encoding_bitrate_total_, frame_rate_);
319 printf(" Number of frames to approach target rate = %d, \n"
320 " Number of dropped frames = %d, \n"
321 " Number of spatial resizes = %d, \n",
322 num_frames_to_hit_target_, num_dropped_frames, num_resize_actions);
323 EXPECT_LE(perc_encoding_rate_mismatch_, max_encoding_rate_mismatch);
324 if (num_key_frames_ > 0) {
325 int perc_key_frame_size_mismatch = 100 * sum_key_frame_size_mismatch_ /
327 printf(" Number of Key frames: %d \n"
328 " Key frame rate mismatch: %d \n",
329 num_key_frames_, perc_key_frame_size_mismatch);
330 EXPECT_LE(perc_key_frame_size_mismatch, max_key_frame_size_mismatch);
333 printf("Rates statistics for Layer data \n");
334 for (int i = 0; i < num_temporal_layers_ ; i++) {
335 printf("Layer #%d \n", i);
336 int perc_frame_size_mismatch = 100 * sum_frame_size_mismatch_[i] /
337 num_frames_per_update_[i];
338 int perc_encoding_rate_mismatch = 100 * fabs(encoding_bitrate_[i] -
339 bit_rate_layer_[i]) /
341 printf(" Target Layer Bit rate: %f \n"
342 " Layer frame rate: %f, \n"
343 " Layer per frame bandwidth: %f, \n"
344 " Layer Encoding bit rate: %f, \n"
345 " Layer Percent frame size mismatch: %d, \n"
346 " Layer Percent encoding rate mismatch = %d, \n"
347 " Number of frame processed per layer = %d \n",
348 bit_rate_layer_[i], frame_rate_layer_[i], per_frame_bandwidth_[i],
349 encoding_bitrate_[i], perc_frame_size_mismatch,
350 perc_encoding_rate_mismatch, num_frames_per_update_[i]);
351 EXPECT_LE(perc_frame_size_mismatch, max_delta_frame_size_mismatch);
352 EXPECT_LE(perc_encoding_rate_mismatch, max_encoding_rate_mismatch);
355 EXPECT_LE(num_frames_to_hit_target_, max_time_hit_target);
356 EXPECT_LE(num_dropped_frames, max_num_dropped_frames);
357 EXPECT_EQ(num_resize_actions, num_spatial_resizes);
360 // Layer index corresponding to frame number, for up to 3 layers.
361 void LayerIndexForFrame(int frame_number) {
362 if (num_temporal_layers_ == 1) {
364 } else if (num_temporal_layers_ == 2) {
365 // layer 0: 0 2 4 ...
367 if (frame_number % 2 == 0) {
372 } else if (num_temporal_layers_ == 3) {
373 // layer 0: 0 4 8 ...
376 if (frame_number % 4 == 0) {
378 } else if ((frame_number + 2) % 4 == 0) {
380 } else if ((frame_number + 1) % 2 == 0) {
384 assert(false); // Only up to 3 layers.
388 // Set the bitrate and frame rate per layer, for up to 3 layers.
389 void SetLayerRates() {
390 assert(num_temporal_layers_<= 3);
391 for (int i = 0; i < num_temporal_layers_; i++) {
392 float bit_rate_ratio =
393 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i];
395 float bit_rate_delta_ratio = kVp8LayerRateAlloction
396 [num_temporal_layers_ - 1][i] -
397 kVp8LayerRateAlloction[num_temporal_layers_ - 1][i - 1];
398 bit_rate_layer_[i] = bit_rate_ * bit_rate_delta_ratio;
400 bit_rate_layer_[i] = bit_rate_ * bit_rate_ratio;
402 frame_rate_layer_[i] = frame_rate_ / static_cast<float>(
403 1 << (num_temporal_layers_ - 1));
405 if (num_temporal_layers_ == 3) {
406 frame_rate_layer_[2] = frame_rate_ / 2.0f;
410 VideoFrameType FrameType(int frame_number) {
411 if (frame_number == 0 || ((frame_number) % key_frame_interval_ == 0 &&
412 key_frame_interval_ > 0)) {
421 delete packet_manipulator_;
422 delete frame_writer_;
423 delete frame_reader_;
428 // Processes all frames in the clip and verifies the result.
429 void ProcessFramesAndVerify(QualityMetrics quality_metrics,
430 RateProfile rate_profile,
431 CodecConfigPars process,
432 RateControlMetrics* rc_metrics) {
433 // Codec/config settings.
434 codec_type_ = process.codec_type;
435 start_bitrate_ = rate_profile.target_bit_rate[0];
436 packet_loss_ = process.packet_loss;
437 key_frame_interval_ = process.key_frame_interval;
438 num_temporal_layers_ = process.num_temporal_layers;
439 error_concealment_on_ = process.error_concealment_on;
440 denoising_on_ = process.denoising_on;
441 frame_dropper_on_ = process.frame_dropper_on;
442 spatial_resize_on_ = process.spatial_resize_on;
444 // Update the layers and the codec with the initial rates.
445 bit_rate_ = rate_profile.target_bit_rate[0];
446 frame_rate_ = rate_profile.input_frame_rate[0];
448 // Set the initial target size for key frame.
449 target_size_key_frame_initial_ = 0.5 * kInitialBufferSize *
451 processor_->SetRates(bit_rate_, frame_rate_);
452 // Process each frame, up to |num_frames|.
453 int num_frames = rate_profile.num_frames;
454 int update_index = 0;
455 ResetRateControlMetrics(
456 rate_profile.frame_index_rate_update[update_index + 1]);
457 int frame_number = 0;
458 VideoFrameType frame_type = kDeltaFrame;
459 while (processor_->ProcessFrame(frame_number) &&
460 frame_number < num_frames) {
461 // Get the layer index for the frame |frame_number|.
462 LayerIndexForFrame(frame_number);
463 frame_type = FrameType(frame_number);
464 // Counter for whole sequence run.
466 // Counters for each rate update.
467 ++num_frames_per_update_[layer_];
469 UpdateRateControlMetrics(frame_number, frame_type);
470 // If we hit another/next update, verify stats for current state and
471 // update layers and codec with new rates.
473 rate_profile.frame_index_rate_update[update_index + 1]) {
476 rc_metrics[update_index].max_key_frame_size_mismatch,
477 rc_metrics[update_index].max_delta_frame_size_mismatch,
478 rc_metrics[update_index].max_encoding_rate_mismatch,
479 rc_metrics[update_index].max_time_hit_target,
480 rc_metrics[update_index].max_num_dropped_frames,
481 rc_metrics[update_index].num_spatial_resizes);
482 // Update layer rates and the codec with new rates.
484 bit_rate_ = rate_profile.target_bit_rate[update_index];
485 frame_rate_ = rate_profile.input_frame_rate[update_index];
487 ResetRateControlMetrics(rate_profile.
488 frame_index_rate_update[update_index + 1]);
489 processor_->SetRates(bit_rate_, frame_rate_);
494 rc_metrics[update_index].max_key_frame_size_mismatch,
495 rc_metrics[update_index].max_delta_frame_size_mismatch,
496 rc_metrics[update_index].max_encoding_rate_mismatch,
497 rc_metrics[update_index].max_time_hit_target,
498 rc_metrics[update_index].max_num_dropped_frames,
499 rc_metrics[update_index].num_spatial_resizes);
500 EXPECT_EQ(num_frames, frame_number);
501 EXPECT_EQ(num_frames + 1, static_cast<int>(stats_.stats_.size()));
503 // Release encoder and decoder to make sure they have finished processing:
504 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
505 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
506 // Close the files before we start using them for SSIM/PSNR calculations.
507 frame_reader_->Close();
508 frame_writer_->Close();
510 // TODO(marpan): should compute these quality metrics per SetRates update.
511 webrtc::test::QualityMetricsResult psnr_result, ssim_result;
512 EXPECT_EQ(0, webrtc::test::I420MetricsFromFiles(
513 config_.input_filename.c_str(),
514 config_.output_filename.c_str(),
515 config_.codec_settings->width,
516 config_.codec_settings->height,
519 printf("PSNR avg: %f, min: %f SSIM avg: %f, min: %f\n",
520 psnr_result.average, psnr_result.min,
521 ssim_result.average, ssim_result.min);
522 stats_.PrintSummary();
523 EXPECT_GT(psnr_result.average, quality_metrics.minimum_avg_psnr);
524 EXPECT_GT(psnr_result.min, quality_metrics.minimum_min_psnr);
525 EXPECT_GT(ssim_result.average, quality_metrics.minimum_avg_ssim);
526 EXPECT_GT(ssim_result.min, quality_metrics.minimum_min_ssim);
527 if (!remove(config_.output_filename.c_str())) {
528 fprintf(stderr, "Failed to remove temporary file!");
533 void SetRateProfilePars(RateProfile* rate_profile,
537 int frame_index_rate_update) {
538 rate_profile->target_bit_rate[update_index] = bit_rate;
539 rate_profile->input_frame_rate[update_index] = frame_rate;
540 rate_profile->frame_index_rate_update[update_index] = frame_index_rate_update;
543 void SetCodecParameters(CodecConfigPars* process_settings,
544 VideoCodecType codec_type,
546 int key_frame_interval,
547 int num_temporal_layers,
548 bool error_concealment_on,
550 bool frame_dropper_on,
551 bool spatial_resize_on) {
552 process_settings->codec_type = codec_type;
553 process_settings->packet_loss = packet_loss;
554 process_settings->key_frame_interval = key_frame_interval;
555 process_settings->num_temporal_layers = num_temporal_layers,
556 process_settings->error_concealment_on = error_concealment_on;
557 process_settings->denoising_on = denoising_on;
558 process_settings->frame_dropper_on = frame_dropper_on;
559 process_settings->spatial_resize_on = spatial_resize_on;
562 void SetQualityMetrics(QualityMetrics* quality_metrics,
563 double minimum_avg_psnr,
564 double minimum_min_psnr,
565 double minimum_avg_ssim,
566 double minimum_min_ssim) {
567 quality_metrics->minimum_avg_psnr = minimum_avg_psnr;
568 quality_metrics->minimum_min_psnr = minimum_min_psnr;
569 quality_metrics->minimum_avg_ssim = minimum_avg_ssim;
570 quality_metrics->minimum_min_ssim = minimum_min_ssim;
573 void SetRateControlMetrics(RateControlMetrics* rc_metrics,
575 int max_num_dropped_frames,
576 int max_key_frame_size_mismatch,
577 int max_delta_frame_size_mismatch,
578 int max_encoding_rate_mismatch,
579 int max_time_hit_target,
580 int num_spatial_resizes) {
581 rc_metrics[update_index].max_num_dropped_frames = max_num_dropped_frames;
582 rc_metrics[update_index].max_key_frame_size_mismatch =
583 max_key_frame_size_mismatch;
584 rc_metrics[update_index].max_delta_frame_size_mismatch =
585 max_delta_frame_size_mismatch;
586 rc_metrics[update_index].max_encoding_rate_mismatch =
587 max_encoding_rate_mismatch;
588 rc_metrics[update_index].max_time_hit_target = max_time_hit_target;
589 rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes;
592 // VP9: Run with no packet loss and fixed bitrate. Quality should be very high.
593 // One key frame (first frame only) in sequence. Setting |key_frame_interval|
594 // to -1 below means no periodic key frames in test.
595 TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) {
596 // Bitrate and frame rate profile.
597 RateProfile rate_profile;
598 SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
599 rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
600 rate_profile.num_frames = kNbrFramesShort;
601 // Codec/network settings.
602 CodecConfigPars process_settings;
603 SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
605 // Metrics for expected quality.
606 QualityMetrics quality_metrics;
607 SetQualityMetrics(&quality_metrics, 37.0, 36.0, 0.93, 0.92);
608 // Metrics for rate control.
609 RateControlMetrics rc_metrics[1];
610 SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
611 ProcessFramesAndVerify(quality_metrics,
617 // VP9: Run with 5% packet loss and fixed bitrate. Quality should be a bit
618 // lower. One key frame (first frame only) in sequence.
619 TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) {
620 // Bitrate and frame rate profile.
621 RateProfile rate_profile;
622 SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
623 rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
624 rate_profile.num_frames = kNbrFramesShort;
625 // Codec/network settings.
626 CodecConfigPars process_settings;
627 SetCodecParameters(&process_settings, kVideoCodecVP9, 0.05f, -1, 1, false,
629 // Metrics for expected quality.
630 QualityMetrics quality_metrics;
631 SetQualityMetrics(&quality_metrics, 17.0, 15.0, 0.45, 0.38);
632 // Metrics for rate control.
633 RateControlMetrics rc_metrics[1];
634 SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
635 ProcessFramesAndVerify(quality_metrics,
642 // VP9: Run with no packet loss, with varying bitrate (3 rate updates):
643 // low to high to medium. Check that quality and encoder response to the new
644 // target rate/per-frame bandwidth (for each rate update) is within limits.
645 // One key frame (first frame only) in sequence.
646 TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) {
647 // Bitrate and frame rate profile.
648 RateProfile rate_profile;
649 SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
650 SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
651 SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
652 rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
653 rate_profile.num_frames = kNbrFramesLong;
654 // Codec/network settings.
655 CodecConfigPars process_settings;
656 SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
658 // Metrics for expected quality.
659 QualityMetrics quality_metrics;
660 SetQualityMetrics(&quality_metrics, 36.0, 31.8, 0.90, 0.85);
661 // Metrics for rate control.
662 RateControlMetrics rc_metrics[3];
663 SetRateControlMetrics(rc_metrics, 0, 0, 30, 20, 20, 20, 0);
664 SetRateControlMetrics(rc_metrics, 1, 2, 0, 20, 20, 60, 0);
665 SetRateControlMetrics(rc_metrics, 2, 0, 0, 20, 20, 40, 0);
666 ProcessFramesAndVerify(quality_metrics,
672 // VP9: Run with no packet loss, with an update (decrease) in frame rate.
673 // Lower frame rate means higher per-frame-bandwidth, so easier to encode.
674 // At the low bitrate in this test, this means better rate control after the
675 // update(s) to lower frame rate. So expect less frame drops, and max values
676 // for the rate control metrics can be lower. One key frame (first frame only).
677 // Note: quality after update should be higher but we currently compute quality
678 // metrics averaged over whole sequence run.
679 TEST_F(VideoProcessorIntegrationTest,
680 ProcessNoLossChangeFrameRateFrameDropVP9) {
681 config_.networking_config.packet_loss_probability = 0;
682 // Bitrate and frame rate profile.
683 RateProfile rate_profile;
684 SetRateProfilePars(&rate_profile, 0, 50, 24, 0);
685 SetRateProfilePars(&rate_profile, 1, 50, 15, 100);
686 SetRateProfilePars(&rate_profile, 2, 50, 10, 200);
687 rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
688 rate_profile.num_frames = kNbrFramesLong;
689 // Codec/network settings.
690 CodecConfigPars process_settings;
691 SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
693 // Metrics for expected quality.
694 QualityMetrics quality_metrics;
695 SetQualityMetrics(&quality_metrics, 29.0, 17.0, 0.80, 0.40);
696 // Metrics for rate control.
697 RateControlMetrics rc_metrics[3];
698 SetRateControlMetrics(rc_metrics, 0, 50, 60, 100, 15, 45, 0);
699 SetRateControlMetrics(rc_metrics, 1, 30, 0, 65, 10, 35, 0);
700 SetRateControlMetrics(rc_metrics, 2, 5, 0, 38, 10, 30, 0);
701 ProcessFramesAndVerify(quality_metrics,
708 // TODO(marpan): Add temporal layer test for VP9, once changes are in
709 // vp9 wrapper for this.
711 // VP8: Run with no packet loss and fixed bitrate. Quality should be very high.
712 // One key frame (first frame only) in sequence. Setting |key_frame_interval|
713 // to -1 below means no periodic key frames in test.
714 TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
715 // Bitrate and frame rate profile.
716 RateProfile rate_profile;
717 SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
718 rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
719 rate_profile.num_frames = kNbrFramesShort;
720 // Codec/network settings.
721 CodecConfigPars process_settings;
722 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
724 // Metrics for expected quality.
725 QualityMetrics quality_metrics;
726 SetQualityMetrics(&quality_metrics, 34.95, 33.0, 0.90, 0.89);
727 // Metrics for rate control.
728 RateControlMetrics rc_metrics[1];
729 SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
730 ProcessFramesAndVerify(quality_metrics,
736 // VP8: Run with 5% packet loss and fixed bitrate. Quality should be a bit
737 // lower. One key frame (first frame only) in sequence.
738 TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
739 // Bitrate and frame rate profile.
740 RateProfile rate_profile;
741 SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
742 rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
743 rate_profile.num_frames = kNbrFramesShort;
744 // Codec/network settings.
745 CodecConfigPars process_settings;
746 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.05f, -1, 1, false,
748 // Metrics for expected quality.
749 QualityMetrics quality_metrics;
750 SetQualityMetrics(&quality_metrics, 20.0, 16.0, 0.60, 0.40);
751 // Metrics for rate control.
752 RateControlMetrics rc_metrics[1];
753 SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
754 ProcessFramesAndVerify(quality_metrics,
760 // VP8: Run with 10% packet loss and fixed bitrate. Quality should be lower.
761 // One key frame (first frame only) in sequence.
762 TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
763 // Bitrate and frame rate profile.
764 RateProfile rate_profile;
765 SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
766 rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
767 rate_profile.num_frames = kNbrFramesShort;
768 // Codec/network settings.
769 CodecConfigPars process_settings;
770 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.1f, -1, 1, false,
772 // Metrics for expected quality.
773 QualityMetrics quality_metrics;
774 SetQualityMetrics(&quality_metrics, 19.0, 16.0, 0.50, 0.35);
775 // Metrics for rate control.
776 RateControlMetrics rc_metrics[1];
777 SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
778 ProcessFramesAndVerify(quality_metrics,
784 // The tests below are currently disabled for Android. For ARM, the encoder
785 // uses |cpu_speed| = 12, as opposed to default |cpu_speed| <= 6 for x86,
786 // which leads to significantly different quality. The quality and rate control
787 // settings in the tests below are defined for encoder speed setting
788 // |cpu_speed| <= ~6. A number of settings would need to be significantly
789 // modified for the |cpu_speed| = 12 case. For now, keep the tests below
790 // disabled on Android. Some quality parameter in the above test has been
791 // adjusted to also pass for |cpu_speed| <= 12.
793 // VP8: Run with no packet loss, with varying bitrate (3 rate updates):
794 // low to high to medium. Check that quality and encoder response to the new
795 // target rate/per-frame bandwidth (for each rate update) is within limits.
796 // One key frame (first frame only) in sequence.
797 TEST_F(VideoProcessorIntegrationTest,
798 DISABLED_ON_ANDROID(ProcessNoLossChangeBitRateVP8)) {
799 // Bitrate and frame rate profile.
800 RateProfile rate_profile;
801 SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
802 SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
803 SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
804 rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
805 rate_profile.num_frames = kNbrFramesLong;
806 // Codec/network settings.
807 CodecConfigPars process_settings;
808 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
810 // Metrics for expected quality.
811 QualityMetrics quality_metrics;
812 SetQualityMetrics(&quality_metrics, 34.0, 32.0, 0.85, 0.80);
813 // Metrics for rate control.
814 RateControlMetrics rc_metrics[3];
815 SetRateControlMetrics(rc_metrics, 0, 0, 45, 20, 10, 15, 0);
816 SetRateControlMetrics(rc_metrics, 1, 0, 0, 25, 20, 10, 0);
817 SetRateControlMetrics(rc_metrics, 2, 0, 0, 25, 15, 10, 0);
818 ProcessFramesAndVerify(quality_metrics,
824 // VP8: Run with no packet loss, with an update (decrease) in frame rate.
825 // Lower frame rate means higher per-frame-bandwidth, so easier to encode.
826 // At the bitrate in this test, this means better rate control after the
827 // update(s) to lower frame rate. So expect less frame drops, and max values
828 // for the rate control metrics can be lower. One key frame (first frame only).
829 // Note: quality after update should be higher but we currently compute quality
830 // metrics averaged over whole sequence run.
831 TEST_F(VideoProcessorIntegrationTest,
832 DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDropVP8)) {
833 config_.networking_config.packet_loss_probability = 0;
834 // Bitrate and frame rate profile.
835 RateProfile rate_profile;
836 SetRateProfilePars(&rate_profile, 0, 80, 24, 0);
837 SetRateProfilePars(&rate_profile, 1, 80, 15, 100);
838 SetRateProfilePars(&rate_profile, 2, 80, 10, 200);
839 rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
840 rate_profile.num_frames = kNbrFramesLong;
841 // Codec/network settings.
842 CodecConfigPars process_settings;
843 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
845 // Metrics for expected quality.
846 QualityMetrics quality_metrics;
847 SetQualityMetrics(&quality_metrics, 31.0, 22.0, 0.80, 0.65);
848 // Metrics for rate control.
849 RateControlMetrics rc_metrics[3];
850 SetRateControlMetrics(rc_metrics, 0, 40, 20, 75, 15, 60, 0);
851 SetRateControlMetrics(rc_metrics, 1, 10, 0, 25, 10, 35, 0);
852 SetRateControlMetrics(rc_metrics, 2, 0, 0, 20, 10, 15, 0);
853 ProcessFramesAndVerify(quality_metrics,
859 // Run with no packet loss, at low bitrate. During this time we should've
861 TEST_F(VideoProcessorIntegrationTest,
862 DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDropVP8)) {
863 config_.networking_config.packet_loss_probability = 0;
864 // Bitrate and frame rate profile.
865 RateProfile rate_profile;
866 SetRateProfilePars(&rate_profile, 0, 50, 30, 0);
867 rate_profile.frame_index_rate_update[1] = kNbrFramesLong + 1;
868 rate_profile.num_frames = kNbrFramesLong;
869 // Codec/network settings.
870 CodecConfigPars process_settings;
871 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, kNbrFramesLong,
872 1, false, true, true, true);
873 // Metrics for expected quality.
874 QualityMetrics quality_metrics;
875 SetQualityMetrics(&quality_metrics, 25.0, 15.0, 0.70, 0.40);
876 // Metrics for rate control.
877 RateControlMetrics rc_metrics[1];
878 SetRateControlMetrics(rc_metrics, 0, 160, 60, 120, 20, 70, 1);
879 ProcessFramesAndVerify(quality_metrics,
885 // VP8: Run with no packet loss, with 3 temporal layers, with a rate update in
886 // the middle of the sequence. The max values for the frame size mismatch and
887 // encoding rate mismatch are applied to each layer.
888 // No dropped frames in this test, and internal spatial resizer is off.
889 // One key frame (first frame only) in sequence, so no spatial resizing.
890 TEST_F(VideoProcessorIntegrationTest,
891 DISABLED_ON_ANDROID(ProcessNoLossTemporalLayersVP8)) {
892 config_.networking_config.packet_loss_probability = 0;
893 // Bitrate and frame rate profile.
894 RateProfile rate_profile;
895 SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
896 SetRateProfilePars(&rate_profile, 1, 400, 30, 150);
897 rate_profile.frame_index_rate_update[2] = kNbrFramesLong + 1;
898 rate_profile.num_frames = kNbrFramesLong;
899 // Codec/network settings.
900 CodecConfigPars process_settings;
901 SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 3, false,
903 // Metrics for expected quality.
904 QualityMetrics quality_metrics;
905 SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80);
906 // Metrics for rate control.
907 RateControlMetrics rc_metrics[2];
908 SetRateControlMetrics(rc_metrics, 0, 0, 20, 30, 10, 10, 0);
909 SetRateControlMetrics(rc_metrics, 1, 0, 0, 30, 15, 10, 0);
910 ProcessFramesAndVerify(quality_metrics,
915 } // namespace webrtc