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