Commit 5acfafb1 authored by Deb Mukherjee's avatar Deb Mukherjee

Adds config opt for highbitdepth + misc. vpx

Adds config parameter vp9_highbitdepth, to support highbitdepth profiles.
Also includes most vpx level high bit-depth functions. However
encode/decode in the highbitdepth profiles will not work until
the rest of the code is in place.

Change-Id: I34c53b253c38873611057a6cbc89a1361b8985a6
parent 72037944
......@@ -334,6 +334,7 @@ CONFIG_LIST="
multi_res_encoding
temporal_denoising
coefficient_range_checking
vp9_highbitdepth
experimental
size_limit
${EXPERIMENT_LIST}
......@@ -392,6 +393,7 @@ CMDLINE_SELECT="
multi_res_encoding
temporal_denoising
coefficient_range_checking
vp9_highbitdepth
experimental
"
......
......@@ -28,7 +28,8 @@ class MD5 {
// plane, we never want to round down and thus skip a pixel so if
// we are shifting by 1 (chroma_shift) we add 1 before doing the shift.
// This works only for chroma_shift of 0 and 1.
const int bytes_per_sample = (img->fmt & VPX_IMG_FMT_HIGH) ? 2 : 1;
const int bytes_per_sample =
(img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
const int h = plane ? (img->d_h + img->y_chroma_shift) >>
img->y_chroma_shift : img->d_h;
const int w = (plane ? (img->d_w + img->x_chroma_shift) >>
......
......@@ -57,7 +57,7 @@ static void write_image_file(const vpx_image_t *img, FILE *file) {
for (plane = 0; plane < 3; ++plane) {
const unsigned char *buf = img->planes[plane];
const int stride = img->stride[plane];
const int bytes_per_sample = (img->fmt & VPX_IMG_FMT_HIGH) ? 2 : 1;
const int bytes_per_sample = (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
const int h = (plane ? (img->d_h + img->y_chroma_shift) >>
img->y_chroma_shift : img->d_h);
const int w = (plane ? (img->d_w + img->x_chroma_shift) >>
......
......@@ -83,7 +83,7 @@ int read_yuv_frame(struct VpxInputContext *input_ctx, vpx_image_t *yuv_frame) {
struct FileTypeDetectionBuffer *detect = &input_ctx->detect;
int plane = 0;
int shortread = 0;
const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGH) ? 2 : 1;
const int bytespp = (yuv_frame->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
for (plane = 0; plane < 3; ++plane) {
uint8_t *ptr;
......@@ -241,7 +241,8 @@ int vpx_img_read(vpx_image_t *img, FILE *file) {
for (plane = 0; plane < 3; ++plane) {
unsigned char *buf = img->planes[plane];
const int stride = img->stride[plane];
const int w = vpx_img_plane_width(img, plane);
const int w = vpx_img_plane_width(img, plane) *
((img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1);
const int h = vpx_img_plane_height(img, plane);
int y;
......
......@@ -1244,6 +1244,9 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] =
320, /* g_width */
240, /* g_height */
VPX_BITS_8, /* g_bit_depth */
8, /* g_input_bit_depth */
{1, 30}, /* g_timebase */
0, /* g_error_resilient */
......
......@@ -177,7 +177,11 @@ int vp9_alloc_ref_frame_buffers(VP9_COMMON *cm, int width, int height) {
for (i = 0; i < FRAME_BUFFERS; ++i) {
cm->frame_bufs[i].ref_count = 0;
if (vp9_alloc_frame_buffer(&cm->frame_bufs[i].buf, width, height,
ss_x, ss_y, VP9_ENC_BORDER_IN_PIXELS) < 0)
ss_x, ss_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS) < 0)
goto fail;
}
......@@ -185,6 +189,9 @@ int vp9_alloc_ref_frame_buffers(VP9_COMMON *cm, int width, int height) {
#if CONFIG_INTERNAL_STATS || CONFIG_VP9_POSTPROC
if (vp9_alloc_frame_buffer(&cm->post_proc_buffer, width, height, ss_x, ss_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS) < 0)
goto fail;
#endif
......
......@@ -64,6 +64,11 @@ static INLINE int get_unsigned_bits(unsigned int num_values) {
return num_values > 0 ? get_msb(num_values) + 1 : 0;
}
#if CONFIG_VP9_HIGHBITDEPTH
#define CONVERT_TO_SHORTPTR(x) ((uint16_t*)(((uintptr_t)x) << 1))
#define CONVERT_TO_BYTEPTR(x) ((uint8_t*)(((uintptr_t)x) >> 1 ))
#endif // CONFIG_VP9_HIGHBITDEPTH
#if CONFIG_DEBUG
#define CHECK_MEM_ERROR(cm, lval, expr) do { \
lval = (expr); \
......
......@@ -40,12 +40,6 @@ typedef enum BITSTREAM_PROFILE {
MAX_PROFILES
} BITSTREAM_PROFILE;
typedef enum BIT_DEPTH {
BITS_8,
BITS_10,
BITS_12
} BIT_DEPTH;
typedef enum BLOCK_SIZE {
BLOCK_4X4,
BLOCK_4X8,
......
......@@ -84,6 +84,10 @@ typedef struct VP9Common {
int subsampling_x;
int subsampling_y;
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth; // Marks if we need to use 16bit frame buffers.
#endif
YV12_BUFFER_CONFIG *frame_to_show;
RefCntBuffer frame_bufs[FRAME_BUFFERS];
......@@ -179,8 +183,8 @@ typedef struct VP9Common {
unsigned int current_video_frame;
BITSTREAM_PROFILE profile;
// BITS_8 in versions 0 and 1, BITS_10 or BITS_12 in version 2
BIT_DEPTH bit_depth;
// VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3.
vpx_bit_depth_t bit_depth;
#if CONFIG_VP9_POSTPROC
struct postproc_state postproc_state;
......
......@@ -653,7 +653,11 @@ static void setup_frame_size(VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
if (vp9_realloc_frame_buffer(
get_frame_new_buffer(cm), cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_DEC_BORDER_IN_PIXELS,
&cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
cm->cb_priv)) {
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
......@@ -700,7 +704,11 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm,
if (vp9_realloc_frame_buffer(
get_frame_new_buffer(cm), cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y, VP9_DEC_BORDER_IN_PIXELS,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_DEC_BORDER_IN_PIXELS,
&cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer, cm->get_fb_cb,
cm->cb_priv)) {
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
......@@ -1100,7 +1108,7 @@ BITSTREAM_PROFILE vp9_read_profile(struct vp9_read_bit_buffer *rb) {
static void read_bitdepth_colorspace_sampling(
VP9_COMMON *cm, struct vp9_read_bit_buffer *rb) {
if (cm->profile >= PROFILE_2)
cm->bit_depth = vp9_rb_read_bit(rb) ? BITS_12 : BITS_10;
cm->bit_depth = vp9_rb_read_bit(rb) ? VPX_BITS_12 : VPX_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
......@@ -1144,6 +1152,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
"Invalid frame marker");
cm->profile = vp9_read_profile(rb);
if (cm->profile >= MAX_PROFILES)
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
"Unsupported bitstream profile");
......@@ -1402,7 +1411,7 @@ void vp9_decode_frame(VP9Decoder *pbi,
if (!first_partition_size) {
// showing a frame directly
*p_data_end = data + 1;
*p_data_end = data + (cm->profile <= PROFILE_2 ? 1 : 2);
return;
}
......
......@@ -66,6 +66,7 @@ VP9Decoder *vp9_decoder_create() {
cm->current_video_frame = 0;
pbi->ready_for_new_data = 1;
cm->bit_depth = VPX_BITS_8;
// vp9_init_dequantizer() is first called here. Add check in
// frame_init_dequantizer() to avoid unnecessary calling of
......
......@@ -1046,8 +1046,8 @@ static void write_profile(BITSTREAM_PROFILE profile,
static void write_bitdepth_colorspace_sampling(
VP9_COMMON *const cm, struct vp9_write_bit_buffer *wb) {
if (cm->profile >= PROFILE_2) {
assert(cm->bit_depth > BITS_8);
vp9_wb_write_bit(wb, cm->bit_depth - BITS_10);
assert(cm->bit_depth > VPX_BITS_8);
vp9_wb_write_bit(wb, cm->bit_depth == VPX_BITS_10 ? 0 : 1);
}
vp9_wb_write_literal(wb, cm->color_space, 3);
if (cm->color_space != SRGB) {
......
......@@ -388,13 +388,21 @@ void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse,
}
int vp9_denoiser_alloc(VP9_DENOISER *denoiser, int width, int height,
int ssx, int ssy, int border) {
int ssx, int ssy,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
#endif
int border) {
int i, fail;
assert(denoiser != NULL);
for (i = 0; i < MAX_REF_FRAMES; ++i) {
fail = vp9_alloc_frame_buffer(&denoiser->running_avg_y[i], width, height,
ssx, ssy, border);
ssx, ssy,
#if CONFIG_VP9_HIGHBITDEPTH
use_highbitdepth,
#endif
border);
if (fail) {
vp9_denoiser_free(denoiser);
return 1;
......@@ -405,7 +413,11 @@ int vp9_denoiser_alloc(VP9_DENOISER *denoiser, int width, int height,
}
fail = vp9_alloc_frame_buffer(&denoiser->mc_running_avg_y, width, height,
ssx, ssy, border);
ssx, ssy,
#if CONFIG_VP9_HIGHBITDEPTH
use_highbitdepth,
#endif
border);
if (fail) {
vp9_denoiser_free(denoiser);
return 1;
......
......@@ -47,7 +47,11 @@ void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi,
PICK_MODE_CONTEXT *ctx);
int vp9_denoiser_alloc(VP9_DENOISER *denoiser, int width, int height,
int ssx, int ssy, int border);
int ssx, int ssy,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
#endif
int border);
void vp9_denoiser_free(VP9_DENOISER *denoiser);
......
......@@ -443,6 +443,9 @@ static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
oxcf->lag_in_frames);
if (!cpi->lookahead)
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
......@@ -451,6 +454,9 @@ static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
oxcf->width, oxcf->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate altref buffer");
......@@ -468,6 +474,9 @@ static void alloc_util_frame_buffers(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate last frame buffer");
......@@ -475,6 +484,9 @@ static void alloc_util_frame_buffers(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->scaled_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled source buffer");
......@@ -482,6 +494,9 @@ static void alloc_util_frame_buffers(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->scaled_last_source,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled last source buffer");
......@@ -514,6 +529,9 @@ static void update_frame_size(VP9_COMP *cpi) {
if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate alt_ref_buffer");
......@@ -600,9 +618,9 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
cm->bit_depth = oxcf->bit_depth;
if (cm->profile <= PROFILE_1)
assert(cm->bit_depth == BITS_8);
assert(cm->bit_depth == VPX_BITS_8);
else
assert(cm->bit_depth > BITS_8);
assert(cm->bit_depth > VPX_BITS_8);
cpi->oxcf = *oxcf;
......@@ -677,6 +695,9 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
if (cpi->oxcf.noise_sensitivity > 0) {
vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS);
}
#endif
......@@ -1604,6 +1625,9 @@ void vp9_scale_references(VP9_COMP *cpi) {
vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
......@@ -2699,6 +2723,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
alloc_util_frame_buffers(cpi);
......
......@@ -114,9 +114,10 @@ typedef enum {
typedef struct VP9EncoderConfig {
BITSTREAM_PROFILE profile;
BIT_DEPTH bit_depth;
vpx_bit_depth_t bit_depth; // Codec bit-depth.
int width; // width of data passed to the compressor
int height; // height of data passed to the compressor
unsigned int input_bit_depth; // Input bit depth.
double init_framerate; // set to passed in framerate
int64_t target_bandwidth; // bandwidth to be used in kilobits per second
......
......@@ -50,6 +50,9 @@ struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
#endif
unsigned int depth) {
struct lookahead_ctx *ctx = NULL;
......@@ -70,6 +73,9 @@ struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
for (i = 0; i < depth; i++)
if (vp9_alloc_frame_buffer(&ctx->buf[i].img,
width, height, subsampling_x, subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS))
goto bail;
}
......
......@@ -56,6 +56,9 @@ struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
#endif
unsigned int depth);
......
......@@ -465,6 +465,9 @@ void vp9_temporal_filter(VP9_COMP *cpi, int distance) {
if (vp9_realloc_frame_buffer(&cpi->svc.scaled_frames[frame_used],
cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
cm->use_highbitdepth,
#endif
VP9_ENC_BORDER_IN_PIXELS, NULL, NULL,
NULL))
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
......
......@@ -37,7 +37,7 @@ struct vp9_extracfg {
unsigned int frame_parallel_decoding_mode;
AQ_MODE aq_mode;
unsigned int frame_periodic_boost;
BIT_DEPTH bit_depth;
vpx_bit_depth_t bit_depth;
vp9e_tune_content content;
};
......@@ -58,7 +58,7 @@ static struct vp9_extracfg default_extra_cfg = {
0, // frame_parallel_decoding_mode
NO_AQ, // aq_mode
0, // frame_periodic_delta_q
BITS_8, // Bit depth
VPX_BITS_8, // Bit depth
VP9E_CONTENT_DEFAULT // content
};
......@@ -208,6 +208,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
RANGE_CHECK(extra_cfg, arnr_max_frames, 0, 15);
RANGE_CHECK_HI(extra_cfg, arnr_strength, 6);
RANGE_CHECK(extra_cfg, cq_level, 0, 63);
RANGE_CHECK(cfg, g_bit_depth, VPX_BITS_8, VPX_BITS_12);
RANGE_CHECK(cfg, g_input_bit_depth, 8, 12);
RANGE_CHECK(extra_cfg, content,
VP9E_CONTENT_DEFAULT, VP9E_CONTENT_INVALID - 1);
......@@ -266,12 +268,16 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
}
}
#if !CONFIG_VP9_HIGHBITDEPTH
if (cfg->g_profile > (unsigned int)PROFILE_1)
ERROR("Profile > 1 not supported in this build configuration");
#endif
if (cfg->g_profile <= (unsigned int)PROFILE_1 &&
extra_cfg->bit_depth > BITS_8)
ERROR("High bit-depth not supported in profile < 2");
extra_cfg->bit_depth > VPX_BITS_8)
ERROR("Codec 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");
extra_cfg->bit_depth == VPX_BITS_8)
ERROR("Codec bit-depth 8 not supported in profile > 1");
return VPX_CODEC_OK;
}
......@@ -303,6 +309,9 @@ static int get_image_bps(const vpx_image_t *img) {
case VPX_IMG_FMT_I420: return 12;
case VPX_IMG_FMT_I422: return 16;
case VPX_IMG_FMT_I444: return 24;
case VPX_IMG_FMT_I42016: return 24;
case VPX_IMG_FMT_I42216: return 32;
case VPX_IMG_FMT_I44416: return 48;
default: assert(0 && "Invalid image format"); break;
}
return 0;
......@@ -317,6 +326,7 @@ static vpx_codec_err_t set_encoder_config(
oxcf->width = cfg->g_w;
oxcf->height = cfg->g_h;
oxcf->bit_depth = extra_cfg->bit_depth;
oxcf->input_bit_depth = cfg->g_input_bit_depth;
// guess a frame rate if out of whack, use 30
oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num;
if (oxcf->init_framerate > 180)
......@@ -1246,6 +1256,9 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
320, // g_width
240, // g_height
VPX_BITS_8, // g_bit_depth
8, // g_input_bit_depth
{1, 30}, // g_timebase
0, // g_error_resilient
......
......@@ -440,6 +440,7 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
// call to get_frame.
if (!(*iter)) {
img = &ctx->img;
img->bit_depth = (int)ctx->pbi->common.bit_depth;
*iter = img;
}
}
......@@ -588,6 +589,23 @@ static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx,
}
}
static vpx_codec_err_t ctrl_get_bit_depth(vpx_codec_alg_priv_t *ctx,
va_list args) {
unsigned int *const bit_depth = va_arg(args, unsigned int *);
if (bit_depth) {
if (ctx->pbi) {
const VP9_COMMON *const cm = &ctx->pbi->common;
*bit_depth = cm->bit_depth;
return VPX_CODEC_OK;
} else {
return VPX_CODEC_ERROR;
}
} else {
return VPX_CODEC_INVALID_PARAM;
}
}
static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
va_list args) {
ctx->invert_tile_order = va_arg(args, int);
......@@ -620,6 +638,7 @@ static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
{VP8D_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted},
{VP9_GET_REFERENCE, ctrl_get_reference},
{VP9D_GET_DISPLAY_SIZE, ctrl_get_display_size},
{VP9D_GET_BIT_DEPTH, ctrl_get_bit_depth},
{ -1, NULL},
};
......
......@@ -154,7 +154,7 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img,
goto fail;
img->fmt = fmt;
img->bit_depth = (fmt & VPX_IMG_FMT_HIGH) ? 16 : 8;
img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
img->w = w;
img->h = h;
img->x_chroma_shift = xcs;
......
......@@ -75,6 +75,9 @@ enum vp8_dec_control_id {
/** control function to get the display dimensions for the current frame. */
VP9D_GET_DISPLAY_SIZE,
/** control function to get the bit depth of the stream. */
VP9D_GET_BIT_DEPTH,
/** For testing. */
VP9_INVERT_TILE_DECODE_ORDER,
......@@ -118,6 +121,7 @@ VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED, int *)
VPX_CTRL_USE_TYPE(VPXD_SET_DECRYPTOR, vpx_decrypt_init *)
VPX_CTRL_USE_TYPE(VP8D_SET_DECRYPTOR, vpx_decrypt_init *)
VPX_CTRL_USE_TYPE(VP9D_GET_DISPLAY_SIZE, int *)
VPX_CTRL_USE_TYPE(VP9D_GET_BIT_DEPTH, unsigned int *)
VPX_CTRL_USE_TYPE(VP9_INVERT_TILE_DECODE_ORDER, int)
/*! @} - end defgroup vp8_decoder */
......
......@@ -217,9 +217,9 @@ extern "C" {
* This enumeration determines the bit depth of the codec.
*/
typedef enum vpx_bit_depth {
VPX_BITS_8, /**< 8 bits */
VPX_BITS_10, /**< 10 bits */
VPX_BITS_12 /**< 12 bits */
VPX_BITS_8 = 8, /**< 8 bits */
VPX_BITS_10 = 10, /**< 10 bits */
VPX_BITS_12 = 12, /**< 12 bits */
} vpx_bit_depth_t;
/*
......
......@@ -80,6 +80,9 @@ extern "C" {
*/
#define VPX_CODEC_CAP_OUTPUT_PARTITION 0x20000
/*! Can support input images at greater than 8 bitdepth.
*/
#define VPX_CODEC_CAP_HIGHBITDEPTH 0x40000
/*! \brief Initialization-time Feature Enabling
*
......@@ -91,6 +94,7 @@ extern "C" {
#define VPX_CODEC_USE_PSNR 0x10000 /**< Calculate PSNR on each frame */
#define VPX_CODEC_USE_OUTPUT_PARTITION 0x20000 /**< Make the encoder output one
partition at a time. */
#define VPX_CODEC_USE_HIGHBITDEPTH 0x40000 /**< Use high bitdepth */
/*!\brief Generic fixed size buffer structure
......@@ -324,6 +328,21 @@ extern "C" {
*/
unsigned int g_h;
/*!\brief Bit-depth of the codec
*
* This value identifies the bit_depth of the codec,
* Only certain bit-depths are supported as identified in the
* vpx_bit_depth_t enum.
*/
vpx_bit_depth_t g_bit_depth;
/*!\brief Bit-depth of the input frames
*
* This value identifies the bit_depth of the input frames in bits.
* Note that the frames passed as input to the encoder must have
* this bit-depth.
*/
unsigned int g_input_bit_depth;
/*!\brief Stream timebase units
*
......
......@@ -31,10 +31,10 @@ extern "C" {
#define VPX_IMAGE_ABI_VERSION (2) /**<\hideinitializer*/
#define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format */
#define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U plane in memory */
#define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel component */
#define VPX_IMG_FMT_HIGH 0x800 /**< Image uses 16bit framebuffer */
#define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
#define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
#define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel. */
#define VPX_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
/*!\brief List of supported image formats */
typedef enum vpx_img_fmt {
......@@ -59,9 +59,9 @@ extern "C" {
VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5,
VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6,
VPX_IMG_FMT_444A = VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_HAS_ALPHA | 7,
VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGH,
VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGH,
VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGH
VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH,
VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH
} vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */
#if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT
......
......@@ -16,6 +16,7 @@
#include <stdlib.h>
#include <string.h>
#include "include/vpx_mem_intrnl.h"
#include "vpx/vpx_integer.h"
#if CONFIG_MEM_TRACKER
#ifndef VPX_NO_GLOBALS
......@@ -452,6 +453,29 @@ void *vpx_memset(void *dest, int val, size_t length) {
return VPX_MEMSET_L(dest, val, length);
}
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
void *vpx_memset16(void *dest, int val, size_t length) {
#if CONFIG_MEM_CHECKS
if ((int)dest < 0x4000) {
_P(printf("WARNING: vpx_memset dest:0x%x val:%d len:%d\n",
(int)dest, val, length);)
#if defined(VXWORKS)
sp(get_my_tt, task_id_self(), 0, 0, 0, 0, 0, 0, 0, 0);
vx_sleep(10000);
#endif
}
#endif
int i;
void *orig = dest;
uint16_t *dest16 = dest;
for (i = 0; i < length; i++)
*dest16++ = val;
return orig;
}
#endif // CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
void *vpx_memmove(void *dest, const void *src, size_t count) {
#if CONFIG_MEM_CHECKS
......
......@@ -73,6 +73,9 @@ extern "C" {
void *vpx_memcpy(void *dest, const void *src, size_t length);
void *vpx_memset(void *dest, int val, size_t length);
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
void *vpx_memset16(void *dest, int val, size_t length);
#endif
void *vpx_memmove(void *dest, const void *src, size_t count);
/* special memory functions */
......
......@@ -13,6 +13,9 @@
#include "./vpx_config.h"
#include "vpx_scale/yv12config.h"
#include "vpx_mem/vpx_mem.h"
#if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH
#include "vp9/common/vp9_common.h"
#endif
/****************************************************************************
* Exports
......@@ -136,7 +139,11 @@ int vp9_free_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
int width, int height,
int ss_x, int ss_y, int border,
int ss_x, int ss_y,
#if CONFIG_VP9_HIGHBITDEPTH
int use_highbitdepth,
#endif
int border,
vpx_codec_frame_buffer_t *fb,
vpx_get_frame_buffer_cb_fn_t cb,
void *cb_priv) {
......@@ -161,11 +168,21 @@ int vp9_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
const int alpha_border_h = border;
const uint64_t alpha_plane_size = (alpha_height + 2 * alpha_border_h) *
(uint64_t)alpha_stride;
#if CONFIG_VP9_HIGHBITDEPTH
const uint64_t frame_size = (1 + use_highbitdepth) *
(yplane_size + 2 * uvplane_size + alpha_plane_size);
#else
const uint64_t frame_size = yplane_size + 2 * uvplane_size +
alpha_plane_size;
#endif // CONFIG_VP9_HIGHBITDEPTH
#else
#if CONFIG_VP9_HIGHBITDEPTH
const uint64_t frame_size =
(1 + use_highbitdepth) * (yplane_size + 2 * uvplane_size);
#else
const uint64_t frame_size = yplane_size + 2 * uvplane_size;
#endif
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // CONFIG_ALPHA
if (cb != NULL) {
const int align_addr_extra_size = 31;