diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index db6e03e06..e6e9cddd7 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -1187,6 +1187,38 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { } +static void update_frame_size(VP9_COMP *cpi) { + VP9_COMMON *cm = &cpi->common; + + /* our internal buffers are always multiples of 16 */ + int width = (cm->Width + 15) & ~15; + int height = (cm->Height + 15) & ~15; + + cm->mb_rows = height >> 4; + cm->mb_cols = width >> 4; + cm->MBs = cm->mb_rows * cm->mb_cols; + cm->mode_info_stride = cm->mb_cols + 1; + memset(cm->mip, 0, + (cm->mb_cols + 1) * (cm->mb_rows + 1) * sizeof(MODE_INFO)); + vp9_update_mode_info_border(cm, cm->mip); + + cm->mi = cm->mip + cm->mode_info_stride + 1; + cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1; + vp9_update_mode_info_in_image(cm, cm->mi); + + /* Update size of buffers local to this frame */ + if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf, + width, height, VP9BORDERINPIXELS)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to reallocate last frame buffer"); + + if (vp8_yv12_realloc_frame_buffer(&cpi->scaled_source, + width, height, VP9BORDERINPIXELS)) + vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, + "Failed to reallocate scaled source buffer"); +} + + // TODO perhaps change number of steps expose to outside world when setting // max and min limits. Also this will likely want refining for the extended Q // range. @@ -1482,14 +1514,18 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs; } - if (((cm->Width + 15) & 0xfffffff0) != - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width || - ((cm->Height + 15) & 0xfffffff0) != - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_height || - cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width == 0) { + // Increasing the size of the frame beyond the first seen frame, or some + // otherwise signalled maximum size, is not supported. + // TODO(jkoleszar): exit gracefully. + if (!cpi->initial_width) { alloc_raw_frame_buffers(cpi); vp9_alloc_compressor_data(cpi); + 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); if (cpi->oxcf.fixed_q >= 0) { cpi->last_q[0] = cpi->oxcf.fixed_q; @@ -3954,6 +3990,11 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, cm->fb_idx_ref_cnt[cm->new_fb_idx]--; cm->new_fb_idx = get_free_fb(cm); + /* Reset the frame pointers to the current frame size */ + vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx], + cm->mb_cols * 16, cm->mb_rows * 16, + VP9BORDERINPIXELS); + vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm); if (cpi->pass == 1) { Pass1Encode(cpi, size, dest, frame_flags); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 4c1113ef2..c4442b4aa 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -677,6 +677,8 @@ typedef struct VP9_COMP { unsigned int mb_mv_ref_count[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; #endif + int initial_width; + int initial_height; } VP9_COMP; void vp9_encode_frame(VP9_COMP *cpi); diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index b443ede6f..6f9333521 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ - +#include #include "vp9/common/vp9_onyxc_int.h" #include "vp9/encoder/vp9_onyx_int.h" #include "vp9/encoder/vp9_picklpf.h" @@ -27,6 +27,7 @@ void vp9_yv12_copy_partial_frame_c(YV12_BUFFER_CONFIG *src_ybc, int yoffset; int linestocopy; + assert(src_ybc->y_stride == dst_ybc->y_stride); yheight = src_ybc->y_height; ystride = src_ybc->y_stride; diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c index 4cb2a4190..267d55f40 100644 --- a/vpx_scale/generic/yv12config.c +++ b/vpx_scale/generic/yv12config.c @@ -35,13 +35,8 @@ vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { return 0; } -/**************************************************************************** - * - ****************************************************************************/ -int -vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border) { - /*NOTE:*/ - +int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, + int width, int height, int border) { if (ybf) { int y_stride = ((width + 2 * border) + 31) & ~31; int yplane_size = (height + 2 * border) * y_stride; @@ -51,8 +46,15 @@ vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int * uv_stride == y_stride/2, so enforce this here. */ int uv_stride = y_stride >> 1; int uvplane_size = (uv_height + border) * uv_stride; + const int frame_size = yplane_size + 2 * uvplane_size; - vp8_yv12_de_alloc_frame_buffer(ybf); + if (!ybf->buffer_alloc) { + ybf->buffer_alloc = vpx_memalign(32, frame_size); + ybf->buffer_alloc_sz = frame_size; + } + + if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size) + return -1; /** Only support allocating buffers that have a height and width that * are multiples of 16, and a border that's a multiple of 32. @@ -72,21 +74,23 @@ vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int ybf->uv_stride = uv_stride; ybf->border = border; - ybf->frame_size = yplane_size + 2 * uvplane_size; - - ybf->buffer_alloc = (unsigned char *) vpx_memalign(32, ybf->frame_size); - - if (ybf->buffer_alloc == NULL) - return -1; + ybf->frame_size = frame_size; ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border; ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2 * uv_stride) + border / 2; ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2 * uv_stride) + border / 2; ybf->corrupted = 0; /* assume not currupted by errors */ - } else { - return -2; + return 0; } - - return 0; + return -2; +} + +int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, + int width, int height, int border) { + if (ybf) { + vp8_yv12_de_alloc_frame_buffer(ybf); + return vp8_yv12_realloc_frame_buffer(ybf, width, height, border); + } + return -2; } diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c index 5a427356b..d733bd49d 100644 --- a/vpx_scale/generic/yv12extend.c +++ b/vpx_scale/generic/yv12extend.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ - +#include #include "vpx_scale/yv12config.h" #include "vpx_mem/vpx_mem.h" #include "vpx_scale/vpx_scale.h" @@ -216,6 +216,9 @@ vp8_yv12_copy_frame_c(YV12_BUFFER_CONFIG *src_ybc, int row; unsigned char *source, *dest; + assert(src_ybc->y_width == dst_ybc->y_width); + assert(src_ybc->y_height == dst_ybc->y_height); + source = src_ybc->y_buffer; dest = dst_ybc->y_buffer; diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h index 23be8f3dd..45e57f401 100644 --- a/vpx_scale/yv12config.h +++ b/vpx_scale/yv12config.h @@ -55,6 +55,7 @@ extern "C" { uint8_t *v_buffer; uint8_t *buffer_alloc; + int buffer_alloc_sz; int border; int frame_size; YUV_TYPE clrtype; @@ -65,6 +66,8 @@ extern "C" { int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border); + int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, + int width, int height, int border); int vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf); #ifdef __cplusplus