| Index: source/libvpx/test/svc_test.cc
 | 
| ===================================================================
 | 
| --- source/libvpx/test/svc_test.cc	(revision 263011)
 | 
| +++ source/libvpx/test/svc_test.cc	(working copy)
 | 
| @@ -31,6 +31,7 @@
 | 
|    SvcTest()
 | 
|        : codec_iface_(0),
 | 
|          test_file_name_("hantro_collage_w352h288.yuv"),
 | 
| +        stats_file_name_("hantro_collage_w352h288.stat"),
 | 
|          codec_initialized_(false),
 | 
|          decoder_(0) {
 | 
|      memset(&svc_, 0, sizeof(svc_));
 | 
| @@ -73,6 +74,7 @@
 | 
|    struct vpx_codec_enc_cfg codec_enc_;
 | 
|    vpx_codec_iface_t *codec_iface_;
 | 
|    std::string test_file_name_;
 | 
| +  std::string stats_file_name_;
 | 
|    bool codec_initialized_;
 | 
|    Decoder *decoder_;
 | 
|  };
 | 
| @@ -362,4 +364,109 @@
 | 
|    EXPECT_EQ(kHeight * 8 / 16, layer_height);
 | 
|  }
 | 
|  
 | 
| +TEST_F(SvcTest, FirstPassEncode) {
 | 
| +  svc_.spatial_layers = 2;
 | 
| +  codec_enc_.g_pass = VPX_RC_FIRST_PASS;
 | 
| +  vpx_svc_set_scale_factors(&svc_, "4/16,16/16");
 | 
| +  vpx_svc_set_quantizers(&svc_, "40,30", 0);
 | 
| +
 | 
| +  vpx_codec_err_t res =
 | 
| +      vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  codec_initialized_ = true;
 | 
| +
 | 
| +  libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
 | 
| +                                     codec_enc_.g_timebase.den,
 | 
| +                                     codec_enc_.g_timebase.num, 0, 30);
 | 
| +  // FRAME 0
 | 
| +  video.Begin();
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_GT(vpx_svc_get_rc_stats_buffer_size(&svc_), 0U);
 | 
| +
 | 
| +  // FRAME 1
 | 
| +  video.Next();
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_GT(vpx_svc_get_rc_stats_buffer_size(&svc_), 0U);
 | 
| +
 | 
| +  // Flush encoder and test EOS packet
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, NULL, video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_GT(vpx_svc_get_rc_stats_buffer_size(&svc_), 0U);
 | 
| +}
 | 
| +
 | 
| +TEST_F(SvcTest, SecondPassEncode) {
 | 
| +  svc_.spatial_layers = 2;
 | 
| +  codec_enc_.g_pass = VPX_RC_LAST_PASS;
 | 
| +
 | 
| +  FILE *const stats_file = libvpx_test::OpenTestDataFile(stats_file_name_);
 | 
| +  ASSERT_TRUE(stats_file != NULL) << "Stats file open failed. Filename: "
 | 
| +      << stats_file;
 | 
| +
 | 
| +  struct vpx_fixed_buf stats_buf;
 | 
| +  fseek(stats_file, 0, SEEK_END);
 | 
| +  stats_buf.sz = static_cast<size_t>(ftell(stats_file));
 | 
| +  fseek(stats_file, 0, SEEK_SET);
 | 
| +
 | 
| +  stats_buf.buf = malloc(stats_buf.sz);
 | 
| +  ASSERT_TRUE(stats_buf.buf != NULL);
 | 
| +  const size_t bytes_read = fread(stats_buf.buf, 1, stats_buf.sz, stats_file);
 | 
| +  ASSERT_EQ(bytes_read, stats_buf.sz);
 | 
| +  fclose(stats_file);
 | 
| +  codec_enc_.rc_twopass_stats_in = stats_buf;
 | 
| +
 | 
| +  vpx_codec_err_t res =
 | 
| +      vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  codec_initialized_ = true;
 | 
| +
 | 
| +  libvpx_test::I420VideoSource video(test_file_name_, kWidth, kHeight,
 | 
| +                                     codec_enc_.g_timebase.den,
 | 
| +                                     codec_enc_.g_timebase.num, 0, 30);
 | 
| +  // FRAME 0
 | 
| +  video.Begin();
 | 
| +  // This frame is a keyframe.
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_EQ(1, vpx_svc_is_keyframe(&svc_));
 | 
| +
 | 
| +  vpx_codec_err_t res_dec = decoder_->DecodeFrame(
 | 
| +      static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)),
 | 
| +      vpx_svc_get_frame_size(&svc_));
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
 | 
| +
 | 
| +  // FRAME 1
 | 
| +  video.Next();
 | 
| +  // This is a P-frame.
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
 | 
| +
 | 
| +  res_dec = decoder_->DecodeFrame(
 | 
| +      static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)),
 | 
| +      vpx_svc_get_frame_size(&svc_));
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
 | 
| +
 | 
| +  // FRAME 2
 | 
| +  video.Next();
 | 
| +  // This is a P-frame.
 | 
| +  res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
 | 
| +                       video.duration(), VPX_DL_GOOD_QUALITY);
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res);
 | 
| +  EXPECT_EQ(0, vpx_svc_is_keyframe(&svc_));
 | 
| +
 | 
| +  res_dec = decoder_->DecodeFrame(
 | 
| +      static_cast<const uint8_t *>(vpx_svc_get_buffer(&svc_)),
 | 
| +      vpx_svc_get_frame_size(&svc_));
 | 
| +  ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
 | 
| +
 | 
| +  free(stats_buf.buf);
 | 
| +}
 | 
| +
 | 
|  }  // namespace
 | 
| 
 |