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