From 317002fb37f0fec657c728b4c5c0479cb5367259 Mon Sep 17 00:00:00 2001 From: Imdad Sardharwalla <imdad.sardharwalla@argondesign.com> Date: Tue, 5 Dec 2017 16:24:56 +0000 Subject: [PATCH] Monochrome control now in colorspace header The monochrome bit has been removed from the end of the sequence header. Monochrome is now coded as a type of colorspace. Encode in monochrome by using aomenc --color-space=monochrome ... Change-Id: I9550de58eb3d67dae0eb651697cb63dc8b137931 --- aom/aom_image.h | 3 ++- aomdec.c | 17 +------------- aomenc.c | 27 +++++++++------------ av1/av1_cx_iface.c | 14 ++++++----- av1/av1_dx_iface.c | 26 +++++++++++---------- av1/common/onyxc_int.h | 5 +--- av1/decoder/decodeframe.c | 49 ++++++++++++++++++++++----------------- av1/decoder/decoder.h | 3 --- av1/encoder/bitstream.c | 21 +++++++++-------- av1/encoder/encoder.c | 4 ---- av1/encoder/encoder.h | 3 --- 11 files changed, 76 insertions(+), 96 deletions(-) diff --git a/aom/aom_image.h b/aom/aom_image.h index 7767949608..0bf00cd346 100644 --- a/aom/aom_image.h +++ b/aom/aom_image.h @@ -78,7 +78,8 @@ typedef enum aom_color_space { AOM_CS_BT_2020_CL = 6, /**< BT.2020 constant luminance */ AOM_CS_SRGB = 7, /**< sRGB */ AOM_CS_ICTCP = 8, /**< ICtCp, ITU-R BT.2100 */ - AOM_CS_RESERVED = 9 /**< Values 9..31 are reserved */ + AOM_CS_MONOCHROME = 9, /**< Monochrome */ + AOM_CS_RESERVED = 10 /**< Values 10..31 are reserved */ } aom_color_space_t; /**< alias for enum aom_color_space */ /*!\brief List of supported transfer functions */ diff --git a/aomdec.c b/aomdec.c index aa8ba94777..8aaffd6097 100644 --- a/aomdec.c +++ b/aomdec.c @@ -74,10 +74,6 @@ static const arg_def_t flipuvarg = ARG_DEF(NULL, "flipuv", 0, "Flip the chroma planes in the output"); static const arg_def_t rawvideo = ARG_DEF(NULL, "rawvideo", 0, "Output raw YUV frames"); -#if CONFIG_MONO_VIDEO -static const arg_def_t monochrome = ARG_DEF( - NULL, "monochrome", 0, "Force monochrome output (constant chroma planes)"); -#endif static const arg_def_t noblitarg = ARG_DEF(NULL, "noblit", 0, "Don't process the decoded frames"); static const arg_def_t progressarg = @@ -127,9 +123,6 @@ static const arg_def_t *all_args[] = { &help, &use_i420, &flipuvarg, &rawvideo, -#if CONFIG_MONO_VIDEO - &monochrome, -#endif &noblitarg, &progressarg, &limitarg, @@ -540,9 +533,6 @@ static int main_loop(int argc, const char **argv_) { int use_y4m = 1; int opt_yv12 = 0; int opt_i420 = 0; -#if CONFIG_MONO_VIDEO - int opt_rawvideo = 0; -#endif aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH, 0 }; #if CONFIG_HIGHBITDEPTH unsigned int output_bit_depth = 0; @@ -609,11 +599,6 @@ static int main_loop(int argc, const char **argv_) { opt_i420 = 1; } else if (arg_match(&arg, &rawvideo, argi)) { use_y4m = 0; -#if CONFIG_MONO_VIDEO - opt_rawvideo = 1; - } else if (arg_match(&arg, &monochrome, argi)) { - cfg.monochrome = 1; -#endif } else if (arg_match(&arg, &flipuvarg, argi)) { flipuv = 1; } else if (arg_match(&arg, &noblitarg, argi)) { @@ -961,7 +946,7 @@ static int main_loop(int argc, const char **argv_) { #endif // CONFIG_EXT_TILE #if CONFIG_MONO_VIDEO - int num_planes = (opt_rawvideo && cfg.monochrome) ? 1 : 3; + int num_planes = (!use_y4m && img->cs == AOM_CS_MONOCHROME) ? 1 : 3; #else int num_planes = 3; #endif diff --git a/aomenc.c b/aomenc.c index 44d8480881..54d6ba134f 100644 --- a/aomenc.c +++ b/aomenc.c @@ -269,10 +269,6 @@ static const arg_def_t large_scale_tile = ARG_DEF(NULL, "large-scale-tile", 1, "Large scale tile coding (0: off (default), 1: on)"); #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO -static const arg_def_t monochrome = - ARG_DEF(NULL, "monochrome", 0, "Monochrome video (no chroma planes)"); -#endif // MONOCHROME static const arg_def_t *global_args[] = { &use_yv12, &use_i420, @@ -297,9 +293,6 @@ static const arg_def_t *global_args[] = { &use_yv12, #if CONFIG_EXT_TILE &large_scale_tile, #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - &monochrome, -#endif // CONFIG_MONO_VIDEO NULL }; static const arg_def_t dropframe_thresh = @@ -509,11 +502,17 @@ static const arg_def_t max_gf_interval = ARG_DEF( "max gf/arf frame interval (default 0, indicating in-built behavior)"); static const struct arg_enum_list color_space_enum[] = { - { "unknown", AOM_CS_UNKNOWN }, { "bt601", AOM_CS_BT_601 }, - { "bt709", AOM_CS_BT_709 }, { "smpte170", AOM_CS_SMPTE_170 }, - { "smpte240", AOM_CS_SMPTE_240 }, { "bt2020ncl", AOM_CS_BT_2020_NCL }, - { "bt2020cl", AOM_CS_BT_2020_CL }, { "sRGB", AOM_CS_SRGB }, - { "ICtCp", AOM_CS_ICTCP }, { NULL, 0 } + { "unknown", AOM_CS_UNKNOWN }, + { "bt601", AOM_CS_BT_601 }, + { "bt709", AOM_CS_BT_709 }, + { "smpte170", AOM_CS_SMPTE_170 }, + { "smpte240", AOM_CS_SMPTE_240 }, + { "bt2020ncl", AOM_CS_BT_2020_NCL }, + { "bt2020cl", AOM_CS_BT_2020_CL }, + { "sRGB", AOM_CS_SRGB }, + { "ICtCp", AOM_CS_ICTCP }, + { "monochrome", AOM_CS_MONOCHROME }, + { NULL, 0 } }; static const arg_def_t input_color_space = @@ -1112,10 +1111,6 @@ static int parse_stream_params(struct AvxEncoderConfig *global, } else if (arg_match(&arg, &large_scale_tile, argi)) { config->cfg.large_scale_tile = arg_parse_uint(&arg); #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - } else if (arg_match(&arg, &monochrome, argi)) { - config->cfg.monochrome = 1; -#endif // CONFIG_MONO_VIDEO } else if (arg_match(&arg, &dropframe_thresh, argi)) { config->cfg.rc_dropframe_thresh = arg_parse_uint(&arg); } else if (arg_match(&arg, &resize_mode, argi)) { diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index 754cab9ba1..03086e60f5 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c @@ -312,9 +312,6 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, #if CONFIG_EXT_TILE } #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - RANGE_CHECK_HI(cfg, monochrome, 1); -#endif // CONFIG_MONO_VIDEO #if CONFIG_EXT_TILE if (cfg->large_scale_tile && extra_cfg->aq_mode) @@ -383,12 +380,20 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, ERROR("Codec bit-depth 8 not supported in profile > 1"); } #if CONFIG_COLORSPACE_HEADERS +#if CONFIG_MONO_VIDEO + RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_MONOCHROME); +#else RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_ICTCP); +#endif // CONFIG_MONO_VIDEO RANGE_CHECK(extra_cfg, transfer_function, AOM_TF_UNKNOWN, AOM_TF_HLG); RANGE_CHECK(extra_cfg, chroma_sample_position, AOM_CSP_UNKNOWN, AOM_CSP_COLOCATED); +#else +#if CONFIG_MONO_VIDEO + RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_MONOCHROME); #else RANGE_CHECK(extra_cfg, color_space, AOM_CS_UNKNOWN, AOM_CS_SRGB); +#endif #endif RANGE_CHECK(extra_cfg, color_range, 0, 1); @@ -634,9 +639,6 @@ static aom_codec_err_t set_encoder_config( #if CONFIG_EXT_TILE } #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - oxcf->monochrome = cfg->monochrome; -#endif // CONFIG_MONO_VIDEO #if CONFIG_MAX_TILE oxcf->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS); diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c index 0d3914dd56..31caa3a24e 100644 --- a/av1/av1_dx_iface.c +++ b/av1/av1_dx_iface.c @@ -171,9 +171,21 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, color_space = (aom_color_space_t)aom_rb_read_literal(rb, 5); rb->bit_offset += 5; // Transfer function #else - color_space = (aom_color_space_t)aom_rb_read_literal(rb, 3); + color_space = + (aom_color_space_t)aom_rb_read_literal(rb, 3 + CONFIG_MONO_VIDEO); #endif - if (color_space != AOM_CS_SRGB) { + if (color_space == AOM_CS_SRGB) { + if (profile == PROFILE_1 || profile == PROFILE_3) { + rb->bit_offset += 1; // unused + } else { + // RGB is only available in version 1. + return 0; + } +#if CONFIG_MONO_VIDEO + } else if (color_space == AOM_CS_MONOCHROME) { + return 1; +#endif // CONFIG_MONO_VIDEO + } else { rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range. if (profile == PROFILE_1 || profile == PROFILE_3) { @@ -195,13 +207,6 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, #else } #endif - } else { - if (profile == PROFILE_1 || profile == PROFILE_3) { - rb->bit_offset += 1; // unused - } else { - // RGB is only available in version 1. - return 0; - } } return 1; } @@ -514,9 +519,6 @@ static aom_codec_err_t init_decoder(aom_codec_alg_priv_t *ctx) { } #endif frame_worker_data->pbi->allow_lowbitdepth = ctx->cfg.allow_lowbitdepth; -#if CONFIG_MONO_VIDEO - frame_worker_data->pbi->monochrome = ctx->cfg.monochrome; -#endif // If decoding in serial mode, FrameWorker thread could create tile worker // thread or loopfilter thread. diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index 7d8fa3f69f..02aec6aa4f 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h @@ -217,9 +217,6 @@ typedef struct SequenceHeader { int frame_id_numbers_present_flag; int frame_id_length; int delta_frame_id_length; -#if CONFIG_MONO_VIDEO - int monochrome; -#endif // CONFIG_MONO_VIDEO } SequenceHeader; #endif // CONFIG_REFERENCE_BUFFER @@ -1160,7 +1157,7 @@ static INLINE int max_intra_block_height(const MACROBLOCKD *xd, static INLINE int av1_num_planes(const AV1_COMMON *cm) { #if CONFIG_MONO_VIDEO - return cm->seq_params.monochrome ? 1 : MAX_MB_PLANE; + return cm->color_space == AOM_CS_MONOCHROME ? 1 : MAX_MB_PLANE; #else (void)cm; return MAX_MB_PLANE; diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index cbc9e6f2f3..39cd3c32b6 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c @@ -2370,9 +2370,33 @@ static void read_bitdepth_colorspace_sampling(AV1_COMMON *cm, cm->color_space = aom_rb_read_literal(rb, 5); cm->transfer_function = aom_rb_read_literal(rb, 5); #else - cm->color_space = aom_rb_read_literal(rb, 3); + cm->color_space = aom_rb_read_literal(rb, 3 + CONFIG_MONO_VIDEO); #endif - if (cm->color_space != AOM_CS_SRGB) { + if (cm->color_space == AOM_CS_SRGB) { + if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { + // Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed. + // 4:2:2 or 4:4:0 chroma sampling is not allowed. + cm->subsampling_y = cm->subsampling_x = 0; + if (aom_rb_read_bit(rb)) + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "Reserved bit set"); + } else { + aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "4:4:4 color not supported in profile 0 or 2"); + } +#if CONFIG_MONO_VIDEO + } else if (cm->color_space == AOM_CS_MONOCHROME) { + cm->color_range = AOM_CR_FULL_RANGE; + cm->subsampling_y = cm->subsampling_x = 1; +#if CONFIG_COLORSPACE_HEADERS + cm->chroma_sample_position = AOM_CSP_UNKNOWN; +#endif +#if CONFIG_EXT_QM + cm->separate_uv_delta_q = 0; +#endif + return; +#endif // CONFIG_MONO_VIDEO + } else { // [16,235] (including xvycc) vs [0,255] range cm->color_range = aom_rb_read_bit(rb); if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { @@ -2392,18 +2416,6 @@ static void read_bitdepth_colorspace_sampling(AV1_COMMON *cm, cm->chroma_sample_position = aom_rb_read_literal(rb, 2); } #endif - } else { - if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { - // Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed. - // 4:2:2 or 4:4:0 chroma sampling is not allowed. - cm->subsampling_y = cm->subsampling_x = 0; - if (aom_rb_read_bit(rb)) - aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, - "Reserved bit set"); - } else { - aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, - "4:4:4 color not supported in profile 0 or 2"); - } } #if CONFIG_EXT_QM cm->separate_uv_delta_q = aom_rb_read_bit(rb); @@ -2435,10 +2447,6 @@ void read_sequence_header(SequenceHeader *seq_params, seq_params->frame_id_length = aom_rb_read_literal(rb, 3) + seq_params->delta_frame_id_length + 1; } - -#if CONFIG_MONO_VIDEO - seq_params->monochrome = aom_rb_read_bit(rb); -#endif // CONFIG_MONO_VIDEO } #endif // CONFIG_REFERENCE_BUFFER || CONFIG_OBU @@ -3575,9 +3583,8 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data, #endif #if CONFIG_MONO_VIDEO - // If the bit stream is monochrome, or the decoder is set to force a - // monochrome output, set the U and V buffers to a constant. - if (pbi->monochrome || cm->seq_params.monochrome) { + // If the bit stream is monochrome, set the U and V buffers to a constant. + if (av1_num_planes(cm) < 3) { #if CONFIG_HIGHBITDEPTH const int bytes_per_sample = cm->use_highbitdepth ? 2 : 1; #else diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h index b5d97b7b38..28227a5ba2 100644 --- a/av1/decoder/decoder.h +++ b/av1/decoder/decoder.h @@ -81,9 +81,6 @@ typedef struct AV1Decoder { void *decrypt_state; int allow_lowbitdepth; -#if CONFIG_MONO_VIDEO - int monochrome; -#endif int max_threads; int inv_tile_order; int need_resync; // wait for key/intra-only frame. diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index bfdf4bed3e..c1e99cf620 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c @@ -1069,7 +1069,7 @@ static void write_palette_mode_info(const AV1_COMMON *cm, const MACROBLOCKD *xd, const int uv_dc_pred = #if CONFIG_MONO_VIDEO - !cm->seq_params.monochrome && + av1_num_planes(cm) > 1 && #endif mbmi->uv_mode == UV_DC_PRED; if (uv_dc_pred) { @@ -3543,9 +3543,16 @@ static void write_bitdepth_colorspace_sampling( aom_wb_write_literal(wb, cm->color_space, 5); aom_wb_write_literal(wb, cm->transfer_function, 5); #else - aom_wb_write_literal(wb, cm->color_space, 3); + aom_wb_write_literal(wb, cm->color_space, 3 + CONFIG_MONO_VIDEO); #endif - if (cm->color_space != AOM_CS_SRGB) { + if (cm->color_space == AOM_CS_SRGB) { + assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3); + aom_wb_write_bit(wb, 0); // unused +#if CONFIG_MONO_VIDEO + } else if (cm->color_space == AOM_CS_MONOCHROME) { + return; +#endif // CONFIG_MONO_VIDEO + } else { // 0: [16, 235] (i.e. xvYCC), 1: [0, 255] aom_wb_write_bit(wb, cm->color_range); if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { @@ -3561,10 +3568,8 @@ static void write_bitdepth_colorspace_sampling( aom_wb_write_literal(wb, cm->chroma_sample_position, 2); } #endif - } else { - assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3); - aom_wb_write_bit(wb, 0); // unused } + #if CONFIG_EXT_QM aom_wb_write_bit(wb, cm->separate_uv_delta_q); #endif @@ -3611,10 +3616,6 @@ void write_sequence_header(AV1_COMP *cpi, struct aom_write_bit_buffer *wb) { wb, seq_params->frame_id_length - seq_params->delta_frame_id_length - 1, 3); } - -#if CONFIG_MONO_VIDEO - aom_wb_write_bit(wb, seq_params->monochrome); -#endif // CONFIG_MONO_VIDEO } #endif // CONFIG_REFERENCE_BUFFER || CONFIG_OBU diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index d8c9037966..14c85e977b 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c @@ -5560,10 +5560,6 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size, #endif // CONFIG_REFERENCE_BUFFER #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - cm->seq_params.monochrome = oxcf->monochrome; -#endif // CONFIG_MONO_VIDEO - #if CONFIG_XIPHRC if (drop_this_frame) { av1_rc_postencode_update_drop_frame(cpi); diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index d1edaf991c..46371b4bb0 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h @@ -296,9 +296,6 @@ typedef struct AV1EncoderConfig { unsigned int large_scale_tile; unsigned int single_tile_decoding; #endif // CONFIG_EXT_TILE -#if CONFIG_MONO_VIDEO - int monochrome; -#endif // CONFIG_MONO_VIDEO unsigned int motion_vector_unit_test; } AV1EncoderConfig; -- GitLab