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"
21 class DatarateTestLarge
22 : public ::libvpx_test::EncoderTest,
23 public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
25 DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
27 virtual ~DatarateTestLarge() {}
30 virtual void SetUp() {
32 SetMode(GET_PARAM(1));
33 set_cpu_used_ = GET_PARAM(2);
37 virtual void ResetModel() {
39 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
44 denoiser_offon_test_ = 0;
45 denoiser_offon_period_ = -1;
50 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
51 ::libvpx_test::Encoder *encoder) {
52 if (video->frame() == 0) {
53 encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
54 encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
55 encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
58 #if CONFIG_VP8_ENCODER
60 encoder->Control(VP8E_SET_ROI_MAP, &roi_);
64 if (denoiser_offon_test_) {
65 ASSERT_GT(denoiser_offon_period_, 0)
66 << "denoiser_offon_period_ is not positive.";
67 if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
68 // Flip denoiser_on_ periodically
71 encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
74 const vpx_rational_t tb = video->timebase();
75 timebase_ = static_cast<double>(tb.num) / tb.den;
79 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
80 // Time since last timestamp = duration.
81 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
83 // TODO(jimbankoski): Remove these lines when the issue:
84 // http://code.google.com/p/webm/issues/detail?id=496 is fixed.
85 // For now the codec assumes buffer starts at starting buffer rate
86 // plus one frame's time.
87 if (last_pts_ == 0) duration = 1;
89 // Add to the buffer the bits we'd expect from a constant bitrate server.
90 bits_in_buffer_model_ += static_cast<int64_t>(
91 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
93 /* Test the buffer model here before subtracting the frame. Do so because
94 * the way the leaky bucket model works in libvpx is to allow the buffer to
95 * empty - and then stop showing frames until we've got enough bits to
96 * show one. As noted in comment below (issue 495), this does not currently
97 * apply to key frames. For now exclude key frames in condition below. */
98 const bool key_frame =
99 (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
101 ASSERT_GE(bits_in_buffer_model_, 0)
102 << "Buffer Underrun at frame " << pkt->data.frame.pts;
105 const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
107 // Subtract from the buffer the bits associated with a played back frame.
108 bits_in_buffer_model_ -= frame_size_in_bits;
110 // Update the running total of bits for end of test datarate checks.
111 bits_total_ += frame_size_in_bits;
113 // If first drop not set and we have a drop set it to this time.
114 if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
116 // Update the most recent pts.
117 last_pts_ = pkt->data.frame.pts;
119 // We update this so that we can calculate the datarate minus the last
120 // frame encoded in the file.
121 bits_in_last_frame_ = frame_size_in_bits;
126 virtual void EndPassHook(void) {
128 const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
130 duration_ = (last_pts_ + 1) * timebase_;
132 // Effective file datarate includes the time spent prebuffering.
133 effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
134 (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
136 file_datarate_ = file_size_in_kb / duration_;
140 vpx_codec_pts_t last_pts_;
141 int64_t bits_in_buffer_model_;
144 vpx_codec_pts_t first_drop_;
147 double file_datarate_;
148 double effective_datarate_;
149 int64_t bits_in_last_frame_;
151 int denoiser_offon_test_;
152 int denoiser_offon_period_;
159 #if CONFIG_TEMPORAL_DENOISING
160 // Check basic datarate targeting, for a single bitrate, but loop over the
161 // various denoiser settings.
162 TEST_P(DatarateTestLarge, DenoiserLevels) {
163 cfg_.rc_buf_initial_sz = 500;
164 cfg_.rc_dropframe_thresh = 1;
165 cfg_.rc_max_quantizer = 56;
166 cfg_.rc_end_usage = VPX_CBR;
167 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
169 for (int j = 1; j < 5; ++j) {
170 // Run over the denoiser levels.
171 // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
172 // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
173 // denoiserOnAggressive, and denoiserOnAdaptive.
175 cfg_.rc_target_bitrate = 300;
177 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
178 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
179 << " The datarate for the file exceeds the target!";
181 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
182 << " The datarate for the file missed the target!";
186 // Check basic datarate targeting, for a single bitrate, when denoiser is off
188 TEST_P(DatarateTestLarge, DenoiserOffOn) {
189 cfg_.rc_buf_initial_sz = 500;
190 cfg_.rc_dropframe_thresh = 1;
191 cfg_.rc_max_quantizer = 56;
192 cfg_.rc_end_usage = VPX_CBR;
193 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
195 cfg_.rc_target_bitrate = 300;
197 // The denoiser is off by default.
199 // Set the offon test flag.
200 denoiser_offon_test_ = 1;
201 denoiser_offon_period_ = 100;
202 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
203 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
204 << " The datarate for the file exceeds the target!";
205 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
206 << " The datarate for the file missed the target!";
208 #endif // CONFIG_TEMPORAL_DENOISING
210 TEST_P(DatarateTestLarge, BasicBufferModel) {
212 cfg_.rc_buf_initial_sz = 500;
213 cfg_.rc_dropframe_thresh = 1;
214 cfg_.rc_max_quantizer = 56;
215 cfg_.rc_end_usage = VPX_CBR;
216 // 2 pass cbr datarate control has a bug hidden by the small # of
217 // frames selected in this encode. The problem is that even if the buffer is
218 // negative we produce a keyframe on a cutscene. Ignoring datarate
220 // TODO(jimbankoski): ( Fix when issue
221 // http://code.google.com/p/webm/issues/detail?id=495 is addressed. )
222 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
225 // There is an issue for low bitrates in real-time mode, where the
226 // effective_datarate slightly overshoots the target bitrate.
227 // This is same the issue as noted about (#495).
228 // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
229 // when the issue is resolved.
230 for (int i = 100; i < 800; i += 200) {
231 cfg_.rc_target_bitrate = i;
233 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
234 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
235 << " The datarate for the file exceeds the target!";
236 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
237 << " The datarate for the file missed the target!";
241 TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
243 cfg_.rc_buf_initial_sz = 500;
244 cfg_.rc_max_quantizer = 36;
245 cfg_.rc_end_usage = VPX_CBR;
246 cfg_.rc_target_bitrate = 200;
247 cfg_.kf_mode = VPX_KF_DISABLED;
249 const int frame_count = 40;
250 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
251 30, 1, 0, frame_count);
253 // Here we check that the first dropped frame gets earlier and earlier
254 // as the drop frame threshold is increased.
256 const int kDropFrameThreshTestStep = 30;
257 vpx_codec_pts_t last_drop = frame_count;
258 for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
259 cfg_.rc_dropframe_thresh = i;
261 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
262 ASSERT_LE(first_drop_, last_drop)
263 << " The first dropped frame for drop_thresh " << i
264 << " > first dropped frame for drop_thresh "
265 << i - kDropFrameThreshTestStep;
266 last_drop = first_drop_;
270 TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
272 cfg_.rc_buf_initial_sz = 500;
273 cfg_.rc_dropframe_thresh = 30;
274 cfg_.rc_max_quantizer = 56;
275 cfg_.rc_end_usage = VPX_CBR;
278 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
280 cfg_.rc_target_bitrate = 200;
282 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
283 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
284 << " The datarate for the file exceeds the target!";
286 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
287 << " The datarate for the file missed the target!";
290 class DatarateTestRealTime : public DatarateTestLarge {
292 virtual ~DatarateTestRealTime() {}
295 #if CONFIG_TEMPORAL_DENOISING
296 // Check basic datarate targeting, for a single bitrate, but loop over the
297 // various denoiser settings.
298 TEST_P(DatarateTestRealTime, DenoiserLevels) {
299 cfg_.rc_buf_initial_sz = 500;
300 cfg_.rc_dropframe_thresh = 1;
301 cfg_.rc_max_quantizer = 56;
302 cfg_.rc_end_usage = VPX_CBR;
303 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
305 for (int j = 1; j < 5; ++j) {
306 // Run over the denoiser levels.
307 // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
308 // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
309 // denoiserOnAggressive, and denoiserOnAdaptive.
311 cfg_.rc_target_bitrate = 300;
313 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
314 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
315 << " The datarate for the file exceeds the target!";
316 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
317 << " The datarate for the file missed the target!";
321 // Check basic datarate targeting, for a single bitrate, when denoiser is off
323 TEST_P(DatarateTestRealTime, DenoiserOffOn) {
324 cfg_.rc_buf_initial_sz = 500;
325 cfg_.rc_dropframe_thresh = 1;
326 cfg_.rc_max_quantizer = 56;
327 cfg_.rc_end_usage = VPX_CBR;
328 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
330 cfg_.rc_target_bitrate = 300;
332 // The denoiser is off by default.
334 // Set the offon test flag.
335 denoiser_offon_test_ = 1;
336 denoiser_offon_period_ = 100;
337 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
338 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
339 << " The datarate for the file exceeds the target!";
340 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
341 << " The datarate for the file missed the target!";
343 #endif // CONFIG_TEMPORAL_DENOISING
345 TEST_P(DatarateTestRealTime, BasicBufferModel) {
347 cfg_.rc_buf_initial_sz = 500;
348 cfg_.rc_dropframe_thresh = 1;
349 cfg_.rc_max_quantizer = 56;
350 cfg_.rc_end_usage = VPX_CBR;
351 // 2 pass cbr datarate control has a bug hidden by the small # of
352 // frames selected in this encode. The problem is that even if the buffer is
353 // negative we produce a keyframe on a cutscene, ignoring datarate
355 // TODO(jimbankoski): Fix when issue
356 // http://bugs.chromium.org/p/webm/issues/detail?id=495 is addressed.
357 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
360 // There is an issue for low bitrates in real-time mode, where the
361 // effective_datarate slightly overshoots the target bitrate.
362 // This is same the issue as noted above (#495).
363 // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
364 // when the issue is resolved.
365 for (int i = 100; i <= 700; i += 200) {
366 cfg_.rc_target_bitrate = i;
368 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
369 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
370 << " The datarate for the file exceeds the target!";
371 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
372 << " The datarate for the file missed the target!";
376 TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
378 cfg_.rc_buf_initial_sz = 500;
379 cfg_.rc_max_quantizer = 36;
380 cfg_.rc_end_usage = VPX_CBR;
381 cfg_.rc_target_bitrate = 200;
382 cfg_.kf_mode = VPX_KF_DISABLED;
384 const int frame_count = 40;
385 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
386 30, 1, 0, frame_count);
388 // Check that the first dropped frame gets earlier and earlier
389 // as the drop frame threshold is increased.
391 const int kDropFrameThreshTestStep = 30;
392 vpx_codec_pts_t last_drop = frame_count;
393 for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
394 cfg_.rc_dropframe_thresh = i;
396 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
397 ASSERT_LE(first_drop_, last_drop)
398 << " The first dropped frame for drop_thresh " << i
399 << " > first dropped frame for drop_thresh "
400 << i - kDropFrameThreshTestStep;
401 last_drop = first_drop_;
405 TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
407 cfg_.rc_buf_initial_sz = 500;
408 cfg_.rc_dropframe_thresh = 30;
409 cfg_.rc_max_quantizer = 56;
410 cfg_.rc_end_usage = VPX_CBR;
411 // Encode using multiple threads.
414 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
416 cfg_.rc_target_bitrate = 200;
418 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
419 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
420 << " The datarate for the file exceeds the target!";
422 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
423 << " The datarate for the file missed the target!";
426 TEST_P(DatarateTestRealTime, RegionOfInterest) {
428 cfg_.rc_buf_initial_sz = 500;
429 cfg_.rc_dropframe_thresh = 0;
430 cfg_.rc_max_quantizer = 56;
431 cfg_.rc_end_usage = VPX_CBR;
432 // Encode using multiple threads.
435 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
437 cfg_.rc_target_bitrate = 450;
443 // Set ROI parameters
445 memset(&roi_, 0, sizeof(roi_));
447 roi_.rows = (cfg_.g_h + 15) / 16;
448 roi_.cols = (cfg_.g_w + 15) / 16;
451 roi_.delta_q[1] = -20;
455 roi_.delta_lf[0] = 0;
456 roi_.delta_lf[1] = -20;
457 roi_.delta_lf[2] = 0;
458 roi_.delta_lf[3] = 0;
460 roi_.static_threshold[0] = 0;
461 roi_.static_threshold[1] = 1000;
462 roi_.static_threshold[2] = 0;
463 roi_.static_threshold[3] = 0;
465 // Use 2 states: 1 is center square, 0 is the rest.
467 (uint8_t *)calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map));
468 for (unsigned int i = 0; i < roi_.rows; ++i) {
469 for (unsigned int j = 0; j < roi_.cols; ++j) {
470 if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
471 j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
472 roi_.roi_map[i * roi_.cols + j] = 1;
477 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
478 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
479 << " The datarate for the file exceeds the target!";
481 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
482 << " The datarate for the file missed the target!";
487 TEST_P(DatarateTestRealTime, GFBoost) {
489 cfg_.rc_buf_initial_sz = 500;
490 cfg_.rc_dropframe_thresh = 0;
491 cfg_.rc_max_quantizer = 56;
492 cfg_.rc_end_usage = VPX_CBR;
493 cfg_.g_error_resilient = 0;
495 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
497 cfg_.rc_target_bitrate = 300;
502 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
503 ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
504 << " The datarate for the file exceeds the target!";
506 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
507 << " The datarate for the file missed the target!";
510 class DatarateTestVP9Large
511 : public ::libvpx_test::EncoderTest,
512 public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
514 DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
517 virtual ~DatarateTestVP9Large() {}
519 virtual void SetUp() {
521 SetMode(GET_PARAM(1));
522 set_cpu_used_ = GET_PARAM(2);
526 virtual void ResetModel() {
528 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
530 tot_frame_number_ = 0;
533 // Denoiser is off by default.
535 // For testing up to 3 layers.
536 for (int i = 0; i < 3; ++i) {
539 denoiser_offon_test_ = 0;
540 denoiser_offon_period_ = -1;
541 frame_parallel_decoding_mode_ = 1;
545 // Frame flags and layer id for temporal layers.
548 // For two layers, test pattern is:
551 // For three layers, test pattern is:
555 // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
556 // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
558 int SetFrameFlags(int frame_num, int num_temp_layers) {
560 if (num_temp_layers == 2) {
561 if (frame_num % 2 == 0) {
562 // Layer 0: predict from L and ARF, update L.
564 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
566 // Layer 1: predict from L, G and ARF, and update G.
567 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
568 VP8_EFLAG_NO_UPD_ENTROPY;
570 } else if (num_temp_layers == 3) {
571 if (frame_num % 4 == 0) {
572 // Layer 0: predict from L and ARF; update L.
574 VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
575 } else if ((frame_num - 2) % 4 == 0) {
576 // Layer 1: predict from L, G, ARF; update G.
577 frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
578 } else if ((frame_num - 1) % 2 == 0) {
579 // Layer 2: predict from L, G, ARF; update ARF.
580 frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
586 int SetLayerId(int frame_num, int num_temp_layers) {
588 if (num_temp_layers == 2) {
589 if (frame_num % 2 == 0) {
594 } else if (num_temp_layers == 3) {
595 if (frame_num % 4 == 0) {
597 } else if ((frame_num - 2) % 4 == 0) {
599 } else if ((frame_num - 1) % 2 == 0) {
606 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
607 ::libvpx_test::Encoder *encoder) {
608 if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
610 if (denoiser_offon_test_) {
611 ASSERT_GT(denoiser_offon_period_, 0)
612 << "denoiser_offon_period_ is not positive.";
613 if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
614 // Flip denoiser_on_ periodically
619 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
620 encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
621 encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
622 frame_parallel_decoding_mode_);
624 if (cfg_.ts_number_layers > 1) {
625 if (video->frame() == 0) {
626 encoder->Control(VP9E_SET_SVC, 1);
628 vpx_svc_layer_id_t layer_id;
629 layer_id.spatial_layer_id = 0;
630 frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
631 layer_id.temporal_layer_id =
632 SetLayerId(video->frame(), cfg_.ts_number_layers);
633 encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
635 const vpx_rational_t tb = video->timebase();
636 timebase_ = static_cast<double>(tb.num) / tb.den;
640 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
641 // Time since last timestamp = duration.
642 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
645 // If first drop not set and we have a drop set it to this time.
646 if (!first_drop_) first_drop_ = last_pts_ + 1;
647 // Update the number of frame drops.
648 num_drops_ += static_cast<int>(duration - 1);
649 // Update counter for total number of frames (#frames input to encoder).
650 // Needed for setting the proper layer_id below.
651 tot_frame_number_ += static_cast<int>(duration - 1);
654 int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
656 // Add to the buffer the bits we'd expect from a constant bitrate server.
657 bits_in_buffer_model_ += static_cast<int64_t>(
658 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
660 // Buffer should not go negative.
661 ASSERT_GE(bits_in_buffer_model_, 0)
662 << "Buffer Underrun at frame " << pkt->data.frame.pts;
664 const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
666 // Update the total encoded bits. For temporal layers, update the cumulative
667 // encoded bits per layer.
668 for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
669 bits_total_[i] += frame_size_in_bits;
672 // Update the most recent pts.
673 last_pts_ = pkt->data.frame.pts;
678 virtual void EndPassHook(void) {
679 for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
681 duration_ = (last_pts_ + 1) * timebase_;
682 if (bits_total_[layer]) {
683 // Effective file datarate:
684 effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
689 vpx_codec_pts_t last_pts_;
691 int frame_number_; // Counter for number of non-dropped/encoded frames.
692 int tot_frame_number_; // Counter for total number of input frames.
693 int64_t bits_total_[3];
695 double effective_datarate_[3];
697 int64_t bits_in_buffer_model_;
698 vpx_codec_pts_t first_drop_;
701 int denoiser_offon_test_;
702 int denoiser_offon_period_;
703 int frame_parallel_decoding_mode_;
706 // Check basic rate targeting for VBR mode with 0 lag.
707 TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
708 cfg_.rc_min_quantizer = 0;
709 cfg_.rc_max_quantizer = 63;
710 cfg_.g_error_resilient = 0;
711 cfg_.rc_end_usage = VPX_VBR;
712 cfg_.g_lag_in_frames = 0;
714 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
716 for (int i = 400; i <= 800; i += 400) {
717 cfg_.rc_target_bitrate = i;
719 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
720 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
721 << " The datarate for the file is lower than target by too much!";
722 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
723 << " The datarate for the file is greater than target by too much!";
727 // Check basic rate targeting for VBR mode with non-zero lag.
728 TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
729 cfg_.rc_min_quantizer = 0;
730 cfg_.rc_max_quantizer = 63;
731 cfg_.g_error_resilient = 0;
732 cfg_.rc_end_usage = VPX_VBR;
733 // For non-zero lag, rate control will work (be within bounds) for
735 if (deadline_ == VPX_DL_REALTIME) {
736 cfg_.g_lag_in_frames = 15;
738 cfg_.g_lag_in_frames = 0;
741 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
743 for (int i = 400; i <= 800; i += 400) {
744 cfg_.rc_target_bitrate = i;
746 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
747 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
748 << " The datarate for the file is lower than target by too much!";
749 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
750 << " The datarate for the file is greater than target by too much!";
754 // Check basic rate targeting for VBR mode with non-zero lag, with
755 // frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
756 // since error_resilience is off.
757 TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
758 cfg_.rc_min_quantizer = 0;
759 cfg_.rc_max_quantizer = 63;
760 cfg_.g_error_resilient = 0;
761 cfg_.rc_end_usage = VPX_VBR;
762 // For non-zero lag, rate control will work (be within bounds) for
764 if (deadline_ == VPX_DL_REALTIME) {
765 cfg_.g_lag_in_frames = 15;
767 cfg_.g_lag_in_frames = 0;
770 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
772 for (int i = 400; i <= 800; i += 400) {
773 cfg_.rc_target_bitrate = i;
775 frame_parallel_decoding_mode_ = 0;
776 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
777 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
778 << " The datarate for the file is lower than target by too much!";
779 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.30)
780 << " The datarate for the file is greater than target by too much!";
784 // Check basic rate targeting for CBR mode.
785 TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
786 cfg_.rc_buf_initial_sz = 500;
787 cfg_.rc_buf_optimal_sz = 500;
788 cfg_.rc_buf_sz = 1000;
789 cfg_.rc_dropframe_thresh = 1;
790 cfg_.rc_min_quantizer = 0;
791 cfg_.rc_max_quantizer = 63;
792 cfg_.rc_end_usage = VPX_CBR;
793 cfg_.g_lag_in_frames = 0;
795 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
797 for (int i = 150; i < 800; i += 200) {
798 cfg_.rc_target_bitrate = i;
800 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
801 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
802 << " The datarate for the file is lower than target by too much!";
803 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
804 << " The datarate for the file is greater than target by too much!";
808 // Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
809 // off( and error_resilience off).
810 TEST_P(DatarateTestVP9Large, BasicRateTargetingFrameParDecOff) {
811 cfg_.rc_buf_initial_sz = 500;
812 cfg_.rc_buf_optimal_sz = 500;
813 cfg_.rc_buf_sz = 1000;
814 cfg_.rc_dropframe_thresh = 1;
815 cfg_.rc_min_quantizer = 0;
816 cfg_.rc_max_quantizer = 63;
817 cfg_.rc_end_usage = VPX_CBR;
818 cfg_.g_lag_in_frames = 0;
819 cfg_.g_error_resilient = 0;
821 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
823 for (int i = 150; i < 800; i += 200) {
824 cfg_.rc_target_bitrate = i;
826 frame_parallel_decoding_mode_ = 0;
827 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
828 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
829 << " The datarate for the file is lower than target by too much!";
830 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
831 << " The datarate for the file is greater than target by too much!";
835 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
836 TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
837 cfg_.rc_buf_initial_sz = 500;
838 cfg_.rc_buf_optimal_sz = 500;
839 cfg_.rc_buf_sz = 1000;
840 cfg_.rc_dropframe_thresh = 30;
841 cfg_.rc_min_quantizer = 0;
842 cfg_.rc_max_quantizer = 63;
843 cfg_.rc_end_usage = VPX_CBR;
844 cfg_.g_lag_in_frames = 0;
845 // Encode using multiple threads.
848 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
850 cfg_.rc_target_bitrate = 200;
852 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
853 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
854 << " The datarate for the file is lower than target by too much!";
855 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
856 << " The datarate for the file is greater than target by too much!";
859 // Check basic rate targeting for CBR.
860 TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
861 ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
864 cfg_.g_timebase = video.timebase();
866 cfg_.rc_buf_initial_sz = 500;
867 cfg_.rc_buf_optimal_sz = 500;
868 cfg_.rc_buf_sz = 1000;
869 cfg_.rc_dropframe_thresh = 1;
870 cfg_.rc_min_quantizer = 0;
871 cfg_.rc_max_quantizer = 63;
872 cfg_.rc_end_usage = VPX_CBR;
874 for (int i = 250; i < 900; i += 200) {
875 cfg_.rc_target_bitrate = i;
877 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
878 ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
879 effective_datarate_[0] * 0.80)
880 << " The datarate for the file exceeds the target by too much!";
881 ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
882 effective_datarate_[0] * 1.15)
883 << " The datarate for the file missed the target!"
884 << cfg_.rc_target_bitrate << " " << effective_datarate_;
888 // Check that (1) the first dropped frame gets earlier and earlier
889 // as the drop frame threshold is increased, and (2) that the total number of
890 // frame drops does not decrease as we increase frame drop threshold.
891 // Use a lower qp-max to force some frame drops.
892 TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
893 cfg_.rc_buf_initial_sz = 500;
894 cfg_.rc_buf_optimal_sz = 500;
895 cfg_.rc_buf_sz = 1000;
896 cfg_.rc_undershoot_pct = 20;
897 cfg_.rc_undershoot_pct = 20;
898 cfg_.rc_dropframe_thresh = 10;
899 cfg_.rc_min_quantizer = 0;
900 cfg_.rc_max_quantizer = 50;
901 cfg_.rc_end_usage = VPX_CBR;
902 cfg_.rc_target_bitrate = 200;
903 cfg_.g_lag_in_frames = 0;
904 // TODO(marpan): Investigate datarate target failures with a smaller keyframe
906 cfg_.kf_max_dist = 9999;
908 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
911 const int kDropFrameThreshTestStep = 30;
912 for (int j = 50; j <= 150; j += 100) {
913 cfg_.rc_target_bitrate = j;
914 vpx_codec_pts_t last_drop = 140;
915 int last_num_drops = 0;
916 for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
917 cfg_.rc_dropframe_thresh = i;
919 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
920 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
921 << " The datarate for the file is lower than target by too much!";
922 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
923 << " The datarate for the file is greater than target by too much!";
924 ASSERT_LE(first_drop_, last_drop)
925 << " The first dropped frame for drop_thresh " << i
926 << " > first dropped frame for drop_thresh "
927 << i - kDropFrameThreshTestStep;
928 ASSERT_GE(num_drops_, last_num_drops * 0.85)
929 << " The number of dropped frames for drop_thresh " << i
930 << " < number of dropped frames for drop_thresh "
931 << i - kDropFrameThreshTestStep;
932 last_drop = first_drop_;
933 last_num_drops = num_drops_;
938 // Check basic rate targeting for 2 temporal layers.
939 TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
940 cfg_.rc_buf_initial_sz = 500;
941 cfg_.rc_buf_optimal_sz = 500;
942 cfg_.rc_buf_sz = 1000;
943 cfg_.rc_dropframe_thresh = 1;
944 cfg_.rc_min_quantizer = 0;
945 cfg_.rc_max_quantizer = 63;
946 cfg_.rc_end_usage = VPX_CBR;
947 cfg_.g_lag_in_frames = 0;
949 // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
950 cfg_.ss_number_layers = 1;
951 cfg_.ts_number_layers = 2;
952 cfg_.ts_rate_decimator[0] = 2;
953 cfg_.ts_rate_decimator[1] = 1;
955 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
957 if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
959 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
961 for (int i = 200; i <= 800; i += 200) {
962 cfg_.rc_target_bitrate = i;
964 // 60-40 bitrate allocation for 2 temporal layers.
965 cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
966 cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
967 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
968 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
969 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
970 << " The datarate for the file is lower than target by too much, "
973 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
974 << " The datarate for the file is greater than target by too much, "
981 // Check basic rate targeting for 3 temporal layers.
982 TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
983 cfg_.rc_buf_initial_sz = 500;
984 cfg_.rc_buf_optimal_sz = 500;
985 cfg_.rc_buf_sz = 1000;
986 cfg_.rc_dropframe_thresh = 1;
987 cfg_.rc_min_quantizer = 0;
988 cfg_.rc_max_quantizer = 63;
989 cfg_.rc_end_usage = VPX_CBR;
990 cfg_.g_lag_in_frames = 0;
992 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
993 cfg_.ss_number_layers = 1;
994 cfg_.ts_number_layers = 3;
995 cfg_.ts_rate_decimator[0] = 4;
996 cfg_.ts_rate_decimator[1] = 2;
997 cfg_.ts_rate_decimator[2] = 1;
999 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
1001 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1003 for (int i = 200; i <= 800; i += 200) {
1004 cfg_.rc_target_bitrate = i;
1006 // 40-20-40 bitrate allocation for 3 temporal layers.
1007 cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
1008 cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
1009 cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
1010 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1011 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
1012 // TODO(yaowu): Work out more stable rc control strategy and
1013 // Adjust the thresholds to be tighter than .75.
1014 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
1015 << " The datarate for the file is lower than target by too much, "
1018 // TODO(yaowu): Work out more stable rc control strategy and
1019 // Adjust the thresholds to be tighter than 1.25.
1020 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
1021 << " The datarate for the file is greater than target by too much, "
1028 // Check basic rate targeting for 3 temporal layers, with frame dropping.
1029 // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
1030 // frame drop threshold, to force frame dropping.
1031 TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
1032 cfg_.rc_buf_initial_sz = 500;
1033 cfg_.rc_buf_optimal_sz = 500;
1034 cfg_.rc_buf_sz = 1000;
1035 // Set frame drop threshold and rc_max_quantizer to force some frame drops.
1036 cfg_.rc_dropframe_thresh = 20;
1037 cfg_.rc_max_quantizer = 45;
1038 cfg_.rc_min_quantizer = 0;
1039 cfg_.rc_end_usage = VPX_CBR;
1040 cfg_.g_lag_in_frames = 0;
1042 // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
1043 cfg_.ss_number_layers = 1;
1044 cfg_.ts_number_layers = 3;
1045 cfg_.ts_rate_decimator[0] = 4;
1046 cfg_.ts_rate_decimator[1] = 2;
1047 cfg_.ts_rate_decimator[2] = 1;
1049 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
1051 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1053 cfg_.rc_target_bitrate = 200;
1055 // 40-20-40 bitrate allocation for 3 temporal layers.
1056 cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
1057 cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
1058 cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
1059 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1060 for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
1061 ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
1062 << " The datarate for the file is lower than target by too much, "
1065 ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
1066 << " The datarate for the file is greater than target by too much, "
1069 // Expect some frame drops in this test: for this 200 frames test,
1070 // expect at least 10% and not more than 60% drops.
1071 ASSERT_GE(num_drops_, 20);
1072 ASSERT_LE(num_drops_, 130);
1076 #if CONFIG_VP9_TEMPORAL_DENOISING
1077 class DatarateTestVP9LargeDenoiser : public DatarateTestVP9Large {
1079 virtual ~DatarateTestVP9LargeDenoiser() {}
1082 // Check basic datarate targeting, for a single bitrate, when denoiser is on.
1083 TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
1084 cfg_.rc_buf_initial_sz = 500;
1085 cfg_.rc_buf_optimal_sz = 500;
1086 cfg_.rc_buf_sz = 1000;
1087 cfg_.rc_dropframe_thresh = 1;
1088 cfg_.rc_min_quantizer = 2;
1089 cfg_.rc_max_quantizer = 56;
1090 cfg_.rc_end_usage = VPX_CBR;
1091 cfg_.g_lag_in_frames = 0;
1093 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1096 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1097 // there is only one denoiser mode: denoiserYonly(which is 1),
1098 // but may add more modes in the future.
1099 cfg_.rc_target_bitrate = 300;
1101 // Turn on the denoiser.
1103 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1104 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1105 << " The datarate for the file is lower than target by too much!";
1106 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
1107 << " The datarate for the file is greater than target by too much!";
1110 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
1111 // for clip with high noise level. Use 2 threads.
1112 TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
1113 cfg_.rc_buf_initial_sz = 500;
1114 cfg_.rc_buf_optimal_sz = 500;
1115 cfg_.rc_buf_sz = 1000;
1116 cfg_.rc_dropframe_thresh = 1;
1117 cfg_.rc_min_quantizer = 2;
1118 cfg_.rc_max_quantizer = 56;
1119 cfg_.rc_end_usage = VPX_CBR;
1120 cfg_.g_lag_in_frames = 0;
1123 ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
1125 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1126 // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
1127 // but may add more modes in the future.
1128 cfg_.rc_target_bitrate = 1000;
1130 // Turn on the denoiser.
1132 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1133 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1134 << " The datarate for the file is lower than target by too much!";
1135 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
1136 << " The datarate for the file is greater than target by too much!";
1139 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
1140 // for 1280x720 clip with 4 threads.
1141 TEST_P(DatarateTestVP9LargeDenoiser, 4threads) {
1142 cfg_.rc_buf_initial_sz = 500;
1143 cfg_.rc_buf_optimal_sz = 500;
1144 cfg_.rc_buf_sz = 1000;
1145 cfg_.rc_dropframe_thresh = 1;
1146 cfg_.rc_min_quantizer = 2;
1147 cfg_.rc_max_quantizer = 56;
1148 cfg_.rc_end_usage = VPX_CBR;
1149 cfg_.g_lag_in_frames = 0;
1152 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1154 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1155 // there is only one denoiser mode: denoiserYonly(which is 1),
1156 // but may add more modes in the future.
1157 cfg_.rc_target_bitrate = 1000;
1159 // Turn on the denoiser.
1161 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1162 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1163 << " The datarate for the file is lower than target by too much!";
1164 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
1165 << " The datarate for the file is greater than target by too much!";
1168 // Check basic datarate targeting, for a single bitrate, when denoiser is off
1170 TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
1171 cfg_.rc_buf_initial_sz = 500;
1172 cfg_.rc_buf_optimal_sz = 500;
1173 cfg_.rc_buf_sz = 1000;
1174 cfg_.rc_dropframe_thresh = 1;
1175 cfg_.rc_min_quantizer = 2;
1176 cfg_.rc_max_quantizer = 56;
1177 cfg_.rc_end_usage = VPX_CBR;
1178 cfg_.g_lag_in_frames = 0;
1180 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1183 // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1184 // there is only one denoiser mode: denoiserYonly(which is 1),
1185 // but may add more modes in the future.
1186 cfg_.rc_target_bitrate = 300;
1188 // The denoiser is off by default.
1190 // Set the offon test flag.
1191 denoiser_offon_test_ = 1;
1192 denoiser_offon_period_ = 100;
1193 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1194 ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1195 << " The datarate for the file is lower than target by too much!";
1196 ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
1197 << " The datarate for the file is greater than target by too much!";
1199 #endif // CONFIG_VP9_TEMPORAL_DENOISING
1201 class DatarateOnePassCbrSvc
1202 : public ::libvpx_test::EncoderTest,
1203 public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
1205 DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
1206 memset(&svc_params_, 0, sizeof(svc_params_));
1208 virtual ~DatarateOnePassCbrSvc() {}
1211 virtual void SetUp() {
1213 SetMode(GET_PARAM(1));
1214 speed_setting_ = GET_PARAM(2);
1217 virtual void ResetModel() {
1219 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
1224 mismatch_psnr_ = 0.0;
1225 mismatch_nframes_ = 0;
1228 base_speed_setting_ = 5;
1230 virtual void BeginPassHook(unsigned int /*pass*/) {}
1231 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
1232 ::libvpx_test::Encoder *encoder) {
1233 if (video->frame() == 0) {
1235 for (i = 0; i < VPX_MAX_LAYERS; ++i) {
1236 svc_params_.max_quantizers[i] = 63;
1237 svc_params_.min_quantizers[i] = 0;
1239 svc_params_.speed_per_layer[0] = base_speed_setting_;
1240 for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
1241 svc_params_.speed_per_layer[i] = speed_setting_;
1244 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
1245 encoder->Control(VP9E_SET_SVC, 1);
1246 encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
1247 encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
1248 encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
1249 encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
1250 encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
1251 encoder->Control(VP9E_SET_ROW_MT, 1);
1252 encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
1253 encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
1255 const vpx_rational_t tb = video->timebase();
1256 timebase_ = static_cast<double>(tb.num) / tb.den;
1259 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
1260 vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
1261 if (last_pts_ == 0) duration = 1;
1262 bits_in_buffer_model_ += static_cast<int64_t>(
1263 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
1264 const bool key_frame =
1265 (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
1267 // TODO(marpan): This check currently fails for some of the SVC tests,
1268 // re-enable when issue (webm:1350) is resolved.
1269 // ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
1270 // << pkt->data.frame.pts;
1272 const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
1273 bits_in_buffer_model_ -= static_cast<int64_t>(frame_size_in_bits);
1274 bits_total_ += frame_size_in_bits;
1275 if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
1276 last_pts_ = pkt->data.frame.pts;
1277 bits_in_last_frame_ = frame_size_in_bits;
1280 virtual void EndPassHook(void) {
1282 const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
1283 duration_ = (last_pts_ + 1) * timebase_;
1284 file_datarate_ = file_size_in_kb / duration_;
1288 virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
1289 double mismatch_psnr = compute_psnr(img1, img2);
1290 mismatch_psnr_ += mismatch_psnr;
1291 ++mismatch_nframes_;
1294 unsigned int GetMismatchFrames() { return mismatch_nframes_; }
1296 vpx_codec_pts_t last_pts_;
1297 int64_t bits_in_buffer_model_;
1300 vpx_codec_pts_t first_drop_;
1301 int64_t bits_total_;
1303 double file_datarate_;
1304 size_t bits_in_last_frame_;
1305 vpx_svc_extra_cfg_t svc_params_;
1307 double mismatch_psnr_;
1308 int mismatch_nframes_;
1311 int base_speed_setting_;
1313 static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
1314 const vpx_svc_extra_cfg_t *svc_params,
1315 int spatial_layers, int temporal_layers,
1316 int temporal_layering_mode) {
1317 int sl, spatial_layer_target;
1319 float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
1320 for (sl = 0; sl < spatial_layers; ++sl) {
1321 if (svc_params->scaling_factor_den[sl] > 0) {
1322 alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
1323 svc_params->scaling_factor_den[sl]);
1324 total += alloc_ratio[sl];
1327 for (sl = 0; sl < spatial_layers; ++sl) {
1328 enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
1329 (unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
1330 const int index = sl * temporal_layers;
1331 if (temporal_layering_mode == 3) {
1332 enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
1333 enc_cfg->layer_target_bitrate[index + 1] =
1334 (spatial_layer_target >> 1) + (spatial_layer_target >> 2);
1335 enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
1336 } else if (temporal_layering_mode == 2) {
1337 enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
1338 enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
1343 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
1344 // temporal layer, with screen content mode on and same speed setting for all
1346 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TLScreenContent1) {
1347 cfg_.rc_buf_initial_sz = 500;
1348 cfg_.rc_buf_optimal_sz = 500;
1349 cfg_.rc_buf_sz = 1000;
1350 cfg_.rc_min_quantizer = 0;
1351 cfg_.rc_max_quantizer = 63;
1352 cfg_.rc_end_usage = VPX_CBR;
1353 cfg_.g_lag_in_frames = 0;
1354 cfg_.ss_number_layers = 2;
1355 cfg_.ts_number_layers = 1;
1356 cfg_.ts_rate_decimator[0] = 1;
1357 cfg_.g_error_resilient = 1;
1359 cfg_.temporal_layering_mode = 0;
1360 svc_params_.scaling_factor_num[0] = 144;
1361 svc_params_.scaling_factor_den[0] = 288;
1362 svc_params_.scaling_factor_num[1] = 288;
1363 svc_params_.scaling_factor_den[1] = 288;
1364 cfg_.rc_dropframe_thresh = 10;
1365 cfg_.kf_max_dist = 9999;
1366 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1367 cfg_.rc_target_bitrate = 500;
1370 base_speed_setting_ = speed_setting_;
1371 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1372 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1373 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1374 EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
1377 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1378 // 3 temporal layers. Run CIF clip with 1 thread.
1379 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL) {
1380 cfg_.rc_buf_initial_sz = 500;
1381 cfg_.rc_buf_optimal_sz = 500;
1382 cfg_.rc_buf_sz = 1000;
1383 cfg_.rc_min_quantizer = 0;
1384 cfg_.rc_max_quantizer = 63;
1385 cfg_.rc_end_usage = VPX_CBR;
1386 cfg_.g_lag_in_frames = 0;
1387 cfg_.ss_number_layers = 2;
1388 cfg_.ts_number_layers = 3;
1389 cfg_.ts_rate_decimator[0] = 4;
1390 cfg_.ts_rate_decimator[1] = 2;
1391 cfg_.ts_rate_decimator[2] = 1;
1392 cfg_.g_error_resilient = 1;
1394 cfg_.temporal_layering_mode = 3;
1395 svc_params_.scaling_factor_num[0] = 144;
1396 svc_params_.scaling_factor_den[0] = 288;
1397 svc_params_.scaling_factor_num[1] = 288;
1398 svc_params_.scaling_factor_den[1] = 288;
1399 cfg_.rc_dropframe_thresh = 0;
1400 cfg_.kf_max_dist = 9999;
1401 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1403 // TODO(marpan): Check that effective_datarate for each layer hits the
1404 // layer target_bitrate.
1405 for (int i = 200; i <= 800; i += 200) {
1406 cfg_.rc_target_bitrate = i;
1408 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1409 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1410 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1411 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1412 << " The datarate for the file exceeds the target by too much!";
1413 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1414 << " The datarate for the file is lower than the target by too much!";
1415 #if CONFIG_VP9_DECODER
1416 // Number of temporal layers > 1, so half of the frames in this SVC pattern
1417 // will be non-reference frame and hence encoder will avoid loopfilter.
1418 // Since frame dropper is off, we can expcet 100 (half of the sequence)
1419 // mismatched frames.
1420 EXPECT_EQ(static_cast<unsigned int>(100), GetMismatchFrames());
1425 // Check basic rate targeting for 1 pass CBR SVC with denoising.
1426 // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
1427 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TLDenoiserOn) {
1428 cfg_.rc_buf_initial_sz = 500;
1429 cfg_.rc_buf_optimal_sz = 500;
1430 cfg_.rc_buf_sz = 1000;
1431 cfg_.rc_min_quantizer = 0;
1432 cfg_.rc_max_quantizer = 63;
1433 cfg_.rc_end_usage = VPX_CBR;
1434 cfg_.g_lag_in_frames = 0;
1435 cfg_.ss_number_layers = 2;
1436 cfg_.ts_number_layers = 3;
1437 cfg_.ts_rate_decimator[0] = 4;
1438 cfg_.ts_rate_decimator[1] = 2;
1439 cfg_.ts_rate_decimator[2] = 1;
1440 cfg_.g_error_resilient = 1;
1442 cfg_.temporal_layering_mode = 3;
1443 svc_params_.scaling_factor_num[0] = 144;
1444 svc_params_.scaling_factor_den[0] = 288;
1445 svc_params_.scaling_factor_num[1] = 288;
1446 svc_params_.scaling_factor_den[1] = 288;
1447 cfg_.rc_dropframe_thresh = 0;
1448 cfg_.kf_max_dist = 9999;
1449 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1450 // TODO(marpan): Check that effective_datarate for each layer hits the
1451 // layer target_bitrate.
1452 // For SVC, noise_sen = 1 means denoising only the top spatial layer
1453 // noise_sen = 2 means denoising the two top spatial layers.
1454 for (int noise_sen = 1; noise_sen <= 2; noise_sen++) {
1455 for (int i = 600; i <= 1000; i += 200) {
1456 cfg_.rc_target_bitrate = i;
1458 denoiser_on_ = noise_sen;
1459 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1460 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1461 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1462 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1463 << " The datarate for the file exceeds the target by too much!";
1464 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1465 << " The datarate for the file is lower than the target by too much!";
1466 #if CONFIG_VP9_DECODER
1467 // Number of temporal layers > 1, so half of the frames in this SVC
1469 // will be non-reference frame and hence encoder will avoid loopfilter.
1470 // Since frame dropper is off, we can expcet 150 (half of the sequence)
1471 // mismatched frames.
1472 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1478 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
1479 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1480 TEST_P(DatarateOnePassCbrSvc, DISABLED_OnePassCbrSvc2SL3TLSmallKf) {
1481 cfg_.rc_buf_initial_sz = 500;
1482 cfg_.rc_buf_optimal_sz = 500;
1483 cfg_.rc_buf_sz = 1000;
1484 cfg_.rc_min_quantizer = 0;
1485 cfg_.rc_max_quantizer = 63;
1486 cfg_.rc_end_usage = VPX_CBR;
1487 cfg_.g_lag_in_frames = 0;
1488 cfg_.ss_number_layers = 2;
1489 cfg_.ts_number_layers = 3;
1490 cfg_.ts_rate_decimator[0] = 4;
1491 cfg_.ts_rate_decimator[1] = 2;
1492 cfg_.ts_rate_decimator[2] = 1;
1493 cfg_.g_error_resilient = 1;
1495 cfg_.temporal_layering_mode = 3;
1496 svc_params_.scaling_factor_num[0] = 144;
1497 svc_params_.scaling_factor_den[0] = 288;
1498 svc_params_.scaling_factor_num[1] = 288;
1499 svc_params_.scaling_factor_den[1] = 288;
1500 cfg_.rc_dropframe_thresh = 10;
1501 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1503 cfg_.rc_target_bitrate = 400;
1504 // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1505 // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1506 for (int j = 64; j <= 67; j++) {
1507 cfg_.kf_max_dist = j;
1509 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1510 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1511 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1512 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
1513 << " The datarate for the file exceeds the target by too much!";
1514 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1515 << " The datarate for the file is lower than the target by too much!";
1519 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1520 // 3 temporal layers. Run HD clip with 4 threads.
1521 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL4Threads) {
1522 cfg_.rc_buf_initial_sz = 500;
1523 cfg_.rc_buf_optimal_sz = 500;
1524 cfg_.rc_buf_sz = 1000;
1525 cfg_.rc_min_quantizer = 0;
1526 cfg_.rc_max_quantizer = 63;
1527 cfg_.rc_end_usage = VPX_CBR;
1528 cfg_.g_lag_in_frames = 0;
1529 cfg_.ss_number_layers = 2;
1530 cfg_.ts_number_layers = 3;
1531 cfg_.ts_rate_decimator[0] = 4;
1532 cfg_.ts_rate_decimator[1] = 2;
1533 cfg_.ts_rate_decimator[2] = 1;
1534 cfg_.g_error_resilient = 1;
1536 cfg_.temporal_layering_mode = 3;
1537 svc_params_.scaling_factor_num[0] = 144;
1538 svc_params_.scaling_factor_den[0] = 288;
1539 svc_params_.scaling_factor_num[1] = 288;
1540 svc_params_.scaling_factor_den[1] = 288;
1541 cfg_.rc_dropframe_thresh = 0;
1542 cfg_.kf_max_dist = 9999;
1543 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1544 cfg_.rc_target_bitrate = 800;
1546 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1547 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1548 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1549 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1550 << " The datarate for the file exceeds the target by too much!";
1551 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1552 << " The datarate for the file is lower than the target by too much!";
1553 #if CONFIG_VP9_DECODER
1554 // Number of temporal layers > 1, so half of the frames in this SVC pattern
1555 // will be non-reference frame and hence encoder will avoid loopfilter.
1556 // Since frame dropper is off, we can expcet 150 (half of the sequence)
1557 // mismatched frames.
1558 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1562 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1563 // 3 temporal layers. Run CIF clip with 1 thread.
1564 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL) {
1565 cfg_.rc_buf_initial_sz = 500;
1566 cfg_.rc_buf_optimal_sz = 500;
1567 cfg_.rc_buf_sz = 1000;
1568 cfg_.rc_min_quantizer = 0;
1569 cfg_.rc_max_quantizer = 63;
1570 cfg_.rc_end_usage = VPX_CBR;
1571 cfg_.g_lag_in_frames = 0;
1572 cfg_.ss_number_layers = 3;
1573 cfg_.ts_number_layers = 3;
1574 cfg_.ts_rate_decimator[0] = 4;
1575 cfg_.ts_rate_decimator[1] = 2;
1576 cfg_.ts_rate_decimator[2] = 1;
1577 cfg_.g_error_resilient = 1;
1579 cfg_.temporal_layering_mode = 3;
1580 svc_params_.scaling_factor_num[0] = 72;
1581 svc_params_.scaling_factor_den[0] = 288;
1582 svc_params_.scaling_factor_num[1] = 144;
1583 svc_params_.scaling_factor_den[1] = 288;
1584 svc_params_.scaling_factor_num[2] = 288;
1585 svc_params_.scaling_factor_den[2] = 288;
1586 cfg_.rc_dropframe_thresh = 0;
1587 cfg_.kf_max_dist = 9999;
1588 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1589 cfg_.rc_target_bitrate = 800;
1591 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1592 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1593 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1594 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1595 << " The datarate for the file exceeds the target by too much!";
1596 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
1597 << " The datarate for the file is lower than the target by too much!";
1598 #if CONFIG_VP9_DECODER
1599 // Number of temporal layers > 1, so half of the frames in this SVC pattern
1600 // will be non-reference frame and hence encoder will avoid loopfilter.
1601 // Since frame dropper is off, we can expcet 150 (half of the sequence)
1602 // mismatched frames.
1603 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1607 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1608 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1609 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TLSmallKf) {
1610 cfg_.rc_buf_initial_sz = 500;
1611 cfg_.rc_buf_optimal_sz = 500;
1612 cfg_.rc_buf_sz = 1000;
1613 cfg_.rc_min_quantizer = 0;
1614 cfg_.rc_max_quantizer = 63;
1615 cfg_.rc_end_usage = VPX_CBR;
1616 cfg_.g_lag_in_frames = 0;
1617 cfg_.ss_number_layers = 3;
1618 cfg_.ts_number_layers = 3;
1619 cfg_.ts_rate_decimator[0] = 4;
1620 cfg_.ts_rate_decimator[1] = 2;
1621 cfg_.ts_rate_decimator[2] = 1;
1622 cfg_.g_error_resilient = 1;
1624 cfg_.temporal_layering_mode = 3;
1625 svc_params_.scaling_factor_num[0] = 72;
1626 svc_params_.scaling_factor_den[0] = 288;
1627 svc_params_.scaling_factor_num[1] = 144;
1628 svc_params_.scaling_factor_den[1] = 288;
1629 svc_params_.scaling_factor_num[2] = 288;
1630 svc_params_.scaling_factor_den[2] = 288;
1631 cfg_.rc_dropframe_thresh = 10;
1632 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1633 cfg_.rc_target_bitrate = 800;
1634 // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1635 // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1636 for (int j = 32; j <= 35; j++) {
1637 cfg_.kf_max_dist = j;
1639 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1640 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1641 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1642 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
1643 << " The datarate for the file exceeds the target by too much!";
1644 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
1645 << " The datarate for the file is lower than the target by too much!";
1649 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1650 // 3 temporal layers. Run HD clip with 4 threads.
1651 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL4threads) {
1652 cfg_.rc_buf_initial_sz = 500;
1653 cfg_.rc_buf_optimal_sz = 500;
1654 cfg_.rc_buf_sz = 1000;
1655 cfg_.rc_min_quantizer = 0;
1656 cfg_.rc_max_quantizer = 63;
1657 cfg_.rc_end_usage = VPX_CBR;
1658 cfg_.g_lag_in_frames = 0;
1659 cfg_.ss_number_layers = 3;
1660 cfg_.ts_number_layers = 3;
1661 cfg_.ts_rate_decimator[0] = 4;
1662 cfg_.ts_rate_decimator[1] = 2;
1663 cfg_.ts_rate_decimator[2] = 1;
1664 cfg_.g_error_resilient = 1;
1666 cfg_.temporal_layering_mode = 3;
1667 svc_params_.scaling_factor_num[0] = 72;
1668 svc_params_.scaling_factor_den[0] = 288;
1669 svc_params_.scaling_factor_num[1] = 144;
1670 svc_params_.scaling_factor_den[1] = 288;
1671 svc_params_.scaling_factor_num[2] = 288;
1672 svc_params_.scaling_factor_den[2] = 288;
1673 cfg_.rc_dropframe_thresh = 0;
1674 cfg_.kf_max_dist = 9999;
1675 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1676 cfg_.rc_target_bitrate = 800;
1678 assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1679 cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1680 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1681 ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1682 << " The datarate for the file exceeds the target by too much!";
1683 ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
1684 << " The datarate for the file is lower than the target by too much!";
1685 #if CONFIG_VP9_DECODER
1686 // Number of temporal layers > 1, so half of the frames in this SVC pattern
1687 // will be non-reference frame and hence encoder will avoid loopfilter.
1688 // Since frame dropper is off, we can expcet 150 (half of the sequence)
1689 // mismatched frames.
1690 EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1694 // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
1696 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
1697 cfg_.rc_buf_initial_sz = 500;
1698 cfg_.rc_buf_optimal_sz = 500;
1699 cfg_.rc_buf_sz = 1000;
1700 cfg_.rc_min_quantizer = 0;
1701 cfg_.rc_max_quantizer = 63;
1702 cfg_.rc_end_usage = VPX_CBR;
1703 cfg_.g_lag_in_frames = 0;
1704 cfg_.ss_number_layers = 2;
1705 cfg_.ts_number_layers = 1;
1706 cfg_.ts_rate_decimator[0] = 1;
1707 cfg_.g_error_resilient = 1;
1709 cfg_.temporal_layering_mode = 0;
1710 svc_params_.scaling_factor_num[0] = 256;
1711 svc_params_.scaling_factor_den[0] = 1280;
1712 svc_params_.scaling_factor_num[1] = 1280;
1713 svc_params_.scaling_factor_den[1] = 1280;
1714 cfg_.rc_dropframe_thresh = 10;
1715 cfg_.kf_max_dist = 999999;
1716 cfg_.kf_min_dist = 0;
1717 cfg_.ss_target_bitrate[0] = 300;
1718 cfg_.ss_target_bitrate[1] = 1400;
1719 cfg_.layer_target_bitrate[0] = 300;
1720 cfg_.layer_target_bitrate[1] = 1400;
1721 cfg_.rc_target_bitrate = 1700;
1722 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1724 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1725 EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
1728 VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
1729 ::testing::Values(0));
1730 VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
1731 ::testing::Values(::libvpx_test::kRealTime),
1732 ::testing::Values(-6, -12));
1733 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
1734 ::testing::Values(::libvpx_test::kOnePassGood,
1735 ::libvpx_test::kRealTime),
1736 ::testing::Range(2, 9));
1737 #if CONFIG_VP9_TEMPORAL_DENOISING
1738 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeDenoiser,
1739 ::testing::Values(::libvpx_test::kRealTime),
1740 ::testing::Range(5, 9));
1742 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
1743 ::testing::Values(::libvpx_test::kRealTime),
1744 ::testing::Range(5, 9));