Miscellaneous decoder changes for high bitdepth
Also includes yv12 config changes. Change-Id: Iacf40d8bf486815b54c32a127ce3cd4516b7e44f
This commit is contained in:
parent
8b4dd536a5
commit
9ed23de13f
@ -224,7 +224,8 @@ void vpx_img_write(const vpx_image_t *img, FILE *file) {
|
|||||||
for (plane = 0; plane < 3; ++plane) {
|
for (plane = 0; plane < 3; ++plane) {
|
||||||
const unsigned char *buf = img->planes[plane];
|
const unsigned char *buf = img->planes[plane];
|
||||||
const int stride = img->stride[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);
|
const int h = vpx_img_plane_height(img, plane);
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@ typedef struct VP9Common {
|
|||||||
|
|
||||||
// VPX_BITS_8 in profile 0 or 1, VPX_BITS_10 or VPX_BITS_12 in profile 2 or 3.
|
// 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;
|
vpx_bit_depth_t bit_depth;
|
||||||
|
vpx_bit_depth_t dequant_bit_depth; // bit_depth of current dequantizer
|
||||||
|
|
||||||
#if CONFIG_VP9_POSTPROC
|
#if CONFIG_VP9_POSTPROC
|
||||||
struct postproc_state postproc_state;
|
struct postproc_state postproc_state;
|
||||||
|
@ -467,13 +467,13 @@ static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
|
|||||||
int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1;
|
int y1 = ((y0_16 + (h - 1) * ys) >> SUBPEL_BITS) + 1;
|
||||||
int x_pad = 0, y_pad = 0;
|
int x_pad = 0, y_pad = 0;
|
||||||
|
|
||||||
if (subpel_x || (sf->x_step_q4 != 16)) {
|
if (subpel_x || (sf->x_step_q4 != SUBPEL_SHIFTS)) {
|
||||||
x0 -= VP9_INTERP_EXTEND - 1;
|
x0 -= VP9_INTERP_EXTEND - 1;
|
||||||
x1 += VP9_INTERP_EXTEND;
|
x1 += VP9_INTERP_EXTEND;
|
||||||
x_pad = 1;
|
x_pad = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subpel_y || (sf->y_step_q4 != 16)) {
|
if (subpel_y || (sf->y_step_q4 != SUBPEL_SHIFTS)) {
|
||||||
y0 -= VP9_INTERP_EXTEND - 1;
|
y0 -= VP9_INTERP_EXTEND - 1;
|
||||||
y1 += VP9_INTERP_EXTEND;
|
y1 += VP9_INTERP_EXTEND;
|
||||||
y_pad = 1;
|
y_pad = 1;
|
||||||
|
@ -652,8 +652,10 @@ static void setup_quantization(VP9_COMMON *const cm, MACROBLOCKD *const xd,
|
|||||||
update |= read_delta_q(rb, &cm->y_dc_delta_q);
|
update |= read_delta_q(rb, &cm->y_dc_delta_q);
|
||||||
update |= read_delta_q(rb, &cm->uv_dc_delta_q);
|
update |= read_delta_q(rb, &cm->uv_dc_delta_q);
|
||||||
update |= read_delta_q(rb, &cm->uv_ac_delta_q);
|
update |= read_delta_q(rb, &cm->uv_ac_delta_q);
|
||||||
if (update)
|
if (update || cm->bit_depth != cm->dequant_bit_depth) {
|
||||||
vp9_init_dequantizer(cm);
|
vp9_init_dequantizer(cm);
|
||||||
|
cm->dequant_bit_depth = cm->bit_depth;
|
||||||
|
}
|
||||||
|
|
||||||
xd->lossless = cm->base_qindex == 0 &&
|
xd->lossless = cm->base_qindex == 0 &&
|
||||||
cm->y_dc_delta_q == 0 &&
|
cm->y_dc_delta_q == 0 &&
|
||||||
|
@ -69,6 +69,7 @@ VP9Decoder *vp9_decoder_create() {
|
|||||||
cm->current_video_frame = 0;
|
cm->current_video_frame = 0;
|
||||||
pbi->ready_for_new_data = 1;
|
pbi->ready_for_new_data = 1;
|
||||||
cm->bit_depth = VPX_BITS_8;
|
cm->bit_depth = VPX_BITS_8;
|
||||||
|
cm->dequant_bit_depth = VPX_BITS_8;
|
||||||
|
|
||||||
// vp9_init_dequantizer() is first called here. Add check in
|
// vp9_init_dequantizer() is first called here. Add check in
|
||||||
// frame_init_dequantizer() to avoid unnecessary calling of
|
// frame_init_dequantizer() to avoid unnecessary calling of
|
||||||
|
@ -437,7 +437,6 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
|
|||||||
// call to get_frame.
|
// call to get_frame.
|
||||||
if (!(*iter)) {
|
if (!(*iter)) {
|
||||||
img = &ctx->img;
|
img = &ctx->img;
|
||||||
img->bit_depth = (int)ctx->pbi->common.bit_depth;
|
|
||||||
*iter = img;
|
*iter = img;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,22 @@ static void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12,
|
|||||||
img->stride[VPX_PLANE_U] = yv12->uv_stride;
|
img->stride[VPX_PLANE_U] = yv12->uv_stride;
|
||||||
img->stride[VPX_PLANE_V] = yv12->uv_stride;
|
img->stride[VPX_PLANE_V] = yv12->uv_stride;
|
||||||
img->stride[VPX_PLANE_ALPHA] = yv12->y_stride;
|
img->stride[VPX_PLANE_ALPHA] = yv12->y_stride;
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
if (yv12->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||||
|
// vpx_image_t uses byte strides and a pointer to the first byte
|
||||||
|
// of the image.
|
||||||
|
img->fmt |= VPX_IMG_FMT_HIGHBITDEPTH;
|
||||||
|
img->bit_depth = yv12->bit_depth;
|
||||||
|
img->planes[VPX_PLANE_Y] = (uint8_t*)CONVERT_TO_SHORTPTR(yv12->y_buffer);
|
||||||
|
img->planes[VPX_PLANE_U] = (uint8_t*)CONVERT_TO_SHORTPTR(yv12->u_buffer);
|
||||||
|
img->planes[VPX_PLANE_V] = (uint8_t*)CONVERT_TO_SHORTPTR(yv12->v_buffer);
|
||||||
|
img->planes[VPX_PLANE_ALPHA] = NULL;
|
||||||
|
img->stride[VPX_PLANE_Y] = 2 * yv12->y_stride;
|
||||||
|
img->stride[VPX_PLANE_U] = 2 * yv12->uv_stride;
|
||||||
|
img->stride[VPX_PLANE_V] = 2 * yv12->uv_stride;
|
||||||
|
img->stride[VPX_PLANE_ALPHA] = 2 * yv12->y_stride;
|
||||||
|
}
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
img->bps = bps;
|
img->bps = bps;
|
||||||
img->user_priv = user_priv;
|
img->user_priv = user_priv;
|
||||||
img->img_data = yv12->buffer_alloc;
|
img->img_data = yv12->buffer_alloc;
|
||||||
@ -72,6 +88,32 @@ static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
|
|||||||
yv12->y_stride = img->stride[VPX_PLANE_Y];
|
yv12->y_stride = img->stride[VPX_PLANE_Y];
|
||||||
yv12->uv_stride = img->stride[VPX_PLANE_U];
|
yv12->uv_stride = img->stride[VPX_PLANE_U];
|
||||||
|
|
||||||
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
if (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) {
|
||||||
|
// In vpx_image_t
|
||||||
|
// planes point to uint8 address of start of data
|
||||||
|
// stride counts uint8s to reach next row
|
||||||
|
// In YV12_BUFFER_CONFIG
|
||||||
|
// y_buffer, u_buffer, v_buffer point to uint16 address of data
|
||||||
|
// stride and border counts in uint16s
|
||||||
|
// This means that all the address calculations in the main body of code
|
||||||
|
// should work correctly.
|
||||||
|
// However, before we do any pixel operations we need to cast the address
|
||||||
|
// to a uint16 ponter and double its value.
|
||||||
|
yv12->y_buffer = CONVERT_TO_BYTEPTR(yv12->y_buffer);
|
||||||
|
yv12->u_buffer = CONVERT_TO_BYTEPTR(yv12->u_buffer);
|
||||||
|
yv12->v_buffer = CONVERT_TO_BYTEPTR(yv12->v_buffer);
|
||||||
|
yv12->y_stride >>= 1;
|
||||||
|
yv12->uv_stride >>= 1;
|
||||||
|
yv12->flags = YV12_FLAG_HIGHBITDEPTH;
|
||||||
|
} else {
|
||||||
|
yv12->flags = 0;
|
||||||
|
}
|
||||||
|
yv12->border = (yv12->y_stride - img->w) / 2;
|
||||||
|
#else
|
||||||
|
yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
|
||||||
|
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||||
|
|
||||||
yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
|
yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
43
vpxdec.c
43
vpxdec.c
@ -551,8 +551,8 @@ static void high_img_upshift(vpx_image_t *dst, vpx_image_t *src,
|
|||||||
int h = src->d_h;
|
int h = src->d_h;
|
||||||
int x, y;
|
int x, y;
|
||||||
if (plane) {
|
if (plane) {
|
||||||
w >>= src->x_chroma_shift;
|
w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
|
||||||
h >>= src->y_chroma_shift;
|
h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
|
||||||
}
|
}
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
||||||
@ -590,8 +590,8 @@ static void low_img_upshift(vpx_image_t *dst, vpx_image_t *src,
|
|||||||
int h = src->d_h;
|
int h = src->d_h;
|
||||||
int x, y;
|
int x, y;
|
||||||
if (plane) {
|
if (plane) {
|
||||||
w >>= src->x_chroma_shift;
|
w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
|
||||||
h >>= src->y_chroma_shift;
|
h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
|
||||||
}
|
}
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
|
uint8_t *p_src = src->planes[plane] + y * src->stride[plane];
|
||||||
@ -636,8 +636,8 @@ static void high_img_downshift(vpx_image_t *dst, vpx_image_t *src,
|
|||||||
int h = src->d_h;
|
int h = src->d_h;
|
||||||
int x, y;
|
int x, y;
|
||||||
if (plane) {
|
if (plane) {
|
||||||
w >>= src->x_chroma_shift;
|
w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
|
||||||
h >>= src->y_chroma_shift;
|
h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
|
||||||
}
|
}
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
||||||
@ -674,8 +674,8 @@ static void low_img_downshift(vpx_image_t *dst, vpx_image_t *src,
|
|||||||
int h = src->d_h;
|
int h = src->d_h;
|
||||||
int x, y;
|
int x, y;
|
||||||
if (plane) {
|
if (plane) {
|
||||||
w >>= src->x_chroma_shift;
|
w = (w + src->x_chroma_shift) >> src->x_chroma_shift;
|
||||||
h >>= src->y_chroma_shift;
|
h = (h + src->y_chroma_shift) >> src->y_chroma_shift;
|
||||||
}
|
}
|
||||||
for (y = 0; y < h; y++) {
|
for (y = 0; y < h; y++) {
|
||||||
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
uint16_t *p_src = (uint16_t *)(src->planes[plane] +
|
||||||
@ -696,6 +696,14 @@ static void img_downshift(vpx_image_t *dst, vpx_image_t *src,
|
|||||||
low_img_downshift(dst, src, down_shift);
|
low_img_downshift(dst, src, down_shift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int img_shifted_realloc_required(const vpx_image_t *img,
|
||||||
|
const vpx_image_t *shifted,
|
||||||
|
vpx_img_fmt_t required_fmt) {
|
||||||
|
return img->d_w != shifted->d_w ||
|
||||||
|
img->d_h != shifted->d_h ||
|
||||||
|
required_fmt != shifted->fmt;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main_loop(int argc, const char **argv_) {
|
int main_loop(int argc, const char **argv_) {
|
||||||
@ -1130,16 +1138,17 @@ int main_loop(int argc, const char **argv_) {
|
|||||||
}
|
}
|
||||||
// Shift up or down if necessary
|
// Shift up or down if necessary
|
||||||
if (output_bit_depth != img->bit_depth) {
|
if (output_bit_depth != img->bit_depth) {
|
||||||
|
const vpx_img_fmt_t shifted_fmt = output_bit_depth == 8 ?
|
||||||
|
img->fmt ^ (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) :
|
||||||
|
img->fmt | VPX_IMG_FMT_HIGHBITDEPTH;
|
||||||
|
if (img_shifted &&
|
||||||
|
img_shifted_realloc_required(img, img_shifted, shifted_fmt)) {
|
||||||
|
vpx_img_free(img_shifted);
|
||||||
|
img_shifted = NULL;
|
||||||
|
}
|
||||||
if (!img_shifted) {
|
if (!img_shifted) {
|
||||||
if (output_bit_depth == 8) {
|
img_shifted = vpx_img_alloc(NULL, shifted_fmt,
|
||||||
img_shifted = vpx_img_alloc(
|
img->d_w, img->d_h, 16);
|
||||||
NULL, img->fmt - VPX_IMG_FMT_HIGHBITDEPTH,
|
|
||||||
img->d_w, img->d_h, 16);
|
|
||||||
} else {
|
|
||||||
img_shifted = vpx_img_alloc(
|
|
||||||
NULL, img->fmt | VPX_IMG_FMT_HIGHBITDEPTH,
|
|
||||||
img->d_w, img->d_h, 16);
|
|
||||||
}
|
|
||||||
img_shifted->bit_depth = output_bit_depth;
|
img_shifted->bit_depth = output_bit_depth;
|
||||||
}
|
}
|
||||||
if (output_bit_depth > img->bit_depth) {
|
if (output_bit_depth > img->bit_depth) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user