vp9[loongarch]: Optimize fdct4x4/8x8_lsx
[platform/upstream/libvpx.git] / test / vp9_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 #include "vpx_ports/bitops.h"
19
20 namespace {
21
22 class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
23  public:
24   explicit DatarateTestVP9(const ::libvpx_test::CodecFactory *codec)
25       : EncoderTest(codec) {
26     tune_content_ = 0;
27   }
28
29  protected:
30   virtual ~DatarateTestVP9() {}
31
32   virtual void ResetModel() {
33     last_pts_ = 0;
34     bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
35     frame_number_ = 0;
36     tot_frame_number_ = 0;
37     first_drop_ = 0;
38     num_drops_ = 0;
39     aq_mode_ = 3;
40     // Denoiser is off by default.
41     denoiser_on_ = 0;
42     // For testing up to 3 layers.
43     for (int i = 0; i < 3; ++i) {
44       bits_total_[i] = 0;
45     }
46     denoiser_offon_test_ = 0;
47     denoiser_offon_period_ = -1;
48     frame_parallel_decoding_mode_ = 1;
49     delta_q_uv_ = 0;
50     use_roi_ = false;
51   }
52
53   //
54   // Frame flags and layer id for temporal layers.
55   //
56
57   // For two layers, test pattern is:
58   //   1     3
59   // 0    2     .....
60   // For three layers, test pattern is:
61   //   1      3    5      7
62   //      2           6
63   // 0          4            ....
64   // LAST is always update on base/layer 0, GOLDEN is updated on layer 1.
65   // For this 3 layer example, the 2nd enhancement layer (layer 2) updates
66   // the altref frame.
67   static int GetFrameFlags(int frame_num, int num_temp_layers) {
68     int frame_flags = 0;
69     if (num_temp_layers == 2) {
70       if (frame_num % 2 == 0) {
71         // Layer 0: predict from L and ARF, update L.
72         frame_flags =
73             VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
74       } else {
75         // Layer 1: predict from L, G and ARF, and update G.
76         frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
77                       VP8_EFLAG_NO_UPD_ENTROPY;
78       }
79     } else if (num_temp_layers == 3) {
80       if (frame_num % 4 == 0) {
81         // Layer 0: predict from L and ARF; update L.
82         frame_flags =
83             VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
84       } else if ((frame_num - 2) % 4 == 0) {
85         // Layer 1: predict from L, G, ARF; update G.
86         frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
87       } else if ((frame_num - 1) % 2 == 0) {
88         // Layer 2: predict from L, G, ARF; update ARF.
89         frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
90       }
91     }
92     return frame_flags;
93   }
94
95   static int SetLayerId(int frame_num, int num_temp_layers) {
96     int layer_id = 0;
97     if (num_temp_layers == 2) {
98       if (frame_num % 2 == 0) {
99         layer_id = 0;
100       } else {
101         layer_id = 1;
102       }
103     } else if (num_temp_layers == 3) {
104       if (frame_num % 4 == 0) {
105         layer_id = 0;
106       } else if ((frame_num - 2) % 4 == 0) {
107         layer_id = 1;
108       } else if ((frame_num - 1) % 2 == 0) {
109         layer_id = 2;
110       }
111     }
112     return layer_id;
113   }
114
115   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
116                                   ::libvpx_test::Encoder *encoder) {
117     if (video->frame() == 0) {
118       encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
119       encoder->Control(VP9E_SET_AQ_MODE, aq_mode_);
120       encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
121     }
122
123     if (denoiser_offon_test_) {
124       ASSERT_GT(denoiser_offon_period_, 0)
125           << "denoiser_offon_period_ is not positive.";
126       if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
127         // Flip denoiser_on_ periodically
128         denoiser_on_ ^= 1;
129       }
130     }
131
132     encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
133     encoder->Control(VP9E_SET_TILE_COLUMNS, get_msb(cfg_.g_threads));
134     encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
135                      frame_parallel_decoding_mode_);
136
137     if (use_roi_) {
138       encoder->Control(VP9E_SET_ROI_MAP, &roi_);
139       encoder->Control(VP9E_SET_AQ_MODE, 0);
140     }
141
142     if (delta_q_uv_ != 0) {
143       encoder->Control(VP9E_SET_DELTA_Q_UV, delta_q_uv_);
144     }
145
146     if (cfg_.ts_number_layers > 1) {
147       if (video->frame() == 0) {
148         encoder->Control(VP9E_SET_SVC, 1);
149       }
150       vpx_svc_layer_id_t layer_id;
151       layer_id.spatial_layer_id = 0;
152       frame_flags_ = GetFrameFlags(video->frame(), cfg_.ts_number_layers);
153       layer_id.temporal_layer_id =
154           SetLayerId(video->frame(), cfg_.ts_number_layers);
155       layer_id.temporal_layer_id_per_spatial[0] =
156           SetLayerId(video->frame(), cfg_.ts_number_layers);
157       encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
158     }
159     const vpx_rational_t tb = video->timebase();
160     timebase_ = static_cast<double>(tb.num) / tb.den;
161     duration_ = 0;
162   }
163
164   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
165     // Time since last timestamp = duration.
166     vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
167
168     if (duration > 1) {
169       // If first drop not set and we have a drop set it to this time.
170       if (!first_drop_) first_drop_ = last_pts_ + 1;
171       // Update the number of frame drops.
172       num_drops_ += static_cast<int>(duration - 1);
173       // Update counter for total number of frames (#frames input to encoder).
174       // Needed for setting the proper layer_id below.
175       tot_frame_number_ += static_cast<int>(duration - 1);
176     }
177
178     int layer = SetLayerId(tot_frame_number_, cfg_.ts_number_layers);
179
180     // Add to the buffer the bits we'd expect from a constant bitrate server.
181     bits_in_buffer_model_ += static_cast<int64_t>(
182         duration * timebase_ * cfg_.rc_target_bitrate * 1000);
183
184     // Buffer should not go negative.
185     ASSERT_GE(bits_in_buffer_model_, 0)
186         << "Buffer Underrun at frame " << pkt->data.frame.pts;
187
188     const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
189
190     // Update the total encoded bits. For temporal layers, update the cumulative
191     // encoded bits per layer.
192     for (int i = layer; i < static_cast<int>(cfg_.ts_number_layers); ++i) {
193       bits_total_[i] += frame_size_in_bits;
194     }
195
196     // Update the most recent pts.
197     last_pts_ = pkt->data.frame.pts;
198     ++frame_number_;
199     ++tot_frame_number_;
200   }
201
202   virtual void EndPassHook(void) {
203     for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
204          ++layer) {
205       duration_ = (last_pts_ + 1) * timebase_;
206       if (bits_total_[layer]) {
207         // Effective file datarate:
208         effective_datarate_[layer] = (bits_total_[layer] / 1000.0) / duration_;
209       }
210     }
211   }
212
213   vpx_codec_pts_t last_pts_;
214   double timebase_;
215   int tune_content_;
216   int frame_number_;      // Counter for number of non-dropped/encoded frames.
217   int tot_frame_number_;  // Counter for total number of input frames.
218   int64_t bits_total_[3];
219   double duration_;
220   double effective_datarate_[3];
221   int set_cpu_used_;
222   int64_t bits_in_buffer_model_;
223   vpx_codec_pts_t first_drop_;
224   int num_drops_;
225   int aq_mode_;
226   int denoiser_on_;
227   int denoiser_offon_test_;
228   int denoiser_offon_period_;
229   int frame_parallel_decoding_mode_;
230   int delta_q_uv_;
231   bool use_roi_;
232   vpx_roi_map_t roi_;
233 };
234
235 // Params: test mode, speed setting and index for bitrate array.
236 class DatarateTestVP9RealTimeMultiBR
237     : public DatarateTestVP9,
238       public ::libvpx_test::CodecTestWith2Params<int, int> {
239  public:
240   DatarateTestVP9RealTimeMultiBR() : DatarateTestVP9(GET_PARAM(0)) {}
241
242  protected:
243   virtual void SetUp() {
244     InitializeConfig();
245     SetMode(::libvpx_test::kRealTime);
246     set_cpu_used_ = GET_PARAM(1);
247     ResetModel();
248   }
249 };
250
251 // Params: speed setting and index for bitrate array.
252 class DatarateTestVP9LargeVBR
253     : public DatarateTestVP9,
254       public ::libvpx_test::CodecTestWith2Params<int, int> {
255  public:
256   DatarateTestVP9LargeVBR() : DatarateTestVP9(GET_PARAM(0)) {}
257
258  protected:
259   virtual void SetUp() {
260     InitializeConfig();
261     SetMode(::libvpx_test::kRealTime);
262     set_cpu_used_ = GET_PARAM(1);
263     ResetModel();
264   }
265 };
266
267 // Check basic rate targeting for VBR mode with 0 lag.
268 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagZero) {
269   cfg_.rc_min_quantizer = 0;
270   cfg_.rc_max_quantizer = 63;
271   cfg_.g_error_resilient = 0;
272   cfg_.rc_end_usage = VPX_VBR;
273   cfg_.g_lag_in_frames = 0;
274
275   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
276                                        30, 1, 0, 300);
277
278   const int bitrates[2] = { 400, 800 };
279   const int bitrate_index = GET_PARAM(2);
280   cfg_.rc_target_bitrate = bitrates[bitrate_index];
281   ResetModel();
282   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
283   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
284       << " The datarate for the file is lower than target by too much!";
285   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.36)
286       << " The datarate for the file is greater than target by too much!";
287 }
288
289 // Check basic rate targeting for VBR mode with non-zero lag.
290 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZero) {
291   cfg_.rc_min_quantizer = 0;
292   cfg_.rc_max_quantizer = 63;
293   cfg_.g_error_resilient = 0;
294   cfg_.rc_end_usage = VPX_VBR;
295   // For non-zero lag, rate control will work (be within bounds) for
296   // real-time mode.
297   if (deadline_ == VPX_DL_REALTIME) {
298     cfg_.g_lag_in_frames = 15;
299   } else {
300     cfg_.g_lag_in_frames = 0;
301   }
302
303   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
304                                        30, 1, 0, 300);
305   const int bitrates[2] = { 400, 800 };
306   const int bitrate_index = GET_PARAM(2);
307   cfg_.rc_target_bitrate = bitrates[bitrate_index];
308   ResetModel();
309   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
310   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
311       << " The datarate for the file is lower than target by too much!";
312   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
313       << " The datarate for the file is greater than target by too much!";
314 }
315
316 // Check basic rate targeting for VBR mode with non-zero lag, with
317 // frame_parallel_decoding_mode off. This enables the adapt_coeff/mode/mv probs
318 // since error_resilience is off.
319 TEST_P(DatarateTestVP9LargeVBR, BasicRateTargetingVBRLagNonZeroFrameParDecOff) {
320   cfg_.rc_min_quantizer = 0;
321   cfg_.rc_max_quantizer = 63;
322   cfg_.g_error_resilient = 0;
323   cfg_.rc_end_usage = VPX_VBR;
324   // For non-zero lag, rate control will work (be within bounds) for
325   // real-time mode.
326   if (deadline_ == VPX_DL_REALTIME) {
327     cfg_.g_lag_in_frames = 15;
328   } else {
329     cfg_.g_lag_in_frames = 0;
330   }
331
332   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
333                                        30, 1, 0, 300);
334   const int bitrates[2] = { 400, 800 };
335   const int bitrate_index = GET_PARAM(2);
336   cfg_.rc_target_bitrate = bitrates[bitrate_index];
337   ResetModel();
338   frame_parallel_decoding_mode_ = 0;
339   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
340   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
341       << " The datarate for the file is lower than target by too much!";
342   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.35)
343       << " The datarate for the file is greater than target by too much!";
344 }
345
346 // Check basic rate targeting for CBR mode.
347 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting) {
348   cfg_.rc_buf_initial_sz = 500;
349   cfg_.rc_buf_optimal_sz = 500;
350   cfg_.rc_buf_sz = 1000;
351   cfg_.rc_dropframe_thresh = 1;
352   cfg_.rc_min_quantizer = 0;
353   cfg_.rc_max_quantizer = 63;
354   cfg_.rc_end_usage = VPX_CBR;
355   cfg_.g_lag_in_frames = 0;
356
357   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
358                                        0, 400);
359   const int bitrates[4] = { 150, 350, 550, 750 };
360   const int bitrate_index = GET_PARAM(2);
361   cfg_.rc_target_bitrate = bitrates[bitrate_index];
362   ResetModel();
363   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
364   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
365       << " The datarate for the file is lower than target by too much!";
366   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
367       << " The datarate for the file is greater than target by too much!";
368 }
369
370 // Check basic rate targeting for CBR mode, with frame_parallel_decoding_mode
371 // off( and error_resilience off).
372 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargetingFrameParDecOff) {
373   cfg_.rc_buf_initial_sz = 500;
374   cfg_.rc_buf_optimal_sz = 500;
375   cfg_.rc_buf_sz = 1000;
376   cfg_.rc_dropframe_thresh = 1;
377   cfg_.rc_min_quantizer = 0;
378   cfg_.rc_max_quantizer = 63;
379   cfg_.rc_end_usage = VPX_CBR;
380   cfg_.g_lag_in_frames = 0;
381   cfg_.g_error_resilient = 0;
382
383   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
384                                        0, 400);
385   const int bitrates[4] = { 150, 350, 550, 750 };
386   const int bitrate_index = GET_PARAM(2);
387   cfg_.rc_target_bitrate = bitrates[bitrate_index];
388   ResetModel();
389   frame_parallel_decoding_mode_ = 0;
390   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
391   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
392       << " The datarate for the file is lower than target by too much!";
393   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
394       << " The datarate for the file is greater than target by too much!";
395 }
396
397 // Check basic rate targeting for CBR.
398 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting444) {
399   ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
400
401   cfg_.g_profile = 1;
402   cfg_.g_timebase = video.timebase();
403
404   cfg_.rc_buf_initial_sz = 500;
405   cfg_.rc_buf_optimal_sz = 500;
406   cfg_.rc_buf_sz = 1000;
407   cfg_.rc_dropframe_thresh = 1;
408   cfg_.rc_min_quantizer = 0;
409   cfg_.rc_max_quantizer = 63;
410   cfg_.rc_end_usage = VPX_CBR;
411   const int bitrates[4] = { 250, 450, 650, 850 };
412   const int bitrate_index = GET_PARAM(2);
413   cfg_.rc_target_bitrate = bitrates[bitrate_index];
414   ResetModel();
415   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
416   ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
417             effective_datarate_[0] * 0.80)
418       << " The datarate for the file exceeds the target by too much!";
419   ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
420             effective_datarate_[0] * 1.15)
421       << " The datarate for the file missed the target!"
422       << cfg_.rc_target_bitrate << " " << effective_datarate_;
423 }
424
425 // Check that (1) the first dropped frame gets earlier and earlier
426 // as the drop frame threshold is increased, and (2) that the total number of
427 // frame drops does not decrease as we increase frame drop threshold.
428 // Use a lower qp-max to force some frame drops.
429 TEST_P(DatarateTestVP9RealTimeMultiBR, ChangingDropFrameThresh) {
430   cfg_.rc_buf_initial_sz = 500;
431   cfg_.rc_buf_optimal_sz = 500;
432   cfg_.rc_buf_sz = 1000;
433   cfg_.rc_undershoot_pct = 20;
434   cfg_.rc_undershoot_pct = 20;
435   cfg_.rc_dropframe_thresh = 10;
436   cfg_.rc_min_quantizer = 0;
437   cfg_.rc_max_quantizer = 50;
438   cfg_.rc_end_usage = VPX_CBR;
439   cfg_.rc_target_bitrate = 200;
440   cfg_.g_lag_in_frames = 0;
441   // TODO(marpan): Investigate datarate target failures with a smaller keyframe
442   // interval (128).
443   cfg_.kf_max_dist = 9999;
444
445   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
446                                        0, 400);
447
448   const int kDropFrameThreshTestStep = 30;
449   const int bitrates[2] = { 50, 150 };
450   const int bitrate_index = GET_PARAM(2);
451   if (bitrate_index > 1) return;
452   cfg_.rc_target_bitrate = bitrates[bitrate_index];
453   vpx_codec_pts_t last_drop = 140;
454   int last_num_drops = 0;
455   for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
456     cfg_.rc_dropframe_thresh = i;
457     ResetModel();
458     ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
459     ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
460         << " The datarate for the file is lower than target by too much!";
461     ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
462         << " The datarate for the file is greater than target by too much!";
463     ASSERT_LE(first_drop_, last_drop)
464         << " The first dropped frame for drop_thresh " << i
465         << " > first dropped frame for drop_thresh "
466         << i - kDropFrameThreshTestStep;
467     ASSERT_GE(num_drops_, last_num_drops * 0.85)
468         << " The number of dropped frames for drop_thresh " << i
469         << " < number of dropped frames for drop_thresh "
470         << i - kDropFrameThreshTestStep;
471     last_drop = first_drop_;
472     last_num_drops = num_drops_;
473   }
474 }  // namespace
475
476 // Check basic rate targeting for 2 temporal layers.
477 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting2TemporalLayers) {
478   cfg_.rc_buf_initial_sz = 500;
479   cfg_.rc_buf_optimal_sz = 500;
480   cfg_.rc_buf_sz = 1000;
481   cfg_.rc_dropframe_thresh = 1;
482   cfg_.rc_min_quantizer = 0;
483   cfg_.rc_max_quantizer = 63;
484   cfg_.rc_end_usage = VPX_CBR;
485   cfg_.g_lag_in_frames = 0;
486
487   // 2 Temporal layers, no spatial layers: Framerate decimation (2, 1).
488   cfg_.ss_number_layers = 1;
489   cfg_.ts_number_layers = 2;
490   cfg_.ts_rate_decimator[0] = 2;
491   cfg_.ts_rate_decimator[1] = 1;
492
493   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
494
495   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
496                                        0, 400);
497   const int bitrates[4] = { 200, 400, 600, 800 };
498   const int bitrate_index = GET_PARAM(2);
499   cfg_.rc_target_bitrate = bitrates[bitrate_index];
500   ResetModel();
501   // 60-40 bitrate allocation for 2 temporal layers.
502   cfg_.layer_target_bitrate[0] = 60 * cfg_.rc_target_bitrate / 100;
503   cfg_.layer_target_bitrate[1] = cfg_.rc_target_bitrate;
504   aq_mode_ = 0;
505   if (deadline_ == VPX_DL_REALTIME) {
506     aq_mode_ = 3;
507     cfg_.g_error_resilient = 1;
508   }
509   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
510   for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
511     ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
512         << " The datarate for the file is lower than target by too much, "
513            "for layer: "
514         << j;
515     ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
516         << " The datarate for the file is greater than target by too much, "
517            "for layer: "
518         << j;
519   }
520 }
521
522 // Check basic rate targeting for 3 temporal layers.
523 TEST_P(DatarateTestVP9RealTimeMultiBR, BasicRateTargeting3TemporalLayers) {
524   cfg_.rc_buf_initial_sz = 500;
525   cfg_.rc_buf_optimal_sz = 500;
526   cfg_.rc_buf_sz = 1000;
527   cfg_.rc_dropframe_thresh = 1;
528   cfg_.rc_min_quantizer = 0;
529   cfg_.rc_max_quantizer = 63;
530   cfg_.rc_end_usage = VPX_CBR;
531   cfg_.g_lag_in_frames = 0;
532
533   // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
534   cfg_.ss_number_layers = 1;
535   cfg_.ts_number_layers = 3;
536   cfg_.ts_rate_decimator[0] = 4;
537   cfg_.ts_rate_decimator[1] = 2;
538   cfg_.ts_rate_decimator[2] = 1;
539
540   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
541
542   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
543                                        0, 400);
544   const int bitrates[4] = { 200, 400, 600, 800 };
545   const int bitrate_index = GET_PARAM(2);
546   cfg_.rc_target_bitrate = bitrates[bitrate_index];
547   ResetModel();
548   // 40-20-40 bitrate allocation for 3 temporal layers.
549   cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
550   cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
551   cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
552   aq_mode_ = 0;
553   if (deadline_ == VPX_DL_REALTIME) {
554     aq_mode_ = 3;
555     cfg_.g_error_resilient = 1;
556   }
557   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
558   for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
559     // TODO(yaowu): Work out more stable rc control strategy and
560     //              Adjust the thresholds to be tighter than .75.
561     ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
562         << " The datarate for the file is lower than target by too much, "
563            "for layer: "
564         << j;
565     // TODO(yaowu): Work out more stable rc control strategy and
566     //              Adjust the thresholds to be tighter than 1.25.
567     ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
568         << " The datarate for the file is greater than target by too much, "
569            "for layer: "
570         << j;
571   }
572 }
573
574 // Params: speed setting.
575 class DatarateTestVP9RealTime : public DatarateTestVP9,
576                                 public ::libvpx_test::CodecTestWithParam<int> {
577  public:
578   DatarateTestVP9RealTime() : DatarateTestVP9(GET_PARAM(0)) {}
579   virtual ~DatarateTestVP9RealTime() {}
580
581  protected:
582   virtual void SetUp() {
583     InitializeConfig();
584     SetMode(::libvpx_test::kRealTime);
585     set_cpu_used_ = GET_PARAM(1);
586     ResetModel();
587   }
588 };
589
590 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
591 TEST_P(DatarateTestVP9RealTime, BasicRateTargetingDropFramesMultiThreads) {
592   cfg_.rc_buf_initial_sz = 500;
593   cfg_.rc_buf_optimal_sz = 500;
594   cfg_.rc_buf_sz = 1000;
595   cfg_.rc_dropframe_thresh = 30;
596   cfg_.rc_min_quantizer = 0;
597   cfg_.rc_max_quantizer = 63;
598   cfg_.rc_end_usage = VPX_CBR;
599   cfg_.g_lag_in_frames = 0;
600   // Encode using multiple threads.
601   cfg_.g_threads = 2;
602
603   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
604                                        0, 400);
605   cfg_.rc_target_bitrate = 200;
606   ResetModel();
607   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
608   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
609       << " The datarate for the file is lower than target by too much!";
610   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
611       << " The datarate for the file is greater than target by too much!";
612 }
613
614 // Check basic rate targeting for 3 temporal layers, with frame dropping.
615 // Only for one (low) bitrate with lower max_quantizer, and somewhat higher
616 // frame drop threshold, to force frame dropping.
617 TEST_P(DatarateTestVP9RealTime,
618        BasicRateTargeting3TemporalLayersFrameDropping) {
619   cfg_.rc_buf_initial_sz = 500;
620   cfg_.rc_buf_optimal_sz = 500;
621   cfg_.rc_buf_sz = 1000;
622   // Set frame drop threshold and rc_max_quantizer to force some frame drops.
623   cfg_.rc_dropframe_thresh = 20;
624   cfg_.rc_max_quantizer = 45;
625   cfg_.rc_min_quantizer = 0;
626   cfg_.rc_end_usage = VPX_CBR;
627   cfg_.g_lag_in_frames = 0;
628
629   // 3 Temporal layers, no spatial layers: Framerate decimation (4, 2, 1).
630   cfg_.ss_number_layers = 1;
631   cfg_.ts_number_layers = 3;
632   cfg_.ts_rate_decimator[0] = 4;
633   cfg_.ts_rate_decimator[1] = 2;
634   cfg_.ts_rate_decimator[2] = 1;
635
636   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
637
638   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
639                                        0, 400);
640   cfg_.rc_target_bitrate = 200;
641   ResetModel();
642   // 40-20-40 bitrate allocation for 3 temporal layers.
643   cfg_.layer_target_bitrate[0] = 40 * cfg_.rc_target_bitrate / 100;
644   cfg_.layer_target_bitrate[1] = 60 * cfg_.rc_target_bitrate / 100;
645   cfg_.layer_target_bitrate[2] = cfg_.rc_target_bitrate;
646   aq_mode_ = 0;
647   if (deadline_ == VPX_DL_REALTIME) {
648     aq_mode_ = 3;
649     cfg_.g_error_resilient = 1;
650   }
651   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
652   for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
653     ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
654         << " The datarate for the file is lower than target by too much, "
655            "for layer: "
656         << j;
657     ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.20)
658         << " The datarate for the file is greater than target by too much, "
659            "for layer: "
660         << j;
661     // Expect some frame drops in this test: for this 200 frames test,
662     // expect at least 10% and not more than 60% drops.
663     ASSERT_GE(num_drops_, 20);
664     ASSERT_LE(num_drops_, 280);
665   }
666 }
667
668 // Check VP9 region of interest feature.
669 TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
670   if (deadline_ != VPX_DL_REALTIME || set_cpu_used_ < 5) return;
671   cfg_.rc_buf_initial_sz = 500;
672   cfg_.rc_buf_optimal_sz = 500;
673   cfg_.rc_buf_sz = 1000;
674   cfg_.rc_dropframe_thresh = 0;
675   cfg_.rc_min_quantizer = 0;
676   cfg_.rc_max_quantizer = 63;
677   cfg_.rc_end_usage = VPX_CBR;
678   cfg_.g_lag_in_frames = 0;
679
680   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
681                                        0, 400);
682
683   cfg_.rc_target_bitrate = 450;
684   cfg_.g_w = 640;
685   cfg_.g_h = 480;
686
687   ResetModel();
688
689   // Set ROI parameters
690   use_roi_ = true;
691   memset(&roi_, 0, sizeof(roi_));
692
693   roi_.rows = (cfg_.g_h + 7) / 8;
694   roi_.cols = (cfg_.g_w + 7) / 8;
695
696   roi_.delta_q[1] = -20;
697   roi_.delta_lf[1] = -20;
698   memset(roi_.ref_frame, -1, sizeof(roi_.ref_frame));
699   roi_.ref_frame[1] = 1;
700
701   // Use 2 states: 1 is center square, 0 is the rest.
702   roi_.roi_map = reinterpret_cast<uint8_t *>(
703       calloc(roi_.rows * roi_.cols, sizeof(*roi_.roi_map)));
704   ASSERT_NE(roi_.roi_map, nullptr);
705
706   for (unsigned int i = 0; i < roi_.rows; ++i) {
707     for (unsigned int j = 0; j < roi_.cols; ++j) {
708       if (i > (roi_.rows >> 2) && i < ((roi_.rows * 3) >> 2) &&
709           j > (roi_.cols >> 2) && j < ((roi_.cols * 3) >> 2)) {
710         roi_.roi_map[i * roi_.cols + j] = 1;
711       }
712     }
713   }
714
715   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
716   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
717       << " The datarate for the file exceeds the target!";
718
719   ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
720       << " The datarate for the file missed the target!";
721
722   free(roi_.roi_map);
723 }
724
725 // Params: speed setting, delta q UV.
726 class DatarateTestVP9RealTimeDeltaQUV
727     : public DatarateTestVP9,
728       public ::libvpx_test::CodecTestWith2Params<int, int> {
729  public:
730   DatarateTestVP9RealTimeDeltaQUV() : DatarateTestVP9(GET_PARAM(0)) {}
731   virtual ~DatarateTestVP9RealTimeDeltaQUV() {}
732
733  protected:
734   virtual void SetUp() {
735     InitializeConfig();
736     SetMode(::libvpx_test::kRealTime);
737     set_cpu_used_ = GET_PARAM(1);
738     ResetModel();
739   }
740 };
741
742 TEST_P(DatarateTestVP9RealTimeDeltaQUV, DeltaQUV) {
743   cfg_.rc_buf_initial_sz = 500;
744   cfg_.rc_buf_optimal_sz = 500;
745   cfg_.rc_buf_sz = 1000;
746   cfg_.rc_dropframe_thresh = 0;
747   cfg_.rc_min_quantizer = 0;
748   cfg_.rc_max_quantizer = 63;
749   cfg_.rc_end_usage = VPX_CBR;
750   cfg_.g_lag_in_frames = 0;
751
752   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
753                                        0, 400);
754
755   cfg_.rc_target_bitrate = 450;
756   cfg_.g_w = 640;
757   cfg_.g_h = 480;
758
759   ResetModel();
760
761   delta_q_uv_ = GET_PARAM(2);
762
763   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
764   ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
765       << " The datarate for the file exceeds the target!";
766
767   ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
768       << " The datarate for the file missed the target!";
769 }
770
771 // Params: test mode, speed setting and index for bitrate array.
772 class DatarateTestVP9PostEncodeDrop
773     : public DatarateTestVP9,
774       public ::libvpx_test::CodecTestWithParam<int> {
775  public:
776   DatarateTestVP9PostEncodeDrop() : DatarateTestVP9(GET_PARAM(0)) {}
777
778  protected:
779   virtual void SetUp() {
780     InitializeConfig();
781     SetMode(::libvpx_test::kRealTime);
782     set_cpu_used_ = GET_PARAM(1);
783     ResetModel();
784   }
785 };
786
787 // Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
788 TEST_P(DatarateTestVP9PostEncodeDrop, PostEncodeDropScreenContent) {
789   cfg_.rc_buf_initial_sz = 500;
790   cfg_.rc_buf_optimal_sz = 500;
791   cfg_.rc_buf_sz = 1000;
792   cfg_.rc_dropframe_thresh = 30;
793   cfg_.rc_min_quantizer = 0;
794   cfg_.rc_max_quantizer = 56;
795   cfg_.rc_end_usage = VPX_CBR;
796   cfg_.g_lag_in_frames = 0;
797   // Encode using multiple threads.
798   cfg_.g_threads = 2;
799   cfg_.g_error_resilient = 0;
800   tune_content_ = 1;
801   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
802                                        30, 1, 0, 300);
803   cfg_.rc_target_bitrate = 300;
804   ResetModel();
805   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
806   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
807       << " The datarate for the file is lower than target by too much!";
808   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
809       << " The datarate for the file is greater than target by too much!";
810 }
811
812 #if CONFIG_VP9_TEMPORAL_DENOISING
813 // Params: speed setting.
814 class DatarateTestVP9RealTimeDenoiser : public DatarateTestVP9RealTime {
815  public:
816   virtual ~DatarateTestVP9RealTimeDenoiser() {}
817 };
818
819 // Check basic datarate targeting, for a single bitrate, when denoiser is on.
820 TEST_P(DatarateTestVP9RealTimeDenoiser, LowNoise) {
821   cfg_.rc_buf_initial_sz = 500;
822   cfg_.rc_buf_optimal_sz = 500;
823   cfg_.rc_buf_sz = 1000;
824   cfg_.rc_dropframe_thresh = 1;
825   cfg_.rc_min_quantizer = 2;
826   cfg_.rc_max_quantizer = 56;
827   cfg_.rc_end_usage = VPX_CBR;
828   cfg_.g_lag_in_frames = 0;
829
830   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
831                                        0, 400);
832
833   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
834   // there is only one denoiser mode: denoiserYonly(which is 1),
835   // but may add more modes in the future.
836   cfg_.rc_target_bitrate = 400;
837   ResetModel();
838   // Turn on the denoiser.
839   denoiser_on_ = 1;
840   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
841   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
842       << " The datarate for the file is lower than target by too much!";
843   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
844       << " The datarate for the file is greater than target by too much!";
845 }
846
847 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
848 // for clip with high noise level. Use 2 threads.
849 TEST_P(DatarateTestVP9RealTimeDenoiser, HighNoise) {
850   cfg_.rc_buf_initial_sz = 500;
851   cfg_.rc_buf_optimal_sz = 500;
852   cfg_.rc_buf_sz = 1000;
853   cfg_.rc_dropframe_thresh = 1;
854   cfg_.rc_min_quantizer = 2;
855   cfg_.rc_max_quantizer = 56;
856   cfg_.rc_end_usage = VPX_CBR;
857   cfg_.g_lag_in_frames = 0;
858   cfg_.g_threads = 2;
859
860   ::libvpx_test::Y4mVideoSource video("noisy_clip_640_360.y4m", 0, 200);
861
862   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
863   // there is only one denoiser mode: kDenoiserOnYOnly(which is 1),
864   // but may add more modes in the future.
865   cfg_.rc_target_bitrate = 1000;
866   ResetModel();
867   // Turn on the denoiser.
868   denoiser_on_ = 1;
869   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
870   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
871       << " The datarate for the file is lower than target by too much!";
872   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
873       << " The datarate for the file is greater than target by too much!";
874 }
875
876 // Check basic datarate targeting, for a single bitrate, when denoiser is on,
877 // for 1280x720 clip with 4 threads.
878 TEST_P(DatarateTestVP9RealTimeDenoiser, 4threads) {
879   cfg_.rc_buf_initial_sz = 500;
880   cfg_.rc_buf_optimal_sz = 500;
881   cfg_.rc_buf_sz = 1000;
882   cfg_.rc_dropframe_thresh = 1;
883   cfg_.rc_min_quantizer = 2;
884   cfg_.rc_max_quantizer = 56;
885   cfg_.rc_end_usage = VPX_CBR;
886   cfg_.g_lag_in_frames = 0;
887   cfg_.g_threads = 4;
888
889   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 300);
890
891   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
892   // there is only one denoiser mode: denoiserYonly(which is 1),
893   // but may add more modes in the future.
894   cfg_.rc_target_bitrate = 1000;
895   ResetModel();
896   // Turn on the denoiser.
897   denoiser_on_ = 1;
898   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
899   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
900       << " The datarate for the file is lower than target by too much!";
901   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.29)
902       << " The datarate for the file is greater than target by too much!";
903 }
904
905 // Check basic datarate targeting, for a single bitrate, when denoiser is off
906 // and on.
907 TEST_P(DatarateTestVP9RealTimeDenoiser, DenoiserOffOn) {
908   cfg_.rc_buf_initial_sz = 500;
909   cfg_.rc_buf_optimal_sz = 500;
910   cfg_.rc_buf_sz = 1000;
911   cfg_.rc_dropframe_thresh = 1;
912   cfg_.rc_min_quantizer = 2;
913   cfg_.rc_max_quantizer = 56;
914   cfg_.rc_end_usage = VPX_CBR;
915   cfg_.g_lag_in_frames = 0;
916
917   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
918                                        0, 400);
919
920   // For the temporal denoiser (#if CONFIG_VP9_TEMPORAL_DENOISING),
921   // there is only one denoiser mode: denoiserYonly(which is 1),
922   // but may add more modes in the future.
923   cfg_.rc_target_bitrate = 400;
924   ResetModel();
925   // The denoiser is off by default.
926   denoiser_on_ = 0;
927   // Set the offon test flag.
928   denoiser_offon_test_ = 1;
929   denoiser_offon_period_ = 100;
930   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
931   ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
932       << " The datarate for the file is lower than target by too much!";
933   ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
934       << " The datarate for the file is greater than target by too much!";
935 }
936 #endif  // CONFIG_VP9_TEMPORAL_DENOISING
937
938 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeMultiBR,
939                            ::testing::Range(5, 10), ::testing::Range(0, 4));
940
941 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9),
942                            ::testing::Range(0, 2));
943
944 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTime, ::testing::Range(5, 10));
945
946 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDeltaQUV,
947                            ::testing::Range(5, 10),
948                            ::testing::Values(-5, -10, -15));
949
950 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9PostEncodeDrop,
951                            ::testing::Range(5, 6));
952
953 #if CONFIG_VP9_TEMPORAL_DENOISING
954 VP9_INSTANTIATE_TEST_SUITE(DatarateTestVP9RealTimeDenoiser,
955                            ::testing::Range(5, 10));
956 #endif
957 }  // namespace