Commit e94b415c authored by Yaowu Xu's avatar Yaowu Xu

Add encoder control for setting color space

This commit adds encoder side control for vp9 to set color space info
in the output compressed bitstream.

It also amends the "vp9_encoder_params_get_to_decoder" test to verify
the correct color space information is passed from the encoder end to
decoder end.

Change-Id: Ibf5fba2edcb2a8dc37557f6fae5c7816efa52650
parent afae733e
......@@ -65,14 +65,15 @@ struct EncodeParameters {
int32_t lossless;
int32_t error_resilient;
int32_t frame_parallel;
vpx_color_space_t cs;
// TODO(JBB): quantizers / bitrate
};
const EncodeParameters kVP9EncodeParameterSet[] = {
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 2, 0, 0, 1},
{0, 0, 0, 1, 0, VPX_CS_BT_601},
{0, 0, 0, 0, 0, VPX_CS_BT_709},
{0, 0, 1, 0, 0, VPX_CS_BT_2020},
{0, 2, 0, 0, 1, VPX_CS_UNKNOWN},
// TODO(JBB): Test profiles (requires more work).
};
......@@ -109,6 +110,7 @@ class Vp9EncoderParmsGetToDecoder
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
::libvpx_test::Encoder *encoder) {
if (video->frame() == 1) {
encoder->Control(VP9E_SET_COLOR_SPACE, encode_parms.cs);
encoder->Control(VP9E_SET_LOSSLESS, encode_parms.lossless);
encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING,
encode_parms.frame_parallel);
......@@ -147,7 +149,7 @@ class Vp9EncoderParmsGetToDecoder
EXPECT_EQ(common->frame_parallel_decoding_mode,
encode_parms.frame_parallel);
}
EXPECT_EQ(common->color_space, encode_parms.cs);
EXPECT_EQ(common->log2_tile_cols, encode_parms.tile_cols);
EXPECT_EQ(common->log2_tile_rows, encode_parms.tile_rows);
......
......@@ -98,17 +98,6 @@ typedef enum {
TX_TYPES = 4
} TX_TYPE;
typedef enum {
UNKNOWN = 0,
BT_601 = 1, // YUV
BT_709 = 2, // YUV
SMPTE_170 = 3, // YUV
SMPTE_240 = 4, // YUV
BT_2020 = 5, // YUV
RESERVED_2 = 6,
SRGB = 7 // RGB
} COLOR_SPACE;
typedef enum {
VP9_LAST_FLAG = 1 << 0,
VP9_GOLD_FLAG = 1 << 1,
......
......@@ -76,7 +76,7 @@ typedef struct VP9Common {
DECLARE_ALIGNED(16, int16_t, y_dequant[QINDEX_RANGE][8]);
DECLARE_ALIGNED(16, int16_t, uv_dequant[QINDEX_RANGE][8]);
COLOR_SPACE color_space;
vpx_color_space_t color_space;
int width;
int height;
......
......@@ -1227,8 +1227,8 @@ static void read_bitdepth_colorspace_sampling(
cm->use_highbitdepth = 0;
#endif
}
cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
if (cm->color_space != SRGB) {
cm->color_space = vp9_rb_read_literal(rb, 3);
if (cm->color_space != VPX_CS_SRGB) {
vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
cm->subsampling_x = vp9_rb_read_bit(rb);
......@@ -1328,7 +1328,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
// of either the color format or color sub-sampling in profile 0. VP9
// specifies that the default color format should be YUV 4:2:0 in this
// case (normative).
cm->color_space = BT_601;
cm->color_space = VPX_CS_BT_601;
cm->subsampling_y = cm->subsampling_x = 1;
cm->bit_depth = VPX_BITS_8;
#if CONFIG_VP9_HIGHBITDEPTH
......
......@@ -1055,7 +1055,7 @@ static void write_bitdepth_colorspace_sampling(
vp9_wb_write_bit(wb, cm->bit_depth == VPX_BITS_10 ? 0 : 1);
}
vp9_wb_write_literal(wb, cm->color_space, 3);
if (cm->color_space != SRGB) {
if (cm->color_space != VPX_CS_SRGB) {
vp9_wb_write_bit(wb, 0); // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) {
assert(cm->subsampling_x != 1 || cm->subsampling_y != 1);
......
......@@ -1264,6 +1264,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
if (cm->profile != oxcf->profile)
cm->profile = oxcf->profile;
cm->bit_depth = oxcf->bit_depth;
cm->color_space = oxcf->color_space;
if (cm->profile <= PROFILE_1)
assert(cm->bit_depth == VPX_BITS_8);
......
......@@ -231,7 +231,7 @@ typedef struct VP9EncoderConfig {
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth;
#endif
COLOR_SPACE color_space;
vpx_color_space_t color_space;
} VP9EncoderConfig;
static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) {
......
......@@ -41,8 +41,8 @@ struct vp9_extracfg {
AQ_MODE aq_mode;
unsigned int frame_periodic_boost;
vpx_bit_depth_t bit_depth;
COLOR_SPACE color_space;
vp9e_tune_content content;
vpx_color_space_t color_space;
};
static struct vp9_extracfg default_extra_cfg = {
......@@ -65,8 +65,8 @@ static struct vp9_extracfg default_extra_cfg = {
NO_AQ, // aq_mode
0, // frame_periodic_delta_q
VPX_BITS_8, // Bit depth
UNKNOWN, // Color Space
VP9E_CONTENT_DEFAULT // content
VP9E_CONTENT_DEFAULT, // content
VPX_CS_UNKNOWN, // color space
};
struct vpx_codec_alg_priv {
......@@ -296,7 +296,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
cfg->g_bit_depth == VPX_BITS_8) {
ERROR("Codec bit-depth 8 not supported in profile > 1");
}
RANGE_CHECK(extra_cfg, color_space, UNKNOWN, SRGB);
RANGE_CHECK(extra_cfg, color_space, VPX_CS_UNKNOWN, VPX_CS_SRGB);
return VPX_CODEC_OK;
}
......@@ -1325,6 +1325,13 @@ static vpx_codec_err_t ctrl_set_tune_content(vpx_codec_alg_priv_t *ctx,
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_err_t ctrl_set_color_space(vpx_codec_alg_priv_t *ctx,
va_list args) {
struct vp9_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.color_space = CAST(VP9E_SET_COLOR_SPACE, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{VP8_COPY_REFERENCE, ctrl_copy_reference},
{VP8E_UPD_ENTROPY, ctrl_update_entropy},
......@@ -1360,6 +1367,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{VP9E_REGISTER_CX_CALLBACK, ctrl_register_cx_callback},
{VP9E_SET_SVC_LAYER_ID, ctrl_set_svc_layer_id},
{VP9E_SET_TUNE_CONTENT, ctrl_set_tune_content},
{VP9E_SET_COLOR_SPACE, ctrl_set_color_space},
{VP9E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity},
// Getters
......
......@@ -259,6 +259,19 @@ enum vp8e_enc_control_id {
VP9E_SET_TUNE_CONTENT,
VP9E_GET_SVC_LAYER_ID,
VP9E_REGISTER_CX_CALLBACK,
/*!\brief control function to set color space info.
* \note Valid ranges: 0..7, default is "UNKNOWN".
* 0 = UNKNOWN,
* 1 = BT_601
* 2 = BT_709
* 3 = SMPTE_170
* 4 = SMPTE_240
* 5 = BT_2020
* 6 = RESERVED
* 7 = SRGB
*/
VP9E_SET_COLOR_SPACE,
};
/*!\brief vpx 1-D scaling mode
......@@ -423,6 +436,8 @@ VPX_CTRL_USE_TYPE(VP9E_SET_FRAME_PERIODIC_BOOST, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_NOISE_SENSITIVITY, unsigned int)
VPX_CTRL_USE_TYPE(VP9E_SET_TUNE_CONTENT, int) /* vp9e_tune_content */
VPX_CTRL_USE_TYPE(VP9E_SET_COLOR_SPACE, int)
/*! @} - end defgroup vp8_encoder */
#ifdef __cplusplus
} // extern "C"
......
......@@ -442,7 +442,7 @@ static const int vp9_arg_ctrl_map[] = {
VP8E_SET_MAX_INTER_BITRATE_PCT, VP8E_SET_GF_CBR_BOOST_PCT,
VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE,
VP9E_SET_FRAME_PERIODIC_BOOST, VP9E_SET_NOISE_SENSITIVITY,
VP9E_SET_TUNE_CONTENT,
VP9E_SET_TUNE_CONTENT, VP9E_SET_COLOR_SPACE,
0
};
#endif
......
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