Commit cd74a901 authored by James Zern's avatar James Zern

Revert "Merge "SVC improvements""

This reverts commit a82001b1, reversing
changes made to f6d870f7.

This commit breaks windows builds and needs some work to fix those and
some additional comments.

Change-Id: Ic0b0228e36704b127e5e399ce59db26182cfffe7
parent a82001b1
......@@ -122,7 +122,6 @@ ifeq ($(CONFIG_VP9_ENCODER),yes)
CODEC_EXPORTS-yes += $(addprefix $(VP9_PREFIX),$(VP9_CX_EXPORTS))
CODEC_SRCS-yes += $(VP9_PREFIX)vp9cx.mk vpx/vp8.h vpx/vp8cx.h
INSTALL-LIBS-yes += include/vpx/vp8.h include/vpx/vp8cx.h
INSTALL-LIBS-yes += include/vpx/svc_context.h
INSTALL_MAPS += include/vpx/% $(SRC_PATH_BARE)/$(VP9_PREFIX)/%
CODEC_DOC_SRCS += vpx/vp8.h vpx/vp8cx.h
CODEC_DOC_SECTIONS += vp9 vp9_encoder
......
#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
......@@ -96,7 +96,6 @@ LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += fdct8x8_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct16x16_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += variance_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += dct32x32_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_VP9_ENCODER) += svc_test.cc
endif # VP9
......
......@@ -221,6 +221,8 @@ extern "C"
int vp9_set_size_literal(VP9_PTR comp, unsigned int width,
unsigned int height);
int vp9_switch_layer(VP9_PTR comp, int layer);
void vp9_set_svc(VP9_PTR comp, int use_svc);
int vp9_get_quantizer(VP9_PTR c);
......
......@@ -4226,9 +4226,37 @@ int vp9_set_size_literal(VP9_PTR comp, unsigned int width,
return 0;
}
int vp9_switch_layer(VP9_PTR comp, int layer) {
VP9_COMP *cpi = (VP9_COMP *)comp;
if (cpi->use_svc) {
cpi->current_layer = layer;
// Use buffer i for layer i LST
cpi->lst_fb_idx = layer;
// Use buffer i-1 for layer i Alt (Inter-layer prediction)
if (layer != 0) cpi->alt_fb_idx = layer - 1;
// Use the rest for Golden
if (layer < 2 * cpi->number_spatial_layers - NUM_REF_FRAMES)
cpi->gld_fb_idx = cpi->lst_fb_idx;
else
cpi->gld_fb_idx = 2 * cpi->number_spatial_layers - 1 - layer;
printf("Switching to layer %d:\n", layer);
printf("Using references: LST/GLD/ALT [%d|%d|%d]\n", cpi->lst_fb_idx,
cpi->gld_fb_idx, cpi->alt_fb_idx);
} else {
printf("Switching layer not supported. Enable SVC first \n");
}
return 0;
}
void vp9_set_svc(VP9_PTR comp, int use_svc) {
VP9_COMP *cpi = (VP9_COMP *)comp;
cpi->use_svc = use_svc;
if (cpi->use_svc) printf("Enabled SVC encoder \n");
return;
}
......
......@@ -442,6 +442,8 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx,
MAP(VP8E_SET_ARNR_TYPE, xcfg.arnr_type);
MAP(VP8E_SET_TUNING, xcfg.tuning);
MAP(VP8E_SET_CQ_LEVEL, xcfg.cq_level);
MAP(VP9E_SET_MAX_Q, ctx->cfg.rc_max_quantizer);
MAP(VP9E_SET_MIN_Q, ctx->cfg.rc_min_quantizer);
MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, xcfg.rc_max_intra_bitrate_pct);
MAP(VP9E_SET_LOSSLESS, xcfg.lossless);
MAP(VP9E_SET_FRAME_PARALLEL_DECODING, xcfg.frame_parallel_decoding_mode);
......@@ -1027,40 +1029,66 @@ static vpx_codec_err_t vp9e_set_scalemode(vpx_codec_alg_priv_t *ctx,
}
}
static vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
va_list args) {
int data = va_arg(args, int);
vp9_set_svc(ctx->cpi, data);
return VPX_CODEC_OK;
static vpx_codec_err_t vp9e_set_width(vpx_codec_alg_priv_t *ctx, int ctr_id,
va_list args) {
unsigned int *data = va_arg(args, unsigned int *);
if (data) {
int res;
res = vp9_set_size_literal(ctx->cpi, *data, 0);
if (!res) {
return VPX_CODEC_OK;
} else {
return VPX_CODEC_INVALID_PARAM;
}
} else {
return VPX_CODEC_INVALID_PARAM;
}
}
static vpx_codec_err_t vp9e_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
int ctr_id, va_list args) {
vpx_svc_parameters_t *data = va_arg(args, vpx_svc_parameters_t *);
VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
vpx_svc_parameters_t params;
static vpx_codec_err_t vp9e_set_height(vpx_codec_alg_priv_t *ctx,
int ctr_id,
va_list args) {
unsigned int *data = va_arg(args, unsigned int *);
if (data) {
int res;
res = vp9_set_size_literal(ctx->cpi, 0, *data);
if (!data) {
if (!res) {
return VPX_CODEC_OK;
} else {
return VPX_CODEC_INVALID_PARAM;
}
} else {
return VPX_CODEC_INVALID_PARAM;
}
}
static vpx_codec_err_t vp9e_set_layer(vpx_codec_alg_priv_t *ctx,
int ctr_id,
va_list args) {
unsigned int *data = va_arg(args, unsigned int *);
params = *(vpx_svc_parameters_t *)data;
if (data) {
int res;
res = 0;
cpi->current_layer = params.layer;
cpi->lst_fb_idx = params.lst_fb_idx;
cpi->gld_fb_idx = params.gld_fb_idx;
cpi->alt_fb_idx = params.alt_fb_idx;
res = vp9_switch_layer(ctx->cpi, *data);
if (vp9_set_size_literal(ctx->cpi, params.width, params.height) != 0) {
if (!res) {
return VPX_CODEC_OK;
} else {
return VPX_CODEC_INVALID_PARAM;
}
} else {
return VPX_CODEC_INVALID_PARAM;
}
}
ctx->cfg.rc_max_quantizer = params.max_quantizer;
ctx->cfg.rc_min_quantizer = params.min_quantizer;
set_vp9e_config(&ctx->oxcf, ctx->cfg, ctx->vp8_cfg);
vp9_change_config(ctx->cpi, &ctx->oxcf);
static vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id,
va_list args) {
int data = va_arg(args, int);
vp9_set_svc(ctx->cpi, data);
return VPX_CODEC_OK;
}
......@@ -1088,12 +1116,16 @@ static vpx_codec_ctrl_fn_map_t vp9e_ctf_maps[] = {
{VP8E_SET_ARNR_TYPE, set_param},
{VP8E_SET_TUNING, set_param},
{VP8E_SET_CQ_LEVEL, set_param},
{VP9E_SET_MAX_Q, set_param},
{VP9E_SET_MIN_Q, set_param},
{VP8E_SET_MAX_INTRA_BITRATE_PCT, set_param},
{VP9E_SET_LOSSLESS, set_param},
{VP9E_SET_FRAME_PARALLEL_DECODING, set_param},
{VP9_GET_REFERENCE, get_reference},
{VP9E_SET_WIDTH, vp9e_set_width},
{VP9E_SET_HEIGHT, vp9e_set_height},
{VP9E_SET_LAYER, vp9e_set_layer},
{VP9E_SET_SVC, vp9e_set_svc},
{VP9E_SET_SVC_PARAMETERS, vp9e_set_svc_parameters},
{ -1, NULL},
};
......
This diff is collapsed.
......@@ -6,12 +6,3 @@ text vpx_codec_get_cx_data
text vpx_codec_get_global_headers
text vpx_codec_get_preview_frame
text vpx_codec_set_cx_data_buf
text vpx_svc_init
text vpx_svc_encode
text svc_dump_statistics
text svc_get_message
text svc_get_buffer
text svc_get_frame_size
text svc_get_encode_frame_count
text svc_is_keyframe
text svc_set_keyframe
\ No newline at end of file
This diff is collapsed.
/**
* SvcContext - input parameters and state to encode a multi-layered
* spatial SVC frame
*/
#ifndef VPX_SVC_CONTEXT_H_
#define VPX_SVC_CONTEXT_H_
typedef enum SVC_ENCODING_MODE {
INTER_LAYER_PREDICTION_I,
ALT_INTER_LAYER_PREDICTION_IP,
INTER_LAYER_PREDICTION_IP,
USE_GOLDEN_FRAME
} SVC_ENCODING_MODE;
typedef enum SVC_LOG_LEVEL {
SVC_LOG_ERROR,
SVC_LOG_INFO,
SVC_LOG_DEBUG,
} SVC_LOG_LEVEL;
typedef struct {
// public interface to svc_command options
int enabled; // set to non-zero to enable svc encoding
int spatial_layers; // number of layers
int first_frame_full_size; // set to one to force first frame full size
SVC_ENCODING_MODE encoding_mode; // svc encoding strategy
// the following lists are ordered from highest resolution to lowest
// if the strings are null, default values are used
const char* quantizer_values; // quantizer values, e.g., "27,33,39,53,60"
const char* scale_factors; // layer scale factors, e.g.,
// "16/16,11/16,7/16,5/16,4/16"
int gop_size; // distance between keyframes
SVC_LOG_LEVEL log_level; // amount of information to display
int log_print; // when set, printf log messages instead of returning the
// message with svc_get_message
// private storage for vpx_svc_encode
void* internal;
} SvcContext;
vpx_codec_err_t vpx_svc_init(SvcContext* svc_ctx, vpx_codec_ctx_t* codec_ctx,
vpx_codec_iface_t* iface,
vpx_codec_enc_cfg_t* cfg);
vpx_codec_err_t vpx_svc_encode(SvcContext* svc_ctx, vpx_codec_ctx_t* codec_ctx,
struct vpx_image* rawimg, vpx_codec_pts_t pts,
int64_t duration, int deadline);
void svc_dump_statistics(SvcContext* svc_ctx);
char* svc_get_message(SvcContext* svc_ctx);
void* svc_get_buffer(SvcContext* svc_ctx);
vpx_codec_err_t svc_get_layer_resolution(SvcContext* svc_ctx, int layer,
unsigned int* width, unsigned int* height);
int svc_get_frame_size(SvcContext* svc_ctx);
int svc_get_encode_frame_count(SvcContext* svc_ctx);
int svc_is_keyframe(SvcContext* svc_ctx);
void svc_set_keyframe(SvcContext* svc_ctx);
#endif /* VPX_SVC_CONTEXT_H_ */
......@@ -195,8 +195,13 @@ enum vp8e_enc_control_id {
VP9E_SET_TILE_ROWS,
VP9E_SET_FRAME_PARALLEL_DECODING,
VP9E_SET_WIDTH = 99,
VP9E_SET_HEIGHT,
VP9E_SET_LAYER,
VP9E_SET_SVC,
VP9E_SET_SVC_PARAMETERS
VP9E_SET_MAX_Q,
VP9E_SET_MIN_Q
};
/*!\brief vpx 1-D scaling mode
......@@ -278,23 +283,6 @@ typedef enum {
VP8_TUNE_SSIM
} vp8e_tuning;
/*!\brief vp9 svc parameters
*
* This defines parameters for svc encoding.
*
*/
typedef struct vpx_svc_parameters {
unsigned int width; /**< width of current spatial layer */
unsigned int height; /**< height of current spatial layer */
int layer; /**< current layer number - 0 = base */
int flags; /**< encode frame flags */
int max_quantizer; /**< max quantizer for current layer */
int min_quantizer; /**< min quantizer for current layer */
int distance_from_i_frame; /**< frame number within current gop */
int lst_fb_idx; /**< last frame frame buffer index */
int gld_fb_idx; /**< golden frame frame buffer index */
int alt_fb_idx; /**< alt reference frame frame buffer index */
} vpx_svc_parameters_t;
/*!\brief VP8 encoder control function parameter type
*
......@@ -315,8 +303,11 @@ VPX_CTRL_USE_TYPE(VP8E_SET_ROI_MAP, vpx_roi_map_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_ACTIVEMAP, vpx_active_map_t *)
VPX_CTRL_USE_TYPE(VP8E_SET_SCALEMODE, vpx_scaling_mode_t *)
VPX_CTRL_USE_TYPE(VP9E_SET_LAYER, int *)
VPX_CTRL_USE_TYPE(VP9E_SET_SVC, int)
VPX_CTRL_USE_TYPE(VP9E_SET_SVC_PARAMETERS, vpx_svc_parameters_t *)
VPX_CTRL_USE_TYPE(VP9E_SET_WIDTH, unsigned int *)
VPX_CTRL_USE_TYPE(VP9E_SET_HEIGHT, unsigned int *)
VPX_CTRL_USE_TYPE(VP8E_SET_CPUUSED, int)
VPX_CTRL_USE_TYPE(VP8E_SET_ENABLEAUTOALTREF, unsigned int)
......@@ -343,6 +334,8 @@ VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PARALLEL_DECODING, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_MAX_Q, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_MIN_Q, unsigned int)
/*! @} - end defgroup vp8_encoder */
#ifdef __cplusplus
} // extern "C"
......
......@@ -15,8 +15,6 @@ API_SRCS-$(CONFIG_VP8_ENCODER) += vp8.h
API_SRCS-$(CONFIG_VP8_ENCODER) += vp8cx.h
API_DOC_SRCS-$(CONFIG_VP8_ENCODER) += vp8.h
API_DOC_SRCS-$(CONFIG_VP8_ENCODER) += vp8cx.h
API_SRCS-$(CONFIG_VP9_ENCODER) += src/svc_encodeframe.c
API_SRCS-$(CONFIG_VP9_ENCODER) += svc_context.h
API_SRCS-$(CONFIG_VP8_DECODER) += vp8.h
API_SRCS-$(CONFIG_VP8_DECODER) += vp8dx.h
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment