663916cea7
These changes were originally made in the Stratacaster team-review repository commit e114bffcd82ad74c3696ec58e13c0ac895d6c82d Author: Charles 'Buck' Krasic <ckrasic@google.com> Date: Mon Oct 14 16:52:13 2013 -0700 Make dummy frame handling a bit more explicit, fixing bug with single layer encodes. Squashed commit of the following: commit 1ebbfd976c0fadb02bf1ea562a2d0e3f0206daad Merge:ac468dd
54e88b7 Author: Ivan Maltz <ivanmaltz@google.com> Date: Fri Oct 11 17:29:58 2013 -0700 Move SVC code from vp9_spatial_scalable_encoder to libvpx module accessible from ffmpeg commit 54e88b78b160becc9569fc3c6cb6b0a8c95dc357 Author: Ivan Maltz <ivanmaltz@google.com> Date: Tue Oct 8 09:08:40 2013 -0700 common svc encoding code for sample app and ffmpeg added svc_encodeframe.c, svc_context.h, svc_test.cc vp9_spatial_scalable_encoder uses vpx_svc_encode commit 5616ec8e2e3d3e8d277333d8a9242f6c70151162 Merge: 4528014e29137d
Author: Ivan Maltz <ivanmaltz@google.com> Date: Tue Oct 8 08:47:58 2013 -0700 Merge branch 'master' into stratacaster commit 45280148450b1f3d61e390df8aadedf85cd5bce1 Merge: bb2b6751ab60f7
Author: Sujeevan Rajayogam <sujee@google.com> Date: Fri Oct 4 10:22:31 2013 -0700 Merge branch 'master' into stratacaster commit bb2b675e595dc9bfc8551e963edf56800c3aea61 Author: Sujeevan Rajayogam <sujee@google.com> Date: Wed Oct 2 12:37:26 2013 -0700 Track individual frame sizes and psnrs instead of averages. commit c6d303b714795c81e7ceb4173967115c9f8ff5b7 Merge: fa87df93583087
Author: Sujeevan Rajayogam <sujee@google.com> Date: Fri Sep 27 10:05:35 2013 -0700 Merge branch 'master' into stratacaster commit fa87df94fba923d9f7aeb8ae20c6e15f777e00b5 Merge: bf22d713c465af
Author: Sujeevan Rajayogam <sujee@google.com> Date: Thu Sep 26 16:10:31 2013 -0700 Merge branch 'master' into stratacaster commit bf22d7144895a82e0c348ac177c8a261b9e2b88e Author: Sujeevan Rajayogam <sujee@google.com> Date: Thu Sep 26 11:10:34 2013 -0700 Parameterized quantizer, 16th scalefactors, more logging, enabled single layer encodes to generate baseline. commit ceffd7e6025b765f9886b5ea0f324248aa37e327 Author: Sujeevan Rajayogam <sujee@google.com> Date: Thu Sep 19 10:04:49 2013 -0700 - Include new mode for 3 layer I frame with 5 total layers. - Refactor svc api. Change-Id: Ie4d775e21e006fa597d884c59488dc999478e9b5
191 lines
6.0 KiB
C++
191 lines
6.0 KiB
C++
#include <string>
|
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
|
#include "test/i420_video_source.h"
|
|
#include "test/decode_test_driver.h"
|
|
#include "vpx/vpx_encoder.h"
|
|
#include "vpx/vp8cx.h"
|
|
#include "test/codec_factory.h"
|
|
|
|
extern "C" {
|
|
#include "vpx/svc_context.h"
|
|
}
|
|
|
|
namespace {
|
|
|
|
using libvpx_test::CodecFactory;
|
|
using libvpx_test::VP9CodecFactory;
|
|
using libvpx_test::Decoder;
|
|
|
|
class SvcTest : public ::testing::Test {
|
|
protected:
|
|
SvcTest()
|
|
: codec_iface_(0),
|
|
test_file_name("hantro_collage_w352h288.yuv"),
|
|
decoder_(0) {}
|
|
|
|
virtual void SetUp() {
|
|
memset(&svc_, 0, sizeof(svc_));
|
|
svc_.first_frame_full_size = 1;
|
|
svc_.encoding_mode = INTER_LAYER_PREDICTION_IP;
|
|
svc_.log_level = SVC_LOG_DEBUG;
|
|
svc_.log_print = 1;
|
|
svc_.gop_size = 100;
|
|
|
|
codec_iface_ = vpx_codec_vp9_cx();
|
|
vpx_codec_err_t res =
|
|
vpx_codec_enc_config_default(codec_iface_, &codec_enc_, 0);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
|
|
codec_enc_.g_w = kWidth;
|
|
codec_enc_.g_h = kHeight;
|
|
codec_enc_.g_timebase.num = 1;
|
|
codec_enc_.g_timebase.den = 60;
|
|
|
|
vpx_codec_dec_cfg_t dec_cfg = {0};
|
|
VP9CodecFactory codec_factory;
|
|
decoder_ = codec_factory.CreateDecoder(dec_cfg, 0);
|
|
}
|
|
|
|
SvcContext svc_;
|
|
vpx_codec_ctx_t codec_;
|
|
struct vpx_codec_enc_cfg codec_enc_;
|
|
vpx_codec_iface_t* codec_iface_;
|
|
std::string test_file_name;
|
|
enum {
|
|
kWidth = 352,
|
|
kHeight = 288,
|
|
};
|
|
|
|
Decoder* decoder_;
|
|
};
|
|
|
|
TEST_F(SvcTest, SvcInit) {
|
|
svc_.spatial_layers = 0; // not enough layers
|
|
vpx_codec_err_t res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_INVALID_PARAM);
|
|
|
|
svc_.spatial_layers = 6; // too many layers
|
|
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_INVALID_PARAM);
|
|
|
|
svc_.spatial_layers = 2;
|
|
svc_.scale_factors = "4/16,16*16"; // invalid scale values
|
|
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_INVALID_PARAM);
|
|
|
|
svc_.scale_factors = "4/16,16/16"; // valid scale values
|
|
|
|
res = vpx_svc_init(&svc_, &codec_, codec_iface_, &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
}
|
|
|
|
// test that decoder can handle an svc frame as the first frame in a sequence
|
|
// this test is disabled since it with the deco
|
|
TEST_F(SvcTest, DISABLED_FirstFrameHasLayers) {
|
|
svc_.first_frame_full_size = 0;
|
|
svc_.spatial_layers = 2;
|
|
svc_.scale_factors = "4/16,16/16";
|
|
svc_.quantizer_values = "40,30";
|
|
|
|
vpx_codec_err_t res =
|
|
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
|
|
libvpx_test::I420VideoSource video(test_file_name, kWidth, kHeight,
|
|
codec_enc_.g_timebase.den,
|
|
codec_enc_.g_timebase.num, 0, 30);
|
|
video.Begin();
|
|
|
|
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
|
|
video.duration(), VPX_DL_REALTIME);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
|
|
vpx_codec_err_t res_dec = decoder_->DecodeFrame(
|
|
(const uint8_t*)svc_get_buffer(&svc_), svc_get_frame_size(&svc_));
|
|
|
|
// this test fails with a decoder error
|
|
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
|
|
}
|
|
|
|
TEST_F(SvcTest, EncodeThreeFrames) {
|
|
svc_.first_frame_full_size = 1;
|
|
svc_.spatial_layers = 2;
|
|
svc_.scale_factors = "4/16,16/16";
|
|
svc_.quantizer_values = "40,30";
|
|
|
|
vpx_codec_err_t res =
|
|
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
|
ASSERT_EQ(res, VPX_CODEC_OK);
|
|
|
|
libvpx_test::I420VideoSource video(test_file_name, kWidth, kHeight,
|
|
codec_enc_.g_timebase.den,
|
|
codec_enc_.g_timebase.num, 0, 30);
|
|
// FRAME 1
|
|
video.Begin();
|
|
// this frame is full size, with only one layer
|
|
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
|
|
video.duration(), VPX_DL_REALTIME);
|
|
ASSERT_EQ(res, VPX_CODEC_OK);
|
|
EXPECT_EQ(1, svc_is_keyframe(&svc_));
|
|
|
|
vpx_codec_err_t res_dec = decoder_->DecodeFrame(
|
|
(const uint8_t*)svc_get_buffer(&svc_), svc_get_frame_size(&svc_));
|
|
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
|
|
|
|
// FRAME 2
|
|
video.Next();
|
|
// this is an I-frame
|
|
res = vpx_svc_encode(&svc_, &codec_, video.img(), video.pts(),
|
|
video.duration(), VPX_DL_REALTIME);
|
|
ASSERT_EQ(res, VPX_CODEC_OK);
|
|
EXPECT_EQ(1, svc_is_keyframe(&svc_));
|
|
|
|
res_dec = decoder_->DecodeFrame((const uint8_t*)svc_get_buffer(&svc_),
|
|
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_REALTIME);
|
|
ASSERT_EQ(res, VPX_CODEC_OK);
|
|
EXPECT_EQ(0, svc_is_keyframe(&svc_));
|
|
|
|
res_dec = decoder_->DecodeFrame((const uint8_t*)svc_get_buffer(&svc_),
|
|
svc_get_frame_size(&svc_));
|
|
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder_->DecodeError();
|
|
}
|
|
|
|
TEST_F(SvcTest, GetLayerResolution) {
|
|
unsigned int layer_width, layer_height;
|
|
|
|
svc_.first_frame_full_size = 0;
|
|
svc_.spatial_layers = 2;
|
|
svc_.scale_factors = "4/16,8/16";
|
|
svc_.quantizer_values = "40,30";
|
|
|
|
vpx_codec_err_t res =
|
|
vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
|
|
// ensure that requested layer is a valid layer
|
|
res = svc_get_layer_resolution(&svc_, svc_.spatial_layers, &layer_width,
|
|
&layer_height);
|
|
EXPECT_EQ(res, VPX_CODEC_INVALID_PARAM);
|
|
|
|
res = svc_get_layer_resolution(&svc_, 0, &layer_width,
|
|
&layer_height);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
EXPECT_EQ((unsigned int)(kWidth * 4 / 16), layer_width);
|
|
EXPECT_EQ((unsigned int)(kHeight * 4 / 16), layer_height);
|
|
|
|
res = svc_get_layer_resolution(&svc_, 1, &layer_width,
|
|
&layer_height);
|
|
EXPECT_EQ(res, VPX_CODEC_OK);
|
|
EXPECT_EQ((unsigned int)(kWidth * 8 / 16), layer_width);
|
|
EXPECT_EQ((unsigned int)(kHeight * 8 / 16), layer_height);
|
|
}
|
|
|
|
} // namespace
|