Commit da58436f authored by John Koleszar's avatar John Koleszar

Subsampling aware allocs and bitstream

Make framebuffer allocations according to the chroma subsamping
factors in use. A bit is placed in the raw part of the frame header for
each of the two subsampling factors. This will be moved in a future
commit to make them part of the TBD feature set bits, probably only set
on keyframes, etc.

Change-Id: I59ed38d3a3c0d4af3c7c277617de28d04a001853
parent 9e327dbb
...@@ -52,10 +52,10 @@ void vp9_free_frame_buffers(VP9_COMMON *oci) { ...@@ -52,10 +52,10 @@ void vp9_free_frame_buffers(VP9_COMMON *oci) {
int i; int i;
for (i = 0; i < NUM_YV12_BUFFERS; i++) for (i = 0; i < NUM_YV12_BUFFERS; i++)
vp8_yv12_de_alloc_frame_buffer(&oci->yv12_fb[i]); vp9_free_frame_buffer(&oci->yv12_fb[i]);
vp8_yv12_de_alloc_frame_buffer(&oci->temp_scale_frame); vp9_free_frame_buffer(&oci->temp_scale_frame);
vp8_yv12_de_alloc_frame_buffer(&oci->post_proc_buffer); vp9_free_frame_buffer(&oci->post_proc_buffer);
vpx_free(oci->mip); vpx_free(oci->mip);
vpx_free(oci->prev_mip); vpx_free(oci->prev_mip);
...@@ -80,8 +80,9 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { ...@@ -80,8 +80,9 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) {
for (i = 0; i < NUM_YV12_BUFFERS; i++) { for (i = 0; i < NUM_YV12_BUFFERS; i++) {
oci->fb_idx_ref_cnt[i] = 0; oci->fb_idx_ref_cnt[i] = 0;
if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, if (vp9_alloc_frame_buffer(&oci->yv12_fb[i], width, height,
VP9BORDERINPIXELS) < 0) { oci->subsampling_x, oci->subsampling_y,
VP9BORDERINPIXELS) < 0) {
vp9_free_frame_buffers(oci); vp9_free_frame_buffers(oci);
return 1; return 1;
} }
...@@ -98,14 +99,16 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { ...@@ -98,14 +99,16 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) {
oci->fb_idx_ref_cnt[i] = 1; oci->fb_idx_ref_cnt[i] = 1;
} }
if (vp8_yv12_alloc_frame_buffer(&oci->temp_scale_frame, width, 16, if (vp9_alloc_frame_buffer(&oci->temp_scale_frame, width, 16,
VP9BORDERINPIXELS) < 0) { oci->subsampling_x, oci->subsampling_y,
VP9BORDERINPIXELS) < 0) {
vp9_free_frame_buffers(oci); vp9_free_frame_buffers(oci);
return 1; return 1;
} }
if (vp8_yv12_alloc_frame_buffer(&oci->post_proc_buffer, width, height, if (vp9_alloc_frame_buffer(&oci->post_proc_buffer, width, height,
VP9BORDERINPIXELS) < 0) { oci->subsampling_x, oci->subsampling_y,
VP9BORDERINPIXELS) < 0) {
vp9_free_frame_buffers(oci); vp9_free_frame_buffers(oci);
return 1; return 1;
} }
......
...@@ -692,7 +692,8 @@ static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, int ib) { ...@@ -692,7 +692,8 @@ static TX_TYPE get_tx_type_16x16(const MACROBLOCKD *xd, int ib) {
return tx_type; return tx_type;
} }
void vp9_setup_block_dptrs(MACROBLOCKD *xd); void vp9_setup_block_dptrs(MACROBLOCKD *xd,
int subsampling_x, int subsampling_y);
static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) { static TX_SIZE get_uv_tx_size(const MACROBLOCKD *xd) {
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
......
...@@ -11,12 +11,13 @@ ...@@ -11,12 +11,13 @@
#include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_blockd.h"
void vp9_setup_block_dptrs(MACROBLOCKD *mb) { void vp9_setup_block_dptrs(MACROBLOCKD *mb,
int subsampling_x, int subsampling_y) {
int i; int i;
for (i = 0; i < MAX_MB_PLANE; i++) { for (i = 0; i < MAX_MB_PLANE; i++) {
mb->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC; mb->plane[i].plane_type = i ? PLANE_TYPE_UV : PLANE_TYPE_Y_WITH_DC;
mb->plane[i].subsampling_x = !!i; mb->plane[i].subsampling_x = i ? subsampling_x : 0;
mb->plane[i].subsampling_y = !!i; mb->plane[i].subsampling_y = i ? subsampling_y : 0;
} }
} }
...@@ -132,6 +132,12 @@ typedef struct VP9Common { ...@@ -132,6 +132,12 @@ typedef struct VP9Common {
int last_width; int last_width;
int last_height; int last_height;
// TODO(jkoleszar): this implies chroma ss right now, but could vary per
// plane. Revisit as part of the future change to YV12_BUFFER_CONFIG to
// support additional planes.
int subsampling_x;
int subsampling_y;
YUV_TYPE clr_type; YUV_TYPE clr_type;
CLAMP_TYPE clamp_type; CLAMP_TYPE clamp_type;
......
...@@ -631,13 +631,7 @@ int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest, ...@@ -631,13 +631,7 @@ int vp9_post_proc_frame(VP9_COMMON *oci, YV12_BUFFER_CONFIG *dest,
if (!flags) { if (!flags) {
*dest = *oci->frame_to_show; *dest = *oci->frame_to_show;
/* handle problem with extending borders */
dest->y_width = oci->width;
dest->y_height = oci->height;
dest->uv_height = dest->y_height / 2;
return 0; return 0;
} }
#if ARCH_X86||ARCH_X86_64 #if ARCH_X86||ARCH_X86_64
......
...@@ -929,6 +929,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { ...@@ -929,6 +929,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
pc->version = (data[0] >> 1) & 7; pc->version = (data[0] >> 1) & 7;
pc->show_frame = (data[0] >> 4) & 1; pc->show_frame = (data[0] >> 4) & 1;
scaling_active = (data[0] >> 5) & 1; scaling_active = (data[0] >> 5) & 1;
pc->subsampling_x = (data[0] >> 6) & 1;
pc->subsampling_y = (data[0] >> 7) & 1;
first_partition_size = read_le16(data + 1); first_partition_size = read_le16(data + 1);
if (!read_is_valid(data, first_partition_size, data_end)) if (!read_is_valid(data, first_partition_size, data_end))
...@@ -961,8 +963,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { ...@@ -961,8 +963,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
init_frame(pbi); init_frame(pbi);
// Reset the frame pointers to the current frame size // Reset the frame pointers to the current frame size
vp8_yv12_realloc_frame_buffer(new_fb, pc->width, pc->height, vp9_realloc_frame_buffer(new_fb, pc->width, pc->height,
VP9BORDERINPIXELS); pc->subsampling_x, pc->subsampling_y,
VP9BORDERINPIXELS);
if (vp9_reader_init(&header_bc, data, first_partition_size)) if (vp9_reader_init(&header_bc, data, first_partition_size))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
...@@ -1073,7 +1076,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { ...@@ -1073,7 +1076,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) {
CHECK_MEM_ERROR(pc->last_frame_seg_map, CHECK_MEM_ERROR(pc->last_frame_seg_map,
vpx_calloc((pc->mi_rows * pc->mi_cols), 1)); vpx_calloc((pc->mi_rows * pc->mi_cols), 1));
vp9_setup_block_dptrs(xd); vp9_setup_block_dptrs(xd, pc->subsampling_x, pc->subsampling_y);
// clear out the coeff buffer // clear out the coeff buffer
for (i = 0; i < MAX_MB_PLANE; ++i) for (i = 0; i < MAX_MB_PLANE; ++i)
......
...@@ -1805,6 +1805,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { ...@@ -1805,6 +1805,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) {
int scaling = (pc->width != pc->display_width || int scaling = (pc->width != pc->display_width ||
pc->height != pc->display_height); pc->height != pc->display_height);
int v = (oh.first_partition_length_in_bytes << 8) | int v = (oh.first_partition_length_in_bytes << 8) |
(pc->subsampling_y << 7) |
(pc->subsampling_x << 6) |
(scaling << 5) | (scaling << 5) |
(oh.show_frame << 4) | (oh.show_frame << 4) |
(oh.version << 1) | (oh.version << 1) |
......
...@@ -1423,7 +1423,7 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { ...@@ -1423,7 +1423,7 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_build_block_offsets(x); vp9_build_block_offsets(x);
vp9_setup_block_dptrs(&x->e_mbd); vp9_setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
xd->mode_info_context->mbmi.mode = DC_PRED; xd->mode_info_context->mbmi.mode = DC_PRED;
xd->mode_info_context->mbmi.uv_mode = DC_PRED; xd->mode_info_context->mbmi.uv_mode = DC_PRED;
......
...@@ -489,7 +489,7 @@ void vp9_first_pass(VP9_COMP *cpi) { ...@@ -489,7 +489,7 @@ void vp9_first_pass(VP9_COMP *cpi) {
vp9_build_block_offsets(x); vp9_build_block_offsets(x);
vp9_setup_block_dptrs(&x->e_mbd); vp9_setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
vp9_frame_init_quantizer(cpi); vp9_frame_init_quantizer(cpi);
......
...@@ -46,7 +46,7 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) { ...@@ -46,7 +46,7 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
unsigned int i; unsigned int i;
for (i = 0; i < ctx->max_sz; i++) for (i = 0; i < ctx->max_sz; i++)
vp8_yv12_de_alloc_frame_buffer(&ctx->buf[i].img); vp9_free_frame_buffer(&ctx->buf[i].img);
free(ctx->buf); free(ctx->buf);
} }
free(ctx); free(ctx);
...@@ -56,6 +56,8 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) { ...@@ -56,6 +56,8 @@ void vp9_lookahead_destroy(struct lookahead_ctx *ctx) {
struct lookahead_ctx * vp9_lookahead_init(unsigned int width, struct lookahead_ctx * vp9_lookahead_init(unsigned int width,
unsigned int height, unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
unsigned int depth) { unsigned int depth) {
struct lookahead_ctx *ctx = NULL; struct lookahead_ctx *ctx = NULL;
...@@ -71,8 +73,9 @@ struct lookahead_ctx * vp9_lookahead_init(unsigned int width, ...@@ -71,8 +73,9 @@ struct lookahead_ctx * vp9_lookahead_init(unsigned int width,
if (!ctx->buf) if (!ctx->buf)
goto bail; goto bail;
for (i = 0; i < depth; i++) for (i = 0; i < depth; i++)
if (vp8_yv12_alloc_frame_buffer(&ctx->buf[i].img, if (vp9_alloc_frame_buffer(&ctx->buf[i].img,
width, height, VP9BORDERINPIXELS)) width, height, subsampling_x, subsampling_y,
VP9BORDERINPIXELS))
goto bail; goto bail;
} }
return ctx; return ctx;
......
...@@ -31,6 +31,8 @@ struct lookahead_ctx; ...@@ -31,6 +31,8 @@ struct lookahead_ctx;
*/ */
struct lookahead_ctx *vp9_lookahead_init(unsigned int width, struct lookahead_ctx *vp9_lookahead_init(unsigned int width,
unsigned int height, unsigned int height,
unsigned int subsampling_x,
unsigned int subsampling_y,
unsigned int depth); unsigned int depth);
......
...@@ -313,9 +313,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { ...@@ -313,9 +313,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
vp9_free_frame_buffers(&cpi->common); vp9_free_frame_buffers(&cpi->common);
vp8_yv12_de_alloc_frame_buffer(&cpi->last_frame_uf); vp9_free_frame_buffer(&cpi->last_frame_uf);
vp8_yv12_de_alloc_frame_buffer(&cpi->scaled_source); vp9_free_frame_buffer(&cpi->scaled_source);
vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer); vp9_free_frame_buffer(&cpi->alt_ref_buffer);
vp9_lookahead_destroy(cpi->lookahead); vp9_lookahead_destroy(cpi->lookahead);
vpx_free(cpi->tok); vpx_free(cpi->tok);
...@@ -835,15 +835,19 @@ void vp9_set_speed_features(VP9_COMP *cpi) { ...@@ -835,15 +835,19 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
} }
static void alloc_raw_frame_buffers(VP9_COMP *cpi) { static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
cpi->lookahead = vp9_lookahead_init(cpi->oxcf.width, cpi->oxcf.height, cpi->lookahead = vp9_lookahead_init(cpi->oxcf.width, cpi->oxcf.height,
cm->subsampling_x, cm->subsampling_y,
cpi->oxcf.lag_in_frames); cpi->oxcf.lag_in_frames);
if (!cpi->lookahead) if (!cpi->lookahead)
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate lag buffers"); "Failed to allocate lag buffers");
if (vp8_yv12_alloc_frame_buffer(&cpi->alt_ref_buffer, if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
cpi->oxcf.width, cpi->oxcf.height, cpi->oxcf.width, cpi->oxcf.height,
VP9BORDERINPIXELS)) cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate altref buffer"); "Failed to allocate altref buffer");
} }
...@@ -873,13 +877,17 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { ...@@ -873,13 +877,17 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) {
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate partition data"); "Failed to allocate partition data");
if (vp8_yv12_alloc_frame_buffer(&cpi->last_frame_uf, if (vp9_alloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height, VP9BORDERINPIXELS)) cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate last frame buffer"); "Failed to allocate last frame buffer");
if (vp8_yv12_alloc_frame_buffer(&cpi->scaled_source, if (vp9_alloc_frame_buffer(&cpi->scaled_source,
cm->width, cm->height, VP9BORDERINPIXELS)) cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to allocate scaled source buffer"); "Failed to allocate scaled source buffer");
...@@ -914,13 +922,17 @@ static void update_frame_size(VP9_COMP *cpi) { ...@@ -914,13 +922,17 @@ static void update_frame_size(VP9_COMP *cpi) {
vp9_update_frame_size(cm); vp9_update_frame_size(cm);
// Update size of buffers local to this frame // Update size of buffers local to this frame
if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf, if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
cm->width, cm->height, VP9BORDERINPIXELS)) cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate last frame buffer"); "Failed to reallocate last frame buffer");
if (vp8_yv12_realloc_frame_buffer(&cpi->scaled_source, if (vp9_realloc_frame_buffer(&cpi->scaled_source,
cm->width, cm->height, VP9BORDERINPIXELS)) cm->width, cm->height,
cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS))
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
"Failed to reallocate scaled source buffer"); "Failed to reallocate scaled source buffer");
...@@ -1032,6 +1044,9 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { ...@@ -1032,6 +1044,9 @@ static void init_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
cm->width = oxcf->width; cm->width = oxcf->width;
cm->height = oxcf->height; cm->height = oxcf->height;
cm->subsampling_x = 0;
cm->subsampling_y = 0;
vp9_alloc_compressor_data(cpi);
// change includes all joint functionality // change includes all joint functionality
vp9_change_config(ptr, oxcf); vp9_change_config(ptr, oxcf);
...@@ -1196,17 +1211,13 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { ...@@ -1196,17 +1211,13 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
cm->sharpness_level = cpi->oxcf.Sharpness; cm->sharpness_level = cpi->oxcf.Sharpness;
// Increasing the size of the frame beyond the first seen frame, or some if (cpi->initial_width) {
// otherwise signalled maximum size, is not supported. // Increasing the size of the frame beyond the first seen frame, or some
// TODO(jkoleszar): exit gracefully. // otherwise signalled maximum size, is not supported.
if (!cpi->initial_width) { // TODO(jkoleszar): exit gracefully.
alloc_raw_frame_buffers(cpi); assert(cm->width <= cpi->initial_width);
vp9_alloc_compressor_data(cpi); assert(cm->height <= cpi->initial_height);
cpi->initial_width = cm->width;
cpi->initial_height = cm->height;
} }
assert(cm->width <= cpi->initial_width);
assert(cm->height <= cpi->initial_height);
update_frame_size(cpi); update_frame_size(cpi);
if (cpi->oxcf.fixed_q >= 0) { if (cpi->oxcf.fixed_q >= 0) {
...@@ -2492,9 +2503,10 @@ static void scale_references(VP9_COMP *cpi) { ...@@ -2492,9 +2503,10 @@ static void scale_references(VP9_COMP *cpi) {
ref->y_crop_height != cm->height) { ref->y_crop_height != cm->height) {
int new_fb = get_free_fb(cm); int new_fb = get_free_fb(cm);
vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[new_fb], vp9_realloc_frame_buffer(&cm->yv12_fb[new_fb],
cm->width, cm->height, cm->width, cm->height,
VP9BORDERINPIXELS); cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS);
scale_and_extend_frame(ref, &cm->yv12_fb[new_fb]); scale_and_extend_frame(ref, &cm->yv12_fb[new_fb]);
cpi->scaled_ref_idx[i] = new_fb; cpi->scaled_ref_idx[i] = new_fb;
} else { } else {
...@@ -3579,6 +3591,15 @@ int vp9_receive_raw_frame(VP9_PTR ptr, unsigned int frame_flags, ...@@ -3579,6 +3591,15 @@ int vp9_receive_raw_frame(VP9_PTR ptr, unsigned int frame_flags,
struct vpx_usec_timer timer; struct vpx_usec_timer timer;
int res = 0; int res = 0;
if (!cpi->initial_width) {
// TODO(jkoleszar): Support 1/4 subsampling?
cm->subsampling_x = sd->uv_width < sd->y_width;
cm->subsampling_y = sd->uv_height < sd->y_height;
alloc_raw_frame_buffers(cpi);
cpi->initial_width = cm->width;
cpi->initial_height = cm->height;
}
vpx_usec_timer_start(&timer); vpx_usec_timer_start(&timer);
if (vp9_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, frame_flags, if (vp9_lookahead_push(cpi->lookahead, sd, time_stamp, end_time, frame_flags,
cpi->active_map_enabled ? cpi->active_map : NULL)) cpi->active_map_enabled ? cpi->active_map : NULL))
...@@ -3843,9 +3864,10 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, ...@@ -3843,9 +3864,10 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
cm->frame_flags = *frame_flags; cm->frame_flags = *frame_flags;
// Reset the frame pointers to the current frame size // Reset the frame pointers to the current frame size
vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx], vp9_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx],
cm->width, cm->height, cm->width, cm->height,
VP9BORDERINPIXELS); cm->subsampling_x, cm->subsampling_y,
VP9BORDERINPIXELS);
// Calculate scaling factors for each of the 3 available references // Calculate scaling factors for each of the 3 available references
for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
......
...@@ -211,11 +211,12 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, ...@@ -211,11 +211,12 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
switch (img->fmt) { switch (img->fmt) {
case VPX_IMG_FMT_YV12: case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_I420: case VPX_IMG_FMT_I420:
case VPX_IMG_FMT_VPXI420: case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_VPXYV12: case VPX_IMG_FMT_I444:
break; break;
default: default:
ERROR("Invalid image format. Only YV12 and I420 images are supported"); ERROR("Invalid image format. Only YV12, I420, I422, I444 images are "
"supported.");
} }
if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h)) if ((img->d_w != ctx->cfg.g_w) || (img->d_h != ctx->cfg.g_h))
...@@ -553,14 +554,17 @@ static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, ...@@ -553,14 +554,17 @@ static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
yv12->y_crop_height = img->d_h; yv12->y_crop_height = img->d_h;
yv12->y_width = img->d_w; yv12->y_width = img->d_w;
yv12->y_height = img->d_h; yv12->y_height = img->d_h;
yv12->uv_width = (1 + yv12->y_width) / 2;
yv12->uv_height = (1 + yv12->y_height) / 2; yv12->uv_width = img->x_chroma_shift == 1 ? (1 + yv12->y_width) / 2
: yv12->y_width;
yv12->uv_height = img->y_chroma_shift == 1 ? (1 + yv12->y_height) / 2
: yv12->y_height;
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];
yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2; yv12->border = (img->stride[VPX_PLANE_Y] - img->w) / 2;
yv12->clrtype = (img->fmt == VPX_IMG_FMT_VPXI420 || img->fmt == VPX_IMG_FMT_VPXYV12); // REG_YUV = 0 yv12->clrtype = REG_YUV;
return res; return res;
} }
...@@ -940,39 +944,7 @@ static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx) { ...@@ -940,39 +944,7 @@ static vpx_image_t *vp8e_get_preview(vpx_codec_alg_priv_t *ctx) {
} }
if (0 == vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags)) { if (0 == vp9_get_preview_raw_frame(ctx->cpi, &sd, &flags)) {
yuvconfig2image(&ctx->preview_img, &sd, NULL);
/*
vpx_img_wrap(&ctx->preview_img, VPX_IMG_FMT_YV12,
sd.y_width + 2*VP9BORDERINPIXELS,
sd.y_height + 2*VP9BORDERINPIXELS,
1,
sd.buffer_alloc);
vpx_img_set_rect(&ctx->preview_img,
VP9BORDERINPIXELS, VP9BORDERINPIXELS,
sd.y_width, sd.y_height);
*/
ctx->preview_img.bps = 12;
ctx->preview_img.planes[VPX_PLANE_Y] = sd.y_buffer;
ctx->preview_img.planes[VPX_PLANE_U] = sd.u_buffer;
ctx->preview_img.planes[VPX_PLANE_V] = sd.v_buffer;
if (sd.clrtype == REG_YUV)
ctx->preview_img.fmt = VPX_IMG_FMT_I420;
else
ctx->preview_img.fmt = VPX_IMG_FMT_VPXI420;
ctx->preview_img.x_chroma_shift = 1;
ctx->preview_img.y_chroma_shift = 1;
ctx->preview_img.d_w = sd.y_width;
ctx->preview_img.d_h = sd.y_height;
ctx->preview_img.stride[VPX_PLANE_Y] = sd.y_stride;
ctx->preview_img.stride[VPX_PLANE_U] = sd.uv_stride;
ctx->preview_img.stride[VPX_PLANE_V] = sd.uv_stride;
ctx->preview_img.w = sd.y_width;
ctx->preview_img.h = sd.y_height;
return &ctx->preview_img; return &ctx->preview_img;
} else } else
return NULL; return NULL;
......
...@@ -16,13 +16,24 @@ static void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12, ...@@ -16,13 +16,24 @@ static void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12,
* the Y, U, and V planes, nor other alignment adjustments that * the Y, U, and V planes, nor other alignment adjustments that
* might be representable by a YV12_BUFFER_CONFIG, so we just * might be representable by a YV12_BUFFER_CONFIG, so we just
* initialize all the fields.*/ * initialize all the fields.*/
img->fmt = yv12->clrtype == REG_YUV ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_VPXI420; int bps = 12;
if (yv12->uv_height == yv12->y_height) {
if (yv12->uv_width == yv12->y_width) {
img->fmt = VPX_IMG_FMT_I444;
bps = 24;
} else {
img->fmt = VPX_IMG_FMT_I422;
bps = 16;
}
} else {
img->fmt = VPX_IMG_FMT_I420;
}
img->w = yv12->y_stride; img->w = yv12->y_stride;
img->h = multiple16(yv12->y_height + 2 * VP9BORDERINPIXELS); img->h = multiple16(yv12->y_height + 2 * VP9BORDERINPIXELS);
img->d_w = yv12->y_width; img->d_w = yv12->y_crop_width;
img->d_h = yv12->y_height; img->d_h = yv12->y_crop_height;
img->x_chroma_shift = 1; img->x_chroma_shift = yv12->uv_width < yv12->y_width;
img->y_chroma_shift = 1; img->y_chroma_shift = yv12->uv_height < yv12->y_height;
img->planes[VPX_PLANE_Y] = yv12->y_buffer; img->planes[VPX_PLANE_Y] = yv12->y_buffer;
img->planes[VPX_PLANE_U] = yv12->u_buffer; img->planes[VPX_PLANE_U] = yv12->u_buffer;<