]> granicus.if.org Git - libvpx/blob - test/svc_datarate_test.cc
Merge "Loopfilter MultiThread Optimization"
[libvpx] / test / svc_datarate_test.cc
1 /*
2  *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "./vpx_config.h"
11 #include "third_party/googletest/src/include/gtest/gtest.h"
12 #include "test/codec_factory.h"
13 #include "test/encode_test_driver.h"
14 #include "test/i420_video_source.h"
15 #include "test/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 {
23
24 class DatarateOnePassCbrSvc : public ::svc_test::OnePassCbrSvc {
25  public:
26   explicit DatarateOnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
27       : OnePassCbrSvc(codec) {
28     inter_layer_pred_mode_ = 0;
29   }
30
31  protected:
32   virtual ~DatarateOnePassCbrSvc() {}
33
34   virtual void ResetModel() {
35     last_pts_ = 0;
36     duration_ = 0.0;
37     mismatch_psnr_ = 0.0;
38     mismatch_nframes_ = 0;
39     denoiser_on_ = 0;
40     tune_content_ = 0;
41     base_speed_setting_ = 5;
42     spatial_layer_id_ = 0;
43     temporal_layer_id_ = 0;
44     update_pattern_ = 0;
45     memset(bits_in_buffer_model_, 0, sizeof(bits_in_buffer_model_));
46     memset(bits_total_, 0, sizeof(bits_total_));
47     memset(layer_target_avg_bandwidth_, 0, sizeof(layer_target_avg_bandwidth_));
48     dynamic_drop_layer_ = false;
49     change_bitrate_ = false;
50     last_pts_ref_ = 0;
51     middle_bitrate_ = 0;
52     top_bitrate_ = 0;
53     superframe_count_ = -1;
54     key_frame_spacing_ = 9999;
55     num_nonref_frames_ = 0;
56     layer_framedrop_ = 0;
57     force_key_ = 0;
58     force_key_test_ = 0;
59     insert_layer_sync_ = 0;
60     layer_sync_on_base_ = 0;
61     force_intra_only_frame_ = 0;
62     superframe_has_intra_only_ = 0;
63   }
64   virtual void BeginPassHook(unsigned int /*pass*/) {}
65
66   // Example pattern for spatial layers and 2 temporal layers used in the
67   // bypass/flexible mode. The pattern corresponds to the pattern
68   // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
69   // non-flexible mode, except that we disable inter-layer prediction.
70   void set_frame_flags_bypass_mode(
71       int tl, int num_spatial_layers, int is_key_frame,
72       vpx_svc_ref_frame_config_t *ref_frame_config) {
73     for (int sl = 0; sl < num_spatial_layers; ++sl)
74       ref_frame_config->update_buffer_slot[sl] = 0;
75
76     for (int sl = 0; sl < num_spatial_layers; ++sl) {
77       if (tl == 0) {
78         ref_frame_config->lst_fb_idx[sl] = sl;
79         if (sl) {
80           if (is_key_frame) {
81             ref_frame_config->lst_fb_idx[sl] = sl - 1;
82             ref_frame_config->gld_fb_idx[sl] = sl;
83           } else {
84             ref_frame_config->gld_fb_idx[sl] = sl - 1;
85           }
86         } else {
87           ref_frame_config->gld_fb_idx[sl] = 0;
88         }
89         ref_frame_config->alt_fb_idx[sl] = 0;
90       } else if (tl == 1) {
91         ref_frame_config->lst_fb_idx[sl] = sl;
92         ref_frame_config->gld_fb_idx[sl] =
93             VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl - 1);
94         ref_frame_config->alt_fb_idx[sl] =
95             VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl);
96       }
97       if (!tl) {
98         if (!sl) {
99           ref_frame_config->reference_last[sl] = 1;
100           ref_frame_config->reference_golden[sl] = 0;
101           ref_frame_config->reference_alt_ref[sl] = 0;
102           ref_frame_config->update_buffer_slot[sl] |=
103               1 << ref_frame_config->lst_fb_idx[sl];
104         } else {
105           if (is_key_frame) {
106             ref_frame_config->reference_last[sl] = 1;
107             ref_frame_config->reference_golden[sl] = 0;
108             ref_frame_config->reference_alt_ref[sl] = 0;
109             ref_frame_config->update_buffer_slot[sl] |=
110                 1 << ref_frame_config->gld_fb_idx[sl];
111           } else {
112             ref_frame_config->reference_last[sl] = 1;
113             ref_frame_config->reference_golden[sl] = 0;
114             ref_frame_config->reference_alt_ref[sl] = 0;
115             ref_frame_config->update_buffer_slot[sl] |=
116                 1 << ref_frame_config->lst_fb_idx[sl];
117           }
118         }
119       } else if (tl == 1) {
120         if (!sl) {
121           ref_frame_config->reference_last[sl] = 1;
122           ref_frame_config->reference_golden[sl] = 0;
123           ref_frame_config->reference_alt_ref[sl] = 0;
124           ref_frame_config->update_buffer_slot[sl] |=
125               1 << ref_frame_config->alt_fb_idx[sl];
126         } else {
127           ref_frame_config->reference_last[sl] = 1;
128           ref_frame_config->reference_golden[sl] = 0;
129           ref_frame_config->reference_alt_ref[sl] = 0;
130           ref_frame_config->update_buffer_slot[sl] |=
131               1 << ref_frame_config->alt_fb_idx[sl];
132         }
133       }
134     }
135   }
136
137   void CheckLayerRateTargeting(int num_spatial_layers, int num_temporal_layers,
138                                double thresh_overshoot,
139                                double thresh_undershoot) const {
140     for (int sl = 0; sl < num_spatial_layers; ++sl)
141       for (int tl = 0; tl < num_temporal_layers; ++tl) {
142         const int layer = sl * num_temporal_layers + tl;
143         ASSERT_GE(cfg_.layer_target_bitrate[layer],
144                   file_datarate_[layer] * thresh_overshoot)
145             << " The datarate for the file exceeds the target by too much!";
146         ASSERT_LE(cfg_.layer_target_bitrate[layer],
147                   file_datarate_[layer] * thresh_undershoot)
148             << " The datarate for the file is lower than the target by too "
149                "much!";
150       }
151   }
152
153   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
154                                   ::libvpx_test::Encoder *encoder) {
155     PreEncodeFrameHookSetup(video, encoder);
156
157     if (video->frame() == 0) {
158       if (force_intra_only_frame_) {
159         // Decoder sets the color_space for Intra-only frames
160         // to BT_601 (see line 1810 in vp9_decodeframe.c).
161         // So set it here in these tess to avoid encoder-decoder
162         // mismatch check on color space setting.
163         encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
164       }
165       encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
166       encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
167       encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
168
169       if (layer_framedrop_) {
170         vpx_svc_frame_drop_t svc_drop_frame;
171         svc_drop_frame.framedrop_mode = LAYER_DROP;
172         for (int i = 0; i < number_spatial_layers_; i++)
173           svc_drop_frame.framedrop_thresh[i] = 30;
174         svc_drop_frame.max_consec_drop = 30;
175         encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
176       }
177     }
178
179     if (update_pattern_ && video->frame() >= 100) {
180       vpx_svc_layer_id_t layer_id;
181       if (video->frame() == 100) {
182         cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
183         encoder->Config(&cfg_);
184       }
185       // Set layer id since the pattern changed.
186       layer_id.spatial_layer_id = 0;
187       layer_id.temporal_layer_id = (video->frame() % 2 != 0);
188       temporal_layer_id_ = layer_id.temporal_layer_id;
189       encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
190       set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
191                                   number_spatial_layers_, 0, &ref_frame_config);
192       encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config);
193     }
194
195     if (change_bitrate_ && video->frame() == 200) {
196       duration_ = (last_pts_ + 1) * timebase_;
197       for (int sl = 0; sl < number_spatial_layers_; ++sl) {
198         for (int tl = 0; tl < number_temporal_layers_; ++tl) {
199           const int layer = sl * number_temporal_layers_ + tl;
200           const double file_size_in_kb = bits_total_[layer] / 1000.;
201           file_datarate_[layer] = file_size_in_kb / duration_;
202         }
203       }
204
205       CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_,
206                               0.78, 1.15);
207
208       memset(file_datarate_, 0, sizeof(file_datarate_));
209       memset(bits_total_, 0, sizeof(bits_total_));
210       int64_t bits_in_buffer_model_tmp[VPX_MAX_LAYERS];
211       last_pts_ref_ = last_pts_;
212       // Set new target bitarate.
213       cfg_.rc_target_bitrate = cfg_.rc_target_bitrate >> 1;
214       // Buffer level should not reset on dynamic bitrate change.
215       memcpy(bits_in_buffer_model_tmp, bits_in_buffer_model_,
216              sizeof(bits_in_buffer_model_));
217       AssignLayerBitrates();
218       memcpy(bits_in_buffer_model_, bits_in_buffer_model_tmp,
219              sizeof(bits_in_buffer_model_));
220
221       // Change config to update encoder with new bitrate configuration.
222       encoder->Config(&cfg_);
223     }
224
225     if (dynamic_drop_layer_) {
226       // TODO(jian): Disable AQ Mode for this test for now.
227       encoder->Control(VP9E_SET_AQ_MODE, 0);
228       if (video->frame() == 0) {
229         // Change layer bitrates to set top layers to 0. This will trigger skip
230         // encoding/dropping of top two spatial layers.
231         cfg_.rc_target_bitrate -=
232             (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
233         middle_bitrate_ = cfg_.layer_target_bitrate[1];
234         top_bitrate_ = cfg_.layer_target_bitrate[2];
235         cfg_.layer_target_bitrate[1] = 0;
236         cfg_.layer_target_bitrate[2] = 0;
237         encoder->Config(&cfg_);
238       } else if (video->frame() == 50) {
239         // Change layer bitrates to non-zero on two top spatial layers.
240         // This will trigger skip encoding of top two spatial layers.
241         cfg_.layer_target_bitrate[1] = middle_bitrate_;
242         cfg_.layer_target_bitrate[2] = top_bitrate_;
243         cfg_.rc_target_bitrate +=
244             cfg_.layer_target_bitrate[2] + cfg_.layer_target_bitrate[1];
245         encoder->Config(&cfg_);
246       } else if (video->frame() == 100) {
247         // Change layer bitrates to set top layers to 0. This will trigger skip
248         // encoding/dropping of top two spatial layers.
249         cfg_.rc_target_bitrate -=
250             (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
251         middle_bitrate_ = cfg_.layer_target_bitrate[1];
252         top_bitrate_ = cfg_.layer_target_bitrate[2];
253         cfg_.layer_target_bitrate[1] = 0;
254         cfg_.layer_target_bitrate[2] = 0;
255         encoder->Config(&cfg_);
256       } else if (video->frame() == 150) {
257         // Change layer bitrate on second layer to non-zero to start
258         // encoding it again.
259         cfg_.layer_target_bitrate[1] = middle_bitrate_;
260         cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[1];
261         encoder->Config(&cfg_);
262       } else if (video->frame() == 200) {
263         // Change layer bitrate on top layer to non-zero to start
264         // encoding it again.
265         cfg_.layer_target_bitrate[2] = top_bitrate_;
266         cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[2];
267         encoder->Config(&cfg_);
268       }
269     }
270
271     if (force_key_test_ && force_key_) frame_flags_ = VPX_EFLAG_FORCE_KF;
272
273     if (insert_layer_sync_) {
274       vpx_svc_spatial_layer_sync_t svc_layer_sync;
275       svc_layer_sync.base_layer_intra_only = 0;
276       for (int i = 0; i < number_spatial_layers_; i++)
277         svc_layer_sync.spatial_layer_sync[i] = 0;
278       if (force_intra_only_frame_) {
279         superframe_has_intra_only_ = 0;
280         if (video->frame() == 0) {
281           svc_layer_sync.base_layer_intra_only = 1;
282           svc_layer_sync.spatial_layer_sync[0] = 1;
283           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
284           superframe_has_intra_only_ = 1;
285         } else if (video->frame() == 100) {
286           svc_layer_sync.base_layer_intra_only = 1;
287           svc_layer_sync.spatial_layer_sync[0] = 1;
288           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
289           superframe_has_intra_only_ = 1;
290         }
291       } else {
292         layer_sync_on_base_ = 0;
293         if (video->frame() == 150) {
294           svc_layer_sync.spatial_layer_sync[1] = 1;
295           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
296         } else if (video->frame() == 240) {
297           svc_layer_sync.spatial_layer_sync[2] = 1;
298           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
299         } else if (video->frame() == 320) {
300           svc_layer_sync.spatial_layer_sync[0] = 1;
301           layer_sync_on_base_ = 1;
302           encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
303         }
304       }
305     }
306
307     const vpx_rational_t tb = video->timebase();
308     timebase_ = static_cast<double>(tb.num) / tb.den;
309     duration_ = 0;
310   }
311
312   vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
313                                          uint32_t sizes[8], int *count) {
314     uint8_t marker;
315     marker = *(data + data_sz - 1);
316     *count = 0;
317     if ((marker & 0xe0) == 0xc0) {
318       const uint32_t frames = (marker & 0x7) + 1;
319       const uint32_t mag = ((marker >> 3) & 0x3) + 1;
320       const size_t index_sz = 2 + mag * frames;
321       // This chunk is marked as having a superframe index but doesn't have
322       // enough data for it, thus it's an invalid superframe index.
323       if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
324       {
325         const uint8_t marker2 = *(data + data_sz - index_sz);
326         // This chunk is marked as having a superframe index but doesn't have
327         // the matching marker byte at the front of the index therefore it's an
328         // invalid chunk.
329         if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
330       }
331       {
332         uint32_t i, j;
333         const uint8_t *x = &data[data_sz - index_sz + 1];
334         for (i = 0; i < frames; ++i) {
335           uint32_t this_sz = 0;
336
337           for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
338           sizes[i] = this_sz;
339         }
340         *count = frames;
341       }
342     }
343     return VPX_CODEC_OK;
344   }
345
346   virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
347     uint32_t sizes[8] = { 0 };
348     uint32_t sizes_parsed[8] = { 0 };
349     int count = 0;
350     int num_layers_encoded = 0;
351     last_pts_ = pkt->data.frame.pts;
352     const bool key_frame =
353         (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
354     if (key_frame) {
355       // For test that inserts layer sync frames: requesting a layer_sync on
356       // the base layer must force key frame. So if any key frame occurs after
357       // first superframe it must due to layer sync on base spatial layer.
358       if (superframe_count_ > 0 && insert_layer_sync_ &&
359           !force_intra_only_frame_) {
360         ASSERT_EQ(layer_sync_on_base_, 1);
361       }
362       temporal_layer_id_ = 0;
363       superframe_count_ = 0;
364     }
365     parse_superframe_index(static_cast<const uint8_t *>(pkt->data.frame.buf),
366                            pkt->data.frame.sz, sizes_parsed, &count);
367     // Count may be less than number of spatial layers because of frame drops.
368     for (int sl = 0; sl < number_spatial_layers_; ++sl) {
369       if (pkt->data.frame.spatial_layer_encoded[sl]) {
370         sizes[sl] = sizes_parsed[num_layers_encoded];
371         num_layers_encoded++;
372       }
373     }
374     // For superframe with Intra-only count will be +1 larger
375     // because of no-show frame.
376     if (force_intra_only_frame_ && superframe_has_intra_only_)
377       ASSERT_EQ(count, num_layers_encoded + 1);
378     else
379       ASSERT_EQ(count, num_layers_encoded);
380
381     // In the constrained frame drop mode, if a given spatial is dropped all
382     // upper layers must be dropped too.
383     if (!layer_framedrop_) {
384       int num_layers_dropped = 0;
385       for (int sl = 0; sl < number_spatial_layers_; ++sl) {
386         if (!pkt->data.frame.spatial_layer_encoded[sl]) {
387           // Check that all upper layers are dropped.
388           num_layers_dropped++;
389           for (int sl2 = sl + 1; sl2 < number_spatial_layers_; ++sl2)
390             ASSERT_EQ(pkt->data.frame.spatial_layer_encoded[sl2], 0);
391         }
392       }
393       if (num_layers_dropped == number_spatial_layers_ - 1)
394         force_key_ = 1;
395       else
396         force_key_ = 0;
397     }
398     // Keep track of number of non-reference frames, needed for mismatch check.
399     // Non-reference frames are top spatial and temporal layer frames,
400     // for TL > 0.
401     if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
402         temporal_layer_id_ > 0 &&
403         pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
404       num_nonref_frames_++;
405     for (int sl = 0; sl < number_spatial_layers_; ++sl) {
406       sizes[sl] = sizes[sl] << 3;
407       // Update the total encoded bits per layer.
408       // For temporal layers, update the cumulative encoded bits per layer.
409       for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
410         const int layer = sl * number_temporal_layers_ + tl;
411         bits_total_[layer] += static_cast<int64_t>(sizes[sl]);
412         // Update the per-layer buffer level with the encoded frame size.
413         bits_in_buffer_model_[layer] -= static_cast<int64_t>(sizes[sl]);
414         // There should be no buffer underrun, except on the base
415         // temporal layer, since there may be key frames there.
416         // Fo short key frame spacing, buffer can underrun on individual frames.
417         if (!key_frame && tl > 0 && key_frame_spacing_ < 100) {
418           ASSERT_GE(bits_in_buffer_model_[layer], 0)
419               << "Buffer Underrun at frame " << pkt->data.frame.pts;
420         }
421       }
422
423       ASSERT_EQ(pkt->data.frame.width[sl],
424                 top_sl_width_ * svc_params_.scaling_factor_num[sl] /
425                     svc_params_.scaling_factor_den[sl]);
426
427       ASSERT_EQ(pkt->data.frame.height[sl],
428                 top_sl_height_ * svc_params_.scaling_factor_num[sl] /
429                     svc_params_.scaling_factor_den[sl]);
430     }
431   }
432
433   virtual void EndPassHook(void) {
434     if (change_bitrate_) last_pts_ = last_pts_ - last_pts_ref_;
435     duration_ = (last_pts_ + 1) * timebase_;
436     for (int sl = 0; sl < number_spatial_layers_; ++sl) {
437       for (int tl = 0; tl < number_temporal_layers_; ++tl) {
438         const int layer = sl * number_temporal_layers_ + tl;
439         const double file_size_in_kb = bits_total_[layer] / 1000.;
440         file_datarate_[layer] = file_size_in_kb / duration_;
441       }
442     }
443   }
444
445   virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
446     double mismatch_psnr = compute_psnr(img1, img2);
447     mismatch_psnr_ += mismatch_psnr;
448     ++mismatch_nframes_;
449   }
450
451   unsigned int GetMismatchFrames() { return mismatch_nframes_; }
452
453   vpx_codec_pts_t last_pts_;
454   double timebase_;
455   int64_t bits_total_[VPX_MAX_LAYERS];
456   double duration_;
457   double file_datarate_[VPX_MAX_LAYERS];
458   size_t bits_in_last_frame_;
459   double mismatch_psnr_;
460   int mismatch_nframes_;
461   int denoiser_on_;
462   int tune_content_;
463   int spatial_layer_id_;
464   bool dynamic_drop_layer_;
465   unsigned int top_sl_width_;
466   unsigned int top_sl_height_;
467   vpx_svc_ref_frame_config_t ref_frame_config;
468   int update_pattern_;
469   bool change_bitrate_;
470   vpx_codec_pts_t last_pts_ref_;
471   int middle_bitrate_;
472   int top_bitrate_;
473   int key_frame_spacing_;
474   unsigned int num_nonref_frames_;
475   int layer_framedrop_;
476   int force_key_;
477   int force_key_test_;
478   int inter_layer_pred_mode_;
479   int insert_layer_sync_;
480   int layer_sync_on_base_;
481   int force_intra_only_frame_;
482   int superframe_has_intra_only_;
483 };
484
485 // Params: speed setting.
486 class DatarateOnePassCbrSvcSingleBR
487     : public DatarateOnePassCbrSvc,
488       public ::libvpx_test::CodecTestWithParam<int> {
489  public:
490   DatarateOnePassCbrSvcSingleBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
491     memset(&svc_params_, 0, sizeof(svc_params_));
492   }
493   virtual ~DatarateOnePassCbrSvcSingleBR() {}
494
495  protected:
496   virtual void SetUp() {
497     InitializeConfig();
498     SetMode(::libvpx_test::kRealTime);
499     speed_setting_ = GET_PARAM(1);
500     ResetModel();
501   }
502 };
503
504 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
505 // temporal layer, with screen content mode on and same speed setting for all
506 // layers.
507 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TLScreenContent1) {
508   cfg_.rc_buf_initial_sz = 500;
509   cfg_.rc_buf_optimal_sz = 500;
510   cfg_.rc_buf_sz = 1000;
511   cfg_.rc_min_quantizer = 0;
512   cfg_.rc_max_quantizer = 63;
513   cfg_.rc_end_usage = VPX_CBR;
514   cfg_.g_lag_in_frames = 0;
515   cfg_.ss_number_layers = 2;
516   cfg_.ts_number_layers = 1;
517   cfg_.ts_rate_decimator[0] = 1;
518   cfg_.g_error_resilient = 1;
519   cfg_.g_threads = 1;
520   cfg_.temporal_layering_mode = 0;
521   svc_params_.scaling_factor_num[0] = 144;
522   svc_params_.scaling_factor_den[0] = 288;
523   svc_params_.scaling_factor_num[1] = 288;
524   svc_params_.scaling_factor_den[1] = 288;
525   cfg_.rc_dropframe_thresh = 10;
526   cfg_.kf_max_dist = 9999;
527   number_spatial_layers_ = cfg_.ss_number_layers;
528   number_temporal_layers_ = cfg_.ts_number_layers;
529   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
530   top_sl_width_ = 1280;
531   top_sl_height_ = 720;
532   cfg_.rc_target_bitrate = 500;
533   ResetModel();
534   tune_content_ = 1;
535   AssignLayerBitrates();
536   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
537   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
538                           1.15);
539 #if CONFIG_VP9_DECODER
540   // The non-reference frames are expected to be mismatched frames as the
541   // encoder will avoid loopfilter on these frames.
542   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
543 #endif
544 }
545
546 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
547 // 3 temporal layers, with force key frame after frame drop
548 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLForceKey) {
549   cfg_.rc_buf_initial_sz = 500;
550   cfg_.rc_buf_optimal_sz = 500;
551   cfg_.rc_buf_sz = 1000;
552   cfg_.rc_min_quantizer = 0;
553   cfg_.rc_max_quantizer = 63;
554   cfg_.rc_end_usage = VPX_CBR;
555   cfg_.g_lag_in_frames = 0;
556   cfg_.ss_number_layers = 3;
557   cfg_.ts_number_layers = 3;
558   cfg_.ts_rate_decimator[0] = 4;
559   cfg_.ts_rate_decimator[1] = 2;
560   cfg_.ts_rate_decimator[2] = 1;
561   cfg_.g_error_resilient = 1;
562   cfg_.g_threads = 1;
563   cfg_.temporal_layering_mode = 3;
564   svc_params_.scaling_factor_num[0] = 72;
565   svc_params_.scaling_factor_den[0] = 288;
566   svc_params_.scaling_factor_num[1] = 144;
567   svc_params_.scaling_factor_den[1] = 288;
568   svc_params_.scaling_factor_num[2] = 288;
569   svc_params_.scaling_factor_den[2] = 288;
570   cfg_.rc_dropframe_thresh = 30;
571   cfg_.kf_max_dist = 9999;
572   number_spatial_layers_ = cfg_.ss_number_layers;
573   number_temporal_layers_ = cfg_.ts_number_layers;
574   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
575                                        0, 400);
576   top_sl_width_ = 640;
577   top_sl_height_ = 480;
578   cfg_.rc_target_bitrate = 100;
579   ResetModel();
580   AssignLayerBitrates();
581   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
582   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
583                           1.25);
584 #if CONFIG_VP9_DECODER
585   // The non-reference frames are expected to be mismatched frames as the
586   // encoder will avoid loopfilter on these frames.
587   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
588 #endif
589 }
590
591 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
592 // 2 temporal layers, with a change on the fly from the fixed SVC pattern to one
593 // generate via SVC_SET_REF_FRAME_CONFIG. The new pattern also disables
594 // inter-layer prediction.
595 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL2TLDynamicPatternChange) {
596   cfg_.rc_buf_initial_sz = 500;
597   cfg_.rc_buf_optimal_sz = 500;
598   cfg_.rc_buf_sz = 1000;
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   cfg_.ss_number_layers = 3;
604   cfg_.ts_number_layers = 2;
605   cfg_.ts_rate_decimator[0] = 2;
606   cfg_.ts_rate_decimator[1] = 1;
607   cfg_.g_error_resilient = 1;
608   cfg_.g_threads = 1;
609   cfg_.temporal_layering_mode = 2;
610   svc_params_.scaling_factor_num[0] = 72;
611   svc_params_.scaling_factor_den[0] = 288;
612   svc_params_.scaling_factor_num[1] = 144;
613   svc_params_.scaling_factor_den[1] = 288;
614   svc_params_.scaling_factor_num[2] = 288;
615   svc_params_.scaling_factor_den[2] = 288;
616   cfg_.rc_dropframe_thresh = 30;
617   cfg_.kf_max_dist = 9999;
618   number_spatial_layers_ = cfg_.ss_number_layers;
619   number_temporal_layers_ = cfg_.ts_number_layers;
620   // Change SVC pattern on the fly.
621   update_pattern_ = 1;
622   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
623                                        0, 400);
624   top_sl_width_ = 640;
625   top_sl_height_ = 480;
626   cfg_.rc_target_bitrate = 800;
627   ResetModel();
628   AssignLayerBitrates();
629   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
630   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
631                           1.15);
632 #if CONFIG_VP9_DECODER
633   // The non-reference frames are expected to be mismatched frames as the
634   // encoder will avoid loopfilter on these frames.
635   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
636 #endif
637 }
638
639 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial layers and on
640 // the fly switching to 1 and then 2 and back to 3 spatial layers. This switch
641 // is done by setting spatial layer bitrates to 0, and then back to non-zero,
642 // during the sequence.
643 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL_DisableEnableLayers) {
644   cfg_.rc_buf_initial_sz = 500;
645   cfg_.rc_buf_optimal_sz = 500;
646   cfg_.rc_buf_sz = 1000;
647   cfg_.rc_min_quantizer = 0;
648   cfg_.rc_max_quantizer = 63;
649   cfg_.rc_end_usage = VPX_CBR;
650   cfg_.g_lag_in_frames = 0;
651   cfg_.ss_number_layers = 3;
652   cfg_.ts_number_layers = 1;
653   cfg_.ts_rate_decimator[0] = 1;
654   cfg_.g_error_resilient = 1;
655   cfg_.g_threads = 1;
656   cfg_.temporal_layering_mode = 0;
657   svc_params_.scaling_factor_num[0] = 72;
658   svc_params_.scaling_factor_den[0] = 288;
659   svc_params_.scaling_factor_num[1] = 144;
660   svc_params_.scaling_factor_den[1] = 288;
661   svc_params_.scaling_factor_num[2] = 288;
662   svc_params_.scaling_factor_den[2] = 288;
663   cfg_.rc_dropframe_thresh = 30;
664   cfg_.kf_max_dist = 9999;
665   number_spatial_layers_ = cfg_.ss_number_layers;
666   number_temporal_layers_ = cfg_.ts_number_layers;
667   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
668                                        0, 400);
669   top_sl_width_ = 640;
670   top_sl_height_ = 480;
671   cfg_.rc_target_bitrate = 800;
672   ResetModel();
673   dynamic_drop_layer_ = true;
674   AssignLayerBitrates();
675   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
676   // Don't check rate targeting on two top spatial layer since they will be
677   // skipped for part of the sequence.
678   CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
679                           0.78, 1.15);
680 #if CONFIG_VP9_DECODER
681   // The non-reference frames are expected to be mismatched frames as the
682   // encoder will avoid loopfilter on these frames.
683   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
684 #endif
685 }
686
687 // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
688 // downscale 5x5.
689 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
690   cfg_.rc_buf_initial_sz = 500;
691   cfg_.rc_buf_optimal_sz = 500;
692   cfg_.rc_buf_sz = 1000;
693   cfg_.rc_min_quantizer = 0;
694   cfg_.rc_max_quantizer = 63;
695   cfg_.rc_end_usage = VPX_CBR;
696   cfg_.g_lag_in_frames = 0;
697   cfg_.ss_number_layers = 2;
698   cfg_.ts_number_layers = 1;
699   cfg_.ts_rate_decimator[0] = 1;
700   cfg_.g_error_resilient = 1;
701   cfg_.g_threads = 3;
702   cfg_.temporal_layering_mode = 0;
703   svc_params_.scaling_factor_num[0] = 256;
704   svc_params_.scaling_factor_den[0] = 1280;
705   svc_params_.scaling_factor_num[1] = 1280;
706   svc_params_.scaling_factor_den[1] = 1280;
707   cfg_.rc_dropframe_thresh = 10;
708   cfg_.kf_max_dist = 999999;
709   cfg_.kf_min_dist = 0;
710   cfg_.ss_target_bitrate[0] = 300;
711   cfg_.ss_target_bitrate[1] = 1400;
712   cfg_.layer_target_bitrate[0] = 300;
713   cfg_.layer_target_bitrate[1] = 1400;
714   cfg_.rc_target_bitrate = 1700;
715   number_spatial_layers_ = cfg_.ss_number_layers;
716   number_temporal_layers_ = cfg_.ts_number_layers;
717   ResetModel();
718   layer_target_avg_bandwidth_[0] = cfg_.layer_target_bitrate[0] * 1000 / 30;
719   bits_in_buffer_model_[0] =
720       cfg_.layer_target_bitrate[0] * cfg_.rc_buf_initial_sz;
721   layer_target_avg_bandwidth_[1] = cfg_.layer_target_bitrate[1] * 1000 / 30;
722   bits_in_buffer_model_[1] =
723       cfg_.layer_target_bitrate[1] * cfg_.rc_buf_initial_sz;
724   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
725   top_sl_width_ = 1280;
726   top_sl_height_ = 720;
727   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
728   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
729                           1.15);
730 #if CONFIG_VP9_DECODER
731   // The non-reference frames are expected to be mismatched frames as the
732   // encoder will avoid loopfilter on these frames.
733   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
734 #endif
735 }
736
737 // Params: speed setting and index for bitrate array.
738 class DatarateOnePassCbrSvcMultiBR
739     : public DatarateOnePassCbrSvc,
740       public ::libvpx_test::CodecTestWith2Params<int, int> {
741  public:
742   DatarateOnePassCbrSvcMultiBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
743     memset(&svc_params_, 0, sizeof(svc_params_));
744   }
745   virtual ~DatarateOnePassCbrSvcMultiBR() {}
746
747  protected:
748   virtual void SetUp() {
749     InitializeConfig();
750     SetMode(::libvpx_test::kRealTime);
751     speed_setting_ = GET_PARAM(1);
752     ResetModel();
753   }
754 };
755
756 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
757 // 3 temporal layers. Run CIF clip with 1 thread.
758 TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassCbrSvc2SL3TL) {
759   cfg_.rc_buf_initial_sz = 500;
760   cfg_.rc_buf_optimal_sz = 500;
761   cfg_.rc_buf_sz = 1000;
762   cfg_.rc_min_quantizer = 0;
763   cfg_.rc_max_quantizer = 63;
764   cfg_.rc_end_usage = VPX_CBR;
765   cfg_.g_lag_in_frames = 0;
766   cfg_.ss_number_layers = 2;
767   cfg_.ts_number_layers = 3;
768   cfg_.ts_rate_decimator[0] = 4;
769   cfg_.ts_rate_decimator[1] = 2;
770   cfg_.ts_rate_decimator[2] = 1;
771   cfg_.g_error_resilient = 1;
772   cfg_.g_threads = 1;
773   cfg_.temporal_layering_mode = 3;
774   svc_params_.scaling_factor_num[0] = 144;
775   svc_params_.scaling_factor_den[0] = 288;
776   svc_params_.scaling_factor_num[1] = 288;
777   svc_params_.scaling_factor_den[1] = 288;
778   cfg_.rc_dropframe_thresh = 30;
779   cfg_.kf_max_dist = 9999;
780   number_spatial_layers_ = cfg_.ss_number_layers;
781   number_temporal_layers_ = cfg_.ts_number_layers;
782   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
783                                        0, 400);
784   top_sl_width_ = 640;
785   top_sl_height_ = 480;
786   const int bitrates[3] = { 200, 400, 600 };
787   // TODO(marpan): Check that effective_datarate for each layer hits the
788   // layer target_bitrate.
789   cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)];
790   ResetModel();
791   AssignLayerBitrates();
792   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
793   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.75,
794                           1.2);
795 #if CONFIG_VP9_DECODER
796   // The non-reference frames are expected to be mismatched frames as the
797   // encoder will avoid loopfilter on these frames.
798   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
799 #endif
800 }
801
802 // Params: speed setting, layer framedrop control and index for bitrate array.
803 class DatarateOnePassCbrSvcFrameDropMultiBR
804     : public DatarateOnePassCbrSvc,
805       public ::libvpx_test::CodecTestWith3Params<int, int, int> {
806  public:
807   DatarateOnePassCbrSvcFrameDropMultiBR()
808       : DatarateOnePassCbrSvc(GET_PARAM(0)) {
809     memset(&svc_params_, 0, sizeof(svc_params_));
810   }
811   virtual ~DatarateOnePassCbrSvcFrameDropMultiBR() {}
812
813  protected:
814   virtual void SetUp() {
815     InitializeConfig();
816     SetMode(::libvpx_test::kRealTime);
817     speed_setting_ = GET_PARAM(1);
818     ResetModel();
819   }
820 };
821
822 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
823 // 3 temporal layers. Run HD clip with 4 threads.
824 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) {
825   cfg_.rc_buf_initial_sz = 500;
826   cfg_.rc_buf_optimal_sz = 500;
827   cfg_.rc_buf_sz = 1000;
828   cfg_.rc_min_quantizer = 0;
829   cfg_.rc_max_quantizer = 63;
830   cfg_.rc_end_usage = VPX_CBR;
831   cfg_.g_lag_in_frames = 0;
832   cfg_.ss_number_layers = 2;
833   cfg_.ts_number_layers = 3;
834   cfg_.ts_rate_decimator[0] = 4;
835   cfg_.ts_rate_decimator[1] = 2;
836   cfg_.ts_rate_decimator[2] = 1;
837   cfg_.g_error_resilient = 1;
838   cfg_.g_threads = 4;
839   cfg_.temporal_layering_mode = 3;
840   svc_params_.scaling_factor_num[0] = 144;
841   svc_params_.scaling_factor_den[0] = 288;
842   svc_params_.scaling_factor_num[1] = 288;
843   svc_params_.scaling_factor_den[1] = 288;
844   cfg_.rc_dropframe_thresh = 30;
845   cfg_.kf_max_dist = 9999;
846   number_spatial_layers_ = cfg_.ss_number_layers;
847   number_temporal_layers_ = cfg_.ts_number_layers;
848   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
849   top_sl_width_ = 1280;
850   top_sl_height_ = 720;
851   layer_framedrop_ = 0;
852   const int bitrates[3] = { 200, 400, 600 };
853   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
854   ResetModel();
855   layer_framedrop_ = GET_PARAM(2);
856   AssignLayerBitrates();
857   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
858   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.71,
859                           1.45);
860 #if CONFIG_VP9_DECODER
861   // The non-reference frames are expected to be mismatched frames as the
862   // encoder will avoid loopfilter on these frames.
863   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
864 #endif
865 }
866
867 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
868 // 3 temporal layers. Run HD clip with 4 threads.
869 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL3TL4Threads) {
870   cfg_.rc_buf_initial_sz = 500;
871   cfg_.rc_buf_optimal_sz = 500;
872   cfg_.rc_buf_sz = 1000;
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   cfg_.ss_number_layers = 3;
878   cfg_.ts_number_layers = 3;
879   cfg_.ts_rate_decimator[0] = 4;
880   cfg_.ts_rate_decimator[1] = 2;
881   cfg_.ts_rate_decimator[2] = 1;
882   cfg_.g_error_resilient = 1;
883   cfg_.g_threads = 4;
884   cfg_.temporal_layering_mode = 3;
885   svc_params_.scaling_factor_num[0] = 72;
886   svc_params_.scaling_factor_den[0] = 288;
887   svc_params_.scaling_factor_num[1] = 144;
888   svc_params_.scaling_factor_den[1] = 288;
889   svc_params_.scaling_factor_num[2] = 288;
890   svc_params_.scaling_factor_den[2] = 288;
891   cfg_.rc_dropframe_thresh = 30;
892   cfg_.kf_max_dist = 9999;
893   number_spatial_layers_ = cfg_.ss_number_layers;
894   number_temporal_layers_ = cfg_.ts_number_layers;
895   ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
896   top_sl_width_ = 1280;
897   top_sl_height_ = 720;
898   layer_framedrop_ = 0;
899   const int bitrates[3] = { 200, 400, 600 };
900   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
901   ResetModel();
902   layer_framedrop_ = GET_PARAM(2);
903   AssignLayerBitrates();
904   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
905   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58,
906                           1.2);
907 #if CONFIG_VP9_DECODER
908   // The non-reference frames are expected to be mismatched frames as the
909   // encoder will avoid loopfilter on these frames.
910   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
911 #endif
912 }
913
914 // Params: speed setting, inter-layer prediction mode.
915 class DatarateOnePassCbrSvcInterLayerPredSingleBR
916     : public DatarateOnePassCbrSvc,
917       public ::libvpx_test::CodecTestWith2Params<int, int> {
918  public:
919   DatarateOnePassCbrSvcInterLayerPredSingleBR()
920       : DatarateOnePassCbrSvc(GET_PARAM(0)) {
921     memset(&svc_params_, 0, sizeof(svc_params_));
922   }
923   virtual ~DatarateOnePassCbrSvcInterLayerPredSingleBR() {}
924
925  protected:
926   virtual void SetUp() {
927     InitializeConfig();
928     SetMode(::libvpx_test::kRealTime);
929     speed_setting_ = GET_PARAM(1);
930     inter_layer_pred_mode_ = GET_PARAM(2);
931     ResetModel();
932   }
933 };
934
935 // Check basic rate targeting with different inter-layer prediction modes for 1
936 // pass CBR SVC: 3 spatial layers and 3 temporal layers. Run CIF clip with 1
937 // thread.
938 TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR, OnePassCbrSvc3SL3TL) {
939   cfg_.rc_buf_initial_sz = 500;
940   cfg_.rc_buf_optimal_sz = 500;
941   cfg_.rc_buf_sz = 1000;
942   cfg_.rc_min_quantizer = 0;
943   cfg_.rc_max_quantizer = 63;
944   cfg_.rc_end_usage = VPX_CBR;
945   cfg_.g_lag_in_frames = 0;
946   cfg_.ss_number_layers = 3;
947   cfg_.ts_number_layers = 3;
948   cfg_.ts_rate_decimator[0] = 4;
949   cfg_.ts_rate_decimator[1] = 2;
950   cfg_.ts_rate_decimator[2] = 1;
951   cfg_.g_error_resilient = 1;
952   cfg_.g_threads = 1;
953   cfg_.temporal_layering_mode = 3;
954   svc_params_.scaling_factor_num[0] = 72;
955   svc_params_.scaling_factor_den[0] = 288;
956   svc_params_.scaling_factor_num[1] = 144;
957   svc_params_.scaling_factor_den[1] = 288;
958   svc_params_.scaling_factor_num[2] = 288;
959   svc_params_.scaling_factor_den[2] = 288;
960   cfg_.rc_dropframe_thresh = 30;
961   cfg_.kf_max_dist = 9999;
962   number_spatial_layers_ = cfg_.ss_number_layers;
963   number_temporal_layers_ = cfg_.ts_number_layers;
964   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
965                                        0, 400);
966   top_sl_width_ = 640;
967   top_sl_height_ = 480;
968   cfg_.rc_target_bitrate = 800;
969   ResetModel();
970   AssignLayerBitrates();
971   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
972   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
973                           1.15);
974 #if CONFIG_VP9_DECODER
975   // The non-reference frames are expected to be mismatched frames as the
976   // encoder will avoid loopfilter on these frames.
977   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
978 #endif
979 }
980
981 // Check rate targeting with different inter-layer prediction modes for 1 pass
982 // CBR SVC: 3 spatial layers and 3 temporal layers, changing the target bitrate
983 // at the middle of encoding.
984 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLDynamicBitrateChange) {
985   cfg_.rc_buf_initial_sz = 500;
986   cfg_.rc_buf_optimal_sz = 500;
987   cfg_.rc_buf_sz = 1000;
988   cfg_.rc_min_quantizer = 0;
989   cfg_.rc_max_quantizer = 63;
990   cfg_.rc_end_usage = VPX_CBR;
991   cfg_.g_lag_in_frames = 0;
992   cfg_.ss_number_layers = 3;
993   cfg_.ts_number_layers = 3;
994   cfg_.ts_rate_decimator[0] = 4;
995   cfg_.ts_rate_decimator[1] = 2;
996   cfg_.ts_rate_decimator[2] = 1;
997   cfg_.g_error_resilient = 1;
998   cfg_.g_threads = 1;
999   cfg_.temporal_layering_mode = 3;
1000   svc_params_.scaling_factor_num[0] = 72;
1001   svc_params_.scaling_factor_den[0] = 288;
1002   svc_params_.scaling_factor_num[1] = 144;
1003   svc_params_.scaling_factor_den[1] = 288;
1004   svc_params_.scaling_factor_num[2] = 288;
1005   svc_params_.scaling_factor_den[2] = 288;
1006   cfg_.rc_dropframe_thresh = 30;
1007   cfg_.kf_max_dist = 9999;
1008   number_spatial_layers_ = cfg_.ss_number_layers;
1009   number_temporal_layers_ = cfg_.ts_number_layers;
1010   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1011                                        0, 400);
1012   top_sl_width_ = 640;
1013   top_sl_height_ = 480;
1014   cfg_.rc_target_bitrate = 800;
1015   ResetModel();
1016   change_bitrate_ = true;
1017   AssignLayerBitrates();
1018   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1019   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1020                           1.15);
1021 #if CONFIG_VP9_DECODER
1022   // The non-reference frames are expected to be mismatched frames as the
1023   // encoder will avoid loopfilter on these frames.
1024   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1025 #endif
1026 }
1027
1028 #if CONFIG_VP9_TEMPORAL_DENOISING
1029 // Params: speed setting, noise sensitivity and index for bitrate array.
1030 class DatarateOnePassCbrSvcDenoiser
1031     : public DatarateOnePassCbrSvc,
1032       public ::libvpx_test::CodecTestWith3Params<int, int, int> {
1033  public:
1034   DatarateOnePassCbrSvcDenoiser() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1035     memset(&svc_params_, 0, sizeof(svc_params_));
1036   }
1037   virtual ~DatarateOnePassCbrSvcDenoiser() {}
1038
1039  protected:
1040   virtual void SetUp() {
1041     InitializeConfig();
1042     SetMode(::libvpx_test::kRealTime);
1043     speed_setting_ = GET_PARAM(1);
1044     ResetModel();
1045   }
1046 };
1047
1048 // Check basic rate targeting for 1 pass CBR SVC with denoising.
1049 // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
1050 TEST_P(DatarateOnePassCbrSvcDenoiser, OnePassCbrSvc2SL3TLDenoiserOn) {
1051   cfg_.rc_buf_initial_sz = 500;
1052   cfg_.rc_buf_optimal_sz = 500;
1053   cfg_.rc_buf_sz = 1000;
1054   cfg_.rc_min_quantizer = 0;
1055   cfg_.rc_max_quantizer = 63;
1056   cfg_.rc_end_usage = VPX_CBR;
1057   cfg_.g_lag_in_frames = 0;
1058   cfg_.ss_number_layers = 2;
1059   cfg_.ts_number_layers = 3;
1060   cfg_.ts_rate_decimator[0] = 4;
1061   cfg_.ts_rate_decimator[1] = 2;
1062   cfg_.ts_rate_decimator[2] = 1;
1063   cfg_.g_error_resilient = 1;
1064   cfg_.g_threads = 2;
1065   cfg_.temporal_layering_mode = 3;
1066   svc_params_.scaling_factor_num[0] = 144;
1067   svc_params_.scaling_factor_den[0] = 288;
1068   svc_params_.scaling_factor_num[1] = 288;
1069   svc_params_.scaling_factor_den[1] = 288;
1070   cfg_.rc_dropframe_thresh = 30;
1071   cfg_.kf_max_dist = 9999;
1072   number_spatial_layers_ = cfg_.ss_number_layers;
1073   number_temporal_layers_ = cfg_.ts_number_layers;
1074   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1075                                        0, 400);
1076   top_sl_width_ = 640;
1077   top_sl_height_ = 480;
1078   const int bitrates[3] = { 600, 800, 1000 };
1079   // TODO(marpan): Check that effective_datarate for each layer hits the
1080   // layer target_bitrate.
1081   // For SVC, noise_sen = 1 means denoising only the top spatial layer
1082   // noise_sen = 2 means denoising the two top spatial layers.
1083   cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1084   ResetModel();
1085   denoiser_on_ = GET_PARAM(2);
1086   AssignLayerBitrates();
1087   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1088   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1089                           1.15);
1090 #if CONFIG_VP9_DECODER
1091   // The non-reference frames are expected to be mismatched frames as the
1092   // encoder will avoid loopfilter on these frames.
1093   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1094 #endif
1095 }
1096 #endif
1097
1098 // Params: speed setting, key frame dist.
1099 class DatarateOnePassCbrSvcSmallKF
1100     : public DatarateOnePassCbrSvc,
1101       public ::libvpx_test::CodecTestWith2Params<int, int> {
1102  public:
1103   DatarateOnePassCbrSvcSmallKF() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1104     memset(&svc_params_, 0, sizeof(svc_params_));
1105   }
1106   virtual ~DatarateOnePassCbrSvcSmallKF() {}
1107
1108  protected:
1109   virtual void SetUp() {
1110     InitializeConfig();
1111     SetMode(::libvpx_test::kRealTime);
1112     speed_setting_ = GET_PARAM(1);
1113     ResetModel();
1114   }
1115 };
1116
1117 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1118 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1119 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc3SL3TLSmallKf) {
1120   cfg_.rc_buf_initial_sz = 500;
1121   cfg_.rc_buf_optimal_sz = 500;
1122   cfg_.rc_buf_sz = 1000;
1123   cfg_.rc_min_quantizer = 0;
1124   cfg_.rc_max_quantizer = 63;
1125   cfg_.rc_end_usage = VPX_CBR;
1126   cfg_.g_lag_in_frames = 0;
1127   cfg_.ss_number_layers = 3;
1128   cfg_.ts_number_layers = 3;
1129   cfg_.ts_rate_decimator[0] = 4;
1130   cfg_.ts_rate_decimator[1] = 2;
1131   cfg_.ts_rate_decimator[2] = 1;
1132   cfg_.g_error_resilient = 1;
1133   cfg_.g_threads = 1;
1134   cfg_.temporal_layering_mode = 3;
1135   svc_params_.scaling_factor_num[0] = 72;
1136   svc_params_.scaling_factor_den[0] = 288;
1137   svc_params_.scaling_factor_num[1] = 144;
1138   svc_params_.scaling_factor_den[1] = 288;
1139   svc_params_.scaling_factor_num[2] = 288;
1140   svc_params_.scaling_factor_den[2] = 288;
1141   cfg_.rc_dropframe_thresh = 10;
1142   cfg_.rc_target_bitrate = 800;
1143   number_spatial_layers_ = cfg_.ss_number_layers;
1144   number_temporal_layers_ = cfg_.ts_number_layers;
1145   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1146                                        0, 400);
1147   top_sl_width_ = 640;
1148   top_sl_height_ = 480;
1149   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1150   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1151   const int kf_dist = GET_PARAM(2);
1152   cfg_.kf_max_dist = kf_dist;
1153   key_frame_spacing_ = kf_dist;
1154   ResetModel();
1155   AssignLayerBitrates();
1156   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1157   // TODO(jianj): webm:1554
1158   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.76,
1159                           1.15);
1160 #if CONFIG_VP9_DECODER
1161   // The non-reference frames are expected to be mismatched frames as the
1162   // encoder will avoid loopfilter on these frames.
1163   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1164 #endif
1165 }
1166
1167 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
1168 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1169 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc2SL3TLSmallKf) {
1170   cfg_.rc_buf_initial_sz = 500;
1171   cfg_.rc_buf_optimal_sz = 500;
1172   cfg_.rc_buf_sz = 1000;
1173   cfg_.rc_min_quantizer = 0;
1174   cfg_.rc_max_quantizer = 63;
1175   cfg_.rc_end_usage = VPX_CBR;
1176   cfg_.g_lag_in_frames = 0;
1177   cfg_.ss_number_layers = 2;
1178   cfg_.ts_number_layers = 3;
1179   cfg_.ts_rate_decimator[0] = 4;
1180   cfg_.ts_rate_decimator[1] = 2;
1181   cfg_.ts_rate_decimator[2] = 1;
1182   cfg_.g_error_resilient = 1;
1183   cfg_.g_threads = 1;
1184   cfg_.temporal_layering_mode = 3;
1185   svc_params_.scaling_factor_num[0] = 144;
1186   svc_params_.scaling_factor_den[0] = 288;
1187   svc_params_.scaling_factor_num[1] = 288;
1188   svc_params_.scaling_factor_den[1] = 288;
1189   cfg_.rc_dropframe_thresh = 10;
1190   cfg_.rc_target_bitrate = 400;
1191   number_spatial_layers_ = cfg_.ss_number_layers;
1192   number_temporal_layers_ = cfg_.ts_number_layers;
1193   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1194                                        0, 400);
1195   top_sl_width_ = 640;
1196   top_sl_height_ = 480;
1197   // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1198   // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1199   const int kf_dist = GET_PARAM(2) + 32;
1200   cfg_.kf_max_dist = kf_dist;
1201   key_frame_spacing_ = kf_dist;
1202   ResetModel();
1203   AssignLayerBitrates();
1204   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1205   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1206                           1.15);
1207 #if CONFIG_VP9_DECODER
1208   // The non-reference frames are expected to be mismatched frames as the
1209   // encoder will avoid loopfilter on these frames.
1210   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1211 #endif
1212 }
1213
1214 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1215 // temporal layers. Run VGA clip with 1 thread, and place layer sync frames:
1216 // one at middle layer first, then another one for top layer, and another
1217 // insert for base spatial layer (which forces key frame).
1218 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLSyncFrames) {
1219   cfg_.rc_buf_initial_sz = 500;
1220   cfg_.rc_buf_optimal_sz = 500;
1221   cfg_.rc_buf_sz = 1000;
1222   cfg_.rc_min_quantizer = 0;
1223   cfg_.rc_max_quantizer = 63;
1224   cfg_.rc_end_usage = VPX_CBR;
1225   cfg_.g_lag_in_frames = 0;
1226   cfg_.ss_number_layers = 3;
1227   cfg_.ts_number_layers = 3;
1228   cfg_.ts_rate_decimator[0] = 4;
1229   cfg_.ts_rate_decimator[1] = 2;
1230   cfg_.ts_rate_decimator[2] = 1;
1231   cfg_.g_error_resilient = 1;
1232   cfg_.g_threads = 1;
1233   cfg_.temporal_layering_mode = 3;
1234   svc_params_.scaling_factor_num[0] = 72;
1235   svc_params_.scaling_factor_den[0] = 288;
1236   svc_params_.scaling_factor_num[1] = 144;
1237   svc_params_.scaling_factor_den[1] = 288;
1238   svc_params_.scaling_factor_num[2] = 288;
1239   svc_params_.scaling_factor_den[2] = 288;
1240   cfg_.kf_max_dist = 9999;
1241   cfg_.rc_dropframe_thresh = 10;
1242   cfg_.rc_target_bitrate = 400;
1243   number_spatial_layers_ = cfg_.ss_number_layers;
1244   number_temporal_layers_ = cfg_.ts_number_layers;
1245   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1246                                        0, 400);
1247   top_sl_width_ = 640;
1248   top_sl_height_ = 480;
1249   ResetModel();
1250   insert_layer_sync_ = 1;
1251   AssignLayerBitrates();
1252   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1253   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1254                           1.15);
1255 #if CONFIG_VP9_DECODER
1256   // The non-reference frames are expected to be mismatched frames as the
1257   // encoder will avoid loopfilter on these frames.
1258   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1259 #endif
1260 }
1261
1262 // Run SVC encoder for 3 spatial layers, 1 temporal layer, with
1263 // intra-only frame as sync frame on base spatial layer.
1264 // Intra_only is inserted at start and in middle of sequence.
1265 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL1TLSyncWithIntraOnly) {
1266   cfg_.rc_buf_initial_sz = 500;
1267   cfg_.rc_buf_optimal_sz = 500;
1268   cfg_.rc_buf_sz = 1000;
1269   cfg_.rc_min_quantizer = 0;
1270   cfg_.rc_max_quantizer = 63;
1271   cfg_.rc_end_usage = VPX_CBR;
1272   cfg_.g_lag_in_frames = 0;
1273   cfg_.ss_number_layers = 3;
1274   cfg_.ts_number_layers = 1;
1275   cfg_.ts_rate_decimator[0] = 1;
1276   cfg_.temporal_layering_mode = 0;
1277   cfg_.g_error_resilient = 1;
1278   cfg_.g_threads = 4;
1279   svc_params_.scaling_factor_num[0] = 72;
1280   svc_params_.scaling_factor_den[0] = 288;
1281   svc_params_.scaling_factor_num[1] = 144;
1282   svc_params_.scaling_factor_den[1] = 288;
1283   svc_params_.scaling_factor_num[2] = 288;
1284   svc_params_.scaling_factor_den[2] = 288;
1285   cfg_.rc_dropframe_thresh = 30;
1286   cfg_.kf_max_dist = 9999;
1287   cfg_.rc_target_bitrate = 400;
1288   number_spatial_layers_ = cfg_.ss_number_layers;
1289   number_temporal_layers_ = cfg_.ts_number_layers;
1290   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1291                                        0, 400);
1292   top_sl_width_ = 640;
1293   top_sl_height_ = 480;
1294   ResetModel();
1295   insert_layer_sync_ = 1;
1296   // Use intra_only frame for sync on base layer.
1297   force_intra_only_frame_ = 1;
1298   AssignLayerBitrates();
1299   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1300   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1301                           1.2);
1302 #if CONFIG_VP9_DECODER
1303   // The non-reference frames are expected to be mismatched frames as the
1304   // encoder will avoid loopfilter on these frames.
1305   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1306 #endif
1307 }
1308
1309 // Run SVC encoder for 2 quality layers (same resolution different,
1310 // bitrates), 1 temporal layer, with screen content mode.
1311 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2QL1TLScreen) {
1312   cfg_.rc_buf_initial_sz = 500;
1313   cfg_.rc_buf_optimal_sz = 500;
1314   cfg_.rc_buf_sz = 1000;
1315   cfg_.rc_min_quantizer = 0;
1316   cfg_.rc_max_quantizer = 56;
1317   cfg_.rc_end_usage = VPX_CBR;
1318   cfg_.g_lag_in_frames = 0;
1319   cfg_.ss_number_layers = 2;
1320   cfg_.ts_number_layers = 1;
1321   cfg_.ts_rate_decimator[0] = 1;
1322   cfg_.temporal_layering_mode = 0;
1323   cfg_.g_error_resilient = 1;
1324   cfg_.g_threads = 2;
1325   svc_params_.scaling_factor_num[0] = 1;
1326   svc_params_.scaling_factor_den[0] = 1;
1327   svc_params_.scaling_factor_num[1] = 1;
1328   svc_params_.scaling_factor_den[1] = 1;
1329   cfg_.rc_dropframe_thresh = 30;
1330   cfg_.kf_max_dist = 9999;
1331   number_spatial_layers_ = cfg_.ss_number_layers;
1332   number_temporal_layers_ = cfg_.ts_number_layers;
1333   ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1334                                        0, 400);
1335   top_sl_width_ = 640;
1336   top_sl_height_ = 480;
1337   ResetModel();
1338   tune_content_ = 1;
1339   // Set the layer bitrates, for 2 spatial layers, 1 temporal.
1340   cfg_.rc_target_bitrate = 400;
1341   cfg_.ss_target_bitrate[0] = 100;
1342   cfg_.ss_target_bitrate[1] = 300;
1343   cfg_.layer_target_bitrate[0] = 100;
1344   cfg_.layer_target_bitrate[1] = 300;
1345   for (int sl = 0; sl < 2; ++sl) {
1346     float layer_framerate = 30.0;
1347     layer_target_avg_bandwidth_[sl] = static_cast<int>(
1348         cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate);
1349     bits_in_buffer_model_[sl] =
1350         cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz;
1351   }
1352   ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1353   CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1354                           1.25);
1355 #if CONFIG_VP9_DECODER
1356   // The non-reference frames are expected to be mismatched frames as the
1357   // encoder will avoid loopfilter on these frames.
1358   EXPECT_EQ(num_nonref_frames_, GetMismatchFrames());
1359 #endif
1360 }
1361
1362 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcSingleBR,
1363                           ::testing::Range(5, 10));
1364
1365 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcInterLayerPredSingleBR,
1366                           ::testing::Range(5, 10), ::testing::Range(0, 3));
1367
1368 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcMultiBR, ::testing::Range(5, 10),
1369                           ::testing::Range(0, 3));
1370
1371 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcFrameDropMultiBR,
1372                           ::testing::Range(5, 10), ::testing::Range(0, 2),
1373                           ::testing::Range(0, 3));
1374
1375 #if CONFIG_VP9_TEMPORAL_DENOISING
1376 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcDenoiser,
1377                           ::testing::Range(5, 10), ::testing::Range(1, 3),
1378                           ::testing::Range(0, 3));
1379 #endif
1380
1381 VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvcSmallKF, ::testing::Range(5, 10),
1382                           ::testing::Range(32, 36));
1383 }  // namespace