2 * Copyright (c) 2013 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.
12 #include "third_party/googletest/src/include/gtest/gtest.h"
13 #include "test/codec_factory.h"
14 #include "test/decode_test_driver.h"
15 #include "test/i420_video_source.h"
17 #include "vp9/decoder/vp9_decoder.h"
19 #include "vpx/svc_context.h"
20 #include "vpx/vp8cx.h"
21 #include "vpx/vpx_encoder.h"
25 using libvpx_test::CodecFactory;
26 using libvpx_test::Decoder;
27 using libvpx_test::DxDataIterator;
28 using libvpx_test::VP9CodecFactory;
30 class SvcTest : public ::testing::Test {
32 static const uint32_t kWidth = 352;
33 static const uint32_t kHeight = 288;
37 test_file_name_("hantro_collage_w352h288.yuv"),
38 codec_initialized_(false),
40 memset(&svc_, 0, sizeof(svc_));
41 memset(&codec_, 0, sizeof(codec_));
42 memset(&codec_enc_, 0, sizeof(codec_enc_));
47 virtual void SetUp() {
48 svc_.log_level = SVC_LOG_DEBUG;
51 codec_iface_ = vpx_codec_vp9_cx();
52 const vpx_codec_err_t res =
53 vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0);
54 EXPECT_EQ(VPX_CODEC_OK, res);
56 codec_enc_.g_w = kWidth;
57 codec_enc_.g_h = kHeight;
58 codec_enc_.g_timebase.num = 1;
59 codec_enc_.g_timebase.den = 60;
60 codec_enc_.kf_min_dist = 100;
61 codec_enc_.kf_max_dist = 100;
63 vpx_codec_dec_cfg_t dec_cfg = vpx_codec_dec_cfg_t();
64 VP9CodecFactory codec_factory;
65 decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
68 virtual void TearDown() {
73 void InitializeEncoder() {
74 const vpx_codec_err_t res =
75 vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
76 EXPECT_EQ(VPX_CODEC_OK, res);
77 codec_initialized_ = true;
80 void ReleaseEncoder() {
81 vpx_svc_release(&svc_);
82 if (codec_initialized_) vpx_codec_destroy(&codec_);
83 codec_initialized_ = false;
86 void Pass1EncodeNFrames(const int n, const int layers,
87 std::string *const stats_buf) {
89 size_t stats_size = 0;
90 const char *stats_data = NULL;
94 svc_.spatial_layers = layers;
95 codec_enc_.g_pass = VPX_RC_FIRST_PASS;
98 libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
99 codec_enc_.g_timebase.den,
100 codec_enc_.g_timebase.num, 0, 30);
103 for (int i = 0; i < n; ++i) {
104 res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
105 video.duration(), VPX_DL_GOOD_QUALITY);
106 ASSERT_EQ(VPX_CODEC_OK, res);
107 stats_size = vpx_svc_get_rc_stats_buffer_size(&svc_);
108 EXPECT_GT(stats_size, 0U);
109 stats_data = vpx_svc_get_rc_stats_buffer(&svc_);
110 ASSERT_TRUE(stats_data != NULL);
111 stats_buf->append(stats_data, stats_size);
115 // Flush encoder and test EOS packet.
116 res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(),
117 video.duration(), VPX_DL_GOOD_QUALITY);
118 stats_size = vpx_svc_get_rc_stats_buffer_size(&svc_);
119 EXPECT_GT(stats_size, 0U);
120 stats_data = vpx_svc_get_rc_stats_buffer(&svc_);
121 ASSERT_TRUE(stats_data != NULL);
122 stats_buf->append(stats_data, stats_size);
127 void StoreFrames(const size_t max_frame_received,
128 struct vpx_fixed_buf *const outputs,
129 size_t *const frame_received) {
131 while ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
132 ASSERT_LT(*frame_received, max_frame_received);
134 if (*frame_received == 0) {
135 EXPECT_EQ(1, vpx_svc_is_keyframe(&svc_));
138 outputs[*frame_received].buf = malloc(frame_size + 16);
139 ASSERT_TRUE(outputs[*frame_received].buf != NULL);
140 memcpy(outputs[*frame_received].buf, vpx_svc_get_buffer(&svc_),
142 outputs[*frame_received].sz = frame_size;
147 void Pass2EncodeNFrames(std::string *const stats_buf,
148 const int n, const int layers,
149 struct vpx_fixed_buf *const outputs) {
151 size_t frame_received = 0;
153 ASSERT_TRUE(outputs != NULL);
155 ASSERT_GT(layers, 0);
156 svc_.spatial_layers = layers;
157 codec_enc_.rc_target_bitrate = 500;
158 if (codec_enc_.g_pass == VPX_RC_LAST_PASS) {
159 ASSERT_TRUE(stats_buf != NULL);
160 ASSERT_GT(stats_buf->size(), 0U);
161 codec_enc_.rc_twopass_stats_in.buf = &(*stats_buf)[0];
162 codec_enc_.rc_twopass_stats_in.sz = stats_buf->size();
166 libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
167 codec_enc_.g_timebase.den,
168 codec_enc_.g_timebase.num, 0, 30);
171 for (int i = 0; i < n; ++i) {
172 res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
173 video.duration(), VPX_DL_GOOD_QUALITY);
174 ASSERT_EQ(VPX_CODEC_OK, res);
175 StoreFrames(n, outputs, &frame_received);
180 res = vpx_svc_encode(&svc_, &codec_, NULL, 0,
181 video.duration(), VPX_DL_GOOD_QUALITY);
182 EXPECT_EQ(VPX_CODEC_OK, res);
183 StoreFrames(n, outputs, &frame_received);
185 EXPECT_EQ(frame_received, static_cast<size_t>(n));
190 void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) {
191 int decoded_frames = 0;
192 int received_frames = 0;
194 ASSERT_TRUE(inputs != NULL);
197 for (int i = 0; i < n; ++i) {
198 ASSERT_TRUE(inputs[i].buf != NULL);
199 ASSERT_GT(inputs[i].sz, 0U);
200 const vpx_codec_err_t res_dec =
201 decoder_->DecodeFrame(static_cast<const uint8_t *>(inputs[i].buf),
203 ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
206 DxDataIterator dec_iter = decoder_->GetDxData();
207 while (dec_iter.Next() != NULL) {
211 EXPECT_EQ(decoded_frames, n);
212 EXPECT_EQ(received_frames, n);
215 void DropLayersAndMakeItVP9Comaptible(struct vpx_fixed_buf *const inputs,
216 const int num_super_frames,
217 const int remained_spatial_layers,
218 const bool is_multiple_frame_contexts) {
219 ASSERT_TRUE(inputs != NULL);
220 ASSERT_GT(num_super_frames, 0);
221 ASSERT_GT(remained_spatial_layers, 0);
223 for (int i = 0; i < num_super_frames; ++i) {
224 uint32_t frame_sizes[8] = {0};
226 int frames_found = 0;
228 ASSERT_TRUE(inputs[i].buf != NULL);
229 ASSERT_GT(inputs[i].sz, 0U);
231 vpx_codec_err_t res =
232 vp9_parse_superframe_index(static_cast<const uint8_t*>(inputs[i].buf),
233 inputs[i].sz, frame_sizes, &frame_count,
235 ASSERT_EQ(VPX_CODEC_OK, res);
237 if (frame_count == 0) {
238 // There's no super frame but only a single frame.
239 ASSERT_EQ(1, remained_spatial_layers);
240 if (is_multiple_frame_contexts) {
241 // Make a new super frame.
242 uint8_t marker = 0xc1;
246 // Choose the magnitude.
247 for (mag = 0, mask = 0xff; mag < 4; ++mag) {
248 if (inputs[i].sz < mask)
254 int index_sz = 2 + (mag + 1) * 2;
256 inputs[i].buf = realloc(inputs[i].buf, inputs[i].sz + index_sz + 16);
257 ASSERT_TRUE(inputs[i].buf != NULL);
258 uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf);
259 frame_data[0] &= ~2; // Set the show_frame flag to 0.
260 frame_data += inputs[i].sz;
261 // Add an one byte frame with show_existing_frame.
262 *frame_data++ = 0x88;
264 // Write the super frame index.
265 *frame_data++ = marker;
267 frame_sizes[0] = inputs[i].sz;
269 for (int j = 0; j < 2; ++j) {
270 unsigned int this_sz = frame_sizes[j];
271 for (int k = 0; k <= mag; k++) {
272 *frame_data++ = this_sz & 0xff;
276 *frame_data++ = marker;
277 inputs[i].sz += index_sz + 1;
280 // Found a super frame.
281 uint8_t *frame_data = static_cast<uint8_t*>(inputs[i].buf);
282 uint8_t *frame_start = frame_data;
283 for (frame = 0; frame < frame_count; ++frame) {
284 // Looking for a visible frame.
285 if (frame_data[0] & 0x02) {
287 if (frames_found == remained_spatial_layers)
290 frame_data += frame_sizes[frame];
292 ASSERT_LT(frame, frame_count) << "Couldn't find a visible frame. "
293 << "remained_spatial_layers: " << remained_spatial_layers
294 << " super_frame: " << i
295 << " is_multiple_frame_context: " << is_multiple_frame_contexts;
296 if (frame == frame_count - 1 && !is_multiple_frame_contexts)
299 frame_data += frame_sizes[frame];
301 // We need to add one more frame for multiple frame contexts.
302 if (is_multiple_frame_contexts)
305 static_cast<const uint8_t*>(inputs[i].buf)[inputs[i].sz - 1];
306 const uint32_t mag = ((marker >> 3) & 0x3) + 1;
307 const size_t index_sz = 2 + mag * frame_count;
308 const size_t new_index_sz = 2 + mag * (frame + 1);
312 // Copy existing frame sizes.
313 memmove(frame_data + (is_multiple_frame_contexts ? 2 : 1),
314 frame_start + inputs[i].sz - index_sz + 1, new_index_sz - 2);
315 if (is_multiple_frame_contexts) {
316 // Add a one byte frame with flag show_existing_frame.
317 *frame_data++ = 0x88 | (remained_spatial_layers - 1);
320 frame_data[0] = marker;
321 frame_data += (mag * (frame + 1) + 1);
323 if (is_multiple_frame_contexts) {
324 // Write the frame size for the one byte frame.
327 for (uint32_t j = 1; j < mag; ++j) {
332 *frame_data++ = marker;
333 inputs[i].sz = frame_data - frame_start;
335 if (is_multiple_frame_contexts) {
336 // Change the show frame flag to 0 for all frames.
337 for (int j = 0; j < frame; ++j) {
338 frame_start[0] &= ~2;
339 frame_start += frame_sizes[j];
346 void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
347 ASSERT_TRUE(inputs != NULL);
350 for (int i = 0; i < n; ++i) {
352 inputs[i].buf = NULL;
358 vpx_codec_ctx_t codec_;
359 struct vpx_codec_enc_cfg codec_enc_;
360 vpx_codec_iface_t *codec_iface_;
361 std::string test_file_name_;
362 bool codec_initialized_;
366 TEST_F(SvcTest, SvcInit) {
367 // test missing parameters
368 vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_);
369 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
370 res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_);
371 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
372 res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_);
373 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
375 res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
376 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
378 svc_.spatial_layers = 6; // too many layers
379 res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
380 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
382 svc_.spatial_layers = 0; // use default layers
384 EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
387 TEST_F(SvcTest, InitTwoLayers) {
388 svc_.spatial_layers = 2;
389 vpx_svc_set_scale_factors(&svc_, "4/16,16*16"); // invalid scale values
390 vpx_codec_err_t res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
391 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
393 vpx_svc_set_scale_factors(&svc_, "4/16,16/16"); // valid scale values
397 TEST_F(SvcTest, InvalidOptions) {
398 vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL);
399 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
401 res = vpx_svc_set_options(&svc_, "not-an-option=1");
402 EXPECT_EQ(VPX_CODEC_OK, res);
403 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
404 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
407 TEST_F(SvcTest, SetLayersOption) {
408 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "spatial-layers=3");
409 EXPECT_EQ(VPX_CODEC_OK, res);
411 EXPECT_EQ(3, svc_.spatial_layers);
414 TEST_F(SvcTest, SetMultipleOptions) {
415 vpx_codec_err_t res =
416 vpx_svc_set_options(&svc_, "spatial-layers=2 scale-factors=1/3,2/3");
417 EXPECT_EQ(VPX_CODEC_OK, res);
419 EXPECT_EQ(2, svc_.spatial_layers);
422 TEST_F(SvcTest, SetScaleFactorsOption) {
423 svc_.spatial_layers = 2;
424 vpx_codec_err_t res =
425 vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors");
426 EXPECT_EQ(VPX_CODEC_OK, res);
427 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
428 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
430 res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
431 EXPECT_EQ(VPX_CODEC_OK, res);
435 TEST_F(SvcTest, SetQuantizersOption) {
436 svc_.spatial_layers = 2;
437 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "quantizers=not-quantizers");
438 EXPECT_EQ(VPX_CODEC_OK, res);
439 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
440 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
442 vpx_svc_set_options(&svc_, "quantizers=40,45");
446 TEST_F(SvcTest, SetAutoAltRefOption) {
447 svc_.spatial_layers = 5;
448 vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none");
449 EXPECT_EQ(VPX_CODEC_OK, res);
450 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
451 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
453 res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0");
454 EXPECT_EQ(VPX_CODEC_OK, res);
455 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
456 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
458 vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
462 TEST_F(SvcTest, SetQuantizers) {
463 vpx_codec_err_t res = vpx_svc_set_quantizers(NULL, "40,30");
464 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
466 res = vpx_svc_set_quantizers(&svc_, NULL);
467 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
469 svc_.spatial_layers = 2;
470 res = vpx_svc_set_quantizers(&svc_, "40");
471 EXPECT_EQ(VPX_CODEC_OK, res);
472 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
473 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
475 res = vpx_svc_set_quantizers(&svc_, "40,30");
476 EXPECT_EQ(VPX_CODEC_OK, res);
480 TEST_F(SvcTest, SetScaleFactors) {
481 vpx_codec_err_t res = vpx_svc_set_scale_factors(NULL, "4/16,16/16");
482 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
484 res = vpx_svc_set_scale_factors(&svc_, NULL);
485 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
487 svc_.spatial_layers = 2;
488 res = vpx_svc_set_scale_factors(&svc_, "4/16");
489 EXPECT_EQ(VPX_CODEC_OK, res);
490 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
491 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
493 res = vpx_svc_set_scale_factors(&svc_, "4/16,16/16");
494 EXPECT_EQ(VPX_CODEC_OK, res);
498 // Test that decoder can handle an SVC frame as the first frame in a sequence.
499 TEST_F(SvcTest, OnePassEncodeOneFrame) {
500 codec_enc_.g_pass = VPX_RC_ONE_PASS;
501 vpx_fixed_buf output = {0};
502 Pass2EncodeNFrames(NULL, 1, 2, &output);
503 DecodeNFrames(&output, 1);
504 FreeBitstreamBuffers(&output, 1);
507 TEST_F(SvcTest, OnePassEncodeThreeFrames) {
508 codec_enc_.g_pass = VPX_RC_ONE_PASS;
509 vpx_fixed_buf outputs[3];
510 memset(&outputs[0], 0, sizeof(outputs));
511 Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
512 DecodeNFrames(&outputs[0], 3);
513 FreeBitstreamBuffers(&outputs[0], 3);
516 TEST_F(SvcTest, GetLayerResolution) {
517 svc_.spatial_layers = 2;
518 vpx_svc_set_scale_factors(&svc_, "4/16,8/16");
519 vpx_svc_set_quantizers(&svc_, "40,30");
523 // ensure that requested layer is a valid layer
524 uint32_t layer_width, layer_height;
525 vpx_codec_err_t res = vpx_svc_get_layer_resolution(&svc_, svc_.spatial_layers,
526 &layer_width, &layer_height);
527 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
529 res = vpx_svc_get_layer_resolution(NULL, 0, &layer_width, &layer_height);
530 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
532 res = vpx_svc_get_layer_resolution(&svc_, 0, NULL, &layer_height);
533 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
535 res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, NULL);
536 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
538 res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, &layer_height);
539 EXPECT_EQ(VPX_CODEC_OK, res);
540 EXPECT_EQ(kWidth * 4 / 16, layer_width);
541 EXPECT_EQ(kHeight * 4 / 16, layer_height);
543 res = vpx_svc_get_layer_resolution(&svc_, 1, &layer_width, &layer_height);
544 EXPECT_EQ(VPX_CODEC_OK, res);
545 EXPECT_EQ(kWidth * 8 / 16, layer_width);
546 EXPECT_EQ(kHeight * 8 / 16, layer_height);
549 TEST_F(SvcTest, TwoPassEncode10Frames) {
551 std::string stats_buf;
552 Pass1EncodeNFrames(10, 2, &stats_buf);
554 // Second pass encode
555 codec_enc_.g_pass = VPX_RC_LAST_PASS;
556 vpx_fixed_buf outputs[10];
557 memset(&outputs[0], 0, sizeof(outputs));
558 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
559 DecodeNFrames(&outputs[0], 10);
560 FreeBitstreamBuffers(&outputs[0], 10);
563 TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
565 std::string stats_buf;
566 Pass1EncodeNFrames(20, 2, &stats_buf);
568 // Second pass encode
569 codec_enc_.g_pass = VPX_RC_LAST_PASS;
570 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
571 vpx_fixed_buf outputs[20];
572 memset(&outputs[0], 0, sizeof(outputs));
573 Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
574 DecodeNFrames(&outputs[0], 20);
575 FreeBitstreamBuffers(&outputs[0], 20);
578 TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
580 std::string stats_buf;
581 Pass1EncodeNFrames(10, 2, &stats_buf);
583 // Second pass encode
584 codec_enc_.g_pass = VPX_RC_LAST_PASS;
585 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
586 vpx_fixed_buf outputs[10];
587 memset(&outputs[0], 0, sizeof(outputs));
588 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
589 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false);
590 DecodeNFrames(&outputs[0], 10);
591 FreeBitstreamBuffers(&outputs[0], 10);
594 TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
596 std::string stats_buf;
597 Pass1EncodeNFrames(10, 5, &stats_buf);
599 // Second pass encode
600 codec_enc_.g_pass = VPX_RC_LAST_PASS;
601 vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
602 vpx_fixed_buf outputs[10];
603 memset(&outputs[0], 0, sizeof(outputs));
604 Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
606 DecodeNFrames(&outputs[0], 10);
607 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 4, false);
608 DecodeNFrames(&outputs[0], 10);
609 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 3, false);
610 DecodeNFrames(&outputs[0], 10);
611 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, false);
612 DecodeNFrames(&outputs[0], 10);
613 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, false);
614 DecodeNFrames(&outputs[0], 10);
616 FreeBitstreamBuffers(&outputs[0], 10);
619 TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
621 std::string stats_buf;
622 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
623 Pass1EncodeNFrames(20, 2, &stats_buf);
625 // Second pass encode
626 codec_enc_.g_pass = VPX_RC_LAST_PASS;
627 vpx_svc_set_options(&svc_,
628 "auto-alt-refs=1,1 scale-factors=1/1,1/1");
629 vpx_fixed_buf outputs[20];
630 memset(&outputs[0], 0, sizeof(outputs));
631 Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
632 DecodeNFrames(&outputs[0], 20);
633 FreeBitstreamBuffers(&outputs[0], 20);
636 TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
638 std::string stats_buf;
639 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
640 Pass1EncodeNFrames(20, 3, &stats_buf);
642 // Second pass encode
643 codec_enc_.g_pass = VPX_RC_LAST_PASS;
644 vpx_svc_set_options(&svc_,
645 "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
646 vpx_fixed_buf outputs[20];
647 memset(&outputs[0], 0, sizeof(outputs));
648 Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
649 DecodeNFrames(&outputs[0], 20);
650 DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 2, false);
651 DecodeNFrames(&outputs[0], 20);
652 DropLayersAndMakeItVP9Comaptible(&outputs[0], 20, 1, false);
653 DecodeNFrames(&outputs[0], 20);
655 FreeBitstreamBuffers(&outputs[0], 20);
658 TEST_F(SvcTest, SetMultipleFrameContextsOption) {
659 svc_.spatial_layers = 5;
660 vpx_codec_err_t res =
661 vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
662 EXPECT_EQ(VPX_CODEC_OK, res);
663 res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
664 EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
666 svc_.spatial_layers = 2;
667 res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
671 TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
673 std::string stats_buf;
674 Pass1EncodeNFrames(10, 2, &stats_buf);
676 // Second pass encode
677 codec_enc_.g_pass = VPX_RC_LAST_PASS;
678 codec_enc_.g_error_resilient = 0;
679 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
680 vpx_fixed_buf outputs[10];
681 memset(&outputs[0], 0, sizeof(outputs));
682 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
683 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true);
684 DecodeNFrames(&outputs[0], 10);
685 FreeBitstreamBuffers(&outputs[0], 10);
689 TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) {
691 std::string stats_buf;
692 Pass1EncodeNFrames(10, 2, &stats_buf);
694 // Second pass encode
695 codec_enc_.g_pass = VPX_RC_LAST_PASS;
696 codec_enc_.g_error_resilient = 0;
697 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 multi-frame-contexts=1");
698 vpx_fixed_buf outputs[10];
699 memset(&outputs[0], 0, sizeof(outputs));
700 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
701 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
702 DecodeNFrames(&outputs[0], 10);
703 FreeBitstreamBuffers(&outputs[0], 10);
706 TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
708 std::string stats_buf;
709 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
710 Pass1EncodeNFrames(10, 2, &stats_buf);
712 // Second pass encode
713 codec_enc_.g_pass = VPX_RC_LAST_PASS;
714 codec_enc_.g_error_resilient = 0;
715 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1 scale-factors=1/1,1/1 "
716 "multi-frame-contexts=1");
717 vpx_fixed_buf outputs[10];
718 memset(&outputs[0], 0, sizeof(outputs));
719 Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
720 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 2, true);
721 DecodeNFrames(&outputs[0], 10);
722 FreeBitstreamBuffers(&outputs[0], 10);
726 TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) {
728 std::string stats_buf;
729 vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
730 Pass1EncodeNFrames(10, 3, &stats_buf);
732 // Second pass encode
733 codec_enc_.g_pass = VPX_RC_LAST_PASS;
734 codec_enc_.g_error_resilient = 0;
735 vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1 "
736 "multi-frame-contexts=1");
737 vpx_fixed_buf outputs[10];
738 memset(&outputs[0], 0, sizeof(outputs));
739 Pass2EncodeNFrames(&stats_buf, 10, 3, &outputs[0]);
741 vpx_fixed_buf outputs_new[10];
742 for (int i = 0; i < 10; ++i) {
743 outputs_new[i].buf = malloc(outputs[i].sz + 16);
744 ASSERT_TRUE(outputs_new[i].buf != NULL);
745 memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
746 outputs_new[i].sz = outputs[i].sz;
748 DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 3, true);
749 DecodeNFrames(&outputs_new[0], 10);
751 for (int i = 0; i < 10; ++i) {
752 memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
753 outputs_new[i].sz = outputs[i].sz;
755 DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 2, true);
756 DecodeNFrames(&outputs_new[0], 10);
758 for (int i = 0; i < 10; ++i) {
759 memcpy(outputs_new[i].buf, outputs[i].buf, outputs[i].sz);
760 outputs_new[i].sz = outputs[i].sz;
762 DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 1, true);
763 DecodeNFrames(&outputs_new[0], 10);
765 FreeBitstreamBuffers(&outputs[0], 10);
766 FreeBitstreamBuffers(&outputs_new[0], 10);
769 TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
771 std::string stats_buf;
772 vpx_svc_set_options(&svc_, "scale-factors=1/1");
773 svc_.temporal_layers = 2;
774 Pass1EncodeNFrames(10, 1, &stats_buf);
776 // Second pass encode
777 codec_enc_.g_pass = VPX_RC_LAST_PASS;
778 svc_.temporal_layers = 2;
779 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
780 vpx_fixed_buf outputs[10];
781 memset(&outputs[0], 0, sizeof(outputs));
782 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
783 DecodeNFrames(&outputs[0], 10);
784 FreeBitstreamBuffers(&outputs[0], 10);
787 TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
789 std::string stats_buf;
790 vpx_svc_set_options(&svc_, "scale-factors=1/1");
791 svc_.temporal_layers = 2;
792 Pass1EncodeNFrames(10, 1, &stats_buf);
794 // Second pass encode
795 codec_enc_.g_pass = VPX_RC_LAST_PASS;
796 svc_.temporal_layers = 2;
797 codec_enc_.g_error_resilient = 0;
798 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
799 "multi-frame-contexts=1");
800 vpx_fixed_buf outputs[10];
801 memset(&outputs[0], 0, sizeof(outputs));
802 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
803 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
804 DecodeNFrames(&outputs[0], 10);
805 FreeBitstreamBuffers(&outputs[0], 10);
808 TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
810 std::string stats_buf;
811 vpx_svc_set_options(&svc_, "scale-factors=1/1");
812 svc_.temporal_layers = 2;
813 Pass1EncodeNFrames(10, 1, &stats_buf);
815 // Second pass encode
816 codec_enc_.g_pass = VPX_RC_LAST_PASS;
817 svc_.temporal_layers = 2;
818 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1");
819 vpx_fixed_buf outputs[10];
820 memset(&outputs[0], 0, sizeof(outputs));
821 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
823 vpx_fixed_buf base_layer[5];
824 for (int i = 0; i < 5; ++i)
825 base_layer[i] = outputs[i * 2];
827 DecodeNFrames(&base_layer[0], 5);
828 FreeBitstreamBuffers(&outputs[0], 10);
832 TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) {
834 std::string stats_buf;
835 vpx_svc_set_options(&svc_, "scale-factors=1/1");
836 svc_.temporal_layers = 2;
837 Pass1EncodeNFrames(10, 1, &stats_buf);
839 // Second pass encode
840 codec_enc_.g_pass = VPX_RC_LAST_PASS;
841 svc_.temporal_layers = 2;
842 codec_enc_.g_error_resilient = 0;
843 vpx_svc_set_options(&svc_, "auto-alt-refs=1 scale-factors=1/1 "
844 "multi-frame-contexts=1");
845 vpx_fixed_buf outputs[10];
846 memset(&outputs[0], 0, sizeof(outputs));
847 Pass2EncodeNFrames(&stats_buf, 10, 1, &outputs[0]);
848 DropLayersAndMakeItVP9Comaptible(&outputs[0], 10, 1, true);
850 vpx_fixed_buf base_layer[5];
851 for (int i = 0; i < 5; ++i)
852 base_layer[i] = outputs[i * 2];
854 DecodeNFrames(&base_layer[0], 5);
855 FreeBitstreamBuffers(&outputs[0], 10);