[spatial svc]Add a few different encode frame tests.
[platform/upstream/libvpx.git] / test / svc_test.cc
1 /*
2  *  Copyright (c) 2013 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
11 #include <string>
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"
16
17 #include "vp9/decoder/vp9_decoder.h"
18
19 #include "vpx/svc_context.h"
20 #include "vpx/vp8cx.h"
21 #include "vpx/vpx_encoder.h"
22
23 namespace {
24
25 using libvpx_test::CodecFactory;
26 using libvpx_test::Decoder;
27 using libvpx_test::DxDataIterator;
28 using libvpx_test::VP9CodecFactory;
29
30 class SvcTest : public ::testing::Test {
31  protected:
32   static const uint32_t kWidth = 352;
33   static const uint32_t kHeight = 288;
34
35   SvcTest()
36       : codec_iface_(0),
37         test_file_name_("hantro_collage_w352h288.yuv"),
38         codec_initialized_(false),
39         decoder_(0) {
40     memset(&svc_, 0, sizeof(svc_));
41     memset(&codec_, 0, sizeof(codec_));
42     memset(&codec_enc_, 0, sizeof(codec_enc_));
43   }
44
45   virtual ~SvcTest() {}
46
47   virtual void SetUp() {
48     svc_.log_level = SVC_LOG_DEBUG;
49     svc_.log_print = 0;
50
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);
55
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;
62
63     vpx_codec_dec_cfg_t dec_cfg = {0};
64     VP9CodecFactory codec_factory;
65     decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
66   }
67
68   virtual void TearDown() {
69     ReleaseEncoder();
70     delete(decoder_);
71   }
72
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;
78   }
79
80   void ReleaseEncoder() {
81     vpx_svc_release(&svc_);
82     if (codec_initialized_) vpx_codec_destroy(&codec_);
83     codec_initialized_ = false;
84   }
85
86   void Pass1EncodeNFrames(const int n, const int layers,
87                           std::string *const stats_buf) {
88     vpx_codec_err_t res;
89     size_t stats_size = 0;
90     const char *stats_data = NULL;
91
92     ASSERT_GT(n, 0);
93     ASSERT_GT(layers, 0);
94     svc_.spatial_layers = layers;
95     codec_enc_.g_pass = VPX_RC_FIRST_PASS;
96     InitializeEncoder();
97
98     libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
99                                        codec_enc_.g_timebase.den,
100                                        codec_enc_.g_timebase.num, 0, 30);
101     video.Begin();
102
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);
112       video.Next();
113     }
114
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);
123
124     ReleaseEncoder();
125   }
126
127   void StoreFrames(const size_t max_frame_received,
128                    struct vpx_fixed_buf *const outputs,
129                    size_t *const frame_received) {
130     size_t frame_size;
131     while ((frame_size = vpx_svc_get_frame_size(&svc_)) > 0) {
132       ASSERT_LT(*frame_received, max_frame_received);
133
134       if (*frame_received == 0) {
135         EXPECT_EQ(1, vpx_svc_is_keyframe(&svc_));
136       }
137
138       outputs[*frame_received].buf = malloc(frame_size);
139       ASSERT_TRUE(outputs[*frame_received].buf != NULL);
140       memcpy(outputs[*frame_received].buf, vpx_svc_get_buffer(&svc_),
141              frame_size);
142       outputs[*frame_received].sz = frame_size;
143       ++(*frame_received);
144     }
145   }
146
147   void Pass2EncodeNFrames(std::string *const stats_buf,
148                           const int n, const int layers,
149                           struct vpx_fixed_buf *const outputs) {
150     vpx_codec_err_t res;
151     size_t frame_received = 0;
152
153     ASSERT_TRUE(outputs != NULL);
154     ASSERT_GT(n, 0);
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();
163     }
164     InitializeEncoder();
165
166     libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
167                                        codec_enc_.g_timebase.den,
168                                        codec_enc_.g_timebase.num, 0, 30);
169     video.Begin();
170
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);
176       video.Next();
177     }
178
179     // Flush Encoder
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);
184
185     EXPECT_EQ(frame_received, (size_t)n);
186
187     ReleaseEncoder();
188   }
189
190   void DecodeNFrames(const struct vpx_fixed_buf *const inputs, const int n) {
191     int decoded_frames = 0;
192     int received_frames = 0;
193
194     ASSERT_TRUE(inputs != NULL);
195     ASSERT_GT(n, 0);
196
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),
202                                 inputs[i].sz);
203       ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
204       ++decoded_frames;
205
206       DxDataIterator dec_iter = decoder_->GetDxData();
207       while (dec_iter.Next()) {
208         ++received_frames;
209       }
210     }
211     EXPECT_EQ(decoded_frames, n);
212     EXPECT_EQ(received_frames, n);
213   }
214
215   void DropEnhancementLayers(struct vpx_fixed_buf *const inputs,
216                              const int num_super_frames,
217                              const int remained_layers) {
218     ASSERT_TRUE(inputs != NULL);
219     ASSERT_GT(num_super_frames, 0);
220     ASSERT_GT(remained_layers, 0);
221
222     for (int i = 0; i < num_super_frames; ++i) {
223       uint32_t frame_sizes[8] = {0};
224       int frame_count = 0;
225       int frames_found = 0;
226       int frame;
227       ASSERT_TRUE(inputs[i].buf != NULL);
228       ASSERT_GT(inputs[i].sz, 0U);
229
230       vpx_codec_err_t res =
231           vp9_parse_superframe_index(static_cast<const uint8_t*>(inputs[i].buf),
232                                      inputs[i].sz, frame_sizes, &frame_count,
233                                      NULL, NULL);
234       ASSERT_EQ(VPX_CODEC_OK, res);
235
236       uint8_t *frame_data = static_cast<uint8_t *>(inputs[i].buf);
237       uint8_t *frame_start = frame_data;
238       for (frame = 0; frame < frame_count; ++frame) {
239         // Looking for a visible frame
240         if (frame_data[0] & 0x02) {
241           ++frames_found;
242           if (frames_found == remained_layers)
243             break;
244         }
245         frame_data += frame_sizes[frame];
246       }
247       ASSERT_LT(frame, frame_count);
248       if (frame == frame_count - 1)
249         continue;
250
251       frame_data += frame_sizes[frame];
252       uint8_t marker =
253           static_cast<const uint8_t *>(inputs[i].buf)[inputs[i].sz - 1];
254       const uint32_t mag = ((marker >> 3) & 0x3) + 1;
255       const size_t index_sz = 2 + mag * frame_count;
256       const size_t new_index_sz = 2 + mag * (frame + 1);
257       marker &= 0x0f8;
258       marker |= frame;
259       frame_data[0] = marker;
260       memcpy(frame_data + 1, frame_start + inputs[i].sz - index_sz + 1,
261              new_index_sz - 2);
262       frame_data[new_index_sz - 1] = marker;
263       inputs[i].sz = frame_data - frame_start + new_index_sz;
264     }
265   }
266
267   void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
268     ASSERT_TRUE(inputs != NULL);
269     ASSERT_GT(n, 0);
270
271     for (int i = 0; i < n; ++i) {
272       free(inputs[i].buf);
273       inputs[i].buf = NULL;
274       inputs[i].sz = 0;
275     }
276   }
277
278   SvcContext svc_;
279   vpx_codec_ctx_t codec_;
280   struct vpx_codec_enc_cfg codec_enc_;
281   vpx_codec_iface_t *codec_iface_;
282   std::string test_file_name_;
283   bool codec_initialized_;
284   Decoder *decoder_;
285 };
286
287 TEST_F(SvcTest, SvcInit) {
288   // test missing parameters
289   vpx_codec_err_t res = vpx_svc_init(NULL, &codec_, codec_iface_, &codec_enc_);
290   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
291   res = vpx_svc_init(&svc_, NULL, codec_iface_, &codec_enc_);
292   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
293   res = vpx_svc_init(&svc_, &codec_, NULL, &codec_enc_);
294   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
295
296   res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
297   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
298
299   svc_.spatial_layers = 6;  // too many layers
300   res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
301   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
302
303   svc_.spatial_layers = 0;  // use default layers
304   InitializeEncoder();
305   EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
306 }
307
308 TEST_F(SvcTest, InitTwoLayers) {
309   svc_.spatial_layers = 2;
310   vpx_svc_set_scale_factors(&svc_, "4/16,16*16");  // invalid scale values
311   vpx_codec_err_t res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
312   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
313
314   vpx_svc_set_scale_factors(&svc_, "4/16,16/16");  // valid scale values
315   InitializeEncoder();
316 }
317
318 TEST_F(SvcTest, InvalidOptions) {
319   vpx_codec_err_t res = vpx_svc_set_options(&svc_, NULL);
320   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
321
322   res = vpx_svc_set_options(&svc_, "not-an-option=1");
323   EXPECT_EQ(VPX_CODEC_OK, res);
324   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
325   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
326 }
327
328 TEST_F(SvcTest, SetLayersOption) {
329   vpx_codec_err_t res = vpx_svc_set_options(&svc_, "layers=3");
330   EXPECT_EQ(VPX_CODEC_OK, res);
331   InitializeEncoder();
332   EXPECT_EQ(3, svc_.spatial_layers);
333 }
334
335 TEST_F(SvcTest, SetMultipleOptions) {
336   vpx_codec_err_t res =
337       vpx_svc_set_options(&svc_, "layers=2 scale-factors=1/3,2/3");
338   EXPECT_EQ(VPX_CODEC_OK, res);
339   InitializeEncoder();
340   EXPECT_EQ(2, svc_.spatial_layers);
341 }
342
343 TEST_F(SvcTest, SetScaleFactorsOption) {
344   svc_.spatial_layers = 2;
345   vpx_codec_err_t res =
346       vpx_svc_set_options(&svc_, "scale-factors=not-scale-factors");
347   EXPECT_EQ(VPX_CODEC_OK, res);
348   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
349   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
350
351   res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
352   EXPECT_EQ(VPX_CODEC_OK, res);
353   InitializeEncoder();
354 }
355
356 TEST_F(SvcTest, SetQuantizersOption) {
357   svc_.spatial_layers = 2;
358   vpx_codec_err_t res = vpx_svc_set_options(&svc_, "quantizers=not-quantizers");
359   EXPECT_EQ(VPX_CODEC_OK, res);
360   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
361   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
362
363   vpx_svc_set_options(&svc_, "quantizers=40,45");
364   InitializeEncoder();
365 }
366
367 TEST_F(SvcTest, SetAutoAltRefOption) {
368   svc_.spatial_layers = 5;
369   vpx_codec_err_t res = vpx_svc_set_options(&svc_, "auto-alt-refs=none");
370   EXPECT_EQ(VPX_CODEC_OK, res);
371   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
372   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
373
374   res = vpx_svc_set_options(&svc_, "auto-alt-refs=1,1,1,1,0");
375   EXPECT_EQ(VPX_CODEC_OK, res);
376   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
377   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
378
379   vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
380   InitializeEncoder();
381 }
382
383 TEST_F(SvcTest, SetQuantizers) {
384   vpx_codec_err_t res = vpx_svc_set_quantizers(NULL, "40,30");
385   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
386
387   res = vpx_svc_set_quantizers(&svc_, NULL);
388   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
389
390   svc_.spatial_layers = 2;
391   res = vpx_svc_set_quantizers(&svc_, "40");
392   EXPECT_EQ(VPX_CODEC_OK, res);
393   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
394   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
395
396   res = vpx_svc_set_quantizers(&svc_, "40,30");
397   EXPECT_EQ(VPX_CODEC_OK, res);
398   InitializeEncoder();
399 }
400
401 TEST_F(SvcTest, SetScaleFactors) {
402   vpx_codec_err_t res = vpx_svc_set_scale_factors(NULL, "4/16,16/16");
403   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
404
405   res = vpx_svc_set_scale_factors(&svc_, NULL);
406   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
407
408   svc_.spatial_layers = 2;
409   res = vpx_svc_set_scale_factors(&svc_, "4/16");
410   EXPECT_EQ(VPX_CODEC_OK, res);
411   res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
412   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
413
414   res = vpx_svc_set_scale_factors(&svc_, "4/16,16/16");
415   EXPECT_EQ(VPX_CODEC_OK, res);
416   InitializeEncoder();
417 }
418
419 // Test that decoder can handle an SVC frame as the first frame in a sequence.
420 TEST_F(SvcTest, OnePassEncodeOneFrame) {
421   codec_enc_.g_pass = VPX_RC_ONE_PASS;
422   vpx_fixed_buf output = {0};
423   Pass2EncodeNFrames(NULL, 1, 2, &output);
424   DecodeNFrames(&output, 1);
425   FreeBitstreamBuffers(&output, 1);
426 }
427
428 TEST_F(SvcTest, OnePassEncodeThreeFrames) {
429   codec_enc_.g_pass = VPX_RC_ONE_PASS;
430   vpx_fixed_buf outputs[3];
431   memset(&outputs[0], 0, sizeof(outputs));
432   Pass2EncodeNFrames(NULL, 3, 2, &outputs[0]);
433   DecodeNFrames(&outputs[0], 3);
434   FreeBitstreamBuffers(&outputs[0], 3);
435 }
436
437 TEST_F(SvcTest, GetLayerResolution) {
438   svc_.spatial_layers = 2;
439   vpx_svc_set_scale_factors(&svc_, "4/16,8/16");
440   vpx_svc_set_quantizers(&svc_, "40,30");
441
442   InitializeEncoder();
443
444   // ensure that requested layer is a valid layer
445   uint32_t layer_width, layer_height;
446   vpx_codec_err_t res = vpx_svc_get_layer_resolution(&svc_, svc_.spatial_layers,
447                                      &layer_width, &layer_height);
448   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
449
450   res = vpx_svc_get_layer_resolution(NULL, 0, &layer_width, &layer_height);
451   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
452
453   res = vpx_svc_get_layer_resolution(&svc_, 0, NULL, &layer_height);
454   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
455
456   res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, NULL);
457   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
458
459   res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, &layer_height);
460   EXPECT_EQ(VPX_CODEC_OK, res);
461   EXPECT_EQ(kWidth * 4 / 16, layer_width);
462   EXPECT_EQ(kHeight * 4 / 16, layer_height);
463
464   res = vpx_svc_get_layer_resolution(&svc_, 1, &layer_width, &layer_height);
465   EXPECT_EQ(VPX_CODEC_OK, res);
466   EXPECT_EQ(kWidth * 8 / 16, layer_width);
467   EXPECT_EQ(kHeight * 8 / 16, layer_height);
468 }
469
470 TEST_F(SvcTest, TwoPassEncode10Frames) {
471   // First pass encode
472   std::string stats_buf;
473   Pass1EncodeNFrames(10, 2, &stats_buf);
474
475   // Second pass encode
476   codec_enc_.g_pass = VPX_RC_LAST_PASS;
477   vpx_fixed_buf outputs[10];
478   memset(&outputs[0], 0, sizeof(outputs));
479   Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
480   DecodeNFrames(&outputs[0], 10);
481   FreeBitstreamBuffers(&outputs[0], 10);
482 }
483
484 TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
485   // First pass encode
486   std::string stats_buf;
487   Pass1EncodeNFrames(20, 2, &stats_buf);
488
489   // Second pass encode
490   codec_enc_.g_pass = VPX_RC_LAST_PASS;
491   vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
492   vpx_fixed_buf outputs[20];
493   memset(&outputs[0], 0, sizeof(outputs));
494   Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
495   DecodeNFrames(&outputs[0], 20);
496   FreeBitstreamBuffers(&outputs[0], 20);
497 }
498
499 TEST_F(SvcTest, TwoPassEncode2LayersDecodeBaseLayerOnly) {
500   // First pass encode
501   std::string stats_buf;
502   Pass1EncodeNFrames(10, 2, &stats_buf);
503
504   // Second pass encode
505   codec_enc_.g_pass = VPX_RC_LAST_PASS;
506   vpx_svc_set_options(&svc_, "auto-alt-refs=1,1");
507   vpx_fixed_buf outputs[10];
508   memset(&outputs[0], 0, sizeof(outputs));
509   Pass2EncodeNFrames(&stats_buf, 10, 2, &outputs[0]);
510   DropEnhancementLayers(&outputs[0], 10, 1);
511   DecodeNFrames(&outputs[0], 10);
512   FreeBitstreamBuffers(&outputs[0], 10);
513 }
514
515 TEST_F(SvcTest, TwoPassEncode5LayersDecode54321Layers) {
516   // First pass encode
517   std::string stats_buf;
518   Pass1EncodeNFrames(10, 5, &stats_buf);
519
520   // Second pass encode
521   codec_enc_.g_pass = VPX_RC_LAST_PASS;
522   vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
523   vpx_fixed_buf outputs[10];
524   memset(&outputs[0], 0, sizeof(outputs));
525   Pass2EncodeNFrames(&stats_buf, 10, 5, &outputs[0]);
526
527   DecodeNFrames(&outputs[0], 10);
528   DropEnhancementLayers(&outputs[0], 10, 4);
529   DecodeNFrames(&outputs[0], 10);
530   DropEnhancementLayers(&outputs[0], 10, 3);
531   DecodeNFrames(&outputs[0], 10);
532   DropEnhancementLayers(&outputs[0], 10, 2);
533   DecodeNFrames(&outputs[0], 10);
534   DropEnhancementLayers(&outputs[0], 10, 1);
535   DecodeNFrames(&outputs[0], 10);
536
537   FreeBitstreamBuffers(&outputs[0], 10);
538 }
539
540 TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
541   // First pass encode
542   std::string stats_buf;
543   vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
544   Pass1EncodeNFrames(20, 2, &stats_buf);
545
546   // Second pass encode
547   codec_enc_.g_pass = VPX_RC_LAST_PASS;
548   vpx_svc_set_options(&svc_,
549                       "auto-alt-refs=1,1 scale-factors=1/1,1/1");
550   vpx_fixed_buf outputs[20];
551   memset(&outputs[0], 0, sizeof(outputs));
552   Pass2EncodeNFrames(&stats_buf, 20, 2, &outputs[0]);
553   DecodeNFrames(&outputs[0], 20);
554   FreeBitstreamBuffers(&outputs[0], 20);
555 }
556
557 TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
558   // First pass encode
559   std::string stats_buf;
560   vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1,1/1");
561   Pass1EncodeNFrames(20, 3, &stats_buf);
562
563   // Second pass encode
564   codec_enc_.g_pass = VPX_RC_LAST_PASS;
565   vpx_svc_set_options(&svc_,
566                       "auto-alt-refs=1,1,1 scale-factors=1/1,1/1,1/1");
567   vpx_fixed_buf outputs[20];
568   memset(&outputs[0], 0, sizeof(outputs));
569   Pass2EncodeNFrames(&stats_buf, 20, 3, &outputs[0]);
570   DecodeNFrames(&outputs[0], 20);
571   DropEnhancementLayers(&outputs[0], 20, 2);
572   DecodeNFrames(&outputs[0], 20);
573   DropEnhancementLayers(&outputs[0], 20, 1);
574   DecodeNFrames(&outputs[0], 20);
575
576   FreeBitstreamBuffers(&outputs[0], 20);
577 }
578
579 }  // namespace