]> granicus.if.org Git - libvpx/blob - test/datarate_test.cc
ppc: Add vpx_sadnxmx4d_vsx for n,m = {8, 16, 32 ,64}
[libvpx] / test / datarate_test.cc
1 /*
2  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3  *
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.
9  */
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
19 namespace {
20
21 class DatarateTestLarge
22     : public ::libvpx_test::EncoderTest,
23       public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
24  public:
25   DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
26
27   virtual ~DatarateTestLarge() {}
28
29  protected:
30   virtual void SetUp() {
31     InitializeConfig();
32     SetMode(GET_PARAM(1));
33     set_cpu_used_ = GET_PARAM(2);
34     ResetModel();
35   }
36
37   virtual void ResetModel() {
38     last_pts_ = 0;
39     bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
40     frame_number_ = 0;
41     first_drop_ = 0;
42     bits_total_ = 0;
43     duration_ = 0.0;
44     denoiser_offon_test_ = 0;
45     denoiser_offon_period_ = -1;
46     gf_boost_ = 0;
47   }
48
49   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
50                                   ::libvpx_test::Encoder *encoder) {
51     if (video->frame() == 0) {
52       encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
53       encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
54       encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
55     }
56
57     if (denoiser_offon_test_) {
58       ASSERT_GT(denoiser_offon_period_, 0)
59           << "denoiser_offon_period_ is not positive.";
60       if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
61         // Flip denoiser_on_ periodically
62         denoiser_on_ ^= 1;
63       }
64       encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
65     }
66
67     const vpx_rational_t tb = video->timebase();
68     timebase_ = static_cast<double>(tb.num) / tb.den;
69     duration_ = 0;
70   }
71
72   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
73     // Time since last timestamp = duration.
74     vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
75
76     // TODO(jimbankoski): Remove these lines when the issue:
77     // http://code.google.com/p/webm/issues/detail?id=496 is fixed.
78     // For now the codec assumes buffer starts at starting buffer rate
79     // plus one frame's time.
80     if (last_pts_ == 0) duration = 1;
81
82     // Add to the buffer the bits we'd expect from a constant bitrate server.
83     bits_in_buffer_model_ += static_cast<int64_t>(
84         duration * timebase_ * cfg_.rc_target_bitrate * 1000);
85
86     /* Test the buffer model here before subtracting the frame. Do so because
87      * the way the leaky bucket model works in libvpx is to allow the buffer to
88      * empty - and then stop showing frames until we've got enough bits to
89      * show one. As noted in comment below (issue 495), this does not currently
90      * apply to key frames. For now exclude key frames in condition below. */
91     const bool key_frame =
92         (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
93     if (!key_frame) {
94       ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
95                                           << pkt->data.frame.pts;
96     }
97
98     const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
99
100     // Subtract from the buffer the bits associated with a played back frame.
101     bits_in_buffer_model_ -= frame_size_in_bits;
102
103     // Update the running total of bits for end of test datarate checks.
104     bits_total_ += frame_size_in_bits;
105
106     // If first drop not set and we have a drop set it to this time.
107     if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
108
109     // Update the most recent pts.
110     last_pts_ = pkt->data.frame.pts;
111
112     // We update this so that we can calculate the datarate minus the last
113     // frame encoded in the file.
114     bits_in_last_frame_ = frame_size_in_bits;
115
116     ++frame_number_;
117   }
118
119   virtual void EndPassHook(void) {
120     if (bits_total_) {
121       const double file_size_in_kb = bits_total_ / 1000.;  // bits per kilobit
122
123       duration_ = (last_pts_ + 1) * timebase_;
124
125       // Effective file datarate includes the time spent prebuffering.
126       effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
127                             (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
128
129       file_datarate_ = file_size_in_kb / duration_;
130     }
131   }
132
133   vpx_codec_pts_t last_pts_;
134   int64_t bits_in_buffer_model_;
135   double timebase_;
136   int frame_number_;
137   vpx_codec_pts_t first_drop_;
138   int64_t bits_total_;
139   double duration_;
140   double file_datarate_;
141   double effective_datarate_;
142   int64_t bits_in_last_frame_;
143   int denoiser_on_;
144   int denoiser_offon_test_;
145   int denoiser_offon_period_;
146   int set_cpu_used_;
147   int gf_boost_;
148 };
149
150 #if CONFIG_TEMPORAL_DENOISING
151 // Check basic datarate targeting, for a single bitrate, but loop over the
152 // various denoiser settings.
153 TEST_P(DatarateTestLarge, DenoiserLevels) {
154   cfg_.rc_buf_initial_sz = 500;
155   cfg_.rc_dropframe_thresh = 1;
156   cfg_.rc_max_quantizer = 56;
157   cfg_.rc_end_usage = VPX_CBR;
158   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
159                                        30, 1, 0, 140);
160   for (int j = 1; j < 5; ++j) {
161     // Run over the denoiser levels.
162     // For the temporal denoiser (#if CONFIG_TEMPORAL_DENOISING) the level j
163     // refers to the 4 denoiser modes: denoiserYonly, denoiserOnYUV,
164     // denoiserOnAggressive, and denoiserOnAdaptive.
165     denoiser_on_ = j;
166     cfg_.rc_target_bitrate = 300;
167     ResetModel();
168     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
169     ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
170         << " The datarate for the file exceeds the target!";
171
172     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
173         << " The datarate for the file missed the target!";
174   }
175 }
176
177 // Check basic datarate targeting, for a single bitrate, when denoiser is off
178 // and on.
179 TEST_P(DatarateTestLarge, DenoiserOffOn) {
180   cfg_.rc_buf_initial_sz = 500;
181   cfg_.rc_dropframe_thresh = 1;
182   cfg_.rc_max_quantizer = 56;
183   cfg_.rc_end_usage = VPX_CBR;
184   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
185                                        30, 1, 0, 299);
186   cfg_.rc_target_bitrate = 300;
187   ResetModel();
188   // The denoiser is off by default.
189   denoiser_on_ = 0;
190   // Set the offon test flag.
191   denoiser_offon_test_ = 1;
192   denoiser_offon_period_ = 100;
193   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
194   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
195       << " The datarate for the file exceeds the target!";
196   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
197       << " The datarate for the file missed the target!";
198 }
199 #endif  // CONFIG_TEMPORAL_DENOISING
200
201 TEST_P(DatarateTestLarge, BasicBufferModel) {
202   denoiser_on_ = 0;
203   cfg_.rc_buf_initial_sz = 500;
204   cfg_.rc_dropframe_thresh = 1;
205   cfg_.rc_max_quantizer = 56;
206   cfg_.rc_end_usage = VPX_CBR;
207   // 2 pass cbr datarate control has a bug hidden by the small # of
208   // frames selected in this encode. The problem is that even if the buffer is
209   // negative we produce a keyframe on a cutscene. Ignoring datarate
210   // constraints
211   // TODO(jimbankoski): ( Fix when issue
212   // http://code.google.com/p/webm/issues/detail?id=495 is addressed. )
213   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
214                                        30, 1, 0, 140);
215
216   // There is an issue for low bitrates in real-time mode, where the
217   // effective_datarate slightly overshoots the target bitrate.
218   // This is same the issue as noted about (#495).
219   // TODO(jimbankoski/marpan): Update test to run for lower bitrates (< 100),
220   // when the issue is resolved.
221   for (int i = 100; i < 800; i += 200) {
222     cfg_.rc_target_bitrate = i;
223     ResetModel();
224     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
225     ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
226         << " The datarate for the file exceeds the target!";
227     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
228         << " The datarate for the file missed the target!";
229   }
230 }
231
232 TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
233   denoiser_on_ = 0;
234   cfg_.rc_buf_initial_sz = 500;
235   cfg_.rc_max_quantizer = 36;
236   cfg_.rc_end_usage = VPX_CBR;
237   cfg_.rc_target_bitrate = 200;
238   cfg_.kf_mode = VPX_KF_DISABLED;
239
240   const int frame_count = 40;
241   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
242                                        30, 1, 0, frame_count);
243
244   // Here we check that the first dropped frame gets earlier and earlier
245   // as the drop frame threshold is increased.
246
247   const int kDropFrameThreshTestStep = 30;
248   vpx_codec_pts_t last_drop = frame_count;
249   for (int i = 1; i < 91; i += kDropFrameThreshTestStep) {
250     cfg_.rc_dropframe_thresh = i;
251     ResetModel();
252     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
253     ASSERT_LE(first_drop_, last_drop)
254         << " The first dropped frame for drop_thresh " << i
255         << " > first dropped frame for drop_thresh "
256         << i - kDropFrameThreshTestStep;
257     last_drop = first_drop_;
258   }
259 }
260
261 // Disabled for tsan, see:
262 // https://bugs.chromium.org/p/webm/issues/detail?id=1049
263 #if defined(__has_feature)
264 #if __has_feature(thread_sanitizer)
265 #define BUILDING_WITH_TSAN
266 #endif
267 #endif
268 #ifndef BUILDING_WITH_TSAN
269 TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
270   denoiser_on_ = 0;
271   cfg_.rc_buf_initial_sz = 500;
272   cfg_.rc_dropframe_thresh = 30;
273   cfg_.rc_max_quantizer = 56;
274   cfg_.rc_end_usage = VPX_CBR;
275   cfg_.g_threads = 2;
276
277   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
278                                        30, 1, 0, 140);
279   cfg_.rc_target_bitrate = 200;
280   ResetModel();
281   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
282   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
283       << " The datarate for the file exceeds the target!";
284
285   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
286       << " The datarate for the file missed the target!";
287 }
288 #endif  // !BUILDING_WITH_TSAN
289
290 class DatarateTestRealTime : public DatarateTestLarge {
291  public:
292   virtual ~DatarateTestRealTime() {}
293 };
294
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,
304                                        30, 1, 0, 140);
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.
310     denoiser_on_ = j;
311     cfg_.rc_target_bitrate = 300;
312     ResetModel();
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!";
318   }
319 }
320
321 // Check basic datarate targeting, for a single bitrate, when denoiser is off
322 // and on.
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,
329                                        30, 1, 0, 299);
330   cfg_.rc_target_bitrate = 300;
331   ResetModel();
332   // The denoiser is off by default.
333   denoiser_on_ = 0;
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!";
342 }
343 #endif  // CONFIG_TEMPORAL_DENOISING
344
345 TEST_P(DatarateTestRealTime, BasicBufferModel) {
346   denoiser_on_ = 0;
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
354   // constraints
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,
358                                        30, 1, 0, 140);
359
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;
367     ResetModel();
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!";
373   }
374 }
375
376 TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
377   denoiser_on_ = 0;
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;
383
384   const int frame_count = 40;
385   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
386                                        30, 1, 0, frame_count);
387
388   // Check that the first dropped frame gets earlier and earlier
389   // as the drop frame threshold is increased.
390
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;
395     ResetModel();
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_;
402   }
403 }
404
405 // Disabled for tsan, see:
406 // https://bugs.chromium.org/p/webm/issues/detail?id=1049
407
408 #ifndef BUILDING_WITH_TSAN
409 TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
410   denoiser_on_ = 0;
411   cfg_.rc_buf_initial_sz = 500;
412   cfg_.rc_dropframe_thresh = 30;
413   cfg_.rc_max_quantizer = 56;
414   cfg_.rc_end_usage = VPX_CBR;
415   // Encode using multiple threads.
416   cfg_.g_threads = 2;
417
418   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
419                                        30, 1, 0, 140);
420   cfg_.rc_target_bitrate = 200;
421   ResetModel();
422   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
423   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
424       << " The datarate for the file exceeds the target!";
425
426   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
427       << " The datarate for the file missed the target!";
428 }
429 #endif
430
431 TEST_P(DatarateTestRealTime, GFBoost) {
432   denoiser_on_ = 0;
433   cfg_.rc_buf_initial_sz = 500;
434   cfg_.rc_dropframe_thresh = 0;
435   cfg_.rc_max_quantizer = 56;
436   cfg_.rc_end_usage = VPX_CBR;
437   cfg_.g_error_resilient = 0;
438
439   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
440                                        30, 1, 0, 300);
441   cfg_.rc_target_bitrate = 300;
442   ResetModel();
443   // Apply a gf boost.
444   gf_boost_ = 50;
445
446   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
447   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
448       << " The datarate for the file exceeds the target!";
449
450   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
451       << " The datarate for the file missed the target!";
452 }
453
454 class DatarateTestVP9Large
455     : public ::libvpx_test::EncoderTest,
456       public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
457  public:
458   DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
459
460  protected:
461   virtual ~DatarateTestVP9Large() {}
462
463   virtual void SetUp() {
464     InitializeConfig();
465     SetMode(GET_PARAM(1));
466     set_cpu_used_ = GET_PARAM(2);
467     ResetModel();
468   }
469
470   virtual void ResetModel() {
471     last_pts_ = 0;
472     bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
473     frame_number_ = 0;
474     tot_frame_number_ = 0;
475     first_drop_ = 0;
476     num_drops_ = 0;
477     // Denoiser is off by default.
478     denoiser_on_ = 0;
479     // For testing up to 3 layers.
480     for (int i = 0; i < 3; ++i) {
481       bits_total_[i] = 0;
482     }
483     denoiser_offon_test_ = 0;
484     denoiser_offon_period_ = -1;
485   }
486
487   //
488   // Frame flags and layer id for temporal layers.
489   //
490
491   // For two layers, test pattern is:
492   //   1     3
493   // 0    2     .....
494   // For three layers, test pattern is:
495   //   1      3    5      7
496   //      2           6
497   // 0          4            ....
498   // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
499   // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
500   // the altref frame.
501   int SetFrameFlags(int frame_num, int num_temp_layers) {
502     int frame_flags = 0;
503     if (num_temp_layers == 2) {
504       if (frame_num % 2 == 0) {
505         // Layer 0: predict from L and ARF, update L.
506         frame_flags =
507             VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
508       } else {
509         // Layer 1: predict from L, G and ARF, and update G.
510         frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
511                       VP8_EFLAG_NO_UPD_ENTROPY;
512       }
513     } else if (num_temp_layers == 3) {
514       if (frame_num % 4 == 0) {
515         // Layer 0: predict from L and ARF; update L.
516         frame_flags =
517             VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
518       } else if ((frame_num - 2) % 4 == 0) {
519         // Layer 1: predict from L, G, ARF; update G.
520         frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
521       } else if ((frame_num - 1) % 2 == 0) {
522         // Layer 2: predict from L, G, ARF; update ARF.
523         frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
524       }
525     }
526     return frame_flags;
527   }
528
529   int SetLayerId(int frame_num, int num_temp_layers) {
530     int layer_id = 0;
531     if (num_temp_layers == 2) {
532       if (frame_num % 2 == 0) {
533         layer_id = 0;
534       } else {
535         layer_id = 1;
536       }
537     } else if (num_temp_layers == 3) {
538       if (frame_num % 4 == 0) {
539         layer_id = 0;
540       } else if ((frame_num - 2) % 4 == 0) {
541         layer_id = 1;
542       } else if ((frame_num - 1) % 2 == 0) {
543         layer_id = 2;
544       }
545     }
546     return layer_id;
547   }
548
549   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
550                                   ::libvpx_test::Encoder *encoder) {
551     if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
552
553     if (denoiser_offon_test_) {
554       ASSERT_GT(denoiser_offon_period_, 0)
555           << "denoiser_offon_period_ is not positive.";
556       if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
557         // Flip denoiser_on_ periodically
558         denoiser_on_ ^= 1;
559       }
560     }
561
562     encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
563     encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
564
565     if (cfg_.ts_number_layers > 1) {
566       if (video->frame() == 0) {
567         encoder->Control(VP9E_SET_SVC, 1);
568       }
569       vpx_svc_layer_id_t layer_id;
570       layer_id.spatial_layer_id = 0;
571       frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
572       layer_id.temporal_layer_id =
573           SetLayerId(video->frame(), cfg_.ts_number_layers);
574       encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
575     }
576     const vpx_rational_t tb = video->timebase();
577     timebase_ = static_cast<double>(tb.num) / tb.den;
578     duration_ = 0;
579   }
580
581   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
582     // Time since last timestamp = duration.
583     vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
584
585     if (duration > 1) {
586       // If first drop not set and we have a drop set it to this time.
587       if (!first_drop_) first_drop_ = last_pts_ + 1;
588       // Update the number of frame drops.
589       num_drops_ += static_cast<int>(duration - 1);
590       // Update counter for total number of frames (#frames input to encoder).
591       // Needed for setting the proper layer_id below.
592       tot_frame_number_ += static_cast<int>(duration - 1);
593     }
594
595     int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
596
597     // Add to the buffer the bits we'd expect from a constant bitrate server.
598     bits_in_buffer_model_ += static_cast<int64_t>(
599         duration * timebase_ * cfg_.rc_target_bitrate * 1000);
600
601     // Buffer should not go negative.
602     ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
603                                         << pkt->data.frame.pts;
604
605     const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
606
607     // Update the total encoded bits. For temporal layers, update the cumulative
608     // encoded bits per layer.
609     for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
610       bits_total_[i] += frame_size_in_bits;
611     }
612
613     // Update the most recent pts.
614     last_pts_ = pkt->data.frame.pts;
615     ++frame_number_;
616     ++tot_frame_number_;
617   }
618
619   virtual void EndPassHook(void) {
620     for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
621          ++layer) {
622       duration_ = (last_pts_ + 1) * timebase_;
623       if (bits_total_[layer]) {
624         // Effective file datarate:
625         effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
626       }
627     }
628   }
629
630   vpx_codec_pts_t last_pts_;
631   double timebase_;
632   int frame_number_;      // Counter for number of non-dropped/encoded frames.
633   int tot_frame_number_;  // Counter for total number of input frames.
634   int64_t bits_total_[3];
635   double duration_;
636   double effective_datarate_[3];
637   int set_cpu_used_;
638   int64_t bits_in_buffer_model_;
639   vpx_codec_pts_t first_drop_;
640   int num_drops_;
641   int denoiser_on_;
642   int denoiser_offon_test_;
643   int denoiser_offon_period_;
644 };
645
646 // Check basic rate targeting for VBR mode with 0 lag.
647 TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
648   cfg_.rc_min_quantizer = 0;
649   cfg_.rc_max_quantizer = 63;
650   cfg_.g_error_resilient = 0;
651   cfg_.rc_end_usage = VPX_VBR;
652   cfg_.g_lag_in_frames = 0;
653
654   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
655                                        30, 1, 0, 300);
656   for (int i = 400; i <= 800; i += 400) {
657     cfg_.rc_target_bitrate = i;
658     ResetModel();
659     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
660     ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
661         << " The datarate for the file is lower than target by too much!";
662     ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
663         << " The datarate for the file is greater than target by too much!";
664   }
665 }
666
667 // Check basic rate targeting for VBR mode with non-zero lag.
668 TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
669   cfg_.rc_min_quantizer = 0;
670   cfg_.rc_max_quantizer = 63;
671   cfg_.g_error_resilient = 0;
672   cfg_.rc_end_usage = VPX_VBR;
673   // For non-zero lag, rate control will work (be within bounds) for
674   // real-time mode.
675   if (deadline_ == VPX_DL_REALTIME) {
676     cfg_.g_lag_in_frames = 15;
677   } else {
678     cfg_.g_lag_in_frames = 0;
679   }
680
681   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
682                                        30, 1, 0, 300);
683   for (int i = 400; i <= 800; i += 400) {
684     cfg_.rc_target_bitrate = i;
685     ResetModel();
686     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
687     ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
688         << " The datarate for the file is lower than target by too much!";
689     ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
690         << " The datarate for the file is greater than target by too much!";
691   }
692 }
693
694 // Check basic rate targeting for CBR mode.
695 TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
696   cfg_.rc_buf_initial_sz = 500;
697   cfg_.rc_buf_optimal_sz = 500;
698   cfg_.rc_buf_sz = 1000;
699   cfg_.rc_dropframe_thresh = 1;
700   cfg_.rc_min_quantizer = 0;
701   cfg_.rc_max_quantizer = 63;
702   cfg_.rc_end_usage = VPX_CBR;
703   cfg_.g_lag_in_frames = 0;
704
705   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
706                                        30, 1, 0, 140);
707   for (int i = 150; i < 800; i += 200) {
708     cfg_.rc_target_bitrate = i;
709     ResetModel();
710     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
711     ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
712         << " The datarate for the file is lower than target by too much!";
713     ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
714         << " The datarate for the file is greater than target by too much!";
715   }
716 }
717
718 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
719 TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
720   cfg_.rc_buf_initial_sz = 500;
721   cfg_.rc_buf_optimal_sz = 500;
722   cfg_.rc_buf_sz = 1000;
723   cfg_.rc_dropframe_thresh = 30;
724   cfg_.rc_min_quantizer = 0;
725   cfg_.rc_max_quantizer = 63;
726   cfg_.rc_end_usage = VPX_CBR;
727   cfg_.g_lag_in_frames = 0;
728   // Encode using multiple threads.
729   cfg_.g_threads = 2;
730
731   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
732                                        30, 1, 0, 140);
733   cfg_.rc_target_bitrate = 200;
734   ResetModel();
735   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
736   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
737       << " The datarate for the file is lower than target by too much!";
738   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
739       << " The datarate for the file is greater than target by too much!";
740 }
741
742 // Check basic rate targeting for CBR.
743 TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
744   ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
745
746   cfg_.g_profile = 1;
747   cfg_.g_timebase = video.timebase();
748
749   cfg_.rc_buf_initial_sz = 500;
750   cfg_.rc_buf_optimal_sz = 500;
751   cfg_.rc_buf_sz = 1000;
752   cfg_.rc_dropframe_thresh = 1;
753   cfg_.rc_min_quantizer = 0;
754   cfg_.rc_max_quantizer = 63;
755   cfg_.rc_end_usage = VPX_CBR;
756
757   for (int i = 250; i < 900; i += 200) {
758     cfg_.rc_target_bitrate = i;
759     ResetModel();
760     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
761     ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
762               effective_datarate_[0] * 0.80)
763         << " The datarate for the file exceeds the target by too much!";
764     ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
765               effective_datarate_[0] * 1.15)
766         << " The datarate for the file missed the target!"
767         << cfg_.rc_target_bitrate << " " << effective_datarate_;
768   }
769 }
770
771 // Check that (1) the first dropped frame gets earlier and earlier
772 // as the drop frame threshold is increased, and (2) that the total number of
773 // frame drops does not decrease as we increase frame drop threshold.
774 // Use a lower qp-max to force some frame drops.
775 TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
776   cfg_.rc_buf_initial_sz = 500;
777   cfg_.rc_buf_optimal_sz = 500;
778   cfg_.rc_buf_sz = 1000;
779   cfg_.rc_undershoot_pct = 20;
780   cfg_.rc_undershoot_pct = 20;
781   cfg_.rc_dropframe_thresh = 10;
782   cfg_.rc_min_quantizer = 0;
783   cfg_.rc_max_quantizer = 50;
784   cfg_.rc_end_usage = VPX_CBR;
785   cfg_.rc_target_bitrate = 200;
786   cfg_.g_lag_in_frames = 0;
787   // TODO(marpan): Investigate datarate target failures with a smaller keyframe
788   // interval (128).
789   cfg_.kf_max_dist = 9999;
790
791   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
792                                        30, 1, 0, 140);
793
794   const int kDropFrameThreshTestStep = 30;
795   vpx_codec_pts_t last_drop = 140;
796   int last_num_drops = 0;
797   for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
798     cfg_.rc_dropframe_thresh = i;
799     ResetModel();
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!";
805     ASSERT_LE(first_drop_, last_drop)
806         << " The first dropped frame for drop_thresh " << i
807         << " > first dropped frame for drop_thresh "
808         << i - kDropFrameThreshTestStep;
809     ASSERT_GE(num_drops_, last_num_drops * 0.85)
810         << " The number of dropped frames for drop_thresh " << i
811         << " < number of dropped frames for drop_thresh "
812         << i - kDropFrameThreshTestStep;
813     last_drop = first_drop_;
814     last_num_drops = num_drops_;
815   }
816 }
817
818 // Check basic rate targeting for 2 temporal layers.
819 TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
820   cfg_.rc_buf_initial_sz = 500;
821   cfg_.rc_buf_optimal_sz = 500;
822   cfg_.rc_buf_sz = 1000;
823   cfg_.rc_dropframe_thresh = 1;
824   cfg_.rc_min_quantizer = 0;
825   cfg_.rc_max_quantizer = 63;
826   cfg_.rc_end_usage = VPX_CBR;
827   cfg_.g_lag_in_frames = 0;
828
829   // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
830   cfg_.ss_number_layers = 1;
831   cfg_.ts_number_layers = 2;
832   cfg_.ts_rate_decimator[0] = 2;
833   cfg_.ts_rate_decimator[1] = 1;
834
835   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
836
837   if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
838
839   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
840                                        30, 1, 0, 200);
841   for (int i = 200; i <= 800; i += 200) {
842     cfg_.rc_target_bitrate = i;
843     ResetModel();
844     // 60-40 bitrate allocation for 2 temporal layers.
845     cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
846     cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
847     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
848     for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
849       ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
850           << " The datarate for the file is lower than target by too much, "
851              "for layer: "
852           << j;
853       ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
854           << " The datarate for the file is greater than target by too much, "
855              "for layer: "
856           << j;
857     }
858   }
859 }
860
861 // Check basic rate targeting for 3 temporal layers.
862 TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
863   cfg_.rc_buf_initial_sz = 500;
864   cfg_.rc_buf_optimal_sz = 500;
865   cfg_.rc_buf_sz = 1000;
866   cfg_.rc_dropframe_thresh = 1;
867   cfg_.rc_min_quantizer = 0;
868   cfg_.rc_max_quantizer = 63;
869   cfg_.rc_end_usage = VPX_CBR;
870   cfg_.g_lag_in_frames = 0;
871
872   // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
873   cfg_.ss_number_layers = 1;
874   cfg_.ts_number_layers = 3;
875   cfg_.ts_rate_decimator[0] = 4;
876   cfg_.ts_rate_decimator[1] = 2;
877   cfg_.ts_rate_decimator[2] = 1;
878
879   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
880
881   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
882                                        30, 1, 0, 200);
883   for (int i = 200; i <= 800; i += 200) {
884     cfg_.rc_target_bitrate = i;
885     ResetModel();
886     // 40-20-40 bitrate allocation for 3 temporal layers.
887     cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
888     cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
889     cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
890     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
891     for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
892       // TODO(yaowu): Work out more stable rc control strategy and
893       //              Adjust the thresholds to be tighter than .75.
894       ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
895           << " The datarate for the file is lower than target by too much, "
896              "for layer: "
897           << j;
898       // TODO(yaowu): Work out more stable rc control strategy and
899       //              Adjust the thresholds to be tighter than 1.25.
900       ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
901           << " The datarate for the file is greater than target by too much, "
902              "for layer: "
903           << j;
904     }
905   }
906 }
907
908 // Check basic rate targeting for 3 temporal layers, with frame dropping.
909 // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
910 // frame drop threshold, to force frame dropping.
911 TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
912   cfg_.rc_buf_initial_sz = 500;
913   cfg_.rc_buf_optimal_sz = 500;
914   cfg_.rc_buf_sz = 1000;
915   // Set frame drop threshold and rc_max_quantizer to force some frame drops.
916   cfg_.rc_dropframe_thresh = 20;
917   cfg_.rc_max_quantizer = 45;
918   cfg_.rc_min_quantizer = 0;
919   cfg_.rc_end_usage = VPX_CBR;
920   cfg_.g_lag_in_frames = 0;
921
922   // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
923   cfg_.ss_number_layers = 1;
924   cfg_.ts_number_layers = 3;
925   cfg_.ts_rate_decimator[0] = 4;
926   cfg_.ts_rate_decimator[1] = 2;
927   cfg_.ts_rate_decimator[2] = 1;
928
929   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
930
931   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
932                                        30, 1, 0, 200);
933   cfg_.rc_target_bitrate = 200;
934   ResetModel();
935   // 40-20-40 bitrate allocation for 3 temporal layers.
936   cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
937   cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
938   cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
939   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
940   for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
941     ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
942         << " The datarate for the file is lower than target by too much, "
943            "for layer: "
944         << j;
945     ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
946         << " The datarate for the file is greater than target by too much, "
947            "for layer: "
948         << j;
949     // Expect some frame drops in this test: for this 200 frames test,
950     // expect at least 10% and not more than 60% drops.
951     ASSERT_GE(num_drops_, 20);
952     ASSERT_LE(num_drops_, 130);
953   }
954 }
955
956 #if CONFIG_VP9_TEMPORAL_DENOISING
957 class DatarateTestVP9LargeDenoiser : public DatarateTestVP9Large {
958  public:
959   virtual ~DatarateTestVP9LargeDenoiser() {}
960 };
961
962 // Check basic datarate targeting, for a single bitrate, when denoiser is on.
963 TEST_P(DatarateTestVP9LargeDenoiser, LowNoise) {
964   cfg_.rc_buf_initial_sz = 500;
965   cfg_.rc_buf_optimal_sz = 500;
966   cfg_.rc_buf_sz = 1000;
967   cfg_.rc_dropframe_thresh = 1;
968   cfg_.rc_min_quantizer = 2;
969   cfg_.rc_max_quantizer = 56;
970   cfg_.rc_end_usage = VPX_CBR;
971   cfg_.g_lag_in_frames = 0;
972
973   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
974                                        30, 1, 0, 140);
975
976   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
977   // there is only one denoiser mode: denoiserYonly(which is 1),
978   // but may add more modes in the future.
979   cfg_.rc_target_bitrate = 300;
980   ResetModel();
981   // Turn on the denoiser.
982   denoiser_on_ = 1;
983   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
984   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
985       << " The datarate for the file is lower than target by too much!";
986   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
987       << " The datarate for the file is greater than target by too much!";
988 }
989
990 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
991 // for clip with high noise level. Use 2 threads.
992 TEST_P(DatarateTestVP9LargeDenoiser, HighNoise) {
993   cfg_.rc_buf_initial_sz = 500;
994   cfg_.rc_buf_optimal_sz = 500;
995   cfg_.rc_buf_sz = 1000;
996   cfg_.rc_dropframe_thresh = 1;
997   cfg_.rc_min_quantizer = 2;
998   cfg_.rc_max_quantizer = 56;
999   cfg_.rc_end_usage = VPX_CBR;
1000   cfg_.g_lag_in_frames = 0;
1001   cfg_.g_threads = 2;
1002
1003   ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
1004
1005   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1006   // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
1007   // but may add more modes in the future.
1008   cfg_.rc_target_bitrate = 1000;
1009   ResetModel();
1010   // Turn on the denoiser.
1011   denoiser_on_ = 1;
1012   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1013   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1014       << " The datarate for the file is lower than target by too much!";
1015   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
1016       << " The datarate for the file is greater than target by too much!";
1017 }
1018
1019 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
1020 // for 1280x720 clip with 4 threads.
1021 TEST_P(DatarateTestVP9LargeDenoiser, 4threads) {
1022   cfg_.rc_buf_initial_sz = 500;
1023   cfg_.rc_buf_optimal_sz = 500;
1024   cfg_.rc_buf_sz = 1000;
1025   cfg_.rc_dropframe_thresh = 1;
1026   cfg_.rc_min_quantizer = 2;
1027   cfg_.rc_max_quantizer = 56;
1028   cfg_.rc_end_usage = VPX_CBR;
1029   cfg_.g_lag_in_frames = 0;
1030   cfg_.g_threads = 4;
1031
1032   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1033
1034   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1035   // there is only one denoiser mode: denoiserYonly(which is 1),
1036   // but may add more modes in the future.
1037   cfg_.rc_target_bitrate = 1000;
1038   ResetModel();
1039   // Turn on the denoiser.
1040   denoiser_on_ = 1;
1041   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1042   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1043       << " The datarate for the file is lower than target by too much!";
1044   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
1045       << " The datarate for the file is greater than target by too much!";
1046 }
1047
1048 // Check basic datarate targeting, for a single bitrate, when denoiser is off
1049 // and on.
1050 TEST_P(DatarateTestVP9LargeDenoiser, DenoiserOffOn) {
1051   cfg_.rc_buf_initial_sz = 500;
1052   cfg_.rc_buf_optimal_sz = 500;
1053   cfg_.rc_buf_sz = 1000;
1054   cfg_.rc_dropframe_thresh = 1;
1055   cfg_.rc_min_quantizer = 2;
1056   cfg_.rc_max_quantizer = 56;
1057   cfg_.rc_end_usage = VPX_CBR;
1058   cfg_.g_lag_in_frames = 0;
1059
1060   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1061                                        30, 1, 0, 299);
1062
1063   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
1064   // there is only one denoiser mode: denoiserYonly(which is 1),
1065   // but may add more modes in the future.
1066   cfg_.rc_target_bitrate = 300;
1067   ResetModel();
1068   // The denoiser is off by default.
1069   denoiser_on_ = 0;
1070   // Set the offon test flag.
1071   denoiser_offon_test_ = 1;
1072   denoiser_offon_period_ = 100;
1073   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1074   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
1075       << " The datarate for the file is lower than target by too much!";
1076   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
1077       << " The datarate for the file is greater than target by too much!";
1078 }
1079 #endif  // CONFIG_VP9_TEMPORAL_DENOISING
1080
1081 class DatarateOnePassCbrSvc
1082     : public ::libvpx_test::EncoderTest,
1083       public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
1084  public:
1085   DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
1086     memset(&svc_params_, 0, sizeof(svc_params_));
1087   }
1088   virtual ~DatarateOnePassCbrSvc() {}
1089
1090  protected:
1091   virtual void SetUp() {
1092     InitializeConfig();
1093     SetMode(GET_PARAM(1));
1094     speed_setting_ = GET_PARAM(2);
1095     ResetModel();
1096   }
1097   virtual void ResetModel() {
1098     last_pts_ = 0;
1099     bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
1100     frame_number_ = 0;
1101     first_drop_ = 0;
1102     bits_total_ = 0;
1103     duration_ = 0.0;
1104     mismatch_psnr_ = 0.0;
1105     mismatch_nframes_ = 0;
1106     denoiser_on_ = 0;
1107     tune_content_ = 0;
1108     base_speed_setting_ = 5;
1109   }
1110   virtual void BeginPassHook(unsigned int /*pass*/) {}
1111   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
1112                                   ::libvpx_test::Encoder *encoder) {
1113     if (video->frame() == 0) {
1114       int i;
1115       for (i = 0; i < VPX_MAX_LAYERS; ++i) {
1116         svc_params_.max_quantizers[i] = 63;
1117         svc_params_.min_quantizers[i] = 0;
1118       }
1119       svc_params_.speed_per_layer[0] = base_speed_setting_;
1120       for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
1121         svc_params_.speed_per_layer[i] = speed_setting_;
1122       }
1123
1124       encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
1125       encoder->Control(VP9E_SET_SVC, 1);
1126       encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
1127       encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
1128       encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
1129       encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
1130       encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
1131       encoder->Control(VP9E_SET_ROW_MT, 1);
1132       encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
1133       encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
1134     }
1135     const vpx_rational_t tb = video->timebase();
1136     timebase_ = static_cast<double>(tb.num) / tb.den;
1137     duration_ = 0;
1138   }
1139   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
1140     vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
1141     if (last_pts_ == 0) duration = 1;
1142     bits_in_buffer_model_ += static_cast<int64_t>(
1143         duration * timebase_ * cfg_.rc_target_bitrate * 1000);
1144     const bool key_frame =
1145         (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
1146     if (!key_frame) {
1147       // TODO(marpan): This check currently fails for some of the SVC tests,
1148       // re-enable when issue (webm:1350) is resolved.
1149       //  ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
1150       //                                      << pkt->data.frame.pts;
1151     }
1152     const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
1153     bits_in_buffer_model_ -= static_cast<int64_t>(frame_size_in_bits);
1154     bits_total_ += frame_size_in_bits;
1155     if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
1156     last_pts_ = pkt->data.frame.pts;
1157     bits_in_last_frame_ = frame_size_in_bits;
1158     ++frame_number_;
1159   }
1160   virtual void EndPassHook(void) {
1161     if (bits_total_) {
1162       const double file_size_in_kb = bits_total_ / 1000.;  // bits per kilobit
1163       duration_ = (last_pts_ + 1) * timebase_;
1164       file_datarate_ = file_size_in_kb / duration_;
1165     }
1166   }
1167
1168   virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
1169     double mismatch_psnr = compute_psnr(img1, img2);
1170     mismatch_psnr_ += mismatch_psnr;
1171     ++mismatch_nframes_;
1172   }
1173
1174   unsigned int GetMismatchFrames() { return mismatch_nframes_; }
1175
1176   vpx_codec_pts_t last_pts_;
1177   int64_t bits_in_buffer_model_;
1178   double timebase_;
1179   int frame_number_;
1180   vpx_codec_pts_t first_drop_;
1181   int64_t bits_total_;
1182   double duration_;
1183   double file_datarate_;
1184   size_t bits_in_last_frame_;
1185   vpx_svc_extra_cfg_t svc_params_;
1186   int speed_setting_;
1187   double mismatch_psnr_;
1188   int mismatch_nframes_;
1189   int denoiser_on_;
1190   int tune_content_;
1191   int base_speed_setting_;
1192 };
1193 static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
1194                                   const vpx_svc_extra_cfg_t *svc_params,
1195                                   int spatial_layers, int temporal_layers,
1196                                   int temporal_layering_mode) {
1197   int sl, spatial_layer_target;
1198   float total = 0;
1199   float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
1200   for (sl = 0; sl < spatial_layers; ++sl) {
1201     if (svc_params->scaling_factor_den[sl] > 0) {
1202       alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
1203                                 svc_params->scaling_factor_den[sl]);
1204       total += alloc_ratio[sl];
1205     }
1206   }
1207   for (sl = 0; sl < spatial_layers; ++sl) {
1208     enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
1209         (unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
1210     const int index = sl * temporal_layers;
1211     if (temporal_layering_mode == 3) {
1212       enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
1213       enc_cfg->layer_target_bitrate[index + 1] =
1214           (spatial_layer_target >> 1) + (spatial_layer_target >> 2);
1215       enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
1216     } else if (temporal_layering_mode == 2) {
1217       enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
1218       enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
1219     }
1220   }
1221 }
1222
1223 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
1224 // temporal layer, with screen content mode on and same speed setting for all
1225 // layers.
1226 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TLScreenContent1) {
1227   cfg_.rc_buf_initial_sz = 500;
1228   cfg_.rc_buf_optimal_sz = 500;
1229   cfg_.rc_buf_sz = 1000;
1230   cfg_.rc_min_quantizer = 0;
1231   cfg_.rc_max_quantizer = 63;
1232   cfg_.rc_end_usage = VPX_CBR;
1233   cfg_.g_lag_in_frames = 0;
1234   cfg_.ss_number_layers = 2;
1235   cfg_.ts_number_layers = 1;
1236   cfg_.ts_rate_decimator[0] = 1;
1237   cfg_.g_error_resilient = 1;
1238   cfg_.g_threads = 1;
1239   cfg_.temporal_layering_mode = 0;
1240   svc_params_.scaling_factor_num[0] = 144;
1241   svc_params_.scaling_factor_den[0] = 288;
1242   svc_params_.scaling_factor_num[1] = 288;
1243   svc_params_.scaling_factor_den[1] = 288;
1244   cfg_.rc_dropframe_thresh = 10;
1245   cfg_.kf_max_dist = 9999;
1246   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1247   cfg_.rc_target_bitrate = 500;
1248   ResetModel();
1249   tune_content_ = 1;
1250   base_speed_setting_ = speed_setting_;
1251   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1252                         cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1253   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1254   EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
1255 }
1256
1257 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1258 // 3 temporal layers. Run CIF clip with 1 thread.
1259 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL) {
1260   cfg_.rc_buf_initial_sz = 500;
1261   cfg_.rc_buf_optimal_sz = 500;
1262   cfg_.rc_buf_sz = 1000;
1263   cfg_.rc_min_quantizer = 0;
1264   cfg_.rc_max_quantizer = 63;
1265   cfg_.rc_end_usage = VPX_CBR;
1266   cfg_.g_lag_in_frames = 0;
1267   cfg_.ss_number_layers = 2;
1268   cfg_.ts_number_layers = 3;
1269   cfg_.ts_rate_decimator[0] = 4;
1270   cfg_.ts_rate_decimator[1] = 2;
1271   cfg_.ts_rate_decimator[2] = 1;
1272   cfg_.g_error_resilient = 1;
1273   cfg_.g_threads = 1;
1274   cfg_.temporal_layering_mode = 3;
1275   svc_params_.scaling_factor_num[0] = 144;
1276   svc_params_.scaling_factor_den[0] = 288;
1277   svc_params_.scaling_factor_num[1] = 288;
1278   svc_params_.scaling_factor_den[1] = 288;
1279   cfg_.rc_dropframe_thresh = 0;
1280   cfg_.kf_max_dist = 9999;
1281   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1282                                        30, 1, 0, 200);
1283   // TODO(marpan): Check that effective_datarate for each layer hits the
1284   // layer target_bitrate.
1285   for (int i = 200; i <= 800; i += 200) {
1286     cfg_.rc_target_bitrate = i;
1287     ResetModel();
1288     assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1289                           cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1290     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1291     ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1292         << " The datarate for the file exceeds the target by too much!";
1293     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1294         << " The datarate for the file is lower than the target by too much!";
1295 #if CONFIG_VP9_DECODER
1296     // Number of temporal layers > 1, so half of the frames in this SVC pattern
1297     // will be non-reference frame and hence encoder will avoid loopfilter.
1298     // Since frame dropper is off, we can expcet 100 (half of the sequence)
1299     // mismatched frames.
1300     EXPECT_EQ(static_cast<unsigned int>(100), GetMismatchFrames());
1301 #endif
1302   }
1303 }
1304
1305 // Check basic rate targeting for 1 pass CBR SVC with denoising.
1306 // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
1307 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TLDenoiserOn) {
1308   cfg_.rc_buf_initial_sz = 500;
1309   cfg_.rc_buf_optimal_sz = 500;
1310   cfg_.rc_buf_sz = 1000;
1311   cfg_.rc_min_quantizer = 0;
1312   cfg_.rc_max_quantizer = 63;
1313   cfg_.rc_end_usage = VPX_CBR;
1314   cfg_.g_lag_in_frames = 0;
1315   cfg_.ss_number_layers = 2;
1316   cfg_.ts_number_layers = 3;
1317   cfg_.ts_rate_decimator[0] = 4;
1318   cfg_.ts_rate_decimator[1] = 2;
1319   cfg_.ts_rate_decimator[2] = 1;
1320   cfg_.g_error_resilient = 1;
1321   cfg_.g_threads = 2;
1322   cfg_.temporal_layering_mode = 3;
1323   svc_params_.scaling_factor_num[0] = 144;
1324   svc_params_.scaling_factor_den[0] = 288;
1325   svc_params_.scaling_factor_num[1] = 288;
1326   svc_params_.scaling_factor_den[1] = 288;
1327   cfg_.rc_dropframe_thresh = 0;
1328   cfg_.kf_max_dist = 9999;
1329   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1330   // TODO(marpan): Check that effective_datarate for each layer hits the
1331   // layer target_bitrate.
1332   for (int i = 600; i <= 1000; i += 200) {
1333     cfg_.rc_target_bitrate = i;
1334     ResetModel();
1335     denoiser_on_ = 1;
1336     assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1337                           cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1338     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1339     ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1340         << " The datarate for the file exceeds the target by too much!";
1341     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1342         << " The datarate for the file is lower than the target by too much!";
1343 #if CONFIG_VP9_DECODER
1344     // Number of temporal layers > 1, so half of the frames in this SVC pattern
1345     // will be non-reference frame and hence encoder will avoid loopfilter.
1346     // Since frame dropper is off, we can expcet 150 (half of the sequence)
1347     // mismatched frames.
1348     EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1349 #endif
1350   }
1351 }
1352
1353 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
1354 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1355 TEST_P(DatarateOnePassCbrSvc, DISABLED_OnePassCbrSvc2SL3TLSmallKf) {
1356   cfg_.rc_buf_initial_sz = 500;
1357   cfg_.rc_buf_optimal_sz = 500;
1358   cfg_.rc_buf_sz = 1000;
1359   cfg_.rc_min_quantizer = 0;
1360   cfg_.rc_max_quantizer = 63;
1361   cfg_.rc_end_usage = VPX_CBR;
1362   cfg_.g_lag_in_frames = 0;
1363   cfg_.ss_number_layers = 2;
1364   cfg_.ts_number_layers = 3;
1365   cfg_.ts_rate_decimator[0] = 4;
1366   cfg_.ts_rate_decimator[1] = 2;
1367   cfg_.ts_rate_decimator[2] = 1;
1368   cfg_.g_error_resilient = 1;
1369   cfg_.g_threads = 1;
1370   cfg_.temporal_layering_mode = 3;
1371   svc_params_.scaling_factor_num[0] = 144;
1372   svc_params_.scaling_factor_den[0] = 288;
1373   svc_params_.scaling_factor_num[1] = 288;
1374   svc_params_.scaling_factor_den[1] = 288;
1375   cfg_.rc_dropframe_thresh = 10;
1376   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1377                                        30, 1, 0, 200);
1378   cfg_.rc_target_bitrate = 400;
1379   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1380   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1381   for (int j = 64; j <= 67; j++) {
1382     cfg_.kf_max_dist = j;
1383     ResetModel();
1384     assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1385                           cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1386     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1387     ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
1388         << " The datarate for the file exceeds the target by too much!";
1389     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1390         << " The datarate for the file is lower than the target by too much!";
1391   }
1392 }
1393
1394 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1395 // 3 temporal layers. Run HD clip with 4 threads.
1396 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL3TL4threads) {
1397   cfg_.rc_buf_initial_sz = 500;
1398   cfg_.rc_buf_optimal_sz = 500;
1399   cfg_.rc_buf_sz = 1000;
1400   cfg_.rc_min_quantizer = 0;
1401   cfg_.rc_max_quantizer = 63;
1402   cfg_.rc_end_usage = VPX_CBR;
1403   cfg_.g_lag_in_frames = 0;
1404   cfg_.ss_number_layers = 2;
1405   cfg_.ts_number_layers = 3;
1406   cfg_.ts_rate_decimator[0] = 4;
1407   cfg_.ts_rate_decimator[1] = 2;
1408   cfg_.ts_rate_decimator[2] = 1;
1409   cfg_.g_error_resilient = 1;
1410   cfg_.g_threads = 4;
1411   cfg_.temporal_layering_mode = 3;
1412   svc_params_.scaling_factor_num[0] = 144;
1413   svc_params_.scaling_factor_den[0] = 288;
1414   svc_params_.scaling_factor_num[1] = 288;
1415   svc_params_.scaling_factor_den[1] = 288;
1416   cfg_.rc_dropframe_thresh = 0;
1417   cfg_.kf_max_dist = 9999;
1418   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1419   cfg_.rc_target_bitrate = 800;
1420   ResetModel();
1421   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1422                         cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1423   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1424   ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1425       << " The datarate for the file exceeds the target by too much!";
1426   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
1427       << " The datarate for the file is lower than the target by too much!";
1428 #if CONFIG_VP9_DECODER
1429   // Number of temporal layers > 1, so half of the frames in this SVC pattern
1430   // will be non-reference frame and hence encoder will avoid loopfilter.
1431   // Since frame dropper is off, we can expcet 150 (half of the sequence)
1432   // mismatched frames.
1433   EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1434 #endif
1435 }
1436
1437 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1438 // 3 temporal layers. Run CIF clip with 1 thread.
1439 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL) {
1440   cfg_.rc_buf_initial_sz = 500;
1441   cfg_.rc_buf_optimal_sz = 500;
1442   cfg_.rc_buf_sz = 1000;
1443   cfg_.rc_min_quantizer = 0;
1444   cfg_.rc_max_quantizer = 63;
1445   cfg_.rc_end_usage = VPX_CBR;
1446   cfg_.g_lag_in_frames = 0;
1447   cfg_.ss_number_layers = 3;
1448   cfg_.ts_number_layers = 3;
1449   cfg_.ts_rate_decimator[0] = 4;
1450   cfg_.ts_rate_decimator[1] = 2;
1451   cfg_.ts_rate_decimator[2] = 1;
1452   cfg_.g_error_resilient = 1;
1453   cfg_.g_threads = 1;
1454   cfg_.temporal_layering_mode = 3;
1455   svc_params_.scaling_factor_num[0] = 72;
1456   svc_params_.scaling_factor_den[0] = 288;
1457   svc_params_.scaling_factor_num[1] = 144;
1458   svc_params_.scaling_factor_den[1] = 288;
1459   svc_params_.scaling_factor_num[2] = 288;
1460   svc_params_.scaling_factor_den[2] = 288;
1461   cfg_.rc_dropframe_thresh = 0;
1462   cfg_.kf_max_dist = 9999;
1463   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1464   cfg_.rc_target_bitrate = 800;
1465   ResetModel();
1466   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1467                         cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1468   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1469   ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1470       << " The datarate for the file exceeds the target by too much!";
1471   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
1472       << " The datarate for the file is lower than the target by too much!";
1473 #if CONFIG_VP9_DECODER
1474   // Number of temporal layers > 1, so half of the frames in this SVC pattern
1475   // will be non-reference frame and hence encoder will avoid loopfilter.
1476   // Since frame dropper is off, we can expcet 150 (half of the sequence)
1477   // mismatched frames.
1478   EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1479 #endif
1480 }
1481
1482 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1483 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1484 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TLSmallKf) {
1485   cfg_.rc_buf_initial_sz = 500;
1486   cfg_.rc_buf_optimal_sz = 500;
1487   cfg_.rc_buf_sz = 1000;
1488   cfg_.rc_min_quantizer = 0;
1489   cfg_.rc_max_quantizer = 63;
1490   cfg_.rc_end_usage = VPX_CBR;
1491   cfg_.g_lag_in_frames = 0;
1492   cfg_.ss_number_layers = 3;
1493   cfg_.ts_number_layers = 3;
1494   cfg_.ts_rate_decimator[0] = 4;
1495   cfg_.ts_rate_decimator[1] = 2;
1496   cfg_.ts_rate_decimator[2] = 1;
1497   cfg_.g_error_resilient = 1;
1498   cfg_.g_threads = 1;
1499   cfg_.temporal_layering_mode = 3;
1500   svc_params_.scaling_factor_num[0] = 72;
1501   svc_params_.scaling_factor_den[0] = 288;
1502   svc_params_.scaling_factor_num[1] = 144;
1503   svc_params_.scaling_factor_den[1] = 288;
1504   svc_params_.scaling_factor_num[2] = 288;
1505   svc_params_.scaling_factor_den[2] = 288;
1506   cfg_.rc_dropframe_thresh = 10;
1507   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1508   cfg_.rc_target_bitrate = 800;
1509   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1510   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1511   for (int j = 32; j <= 35; j++) {
1512     cfg_.kf_max_dist = j;
1513     ResetModel();
1514     assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1515                           cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1516     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1517     ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.80)
1518         << " The datarate for the file exceeds the target by too much!";
1519     ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
1520         << " The datarate for the file is lower than the target by too much!";
1521   }
1522 }
1523
1524 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1525 // 3 temporal layers. Run HD clip with 4 threads.
1526 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SL3TL4threads) {
1527   cfg_.rc_buf_initial_sz = 500;
1528   cfg_.rc_buf_optimal_sz = 500;
1529   cfg_.rc_buf_sz = 1000;
1530   cfg_.rc_min_quantizer = 0;
1531   cfg_.rc_max_quantizer = 63;
1532   cfg_.rc_end_usage = VPX_CBR;
1533   cfg_.g_lag_in_frames = 0;
1534   cfg_.ss_number_layers = 3;
1535   cfg_.ts_number_layers = 3;
1536   cfg_.ts_rate_decimator[0] = 4;
1537   cfg_.ts_rate_decimator[1] = 2;
1538   cfg_.ts_rate_decimator[2] = 1;
1539   cfg_.g_error_resilient = 1;
1540   cfg_.g_threads = 4;
1541   cfg_.temporal_layering_mode = 3;
1542   svc_params_.scaling_factor_num[0] = 72;
1543   svc_params_.scaling_factor_den[0] = 288;
1544   svc_params_.scaling_factor_num[1] = 144;
1545   svc_params_.scaling_factor_den[1] = 288;
1546   svc_params_.scaling_factor_num[2] = 288;
1547   svc_params_.scaling_factor_den[2] = 288;
1548   cfg_.rc_dropframe_thresh = 0;
1549   cfg_.kf_max_dist = 9999;
1550   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1551   cfg_.rc_target_bitrate = 800;
1552   ResetModel();
1553   assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
1554                         cfg_.ts_number_layers, cfg_.temporal_layering_mode);
1555   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1556   ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.78)
1557       << " The datarate for the file exceeds the target by too much!";
1558   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
1559       << " The datarate for the file is lower than the target by too much!";
1560 #if CONFIG_VP9_DECODER
1561   // Number of temporal layers > 1, so half of the frames in this SVC pattern
1562   // will be non-reference frame and hence encoder will avoid loopfilter.
1563   // Since frame dropper is off, we can expcet 150 (half of the sequence)
1564   // mismatched frames.
1565   EXPECT_EQ(static_cast<unsigned int>(150), GetMismatchFrames());
1566 #endif
1567 }
1568
1569 // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
1570 // downscale 5x5.
1571 TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
1572   cfg_.rc_buf_initial_sz = 500;
1573   cfg_.rc_buf_optimal_sz = 500;
1574   cfg_.rc_buf_sz = 1000;
1575   cfg_.rc_min_quantizer = 0;
1576   cfg_.rc_max_quantizer = 63;
1577   cfg_.rc_end_usage = VPX_CBR;
1578   cfg_.g_lag_in_frames = 0;
1579   cfg_.ss_number_layers = 2;
1580   cfg_.ts_number_layers = 1;
1581   cfg_.ts_rate_decimator[0] = 1;
1582   cfg_.g_error_resilient = 1;
1583   cfg_.g_threads = 3;
1584   cfg_.temporal_layering_mode = 0;
1585   svc_params_.scaling_factor_num[0] = 256;
1586   svc_params_.scaling_factor_den[0] = 1280;
1587   svc_params_.scaling_factor_num[1] = 1280;
1588   svc_params_.scaling_factor_den[1] = 1280;
1589   cfg_.rc_dropframe_thresh = 10;
1590   cfg_.kf_max_dist = 999999;
1591   cfg_.kf_min_dist = 0;
1592   cfg_.ss_target_bitrate[0] = 300;
1593   cfg_.ss_target_bitrate[1] = 1400;
1594   cfg_.layer_target_bitrate[0] = 300;
1595   cfg_.layer_target_bitrate[1] = 1400;
1596   cfg_.rc_target_bitrate = 1700;
1597   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
1598   ResetModel();
1599   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1600   EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
1601 }
1602
1603 VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES,
1604                           ::testing::Values(0));
1605 VP8_INSTANTIATE_TEST_CASE(DatarateTestRealTime,
1606                           ::testing::Values(::libvpx_test::kRealTime),
1607                           ::testing::Values(-6, -12));
1608 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
1609                           ::testing::Values(::libvpx_test::kOnePassGood,
1610                                             ::libvpx_test::kRealTime),
1611                           ::testing::Range(2, 9));
1612 #if CONFIG_VP9_TEMPORAL_DENOISING
1613 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeDenoiser,
1614                           ::testing::Values(::libvpx_test::kRealTime),
1615                           ::testing::Range(5, 9));
1616 #endif
1617 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
1618                           ::testing::Values(::libvpx_test::kRealTime),
1619                           ::testing::Range(5, 9));
1620 }  // namespace