summaryrefslogtreecommitdiff
path: root/vpx_scale
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2013-03-13 17:09:05 -0700
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>2013-03-13 19:10:10 -0700
commit9b7be888839c884451646905bd54b5861aac592b (patch)
treee89260e1a8dc81f15c27f68a8d9368aecf4a3b7c /vpx_scale
parentb3c350a1a99ac89e81cff77d82a9a11c0a762600 (diff)
downloadlibvpx-9b7be888839c884451646905bd54b5861aac592b.tar.gz
libvpx-9b7be888839c884451646905bd54b5861aac592b.tar.bz2
libvpx-9b7be888839c884451646905bd54b5861aac592b.zip
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
Diffstat (limited to 'vpx_scale')
-rw-r--r--vpx_scale/generic/yv12config.c29
-rw-r--r--vpx_scale/generic/yv12extend.c223
-rw-r--r--vpx_scale/yv12config.h2
3 files changed, 80 insertions, 174 deletions
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 @@
/****************************************************************************
*
****************************************************************************/
-void
-vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) {
+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;
- 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;
+ uint8_t *src_ptr1, *src_ptr2;
+ uint8_t *dest_ptr1, *dest_ptr2;
+ int linesize;
/* 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;
+ 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 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;
+ /* 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;
}
-
- /***********/
- /* 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;
+ for (i = 0; i < eb; i++) {
+ vpx_memcpy(dest_ptr2, src_ptr2, linesize);
+ dest_ptr2 += sp;
}
}
-
-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;
-
+void
+vp8_yv12_extend_frame_borders_c(YV12_BUFFER_CONFIG *ybf) {
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
}
-
/****************************************************************************
*
* 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; */