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