From 9b7be888839c884451646905bd54b5861aac592b Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Wed, 13 Mar 2013 17:09:05 -0700 Subject: [PATCH] Fix pulsing issue with scaling Updates the YV12_BUFFER_CONFIG structure to be crop-aware. The exiting width/height parameters are left unchanged, storing the width and height algined to a 16 byte boundary. The cropped dimensions are added as new fields. This fixes a nasty visual pulse when switching between scaled and unscaled frame dimensions due to a mismatch between the scaling ratio and the 16-byte aligned sizes. Change-Id: Id4a3f6aea6b9b9ae38bdfa1b87b7eb2cfcdd57b6 --- vp9/common/vp9_alloccommon.c | 13 +- vp9/common/vp9_reconinter.c | 6 +- vp9/decoder/vp9_decodframe.c | 2 +- vp9/encoder/vp9_lookahead.c | 4 - vp9/encoder/vp9_onyx_if.c | 54 +++---- vp9/encoder/vp9_onyx_int.h | 2 - vp9/encoder/vp9_picklpf.c | 2 +- vp9/encoder/vp9_rdopt.c | 8 +- vp9/encoder/vp9_temporal_filter.c | 4 +- vp9/vp9_cx_iface.c | 2 + vp9/vp9_dx_iface.c | 2 + vpx_scale/generic/yv12config.c | 29 ++-- vpx_scale/generic/yv12extend.c | 233 +++++++++--------------------- vpx_scale/yv12config.h | 2 + vpxdec.c | 2 +- 15 files changed, 126 insertions(+), 239 deletions(-) diff --git a/vp9/common/vp9_alloccommon.c b/vp9/common/vp9_alloccommon.c index c3d6dae93..15c8c0d64 100644 --- a/vp9/common/vp9_alloccommon.c +++ b/vp9/common/vp9_alloccommon.c @@ -67,16 +67,13 @@ void vp9_de_alloc_frame_buffers(VP9_COMMON *oci) { int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { int i; + int aligned_width, aligned_height; vp9_de_alloc_frame_buffers(oci); /* our internal buffers are always multiples of 16 */ - if ((width & 0xf) != 0) - width += 16 - (width & 0xf); - - if ((height & 0xf) != 0) - height += 16 - (height & 0xf); - + aligned_width = (width + 15) & ~15; + aligned_height = (height + 15) & ~15; for (i = 0; i < NUM_YV12_BUFFERS; i++) { oci->fb_idx_ref_cnt[i] = 0; @@ -110,8 +107,8 @@ int vp9_alloc_frame_buffers(VP9_COMMON *oci, int width, int height) { return 1; } - oci->mb_rows = height >> 4; - oci->mb_cols = width >> 4; + oci->mb_rows = aligned_height >> 4; + oci->mb_cols = aligned_width >> 4; oci->MBs = oci->mb_rows * oci->mb_cols; oci->mode_info_stride = oci->mb_cols + 1; oci->mip = vpx_calloc((oci->mb_cols + 1) * (oci->mb_rows + 1), sizeof(MODE_INFO)); diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index a0867ae7f..f98ec442d 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -20,8 +20,8 @@ void vp9_setup_scale_factors_for_frame(struct scale_factors *scale, YV12_BUFFER_CONFIG *other, int this_w, int this_h) { - int other_h = other->y_height; - int other_w = other->y_width; + int other_h = other->y_crop_height; + int other_w = other->y_crop_width; scale->x_num = other_w; scale->x_den = this_w; @@ -95,7 +95,7 @@ void vp9_setup_interp_filters(MACROBLOCKD *xd, vp9_setup_scale_factors_for_frame(&cm->active_ref_scale[i], &cm->yv12_fb[cm->active_ref_idx[i]], - cm->mb_cols * 16, cm->mb_rows * 16); + cm->Width, cm->Height); } if (xd->mode_info_context) { diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 572ba2905..a3324731e 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -1367,7 +1367,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) { /* Reset the frame pointers to the current frame size */ vp8_yv12_realloc_frame_buffer(&pc->yv12_fb[pc->new_fb_idx], - pc->mb_cols * 16, pc->mb_rows * 16, + pc->Width, pc->Height, VP9BORDERINPIXELS); if (vp9_start_decode(&header_bc, data, diff --git a/vp9/encoder/vp9_lookahead.c b/vp9/encoder/vp9_lookahead.c index 2214ac99b..a89d2547e 100644 --- a/vp9/encoder/vp9_lookahead.c +++ b/vp9/encoder/vp9_lookahead.c @@ -62,10 +62,6 @@ struct lookahead_ctx * vp9_lookahead_init(unsigned int width, // Clamp the lookahead queue depth depth = clamp(depth, 1, MAX_LAG_BUFFERS); - // Align the buffer dimensions - width = (width + 15) &~15; - height = (height + 15) &~15; - // Allocate the lookahead structures ctx = calloc(1, sizeof(*ctx)); if (ctx) { diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 19456e44f..5e4b4915b 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -873,9 +873,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) { } static void alloc_raw_frame_buffers(VP9_COMP *cpi) { - int width = (cpi->oxcf.Width + 15) & ~15; - int height = (cpi->oxcf.Height + 15) & ~15; - cpi->lookahead = vp9_lookahead_init(cpi->oxcf.Width, cpi->oxcf.Height, cpi->oxcf.lag_in_frames); if (!cpi->lookahead) @@ -885,7 +882,8 @@ static void alloc_raw_frame_buffers(VP9_COMP *cpi) { #if VP9_TEMPORAL_ALT_REF if (vp8_yv12_alloc_frame_buffer(&cpi->alt_ref_buffer, - width, height, VP9BORDERINPIXELS)) + cpi->oxcf.Width, cpi->oxcf.Height, + VP9BORDERINPIXELS)) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate altref buffer"); @@ -909,10 +907,7 @@ static int alloc_partition_data(VP9_COMP *cpi) { void vp9_alloc_compressor_data(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; - int width = cm->Width; - int height = cm->Height; - - if (vp9_alloc_frame_buffers(cm, width, height)) + if (vp9_alloc_frame_buffers(cm, cm->Width, cm->Height)) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate frame buffers"); @@ -920,21 +915,13 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) { vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate partition data"); - - if ((width & 0xf) != 0) - width += 16 - (width & 0xf); - - if ((height & 0xf) != 0) - height += 16 - (height & 0xf); - - if (vp8_yv12_alloc_frame_buffer(&cpi->last_frame_uf, - width, height, VP9BORDERINPIXELS)) + cm->Width, cm->Height, VP9BORDERINPIXELS)) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate last frame buffer"); if (vp8_yv12_alloc_frame_buffer(&cpi->scaled_source, - width, height, VP9BORDERINPIXELS)) + cm->Width, cm->Height, VP9BORDERINPIXELS)) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to allocate scaled source buffer"); @@ -996,11 +983,11 @@ 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; + int aligned_width = (cm->Width + 15) & ~15; + int aligned_height = (cm->Height + 15) & ~15; - cm->mb_rows = height >> 4; - cm->mb_cols = width >> 4; + cm->mb_rows = aligned_height >> 4; + cm->mb_cols = aligned_width >> 4; cm->MBs = cm->mb_rows * cm->mb_cols; cm->mode_info_stride = cm->mb_cols + 1; memset(cm->mip, 0, @@ -1013,12 +1000,12 @@ static void update_frame_size(VP9_COMP *cpi) { /* Update size of buffers local to this frame */ if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf, - width, height, VP9BORDERINPIXELS)) + cm->Width, cm->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)) + cm->Width, cm->Height, VP9BORDERINPIXELS)) vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR, "Failed to reallocate scaled source buffer"); @@ -1315,9 +1302,6 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { cm->Width = cpi->oxcf.Width; cm->Height = cpi->oxcf.Height; - cm->horiz_scale = cpi->horiz_scale; - cm->vert_scale = cpi->vert_scale; - // VP8 sharpness level mapping 0-7 (vs 0-10 in general VPx dialogs) if (cpi->oxcf.Sharpness > 7) cpi->oxcf.Sharpness = 7; @@ -2223,10 +2207,10 @@ void vp9_write_yuv_rec_frame(VP9_COMMON *cm) { static void scale_and_extend_frame(YV12_BUFFER_CONFIG *src_fb, YV12_BUFFER_CONFIG *dst_fb) { - const int in_w = src_fb->y_width; - const int in_h = src_fb->y_height; - const int out_w = dst_fb->y_width; - const int out_h = dst_fb->y_height; + const int in_w = src_fb->y_crop_width; + const int in_h = src_fb->y_crop_height; + const int out_w = dst_fb->y_crop_width; + const int out_h = dst_fb->y_crop_height; int x, y; for (y = 0; y < out_h; y += 16) { @@ -2628,12 +2612,12 @@ static void scale_references(VP9_COMP *cpi) { for (i = 0; i < 3; i++) { YV12_BUFFER_CONFIG *ref = &cm->yv12_fb[cm->ref_frame_map[i]]; - if (ref->y_width != cm->mb_cols * 16 || ref->y_height != cm->mb_rows * 16) { + if (ref->y_crop_width != cm->Width || + ref->y_crop_height != cm->Height) { int new_fb = get_free_fb(cm); vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[new_fb], - cm->mb_cols * 16, - cm->mb_rows * 16, + cm->Width, cm->Height, VP9BORDERINPIXELS); scale_and_extend_frame(ref, &cm->yv12_fb[new_fb]); cpi->scaled_ref_idx[i] = new_fb; @@ -3912,7 +3896,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, /* 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, + cm->Width, cm->Height, VP9BORDERINPIXELS); vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 300e12869..a7a07b393 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -545,8 +545,6 @@ typedef struct VP9_COMP { int goldfreq; int auto_worst_q; int cpu_used; - int horiz_scale; - int vert_scale; int pass; vp9_prob last_skip_false_probs[3][MBSKIP_CONTEXTS]; diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c index 6f9333521..d80ea02c1 100644 --- a/vp9/encoder/vp9_picklpf.c +++ b/vp9/encoder/vp9_picklpf.c @@ -247,7 +247,7 @@ void vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi) { int Bias = 0; // Bias against raising loop filter and in favour of lowering it // Make a copy of the unfiltered / processed recon buffer - vp8_yv12_copy_frame(cm->frame_to_show, &cpi->last_frame_uf); + vp8_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf); if (cm->frame_type == KEY_FRAME) cm->sharpness_level = 0; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 3004d6bf3..387e32583 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -3444,9 +3444,11 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, // Further refinement that is encode side only to test the top few candidates // in full and choose the best as the centre point for subsequent searches. - mv_pred(cpi, x, yv12_mb[frame_type].y_buffer, yv12->y_stride, - frame_type, block_size); - + // The current implementation doesn't support scaling. + if (scale[frame_type].x_num == scale[frame_type].x_den && + scale[frame_type].y_num == scale[frame_type].y_den) + mv_pred(cpi, x, yv12_mb[frame_type].y_buffer, yv12->y_stride, + frame_type, block_size); } static void model_rd_from_var_lapndz(int var, int n, int qstep, diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index a6cd1c0c3..7bfca5590 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -459,8 +459,8 @@ void vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) { // Setup scaling factors. Scaling on each of the arnr frames is not supported vp9_setup_scale_factors_for_frame(&cpi->mb.e_mbd.scale_factor[0], &cpi->common.yv12_fb[cpi->common.new_fb_idx], - 16 * cpi->common.mb_cols, - 16 * cpi->common.mb_rows); + cpi->common.Width, + cpi->common.Height); cpi->mb.e_mbd.scale_factor_uv[0] = cpi->mb.e_mbd.scale_factor[0]; // Setup frame pointers, NULL indicates frame not included in filter diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index c0828acdb..1eeec6b5a 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -545,6 +545,8 @@ static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, yv12->u_buffer = img->planes[VPX_PLANE_U]; yv12->v_buffer = img->planes[VPX_PLANE_V]; + yv12->y_crop_width = img->d_w; + yv12->y_crop_height = img->d_h; yv12->y_width = img->d_w; yv12->y_height = img->d_h; yv12->uv_width = (1 + yv12->y_width) / 2; diff --git a/vp9/vp9_dx_iface.c b/vp9/vp9_dx_iface.c index 655d25b69..66c89b5a9 100644 --- a/vp9/vp9_dx_iface.c +++ b/vp9/vp9_dx_iface.c @@ -584,6 +584,8 @@ static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img, yv12->u_buffer = img->planes[VPX_PLANE_U]; yv12->v_buffer = img->planes[VPX_PLANE_V]; + yv12->y_crop_width = img->d_w; + yv12->y_crop_height = img->d_h; yv12->y_width = img->d_w; yv12->y_height = img->d_h; yv12->uv_width = yv12->y_width / 2; diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c index 267d55f40..fc7f82881 100644 --- a/vpx_scale/generic/yv12config.c +++ b/vpx_scale/generic/yv12config.c @@ -38,10 +38,12 @@ vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) { 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; - int uv_width = width >> 1; - int uv_height = height >> 1; + int aligned_width = (width + 15) & ~15; + int aligned_height = (height + 15) & ~15; + int y_stride = ((aligned_width + 2 * border) + 31) & ~31; + int yplane_size = (aligned_height + 2 * border) * y_stride; + int uv_width = aligned_width >> 1; + int uv_height = aligned_height >> 1; /** There is currently a bunch of code which assumes * uv_stride == y_stride/2, so enforce this here. */ int uv_stride = y_stride >> 1; @@ -56,17 +58,18 @@ int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, 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. - * The border restriction is required to get 16-byte alignment of the - * start of the chroma rows without intoducing an arbitrary gap - * between planes, which would break the semantics of things like - * vpx_img_set_rect(). */ - if ((width & 0xf) | (height & 0xf) | (border & 0x1f)) + /* Only support allocating buffers that have a border that's a multiple + * of 32. The border restriction is required to get 16-byte alignment of + * the start of the chroma rows without intoducing an arbitrary gap + * between planes, which would break the semantics of things like + * vpx_img_set_rect(). */ + if (border & 0x1f) return -3; - ybf->y_width = width; - ybf->y_height = height; + ybf->y_crop_width = width; + ybf->y_crop_height = height; + ybf->y_width = aligned_width; + ybf->y_height = aligned_height; ybf->y_stride = y_stride; ybf->uv_width = uv_width; diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c index d733bd49d..49d7e8e56 100644 --- a/vpx_scale/generic/yv12extend.c +++ b/vpx_scale/generic/yv12extend.c @@ -20,180 +20,81 @@ /**************************************************************************** * ****************************************************************************/ +static void extend_plane(uint8_t *s, /* source */ + int sp, /* source pitch */ + int w, /* width */ + int h, /* height */ + int et, /* extend top border */ + int el, /* extend left border */ + int eb, /* extend bottom border */ + int er) { /* extend right border */ + int i; + uint8_t *src_ptr1, *src_ptr2; + uint8_t *dest_ptr1, *dest_ptr2; + int linesize; + + /* copy the left and right most columns out */ + src_ptr1 = s; + src_ptr2 = s + w - 1; + dest_ptr1 = s - el; + dest_ptr2 = s + w; + + for (i = 0; i < h; i++) { + vpx_memset(dest_ptr1, src_ptr1[0], el); + vpx_memset(dest_ptr2, src_ptr2[0], er); + src_ptr1 += sp; + src_ptr2 += sp; + dest_ptr1 += sp; + dest_ptr2 += sp; + } + + /* Now copy the top and bottom lines into each line of the respective + * borders + */ + src_ptr1 = s - el; + src_ptr2 = s + sp * (h - 1) - el; + dest_ptr1 = s + sp * (-et) - el; + dest_ptr2 = s + sp * (h) - el; + linesize = el + er + w; + + for (i = 0; i < et; i++) { + vpx_memcpy(dest_ptr1, src_ptr1, linesize); + dest_ptr1 += sp; + } + + for (i = 0; i < eb; i++) { + vpx_memcpy(dest_ptr2, src_ptr2, linesize); + dest_ptr2 += sp; + } +} + void vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) { - int i; - unsigned char *src_ptr1, *src_ptr2; - unsigned char *dest_ptr1, *dest_ptr2; + assert(ybf->y_height - ybf->y_crop_height < 16); + assert(ybf->y_width - ybf->y_crop_width < 16); + assert(ybf->y_height - ybf->y_crop_height >= 0); + assert(ybf->y_width - ybf->y_crop_width >= 0); - unsigned int Border; - int plane_stride; - int plane_height; - int plane_width; + extend_plane(ybf->y_buffer, ybf->y_stride, + ybf->y_crop_width, ybf->y_crop_height, + ybf->border, ybf->border, + ybf->border + ybf->y_height - ybf->y_crop_height, + ybf->border + ybf->y_width - ybf->y_crop_width); - /***********/ - /* Y Plane */ - /***********/ - Border = ybf->border; - plane_stride = ybf->y_stride; - plane_height = ybf->y_height; - plane_width = ybf->y_width; + extend_plane(ybf->u_buffer, ybf->uv_stride, + (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, + ybf->border / 2, ybf->border / 2, + (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, + (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); - /* copy the left and right most columns out */ - src_ptr1 = ybf->y_buffer; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; i++) { - vpx_memset(dest_ptr1, src_ptr1[0], Border); - vpx_memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /* Now copy the top and bottom source lines into each line of the respective borders */ - src_ptr1 = ybf->y_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)Border; i++) { - vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); - vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - - /***********/ - /* U Plane */ - /***********/ - plane_stride = ybf->uv_stride; - plane_height = ybf->uv_height; - plane_width = ybf->uv_width; - Border /= 2; - - /* copy the left and right most columns out */ - src_ptr1 = ybf->u_buffer; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; i++) { - vpx_memset(dest_ptr1, src_ptr1[0], Border); - vpx_memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /* Now copy the top and bottom source lines into each line of the respective borders */ - src_ptr1 = ybf->u_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)(Border); i++) { - vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); - vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /***********/ - /* V Plane */ - /***********/ - - /* copy the left and right most columns out */ - src_ptr1 = ybf->v_buffer; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; i++) { - vpx_memset(dest_ptr1, src_ptr1[0], Border); - vpx_memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /* Now copy the top and bottom source lines into each line of the respective borders */ - src_ptr1 = ybf->v_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)(Border); i++) { - vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); - vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } + extend_plane(ybf->v_buffer, ybf->uv_stride, + (ybf->y_crop_width + 1) / 2, (ybf->y_crop_height + 1) / 2, + ybf->border / 2, ybf->border / 2, + (ybf->border + ybf->y_height - ybf->y_crop_height + 1) / 2, + (ybf->border + ybf->y_width - ybf->y_crop_width + 1) / 2); } -static void -extend_frame_borders_yonly_c(YV12_BUFFER_CONFIG *ybf) { - int i; - unsigned char *src_ptr1, *src_ptr2; - unsigned char *dest_ptr1, *dest_ptr2; - - unsigned int Border; - int plane_stride; - int plane_height; - int plane_width; - - /***********/ - /* Y Plane */ - /***********/ - Border = ybf->border; - plane_stride = ybf->y_stride; - plane_height = ybf->y_height; - plane_width = ybf->y_width; - - /* copy the left and right most columns out */ - src_ptr1 = ybf->y_buffer; - src_ptr2 = src_ptr1 + plane_width - 1; - dest_ptr1 = src_ptr1 - Border; - dest_ptr2 = src_ptr2 + 1; - - for (i = 0; i < plane_height; i++) { - vpx_memset(dest_ptr1, src_ptr1[0], Border); - vpx_memset(dest_ptr2, src_ptr2[0], Border); - src_ptr1 += plane_stride; - src_ptr2 += plane_stride; - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - /* Now copy the top and bottom source lines into each line of the respective borders */ - src_ptr1 = ybf->y_buffer - Border; - src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride; - dest_ptr1 = src_ptr1 - (Border * plane_stride); - dest_ptr2 = src_ptr2 + plane_stride; - - for (i = 0; i < (int)Border; i++) { - vpx_memcpy(dest_ptr1, src_ptr1, plane_stride); - vpx_memcpy(dest_ptr2, src_ptr2, plane_stride); - dest_ptr1 += plane_stride; - dest_ptr2 += plane_stride; - } - - plane_stride /= 2; - plane_height /= 2; - plane_width /= 2; - Border /= 2; - -} - - - /**************************************************************************** * * ROUTINE : vp8_yv12_copy_frame diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h index 45e57f401..14b6e278b 100644 --- a/vpx_scale/yv12config.h +++ b/vpx_scale/yv12config.h @@ -42,6 +42,8 @@ extern "C" { typedef struct yv12_buffer_config { int y_width; int y_height; + int y_crop_width; + int y_crop_height; int y_stride; /* int yinternal_width; */ diff --git a/vpxdec.c b/vpxdec.c index 30196ecc8..287e796ae 100644 --- a/vpxdec.c +++ b/vpxdec.c @@ -711,7 +711,7 @@ int main(int argc, const char **argv_) { struct input_ctx input = {0}; int frames_corrupted = 0; int dec_flags = 0; - int do_scale; + int do_scale = 0; int stream_w = 0, stream_h = 0; vpx_image_t *scaled_img = NULL;