summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp9/common/vp9_enums.h17
-rw-r--r--vp9/common/vp9_onyxc_int.h5
-rw-r--r--vp9/decoder/vp9_decodeframe.c22
-rw-r--r--vp9/encoder/vp9_bitstream.c23
-rw-r--r--vp9/encoder/vp9_onyx_if.c15
-rw-r--r--vp9/encoder/vp9_onyx_int.h5
-rw-r--r--vp9/vp9_cx_iface.c17
7 files changed, 76 insertions, 28 deletions
diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h
index 779dce017..068284faa 100644
--- a/vp9/common/vp9_enums.h
+++ b/vp9/common/vp9_enums.h
@@ -25,6 +25,23 @@ extern "C" {
#define MI_MASK (MI_BLOCK_SIZE - 1)
+// Bitstream profiles indicated by 2 bits in the uncompressed header.
+// 00: Profile 0. 4:2:0 only.
+// 10: Profile 1. adds 4:4:4, 4:2:2, alpha.
+// 01: Profile 2. Supports 10-bit and 12-bit color only.
+// 11: Undefined profile.
+typedef enum BITSTREAM_PROFILE {
+ PROFILE_0,
+ PROFILE_1,
+ PROFILE_2,
+ MAX_PROFILES
+} BITSTREAM_PROFILE;
+
+typedef enum BIT_DEPTH {
+ BITS_8,
+ BITS_10,
+ BITS_12
+} BIT_DEPTH;
typedef enum BLOCK_SIZE {
BLOCK_4X4,
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index ea1b8856e..77f563f2f 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -179,7 +179,10 @@ typedef struct VP9Common {
FRAME_COUNTS counts;
unsigned int current_video_frame;
- int version;
+ BITSTREAM_PROFILE profile;
+
+ // BITS_8 in versions 0 and 1, BITS_10 or BITS_12 in version 2
+ BIT_DEPTH bit_depth;
#if CONFIG_VP9_POSTPROC
struct postproc_state postproc_state;
diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c
index 6784238de..f903e0919 100644
--- a/vp9/decoder/vp9_decodeframe.c
+++ b/vp9/decoder/vp9_decodeframe.c
@@ -1005,10 +1005,11 @@ static void error_handler(void *data) {
vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, "Truncated packet");
}
-#define RESERVED \
- if (vp9_rb_read_bit(rb)) \
- vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, \
- "Reserved bit must be unset")
+static BITSTREAM_PROFILE read_profile(struct vp9_read_bit_buffer *rb) {
+ int profile = vp9_rb_read_bit(rb);
+ profile |= vp9_rb_read_bit(rb) << 1;
+ return (BITSTREAM_PROFILE) profile;
+}
static size_t read_uncompressed_header(VP9Decoder *pbi,
struct vp9_read_bit_buffer *rb) {
@@ -1022,8 +1023,10 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
"Invalid frame marker");
- cm->version = vp9_rb_read_bit(rb);
- RESERVED;
+ cm->profile = read_profile(rb);
+ if (cm->profile >= MAX_PROFILES)
+ vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
+ "Unsupported bitstream profile");
cm->show_existing_frame = vp9_rb_read_bit(rb);
if (cm->show_existing_frame) {
@@ -1048,11 +1051,12 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
if (cm->frame_type == KEY_FRAME) {
check_sync_code(cm, rb);
-
+ if (cm->profile > PROFILE_1)
+ cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
cm->color_space = (COLOR_SPACE)vp9_rb_read_literal(rb, 3);
if (cm->color_space != SRGB) {
vp9_rb_read_bit(rb); // [16,235] (including xvycc) vs [0,255] range
- if (cm->version == 1) {
+ if (cm->profile >= PROFILE_1) {
cm->subsampling_x = vp9_rb_read_bit(rb);
cm->subsampling_y = vp9_rb_read_bit(rb);
vp9_rb_read_bit(rb); // has extra plane
@@ -1060,7 +1064,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
cm->subsampling_y = cm->subsampling_x = 1;
}
} else {
- if (cm->version == 1) {
+ if (cm->profile >= PROFILE_1) {
cm->subsampling_y = cm->subsampling_x = 0;
vp9_rb_read_bit(rb); // has extra plane
} else {
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 4313418d4..8d2afb991 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1031,19 +1031,22 @@ static void write_sync_code(struct vp9_write_bit_buffer *wb) {
vp9_wb_write_literal(wb, VP9_SYNC_CODE_2, 8);
}
+static void write_profile(BITSTREAM_PROFILE profile,
+ struct vp9_write_bit_buffer *wb) {
+ assert(profile < MAX_PROFILES);
+ vp9_wb_write_bit(wb, profile & 1);
+ vp9_wb_write_bit(wb, profile >> 1);
+}
+
static void write_uncompressed_header(VP9_COMP *cpi,
struct vp9_write_bit_buffer *wb) {
VP9_COMMON *const cm = &cpi->common;
vp9_wb_write_literal(wb, VP9_FRAME_MARKER, 2);
- // bitstream version.
- // 00 - profile 0. 4:2:0 only
- // 10 - profile 1. adds 4:4:4, 4:2:2, alpha
- vp9_wb_write_bit(wb, cm->version);
- vp9_wb_write_bit(wb, 0);
+ write_profile(cm->profile, wb);
- vp9_wb_write_bit(wb, 0);
+ vp9_wb_write_bit(wb, 0); // show_existing_frame
vp9_wb_write_bit(wb, cm->frame_type);
vp9_wb_write_bit(wb, cm->show_frame);
vp9_wb_write_bit(wb, cm->error_resilient_mode);
@@ -1051,16 +1054,20 @@ static void write_uncompressed_header(VP9_COMP *cpi,
if (cm->frame_type == KEY_FRAME) {
const COLOR_SPACE cs = UNKNOWN;
write_sync_code(wb);
+ if (cm->profile > PROFILE_1) {
+ assert(cm->bit_depth > BITS_8);
+ vp9_wb_write_bit(wb, cm->bit_depth - BITS_10);
+ }
vp9_wb_write_literal(wb, cs, 3);
if (cs != SRGB) {
vp9_wb_write_bit(wb, 0); // 0: [16, 235] (i.e. xvYCC), 1: [0, 255]
- if (cm->version == 1) {
+ if (cm->profile >= PROFILE_1) {
vp9_wb_write_bit(wb, cm->subsampling_x);
vp9_wb_write_bit(wb, cm->subsampling_y);
vp9_wb_write_bit(wb, 0); // has extra plane
}
} else {
- assert(cm->version == 1);
+ assert(cm->profile == PROFILE_1);
vp9_wb_write_bit(wb, 0); // has extra plane
}
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 04c742f0a..8d0faba2b 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -754,7 +754,8 @@ static void init_config(struct VP9_COMP *cpi, VP9_CONFIG *oxcf) {
cpi->oxcf = *oxcf;
- cm->version = oxcf->version;
+ cm->profile = oxcf->profile;
+ cm->bit_depth = oxcf->bit_depth;
cm->width = oxcf->width;
cm->height = oxcf->height;
@@ -794,8 +795,14 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9_CONFIG *oxcf) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
- if (cm->version != oxcf->version)
- cm->version = oxcf->version;
+ if (cm->profile != oxcf->profile)
+ cm->profile = oxcf->profile;
+ cm->bit_depth = oxcf->bit_depth;
+
+ if (cm->profile <= PROFILE_1)
+ assert(cm->bit_depth == BITS_8);
+ else
+ assert(cm->bit_depth > BITS_8);
cpi->oxcf = *oxcf;
@@ -2847,7 +2854,7 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
vpx_usec_timer_mark(&timer);
cpi->time_receive_data += vpx_usec_timer_elapsed(&timer);
- if (cm->version == 0 && (subsampling_x != 1 || subsampling_y != 1)) {
+ if (cm->profile == PROFILE_0 && (subsampling_x != 1 || subsampling_y != 1)) {
vpx_internal_error(&cm->error, VPX_CODEC_INVALID_PARAM,
"Non-4:2:0 color space requires profile >= 1");
res = -1;
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 6d5f62fb7..3d2c2da7b 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -186,9 +186,8 @@ typedef enum {
} AQ_MODE;
typedef struct VP9_CONFIG {
- int version; // 4 versions of bitstream defined:
- // 0 - best quality/slowest decode,
- // 3 - lowest quality/fastest decode
+ BITSTREAM_PROFILE profile;
+ BIT_DEPTH bit_depth;
int width; // width of data passed to the compressor
int height; // height of data passed to the compressor
double framerate; // set to passed in framerate
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index dfcec783c..5b2645e99 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -38,6 +38,7 @@ struct vp9_extracfg {
unsigned int frame_parallel_decoding_mode;
AQ_MODE aq_mode;
unsigned int frame_periodic_boost;
+ BIT_DEPTH bit_depth;
};
struct extraconfig_map {
@@ -67,6 +68,7 @@ static const struct extraconfig_map extracfg_map[] = {
0, // frame_parallel_decoding_mode
NO_AQ, // aq_mode
0, // frame_periodic_delta_q
+ BITS_8, // Bit depth
}
}
};
@@ -252,6 +254,12 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
ERROR("rc_twopass_stats_in missing EOS stats packet");
}
}
+ if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
+ extra_cfg->bit_depth > BITS_8)
+ ERROR("High bit-depth not supported in profile < 2");
+ if (cfg->g_profile > (unsigned int)PROFILE_1 &&
+ extra_cfg->bit_depth == BITS_8)
+ ERROR("Bit-depth 8 not supported in profile > 1");
return VPX_CODEC_OK;
}
@@ -277,11 +285,14 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
}
-static vpx_codec_err_t set_encoder_config(VP9_CONFIG *oxcf,
- const vpx_codec_enc_cfg_t *cfg, const struct vp9_extracfg *extra_cfg) {
- oxcf->version = cfg->g_profile;
+static vpx_codec_err_t set_encoder_config(
+ VP9_CONFIG *oxcf,
+ const vpx_codec_enc_cfg_t *cfg,
+ const struct vp9_extracfg *extra_cfg) {
+ oxcf->profile = cfg->g_profile;
oxcf->width = cfg->g_w;
oxcf->height = cfg->g_h;
+ oxcf->bit_depth = extra_cfg->bit_depth;
// guess a frame rate if out of whack, use 30
oxcf->framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
if (oxcf->framerate > 180)