Commit f9a50ea3 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Update profile/bitdepth/sampling in header

Designs the sequence header syntax to support various
profiles as decided in the AV1 codec WG:

Profile 0: 4:2:0 and 4:0:0 8/10-bit
Profile 1: 4:4:4 8/10-bit
Profile 2: 4:2:0/4:0:0/4:4:4 12-bit as well as 4:2:2 8/10/12-bit

Change-Id: Iea351698280e37d65847bf75a43c5bbeba8f7cf4
parent 4a766a4b
...@@ -2028,12 +2028,23 @@ int main(int argc, const char **argv_) { ...@@ -2028,12 +2028,23 @@ int main(int argc, const char **argv_) {
was selected. */ was selected. */
switch (stream->config.cfg.g_profile) { switch (stream->config.cfg.g_profile) {
case 0: case 0:
stream->config.cfg.g_profile = 1; if ((input.bit_depth == 8 || input.bit_depth == 10) &&
profile_updated = 1; (input.fmt == AOM_IMG_FMT_I444 ||
input.fmt == AOM_IMG_FMT_I44416)) {
stream->config.cfg.g_profile = 1;
profile_updated = 1;
} else if (input.bit_depth == 12 || input.fmt == AOM_IMG_FMT_I422 ||
input.fmt == AOM_IMG_FMT_I42216) {
stream->config.cfg.g_profile = 2;
profile_updated = 1;
}
break; break;
case 2: case 1:
stream->config.cfg.g_profile = 3; if (input.bit_depth == 12 || input.fmt == AOM_IMG_FMT_I422 ||
profile_updated = 1; input.fmt == AOM_IMG_FMT_I42216) {
stream->config.cfg.g_profile = 2;
profile_updated = 1;
}
break; break;
default: break; default: break;
} }
......
...@@ -241,7 +241,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, ...@@ -241,7 +241,7 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available RANGE_CHECK(cfg, g_h, 1, 65535); // 16 bits available
RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000); RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den); RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
RANGE_CHECK_HI(cfg, g_profile, 3); RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); RANGE_CHECK_HI(cfg, rc_max_quantizer, 63);
RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer);
...@@ -391,15 +391,12 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, ...@@ -391,15 +391,12 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
} }
if (cfg->g_profile <= (unsigned int)PROFILE_1 && if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
cfg->g_bit_depth > AOM_BITS_8) { cfg->g_bit_depth > AOM_BITS_10) {
ERROR("Codec high bit-depth not supported in profile < 2"); ERROR("Codec bit-depth 12 not supported in profile < 2");
} }
if (cfg->g_profile <= (unsigned int)PROFILE_1 && cfg->g_input_bit_depth > 8) { if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
ERROR("Source high bit-depth not supported in profile < 2"); cfg->g_input_bit_depth > 10) {
} ERROR("Source bit-depth 12 not supported in profile < 2");
if (cfg->g_profile > (unsigned int)PROFILE_1 &&
cfg->g_bit_depth == AOM_BITS_8) {
ERROR("Codec bit-depth 8 not supported in profile > 1");
} }
#if CONFIG_CICP #if CONFIG_CICP
...@@ -454,25 +451,20 @@ static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx, ...@@ -454,25 +451,20 @@ static aom_codec_err_t validate_img(aom_codec_alg_priv_t *ctx,
case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_YV12:
case AOM_IMG_FMT_I420: case AOM_IMG_FMT_I420:
case AOM_IMG_FMT_I42016: break; case AOM_IMG_FMT_I42016: break;
case AOM_IMG_FMT_I422:
case AOM_IMG_FMT_I444: case AOM_IMG_FMT_I444:
case AOM_IMG_FMT_I440: case AOM_IMG_FMT_I44416:
if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) { if (ctx->cfg.g_profile == (unsigned int)PROFILE_0) {
ERROR( ERROR("Invalid image format. I444 images not supported in profile.");
"Invalid image format. I422, I444, I440 images are "
"not supported in profile.");
} }
break; break;
case AOM_IMG_FMT_I422:
case AOM_IMG_FMT_I42216: case AOM_IMG_FMT_I42216:
case AOM_IMG_FMT_I44416: if (ctx->cfg.g_profile != (unsigned int)PROFILE_2) {
case AOM_IMG_FMT_I44016: ERROR("Invalid image format. I422 images not supported in profile.");
if (ctx->cfg.g_profile != (unsigned int)PROFILE_1 &&
ctx->cfg.g_profile != (unsigned int)PROFILE_3) {
ERROR(
"Invalid image format. 16-bit I422, I444, I440 images are "
"not supported in profile.");
} }
break; break;
case AOM_IMG_FMT_I440:
case AOM_IMG_FMT_I44016:
default: default:
ERROR( ERROR(
"Invalid image format. Only YV12, I420, I422, I444 images are " "Invalid image format. Only YV12, I420, I422, I444 images are "
......
...@@ -156,21 +156,37 @@ static aom_codec_err_t decoder_destroy(aom_codec_alg_priv_t *ctx) { ...@@ -156,21 +156,37 @@ static aom_codec_err_t decoder_destroy(aom_codec_alg_priv_t *ctx) {
} }
#if !CONFIG_OBU #if !CONFIG_OBU
static aom_bit_depth_t parse_bitdepth(BITSTREAM_PROFILE profile,
struct aom_read_bit_buffer *rb) {
aom_bit_depth_t bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_10 : AOM_BITS_8;
if (profile < PROFILE_2 || bit_depth == AOM_BITS_8) {
return bit_depth;
}
bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_12 : AOM_BITS_10;
return bit_depth;
}
static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile,
struct aom_read_bit_buffer *rb) { struct aom_read_bit_buffer *rb) {
#if CONFIG_CICP #if CONFIG_CICP
aom_color_primaries_t color_primaries; aom_color_primaries_t color_primaries;
aom_transfer_characteristics_t transfer_characteristics; aom_transfer_characteristics_t transfer_characteristics;
aom_matrix_coefficients_t matrix_coefficients; aom_matrix_coefficients_t matrix_coefficients;
#else #endif // CONFIG_CICP
aom_color_space_t color_space;
#endif
#if CONFIG_COLORSPACE_HEADERS
int subsampling_x = 0; int subsampling_x = 0;
int subsampling_y = 0; int subsampling_y = 0;
#endif aom_color_space_t color_space;
aom_bit_depth_t bit_depth = parse_bitdepth(profile, rb);
color_space = AOM_CS_UNKNOWN;
#if CONFIG_MONO_VIDEO
// Monochrome bit
const int is_monochrome = profile != PROFILE_1 ? aom_rb_read_bit(rb) : 0;
color_space = is_monochrome ? AOM_CS_MONOCHROME : AOM_CS_UNKNOWN;
#else
const int is_monochrome = 0;
#endif // CONFIG_MONO_VIDEO
if (profile >= PROFILE_2) rb->bit_offset += 1; // Bit-depth 10 or 12.
#if CONFIG_CICP #if CONFIG_CICP
int color_description_present_flag = aom_rb_read_bit(rb); int color_description_present_flag = aom_rb_read_bit(rb);
if (color_description_present_flag) { if (color_description_present_flag) {
...@@ -185,13 +201,16 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, ...@@ -185,13 +201,16 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile,
} }
#else #else
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
color_space = (aom_color_space_t)aom_rb_read_literal(rb, 5); if (!is_monochrome) {
color_space = (aom_color_space_t)aom_rb_read_literal(rb, 5);
}
rb->bit_offset += 5; // Transfer function rb->bit_offset += 5; // Transfer function
#else #else
color_space = if (!is_monochrome) {
(aom_color_space_t)aom_rb_read_literal(rb, 3 + CONFIG_MONO_VIDEO); color_space = (aom_color_space_t)aom_rb_read_literal(rb, 4);
#endif }
#endif #endif // CONFIG_COLORSPACE_HEADERS
#endif // CONFIG_CICP
#if CONFIG_CICP #if CONFIG_CICP
if (color_primaries == AOM_CICP_CP_BT_709 && if (color_primaries == AOM_CICP_CP_BT_709 &&
transfer_characteristics == AOM_CICP_TC_SRGB && transfer_characteristics == AOM_CICP_TC_SRGB &&
...@@ -200,40 +219,42 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile, ...@@ -200,40 +219,42 @@ static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile,
// too // too
#else #else
if (color_space == AOM_CS_SRGB) { if (color_space == AOM_CS_SRGB) {
#endif #endif // CONFIG_CICP
if (profile == PROFILE_1 || profile == PROFILE_3) { if (!(profile == PROFILE_1 ||
rb->bit_offset += 1; // unused (profile == PROFILE_2 && bit_depth == AOM_BITS_12))) {
} else {
// RGB is only available in version 1.
return 0; return 0;
} }
#if CONFIG_MONO_VIDEO && !CONFIG_CICP #if CONFIG_MONO_VIDEO
} else if (color_space == AOM_CS_MONOCHROME) { } else if (is_monochrome) {
return 1; return 1;
#endif // CONFIG_MONO_VIDEO #endif // CONFIG_MONO_VIDEO
} else { } else {
rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range. rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range.
if (profile == PROFILE_1 || profile == PROFILE_3) { if (profile == PROFILE_0) {
#if CONFIG_COLORSPACE_HEADERS
subsampling_x = aom_rb_read_bit(rb);
subsampling_y = aom_rb_read_bit(rb);
#else
rb->bit_offset += 2; // subsampling x/y.
#endif
rb->bit_offset += 1; // unused.
#if CONFIG_COLORSPACE_HEADERS
} else {
subsampling_x = 1; subsampling_x = 1;
subsampling_y = 1; subsampling_y = 1;
} else if (profile == PROFILE_1) {
subsampling_x = 0;
subsampling_y = 0;
} else if (profile == PROFILE_2) {
if (bit_depth == AOM_BITS_12) {
subsampling_x = aom_rb_read_bit(rb);
subsampling_y = aom_rb_read_bit(rb);
} else {
subsampling_x = 1;
subsampling_y = 0;
}
} }
#if CONFIG_COLORSPACE_HEADERS
if (subsampling_x == 1 && subsampling_y == 1) { if (subsampling_x == 1 && subsampling_y == 1) {
rb->bit_offset += 2; rb->bit_offset += 2; // chroma_sample_position
} }
#else #endif // CONFIG_COLORSPACE_HEADERS
}
#endif
} }
#if CONFIG_EXT_QM
rb->bit_offset += 1; // separate_uv_delta_q
#endif // CONFIG_EXT_QM
return 1; return 1;
} }
#endif #endif
......
...@@ -108,7 +108,6 @@ typedef enum BITSTREAM_PROFILE { ...@@ -108,7 +108,6 @@ typedef enum BITSTREAM_PROFILE {
PROFILE_0, PROFILE_0,
PROFILE_1, PROFILE_1,
PROFILE_2, PROFILE_2,
PROFILE_3,
MAX_PROFILES MAX_PROFILES
} BITSTREAM_PROFILE; } BITSTREAM_PROFILE;
......
...@@ -2140,16 +2140,28 @@ static void error_handler(void *data) { ...@@ -2140,16 +2140,28 @@ static void error_handler(void *data) {
aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, "Truncated packet"); aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, "Truncated packet");
} }
void av1_read_bitdepth(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
cm->bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_10 : AOM_BITS_8;
if (cm->profile < PROFILE_2 || cm->bit_depth == AOM_BITS_8) {
return;
}
cm->bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_12 : AOM_BITS_10;
return;
}
void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm, void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm,
struct aom_read_bit_buffer *rb, struct aom_read_bit_buffer *rb,
int allow_lowbitdepth) { int allow_lowbitdepth) {
if (cm->profile >= PROFILE_2) { av1_read_bitdepth(cm, rb);
cm->bit_depth = aom_rb_read_bit(rb) ? AOM_BITS_12 : AOM_BITS_10;
} else {
cm->bit_depth = AOM_BITS_8;
}
cm->use_highbitdepth = cm->bit_depth > AOM_BITS_8 || !allow_lowbitdepth; cm->use_highbitdepth = cm->bit_depth > AOM_BITS_8 || !allow_lowbitdepth;
#if CONFIG_MONO_VIDEO
// monochrome bit (not needed for PROFILE_1)
const int is_monochrome = cm->profile != PROFILE_1 ? aom_rb_read_bit(rb) : 0;
cm->color_space = is_monochrome ? AOM_CS_MONOCHROME : AOM_CS_UNKNOWN;
#elif !CONFIG_CICP
const int is_monochrome = 0;
#endif // CONFIG_MONO_VIDEO
#if CONFIG_CICP #if CONFIG_CICP
int color_description_present_flag = aom_rb_read_bit(rb); int color_description_present_flag = aom_rb_read_bit(rb);
if (color_description_present_flag) { if (color_description_present_flag) {
...@@ -2163,12 +2175,12 @@ void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm, ...@@ -2163,12 +2175,12 @@ void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm,
} }
#else #else
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
cm->color_space = aom_rb_read_literal(rb, 5); if (!is_monochrome) cm->color_space = aom_rb_read_literal(rb, 5);
cm->transfer_function = aom_rb_read_literal(rb, 5); cm->transfer_function = aom_rb_read_literal(rb, 5);
#else #else
cm->color_space = aom_rb_read_literal(rb, 3 + CONFIG_MONO_VIDEO); if (!is_monochrome) cm->color_space = aom_rb_read_literal(rb, 4);
#endif #endif // CONFIG_COLORSPACE_HEADERS
#endif #endif // CONFIG_CICP
#if CONFIG_CICP #if CONFIG_CICP
if (cm->color_primaries == AOM_CICP_CP_BT_709 && if (cm->color_primaries == AOM_CICP_CP_BT_709 &&
cm->transfer_characteristics == AOM_CICP_TC_SRGB && cm->transfer_characteristics == AOM_CICP_TC_SRGB &&
...@@ -2177,54 +2189,53 @@ void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm, ...@@ -2177,54 +2189,53 @@ void av1_read_bitdepth_colorspace_sampling(AV1_COMMON *cm,
// dependency too // dependency too
#else #else
if (cm->color_space == AOM_CS_SRGB) { if (cm->color_space == AOM_CS_SRGB) {
#endif #endif // CONFIG_CICP
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { cm->subsampling_y = cm->subsampling_x = 0;
// Note if colorspace is SRGB then 4:4:4 chroma sampling is assumed. if (!(cm->profile == PROFILE_1 ||
// 4:2:2 or 4:4:0 chroma sampling is not allowed. (cm->profile == PROFILE_2 && cm->bit_depth == AOM_BITS_12))) {
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, aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
"4:4:4 color not supported in profile 0 or 2"); "SRGB colorspace not copatible with profile");
} }
#if CONFIG_MONO_VIDEO && !CONFIG_CICP #if CONFIG_MONO_VIDEO
} else if (cm->color_space == AOM_CS_MONOCHROME) { } else if (is_monochrome) {
cm->color_range = AOM_CR_FULL_RANGE; cm->color_range = AOM_CR_FULL_RANGE;
cm->subsampling_y = cm->subsampling_x = 1; cm->subsampling_y = cm->subsampling_x = 1;
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
cm->chroma_sample_position = AOM_CSP_UNKNOWN; cm->chroma_sample_position = AOM_CSP_UNKNOWN;
#endif #endif // CONFIG_COLORSPACE_HEADERS
#if CONFIG_EXT_QM #if CONFIG_EXT_QM
cm->separate_uv_delta_q = 0; cm->separate_uv_delta_q = 0;
#endif #endif // CONFIG_EXT_QM
return; return;
#endif // CONFIG_MONO_VIDEO #endif // CONFIG_MONO_VIDEO
} else { } else {
// [16,235] (including xvycc) vs [0,255] range // [16,235] (including xvycc) vs [0,255] range
cm->color_range = aom_rb_read_bit(rb); cm->color_range = aom_rb_read_bit(rb);
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { if (cm->profile == PROFILE_0) {
cm->subsampling_x = aom_rb_read_bit(rb); // 420 only
cm->subsampling_y = aom_rb_read_bit(rb); cm->subsampling_x = cm->subsampling_y = 1;
if (cm->subsampling_x == 1 && cm->subsampling_y == 1) } else if (cm->profile == PROFILE_1) {
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, // 444 only
"4:2:0 color not supported in profile 1 or 3"); cm->subsampling_x = cm->subsampling_y = 0;
if (aom_rb_read_bit(rb)) } else if (cm->profile == PROFILE_2) {
aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM, if (cm->bit_depth == AOM_BITS_12) {
"Reserved bit set"); cm->subsampling_x = aom_rb_read_bit(rb);
} else { cm->subsampling_y = aom_rb_read_bit(rb);
cm->subsampling_y = cm->subsampling_x = 1; } else {
// 422
cm->subsampling_x = 1;
cm->subsampling_y = 0;
}
} }
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
if (cm->subsampling_x == 1 && cm->subsampling_y == 1) { if (cm->subsampling_x == 1 && cm->subsampling_y == 1) {
cm->chroma_sample_position = aom_rb_read_literal(rb, 2); cm->chroma_sample_position = aom_rb_read_literal(rb, 2);
} }
#endif #endif // CONFIG_COLORSPACE_HEADERS
} }
#if CONFIG_EXT_QM #if CONFIG_EXT_QM
cm->separate_uv_delta_q = aom_rb_read_bit(rb); cm->separate_uv_delta_q = aom_rb_read_bit(rb);
#endif #endif // CONFIG_EXT_QM
} }
#if CONFIG_REFERENCE_BUFFER || CONFIG_OBU #if CONFIG_REFERENCE_BUFFER || CONFIG_OBU
...@@ -3206,9 +3217,7 @@ void av1_read_frame_size(struct aom_read_bit_buffer *rb, int *width, ...@@ -3206,9 +3217,7 @@ void av1_read_frame_size(struct aom_read_bit_buffer *rb, int *width,
} }
BITSTREAM_PROFILE av1_read_profile(struct aom_read_bit_buffer *rb) { BITSTREAM_PROFILE av1_read_profile(struct aom_read_bit_buffer *rb) {
int profile = aom_rb_read_bit(rb); int profile = aom_rb_read_literal(rb, 2);
profile |= aom_rb_read_bit(rb) << 1;
if (profile > 2) profile += aom_rb_read_bit(rb);
return (BITSTREAM_PROFILE)profile; return (BITSTREAM_PROFILE)profile;
} }
......
...@@ -3266,21 +3266,33 @@ static void write_frame_size_with_refs(AV1_COMP *cpi, ...@@ -3266,21 +3266,33 @@ static void write_frame_size_with_refs(AV1_COMP *cpi,
static void write_profile(BITSTREAM_PROFILE profile, static void write_profile(BITSTREAM_PROFILE profile,
struct aom_write_bit_buffer *wb) { struct aom_write_bit_buffer *wb) {
switch (profile) { assert(profile >= PROFILE_0 && profile < MAX_PROFILES);
case PROFILE_0: aom_wb_write_literal(wb, 0, 2); break; aom_wb_write_literal(wb, profile, 2);
case PROFILE_1: aom_wb_write_literal(wb, 2, 2); break; }
case PROFILE_2: aom_wb_write_literal(wb, 1, 2); break;
case PROFILE_3: aom_wb_write_literal(wb, 6, 3); break; static void write_bitdepth(AV1_COMMON *const cm,
default: assert(0); struct aom_write_bit_buffer *wb) {
// Profile 0/1: [0] for 8 bit, [1] 10-bit
// Profile 2: [0] for 8 bit, [10] 10-bit, [11] - 12-bit
aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_8 ? 0 : 1);
if (cm->profile == PROFILE_2 && cm->bit_depth != AOM_BITS_8) {
aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_10 ? 0 : 1);
} }
} }
static void write_bitdepth_colorspace_sampling( static void write_bitdepth_colorspace_sampling(
AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) {
if (cm->profile >= PROFILE_2) { write_bitdepth(cm, wb);
assert(cm->bit_depth > AOM_BITS_8); #if CONFIG_MONO_VIDEO
aom_wb_write_bit(wb, cm->bit_depth == AOM_BITS_10 ? 0 : 1); const int is_monochrome = cm->color_space == AOM_CS_MONOCHROME;
} // monochrome bit
if (cm->profile != PROFILE_1)
aom_wb_write_bit(wb, is_monochrome);
else
assert(!is_monochrome);
#elif !CONFIG_CICP
const int is_monochrome = 0;
#endif // CONFIG_MONO_VIDEO
#if CONFIG_CICP #if CONFIG_CICP
if (cm->color_primaries == AOM_CICP_CP_UNSPECIFIED && if (cm->color_primaries == AOM_CICP_CP_UNSPECIFIED &&
cm->transfer_characteristics == AOM_CICP_TC_UNSPECIFIED && cm->transfer_characteristics == AOM_CICP_TC_UNSPECIFIED &&
...@@ -3294,12 +3306,12 @@ static void write_bitdepth_colorspace_sampling( ...@@ -3294,12 +3306,12 @@ static void write_bitdepth_colorspace_sampling(
} }
#else #else
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
aom_wb_write_literal(wb, cm->color_space, 5); if (!is_monochrome) aom_wb_write_literal(wb, cm->color_space, 5);
aom_wb_write_literal(wb, cm->transfer_function, 5); aom_wb_write_literal(wb, cm->transfer_function, 5);
#else #else
aom_wb_write_literal(wb, cm->color_space, 3 + CONFIG_MONO_VIDEO); if (!is_monochrome) aom_wb_write_literal(wb, cm->color_space, 4);
#endif #endif // CONFIG_COLORSPACE_HEADERS
#endif #endif // CONFIG_CICP
#if CONFIG_CICP #if CONFIG_CICP
if (cm->color_primaries == AOM_CICP_CP_BT_709 && if (cm->color_primaries == AOM_CICP_CP_BT_709 &&
cm->transfer_characteristics == AOM_CICP_TC_SRGB && cm->transfer_characteristics == AOM_CICP_TC_SRGB &&
...@@ -3308,23 +3320,32 @@ static void write_bitdepth_colorspace_sampling( ...@@ -3308,23 +3320,32 @@ static void write_bitdepth_colorspace_sampling(
// dependency too // dependency too
#else #else
if (cm->color_space == AOM_CS_SRGB) { if (cm->color_space == AOM_CS_SRGB) {
#endif #endif // CONFIG_CICP
assert(cm->profile == PROFILE_1 || cm->profile == PROFILE_3); assert(cm->subsampling_x == 0 && cm->subsampling_y == 0);
aom_wb_write_bit(wb, 0); // unused assert(cm->profile == PROFILE_1 ||
#if CONFIG_MONO_VIDEO && !CONFIG_CICP (cm->profile == PROFILE_2 && cm->bit_depth == AOM_BITS_12));
} else if (cm->color_space == AOM_CS_MONOCHROME) { #if CONFIG_MONO_VIDEO
} else if (is_monochrome) {
return; return;
#endif // CONFIG_MONO_VIDEO #endif // CONFIG_MONO_VIDEO
} else { } else {
// 0: [16, 235] (i.e. xvYCC), 1: [0, 255] // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
aom_wb_write_bit(wb, cm->color_range); aom_wb_write_bit(wb, cm->color_range);
if (cm->profile == PROFILE_1 || cm->profile == PROFILE_3) { if (cm->profile == PROFILE_0) {
assert(cm->subsampling_x != 1 || cm->subsampling_y != 1); // 420 only
aom_wb_write_bit(wb, cm->subsampling_x);
aom_wb_write_bit(wb, cm->subsampling_y);
aom_wb_write_bit(wb, 0); // unused
} else {
assert(cm->subsampling_x == 1 && cm->subsampling_y == 1); assert(cm->subsampling_x == 1 && cm->subsampling_y == 1);
} else if (cm->profile == PROFILE_1) {
// 444 only
assert(cm->subsampling_x == 0 && cm->subsampling_y == 0);
} else if (cm->profile == PROFILE_2) {
if (cm->bit_depth == AOM_BITS_12) {
// 420, 444 or 422
aom_wb_write_bit(wb, cm->subsampling_x);
aom_wb_write_bit(wb, cm->subsampling_y);
} else {
// 422 only
assert(cm->subsampling_x == 1 && cm->subsampling_y == 0);
}
} }
#if CONFIG_COLORSPACE_HEADERS #if CONFIG_COLORSPACE_HEADERS
if (cm->subsampling_x == 1 && cm->subsampling_y == 1) { if (cm->subsampling_x == 1 && cm->subsampling_y == 1) {
......
...@@ -3090,10 +3090,7 @@ void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) { ...@@ -3090,10 +3090,7 @@ void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
#endif #endif
cm->color_range = oxcf->color_range; cm->color_range = oxcf->color_range;
if (cm->profile <= PROFILE_1) assert(IMPLIES(cm->profile <= PROFILE_1, cm->bit_depth <= AOM_BITS_10));
assert(cm->bit_depth == AOM_BITS_8);
else
assert(cm->bit_depth > AOM_BITS_8);
cpi->oxcf = *oxcf; cpi->oxcf = *oxcf;
x->e_mbd.bd = (int)cm->bit_depth; x->e_mbd.bd = (int)cm->bit_depth;
...@@ -6435,16 +6432,22 @@ int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags, ...@@ -6435,16 +6432,22 @@ int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
aom_usec_timer_mark(&timer); aom_usec_timer_mark(&timer);
cpi->time_receive_data += aom_usec_timer_elapsed(&timer); cpi->time_receive_data += aom_usec_timer_elapsed(&timer);
if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) && if ((cm->profile == PROFILE_0) &&
(subsampling_x != 1 || subsampling_y != 1)) { (subsampling_x != 1 || subsampling_y != 1)) {
aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM, aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
"Non-4:2:0 color format requires profile 1 or 3"); "Non-4:2:0 color format requires profile 1 or 2");
res = -1;
}
if ((cm->profile == PROFILE_1) &&
!(subsampling_x == 0 && subsampling_y == 0)) {
aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
"Profile 1 requires 4:4:4 color format");