2 * Copyright (c) 2012 The WebM 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.
10 #include "./vpx_config.h"
11 #include "third_party/googletest/src/include/gtest/gtest.h"
12 #include "test/codec_factory.h"
13 #include "test/encode_test_driver.h"
14 #include "test/i420_video_source.h"
15 #include "test/util.h"
16 #include "test/y4m_video_source.h"
17 #include "vpx/vpx_codec.h"
18 #include "vpx_ports/bitops.h"
22 class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
24 explicit DatarateTestVP9(const ::libvpx_test::CodecFactory *codec)
25 : EncoderTest(codec) {
30 virtual ~DatarateTestVP9() {}
32 virtual void ResetModel() {
34 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
36 tot_frame_number_ = 0;
40 // Denoiser is off by default.
42 // For testing up to 3 layers.
43 for (int i = 0; i < 3; ++i) {
46 denoiser_offon_test_ = 0;
47 denoiser_offon_period_ = -1;
48 frame_parallel_decoding_mode_ = 1;
54 // Frame flags and layer id for temporal layers.
57 // For two layers, test pattern is:
60 // For three layers, test pattern is:
64 // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
65 // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
67 static int GetFrameFlags(int frame_num, int num_temp_layers) {
69 if (num_temp_layers == 2) {
70 if (frame_num % 2 == 0) {
71 // Layer 0: predict from L and ARF, update L.
73 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
75 // Layer 1: predict from L, G and ARF, and update G.
76 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
77 VP8_EFLAG_NO_UPD_ENTROPY;
79 } else if (num_temp_layers == 3) {
80 if (frame_num % 4 == 0) {
81 // Layer 0: predict from L and ARF; update L.
83 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
84 } else if ((frame_num - 2) % 4 == 0) {
85 // Layer 1: predict from L, G, ARF; update G.
86 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
87 } else if ((frame_num - 1) % 2 == 0) {
88 // Layer 2: predict from L, G, ARF; update ARF.
89 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
95 static int SetLayerId(int frame_num, int num_temp_layers) {
97 if (num_temp_layers == 2) {
98 if (frame_num % 2 == 0) {
103 } else if (num_temp_layers == 3) {
104 if (frame_num % 4 == 0) {
106 } else if ((frame_num - 2) % 4 == 0) {
108 } else if ((frame_num - 1) % 2 == 0) {
115 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
116 ::libvpx_test::Encoder *encoder) {
117 if (video->frame() == 0) {
118 encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
119 encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
120 encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
123 if (denoiser_offon_test_) {
124 ASSERT_GT(denoiser_offon_period_, 0)
125 << "denoiser_offon_period_ is not positive.";
126 if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
127 // Flip denoiser_on_ periodically
132 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
133 encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
134 encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
135 frame_parallel_decoding_mode_);
138 encoder->Control(VP9E_SET_ROI_MAP, &roi_);
139 encoder->Control(VP9E_SET_AQ_MODE, 0);
142 if (delta_q_uv_ != 0) {
143 encoder->Control(VP9E_SET_DELTA_Q_UV, delta_q_uv_);
146 if (cfg_.ts_number_layers > 1) {
147 if (video->frame() == 0) {
148 encoder->Control(VP9E_SET_SVC, 1);
150 vpx_svc_layer_id_t layer_id;
151 layer_id.spatial_layer_id = 0;
152 frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
153 layer_id.temporal_layer_id =
154 SetLayerId(video->frame(), cfg_.ts_number_layers);
155 layer_id.temporal_layer_id_per_spatial[0] =
156 SetLayerId(video->frame(), cfg_.ts_number_layers);
157 encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
159 const vpx_rational_t tb = video->timebase();
160 timebase_ = static_cast<double>(tb.num) / tb.den;
164 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
165 // Time since last timestamp = duration.
166 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
169 // If first drop not set and we have a drop set it to this time.
170 if (!first_drop_) first_drop_ = last_pts_ + 1;
171 // Update the number of frame drops.
172 num_drops_ += static_cast<int>(duration - 1);
173 // Update counter for total number of frames (#frames input to encoder).
174 // Needed for setting the proper layer_id below.
175 tot_frame_number_ += static_cast<int>(duration - 1);
178 int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
180 // Add to the buffer the bits we'd expect from a constant bitrate server.
181 bits_in_buffer_model_ += static_cast<int64_t>(
182 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
184 // Buffer should not go negative.
185 ASSERT_GE(bits_in_buffer_model_, 0)
186 << "Buffer Underrun at frame " << pkt->data.frame.pts;
188 const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
190 // Update the total encoded bits. For temporal layers, update the cumulative
191 // encoded bits per layer.
192 for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
193 bits_total_[i] += frame_size_in_bits;
196 // Update the most recent pts.
197 last_pts_ = pkt->data.frame.pts;
202 virtual void EndPassHook(void) {
203 for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
205 duration_ = (last_pts_ + 1) * timebase_;
206 if (bits_total_[layer]) {
207 // Effective file datarate:
208 effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
213 vpx_codec_pts_t last_pts_;
216 int frame_number_; // Counter for number of non-dropped/encoded frames.
217 int tot_frame_number_; // Counter for total number of input frames.
218 int64_t bits_total_[3];
220 double effective_datarate_[3];
222 int64_t bits_in_buffer_model_;
223 vpx_codec_pts_t first_drop_;
227 int denoiser_offon_test_;
228 int denoiser_offon_period_;
229 int frame_parallel_decoding_mode_;
235 // Params: test mode, speed setting and index for bitrate array.
236 class DatarateTestVP9RealTimeMultiBR
237 : public DatarateTestVP9,
238 public ::libvpx_test::CodecTestWith2Params<int, int> {
240 DatarateTestVP9RealTimeMultiBR() : DatarateTestVP9(GET_PARAM(0)) {}
243 virtual void SetUp() {
245 SetMode(::libvpx_test::kRealTime);
246 set_cpu_used_ = GET_PARAM(1);
251 // Params: speed setting and index for bitrate array.
252 class DatarateTestVP9LargeVBR
253 : public DatarateTestVP9,
254 public ::libvpx_test::CodecTestWith2Params<int, int> {
256 DatarateTestVP9LargeVBR() : DatarateTestVP9(GET_PARAM(0)) {}
259 virtual void SetUp() {
261 SetMode(::libvpx_test::kRealTime);
262 set_cpu_used_ = GET_PARAM(1);
267 // Check basic rate targeting for VBR mode with 0 lag.
268 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagZero) {
269 cfg_.rc_min_quantizer = 0;
270 cfg_.rc_max_quantizer = 63;
271 cfg_.g_error_resilient = 0;
272 cfg_.rc_end_usage = VPX_VBR;
273 cfg_.g_lag_in_frames = 0;
275 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
278 const int bitrates[2] = { 400, 800 };
279 const int bitrate_index = GET_PARAM(2);
280 cfg_.rc_target_bitrate = bitrates[bitrate_index];
282 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
283 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
284 << " The datarate for the file is lower than target by too much!";
285 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.36)
286 << " The datarate for the file is greater than target by too much!";
289 // Check basic rate targeting for VBR mode with non-zero lag.
290 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZero) {
291 cfg_.rc_min_quantizer = 0;
292 cfg_.rc_max_quantizer = 63;
293 cfg_.g_error_resilient = 0;
294 cfg_.rc_end_usage = VPX_VBR;
295 // For non-zero lag, rate control will work (be within bounds) for
297 if (deadline_ == VPX_DL_REALTIME) {
298 cfg_.g_lag_in_frames = 15;
300 cfg_.g_lag_in_frames = 0;
303 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
305 const int bitrates[2] = { 400, 800 };
306 const int bitrate_index = GET_PARAM(2);
307 cfg_.rc_target_bitrate = bitrates[bitrate_index];
309 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
310 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
311 << " The datarate for the file is lower than target by too much!";
312 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
313 << " The datarate for the file is greater than target by too much!";
316 // Check basic rate targeting for VBR mode with non-zero lag, with
317 // frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
318 // since error_resilience is off.
319 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
320 cfg_.rc_min_quantizer = 0;
321 cfg_.rc_max_quantizer = 63;
322 cfg_.g_error_resilient = 0;
323 cfg_.rc_end_usage = VPX_VBR;
324 // For non-zero lag, rate control will work (be within bounds) for
326 if (deadline_ == VPX_DL_REALTIME) {
327 cfg_.g_lag_in_frames = 15;
329 cfg_.g_lag_in_frames = 0;
332 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
334 const int bitrates[2] = { 400, 800 };
335 const int bitrate_index = GET_PARAM(2);
336 cfg_.rc_target_bitrate = bitrates[bitrate_index];
338 frame_parallel_decoding_mode_ = 0;
339 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
340 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
341 << " The datarate for the file is lower than target by too much!";
342 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
343 << " The datarate for the file is greater than target by too much!";
346 // Check basic rate targeting for CBR mode.
347 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting) {
348 cfg_.rc_buf_initial_sz = 500;
349 cfg_.rc_buf_optimal_sz = 500;
350 cfg_.rc_buf_sz = 1000;
351 cfg_.rc_dropframe_thresh = 1;
352 cfg_.rc_min_quantizer = 0;
353 cfg_.rc_max_quantizer = 63;
354 cfg_.rc_end_usage = VPX_CBR;
355 cfg_.g_lag_in_frames = 0;
357 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
359 const int bitrates[4] = { 150, 350, 550, 750 };
360 const int bitrate_index = GET_PARAM(2);
361 cfg_.rc_target_bitrate = bitrates[bitrate_index];
363 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
364 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
365 << " The datarate for the file is lower than target by too much!";
366 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
367 << " The datarate for the file is greater than target by too much!";
370 // Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
371 // off( and error_resilience off).
372 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargetingFrameParDecOff) {
373 cfg_.rc_buf_initial_sz = 500;
374 cfg_.rc_buf_optimal_sz = 500;
375 cfg_.rc_buf_sz = 1000;
376 cfg_.rc_dropframe_thresh = 1;
377 cfg_.rc_min_quantizer = 0;
378 cfg_.rc_max_quantizer = 63;
379 cfg_.rc_end_usage = VPX_CBR;
380 cfg_.g_lag_in_frames = 0;
381 cfg_.g_error_resilient = 0;
383 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
385 const int bitrates[4] = { 150, 350, 550, 750 };
386 const int bitrate_index = GET_PARAM(2);
387 cfg_.rc_target_bitrate = bitrates[bitrate_index];
389 frame_parallel_decoding_mode_ = 0;
390 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
391 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
392 << " The datarate for the file is lower than target by too much!";
393 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
394 << " The datarate for the file is greater than target by too much!";
397 // Check basic rate targeting for CBR.
398 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting444) {
399 ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
402 cfg_.g_timebase = video.timebase();
404 cfg_.rc_buf_initial_sz = 500;
405 cfg_.rc_buf_optimal_sz = 500;
406 cfg_.rc_buf_sz = 1000;
407 cfg_.rc_dropframe_thresh = 1;
408 cfg_.rc_min_quantizer = 0;
409 cfg_.rc_max_quantizer = 63;
410 cfg_.rc_end_usage = VPX_CBR;
411 const int bitrates[4] = { 250, 450, 650, 850 };
412 const int bitrate_index = GET_PARAM(2);
413 cfg_.rc_target_bitrate = bitrates[bitrate_index];
415 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
416 ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
417 effective_datarate_[0] * 0.80)
418 << " The datarate for the file exceeds the target by too much!";
419 ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
420 effective_datarate_[0] * 1.15)
421 << " The datarate for the file missed the target!"
422 << cfg_.rc_target_bitrate << " " << effective_datarate_;
425 // Check that (1) the first dropped frame gets earlier and earlier
426 // as the drop frame threshold is increased, and (2) that the total number of
427 // frame drops does not decrease as we increase frame drop threshold.
428 // Use a lower qp-max to force some frame drops.
429 TEST_P(DatarateTestVP9RealTimeMultiBR, ChangingDropFrameThresh) {
430 cfg_.rc_buf_initial_sz = 500;
431 cfg_.rc_buf_optimal_sz = 500;
432 cfg_.rc_buf_sz = 1000;
433 cfg_.rc_undershoot_pct = 20;
434 cfg_.rc_undershoot_pct = 20;
435 cfg_.rc_dropframe_thresh = 10;
436 cfg_.rc_min_quantizer = 0;
437 cfg_.rc_max_quantizer = 50;
438 cfg_.rc_end_usage = VPX_CBR;
439 cfg_.rc_target_bitrate = 200;
440 cfg_.g_lag_in_frames = 0;
441 // TODO(marpan): Investigate datarate target failures with a smaller keyframe
443 cfg_.kf_max_dist = 9999;
445 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
448 const int kDropFrameThreshTestStep = 30;
449 const int bitrates[2] = { 50, 150 };
450 const int bitrate_index = GET_PARAM(2);
451 if (bitrate_index > 1) return;
452 cfg_.rc_target_bitrate = bitrates[bitrate_index];
453 vpx_codec_pts_t last_drop = 140;
454 int last_num_drops = 0;
455 for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
456 cfg_.rc_dropframe_thresh = i;
458 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
459 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
460 << " The datarate for the file is lower than target by too much!";
461 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
462 << " The datarate for the file is greater than target by too much!";
463 ASSERT_LE(first_drop_, last_drop)
464 << " The first dropped frame for drop_thresh " << i
465 << " > first dropped frame for drop_thresh "
466 << i - kDropFrameThreshTestStep;
467 ASSERT_GE(num_drops_, last_num_drops * 0.85)
468 << " The number of dropped frames for drop_thresh " << i
469 << " < number of dropped frames for drop_thresh "
470 << i - kDropFrameThreshTestStep;
471 last_drop = first_drop_;
472 last_num_drops = num_drops_;
476 // Check basic rate targeting for 2 temporal layers.
477 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting2TemporalLayers) {
478 cfg_.rc_buf_initial_sz = 500;
479 cfg_.rc_buf_optimal_sz = 500;
480 cfg_.rc_buf_sz = 1000;
481 cfg_.rc_dropframe_thresh = 1;
482 cfg_.rc_min_quantizer = 0;
483 cfg_.rc_max_quantizer = 63;
484 cfg_.rc_end_usage = VPX_CBR;
485 cfg_.g_lag_in_frames = 0;
487 // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
488 cfg_.ss_number_layers = 1;
489 cfg_.ts_number_layers = 2;
490 cfg_.ts_rate_decimator[0] = 2;
491 cfg_.ts_rate_decimator[1] = 1;
493 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
495 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
497 const int bitrates[4] = { 200, 400, 600, 800 };
498 const int bitrate_index = GET_PARAM(2);
499 cfg_.rc_target_bitrate = bitrates[bitrate_index];
501 // 60-40 bitrate allocation for 2 temporal layers.
502 cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
503 cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
505 if (deadline_ == VPX_DL_REALTIME) {
507 cfg_.g_error_resilient = 1;
509 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
510 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
511 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
512 << " The datarate for the file is lower than target by too much, "
515 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
516 << " The datarate for the file is greater than target by too much, "
522 // Check basic rate targeting for 3 temporal layers.
523 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting3TemporalLayers) {
524 cfg_.rc_buf_initial_sz = 500;
525 cfg_.rc_buf_optimal_sz = 500;
526 cfg_.rc_buf_sz = 1000;
527 cfg_.rc_dropframe_thresh = 1;
528 cfg_.rc_min_quantizer = 0;
529 cfg_.rc_max_quantizer = 63;
530 cfg_.rc_end_usage = VPX_CBR;
531 cfg_.g_lag_in_frames = 0;
533 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
534 cfg_.ss_number_layers = 1;
535 cfg_.ts_number_layers = 3;
536 cfg_.ts_rate_decimator[0] = 4;
537 cfg_.ts_rate_decimator[1] = 2;
538 cfg_.ts_rate_decimator[2] = 1;
540 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
542 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
544 const int bitrates[4] = { 200, 400, 600, 800 };
545 const int bitrate_index = GET_PARAM(2);
546 cfg_.rc_target_bitrate = bitrates[bitrate_index];
548 // 40-20-40 bitrate allocation for 3 temporal layers.
549 cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
550 cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
551 cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
553 if (deadline_ == VPX_DL_REALTIME) {
555 cfg_.g_error_resilient = 1;
557 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
558 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
559 // TODO(yaowu): Work out more stable rc control strategy and
560 // Adjust the thresholds to be tighter than .75.
561 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
562 << " The datarate for the file is lower than target by too much, "
565 // TODO(yaowu): Work out more stable rc control strategy and
566 // Adjust the thresholds to be tighter than 1.25.
567 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
568 << " The datarate for the file is greater than target by too much, "
574 // Params: speed setting.
575 class DatarateTestVP9RealTime : public DatarateTestVP9,
576 public ::libvpx_test::CodecTestWithParam<int> {
578 DatarateTestVP9RealTime() : DatarateTestVP9(GET_PARAM(0)) {}
579 virtual ~DatarateTestVP9RealTime() {}
582 virtual void SetUp() {
584 SetMode(::libvpx_test::kRealTime);
585 set_cpu_used_ = GET_PARAM(1);
590 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
591 TEST_P(DatarateTestVP9RealTime, BasicRateTargetingDropFramesMultiThreads) {
592 cfg_.rc_buf_initial_sz = 500;
593 cfg_.rc_buf_optimal_sz = 500;
594 cfg_.rc_buf_sz = 1000;
595 cfg_.rc_dropframe_thresh = 30;
596 cfg_.rc_min_quantizer = 0;
597 cfg_.rc_max_quantizer = 63;
598 cfg_.rc_end_usage = VPX_CBR;
599 cfg_.g_lag_in_frames = 0;
600 // Encode using multiple threads.
603 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
605 cfg_.rc_target_bitrate = 200;
607 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
608 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
609 << " The datarate for the file is lower than target by too much!";
610 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
611 << " The datarate for the file is greater than target by too much!";
614 // Check basic rate targeting for 3 temporal layers, with frame dropping.
615 // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
616 // frame drop threshold, to force frame dropping.
617 TEST_P(DatarateTestVP9RealTime,
618 BasicRateTargeting3TemporalLayersFrameDropping) {
619 cfg_.rc_buf_initial_sz = 500;
620 cfg_.rc_buf_optimal_sz = 500;
621 cfg_.rc_buf_sz = 1000;
622 // Set frame drop threshold and rc_max_quantizer to force some frame drops.
623 cfg_.rc_dropframe_thresh = 20;
624 cfg_.rc_max_quantizer = 45;
625 cfg_.rc_min_quantizer = 0;
626 cfg_.rc_end_usage = VPX_CBR;
627 cfg_.g_lag_in_frames = 0;
629 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
630 cfg_.ss_number_layers = 1;
631 cfg_.ts_number_layers = 3;
632 cfg_.ts_rate_decimator[0] = 4;
633 cfg_.ts_rate_decimator[1] = 2;
634 cfg_.ts_rate_decimator[2] = 1;
636 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
638 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
640 cfg_.rc_target_bitrate = 200;
642 // 40-20-40 bitrate allocation for 3 temporal layers.
643 cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
644 cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
645 cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
647 if (deadline_ == VPX_DL_REALTIME) {
649 cfg_.g_error_resilient = 1;
651 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
652 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
653 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
654 << " The datarate for the file is lower than target by too much, "
657 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.20)
658 << " The datarate for the file is greater than target by too much, "
661 // Expect some frame drops in this test: for this 200 frames test,
662 // expect at least 10% and not more than 60% drops.
663 ASSERT_GE(num_drops_, 20);
664 ASSERT_LE(num_drops_, 280);
668 // Check VP9 region of interest feature.
669 TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
670 if (deadline_ != VPX_DL_REALTIME || set_cpu_used_ < 5) return;
671 cfg_.rc_buf_initial_sz = 500;
672 cfg_.rc_buf_optimal_sz = 500;
673 cfg_.rc_buf_sz = 1000;
674 cfg_.rc_dropframe_thresh = 0;
675 cfg_.rc_min_quantizer = 0;
676 cfg_.rc_max_quantizer = 63;
677 cfg_.rc_end_usage = VPX_CBR;
678 cfg_.g_lag_in_frames = 0;
680 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
683 cfg_.rc_target_bitrate = 450;
689 // Set ROI parameters
691 memset(&roi_, 0, sizeof(roi_));
693 roi_.rows = (cfg_.g_h + 7) / 8;
694 roi_.cols = (cfg_.g_w + 7) / 8;
696 roi_.delta_q[1] = -20;
697 roi_.delta_lf[1] = -20;
698 memset(roi_.ref_frame, -1, sizeof(roi_.ref_frame));
699 roi_.ref_frame[1] = 1;
701 // Use 2 states: 1 is center square, 0 is the rest.
702 roi_.roi_map = reinterpret_cast<uint8_t *>(
703 calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)));
704 ASSERT_NE(roi_.roi_map, nullptr);
706 for (unsigned int i = 0; i < roi_.rows; ++i) {
707 for (unsigned int j = 0; j < roi_.cols; ++j) {
708 if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
709 j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
710 roi_.roi_map[i * roi_.cols + j] = 1;
715 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
716 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
717 << " The datarate for the file exceeds the target!";
719 ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
720 << " The datarate for the file missed the target!";
725 // Params: speed setting, delta q UV.
726 class DatarateTestVP9RealTimeDeltaQUV
727 : public DatarateTestVP9,
728 public ::libvpx_test::CodecTestWith2Params<int, int> {
730 DatarateTestVP9RealTimeDeltaQUV() : DatarateTestVP9(GET_PARAM(0)) {}
731 virtual ~DatarateTestVP9RealTimeDeltaQUV() {}
734 virtual void SetUp() {
736 SetMode(::libvpx_test::kRealTime);
737 set_cpu_used_ = GET_PARAM(1);
742 TEST_P(DatarateTestVP9RealTimeDeltaQUV, DeltaQUV) {
743 cfg_.rc_buf_initial_sz = 500;
744 cfg_.rc_buf_optimal_sz = 500;
745 cfg_.rc_buf_sz = 1000;
746 cfg_.rc_dropframe_thresh = 0;
747 cfg_.rc_min_quantizer = 0;
748 cfg_.rc_max_quantizer = 63;
749 cfg_.rc_end_usage = VPX_CBR;
750 cfg_.g_lag_in_frames = 0;
752 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
755 cfg_.rc_target_bitrate = 450;
761 delta_q_uv_ = GET_PARAM(2);
763 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
764 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
765 << " The datarate for the file exceeds the target!";
767 ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
768 << " The datarate for the file missed the target!";
771 // Params: test mode, speed setting and index for bitrate array.
772 class DatarateTestVP9PostEncodeDrop
773 : public DatarateTestVP9,
774 public ::libvpx_test::CodecTestWithParam<int> {
776 DatarateTestVP9PostEncodeDrop() : DatarateTestVP9(GET_PARAM(0)) {}
779 virtual void SetUp() {
781 SetMode(::libvpx_test::kRealTime);
782 set_cpu_used_ = GET_PARAM(1);
787 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
788 TEST_P(DatarateTestVP9PostEncodeDrop, PostEncodeDropScreenContent) {
789 cfg_.rc_buf_initial_sz = 500;
790 cfg_.rc_buf_optimal_sz = 500;
791 cfg_.rc_buf_sz = 1000;
792 cfg_.rc_dropframe_thresh = 30;
793 cfg_.rc_min_quantizer = 0;
794 cfg_.rc_max_quantizer = 56;
795 cfg_.rc_end_usage = VPX_CBR;
796 cfg_.g_lag_in_frames = 0;
797 // Encode using multiple threads.
799 cfg_.g_error_resilient = 0;
801 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
803 cfg_.rc_target_bitrate = 300;
805 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
806 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
807 << " The datarate for the file is lower than target by too much!";
808 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
809 << " The datarate for the file is greater than target by too much!";
812 #if CONFIG_VP9_TEMPORAL_DENOISING
813 // Params: speed setting.
814 class DatarateTestVP9RealTimeDenoiser : public DatarateTestVP9RealTime {
816 virtual ~DatarateTestVP9RealTimeDenoiser() {}
819 // Check basic datarate targeting, for a single bitrate, when denoiser is on.
820 TEST_P(DatarateTestVP9RealTimeDenoiser, LowNoise) {
821 cfg_.rc_buf_initial_sz = 500;
822 cfg_.rc_buf_optimal_sz = 500;
823 cfg_.rc_buf_sz = 1000;
824 cfg_.rc_dropframe_thresh = 1;
825 cfg_.rc_min_quantizer = 2;
826 cfg_.rc_max_quantizer = 56;
827 cfg_.rc_end_usage = VPX_CBR;
828 cfg_.g_lag_in_frames = 0;
830 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
833 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
834 // there is only one denoiser mode: denoiserYonly(which is 1),
835 // but may add more modes in the future.
836 cfg_.rc_target_bitrate = 400;
838 // Turn on the denoiser.
840 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
841 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
842 << " The datarate for the file is lower than target by too much!";
843 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
844 << " The datarate for the file is greater than target by too much!";
847 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
848 // for clip with high noise level. Use 2 threads.
849 TEST_P(DatarateTestVP9RealTimeDenoiser, HighNoise) {
850 cfg_.rc_buf_initial_sz = 500;
851 cfg_.rc_buf_optimal_sz = 500;
852 cfg_.rc_buf_sz = 1000;
853 cfg_.rc_dropframe_thresh = 1;
854 cfg_.rc_min_quantizer = 2;
855 cfg_.rc_max_quantizer = 56;
856 cfg_.rc_end_usage = VPX_CBR;
857 cfg_.g_lag_in_frames = 0;
860 ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
862 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
863 // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
864 // but may add more modes in the future.
865 cfg_.rc_target_bitrate = 1000;
867 // Turn on the denoiser.
869 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
870 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
871 << " The datarate for the file is lower than target by too much!";
872 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
873 << " The datarate for the file is greater than target by too much!";
876 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
877 // for 1280x720 clip with 4 threads.
878 TEST_P(DatarateTestVP9RealTimeDenoiser, 4threads) {
879 cfg_.rc_buf_initial_sz = 500;
880 cfg_.rc_buf_optimal_sz = 500;
881 cfg_.rc_buf_sz = 1000;
882 cfg_.rc_dropframe_thresh = 1;
883 cfg_.rc_min_quantizer = 2;
884 cfg_.rc_max_quantizer = 56;
885 cfg_.rc_end_usage = VPX_CBR;
886 cfg_.g_lag_in_frames = 0;
889 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
891 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
892 // there is only one denoiser mode: denoiserYonly(which is 1),
893 // but may add more modes in the future.
894 cfg_.rc_target_bitrate = 1000;
896 // Turn on the denoiser.
898 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
899 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
900 << " The datarate for the file is lower than target by too much!";
901 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
902 << " The datarate for the file is greater than target by too much!";
905 // Check basic datarate targeting, for a single bitrate, when denoiser is off
907 TEST_P(DatarateTestVP9RealTimeDenoiser, DenoiserOffOn) {
908 cfg_.rc_buf_initial_sz = 500;
909 cfg_.rc_buf_optimal_sz = 500;
910 cfg_.rc_buf_sz = 1000;
911 cfg_.rc_dropframe_thresh = 1;
912 cfg_.rc_min_quantizer = 2;
913 cfg_.rc_max_quantizer = 56;
914 cfg_.rc_end_usage = VPX_CBR;
915 cfg_.g_lag_in_frames = 0;
917 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
920 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
921 // there is only one denoiser mode: denoiserYonly(which is 1),
922 // but may add more modes in the future.
923 cfg_.rc_target_bitrate = 400;
925 // The denoiser is off by default.
927 // Set the offon test flag.
928 denoiser_offon_test_ = 1;
929 denoiser_offon_period_ = 100;
930 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
931 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
932 << " The datarate for the file is lower than target by too much!";
933 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
934 << " The datarate for the file is greater than target by too much!";
936 #endif // CONFIG_VP9_TEMPORAL_DENOISING
938 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeMultiBR,
939 ::testing::Range(5, 10), ::testing::Range(0, 4));
941 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9),
942 ::testing::Range(0, 2));
944 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTime, ::testing::Range(5, 10));
946 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDeltaQUV,
947 ::testing::Range(5, 10),
948 ::testing::Values(-5, -10, -15));
950 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9PostEncodeDrop,
951 ::testing::Range(5, 6));
953 #if CONFIG_VP9_TEMPORAL_DENOISING
954 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDenoiser,
955 ::testing::Range(5, 10));