Commit 317002fb authored by Imdad Sardharwalla's avatar Imdad Sardharwalla Committed by Peter de Rivaz

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
parent 0687d3e9
......@@ -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 */
......
......@@ -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
......
......@@ -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)) {
......
......@@ -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);
......
......@@ -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.
......
......@@ -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;
......
......@@ -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
......
......@@ -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.
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
......
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