From e94b415c3479129944a69fafbeacf550fb9237b7 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Tue, 13 Jan 2015 10:07:20 -0800 Subject: [PATCH] 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 --- test/vp9_encoder_parms_get_to_decoder.cc | 12 +++++++----- vp9/common/vp9_enums.h | 11 ----------- vp9/common/vp9_onyxc_int.h | 2 +- vp9/decoder/vp9_decodeframe.c | 6 +++--- vp9/encoder/vp9_bitstream.c | 2 +- vp9/encoder/vp9_encoder.c | 1 + vp9/encoder/vp9_encoder.h | 2 +- vp9/vp9_cx_iface.c | 16 ++++++++++++---- vpx/vp8cx.h | 15 +++++++++++++++ vpxenc.c | 2 +- 10 files changed, 42 insertions(+), 27 deletions(-) diff --git a/test/vp9_encoder_parms_get_to_decoder.cc b/test/vp9_encoder_parms_get_to_decoder.cc index 6c354fd38..34e7854a9 100644 --- a/test/vp9_encoder_parms_get_to_decoder.cc +++ b/test/vp9_encoder_parms_get_to_decoder.cc @@ -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); diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h index 7454dd439..7938fc10a 100644 --- a/vp9/common/vp9_enums.h +++ b/vp9/common/vp9_enums.h @@ -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, diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index ff1ab9fa2..1a957bc99 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -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; diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 5cef552d1..d135199c1 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -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 diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 19bcfd2b6..3f4ed94d6 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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); diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 632cc45e1..7cfe0de90 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -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); diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 7becba788..a41284af0 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -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) { diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index b3ae4a71e..46e6e919c 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -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 diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 4fc0fd62f..f6fbec538 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -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" diff --git a/vpxenc.c b/vpxenc.c index e14c5eaab..944dfa8b5 100644 --- a/vpxenc.c +++ b/vpxenc.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 -- 2.40.0