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) {