]> granicus.if.org Git - libvpx/blob - test/svc_test.cc
218f53db77315d6189351ee572b71a6889b2d1bf
[libvpx] / 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 = vpx_codec_dec_cfg_t();
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 + 16);
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, static_cast<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() != NULL) {
208         ++received_frames;
209       }
210     }
211     EXPECT_EQ(decoded_frames, n);
212     EXPECT_EQ(received_frames, n);
213   }
214
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);
222
223     for (int i = 0; i < num_super_frames; ++i) {
224       uint32_t frame_sizes[8] = {0};
225       int frame_count = 0;
226       int frames_found = 0;
227       int frame;
228       ASSERT_TRUE(inputs[i].buf != NULL);
229       ASSERT_GT(inputs[i].sz, 0U);
230
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,
234                                      NULL, NULL);
235       ASSERT_EQ(VPX_CODEC_OK, res);
236
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;
243           unsigned int mask;
244           int mag;
245
246           // Choose the magnitude.
247           for (mag = 0, mask = 0xff; mag < 4; ++mag) {
248             if (inputs[i].sz < mask)
249               break;
250             mask <<= 8;
251             mask |= 0xff;
252           }
253           marker |= mag << 3;
254           int index_sz = 2 + (mag + 1) * 2;
255
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;
263
264           // Write the super frame index.
265           *frame_data++ = marker;
266
267           frame_sizes[0] = inputs[i].sz;
268           frame_sizes[1] = 1;
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;
273               this_sz >>= 8;
274             }
275           }
276           *frame_data++ = marker;
277           inputs[i].sz += index_sz + 1;
278         }
279       } else {
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) {
286             ++frames_found;
287             if (frames_found == remained_spatial_layers)
288               break;
289           }
290           frame_data += frame_sizes[frame];
291         }
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)
297           continue;
298
299         frame_data += frame_sizes[frame];
300
301         // We need to add one more frame for multiple frame contexts.
302         if (is_multiple_frame_contexts)
303           ++frame;
304         uint8_t marker =
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);
309         marker &= 0x0f8;
310         marker |= frame;
311
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);
318         }
319         // New marker.
320         frame_data[0] = marker;
321         frame_data += (mag * (frame + 1) + 1);
322
323         if (is_multiple_frame_contexts) {
324           // Write the frame size for the one byte frame.
325           frame_data -= mag;
326           *frame_data++ = 1;
327           for (uint32_t j = 1; j < mag; ++j) {
328             *frame_data++ = 0;
329           }
330         }
331
332         *frame_data++ = marker;
333         inputs[i].sz = frame_data - frame_start;
334
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];
340           }
341         }
342       }
343     }
344   }
345
346   void FreeBitstreamBuffers(struct vpx_fixed_buf *const inputs, const int n) {
347     ASSERT_TRUE(inputs != NULL);
348     ASSERT_GT(n, 0);
349
350     for (int i = 0; i < n; ++i) {
351       free(inputs[i].buf);
352       inputs[i].buf = NULL;
353       inputs[i].sz = 0;
354     }
355   }
356
357   SvcContext svc_;
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_;
363   Decoder *decoder_;
364 };
365
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);
374
375   res = vpx_svc_init(&svc_, &codec_, codec_iface_, NULL);
376   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
377
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);
381
382   svc_.spatial_layers = 0;  // use default layers
383   InitializeEncoder();
384   EXPECT_EQ(VPX_SS_DEFAULT_LAYERS, svc_.spatial_layers);
385 }
386
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);
392
393   vpx_svc_set_scale_factors(&svc_, "4/16,16/16");  // valid scale values
394   InitializeEncoder();
395 }
396
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);
400
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);
405 }
406
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);
410   InitializeEncoder();
411   EXPECT_EQ(3, svc_.spatial_layers);
412 }
413
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);
418   InitializeEncoder();
419   EXPECT_EQ(2, svc_.spatial_layers);
420 }
421
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);
429
430   res = vpx_svc_set_options(&svc_, "scale-factors=1/3,2/3");
431   EXPECT_EQ(VPX_CODEC_OK, res);
432   InitializeEncoder();
433 }
434
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);
441
442   vpx_svc_set_options(&svc_, "quantizers=40,45");
443   InitializeEncoder();
444 }
445
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);
452
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);
457
458   vpx_svc_set_options(&svc_, "auto-alt-refs=0,1,1,1,0");
459   InitializeEncoder();
460 }
461
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);
465
466   res = vpx_svc_set_quantizers(&svc_, NULL);
467   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
468
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);
474
475   res = vpx_svc_set_quantizers(&svc_, "40,30");
476   EXPECT_EQ(VPX_CODEC_OK, res);
477   InitializeEncoder();
478 }
479
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);
483
484   res = vpx_svc_set_scale_factors(&svc_, NULL);
485   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
486
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);
492
493   res = vpx_svc_set_scale_factors(&svc_, "4/16,16/16");
494   EXPECT_EQ(VPX_CODEC_OK, res);
495   InitializeEncoder();
496 }
497
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);
505 }
506
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);
514 }
515
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");
520
521   InitializeEncoder();
522
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);
528
529   res = vpx_svc_get_layer_resolution(NULL, 0, &layer_width, &layer_height);
530   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
531
532   res = vpx_svc_get_layer_resolution(&svc_, 0, NULL, &layer_height);
533   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
534
535   res = vpx_svc_get_layer_resolution(&svc_, 0, &layer_width, NULL);
536   EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res);
537
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);
542
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);
547 }
548
549 TEST_F(SvcTest, TwoPassEncode10Frames) {
550   // First pass encode
551   std::string stats_buf;
552   Pass1EncodeNFrames(10, 2, &stats_buf);
553
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);
561 }
562
563 TEST_F(SvcTest, TwoPassEncode20FramesWithAltRef) {
564   // First pass encode
565   std::string stats_buf;
566   Pass1EncodeNFrames(20, 2, &stats_buf);
567
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);
576 }
577
578 TEST_F(SvcTest, TwoPassEncode2SpatialLayersDecodeBaseLayerOnly) {
579   // First pass encode
580   std::string stats_buf;
581   Pass1EncodeNFrames(10, 2, &stats_buf);
582
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);
592 }
593
594 TEST_F(SvcTest, TwoPassEncode5SpatialLayersDecode54321Layers) {
595   // First pass encode
596   std::string stats_buf;
597   Pass1EncodeNFrames(10, 5, &stats_buf);
598
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]);
605
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);
615
616   FreeBitstreamBuffers(&outputs[0], 10);
617 }
618
619 TEST_F(SvcTest, TwoPassEncode2SNRLayers) {
620   // First pass encode
621   std::string stats_buf;
622   vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
623   Pass1EncodeNFrames(20, 2, &stats_buf);
624
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);
634 }
635
636 TEST_F(SvcTest, TwoPassEncode3SNRLayersDecode321Layers) {
637   // First pass encode
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);
641
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);
654
655   FreeBitstreamBuffers(&outputs[0], 20);
656 }
657
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);
665
666   svc_.spatial_layers = 2;
667   res = vpx_svc_set_options(&svc_, "multi-frame-contexts=1");
668   InitializeEncoder();
669 }
670
671 TEST_F(SvcTest, TwoPassEncode2SpatialLayersWithMultipleFrameContexts) {
672   // First pass encode
673   std::string stats_buf;
674   Pass1EncodeNFrames(10, 2, &stats_buf);
675
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);
686 }
687
688 TEST_F(SvcTest,
689        TwoPassEncode2SpatialLayersWithMultipleFrameContextsDecodeBaselayer) {
690   // First pass encode
691   std::string stats_buf;
692   Pass1EncodeNFrames(10, 2, &stats_buf);
693
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);
704 }
705
706 TEST_F(SvcTest, TwoPassEncode2SNRLayersWithMultipleFrameContexts) {
707   // First pass encode
708   std::string stats_buf;
709   vpx_svc_set_options(&svc_, "scale-factors=1/1,1/1");
710   Pass1EncodeNFrames(10, 2, &stats_buf);
711
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);
723 }
724
725 TEST_F(SvcTest,
726        TwoPassEncode3SNRLayersWithMultipleFrameContextsDecode321Layer) {
727   // First pass encode
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);
731
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]);
740
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;
747   }
748   DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 3, true);
749   DecodeNFrames(&outputs_new[0], 10);
750
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;
754   }
755   DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 2, true);
756   DecodeNFrames(&outputs_new[0], 10);
757
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;
761   }
762   DropLayersAndMakeItVP9Comaptible(&outputs_new[0], 10, 1, true);
763   DecodeNFrames(&outputs_new[0], 10);
764
765   FreeBitstreamBuffers(&outputs[0], 10);
766   FreeBitstreamBuffers(&outputs_new[0], 10);
767 }
768
769 TEST_F(SvcTest, TwoPassEncode2TemporalLayers) {
770   // First pass encode
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);
775
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);
785 }
786
787 TEST_F(SvcTest, TwoPassEncode2TemporalLayersWithMultipleFrameContexts) {
788   // First pass encode
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);
793
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);
806 }
807
808 TEST_F(SvcTest, TwoPassEncode2TemporalLayersDecodeBaseLayer) {
809   // First pass encode
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);
814
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]);
822
823   vpx_fixed_buf base_layer[5];
824   for (int i = 0; i < 5; ++i)
825     base_layer[i] = outputs[i * 2];
826
827   DecodeNFrames(&base_layer[0], 5);
828   FreeBitstreamBuffers(&outputs[0], 10);
829 }
830
831 TEST_F(SvcTest,
832        TwoPassEncode2TemporalLayersWithMultipleFrameContextsDecodeBaseLayer) {
833   // First pass encode
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);
838
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);
849
850   vpx_fixed_buf base_layer[5];
851   for (int i = 0; i < 5; ++i)
852     base_layer[i] = outputs[i * 2];
853
854   DecodeNFrames(&base_layer[0], 5);
855   FreeBitstreamBuffers(&outputs[0], 10);
856 }
857
858 }  // namespace