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:
Родитель
e8e380f994
Коммит
d35df2d8ea
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче