High-level hooks for Profile 2 (10/12 bit)

Adds some high-level hooks for profile 2 before further
progress on the implementation.

According to the definitiion in this patch:
1. Profile 2 only supports 10 or 12 bit color but not 8
2. Profile 2 supports all color sampling modes: 444, 422 and 420,
and alpha plane.
3. Profile 3 is currently undefined.

Please consider the definition carefully and suggest modifications
to the definition as needed.

Change-Id: I5b284fc679e54ac5aee171af72fa7994cfd28995
This commit is contained in:
Deb Mukherjee 2014-04-04 17:30:16 -07:00
Родитель e8e380f994
Коммит d35df2d8ea
7 изменённых файлов: 76 добавлений и 28 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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;

Просмотреть файл

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

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

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