xref: /aosp_15_r20/external/libvpx/test/svc_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/codec_factory.h"
13 #include "test/encode_test_driver.h"
14 #include "test/i420_video_source.h"
15 #include "test/svc_test.h"
16 #include "test/util.h"
17 #include "test/y4m_video_source.h"
18 #include "vp9/common/vp9_onyxc_int.h"
19 #include "vpx/vpx_codec.h"
20 #include "vpx_ports/bitops.h"
21 
22 namespace svc_test {
23 namespace {
24 
25 typedef enum {
26   // Inter-layer prediction is on on all frames.
27   INTER_LAYER_PRED_ON,
28   // Inter-layer prediction is off on all frames.
29   INTER_LAYER_PRED_OFF,
30   // Inter-layer prediction is off on non-key frames and non-sync frames.
31   INTER_LAYER_PRED_OFF_NONKEY,
32   // Inter-layer prediction is on on all frames, but constrained such
33   // that any layer S (> 0) can only predict from previous spatial
34   // layer S-1, from the same superframe.
35   INTER_LAYER_PRED_ON_CONSTRAINED
36 } INTER_LAYER_PRED;
37 
38 class DatarateOnePassCbrSvc : public OnePassCbrSvc {
39  public:
DatarateOnePassCbrSvc(const::libvpx_test::CodecFactory * codec)40   explicit DatarateOnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
41       : OnePassCbrSvc(codec) {
42     inter_layer_pred_mode_ = 0;
43   }
44 
45  protected:
46   ~DatarateOnePassCbrSvc() override = default;
47 
ResetModel()48   virtual void ResetModel() {
49     last_pts_ = 0;
50     duration_ = 0.0;
51     mismatch_psnr_ = 0.0;
52     mismatch_nframes_ = 0;
53     denoiser_on_ = 0;
54     tune_content_ = 0;
55     base_speed_setting_ = 5;
56     spatial_layer_id_ = 0;
57     temporal_layer_id_ = 0;
58     update_pattern_ = 0;
59     memset(bits_in_buffer_model_, 0, sizeof(bits_in_buffer_model_));
60     memset(bits_total_, 0, sizeof(bits_total_));
61     memset(layer_target_avg_bandwidth_, 0, sizeof(layer_target_avg_bandwidth_));
62     dynamic_drop_layer_ = false;
63     single_layer_resize_ = false;
64     change_bitrate_ = false;
65     last_pts_ref_ = 0;
66     middle_bitrate_ = 0;
67     top_bitrate_ = 0;
68     superframe_count_ = -1;
69     key_frame_spacing_ = 9999;
70     num_nonref_frames_ = 0;
71     layer_framedrop_ = 0;
72     force_key_ = 0;
73     force_key_test_ = 0;
74     insert_layer_sync_ = 0;
75     layer_sync_on_base_ = 0;
76     force_intra_only_frame_ = 0;
77     superframe_has_intra_only_ = 0;
78     use_post_encode_drop_ = 0;
79     denoiser_off_on_ = false;
80     denoiser_enable_layers_ = false;
81     num_resize_down_ = 0;
82     num_resize_up_ = 0;
83     for (int i = 0; i < VPX_MAX_LAYERS; i++) {
84       prev_frame_width[i] = 320;
85       prev_frame_height[i] = 240;
86     }
87     ksvc_flex_noupd_tlenh_ = false;
88   }
BeginPassHook(unsigned int)89   void BeginPassHook(unsigned int /*pass*/) override {}
90 
91   // Example pattern for spatial layers and 2 temporal layers used in the
92   // bypass/flexible mode. The pattern corresponds to the pattern
93   // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
94   // non-flexible mode, except that we disable inter-layer prediction.
set_frame_flags_bypass_mode(int tl,int num_spatial_layers,int is_key_frame,vpx_svc_ref_frame_config_t * ref_frame_config,int noupdate_tlenh)95   void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
96                                    int is_key_frame,
97                                    vpx_svc_ref_frame_config_t *ref_frame_config,
98                                    int noupdate_tlenh) {
99     for (int sl = 0; sl < num_spatial_layers; ++sl)
100       ref_frame_config->update_buffer_slot[sl] = 0;
101 
102     for (int sl = 0; sl < num_spatial_layers; ++sl) {
103       if (tl == 0) {
104         ref_frame_config->lst_fb_idx[sl] = sl;
105         if (sl) {
106           if (is_key_frame) {
107             ref_frame_config->lst_fb_idx[sl] = sl - 1;
108             ref_frame_config->gld_fb_idx[sl] = sl;
109           } else {
110             ref_frame_config->gld_fb_idx[sl] = sl - 1;
111           }
112         } else {
113           ref_frame_config->gld_fb_idx[sl] = 0;
114         }
115         ref_frame_config->alt_fb_idx[sl] = 0;
116       } else if (tl == 1) {
117         ref_frame_config->lst_fb_idx[sl] = sl;
118         ref_frame_config->gld_fb_idx[sl] =
119             VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl - 1);
120         ref_frame_config->alt_fb_idx[sl] =
121             VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl);
122       }
123       if (!tl) {
124         if (!sl) {
125           ref_frame_config->reference_last[sl] = 1;
126           ref_frame_config->reference_golden[sl] = 0;
127           ref_frame_config->reference_alt_ref[sl] = 0;
128           ref_frame_config->update_buffer_slot[sl] |=
129               1 << ref_frame_config->lst_fb_idx[sl];
130         } else {
131           if (is_key_frame) {
132             ref_frame_config->reference_last[sl] = 1;
133             ref_frame_config->reference_golden[sl] = 0;
134             ref_frame_config->reference_alt_ref[sl] = 0;
135             ref_frame_config->update_buffer_slot[sl] |=
136                 1 << ref_frame_config->gld_fb_idx[sl];
137           } else {
138             ref_frame_config->reference_last[sl] = 1;
139             ref_frame_config->reference_golden[sl] = 0;
140             ref_frame_config->reference_alt_ref[sl] = 0;
141             ref_frame_config->update_buffer_slot[sl] |=
142                 1 << ref_frame_config->lst_fb_idx[sl];
143           }
144         }
145       } else if (tl == 1) {
146         if (!sl) {
147           ref_frame_config->reference_last[sl] = 1;
148           ref_frame_config->reference_golden[sl] = 0;
149           ref_frame_config->reference_alt_ref[sl] = 0;
150           ref_frame_config->update_buffer_slot[sl] |=
151               1 << ref_frame_config->alt_fb_idx[sl];
152         } else {
153           ref_frame_config->reference_last[sl] = 1;
154           ref_frame_config->reference_golden[sl] = 0;
155           ref_frame_config->reference_alt_ref[sl] = 0;
156           // Non reference frame on top temporal top spatial.
157           ref_frame_config->update_buffer_slot[sl] = 0;
158         }
159         // Force no update on all spatial layers for temporal enhancement layer
160         // frames.
161         if (noupdate_tlenh) ref_frame_config->update_buffer_slot[sl] = 0;
162       }
163     }
164   }
165 
CheckLayerRateTargeting(int num_spatial_layers,int num_temporal_layers,double thresh_overshoot,double thresh_undershoot) const166   void CheckLayerRateTargeting(int num_spatial_layers, int num_temporal_layers,
167                                double thresh_overshoot,
168                                double thresh_undershoot) const {
169     for (int sl = 0; sl < num_spatial_layers; ++sl)
170       for (int tl = 0; tl < num_temporal_layers; ++tl) {
171         const int layer = sl * num_temporal_layers + tl;
172         ASSERT_GE(cfg_.layer_target_bitrate[layer],
173                   file_datarate_[layer] * thresh_overshoot)
174             << " The datarate for the file exceeds the target by too much!";
175         ASSERT_LE(cfg_.layer_target_bitrate[layer],
176                   file_datarate_[layer] * thresh_undershoot)
177             << " The datarate for the file is lower than the target by too "
178                "much!";
179       }
180   }
181 
PreEncodeFrameHook(::libvpx_test::VideoSource * video,::libvpx_test::Encoder * encoder)182   void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
183                           ::libvpx_test::Encoder *encoder) override {
184     PreEncodeFrameHookSetup(video, encoder);
185 
186     if (video->frame() == 0) {
187       if (force_intra_only_frame_) {
188         // Decoder sets the color_space for Intra-only frames
189         // to BT_601 (see line 1810 in vp9_decodeframe.c).
190         // So set it here in these tess to avoid encoder-decoder
191         // mismatch check on color space setting.
192         encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
193       }
194       encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
195       encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
196       encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
197 
198       if (layer_framedrop_) {
199         vpx_svc_frame_drop_t svc_drop_frame;
200         svc_drop_frame.framedrop_mode = LAYER_DROP;
201         for (int i = 0; i < number_spatial_layers_; i++)
202           svc_drop_frame.framedrop_thresh[i] = 30;
203         svc_drop_frame.max_consec_drop = 30;
204         encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
205       }
206 
207       if (use_post_encode_drop_) {
208         encoder->Control(VP9E_SET_POSTENCODE_DROP, use_post_encode_drop_);
209       }
210     }
211 
212     if (denoiser_off_on_) {
213       encoder->Control(VP9E_SET_AQ_MODE, 3);
214       // Set inter_layer_pred to INTER_LAYER_PRED_OFF_NONKEY (K-SVC).
215       encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, 2);
216       if (!denoiser_enable_layers_) {
217         if (video->frame() == 0)
218           encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0);
219         else if (video->frame() == 100)
220           encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1);
221       } else {
222         // Cumulative bitrates for top spatial layers, for
223         // 3 temporal layers.
224         if (video->frame() == 0) {
225           encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0);
226           // Change layer bitrates to set top spatial layer to 0.
227           // This is for 3 spatial 3 temporal layers.
228           // This will trigger skip encoding/dropping of top spatial layer.
229           cfg_.rc_target_bitrate -= cfg_.layer_target_bitrate[8];
230           for (int i = 0; i < 3; i++)
231             bitrate_sl3_[i] = cfg_.layer_target_bitrate[i + 6];
232           cfg_.layer_target_bitrate[6] = 0;
233           cfg_.layer_target_bitrate[7] = 0;
234           cfg_.layer_target_bitrate[8] = 0;
235           encoder->Config(&cfg_);
236         } else if (video->frame() == 100) {
237           // Change layer bitrates to non-zero on top spatial layer.
238           // This will trigger skip encoding of top spatial layer
239           // on key frame (period = 100).
240           for (int i = 0; i < 3; i++)
241             cfg_.layer_target_bitrate[i + 6] = bitrate_sl3_[i];
242           cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[8];
243           encoder->Config(&cfg_);
244         } else if (video->frame() == 120) {
245           // Enable denoiser and top spatial layer after key frame (period is
246           // 100).
247           encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1);
248         }
249       }
250     }
251 
252     if (ksvc_flex_noupd_tlenh_) {
253       vpx_svc_layer_id_t layer_id;
254       layer_id.spatial_layer_id = 0;
255       layer_id.temporal_layer_id = (video->frame() % 2 != 0);
256       temporal_layer_id_ = layer_id.temporal_layer_id;
257       for (int i = 0; i < number_spatial_layers_; i++) {
258         layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_;
259         ref_frame_config_.duration[i] = 1;
260       }
261       encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
262       set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
263                                   number_spatial_layers_, 0, &ref_frame_config_,
264                                   1);
265       encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_);
266     }
267 
268     if (update_pattern_ && video->frame() >= 100) {
269       vpx_svc_layer_id_t layer_id;
270       if (video->frame() == 100) {
271         cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
272         encoder->Config(&cfg_);
273       }
274       // Set layer id since the pattern changed.
275       layer_id.spatial_layer_id = 0;
276       layer_id.temporal_layer_id = (video->frame() % 2 != 0);
277       temporal_layer_id_ = layer_id.temporal_layer_id;
278       for (int i = 0; i < number_spatial_layers_; i++) {
279         layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_;
280         ref_frame_config_.duration[i] = 1;
281       }
282       encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
283       set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
284                                   number_spatial_layers_, 0, &ref_frame_config_,
285                                   0);
286       encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config_);
287     }
288 
289     if (change_bitrate_ && video->frame() == 200) {
290       duration_ = (last_pts_ + 1) * timebase_;
291       for (int sl = 0; sl < number_spatial_layers_; ++sl) {
292         for (int tl = 0; tl < number_temporal_layers_; ++tl) {
293           const int layer = sl * number_temporal_layers_ + tl;
294           const double file_size_in_kb = bits_total_[layer] / 1000.;
295           file_datarate_[layer] = file_size_in_kb / duration_;
296         }
297       }
298 
299       CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_,
300                               0.78, 1.15);
301 
302       memset(file_datarate_, 0, sizeof(file_datarate_));
303       memset(bits_total_, 0, sizeof(bits_total_));
304       int64_t bits_in_buffer_model_tmp[VPX_MAX_LAYERS];
305       last_pts_ref_ = last_pts_;
306       // Set new target bitarate.
307       cfg_.rc_target_bitrate = cfg_.rc_target_bitrate >> 1;
308       // Buffer level should not reset on dynamic bitrate change.
309       memcpy(bits_in_buffer_model_tmp, bits_in_buffer_model_,
310              sizeof(bits_in_buffer_model_));
311       AssignLayerBitrates();
312       memcpy(bits_in_buffer_model_, bits_in_buffer_model_tmp,
313              sizeof(bits_in_buffer_model_));
314 
315       // Change config to update encoder with new bitrate configuration.
316       encoder->Config(&cfg_);
317     }
318 
319     if (dynamic_drop_layer_ && !single_layer_resize_) {
320       if (video->frame() == 0) {
321         // Change layer bitrates to set top layers to 0. This will trigger skip
322         // encoding/dropping of top two spatial layers.
323         cfg_.rc_target_bitrate -=
324             (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
325         middle_bitrate_ = cfg_.layer_target_bitrate[1];
326         top_bitrate_ = cfg_.layer_target_bitrate[2];
327         cfg_.layer_target_bitrate[1] = 0;
328         cfg_.layer_target_bitrate[2] = 0;
329         encoder->Config(&cfg_);
330       } else if (video->frame() == 50) {
331         // Change layer bitrates to non-zero on two top spatial layers.
332         // This will trigger skip encoding of top two spatial layers.
333         cfg_.layer_target_bitrate[1] = middle_bitrate_;
334         cfg_.layer_target_bitrate[2] = top_bitrate_;
335         cfg_.rc_target_bitrate +=
336             cfg_.layer_target_bitrate[2] + cfg_.layer_target_bitrate[1];
337         encoder->Config(&cfg_);
338       } else if (video->frame() == 100) {
339         // Change layer bitrates to set top layers to 0. This will trigger skip
340         // encoding/dropping of top two spatial layers.
341         cfg_.rc_target_bitrate -=
342             (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
343         middle_bitrate_ = cfg_.layer_target_bitrate[1];
344         top_bitrate_ = cfg_.layer_target_bitrate[2];
345         cfg_.layer_target_bitrate[1] = 0;
346         cfg_.layer_target_bitrate[2] = 0;
347         encoder->Config(&cfg_);
348       } else if (video->frame() == 150) {
349         // Change layer bitrate on second layer to non-zero to start
350         // encoding it again.
351         cfg_.layer_target_bitrate[1] = middle_bitrate_;
352         cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[1];
353         encoder->Config(&cfg_);
354       } else if (video->frame() == 200) {
355         // Change layer bitrate on top layer to non-zero to start
356         // encoding it again.
357         cfg_.layer_target_bitrate[2] = top_bitrate_;
358         cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[2];
359         encoder->Config(&cfg_);
360       }
361     } else if (dynamic_drop_layer_ && single_layer_resize_) {
362       // Change layer bitrates to set top layers to 0. This will trigger skip
363       // encoding/dropping of top spatial layers.
364       if (video->frame() == 2) {
365         cfg_.rc_target_bitrate -=
366             (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
367         middle_bitrate_ = cfg_.layer_target_bitrate[1];
368         top_bitrate_ = cfg_.layer_target_bitrate[2];
369         cfg_.layer_target_bitrate[1] = 0;
370         cfg_.layer_target_bitrate[2] = 0;
371         // Set spatial layer 0 to a very low bitrate to trigger resize.
372         cfg_.layer_target_bitrate[0] = 30;
373         cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0];
374         encoder->Config(&cfg_);
375       } else if (video->frame() == 100) {
376         // Set base spatial layer to very high to go back up to original size.
377         cfg_.layer_target_bitrate[0] = 400;
378         cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0];
379         encoder->Config(&cfg_);
380       }
381     } else if (!dynamic_drop_layer_ && single_layer_resize_) {
382       if (video->frame() == 2) {
383         cfg_.layer_target_bitrate[0] = 30;
384         cfg_.layer_target_bitrate[1] = 50;
385         cfg_.rc_target_bitrate =
386             (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]);
387         encoder->Config(&cfg_);
388       } else if (video->frame() == 160) {
389         cfg_.layer_target_bitrate[0] = 1500;
390         cfg_.layer_target_bitrate[1] = 2000;
391         cfg_.rc_target_bitrate =
392             (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]);
393         encoder->Config(&cfg_);
394       }
395     }
396     if (force_key_test_ && force_key_) frame_flags_ = VPX_EFLAG_FORCE_KF;
397 
398     if (insert_layer_sync_) {
399       vpx_svc_spatial_layer_sync_t svc_layer_sync;
400       svc_layer_sync.base_layer_intra_only = 0;
401       for (int i = 0; i < number_spatial_layers_; i++)
402         svc_layer_sync.spatial_layer_sync[i] = 0;
403       if (force_intra_only_frame_) {
404         superframe_has_intra_only_ = 0;
405         if (video->frame() == 0) {
406           svc_layer_sync.base_layer_intra_only = 1;
407           svc_layer_sync.spatial_layer_sync[0] = 1;
408           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
409           superframe_has_intra_only_ = 1;
410         } else if (video->frame() == 100) {
411           svc_layer_sync.base_layer_intra_only = 1;
412           svc_layer_sync.spatial_layer_sync[0] = 1;
413           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
414           superframe_has_intra_only_ = 1;
415         }
416       } else {
417         layer_sync_on_base_ = 0;
418         if (video->frame() == 150) {
419           svc_layer_sync.spatial_layer_sync[1] = 1;
420           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
421         } else if (video->frame() == 240) {
422           svc_layer_sync.spatial_layer_sync[2] = 1;
423           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
424         } else if (video->frame() == 320) {
425           svc_layer_sync.spatial_layer_sync[0] = 1;
426           layer_sync_on_base_ = 1;
427           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
428         }
429       }
430     }
431 
432     const vpx_rational_t tb = video->timebase();
433     timebase_ = static_cast<double>(tb.num) / tb.den;
434     duration_ = 0;
435   }
436 
parse_superframe_index(const uint8_t * data,size_t data_sz,uint32_t sizes[8],int * count)437   vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
438                                          uint32_t sizes[8], int *count) {
439     uint8_t marker;
440     marker = *(data + data_sz - 1);
441     *count = 0;
442     if ((marker & 0xe0) == 0xc0) {
443       const uint32_t frames = (marker & 0x7) + 1;
444       const uint32_t mag = ((marker >> 3) & 0x3) + 1;
445       const size_t index_sz = 2 + mag * frames;
446       // This chunk is marked as having a superframe index but doesn't have
447       // enough data for it, thus it's an invalid superframe index.
448       if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
449       {
450         const uint8_t marker2 = *(data + data_sz - index_sz);
451         // This chunk is marked as having a superframe index but doesn't have
452         // the matching marker byte at the front of the index therefore it's an
453         // invalid chunk.
454         if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
455       }
456       {
457         uint32_t i, j;
458         const uint8_t *x = &data[data_sz - index_sz + 1];
459         for (i = 0; i < frames; ++i) {
460           uint32_t this_sz = 0;
461 
462           for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
463           sizes[i] = this_sz;
464         }
465         *count = frames;
466       }
467     }
468     return VPX_CODEC_OK;
469   }
470 
FramePktHook(const vpx_codec_cx_pkt_t * pkt)471   void FramePktHook(const vpx_codec_cx_pkt_t *pkt) override {
472     uint32_t sizes[8] = { 0 };
473     uint32_t sizes_parsed[8] = { 0 };
474     int count = 0;
475     int num_layers_encoded = 0;
476     last_pts_ = pkt->data.frame.pts;
477     const bool key_frame =
478         (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
479     if (key_frame) {
480       // For test that inserts layer sync frames: requesting a layer_sync on
481       // the base layer must force key frame. So if any key frame occurs after
482       // first superframe it must due to layer sync on base spatial layer.
483       if (superframe_count_ > 0 && insert_layer_sync_ &&
484           !force_intra_only_frame_) {
485         ASSERT_EQ(layer_sync_on_base_, 1);
486       }
487       temporal_layer_id_ = 0;
488       superframe_count_ = 0;
489     }
490     parse_superframe_index(static_cast<const uint8_t *>(pkt->data.frame.buf),
491                            pkt->data.frame.sz, sizes_parsed, &count);
492     // Count may be less than number of spatial layers because of frame drops.
493     if (number_spatial_layers_ > 1) {
494       for (int sl = 0; sl < number_spatial_layers_; ++sl) {
495         if (pkt->data.frame.spatial_layer_encoded[sl]) {
496           sizes[sl] = sizes_parsed[num_layers_encoded];
497           num_layers_encoded++;
498         }
499       }
500     }
501     // For superframe with Intra-only count will be +1 larger
502     // because of no-show frame.
503     if (force_intra_only_frame_ && superframe_has_intra_only_)
504       ASSERT_EQ(count, num_layers_encoded + 1);
505     else
506       ASSERT_EQ(count, num_layers_encoded);
507 
508     // In the constrained frame drop mode, if a given spatial is dropped all
509     // upper layers must be dropped too.
510     if (!layer_framedrop_) {
511       int num_layers_dropped = 0;
512       for (int sl = 0; sl < number_spatial_layers_; ++sl) {
513         if (!pkt->data.frame.spatial_layer_encoded[sl]) {
514           // Check that all upper layers are dropped.
515           num_layers_dropped++;
516           for (int sl2 = sl + 1; sl2 < number_spatial_layers_; ++sl2)
517             ASSERT_EQ(pkt->data.frame.spatial_layer_encoded[sl2], 0);
518         }
519       }
520       if (num_layers_dropped == number_spatial_layers_ - 1)
521         force_key_ = 1;
522       else
523         force_key_ = 0;
524     }
525     // Keep track of number of non-reference frames, needed for mismatch check.
526     // Non-reference frames are top spatial and temporal layer frames,
527     // for TL > 0.
528     if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
529         temporal_layer_id_ > 0 &&
530         pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
531       num_nonref_frames_++;
532     for (int sl = 0; sl < number_spatial_layers_; ++sl) {
533       sizes[sl] = sizes[sl] << 3;
534       // Update the total encoded bits per layer.
535       // For temporal layers, update the cumulative encoded bits per layer.
536       for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
537         const int layer = sl * number_temporal_layers_ + tl;
538         bits_total_[layer] += static_cast<int64_t>(sizes[sl]);
539         // Update the per-layer buffer level with the encoded frame size.
540         bits_in_buffer_model_[layer] -= static_cast<int64_t>(sizes[sl]);
541         // There should be no buffer underrun, except on the base
542         // temporal layer, since there may be key frames there.
543         // Fo short key frame spacing, buffer can underrun on individual frames.
544         if (!key_frame && tl > 0 && key_frame_spacing_ < 100) {
545           ASSERT_GE(bits_in_buffer_model_[layer], 0)
546               << "Buffer Underrun at frame " << pkt->data.frame.pts;
547         }
548       }
549 
550       if (!single_layer_resize_) {
551         unsigned int scaled_width = top_sl_width_ *
552                                     svc_params_.scaling_factor_num[sl] /
553                                     svc_params_.scaling_factor_den[sl];
554         if (scaled_width % 2 != 0) scaled_width += 1;
555         ASSERT_EQ(pkt->data.frame.width[sl], scaled_width);
556         unsigned int scaled_height = top_sl_height_ *
557                                      svc_params_.scaling_factor_num[sl] /
558                                      svc_params_.scaling_factor_den[sl];
559         if (scaled_height % 2 != 0) scaled_height += 1;
560         ASSERT_EQ(pkt->data.frame.height[sl], scaled_height);
561       } else if (superframe_count_ > 0) {
562         if (pkt->data.frame.width[sl] < prev_frame_width[sl] &&
563             pkt->data.frame.height[sl] < prev_frame_height[sl])
564           num_resize_down_ += 1;
565         if (pkt->data.frame.width[sl] > prev_frame_width[sl] &&
566             pkt->data.frame.height[sl] > prev_frame_height[sl])
567           num_resize_up_ += 1;
568       }
569       prev_frame_width[sl] = pkt->data.frame.width[sl];
570       prev_frame_height[sl] = pkt->data.frame.height[sl];
571     }
572   }
573 
EndPassHook()574   void EndPassHook() override {
575     if (change_bitrate_) last_pts_ = last_pts_ - last_pts_ref_;
576     duration_ = (last_pts_ + 1) * timebase_;
577     for (int sl = 0; sl < number_spatial_layers_; ++sl) {
578       for (int tl = 0; tl < number_temporal_layers_; ++tl) {
579         const int layer = sl * number_temporal_layers_ + tl;
580         const double file_size_in_kb = bits_total_[layer] / 1000.;
581         file_datarate_[layer] = file_size_in_kb / duration_;
582       }
583     }
584   }
585 
MismatchHook(const vpx_image_t * img1,const vpx_image_t * img2)586   void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) override {
587     // TODO(marpan): Look into why an assert is triggered in compute_psnr
588     // for mismatch frames for the special test case: ksvc_flex_noupd_tlenh.
589     // Has to do with dropped frames in bypass/flexible svc mode.
590     if (!ksvc_flex_noupd_tlenh_) {
591       double mismatch_psnr = compute_psnr(img1, img2);
592       mismatch_psnr_ += mismatch_psnr;
593       ++mismatch_nframes_;
594     }
595   }
596 
GetMismatchFrames()597   unsigned int GetMismatchFrames() { return mismatch_nframes_; }
GetNonRefFrames()598   unsigned int GetNonRefFrames() { return num_nonref_frames_; }
599 
600   vpx_codec_pts_t last_pts_;
601   double timebase_;
602   int64_t bits_total_[VPX_MAX_LAYERS];
603   double duration_;
604   double file_datarate_[VPX_MAX_LAYERS];
605   size_t bits_in_last_frame_;
606   double mismatch_psnr_;
607   int denoiser_on_;
608   int tune_content_;
609   int spatial_layer_id_;
610   bool dynamic_drop_layer_;
611   bool single_layer_resize_;
612   unsigned int top_sl_width_;
613   unsigned int top_sl_height_;
614   vpx_svc_ref_frame_config_t ref_frame_config_;
615   int update_pattern_;
616   bool change_bitrate_;
617   vpx_codec_pts_t last_pts_ref_;
618   int middle_bitrate_;
619   int top_bitrate_;
620   int key_frame_spacing_;
621   int layer_framedrop_;
622   int force_key_;
623   int force_key_test_;
624   int inter_layer_pred_mode_;
625   int insert_layer_sync_;
626   int layer_sync_on_base_;
627   int force_intra_only_frame_;
628   int superframe_has_intra_only_;
629   int use_post_encode_drop_;
630   int bitrate_sl3_[3];
631   // Denoiser switched on the fly.
632   bool denoiser_off_on_;
633   // Top layer enabled on the fly.
634   bool denoiser_enable_layers_;
635   int num_resize_up_;
636   int num_resize_down_;
637   unsigned int prev_frame_width[VPX_MAX_LAYERS];
638   unsigned int prev_frame_height[VPX_MAX_LAYERS];
639   bool ksvc_flex_noupd_tlenh_;
640 
641  private:
SetConfig(const int num_temporal_layer)642   void SetConfig(const int num_temporal_layer) override {
643     cfg_.rc_end_usage = VPX_CBR;
644     cfg_.g_lag_in_frames = 0;
645     cfg_.g_error_resilient = 1;
646     if (num_temporal_layer == 3) {
647       cfg_.ts_rate_decimator[0] = 4;
648       cfg_.ts_rate_decimator[1] = 2;
649       cfg_.ts_rate_decimator[2] = 1;
650       cfg_.temporal_layering_mode = 3;
651     } else if (num_temporal_layer == 2) {
652       cfg_.ts_rate_decimator[0] = 2;
653       cfg_.ts_rate_decimator[1] = 1;
654       cfg_.temporal_layering_mode = 2;
655     } else if (num_temporal_layer == 1) {
656       cfg_.ts_rate_decimator[0] = 1;
657       cfg_.temporal_layering_mode = 0;
658     }
659   }
660 
661   unsigned int num_nonref_frames_;
662   unsigned int mismatch_nframes_;
663 };
664 
665 // Params: speed setting.
666 class DatarateOnePassCbrSvcSingleBR
667     : public DatarateOnePassCbrSvc,
668       public ::libvpx_test::CodecTestWithParam<int> {
669  public:
DatarateOnePassCbrSvcSingleBR()670   DatarateOnePassCbrSvcSingleBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
671     memset(&svc_params_, 0, sizeof(svc_params_));
672   }
673   ~DatarateOnePassCbrSvcSingleBR() override = default;
674 
675  protected:
SetUp()676   void SetUp() override {
677     InitializeConfig();
678     SetMode(::libvpx_test::kRealTime);
679     speed_setting_ = GET_PARAM(1);
680     ResetModel();
681   }
682 };
683 
684 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
685 // temporal layers, for 4:4:4 Profile 1.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TL444Profile1)686 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL444Profile1) {
687   SetSvcConfig(3, 3);
688   ::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
689   cfg_.g_profile = 1;
690   cfg_.g_bit_depth = VPX_BITS_8;
691   cfg_.rc_buf_initial_sz = 500;
692   cfg_.rc_buf_optimal_sz = 500;
693   cfg_.rc_buf_sz = 1000;
694   cfg_.rc_min_quantizer = 0;
695   cfg_.rc_max_quantizer = 63;
696   cfg_.g_threads = 1;
697   cfg_.rc_dropframe_thresh = 0;
698   cfg_.kf_max_dist = 9999;
699 
700   top_sl_width_ = 352;
701   top_sl_height_ = 288;
702   cfg_.rc_target_bitrate = 500;
703   ResetModel();
704   AssignLayerBitrates();
705   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
706   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
707                           1.15);
708 #if CONFIG_VP9_DECODER
709   // The non-reference frames are expected to be mismatched frames as the
710   // encoder will avoid loopfilter on these frames.
711   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
712 #endif
713 }
714 
715 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
716 // temporal layers, for 4:2:2 Profile 1.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc2SL3TL422Profile1)717 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL3TL422Profile1) {
718   SetSvcConfig(2, 3);
719   ::libvpx_test::Y4mVideoSource video("park_joy_90p_8_422.y4m", 0, 20);
720   cfg_.g_profile = 1;
721   cfg_.g_bit_depth = VPX_BITS_8;
722   cfg_.rc_buf_initial_sz = 500;
723   cfg_.rc_buf_optimal_sz = 500;
724   cfg_.rc_buf_sz = 1000;
725   cfg_.rc_min_quantizer = 0;
726   cfg_.rc_max_quantizer = 63;
727   cfg_.g_threads = 1;
728   cfg_.rc_dropframe_thresh = 0;
729   cfg_.kf_max_dist = 9999;
730 
731   top_sl_width_ = 160;
732   top_sl_height_ = 90;
733   cfg_.rc_target_bitrate = 500;
734   ResetModel();
735   AssignLayerBitrates();
736   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
737   // Use large under/over shoot thresholds as this is a very short clip,
738   // so not good for testing rate-targeting.
739   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5,
740                           1.7);
741 #if CONFIG_VP9_DECODER
742   // The non-reference frames are expected to be mismatched frames as the
743   // encoder will avoid loopfilter on these frames.
744   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
745 #endif
746 }
747 
748 #if CONFIG_VP9_HIGHBITDEPTH
749 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
750 // temporal layers, for Profle 2 10bit.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TL10bitProfile2)751 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL10bitProfile2) {
752   SetSvcConfig(3, 3);
753   ::libvpx_test::Y4mVideoSource video("park_joy_90p_10_420_20f.y4m", 0, 20);
754   cfg_.g_profile = 2;
755   cfg_.g_bit_depth = VPX_BITS_10;
756   cfg_.g_input_bit_depth = VPX_BITS_10;
757   if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
758   cfg_.rc_buf_initial_sz = 500;
759   cfg_.rc_buf_optimal_sz = 500;
760   cfg_.rc_buf_sz = 1000;
761   cfg_.rc_min_quantizer = 0;
762   cfg_.rc_max_quantizer = 63;
763   cfg_.g_threads = 1;
764   cfg_.rc_dropframe_thresh = 0;
765   cfg_.kf_max_dist = 9999;
766 
767   top_sl_width_ = 160;
768   top_sl_height_ = 90;
769   cfg_.rc_target_bitrate = 500;
770   ResetModel();
771   AssignLayerBitrates();
772   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
773   // TODO(marpan/jianj): Comment out the rate-target checking for now
774   // as superframe parsing to get frame size needs to be fixed for
775   // high bitdepth.
776   /*
777   // Use large under/over shoot thresholds as this is a very short clip,
778   // so not good for testing rate-targeting.
779   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5,
780                           1.7);
781   */
782 #if CONFIG_VP9_DECODER
783   // The non-reference frames are expected to be mismatched frames as the
784   // encoder will avoid loopfilter on these frames.
785   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
786 #endif
787 }
788 
789 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
790 // temporal layers, for Profle 2 12bit.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TL12bitProfile2)791 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TL12bitProfile2) {
792   SetSvcConfig(3, 3);
793   ::libvpx_test::Y4mVideoSource video("park_joy_90p_12_420_20f.y4m", 0, 20);
794   cfg_.g_profile = 2;
795   cfg_.g_bit_depth = VPX_BITS_12;
796   cfg_.g_input_bit_depth = VPX_BITS_12;
797   if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH;
798   cfg_.rc_buf_initial_sz = 500;
799   cfg_.rc_buf_optimal_sz = 500;
800   cfg_.rc_buf_sz = 1000;
801   cfg_.rc_min_quantizer = 0;
802   cfg_.rc_max_quantizer = 63;
803   cfg_.g_threads = 1;
804   cfg_.rc_dropframe_thresh = 0;
805   cfg_.kf_max_dist = 9999;
806 
807   top_sl_width_ = 160;
808   top_sl_height_ = 90;
809   cfg_.rc_target_bitrate = 500;
810   ResetModel();
811   AssignLayerBitrates();
812   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
813   // TODO(marpan/jianj): Comment out the rate-target checking for now
814   // as superframe parsing to get frame size needs to be fixed for
815   // high bitdepth.
816   /*
817   // Use large under/over shoot thresholds as this is a very short clip,
818   // so not good for testing rate-targeting.
819   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.5,
820                           1.7);
821   */
822 #if CONFIG_VP9_DECODER
823   // The non-reference frames are expected to be mismatched frames as the
824   // encoder will avoid loopfilter on these frames.
825   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
826 #endif
827 }
828 #endif
829 
830 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
831 // temporal layer, with screen content mode on and same speed setting for all
832 // layers.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc2SL1TLScreenContent1)833 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TLScreenContent1) {
834   SetSvcConfig(2, 1);
835   cfg_.rc_buf_initial_sz = 500;
836   cfg_.rc_buf_optimal_sz = 500;
837   cfg_.rc_buf_sz = 1000;
838   cfg_.rc_min_quantizer = 0;
839   cfg_.rc_max_quantizer = 63;
840   cfg_.g_threads = 1;
841   cfg_.rc_dropframe_thresh = 10;
842   cfg_.kf_max_dist = 9999;
843 
844   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
845   top_sl_width_ = 1280;
846   top_sl_height_ = 720;
847   cfg_.rc_target_bitrate = 500;
848   ResetModel();
849   tune_content_ = 1;
850   AssignLayerBitrates();
851   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
852   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
853                           1.15);
854 #if CONFIG_VP9_DECODER
855   // The non-reference frames are expected to be mismatched frames as the
856   // encoder will avoid loopfilter on these frames.
857   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
858 #endif
859 }
860 
861 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
862 // 3 temporal layers, with force key frame after frame drop
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TLForceKey)863 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLForceKey) {
864   SetSvcConfig(3, 3);
865   cfg_.rc_buf_initial_sz = 500;
866   cfg_.rc_buf_optimal_sz = 500;
867   cfg_.rc_buf_sz = 1000;
868   cfg_.rc_min_quantizer = 0;
869   cfg_.rc_max_quantizer = 63;
870   cfg_.g_threads = 1;
871   cfg_.rc_dropframe_thresh = 30;
872   cfg_.kf_max_dist = 9999;
873   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
874                                        0, 400);
875   top_sl_width_ = 640;
876   top_sl_height_ = 480;
877   cfg_.rc_target_bitrate = 100;
878   ResetModel();
879   AssignLayerBitrates();
880   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
881   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
882                           1.25);
883 #if CONFIG_VP9_DECODER
884   // The non-reference frames are expected to be mismatched frames as the
885   // encoder will avoid loopfilter on these frames.
886   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
887 #endif
888 }
889 
890 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
891 // 2 temporal layers, with a change on the fly from the fixed SVC pattern to one
892 // generate via SVC_SET_REF_FRAME_CONFIG. The new pattern also disables
893 // inter-layer prediction.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL2TLDynamicPatternChange)894 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL2TLDynamicPatternChange) {
895   SetSvcConfig(3, 2);
896   cfg_.rc_buf_initial_sz = 500;
897   cfg_.rc_buf_optimal_sz = 500;
898   cfg_.rc_buf_sz = 1000;
899   cfg_.rc_min_quantizer = 0;
900   cfg_.rc_max_quantizer = 63;
901   cfg_.g_threads = 1;
902   cfg_.rc_dropframe_thresh = 30;
903   cfg_.kf_max_dist = 9999;
904   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
905                                        0, 400);
906   top_sl_width_ = 640;
907   top_sl_height_ = 480;
908   cfg_.rc_target_bitrate = 800;
909   ResetModel();
910   // Change SVC pattern on the fly.
911   update_pattern_ = 1;
912   AssignLayerBitrates();
913   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
914   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
915                           1.15);
916 #if CONFIG_VP9_DECODER
917   // The non-reference frames are expected to be mismatched frames as the
918   // encoder will avoid loopfilter on these frames.
919   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
920 #endif
921 }
922 
923 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal
924 // layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching
925 // of denoiser from off to on (on at frame = 100). Key frame period is set to
926 // 1000 so denoise is enabled on non-key.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TL_DenoiserOffOnFixedLayers)927 TEST_P(DatarateOnePassCbrSvcSingleBR,
928        OnePassCbrSvc3SL3TL_DenoiserOffOnFixedLayers) {
929   SetSvcConfig(3, 3);
930   cfg_.rc_buf_initial_sz = 500;
931   cfg_.rc_buf_optimal_sz = 500;
932   cfg_.rc_buf_sz = 1000;
933   cfg_.rc_min_quantizer = 0;
934   cfg_.rc_max_quantizer = 63;
935   cfg_.g_threads = 1;
936   cfg_.rc_dropframe_thresh = 30;
937   cfg_.kf_max_dist = 1000;
938   ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
939                                        720, 30, 1, 0, 300);
940   top_sl_width_ = 1280;
941   top_sl_height_ = 720;
942   cfg_.rc_target_bitrate = 1000;
943   ResetModel();
944   denoiser_off_on_ = true;
945   denoiser_enable_layers_ = false;
946   AssignLayerBitrates();
947   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
948   // Don't check rate targeting on two top spatial layer since they will be
949   // skipped for part of the sequence.
950   CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
951                           0.78, 1.15);
952 #if CONFIG_VP9_DECODER
953   // The non-reference frames are expected to be mismatched frames as the
954   // encoder will avoid loopfilter on these frames.
955   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
956 #endif
957 }
958 
959 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal
960 // layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching
961 // of denoiser from off to on, for dynamic layers. Start at 2 spatial layers
962 // and enable 3rd spatial layer at frame = 100. Use periodic key frame with
963 // period 100 so enabling of spatial layer occurs at key frame. Enable denoiser
964 // at frame > 100, after the key frame sync.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TL_DenoiserOffOnEnableLayers)965 TEST_P(DatarateOnePassCbrSvcSingleBR,
966        OnePassCbrSvc3SL3TL_DenoiserOffOnEnableLayers) {
967   SetSvcConfig(3, 3);
968   cfg_.rc_buf_initial_sz = 500;
969   cfg_.rc_buf_optimal_sz = 500;
970   cfg_.rc_buf_sz = 1000;
971   cfg_.rc_min_quantizer = 0;
972   cfg_.rc_max_quantizer = 63;
973   cfg_.g_threads = 1;
974   cfg_.rc_dropframe_thresh = 0;
975   cfg_.kf_max_dist = 100;
976   ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
977                                        720, 30, 1, 0, 300);
978   top_sl_width_ = 1280;
979   top_sl_height_ = 720;
980   cfg_.rc_target_bitrate = 1000;
981   ResetModel();
982   denoiser_off_on_ = true;
983   denoiser_enable_layers_ = true;
984   AssignLayerBitrates();
985   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
986   // Don't check rate targeting on two top spatial layer since they will be
987   // skipped for part of the sequence.
988   CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
989                           0.78, 1.15);
990 #if CONFIG_VP9_DECODER
991   // The non-reference frames are expected to be mismatched frames as the
992   // encoder will avoid loopfilter on these frames.
993   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
994 #endif
995 }
996 
997 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial layers and on
998 // the fly switching to 1 and then 2 and back to 3 spatial layers. This switch
999 // is done by setting spatial layer bitrates to 0, and then back to non-zero,
1000 // during the sequence.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL_DisableEnableLayers)1001 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL_DisableEnableLayers) {
1002   SetSvcConfig(3, 1);
1003   cfg_.rc_buf_initial_sz = 500;
1004   cfg_.rc_buf_optimal_sz = 500;
1005   cfg_.rc_buf_sz = 1000;
1006   cfg_.rc_min_quantizer = 0;
1007   cfg_.rc_max_quantizer = 63;
1008   cfg_.g_threads = 1;
1009   cfg_.temporal_layering_mode = 0;
1010   cfg_.rc_dropframe_thresh = 30;
1011   cfg_.kf_max_dist = 9999;
1012   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1013                                        0, 400);
1014   top_sl_width_ = 640;
1015   top_sl_height_ = 480;
1016   cfg_.rc_target_bitrate = 800;
1017   ResetModel();
1018   dynamic_drop_layer_ = true;
1019   AssignLayerBitrates();
1020   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1021   // Don't check rate targeting on two top spatial layer since they will be
1022   // skipped for part of the sequence.
1023   CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
1024                           0.78, 1.15);
1025 #if CONFIG_VP9_DECODER
1026   // The non-reference frames are expected to be mismatched frames as the
1027   // encoder will avoid loopfilter on these frames.
1028   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1029 #endif
1030 }
1031 
1032 // Check basic rate targeting for 1 pass CBR SVC with 2 spatial layers and on
1033 // the fly switching to 1 spatial layer with dynamic resize enabled.
1034 // The resizer will resize the single layer down and back up again, as the
1035 // bitrate goes back up.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc2SL_SingleLayerResize)1036 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL_SingleLayerResize) {
1037   SetSvcConfig(2, 1);
1038   cfg_.rc_buf_initial_sz = 500;
1039   cfg_.rc_buf_optimal_sz = 500;
1040   cfg_.rc_buf_sz = 1000;
1041   cfg_.rc_min_quantizer = 0;
1042   cfg_.rc_max_quantizer = 63;
1043   cfg_.g_threads = 1;
1044   cfg_.temporal_layering_mode = 0;
1045   cfg_.rc_dropframe_thresh = 30;
1046   cfg_.kf_max_dist = 9999;
1047   cfg_.rc_resize_allowed = 1;
1048   ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
1049                                        720, 15, 1, 0, 300);
1050   top_sl_width_ = 1280;
1051   top_sl_height_ = 720;
1052   cfg_.rc_target_bitrate = 800;
1053   ResetModel();
1054   dynamic_drop_layer_ = true;
1055   single_layer_resize_ = true;
1056   base_speed_setting_ = speed_setting_;
1057   AssignLayerBitrates();
1058   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1059   // Expect at least one resize down and at least one resize back up.
1060   EXPECT_GE(num_resize_down_, 1);
1061   EXPECT_GE(num_resize_up_, 1);
1062   // Don't check rate targeting on two top spatial layer since they will be
1063   // skipped for part of the sequence.
1064   CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
1065                           0.78, 1.15);
1066 #if CONFIG_VP9_DECODER
1067   // The non-reference frames are expected to be mismatched frames as the
1068   // encoder will avoid loopfilter on these frames.
1069   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1070 #endif
1071 }
1072 
1073 // For  pass CBR SVC with 1 spatial and 2 temporal layers with dynamic resize
1074 // and denoiser enabled. The resizer will resize the single layer down and back
1075 // up again, as the bitrate goes back up.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc1SL2TL_DenoiseResize)1076 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc1SL2TL_DenoiseResize) {
1077   SetSvcConfig(1, 2);
1078   cfg_.rc_buf_initial_sz = 500;
1079   cfg_.rc_buf_optimal_sz = 500;
1080   cfg_.rc_buf_sz = 1000;
1081   cfg_.rc_min_quantizer = 0;
1082   cfg_.rc_max_quantizer = 63;
1083   cfg_.g_threads = 1;
1084   cfg_.temporal_layering_mode = 2;
1085   cfg_.rc_dropframe_thresh = 30;
1086   cfg_.kf_max_dist = 9999;
1087   cfg_.rc_resize_allowed = 1;
1088   ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
1089                                        720, 12, 1, 0, 300);
1090   top_sl_width_ = 1280;
1091   top_sl_height_ = 720;
1092   cfg_.rc_target_bitrate = 800;
1093   ResetModel();
1094   dynamic_drop_layer_ = false;
1095   single_layer_resize_ = true;
1096   denoiser_on_ = 1;
1097   base_speed_setting_ = speed_setting_;
1098   AssignLayerBitrates();
1099   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1100   // Expect at least one resize down and at least one resize back up.
1101   EXPECT_GE(num_resize_down_, 1);
1102   EXPECT_GE(num_resize_up_, 1);
1103 }
1104 
1105 // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
1106 // downscale 5x5.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc2SL1TL5x5MultipleRuns)1107 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
1108   cfg_.rc_buf_initial_sz = 500;
1109   cfg_.rc_buf_optimal_sz = 500;
1110   cfg_.rc_buf_sz = 1000;
1111   cfg_.rc_min_quantizer = 0;
1112   cfg_.rc_max_quantizer = 63;
1113   cfg_.rc_end_usage = VPX_CBR;
1114   cfg_.g_lag_in_frames = 0;
1115   cfg_.ss_number_layers = 2;
1116   cfg_.ts_number_layers = 1;
1117   cfg_.ts_rate_decimator[0] = 1;
1118   cfg_.g_error_resilient = 1;
1119   cfg_.g_threads = 3;
1120   cfg_.temporal_layering_mode = 0;
1121   svc_params_.scaling_factor_num[0] = 256;
1122   svc_params_.scaling_factor_den[0] = 1280;
1123   svc_params_.scaling_factor_num[1] = 1280;
1124   svc_params_.scaling_factor_den[1] = 1280;
1125   cfg_.rc_dropframe_thresh = 10;
1126   cfg_.kf_max_dist = 999999;
1127   cfg_.kf_min_dist = 0;
1128   cfg_.ss_target_bitrate[0] = 300;
1129   cfg_.ss_target_bitrate[1] = 1400;
1130   cfg_.layer_target_bitrate[0] = 300;
1131   cfg_.layer_target_bitrate[1] = 1400;
1132   cfg_.rc_target_bitrate = 1700;
1133   number_spatial_layers_ = cfg_.ss_number_layers;
1134   number_temporal_layers_ = cfg_.ts_number_layers;
1135   ResetModel();
1136   layer_target_avg_bandwidth_[0] = cfg_.layer_target_bitrate[0] * 1000 / 30;
1137   bits_in_buffer_model_[0] =
1138       cfg_.layer_target_bitrate[0] * cfg_.rc_buf_initial_sz;
1139   layer_target_avg_bandwidth_[1] = cfg_.layer_target_bitrate[1] * 1000 / 30;
1140   bits_in_buffer_model_[1] =
1141       cfg_.layer_target_bitrate[1] * cfg_.rc_buf_initial_sz;
1142   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1143   top_sl_width_ = 1280;
1144   top_sl_height_ = 720;
1145   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1146   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1147                           1.15);
1148 #if CONFIG_VP9_DECODER
1149   // The non-reference frames are expected to be mismatched frames as the
1150   // encoder will avoid loopfilter on these frames.
1151   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1152 #endif
1153 }
1154 
1155 // Params: speed setting and index for bitrate array.
1156 class DatarateOnePassCbrSvcMultiBR
1157     : public DatarateOnePassCbrSvc,
1158       public ::libvpx_test::CodecTestWith2Params<int, int> {
1159  public:
DatarateOnePassCbrSvcMultiBR()1160   DatarateOnePassCbrSvcMultiBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1161     memset(&svc_params_, 0, sizeof(svc_params_));
1162   }
1163   ~DatarateOnePassCbrSvcMultiBR() override = default;
1164 
1165  protected:
SetUp()1166   void SetUp() override {
1167     InitializeConfig();
1168     SetMode(::libvpx_test::kRealTime);
1169     speed_setting_ = GET_PARAM(1);
1170     ResetModel();
1171   }
1172 };
1173 
1174 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1175 // 3 temporal layers. Run CIF clip with 1 thread.
TEST_P(DatarateOnePassCbrSvcMultiBR,OnePassCbrSvc2SL3TL)1176 TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassCbrSvc2SL3TL) {
1177   SetSvcConfig(2, 3);
1178   cfg_.rc_buf_initial_sz = 500;
1179   cfg_.rc_buf_optimal_sz = 500;
1180   cfg_.rc_buf_sz = 1000;
1181   cfg_.rc_min_quantizer = 0;
1182   cfg_.rc_max_quantizer = 63;
1183   cfg_.g_threads = 1;
1184   cfg_.rc_dropframe_thresh = 30;
1185   cfg_.kf_max_dist = 9999;
1186   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1187                                        0, 400);
1188   top_sl_width_ = 640;
1189   top_sl_height_ = 480;
1190   const int bitrates[3] = { 200, 400, 600 };
1191   // TODO(marpan): Check that effective_datarate for each layer hits the
1192   // layer target_bitrate.
1193   cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)];
1194   ResetModel();
1195   AssignLayerBitrates();
1196   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1197   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.75,
1198                           1.2);
1199 #if CONFIG_VP9_DECODER
1200   // The non-reference frames are expected to be mismatched frames as the
1201   // encoder will avoid loopfilter on these frames.
1202   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1203 #endif
1204 }
1205 
1206 // Check basic rate targeting for 1 pass VBR SVC: 2 spatial layers and
1207 // 3 temporal layers. Run VGA clip with 1 thread.
TEST_P(DatarateOnePassCbrSvcMultiBR,OnePassVbrSvc2SL3TL)1208 TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassVbrSvc2SL3TL) {
1209   SetSvcConfig(2, 3);
1210   cfg_.rc_buf_initial_sz = 500;
1211   cfg_.rc_buf_optimal_sz = 500;
1212   cfg_.rc_buf_sz = 1000;
1213   cfg_.rc_min_quantizer = 2;
1214   cfg_.rc_max_quantizer = 56;
1215   cfg_.g_threads = 1;
1216   cfg_.rc_dropframe_thresh = 30;
1217   cfg_.kf_max_dist = 9999;
1218   cfg_.rc_end_usage = VPX_VBR;
1219   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1220                                        0, 400);
1221   top_sl_width_ = 640;
1222   top_sl_height_ = 480;
1223   const int bitrates[3] = { 200, 400, 600 };
1224   cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)];
1225   ResetModel();
1226   AssignLayerBitrates();
1227   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1228   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.70,
1229                           1.3);
1230 #if CONFIG_VP9_DECODER
1231   // The non-reference frames are expected to be mismatched frames as the
1232   // encoder will avoid loopfilter on these frames.
1233   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1234 #endif
1235 }
1236 
1237 // Params: speed setting, layer framedrop control and index for bitrate array.
1238 class DatarateOnePassCbrSvcFrameDropMultiBR
1239     : public DatarateOnePassCbrSvc,
1240       public ::libvpx_test::CodecTestWith3Params<int, int, int> {
1241  public:
DatarateOnePassCbrSvcFrameDropMultiBR()1242   DatarateOnePassCbrSvcFrameDropMultiBR()
1243       : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1244     memset(&svc_params_, 0, sizeof(svc_params_));
1245   }
1246   ~DatarateOnePassCbrSvcFrameDropMultiBR() override = default;
1247 
1248  protected:
SetUp()1249   void SetUp() override {
1250     InitializeConfig();
1251     SetMode(::libvpx_test::kRealTime);
1252     speed_setting_ = GET_PARAM(1);
1253     ResetModel();
1254   }
1255 };
1256 
1257 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1258 // 3 temporal layers. Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR,OnePassCbrSvc2SL3TL4Threads)1259 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) {
1260   SetSvcConfig(2, 3);
1261   cfg_.rc_buf_initial_sz = 500;
1262   cfg_.rc_buf_optimal_sz = 500;
1263   cfg_.rc_buf_sz = 1000;
1264   cfg_.rc_min_quantizer = 0;
1265   cfg_.rc_max_quantizer = 63;
1266   cfg_.g_threads = 4;
1267   cfg_.rc_dropframe_thresh = 30;
1268   cfg_.kf_max_dist = 9999;
1269   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1270   top_sl_width_ = 1280;
1271   top_sl_height_ = 720;
1272   layer_framedrop_ = 0;
1273   const int bitrates[3] = { 200, 400, 600 };
1274   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1275   ResetModel();
1276   layer_framedrop_ = GET_PARAM(2);
1277   AssignLayerBitrates();
1278   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1279   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.64,
1280                           1.45);
1281 #if CONFIG_VP9_DECODER
1282   // The non-reference frames are expected to be mismatched frames as the
1283   // encoder will avoid loopfilter on these frames.
1284   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1285 #endif
1286 }
1287 
1288 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1289 // 3 temporal layers. Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR,OnePassCbrSvc3SL3TL4Threads)1290 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL3TL4Threads) {
1291   SetSvcConfig(3, 3);
1292   cfg_.rc_buf_initial_sz = 500;
1293   cfg_.rc_buf_optimal_sz = 500;
1294   cfg_.rc_buf_sz = 1000;
1295   cfg_.rc_min_quantizer = 0;
1296   cfg_.rc_max_quantizer = 63;
1297   cfg_.g_threads = 4;
1298   cfg_.rc_dropframe_thresh = 30;
1299   cfg_.kf_max_dist = 9999;
1300   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1301   top_sl_width_ = 1280;
1302   top_sl_height_ = 720;
1303   layer_framedrop_ = 0;
1304   const int bitrates[3] = { 200, 400, 600 };
1305   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1306   ResetModel();
1307   layer_framedrop_ = GET_PARAM(2);
1308   AssignLayerBitrates();
1309   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1310   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58,
1311                           1.2);
1312 #if CONFIG_VP9_DECODER
1313   // The non-reference frames are expected to be mismatched frames as the
1314   // encoder will avoid loopfilter on these frames.
1315   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1316 #endif
1317 }
1318 
1319 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1320 // 2 temporal layers, for KSVC in flexible mode with no update of reference
1321 // frames for all spatial layers on TL > 0 superframes.
1322 // Run HD clip with 4 threads.
TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR,OnePassCbrSvc3SL2TL4ThKSVCFlex)1323 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL2TL4ThKSVCFlex) {
1324   SetSvcConfig(3, 2);
1325   cfg_.rc_buf_initial_sz = 500;
1326   cfg_.rc_buf_optimal_sz = 500;
1327   cfg_.rc_buf_sz = 1000;
1328   cfg_.rc_min_quantizer = 0;
1329   cfg_.rc_max_quantizer = 63;
1330   cfg_.g_threads = 4;
1331   cfg_.rc_dropframe_thresh = 30;
1332   cfg_.kf_max_dist = 9999;
1333   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1334   top_sl_width_ = 1280;
1335   top_sl_height_ = 720;
1336   layer_framedrop_ = 0;
1337   const int bitrates[3] = { 200, 400, 600 };
1338   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1339   ResetModel();
1340   layer_framedrop_ = GET_PARAM(2);
1341   AssignLayerBitrates();
1342   ksvc_flex_noupd_tlenh_ = true;
1343   cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
1344   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1345   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58,
1346                           1.2);
1347 }
1348 
1349 // Params: speed setting, inter-layer prediction mode.
1350 class DatarateOnePassCbrSvcInterLayerPredSingleBR
1351     : public DatarateOnePassCbrSvc,
1352       public ::libvpx_test::CodecTestWith2Params<int, int> {
1353  public:
DatarateOnePassCbrSvcInterLayerPredSingleBR()1354   DatarateOnePassCbrSvcInterLayerPredSingleBR()
1355       : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1356     memset(&svc_params_, 0, sizeof(svc_params_));
1357   }
1358   ~DatarateOnePassCbrSvcInterLayerPredSingleBR() override = default;
1359 
1360  protected:
SetUp()1361   void SetUp() override {
1362     InitializeConfig();
1363     SetMode(::libvpx_test::kRealTime);
1364     speed_setting_ = GET_PARAM(1);
1365     inter_layer_pred_mode_ = GET_PARAM(2);
1366     ResetModel();
1367   }
1368 };
1369 
1370 // Check basic rate targeting with different inter-layer prediction modes for 1
1371 // pass CBR SVC: 3 spatial layers and 3 temporal layers. Run CIF clip with 1
1372 // thread.
TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR,OnePassCbrSvc3SL3TL)1373 TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR, OnePassCbrSvc3SL3TL) {
1374   // Disable test for inter-layer pred off for now since simulcast_mode fails.
1375   if (inter_layer_pred_mode_ == INTER_LAYER_PRED_OFF) return;
1376   SetSvcConfig(3, 3);
1377   cfg_.rc_buf_initial_sz = 500;
1378   cfg_.rc_buf_optimal_sz = 500;
1379   cfg_.rc_buf_sz = 1000;
1380   cfg_.rc_min_quantizer = 0;
1381   cfg_.rc_max_quantizer = 63;
1382   cfg_.g_threads = 1;
1383   cfg_.temporal_layering_mode = 3;
1384   cfg_.rc_dropframe_thresh = 30;
1385   cfg_.kf_max_dist = 9999;
1386   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1387                                        0, 400);
1388   top_sl_width_ = 640;
1389   top_sl_height_ = 480;
1390   cfg_.rc_target_bitrate = 800;
1391   ResetModel();
1392   AssignLayerBitrates();
1393   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1394   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1395                           1.15);
1396 #if CONFIG_VP9_DECODER
1397   // The non-reference frames are expected to be mismatched frames as the
1398   // encoder will avoid loopfilter on these frames.
1399   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1400 #endif
1401 }
1402 
1403 // Check rate targeting with different inter-layer prediction modes for 1 pass
1404 // CBR SVC: 3 spatial layers and 3 temporal layers, changing the target bitrate
1405 // at the middle of encoding.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TLDynamicBitrateChange)1406 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLDynamicBitrateChange) {
1407   SetSvcConfig(3, 3);
1408   cfg_.rc_buf_initial_sz = 500;
1409   cfg_.rc_buf_optimal_sz = 500;
1410   cfg_.rc_buf_sz = 1000;
1411   cfg_.rc_min_quantizer = 0;
1412   cfg_.rc_max_quantizer = 63;
1413   cfg_.g_threads = 1;
1414   cfg_.rc_dropframe_thresh = 30;
1415   cfg_.kf_max_dist = 9999;
1416   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1417                                        0, 400);
1418   top_sl_width_ = 640;
1419   top_sl_height_ = 480;
1420   cfg_.rc_target_bitrate = 800;
1421   ResetModel();
1422   change_bitrate_ = true;
1423   AssignLayerBitrates();
1424   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1425   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1426                           1.15);
1427 #if CONFIG_VP9_DECODER
1428   // The non-reference frames are expected to be mismatched frames as the
1429   // encoder will avoid loopfilter on these frames.
1430   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1431 #endif
1432 }
1433 
1434 #if CONFIG_VP9_TEMPORAL_DENOISING
1435 // Params: speed setting, noise sensitivity, index for bitrate array and inter
1436 // layer pred mode.
1437 class DatarateOnePassCbrSvcDenoiser
1438     : public DatarateOnePassCbrSvc,
1439       public ::libvpx_test::CodecTestWith4Params<int, int, int, int> {
1440  public:
DatarateOnePassCbrSvcDenoiser()1441   DatarateOnePassCbrSvcDenoiser() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1442     memset(&svc_params_, 0, sizeof(svc_params_));
1443   }
1444   ~DatarateOnePassCbrSvcDenoiser() override = default;
1445 
1446  protected:
SetUp()1447   void SetUp() override {
1448     InitializeConfig();
1449     SetMode(::libvpx_test::kRealTime);
1450     speed_setting_ = GET_PARAM(1);
1451     inter_layer_pred_mode_ = GET_PARAM(3);
1452     ResetModel();
1453   }
1454 };
1455 
1456 // Check basic rate targeting for 1 pass CBR SVC with denoising.
1457 // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
TEST_P(DatarateOnePassCbrSvcDenoiser,OnePassCbrSvc2SL3TLDenoiserOn)1458 TEST_P(DatarateOnePassCbrSvcDenoiser, OnePassCbrSvc2SL3TLDenoiserOn) {
1459   SetSvcConfig(2, 3);
1460   cfg_.rc_buf_initial_sz = 500;
1461   cfg_.rc_buf_optimal_sz = 500;
1462   cfg_.rc_buf_sz = 1000;
1463   cfg_.rc_min_quantizer = 0;
1464   cfg_.rc_max_quantizer = 63;
1465   cfg_.g_threads = 2;
1466   cfg_.rc_dropframe_thresh = 30;
1467   cfg_.kf_max_dist = 9999;
1468   number_spatial_layers_ = cfg_.ss_number_layers;
1469   number_temporal_layers_ = cfg_.ts_number_layers;
1470   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1471                                        0, 400);
1472   top_sl_width_ = 640;
1473   top_sl_height_ = 480;
1474   const int bitrates[3] = { 600, 800, 1000 };
1475   // TODO(marpan): Check that effective_datarate for each layer hits the
1476   // layer target_bitrate.
1477   // For SVC, noise_sen = 1 means denoising only the top spatial layer
1478   // noise_sen = 2 means denoising the two top spatial layers.
1479   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1480   ResetModel();
1481   denoiser_on_ = GET_PARAM(2);
1482   AssignLayerBitrates();
1483   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1484   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1485                           1.15);
1486 #if CONFIG_VP9_DECODER
1487   // The non-reference frames are expected to be mismatched frames as the
1488   // encoder will avoid loopfilter on these frames.
1489   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1490 #endif
1491 }
1492 #endif
1493 
1494 // Params: speed setting, key frame dist.
1495 class DatarateOnePassCbrSvcSmallKF
1496     : public DatarateOnePassCbrSvc,
1497       public ::libvpx_test::CodecTestWith2Params<int, int> {
1498  public:
DatarateOnePassCbrSvcSmallKF()1499   DatarateOnePassCbrSvcSmallKF() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1500     memset(&svc_params_, 0, sizeof(svc_params_));
1501   }
1502   ~DatarateOnePassCbrSvcSmallKF() override = default;
1503 
1504  protected:
SetUp()1505   void SetUp() override {
1506     InitializeConfig();
1507     SetMode(::libvpx_test::kRealTime);
1508     speed_setting_ = GET_PARAM(1);
1509     ResetModel();
1510   }
1511 };
1512 
1513 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1514 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
TEST_P(DatarateOnePassCbrSvcSmallKF,OnePassCbrSvc3SL3TLSmallKf)1515 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc3SL3TLSmallKf) {
1516   SetSvcConfig(3, 3);
1517   cfg_.rc_buf_initial_sz = 500;
1518   cfg_.rc_buf_optimal_sz = 500;
1519   cfg_.rc_buf_sz = 1000;
1520   cfg_.rc_min_quantizer = 0;
1521   cfg_.rc_max_quantizer = 63;
1522   cfg_.g_threads = 1;
1523   cfg_.rc_dropframe_thresh = 10;
1524   cfg_.rc_target_bitrate = 800;
1525   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1526                                        0, 400);
1527   top_sl_width_ = 640;
1528   top_sl_height_ = 480;
1529   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1530   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1531   const int kf_dist = GET_PARAM(2);
1532   cfg_.kf_max_dist = kf_dist;
1533   key_frame_spacing_ = kf_dist;
1534   ResetModel();
1535   AssignLayerBitrates();
1536   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1537   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.70,
1538                           1.15);
1539 #if CONFIG_VP9_DECODER
1540   // The non-reference frames are expected to be mismatched frames as the
1541   // encoder will avoid loopfilter on these frames.
1542   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1543 #endif
1544 }
1545 
1546 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
1547 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
TEST_P(DatarateOnePassCbrSvcSmallKF,OnePassCbrSvc2SL3TLSmallKf)1548 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc2SL3TLSmallKf) {
1549   SetSvcConfig(2, 3);
1550   cfg_.rc_buf_initial_sz = 500;
1551   cfg_.rc_buf_optimal_sz = 500;
1552   cfg_.rc_buf_sz = 1000;
1553   cfg_.rc_min_quantizer = 0;
1554   cfg_.rc_max_quantizer = 63;
1555   cfg_.g_threads = 1;
1556   cfg_.rc_dropframe_thresh = 10;
1557   cfg_.rc_target_bitrate = 400;
1558   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1559                                        0, 400);
1560   top_sl_width_ = 640;
1561   top_sl_height_ = 480;
1562   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1563   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1564   const int kf_dist = GET_PARAM(2) + 32;
1565   cfg_.kf_max_dist = kf_dist;
1566   key_frame_spacing_ = kf_dist;
1567   ResetModel();
1568   AssignLayerBitrates();
1569   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1570   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1571                           1.15);
1572 #if CONFIG_VP9_DECODER
1573   // The non-reference frames are expected to be mismatched frames as the
1574   // encoder will avoid loopfilter on these frames.
1575   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1576 #endif
1577 }
1578 
1579 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1580 // temporal layers. Run VGA clip with 1 thread, and place layer sync frames:
1581 // one at middle layer first, then another one for top layer, and another
1582 // insert for base spatial layer (which forces key frame).
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL3TLSyncFrames)1583 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLSyncFrames) {
1584   SetSvcConfig(3, 3);
1585   cfg_.rc_buf_initial_sz = 500;
1586   cfg_.rc_buf_optimal_sz = 500;
1587   cfg_.rc_buf_sz = 1000;
1588   cfg_.rc_min_quantizer = 0;
1589   cfg_.rc_max_quantizer = 63;
1590   cfg_.g_threads = 1;
1591   cfg_.kf_max_dist = 9999;
1592   cfg_.rc_dropframe_thresh = 10;
1593   cfg_.rc_target_bitrate = 400;
1594   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1595                                        0, 400);
1596   top_sl_width_ = 640;
1597   top_sl_height_ = 480;
1598   ResetModel();
1599   insert_layer_sync_ = 1;
1600   AssignLayerBitrates();
1601   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1602   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1603                           1.15);
1604 #if CONFIG_VP9_DECODER
1605   // The non-reference frames are expected to be mismatched frames as the
1606   // encoder will avoid loopfilter on these frames.
1607   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1608 #endif
1609 }
1610 
1611 // Run SVC encoder for 3 spatial layers, 1 temporal layer, with
1612 // intra-only frame as sync frame on base spatial layer.
1613 // Intra_only is inserted at start and in middle of sequence.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc3SL1TLSyncWithIntraOnly)1614 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL1TLSyncWithIntraOnly) {
1615   SetSvcConfig(3, 1);
1616   cfg_.rc_buf_initial_sz = 500;
1617   cfg_.rc_buf_optimal_sz = 500;
1618   cfg_.rc_buf_sz = 1000;
1619   cfg_.rc_min_quantizer = 0;
1620   cfg_.rc_max_quantizer = 63;
1621   cfg_.g_threads = 4;
1622   cfg_.rc_dropframe_thresh = 30;
1623   cfg_.kf_max_dist = 9999;
1624   cfg_.rc_target_bitrate = 400;
1625   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1626                                        0, 400);
1627   top_sl_width_ = 640;
1628   top_sl_height_ = 480;
1629   ResetModel();
1630   insert_layer_sync_ = 1;
1631   // Use intra_only frame for sync on base layer.
1632   force_intra_only_frame_ = 1;
1633   AssignLayerBitrates();
1634   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1635   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1636                           1.2);
1637 #if CONFIG_VP9_DECODER
1638   // The non-reference frames are expected to be mismatched frames as the
1639   // encoder will avoid loopfilter on these frames.
1640   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1641 #endif
1642 }
1643 
1644 // Run SVC encoder for 2 quality layers (same resolution different,
1645 // bitrates), 1 temporal layer, with screen content mode.
TEST_P(DatarateOnePassCbrSvcSingleBR,OnePassCbrSvc2QL1TLScreen)1646 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2QL1TLScreen) {
1647   cfg_.rc_buf_initial_sz = 500;
1648   cfg_.rc_buf_optimal_sz = 500;
1649   cfg_.rc_buf_sz = 1000;
1650   cfg_.rc_min_quantizer = 0;
1651   cfg_.rc_max_quantizer = 56;
1652   cfg_.rc_end_usage = VPX_CBR;
1653   cfg_.g_lag_in_frames = 0;
1654   cfg_.ss_number_layers = 2;
1655   cfg_.ts_number_layers = 1;
1656   cfg_.ts_rate_decimator[0] = 1;
1657   cfg_.temporal_layering_mode = 0;
1658   cfg_.g_error_resilient = 1;
1659   cfg_.g_threads = 2;
1660   svc_params_.scaling_factor_num[0] = 1;
1661   svc_params_.scaling_factor_den[0] = 1;
1662   svc_params_.scaling_factor_num[1] = 1;
1663   svc_params_.scaling_factor_den[1] = 1;
1664   cfg_.rc_dropframe_thresh = 30;
1665   cfg_.kf_max_dist = 9999;
1666   number_spatial_layers_ = cfg_.ss_number_layers;
1667   number_temporal_layers_ = cfg_.ts_number_layers;
1668   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1669                                        0, 400);
1670   top_sl_width_ = 640;
1671   top_sl_height_ = 480;
1672   ResetModel();
1673   tune_content_ = 1;
1674   // Set the layer bitrates, for 2 spatial layers, 1 temporal.
1675   cfg_.rc_target_bitrate = 400;
1676   cfg_.ss_target_bitrate[0] = 100;
1677   cfg_.ss_target_bitrate[1] = 300;
1678   cfg_.layer_target_bitrate[0] = 100;
1679   cfg_.layer_target_bitrate[1] = 300;
1680   for (int sl = 0; sl < 2; ++sl) {
1681     float layer_framerate = 30.0;
1682     layer_target_avg_bandwidth_[sl] = static_cast<int>(
1683         cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate);
1684     bits_in_buffer_model_[sl] =
1685         cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz;
1686   }
1687   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1688   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1689                           1.25);
1690 #if CONFIG_VP9_DECODER
1691   // The non-reference frames are expected to be mismatched frames as the
1692   // encoder will avoid loopfilter on these frames.
1693   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1694 #endif
1695 }
1696 
1697 // Params: speed setting.
1698 class DatarateOnePassCbrSvcPostencodeDrop
1699     : public DatarateOnePassCbrSvc,
1700       public ::libvpx_test::CodecTestWithParam<int> {
1701  public:
DatarateOnePassCbrSvcPostencodeDrop()1702   DatarateOnePassCbrSvcPostencodeDrop() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1703     memset(&svc_params_, 0, sizeof(svc_params_));
1704   }
1705   ~DatarateOnePassCbrSvcPostencodeDrop() override = default;
1706 
1707  protected:
SetUp()1708   void SetUp() override {
1709     InitializeConfig();
1710     SetMode(::libvpx_test::kRealTime);
1711     speed_setting_ = GET_PARAM(1);
1712     ResetModel();
1713   }
1714 };
1715 
1716 // Run SVC encoder for 2 quality layers (same resolution different,
1717 // bitrates), 1 temporal layer, with screen content mode.
TEST_P(DatarateOnePassCbrSvcPostencodeDrop,OnePassCbrSvc2QL1TLScreen)1718 TEST_P(DatarateOnePassCbrSvcPostencodeDrop, OnePassCbrSvc2QL1TLScreen) {
1719   cfg_.rc_buf_initial_sz = 200;
1720   cfg_.rc_buf_optimal_sz = 200;
1721   cfg_.rc_buf_sz = 400;
1722   cfg_.rc_min_quantizer = 0;
1723   cfg_.rc_max_quantizer = 52;
1724   cfg_.rc_end_usage = VPX_CBR;
1725   cfg_.g_lag_in_frames = 0;
1726   cfg_.ss_number_layers = 2;
1727   cfg_.ts_number_layers = 1;
1728   cfg_.ts_rate_decimator[0] = 1;
1729   cfg_.temporal_layering_mode = 0;
1730   cfg_.g_error_resilient = 1;
1731   cfg_.g_threads = 2;
1732   svc_params_.scaling_factor_num[0] = 1;
1733   svc_params_.scaling_factor_den[0] = 1;
1734   svc_params_.scaling_factor_num[1] = 1;
1735   svc_params_.scaling_factor_den[1] = 1;
1736   cfg_.rc_dropframe_thresh = 30;
1737   cfg_.kf_max_dist = 9999;
1738   number_spatial_layers_ = cfg_.ss_number_layers;
1739   number_temporal_layers_ = cfg_.ts_number_layers;
1740   ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1741                                        30, 1, 0, 300);
1742   top_sl_width_ = 352;
1743   top_sl_height_ = 288;
1744   ResetModel();
1745   base_speed_setting_ = speed_setting_;
1746   tune_content_ = 1;
1747   use_post_encode_drop_ = 1;
1748   // Set the layer bitrates, for 2 spatial layers, 1 temporal.
1749   cfg_.rc_target_bitrate = 400;
1750   cfg_.ss_target_bitrate[0] = 100;
1751   cfg_.ss_target_bitrate[1] = 300;
1752   cfg_.layer_target_bitrate[0] = 100;
1753   cfg_.layer_target_bitrate[1] = 300;
1754   for (int sl = 0; sl < 2; ++sl) {
1755     float layer_framerate = 30.0;
1756     layer_target_avg_bandwidth_[sl] = static_cast<int>(
1757         cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate);
1758     bits_in_buffer_model_[sl] =
1759         cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz;
1760   }
1761   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1762   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1763                           1.25);
1764 #if CONFIG_VP9_DECODER
1765   // The non-reference frames are expected to be mismatched frames as the
1766   // encoder will avoid loopfilter on these frames.
1767   EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1768 #endif
1769 }
1770 
1771 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSingleBR,
1772                            ::testing::Range(5, 10));
1773 
1774 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcPostencodeDrop,
1775                            ::testing::Range(5, 6));
1776 
1777 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcInterLayerPredSingleBR,
1778                            ::testing::Range(5, 10), ::testing::Range(0, 3));
1779 
1780 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcMultiBR,
1781                            ::testing::Range(5, 10), ::testing::Range(0, 3));
1782 
1783 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcFrameDropMultiBR,
1784                            ::testing::Range(5, 10), ::testing::Range(0, 2),
1785                            ::testing::Range(0, 3));
1786 
1787 #if CONFIG_VP9_TEMPORAL_DENOISING
1788 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcDenoiser,
1789                            ::testing::Range(5, 10), ::testing::Range(1, 3),
1790                            ::testing::Range(0, 3), ::testing::Range(0, 4));
1791 #endif
1792 
1793 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSmallKF,
1794                            ::testing::Range(5, 10), ::testing::Range(32, 36));
1795 }  // namespace
1796 }  // namespace svc_test
1797