Add API hooks for setting chroma subsampling values. BUG=aomedia:2107 Change-Id: Iac96b16b03c8b895463dfbf29feade799f458476
diff --git a/aom/aomcx.h b/aom/aomcx.h index 0d6ce7d..bbf1775 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -862,6 +862,12 @@ /*!\brief Sets the denoisers block size */ AV1E_SET_DENOISE_BLOCK_SIZE, + + /*!\brief Sets the chroma subsampling x value */ + AV1E_SET_CHROMA_SUBSAMPLING_X, + + /*!\brief Sets the chroma subsampling y value */ + AV1E_SET_CHROMA_SUBSAMPLING_Y, }; /*!\brief aom 1-D scaling mode @@ -1142,10 +1148,6 @@ AOM_CTRL_USE_TYPE(AV1E_SET_COLOR_RANGE, int) #define AOM_CTRL_AV1E_SET_COLOR_RANGE -/*!\brief - * - * TODO(rbultje) : add support of the control in ffmpeg - */ #define AOM_CTRL_AV1E_SET_RENDER_SIZE AOM_CTRL_USE_TYPE(AV1E_SET_RENDER_SIZE, int *) @@ -1184,6 +1186,12 @@ #define AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE #endif +AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_X, unsigned int) +#define AOM_CTRL_AV1E_SET_CHROMA_SUBSAMPLING_X + +AOM_CTRL_USE_TYPE(AV1E_SET_CHROMA_SUBSAMPLING_Y, unsigned int) +#define AOM_CTRL_AV1E_SET_CHROMA_SUBSAMPLING_Y + /*!\endcond */ /*! @} - end defgroup aom_encoder */ #ifdef __cplusplus
diff --git a/apps/aomenc.c b/apps/aomenc.c index 7518e3a..25f012f 100644 --- a/apps/aomenc.c +++ b/apps/aomenc.c
@@ -203,6 +203,12 @@ bitdepth_enum); static const arg_def_t inbitdeptharg = ARG_DEF(NULL, "input-bit-depth", 1, "Bit depth of input"); + +static const arg_def_t input_chroma_subsampling_x = ARG_DEF( + NULL, "input-chroma-subsampling-x", 1, "chroma subsampling x value."); +static const arg_def_t input_chroma_subsampling_y = ARG_DEF( + NULL, "input-chroma-subsampling-y", 1, "chroma subsampling y value."); + static const arg_def_t *main_args[] = { &help, #if CONFIG_FILEOPTIONS &use_cfg, @@ -671,6 +677,8 @@ &enable_ref_frame_mvs, &bitdeptharg, &inbitdeptharg, + &input_chroma_subsampling_x, + &input_chroma_subsampling_y, &sframe_dist, &sframe_mode, &save_as_annexb, @@ -831,6 +839,8 @@ struct aom_image *img; aom_codec_ctx_t decoder; int mismatch_seen; + unsigned int chroma_subsampling_x; + unsigned int chroma_subsampling_y; }; static void validate_positive_rational(const char *msg, @@ -1180,6 +1190,10 @@ config->cfg.g_bit_depth = arg_parse_enum_or_int(&arg); } else if (arg_match(&arg, &inbitdeptharg, argi)) { config->cfg.g_input_bit_depth = arg_parse_uint(&arg); + } else if (arg_match(&arg, &input_chroma_subsampling_x, argi)) { + stream->chroma_subsampling_x = arg_parse_uint(&arg); + } else if (arg_match(&arg, &input_chroma_subsampling_y, argi)) { + stream->chroma_subsampling_y = arg_parse_uint(&arg); #if CONFIG_WEBM_IO } else if (arg_match(&arg, &stereo_mode, argi)) { config->stereo_fmt = arg_parse_enum_or_int(&arg); @@ -2049,6 +2063,20 @@ input.fmt == AOM_IMG_FMT_I42016)) { stream->config.cfg.g_profile = 0; profile_updated = 1; + } else if (input.bit_depth == 12 && + input.file_type == FILE_TYPE_Y4M) { + // Note that here the input file values for chroma subsampling + // are used instead of those from the command line. + aom_codec_control(&stream->encoder, AV1E_SET_CHROMA_SUBSAMPLING_X, + input.y4m.dst_c_dec_h >> 1); + aom_codec_control(&stream->encoder, AV1E_SET_CHROMA_SUBSAMPLING_Y, + input.y4m.dst_c_dec_v >> 1); + } else if (input.bit_depth == 12 && + input.file_type == FILE_TYPE_RAW) { + aom_codec_control(&stream->encoder, AV1E_SET_CHROMA_SUBSAMPLING_X, + stream->chroma_subsampling_x); + aom_codec_control(&stream->encoder, AV1E_SET_CHROMA_SUBSAMPLING_Y, + stream->chroma_subsampling_y); } break; default: break;
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index 0598535..65f35bd 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -99,6 +99,9 @@ float noise_level; int noise_block_size; #endif + + unsigned int chroma_subsampling_x; + unsigned int chroma_subsampling_y; }; static struct av1_extracfg default_extra_cfg = { @@ -169,6 +172,8 @@ 0, // noise_level 32, // noise_block_size #endif + 0, // chroma_subsampling_x + 0, // chroma_subsampling_y }; struct aom_codec_alg_priv { @@ -371,6 +376,9 @@ #endif } + RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1); + RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1); + return AOM_CODEC_OK; } @@ -707,6 +715,9 @@ } #endif // CONFIG_REDUCED_ENCODER_BORDER + oxcf->chroma_subsampling_x = extra_cfg->chroma_subsampling_x; + oxcf->chroma_subsampling_y = extra_cfg->chroma_subsampling_y; + return AOM_CODEC_OK; } @@ -1685,6 +1696,20 @@ return update_extra_cfg(ctx, &extra_cfg); } +static aom_codec_err_t ctrl_set_chroma_subsampling_x(aom_codec_alg_priv_t *ctx, + va_list args) { + struct av1_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.chroma_subsampling_x = CAST(AV1E_SET_CHROMA_SUBSAMPLING_X, args); + return update_extra_cfg(ctx, &extra_cfg); +} + +static aom_codec_err_t ctrl_set_chroma_subsampling_y(aom_codec_alg_priv_t *ctx, + va_list args) { + struct av1_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.chroma_subsampling_y = CAST(AV1E_SET_CHROMA_SUBSAMPLING_Y, args); + return update_extra_cfg(ctx, &extra_cfg); +} + static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { { AV1_COPY_REFERENCE, ctrl_copy_reference }, { AOME_USE_REFERENCE, ctrl_use_reference }, @@ -1770,7 +1795,8 @@ { AV1E_GET_ACTIVEMAP, ctrl_get_active_map }, { AV1_GET_NEW_FRAME_IMAGE, ctrl_get_new_frame_image }, { AV1_COPY_NEW_FRAME_IMAGE, ctrl_copy_new_frame_image }, - + { AV1E_SET_CHROMA_SUBSAMPLING_X, ctrl_set_chroma_subsampling_x }, + { AV1E_SET_CHROMA_SUBSAMPLING_Y, ctrl_set_chroma_subsampling_y }, { -1, NULL }, };
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 0c0c7e9..9b2fde2 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -1067,6 +1067,11 @@ 10; // Default value (not signaled) } + if (cm->seq_params.bit_depth == AOM_BITS_12) { + cm->seq_params.subsampling_x = oxcf->chroma_subsampling_x; + cm->seq_params.subsampling_y = oxcf->chroma_subsampling_y; + } + cm->width = oxcf->width; cm->height = oxcf->height; set_sb_size(&cm->seq_params,
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 3ba1354..a47a4d7 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -309,6 +309,9 @@ float noise_level; int noise_block_size; #endif + + unsigned int chroma_subsampling_x; + unsigned int chroma_subsampling_y; } AV1EncoderConfig; static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {