2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
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.
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"
26 // Inter-layer prediction is on on all frames.
28 // Inter-layer prediction is off on all frames.
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
38 class DatarateOnePassCbrSvc : public OnePassCbrSvc {
40 explicit DatarateOnePassCbrSvc(const ::libvpx_test::CodecFactory *codec)
41 : OnePassCbrSvc(codec) {
42 inter_layer_pred_mode_ = 0;
46 virtual ~DatarateOnePassCbrSvc() {}
48 virtual void ResetModel() {
52 mismatch_nframes_ = 0;
55 base_speed_setting_ = 5;
56 spatial_layer_id_ = 0;
57 temporal_layer_id_ = 0;
59 memset(bits_in_buffer_model_, 0, sizeof(bits_in_buffer_model_));
60 memset(bits_total_, 0, sizeof(bits_total_));
61 memset(layer_target_avg_bandwidth_, 0, sizeof(layer_target_avg_bandwidth_));
62 dynamic_drop_layer_ = false;
63 single_layer_resize_ = false;
64 change_bitrate_ = false;
68 superframe_count_ = -1;
69 key_frame_spacing_ = 9999;
70 num_nonref_frames_ = 0;
74 insert_layer_sync_ = 0;
75 layer_sync_on_base_ = 0;
76 force_intra_only_frame_ = 0;
77 superframe_has_intra_only_ = 0;
78 use_post_encode_drop_ = 0;
79 denoiser_off_on_ = false;
80 denoiser_enable_layers_ = false;
83 for (int i = 0; i < VPX_MAX_LAYERS; i++) {
84 prev_frame_width[i] = 320;
85 prev_frame_height[i] = 240;
87 ksvc_flex_noupd_tlenh_ = false;
89 virtual void BeginPassHook(unsigned int /*pass*/) {}
91 // Example pattern for spatial layers and 2 temporal layers used in the
92 // bypass/flexible mode. The pattern corresponds to the pattern
93 // VP9E_TEMPORAL_LAYERING_MODE_0101 (temporal_layering_mode == 2) used in
94 // non-flexible mode, except that we disable inter-layer prediction.
95 void set_frame_flags_bypass_mode(int tl, int num_spatial_layers,
97 vpx_svc_ref_frame_config_t *ref_frame_config,
99 for (int sl = 0; sl < num_spatial_layers; ++sl)
100 ref_frame_config->update_buffer_slot[sl] = 0;
102 for (int sl = 0; sl < num_spatial_layers; ++sl) {
104 ref_frame_config->lst_fb_idx[sl] = sl;
107 ref_frame_config->lst_fb_idx[sl] = sl - 1;
108 ref_frame_config->gld_fb_idx[sl] = sl;
110 ref_frame_config->gld_fb_idx[sl] = sl - 1;
113 ref_frame_config->gld_fb_idx[sl] = 0;
115 ref_frame_config->alt_fb_idx[sl] = 0;
116 } else if (tl == 1) {
117 ref_frame_config->lst_fb_idx[sl] = sl;
118 ref_frame_config->gld_fb_idx[sl] =
119 VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl - 1);
120 ref_frame_config->alt_fb_idx[sl] =
121 VPXMIN(REF_FRAMES - 1, num_spatial_layers + sl);
125 ref_frame_config->reference_last[sl] = 1;
126 ref_frame_config->reference_golden[sl] = 0;
127 ref_frame_config->reference_alt_ref[sl] = 0;
128 ref_frame_config->update_buffer_slot[sl] |=
129 1 << ref_frame_config->lst_fb_idx[sl];
132 ref_frame_config->reference_last[sl] = 1;
133 ref_frame_config->reference_golden[sl] = 0;
134 ref_frame_config->reference_alt_ref[sl] = 0;
135 ref_frame_config->update_buffer_slot[sl] |=
136 1 << ref_frame_config->gld_fb_idx[sl];
138 ref_frame_config->reference_last[sl] = 1;
139 ref_frame_config->reference_golden[sl] = 0;
140 ref_frame_config->reference_alt_ref[sl] = 0;
141 ref_frame_config->update_buffer_slot[sl] |=
142 1 << ref_frame_config->lst_fb_idx[sl];
145 } else if (tl == 1) {
147 ref_frame_config->reference_last[sl] = 1;
148 ref_frame_config->reference_golden[sl] = 0;
149 ref_frame_config->reference_alt_ref[sl] = 0;
150 ref_frame_config->update_buffer_slot[sl] |=
151 1 << ref_frame_config->alt_fb_idx[sl];
153 ref_frame_config->reference_last[sl] = 1;
154 ref_frame_config->reference_golden[sl] = 0;
155 ref_frame_config->reference_alt_ref[sl] = 0;
156 // Non reference frame on top temporal top spatial.
157 ref_frame_config->update_buffer_slot[sl] = 0;
159 // Force no update on all spatial layers for temporal enhancement layer
161 if (noupdate_tlenh) ref_frame_config->update_buffer_slot[sl] = 0;
166 void CheckLayerRateTargeting(int num_spatial_layers, int num_temporal_layers,
167 double thresh_overshoot,
168 double thresh_undershoot) const {
169 for (int sl = 0; sl < num_spatial_layers; ++sl)
170 for (int tl = 0; tl < num_temporal_layers; ++tl) {
171 const int layer = sl * num_temporal_layers + tl;
172 ASSERT_GE(cfg_.layer_target_bitrate[layer],
173 file_datarate_[layer] * thresh_overshoot)
174 << " The datarate for the file exceeds the target by too much!";
175 ASSERT_LE(cfg_.layer_target_bitrate[layer],
176 file_datarate_[layer] * thresh_undershoot)
177 << " The datarate for the file is lower than the target by too "
182 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
183 ::libvpx_test::Encoder *encoder) {
184 PreEncodeFrameHookSetup(video, encoder);
186 if (video->frame() == 0) {
187 if (force_intra_only_frame_) {
188 // Decoder sets the color_space for Intra-only frames
189 // to BT_601 (see line 1810 in vp9_decodeframe.c).
190 // So set it here in these tess to avoid encoder-decoder
191 // mismatch check on color space setting.
192 encoder->Control(VP9E_SET_COLOR_SPACE, VPX_CS_BT_601);
194 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, denoiser_on_);
195 encoder->Control(VP9E_SET_TUNE_CONTENT, tune_content_);
196 encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, inter_layer_pred_mode_);
198 if (layer_framedrop_) {
199 vpx_svc_frame_drop_t svc_drop_frame;
200 svc_drop_frame.framedrop_mode = LAYER_DROP;
201 for (int i = 0; i < number_spatial_layers_; i++)
202 svc_drop_frame.framedrop_thresh[i] = 30;
203 svc_drop_frame.max_consec_drop = 30;
204 encoder->Control(VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
207 if (use_post_encode_drop_) {
208 encoder->Control(VP9E_SET_POSTENCODE_DROP, use_post_encode_drop_);
212 if (denoiser_off_on_) {
213 encoder->Control(VP9E_SET_AQ_MODE, 3);
214 // Set inter_layer_pred to INTER_LAYER_PRED_OFF_NONKEY (K-SVC).
215 encoder->Control(VP9E_SET_SVC_INTER_LAYER_PRED, 2);
216 if (!denoiser_enable_layers_) {
217 if (video->frame() == 0)
218 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0);
219 else if (video->frame() == 100)
220 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1);
222 // Cumulative bitrates for top spatial layers, for
223 // 3 temporal layers.
224 if (video->frame() == 0) {
225 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 0);
226 // Change layer bitrates to set top spatial layer to 0.
227 // This is for 3 spatial 3 temporal layers.
228 // This will trigger skip encoding/dropping of top spatial layer.
229 cfg_.rc_target_bitrate -= cfg_.layer_target_bitrate[8];
230 for (int i = 0; i < 3; i++)
231 bitrate_sl3_[i] = cfg_.layer_target_bitrate[i + 6];
232 cfg_.layer_target_bitrate[6] = 0;
233 cfg_.layer_target_bitrate[7] = 0;
234 cfg_.layer_target_bitrate[8] = 0;
235 encoder->Config(&cfg_);
236 } else if (video->frame() == 100) {
237 // Change layer bitrates to non-zero on top spatial layer.
238 // This will trigger skip encoding of top spatial layer
239 // on key frame (period = 100).
240 for (int i = 0; i < 3; i++)
241 cfg_.layer_target_bitrate[i + 6] = bitrate_sl3_[i];
242 cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[8];
243 encoder->Config(&cfg_);
244 } else if (video->frame() == 120) {
245 // Enable denoiser and top spatial layer after key frame (period is
247 encoder->Control(VP9E_SET_NOISE_SENSITIVITY, 1);
252 if (ksvc_flex_noupd_tlenh_) {
253 vpx_svc_layer_id_t layer_id;
254 layer_id.spatial_layer_id = 0;
255 layer_id.temporal_layer_id = (video->frame() % 2 != 0);
256 temporal_layer_id_ = layer_id.temporal_layer_id;
257 for (int i = 0; i < number_spatial_layers_; i++) {
258 layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_;
259 ref_frame_config.duration[i] = 1;
261 encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
262 set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
263 number_spatial_layers_, 0, &ref_frame_config,
265 encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config);
268 if (update_pattern_ && video->frame() >= 100) {
269 vpx_svc_layer_id_t layer_id;
270 if (video->frame() == 100) {
271 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
272 encoder->Config(&cfg_);
274 // Set layer id since the pattern changed.
275 layer_id.spatial_layer_id = 0;
276 layer_id.temporal_layer_id = (video->frame() % 2 != 0);
277 temporal_layer_id_ = layer_id.temporal_layer_id;
278 for (int i = 0; i < number_spatial_layers_; i++) {
279 layer_id.temporal_layer_id_per_spatial[i] = temporal_layer_id_;
280 ref_frame_config.duration[i] = 1;
282 encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
283 set_frame_flags_bypass_mode(layer_id.temporal_layer_id,
284 number_spatial_layers_, 0, &ref_frame_config,
286 encoder->Control(VP9E_SET_SVC_REF_FRAME_CONFIG, &ref_frame_config);
289 if (change_bitrate_ && video->frame() == 200) {
290 duration_ = (last_pts_ + 1) * timebase_;
291 for (int sl = 0; sl < number_spatial_layers_; ++sl) {
292 for (int tl = 0; tl < number_temporal_layers_; ++tl) {
293 const int layer = sl * number_temporal_layers_ + tl;
294 const double file_size_in_kb = bits_total_[layer] / 1000.;
295 file_datarate_[layer] = file_size_in_kb / duration_;
299 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_,
302 memset(file_datarate_, 0, sizeof(file_datarate_));
303 memset(bits_total_, 0, sizeof(bits_total_));
304 int64_t bits_in_buffer_model_tmp[VPX_MAX_LAYERS];
305 last_pts_ref_ = last_pts_;
306 // Set new target bitarate.
307 cfg_.rc_target_bitrate = cfg_.rc_target_bitrate >> 1;
308 // Buffer level should not reset on dynamic bitrate change.
309 memcpy(bits_in_buffer_model_tmp, bits_in_buffer_model_,
310 sizeof(bits_in_buffer_model_));
311 AssignLayerBitrates();
312 memcpy(bits_in_buffer_model_, bits_in_buffer_model_tmp,
313 sizeof(bits_in_buffer_model_));
315 // Change config to update encoder with new bitrate configuration.
316 encoder->Config(&cfg_);
319 if (dynamic_drop_layer_ && !single_layer_resize_) {
320 if (video->frame() == 0) {
321 // Change layer bitrates to set top layers to 0. This will trigger skip
322 // encoding/dropping of top two spatial layers.
323 cfg_.rc_target_bitrate -=
324 (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
325 middle_bitrate_ = cfg_.layer_target_bitrate[1];
326 top_bitrate_ = cfg_.layer_target_bitrate[2];
327 cfg_.layer_target_bitrate[1] = 0;
328 cfg_.layer_target_bitrate[2] = 0;
329 encoder->Config(&cfg_);
330 } else if (video->frame() == 50) {
331 // Change layer bitrates to non-zero on two top spatial layers.
332 // This will trigger skip encoding of top two spatial layers.
333 cfg_.layer_target_bitrate[1] = middle_bitrate_;
334 cfg_.layer_target_bitrate[2] = top_bitrate_;
335 cfg_.rc_target_bitrate +=
336 cfg_.layer_target_bitrate[2] + cfg_.layer_target_bitrate[1];
337 encoder->Config(&cfg_);
338 } else if (video->frame() == 100) {
339 // Change layer bitrates to set top layers to 0. This will trigger skip
340 // encoding/dropping of top two spatial layers.
341 cfg_.rc_target_bitrate -=
342 (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
343 middle_bitrate_ = cfg_.layer_target_bitrate[1];
344 top_bitrate_ = cfg_.layer_target_bitrate[2];
345 cfg_.layer_target_bitrate[1] = 0;
346 cfg_.layer_target_bitrate[2] = 0;
347 encoder->Config(&cfg_);
348 } else if (video->frame() == 150) {
349 // Change layer bitrate on second layer to non-zero to start
350 // encoding it again.
351 cfg_.layer_target_bitrate[1] = middle_bitrate_;
352 cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[1];
353 encoder->Config(&cfg_);
354 } else if (video->frame() == 200) {
355 // Change layer bitrate on top layer to non-zero to start
356 // encoding it again.
357 cfg_.layer_target_bitrate[2] = top_bitrate_;
358 cfg_.rc_target_bitrate += cfg_.layer_target_bitrate[2];
359 encoder->Config(&cfg_);
361 } else if (dynamic_drop_layer_ && single_layer_resize_) {
362 // Change layer bitrates to set top layers to 0. This will trigger skip
363 // encoding/dropping of top spatial layers.
364 if (video->frame() == 2) {
365 cfg_.rc_target_bitrate -=
366 (cfg_.layer_target_bitrate[1] + cfg_.layer_target_bitrate[2]);
367 middle_bitrate_ = cfg_.layer_target_bitrate[1];
368 top_bitrate_ = cfg_.layer_target_bitrate[2];
369 cfg_.layer_target_bitrate[1] = 0;
370 cfg_.layer_target_bitrate[2] = 0;
371 // Set spatial layer 0 to a very low bitrate to trigger resize.
372 cfg_.layer_target_bitrate[0] = 30;
373 cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0];
374 encoder->Config(&cfg_);
375 } else if (video->frame() == 100) {
376 // Set base spatial layer to very high to go back up to original size.
377 cfg_.layer_target_bitrate[0] = 400;
378 cfg_.rc_target_bitrate = cfg_.layer_target_bitrate[0];
379 encoder->Config(&cfg_);
381 } else if (!dynamic_drop_layer_ && single_layer_resize_) {
382 if (video->frame() == 2) {
383 cfg_.layer_target_bitrate[0] = 30;
384 cfg_.layer_target_bitrate[1] = 50;
385 cfg_.rc_target_bitrate =
386 (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]);
387 encoder->Config(&cfg_);
388 } else if (video->frame() == 160) {
389 cfg_.layer_target_bitrate[0] = 1500;
390 cfg_.layer_target_bitrate[1] = 2000;
391 cfg_.rc_target_bitrate =
392 (cfg_.layer_target_bitrate[0] + cfg_.layer_target_bitrate[1]);
393 encoder->Config(&cfg_);
396 if (force_key_test_ && force_key_) frame_flags_ = VPX_EFLAG_FORCE_KF;
398 if (insert_layer_sync_) {
399 vpx_svc_spatial_layer_sync_t svc_layer_sync;
400 svc_layer_sync.base_layer_intra_only = 0;
401 for (int i = 0; i < number_spatial_layers_; i++)
402 svc_layer_sync.spatial_layer_sync[i] = 0;
403 if (force_intra_only_frame_) {
404 superframe_has_intra_only_ = 0;
405 if (video->frame() == 0) {
406 svc_layer_sync.base_layer_intra_only = 1;
407 svc_layer_sync.spatial_layer_sync[0] = 1;
408 encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
409 superframe_has_intra_only_ = 1;
410 } else if (video->frame() == 100) {
411 svc_layer_sync.base_layer_intra_only = 1;
412 svc_layer_sync.spatial_layer_sync[0] = 1;
413 encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
414 superframe_has_intra_only_ = 1;
417 layer_sync_on_base_ = 0;
418 if (video->frame() == 150) {
419 svc_layer_sync.spatial_layer_sync[1] = 1;
420 encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
421 } else if (video->frame() == 240) {
422 svc_layer_sync.spatial_layer_sync[2] = 1;
423 encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
424 } else if (video->frame() == 320) {
425 svc_layer_sync.spatial_layer_sync[0] = 1;
426 layer_sync_on_base_ = 1;
427 encoder->Control(VP9E_SET_SVC_SPATIAL_LAYER_SYNC, &svc_layer_sync);
432 const vpx_rational_t tb = video->timebase();
433 timebase_ = static_cast<double>(tb.num) / tb.den;
437 vpx_codec_err_t parse_superframe_index(const uint8_t *data, size_t data_sz,
438 uint32_t sizes[8], int *count) {
440 marker = *(data + data_sz - 1);
442 if ((marker & 0xe0) == 0xc0) {
443 const uint32_t frames = (marker & 0x7) + 1;
444 const uint32_t mag = ((marker >> 3) & 0x3) + 1;
445 const size_t index_sz = 2 + mag * frames;
446 // This chunk is marked as having a superframe index but doesn't have
447 // enough data for it, thus it's an invalid superframe index.
448 if (data_sz < index_sz) return VPX_CODEC_CORRUPT_FRAME;
450 const uint8_t marker2 = *(data + data_sz - index_sz);
451 // This chunk is marked as having a superframe index but doesn't have
452 // the matching marker byte at the front of the index therefore it's an
454 if (marker != marker2) return VPX_CODEC_CORRUPT_FRAME;
458 const uint8_t *x = &data[data_sz - index_sz + 1];
459 for (i = 0; i < frames; ++i) {
460 uint32_t this_sz = 0;
462 for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
471 virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
472 uint32_t sizes[8] = { 0 };
473 uint32_t sizes_parsed[8] = { 0 };
475 int num_layers_encoded = 0;
476 last_pts_ = pkt->data.frame.pts;
477 const bool key_frame =
478 (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
480 // For test that inserts layer sync frames: requesting a layer_sync on
481 // the base layer must force key frame. So if any key frame occurs after
482 // first superframe it must due to layer sync on base spatial layer.
483 if (superframe_count_ > 0 && insert_layer_sync_ &&
484 !force_intra_only_frame_) {
485 ASSERT_EQ(layer_sync_on_base_, 1);
487 temporal_layer_id_ = 0;
488 superframe_count_ = 0;
490 parse_superframe_index(static_cast<const uint8_t *>(pkt->data.frame.buf),
491 pkt->data.frame.sz, sizes_parsed, &count);
492 // Count may be less than number of spatial layers because of frame drops.
493 if (number_spatial_layers_ > 1) {
494 for (int sl = 0; sl < number_spatial_layers_; ++sl) {
495 if (pkt->data.frame.spatial_layer_encoded[sl]) {
496 sizes[sl] = sizes_parsed[num_layers_encoded];
497 num_layers_encoded++;
501 // For superframe with Intra-only count will be +1 larger
502 // because of no-show frame.
503 if (force_intra_only_frame_ && superframe_has_intra_only_)
504 ASSERT_EQ(count, num_layers_encoded + 1);
506 ASSERT_EQ(count, num_layers_encoded);
508 // In the constrained frame drop mode, if a given spatial is dropped all
509 // upper layers must be dropped too.
510 if (!layer_framedrop_) {
511 int num_layers_dropped = 0;
512 for (int sl = 0; sl < number_spatial_layers_; ++sl) {
513 if (!pkt->data.frame.spatial_layer_encoded[sl]) {
514 // Check that all upper layers are dropped.
515 num_layers_dropped++;
516 for (int sl2 = sl + 1; sl2 < number_spatial_layers_; ++sl2)
517 ASSERT_EQ(pkt->data.frame.spatial_layer_encoded[sl2], 0);
520 if (num_layers_dropped == number_spatial_layers_ - 1)
525 // Keep track of number of non-reference frames, needed for mismatch check.
526 // Non-reference frames are top spatial and temporal layer frames,
528 if (temporal_layer_id_ == number_temporal_layers_ - 1 &&
529 temporal_layer_id_ > 0 &&
530 pkt->data.frame.spatial_layer_encoded[number_spatial_layers_ - 1])
531 num_nonref_frames_++;
532 for (int sl = 0; sl < number_spatial_layers_; ++sl) {
533 sizes[sl] = sizes[sl] << 3;
534 // Update the total encoded bits per layer.
535 // For temporal layers, update the cumulative encoded bits per layer.
536 for (int tl = temporal_layer_id_; tl < number_temporal_layers_; ++tl) {
537 const int layer = sl * number_temporal_layers_ + tl;
538 bits_total_[layer] += static_cast<int64_t>(sizes[sl]);
539 // Update the per-layer buffer level with the encoded frame size.
540 bits_in_buffer_model_[layer] -= static_cast<int64_t>(sizes[sl]);
541 // There should be no buffer underrun, except on the base
542 // temporal layer, since there may be key frames there.
543 // Fo short key frame spacing, buffer can underrun on individual frames.
544 if (!key_frame && tl > 0 && key_frame_spacing_ < 100) {
545 ASSERT_GE(bits_in_buffer_model_[layer], 0)
546 << "Buffer Underrun at frame " << pkt->data.frame.pts;
550 if (!single_layer_resize_) {
551 ASSERT_EQ(pkt->data.frame.width[sl],
552 top_sl_width_ * svc_params_.scaling_factor_num[sl] /
553 svc_params_.scaling_factor_den[sl]);
555 ASSERT_EQ(pkt->data.frame.height[sl],
556 top_sl_height_ * svc_params_.scaling_factor_num[sl] /
557 svc_params_.scaling_factor_den[sl]);
558 } else if (superframe_count_ > 0) {
559 if (pkt->data.frame.width[sl] < prev_frame_width[sl] &&
560 pkt->data.frame.height[sl] < prev_frame_height[sl])
561 num_resize_down_ += 1;
562 if (pkt->data.frame.width[sl] > prev_frame_width[sl] &&
563 pkt->data.frame.height[sl] > prev_frame_height[sl])
566 prev_frame_width[sl] = pkt->data.frame.width[sl];
567 prev_frame_height[sl] = pkt->data.frame.height[sl];
571 virtual void EndPassHook(void) {
572 if (change_bitrate_) last_pts_ = last_pts_ - last_pts_ref_;
573 duration_ = (last_pts_ + 1) * timebase_;
574 for (int sl = 0; sl < number_spatial_layers_; ++sl) {
575 for (int tl = 0; tl < number_temporal_layers_; ++tl) {
576 const int layer = sl * number_temporal_layers_ + tl;
577 const double file_size_in_kb = bits_total_[layer] / 1000.;
578 file_datarate_[layer] = file_size_in_kb / duration_;
583 virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
584 // TODO(marpan): Look into why an assert is triggered in compute_psnr
585 // for mismatch frames for the special test case: ksvc_flex_noupd_tlenh.
586 // Has to do with dropped frames in bypass/flexible svc mode.
587 if (!ksvc_flex_noupd_tlenh_) {
588 double mismatch_psnr = compute_psnr(img1, img2);
589 mismatch_psnr_ += mismatch_psnr;
594 unsigned int GetMismatchFrames() { return mismatch_nframes_; }
595 unsigned int GetNonRefFrames() { return num_nonref_frames_; }
597 vpx_codec_pts_t last_pts_;
599 int64_t bits_total_[VPX_MAX_LAYERS];
601 double file_datarate_[VPX_MAX_LAYERS];
602 size_t bits_in_last_frame_;
603 double mismatch_psnr_;
606 int spatial_layer_id_;
607 bool dynamic_drop_layer_;
608 bool single_layer_resize_;
609 unsigned int top_sl_width_;
610 unsigned int top_sl_height_;
611 vpx_svc_ref_frame_config_t ref_frame_config;
613 bool change_bitrate_;
614 vpx_codec_pts_t last_pts_ref_;
617 int key_frame_spacing_;
618 int layer_framedrop_;
621 int inter_layer_pred_mode_;
622 int insert_layer_sync_;
623 int layer_sync_on_base_;
624 int force_intra_only_frame_;
625 int superframe_has_intra_only_;
626 int use_post_encode_drop_;
628 // Denoiser switched on the fly.
629 bool denoiser_off_on_;
630 // Top layer enabled on the fly.
631 bool denoiser_enable_layers_;
633 int num_resize_down_;
634 unsigned int prev_frame_width[VPX_MAX_LAYERS];
635 unsigned int prev_frame_height[VPX_MAX_LAYERS];
636 bool ksvc_flex_noupd_tlenh_;
639 virtual void SetConfig(const int num_temporal_layer) {
640 cfg_.rc_end_usage = VPX_CBR;
641 cfg_.g_lag_in_frames = 0;
642 cfg_.g_error_resilient = 1;
643 if (num_temporal_layer == 3) {
644 cfg_.ts_rate_decimator[0] = 4;
645 cfg_.ts_rate_decimator[1] = 2;
646 cfg_.ts_rate_decimator[2] = 1;
647 cfg_.temporal_layering_mode = 3;
648 } else if (num_temporal_layer == 2) {
649 cfg_.ts_rate_decimator[0] = 2;
650 cfg_.ts_rate_decimator[1] = 1;
651 cfg_.temporal_layering_mode = 2;
652 } else if (num_temporal_layer == 1) {
653 cfg_.ts_rate_decimator[0] = 1;
654 cfg_.temporal_layering_mode = 0;
658 unsigned int num_nonref_frames_;
659 unsigned int mismatch_nframes_;
662 // Params: speed setting.
663 class DatarateOnePassCbrSvcSingleBR
664 : public DatarateOnePassCbrSvc,
665 public ::libvpx_test::CodecTestWithParam<int> {
667 DatarateOnePassCbrSvcSingleBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
668 memset(&svc_params_, 0, sizeof(svc_params_));
670 virtual ~DatarateOnePassCbrSvcSingleBR() {}
673 virtual void SetUp() {
675 SetMode(::libvpx_test::kRealTime);
676 speed_setting_ = GET_PARAM(1);
681 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 1
682 // temporal layer, with screen content mode on and same speed setting for all
684 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TLScreenContent1) {
686 cfg_.rc_buf_initial_sz = 500;
687 cfg_.rc_buf_optimal_sz = 500;
688 cfg_.rc_buf_sz = 1000;
689 cfg_.rc_min_quantizer = 0;
690 cfg_.rc_max_quantizer = 63;
692 cfg_.rc_dropframe_thresh = 10;
693 cfg_.kf_max_dist = 9999;
695 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
696 top_sl_width_ = 1280;
697 top_sl_height_ = 720;
698 cfg_.rc_target_bitrate = 500;
701 AssignLayerBitrates();
702 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
703 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
705 #if CONFIG_VP9_DECODER
706 // The non-reference frames are expected to be mismatched frames as the
707 // encoder will avoid loopfilter on these frames.
708 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
712 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
713 // 3 temporal layers, with force key frame after frame drop
714 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLForceKey) {
716 cfg_.rc_buf_initial_sz = 500;
717 cfg_.rc_buf_optimal_sz = 500;
718 cfg_.rc_buf_sz = 1000;
719 cfg_.rc_min_quantizer = 0;
720 cfg_.rc_max_quantizer = 63;
722 cfg_.rc_dropframe_thresh = 30;
723 cfg_.kf_max_dist = 9999;
724 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
727 top_sl_height_ = 480;
728 cfg_.rc_target_bitrate = 100;
730 AssignLayerBitrates();
731 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
732 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
734 #if CONFIG_VP9_DECODER
735 // The non-reference frames are expected to be mismatched frames as the
736 // encoder will avoid loopfilter on these frames.
737 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
741 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
742 // 2 temporal layers, with a change on the fly from the fixed SVC pattern to one
743 // generate via SVC_SET_REF_FRAME_CONFIG. The new pattern also disables
744 // inter-layer prediction.
745 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL2TLDynamicPatternChange) {
747 cfg_.rc_buf_initial_sz = 500;
748 cfg_.rc_buf_optimal_sz = 500;
749 cfg_.rc_buf_sz = 1000;
750 cfg_.rc_min_quantizer = 0;
751 cfg_.rc_max_quantizer = 63;
753 cfg_.rc_dropframe_thresh = 30;
754 cfg_.kf_max_dist = 9999;
755 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
758 top_sl_height_ = 480;
759 cfg_.rc_target_bitrate = 800;
761 // Change SVC pattern on the fly.
763 AssignLayerBitrates();
764 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
765 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
767 #if CONFIG_VP9_DECODER
768 // The non-reference frames are expected to be mismatched frames as the
769 // encoder will avoid loopfilter on these frames.
770 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
774 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal
775 // layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching
776 // of denoiser from off to on (on at frame = 100). Key frame period is set to
777 // 1000 so denoise is enabled on non-key.
778 TEST_P(DatarateOnePassCbrSvcSingleBR,
779 OnePassCbrSvc3SL3TL_DenoiserOffOnFixedLayers) {
781 cfg_.rc_buf_initial_sz = 500;
782 cfg_.rc_buf_optimal_sz = 500;
783 cfg_.rc_buf_sz = 1000;
784 cfg_.rc_min_quantizer = 0;
785 cfg_.rc_max_quantizer = 63;
787 cfg_.rc_dropframe_thresh = 30;
788 cfg_.kf_max_dist = 1000;
789 ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
791 top_sl_width_ = 1280;
792 top_sl_height_ = 720;
793 cfg_.rc_target_bitrate = 1000;
795 denoiser_off_on_ = true;
796 denoiser_enable_layers_ = false;
797 AssignLayerBitrates();
798 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
799 // Don't check rate targeting on two top spatial layer since they will be
800 // skipped for part of the sequence.
801 CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
803 #if CONFIG_VP9_DECODER
804 // The non-reference frames are expected to be mismatched frames as the
805 // encoder will avoid loopfilter on these frames.
806 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
810 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial and 3 temporal
811 // layers, for inter_layer_pred=OffKey (K-SVC) and on the fly switching
812 // of denoiser from off to on, for dynamic layers. Start at 2 spatial layers
813 // and enable 3rd spatial layer at frame = 100. Use periodic key frame with
814 // period 100 so enabling of spatial layer occurs at key frame. Enable denoiser
815 // at frame > 100, after the key frame sync.
816 TEST_P(DatarateOnePassCbrSvcSingleBR,
817 OnePassCbrSvc3SL3TL_DenoiserOffOnEnableLayers) {
819 cfg_.rc_buf_initial_sz = 500;
820 cfg_.rc_buf_optimal_sz = 500;
821 cfg_.rc_buf_sz = 1000;
822 cfg_.rc_min_quantizer = 0;
823 cfg_.rc_max_quantizer = 63;
825 cfg_.rc_dropframe_thresh = 0;
826 cfg_.kf_max_dist = 100;
827 ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
829 top_sl_width_ = 1280;
830 top_sl_height_ = 720;
831 cfg_.rc_target_bitrate = 1000;
833 denoiser_off_on_ = true;
834 denoiser_enable_layers_ = true;
835 AssignLayerBitrates();
836 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
837 // Don't check rate targeting on two top spatial layer since they will be
838 // skipped for part of the sequence.
839 CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
841 #if CONFIG_VP9_DECODER
842 // The non-reference frames are expected to be mismatched frames as the
843 // encoder will avoid loopfilter on these frames.
844 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
848 // Check basic rate targeting for 1 pass CBR SVC with 3 spatial layers and on
849 // the fly switching to 1 and then 2 and back to 3 spatial layers. This switch
850 // is done by setting spatial layer bitrates to 0, and then back to non-zero,
851 // during the sequence.
852 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL_DisableEnableLayers) {
854 cfg_.rc_buf_initial_sz = 500;
855 cfg_.rc_buf_optimal_sz = 500;
856 cfg_.rc_buf_sz = 1000;
857 cfg_.rc_min_quantizer = 0;
858 cfg_.rc_max_quantizer = 63;
860 cfg_.temporal_layering_mode = 0;
861 cfg_.rc_dropframe_thresh = 30;
862 cfg_.kf_max_dist = 9999;
863 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
866 top_sl_height_ = 480;
867 cfg_.rc_target_bitrate = 800;
869 dynamic_drop_layer_ = true;
870 AssignLayerBitrates();
871 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
872 // Don't check rate targeting on two top spatial layer since they will be
873 // skipped for part of the sequence.
874 CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
876 #if CONFIG_VP9_DECODER
877 // The non-reference frames are expected to be mismatched frames as the
878 // encoder will avoid loopfilter on these frames.
879 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
883 // Check basic rate targeting for 1 pass CBR SVC with 2 spatial layers and on
884 // the fly switching to 1 spatial layer with dynamic resize enabled.
885 // The resizer will resize the single layer down and back up again, as the
886 // bitrate goes back up.
887 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL_SingleLayerResize) {
889 cfg_.rc_buf_initial_sz = 500;
890 cfg_.rc_buf_optimal_sz = 500;
891 cfg_.rc_buf_sz = 1000;
892 cfg_.rc_min_quantizer = 0;
893 cfg_.rc_max_quantizer = 63;
895 cfg_.temporal_layering_mode = 0;
896 cfg_.rc_dropframe_thresh = 30;
897 cfg_.kf_max_dist = 9999;
898 cfg_.rc_resize_allowed = 1;
899 ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
901 top_sl_width_ = 1280;
902 top_sl_height_ = 720;
903 cfg_.rc_target_bitrate = 800;
905 dynamic_drop_layer_ = true;
906 single_layer_resize_ = true;
907 base_speed_setting_ = speed_setting_;
908 AssignLayerBitrates();
909 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
910 // Expect at least one resize down and at least one resize back up.
911 EXPECT_GE(num_resize_down_, 1);
912 EXPECT_GE(num_resize_up_, 1);
913 // Don't check rate targeting on two top spatial layer since they will be
914 // skipped for part of the sequence.
915 CheckLayerRateTargeting(number_spatial_layers_ - 2, number_temporal_layers_,
917 #if CONFIG_VP9_DECODER
918 // The non-reference frames are expected to be mismatched frames as the
919 // encoder will avoid loopfilter on these frames.
920 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
924 // For pass CBR SVC with 1 spatial and 2 temporal layers with dynamic resize
925 // and denoiser enabled. The resizer will resize the single layer down and back
926 // up again, as the bitrate goes back up.
927 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc1SL2TL_DenoiseResize) {
929 cfg_.rc_buf_initial_sz = 500;
930 cfg_.rc_buf_optimal_sz = 500;
931 cfg_.rc_buf_sz = 1000;
932 cfg_.rc_min_quantizer = 0;
933 cfg_.rc_max_quantizer = 63;
935 cfg_.temporal_layering_mode = 2;
936 cfg_.rc_dropframe_thresh = 30;
937 cfg_.kf_max_dist = 9999;
938 cfg_.rc_resize_allowed = 1;
939 ::libvpx_test::I420VideoSource video("desktop_office1.1280_720-020.yuv", 1280,
941 top_sl_width_ = 1280;
942 top_sl_height_ = 720;
943 cfg_.rc_target_bitrate = 800;
945 dynamic_drop_layer_ = false;
946 single_layer_resize_ = true;
948 base_speed_setting_ = speed_setting_;
949 AssignLayerBitrates();
950 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
951 // Expect at least one resize down and at least one resize back up.
952 EXPECT_GE(num_resize_down_, 1);
953 EXPECT_GE(num_resize_up_, 1);
956 // Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
958 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2SL1TL5x5MultipleRuns) {
959 cfg_.rc_buf_initial_sz = 500;
960 cfg_.rc_buf_optimal_sz = 500;
961 cfg_.rc_buf_sz = 1000;
962 cfg_.rc_min_quantizer = 0;
963 cfg_.rc_max_quantizer = 63;
964 cfg_.rc_end_usage = VPX_CBR;
965 cfg_.g_lag_in_frames = 0;
966 cfg_.ss_number_layers = 2;
967 cfg_.ts_number_layers = 1;
968 cfg_.ts_rate_decimator[0] = 1;
969 cfg_.g_error_resilient = 1;
971 cfg_.temporal_layering_mode = 0;
972 svc_params_.scaling_factor_num[0] = 256;
973 svc_params_.scaling_factor_den[0] = 1280;
974 svc_params_.scaling_factor_num[1] = 1280;
975 svc_params_.scaling_factor_den[1] = 1280;
976 cfg_.rc_dropframe_thresh = 10;
977 cfg_.kf_max_dist = 999999;
978 cfg_.kf_min_dist = 0;
979 cfg_.ss_target_bitrate[0] = 300;
980 cfg_.ss_target_bitrate[1] = 1400;
981 cfg_.layer_target_bitrate[0] = 300;
982 cfg_.layer_target_bitrate[1] = 1400;
983 cfg_.rc_target_bitrate = 1700;
984 number_spatial_layers_ = cfg_.ss_number_layers;
985 number_temporal_layers_ = cfg_.ts_number_layers;
987 layer_target_avg_bandwidth_[0] = cfg_.layer_target_bitrate[0] * 1000 / 30;
988 bits_in_buffer_model_[0] =
989 cfg_.layer_target_bitrate[0] * cfg_.rc_buf_initial_sz;
990 layer_target_avg_bandwidth_[1] = cfg_.layer_target_bitrate[1] * 1000 / 30;
991 bits_in_buffer_model_[1] =
992 cfg_.layer_target_bitrate[1] * cfg_.rc_buf_initial_sz;
993 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
994 top_sl_width_ = 1280;
995 top_sl_height_ = 720;
996 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
997 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
999 #if CONFIG_VP9_DECODER
1000 // The non-reference frames are expected to be mismatched frames as the
1001 // encoder will avoid loopfilter on these frames.
1002 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1006 // Params: speed setting and index for bitrate array.
1007 class DatarateOnePassCbrSvcMultiBR
1008 : public DatarateOnePassCbrSvc,
1009 public ::libvpx_test::CodecTestWith2Params<int, int> {
1011 DatarateOnePassCbrSvcMultiBR() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1012 memset(&svc_params_, 0, sizeof(svc_params_));
1014 virtual ~DatarateOnePassCbrSvcMultiBR() {}
1017 virtual void SetUp() {
1019 SetMode(::libvpx_test::kRealTime);
1020 speed_setting_ = GET_PARAM(1);
1025 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1026 // 3 temporal layers. Run CIF clip with 1 thread.
1027 TEST_P(DatarateOnePassCbrSvcMultiBR, OnePassCbrSvc2SL3TL) {
1029 cfg_.rc_buf_initial_sz = 500;
1030 cfg_.rc_buf_optimal_sz = 500;
1031 cfg_.rc_buf_sz = 1000;
1032 cfg_.rc_min_quantizer = 0;
1033 cfg_.rc_max_quantizer = 63;
1035 cfg_.rc_dropframe_thresh = 30;
1036 cfg_.kf_max_dist = 9999;
1037 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1039 top_sl_width_ = 640;
1040 top_sl_height_ = 480;
1041 const int bitrates[3] = { 200, 400, 600 };
1042 // TODO(marpan): Check that effective_datarate for each layer hits the
1043 // layer target_bitrate.
1044 cfg_.rc_target_bitrate = bitrates[GET_PARAM(2)];
1046 AssignLayerBitrates();
1047 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1048 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.75,
1050 #if CONFIG_VP9_DECODER
1051 // The non-reference frames are expected to be mismatched frames as the
1052 // encoder will avoid loopfilter on these frames.
1053 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1057 // Params: speed setting, layer framedrop control and index for bitrate array.
1058 class DatarateOnePassCbrSvcFrameDropMultiBR
1059 : public DatarateOnePassCbrSvc,
1060 public ::libvpx_test::CodecTestWith3Params<int, int, int> {
1062 DatarateOnePassCbrSvcFrameDropMultiBR()
1063 : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1064 memset(&svc_params_, 0, sizeof(svc_params_));
1066 virtual ~DatarateOnePassCbrSvcFrameDropMultiBR() {}
1069 virtual void SetUp() {
1071 SetMode(::libvpx_test::kRealTime);
1072 speed_setting_ = GET_PARAM(1);
1077 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
1078 // 3 temporal layers. Run HD clip with 4 threads.
1079 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc2SL3TL4Threads) {
1081 cfg_.rc_buf_initial_sz = 500;
1082 cfg_.rc_buf_optimal_sz = 500;
1083 cfg_.rc_buf_sz = 1000;
1084 cfg_.rc_min_quantizer = 0;
1085 cfg_.rc_max_quantizer = 63;
1087 cfg_.rc_dropframe_thresh = 30;
1088 cfg_.kf_max_dist = 9999;
1089 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1090 top_sl_width_ = 1280;
1091 top_sl_height_ = 720;
1092 layer_framedrop_ = 0;
1093 const int bitrates[3] = { 200, 400, 600 };
1094 cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1096 layer_framedrop_ = GET_PARAM(2);
1097 AssignLayerBitrates();
1098 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1099 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.64,
1101 #if CONFIG_VP9_DECODER
1102 // The non-reference frames are expected to be mismatched frames as the
1103 // encoder will avoid loopfilter on these frames.
1104 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1108 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1109 // 3 temporal layers. Run HD clip with 4 threads.
1110 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL3TL4Threads) {
1112 cfg_.rc_buf_initial_sz = 500;
1113 cfg_.rc_buf_optimal_sz = 500;
1114 cfg_.rc_buf_sz = 1000;
1115 cfg_.rc_min_quantizer = 0;
1116 cfg_.rc_max_quantizer = 63;
1118 cfg_.rc_dropframe_thresh = 30;
1119 cfg_.kf_max_dist = 9999;
1120 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1121 top_sl_width_ = 1280;
1122 top_sl_height_ = 720;
1123 layer_framedrop_ = 0;
1124 const int bitrates[3] = { 200, 400, 600 };
1125 cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1127 layer_framedrop_ = GET_PARAM(2);
1128 AssignLayerBitrates();
1129 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1130 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58,
1132 #if CONFIG_VP9_DECODER
1133 // The non-reference frames are expected to be mismatched frames as the
1134 // encoder will avoid loopfilter on these frames.
1135 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1139 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
1140 // 2 temporal layers, for KSVC in flexible mode with no update of reference
1141 // frames for all spatial layers on TL > 0 superframes.
1142 // Run HD clip with 4 threads.
1143 TEST_P(DatarateOnePassCbrSvcFrameDropMultiBR, OnePassCbrSvc3SL2TL4ThKSVCFlex) {
1145 cfg_.rc_buf_initial_sz = 500;
1146 cfg_.rc_buf_optimal_sz = 500;
1147 cfg_.rc_buf_sz = 1000;
1148 cfg_.rc_min_quantizer = 0;
1149 cfg_.rc_max_quantizer = 63;
1151 cfg_.rc_dropframe_thresh = 30;
1152 cfg_.kf_max_dist = 9999;
1153 ::libvpx_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
1154 top_sl_width_ = 1280;
1155 top_sl_height_ = 720;
1156 layer_framedrop_ = 0;
1157 const int bitrates[3] = { 200, 400, 600 };
1158 cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1160 layer_framedrop_ = GET_PARAM(2);
1161 AssignLayerBitrates();
1162 ksvc_flex_noupd_tlenh_ = true;
1163 cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
1164 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1165 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.58,
1169 // Params: speed setting, inter-layer prediction mode.
1170 class DatarateOnePassCbrSvcInterLayerPredSingleBR
1171 : public DatarateOnePassCbrSvc,
1172 public ::libvpx_test::CodecTestWith2Params<int, int> {
1174 DatarateOnePassCbrSvcInterLayerPredSingleBR()
1175 : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1176 memset(&svc_params_, 0, sizeof(svc_params_));
1178 virtual ~DatarateOnePassCbrSvcInterLayerPredSingleBR() {}
1181 virtual void SetUp() {
1183 SetMode(::libvpx_test::kRealTime);
1184 speed_setting_ = GET_PARAM(1);
1185 inter_layer_pred_mode_ = GET_PARAM(2);
1190 // Check basic rate targeting with different inter-layer prediction modes for 1
1191 // pass CBR SVC: 3 spatial layers and 3 temporal layers. Run CIF clip with 1
1193 TEST_P(DatarateOnePassCbrSvcInterLayerPredSingleBR, OnePassCbrSvc3SL3TL) {
1194 // Disable test for inter-layer pred off for now since simulcast_mode fails.
1195 if (inter_layer_pred_mode_ == INTER_LAYER_PRED_OFF) return;
1197 cfg_.rc_buf_initial_sz = 500;
1198 cfg_.rc_buf_optimal_sz = 500;
1199 cfg_.rc_buf_sz = 1000;
1200 cfg_.rc_min_quantizer = 0;
1201 cfg_.rc_max_quantizer = 63;
1203 cfg_.temporal_layering_mode = 3;
1204 cfg_.rc_dropframe_thresh = 30;
1205 cfg_.kf_max_dist = 9999;
1206 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1208 top_sl_width_ = 640;
1209 top_sl_height_ = 480;
1210 cfg_.rc_target_bitrate = 800;
1212 AssignLayerBitrates();
1213 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1214 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1216 #if CONFIG_VP9_DECODER
1217 // The non-reference frames are expected to be mismatched frames as the
1218 // encoder will avoid loopfilter on these frames.
1219 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1223 // Check rate targeting with different inter-layer prediction modes for 1 pass
1224 // CBR SVC: 3 spatial layers and 3 temporal layers, changing the target bitrate
1225 // at the middle of encoding.
1226 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLDynamicBitrateChange) {
1228 cfg_.rc_buf_initial_sz = 500;
1229 cfg_.rc_buf_optimal_sz = 500;
1230 cfg_.rc_buf_sz = 1000;
1231 cfg_.rc_min_quantizer = 0;
1232 cfg_.rc_max_quantizer = 63;
1234 cfg_.rc_dropframe_thresh = 30;
1235 cfg_.kf_max_dist = 9999;
1236 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1238 top_sl_width_ = 640;
1239 top_sl_height_ = 480;
1240 cfg_.rc_target_bitrate = 800;
1242 change_bitrate_ = true;
1243 AssignLayerBitrates();
1244 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1245 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1247 #if CONFIG_VP9_DECODER
1248 // The non-reference frames are expected to be mismatched frames as the
1249 // encoder will avoid loopfilter on these frames.
1250 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1254 #if CONFIG_VP9_TEMPORAL_DENOISING
1255 // Params: speed setting, noise sensitivity, index for bitrate array and inter
1257 class DatarateOnePassCbrSvcDenoiser
1258 : public DatarateOnePassCbrSvc,
1259 public ::libvpx_test::CodecTestWith4Params<int, int, int, int> {
1261 DatarateOnePassCbrSvcDenoiser() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1262 memset(&svc_params_, 0, sizeof(svc_params_));
1264 virtual ~DatarateOnePassCbrSvcDenoiser() {}
1267 virtual void SetUp() {
1269 SetMode(::libvpx_test::kRealTime);
1270 speed_setting_ = GET_PARAM(1);
1271 inter_layer_pred_mode_ = GET_PARAM(3);
1276 // Check basic rate targeting for 1 pass CBR SVC with denoising.
1277 // 2 spatial layers and 3 temporal layer. Run HD clip with 2 threads.
1278 TEST_P(DatarateOnePassCbrSvcDenoiser, OnePassCbrSvc2SL3TLDenoiserOn) {
1280 cfg_.rc_buf_initial_sz = 500;
1281 cfg_.rc_buf_optimal_sz = 500;
1282 cfg_.rc_buf_sz = 1000;
1283 cfg_.rc_min_quantizer = 0;
1284 cfg_.rc_max_quantizer = 63;
1286 cfg_.rc_dropframe_thresh = 30;
1287 cfg_.kf_max_dist = 9999;
1288 number_spatial_layers_ = cfg_.ss_number_layers;
1289 number_temporal_layers_ = cfg_.ts_number_layers;
1290 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1292 top_sl_width_ = 640;
1293 top_sl_height_ = 480;
1294 const int bitrates[3] = { 600, 800, 1000 };
1295 // TODO(marpan): Check that effective_datarate for each layer hits the
1296 // layer target_bitrate.
1297 // For SVC, noise_sen = 1 means denoising only the top spatial layer
1298 // noise_sen = 2 means denoising the two top spatial layers.
1299 cfg_.rc_target_bitrate = bitrates[GET_PARAM(3)];
1301 denoiser_on_ = GET_PARAM(2);
1302 AssignLayerBitrates();
1303 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1304 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1306 #if CONFIG_VP9_DECODER
1307 // The non-reference frames are expected to be mismatched frames as the
1308 // encoder will avoid loopfilter on these frames.
1309 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1314 // Params: speed setting, key frame dist.
1315 class DatarateOnePassCbrSvcSmallKF
1316 : public DatarateOnePassCbrSvc,
1317 public ::libvpx_test::CodecTestWith2Params<int, int> {
1319 DatarateOnePassCbrSvcSmallKF() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1320 memset(&svc_params_, 0, sizeof(svc_params_));
1322 virtual ~DatarateOnePassCbrSvcSmallKF() {}
1325 virtual void SetUp() {
1327 SetMode(::libvpx_test::kRealTime);
1328 speed_setting_ = GET_PARAM(1);
1333 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1334 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1335 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc3SL3TLSmallKf) {
1337 cfg_.rc_buf_initial_sz = 500;
1338 cfg_.rc_buf_optimal_sz = 500;
1339 cfg_.rc_buf_sz = 1000;
1340 cfg_.rc_min_quantizer = 0;
1341 cfg_.rc_max_quantizer = 63;
1343 cfg_.rc_dropframe_thresh = 10;
1344 cfg_.rc_target_bitrate = 800;
1345 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1347 top_sl_width_ = 640;
1348 top_sl_height_ = 480;
1349 // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1350 // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1351 const int kf_dist = GET_PARAM(2);
1352 cfg_.kf_max_dist = kf_dist;
1353 key_frame_spacing_ = kf_dist;
1355 AssignLayerBitrates();
1356 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1357 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.70,
1359 #if CONFIG_VP9_DECODER
1360 // The non-reference frames are expected to be mismatched frames as the
1361 // encoder will avoid loopfilter on these frames.
1362 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1366 // Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
1367 // temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
1368 TEST_P(DatarateOnePassCbrSvcSmallKF, OnePassCbrSvc2SL3TLSmallKf) {
1370 cfg_.rc_buf_initial_sz = 500;
1371 cfg_.rc_buf_optimal_sz = 500;
1372 cfg_.rc_buf_sz = 1000;
1373 cfg_.rc_min_quantizer = 0;
1374 cfg_.rc_max_quantizer = 63;
1376 cfg_.rc_dropframe_thresh = 10;
1377 cfg_.rc_target_bitrate = 400;
1378 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1380 top_sl_width_ = 640;
1381 top_sl_height_ = 480;
1382 // For this 3 temporal layer case, pattern repeats every 4 frames, so choose
1383 // 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
1384 const int kf_dist = GET_PARAM(2) + 32;
1385 cfg_.kf_max_dist = kf_dist;
1386 key_frame_spacing_ = kf_dist;
1388 AssignLayerBitrates();
1389 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1390 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1392 #if CONFIG_VP9_DECODER
1393 // The non-reference frames are expected to be mismatched frames as the
1394 // encoder will avoid loopfilter on these frames.
1395 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1399 // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
1400 // temporal layers. Run VGA clip with 1 thread, and place layer sync frames:
1401 // one at middle layer first, then another one for top layer, and another
1402 // insert for base spatial layer (which forces key frame).
1403 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL3TLSyncFrames) {
1405 cfg_.rc_buf_initial_sz = 500;
1406 cfg_.rc_buf_optimal_sz = 500;
1407 cfg_.rc_buf_sz = 1000;
1408 cfg_.rc_min_quantizer = 0;
1409 cfg_.rc_max_quantizer = 63;
1411 cfg_.kf_max_dist = 9999;
1412 cfg_.rc_dropframe_thresh = 10;
1413 cfg_.rc_target_bitrate = 400;
1414 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1416 top_sl_width_ = 640;
1417 top_sl_height_ = 480;
1419 insert_layer_sync_ = 1;
1420 AssignLayerBitrates();
1421 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1422 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.78,
1424 #if CONFIG_VP9_DECODER
1425 // The non-reference frames are expected to be mismatched frames as the
1426 // encoder will avoid loopfilter on these frames.
1427 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1431 // Run SVC encoder for 3 spatial layers, 1 temporal layer, with
1432 // intra-only frame as sync frame on base spatial layer.
1433 // Intra_only is inserted at start and in middle of sequence.
1434 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc3SL1TLSyncWithIntraOnly) {
1436 cfg_.rc_buf_initial_sz = 500;
1437 cfg_.rc_buf_optimal_sz = 500;
1438 cfg_.rc_buf_sz = 1000;
1439 cfg_.rc_min_quantizer = 0;
1440 cfg_.rc_max_quantizer = 63;
1442 cfg_.rc_dropframe_thresh = 30;
1443 cfg_.kf_max_dist = 9999;
1444 cfg_.rc_target_bitrate = 400;
1445 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1447 top_sl_width_ = 640;
1448 top_sl_height_ = 480;
1450 insert_layer_sync_ = 1;
1451 // Use intra_only frame for sync on base layer.
1452 force_intra_only_frame_ = 1;
1453 AssignLayerBitrates();
1454 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1455 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1457 #if CONFIG_VP9_DECODER
1458 // The non-reference frames are expected to be mismatched frames as the
1459 // encoder will avoid loopfilter on these frames.
1460 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1464 // Run SVC encoder for 2 quality layers (same resolution different,
1465 // bitrates), 1 temporal layer, with screen content mode.
1466 TEST_P(DatarateOnePassCbrSvcSingleBR, OnePassCbrSvc2QL1TLScreen) {
1467 cfg_.rc_buf_initial_sz = 500;
1468 cfg_.rc_buf_optimal_sz = 500;
1469 cfg_.rc_buf_sz = 1000;
1470 cfg_.rc_min_quantizer = 0;
1471 cfg_.rc_max_quantizer = 56;
1472 cfg_.rc_end_usage = VPX_CBR;
1473 cfg_.g_lag_in_frames = 0;
1474 cfg_.ss_number_layers = 2;
1475 cfg_.ts_number_layers = 1;
1476 cfg_.ts_rate_decimator[0] = 1;
1477 cfg_.temporal_layering_mode = 0;
1478 cfg_.g_error_resilient = 1;
1480 svc_params_.scaling_factor_num[0] = 1;
1481 svc_params_.scaling_factor_den[0] = 1;
1482 svc_params_.scaling_factor_num[1] = 1;
1483 svc_params_.scaling_factor_den[1] = 1;
1484 cfg_.rc_dropframe_thresh = 30;
1485 cfg_.kf_max_dist = 9999;
1486 number_spatial_layers_ = cfg_.ss_number_layers;
1487 number_temporal_layers_ = cfg_.ts_number_layers;
1488 ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
1490 top_sl_width_ = 640;
1491 top_sl_height_ = 480;
1494 // Set the layer bitrates, for 2 spatial layers, 1 temporal.
1495 cfg_.rc_target_bitrate = 400;
1496 cfg_.ss_target_bitrate[0] = 100;
1497 cfg_.ss_target_bitrate[1] = 300;
1498 cfg_.layer_target_bitrate[0] = 100;
1499 cfg_.layer_target_bitrate[1] = 300;
1500 for (int sl = 0; sl < 2; ++sl) {
1501 float layer_framerate = 30.0;
1502 layer_target_avg_bandwidth_[sl] = static_cast<int>(
1503 cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate);
1504 bits_in_buffer_model_[sl] =
1505 cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz;
1507 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1508 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1510 #if CONFIG_VP9_DECODER
1511 // The non-reference frames are expected to be mismatched frames as the
1512 // encoder will avoid loopfilter on these frames.
1513 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1517 // Params: speed setting.
1518 class DatarateOnePassCbrSvcPostencodeDrop
1519 : public DatarateOnePassCbrSvc,
1520 public ::libvpx_test::CodecTestWithParam<int> {
1522 DatarateOnePassCbrSvcPostencodeDrop() : DatarateOnePassCbrSvc(GET_PARAM(0)) {
1523 memset(&svc_params_, 0, sizeof(svc_params_));
1525 virtual ~DatarateOnePassCbrSvcPostencodeDrop() {}
1528 virtual void SetUp() {
1530 SetMode(::libvpx_test::kRealTime);
1531 speed_setting_ = GET_PARAM(1);
1536 // Run SVC encoder for 2 quality layers (same resolution different,
1537 // bitrates), 1 temporal layer, with screen content mode.
1538 TEST_P(DatarateOnePassCbrSvcPostencodeDrop, OnePassCbrSvc2QL1TLScreen) {
1539 cfg_.rc_buf_initial_sz = 200;
1540 cfg_.rc_buf_optimal_sz = 200;
1541 cfg_.rc_buf_sz = 400;
1542 cfg_.rc_min_quantizer = 0;
1543 cfg_.rc_max_quantizer = 52;
1544 cfg_.rc_end_usage = VPX_CBR;
1545 cfg_.g_lag_in_frames = 0;
1546 cfg_.ss_number_layers = 2;
1547 cfg_.ts_number_layers = 1;
1548 cfg_.ts_rate_decimator[0] = 1;
1549 cfg_.temporal_layering_mode = 0;
1550 cfg_.g_error_resilient = 1;
1552 svc_params_.scaling_factor_num[0] = 1;
1553 svc_params_.scaling_factor_den[0] = 1;
1554 svc_params_.scaling_factor_num[1] = 1;
1555 svc_params_.scaling_factor_den[1] = 1;
1556 cfg_.rc_dropframe_thresh = 30;
1557 cfg_.kf_max_dist = 9999;
1558 number_spatial_layers_ = cfg_.ss_number_layers;
1559 number_temporal_layers_ = cfg_.ts_number_layers;
1560 ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
1562 top_sl_width_ = 352;
1563 top_sl_height_ = 288;
1565 base_speed_setting_ = speed_setting_;
1567 use_post_encode_drop_ = 1;
1568 // Set the layer bitrates, for 2 spatial layers, 1 temporal.
1569 cfg_.rc_target_bitrate = 400;
1570 cfg_.ss_target_bitrate[0] = 100;
1571 cfg_.ss_target_bitrate[1] = 300;
1572 cfg_.layer_target_bitrate[0] = 100;
1573 cfg_.layer_target_bitrate[1] = 300;
1574 for (int sl = 0; sl < 2; ++sl) {
1575 float layer_framerate = 30.0;
1576 layer_target_avg_bandwidth_[sl] = static_cast<int>(
1577 cfg_.layer_target_bitrate[sl] * 1000.0 / layer_framerate);
1578 bits_in_buffer_model_[sl] =
1579 cfg_.layer_target_bitrate[sl] * cfg_.rc_buf_initial_sz;
1581 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
1582 CheckLayerRateTargeting(number_spatial_layers_, number_temporal_layers_, 0.73,
1584 #if CONFIG_VP9_DECODER
1585 // The non-reference frames are expected to be mismatched frames as the
1586 // encoder will avoid loopfilter on these frames.
1587 EXPECT_EQ(GetNonRefFrames(), GetMismatchFrames());
1591 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSingleBR,
1592 ::testing::Range(5, 10));
1594 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcPostencodeDrop,
1595 ::testing::Range(5, 6));
1597 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcInterLayerPredSingleBR,
1598 ::testing::Range(5, 10), ::testing::Range(0, 3));
1600 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcMultiBR,
1601 ::testing::Range(5, 10), ::testing::Range(0, 3));
1603 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcFrameDropMultiBR,
1604 ::testing::Range(5, 10), ::testing::Range(0, 2),
1605 ::testing::Range(0, 3));
1607 #if CONFIG_VP9_TEMPORAL_DENOISING
1608 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcDenoiser,
1609 ::testing::Range(5, 10), ::testing::Range(1, 3),
1610 ::testing::Range(0, 3), ::testing::Range(0, 4));
1613 VP9_INSTANTIATE_TEST_SUITE(DatarateOnePassCbrSvcSmallKF,
1614 ::testing::Range(5, 10), ::testing::Range(32, 36));
1616 } // namespace svc_test