From: David Schleef Date: Wed, 31 Jul 2013 18:54:06 +0000 (-0700) Subject: ivtc: implement new edge-directed upsampling X-Git-Tag: 1.19.3~507^2~13215 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d5f1ddad859fe7435aec717b81f05bc47f8a0a2e;p=platform%2Fupstream%2Fgstreamer.git ivtc: implement new edge-directed upsampling --- diff --git a/gst/ivtc/gstivtc.c b/gst/ivtc/gstivtc.c index 3ece8e6..a377537 100644 --- a/gst/ivtc/gstivtc.c +++ b/gst/ivtc/gstivtc.c @@ -351,6 +351,24 @@ reconstruct (GstIvtc * ivtc, GstVideoFrame * dest_frame, int i1, int i2) } +static int +reconstruct_line (guint8 * line1, guint8 * line2, int i, int a, int b, int c, + int d) +{ + int x; + + x = line1[i - 3] * a; + x += line1[i - 2] * b; + x += line1[i - 1] * c; + x += line1[i - 0] * d; + x += line2[i + 0] * d; + x += line2[i + 1] * c; + x += line2[i + 2] * b; + x += line2[i + 3] * a; + return (x + 16) >> 5; +} + + static void reconstruct_single (GstIvtc * ivtc, GstVideoFrame * dest_frame, int i1) { @@ -360,7 +378,77 @@ reconstruct_single (GstIvtc * ivtc, GstVideoFrame * dest_frame, int i1) int width; GstIvtcField *field = &ivtc->fields[i1]; - for (k = 0; k < 3; k++) { + for (k = 0; k < 1; k++) { + height = GST_VIDEO_FRAME_COMP_HEIGHT (dest_frame, k); + width = GST_VIDEO_FRAME_COMP_WIDTH (dest_frame, k); + for (j = 0; j < height; j++) { + if ((j & 1) == field->parity) { + memcpy (GET_LINE (dest_frame, k, j), + GET_LINE (&field->frame, k, j), width); + } else { + if (j == 0 || j == height - 1) { + memcpy (GET_LINE (dest_frame, k, j), + GET_LINE (&field->frame, k, (j ^ 1)), width); + } else { + guint8 *dest = GET_LINE (dest_frame, k, j); + guint8 *line1 = GET_LINE (&field->frame, k, j - 1); + guint8 *line2 = GET_LINE (&field->frame, k, j + 1); + int i; + +#define MARGIN 3 + for (i = MARGIN; i < width - MARGIN; i++) { + int dx, dy; + + dx = -line1[i - 1] - line2[i - 1] + line1[i + 1] + line2[i + 1]; + dx *= 2; + + dy = -line1[i - 1] - 2 * line1[i] - line1[i + 1] + + line2[i - 1] + 2 * line2[i] + line2[i + 1]; + if (dy < 0) { + dy = -dy; + dx = -dx; + } + + if (dx == 0 && dy == 0) { + dest[i] = (line1[i] + line2[i] + 1) >> 1; + } else if (dx < 0) { + if (dx < -2 * dy) { + dest[i] = reconstruct_line (line1, line2, i, 0, 0, 0, 16); + } else if (dx < -dy) { + dest[i] = reconstruct_line (line1, line2, i, 0, 0, 8, 8); + } else if (2 * dx < -dy) { + dest[i] = reconstruct_line (line1, line2, i, 0, 4, 8, 4); + } else if (3 * dx < -dy) { + dest[i] = reconstruct_line (line1, line2, i, 1, 7, 7, 1); + } else { + dest[i] = reconstruct_line (line1, line2, i, 4, 8, 4, 0); + } + } else { + if (dx > 2 * dy) { + dest[i] = reconstruct_line (line2, line1, i, 0, 0, 0, 16); + } else if (dx > dy) { + dest[i] = reconstruct_line (line2, line1, i, 0, 0, 8, 8); + } else if (2 * dx > dy) { + dest[i] = reconstruct_line (line2, line1, i, 0, 4, 8, 4); + } else if (3 * dx > dy) { + dest[i] = reconstruct_line (line2, line1, i, 1, 7, 7, 1); + } else { + dest[i] = reconstruct_line (line2, line1, i, 4, 8, 4, 0); + } + } + } + + for (i = 0; i < MARGIN; i++) { + dest[i] = (line1[i] + line2[i] + 1) >> 1; + } + for (i = width - MARGIN; i < width; i++) { + dest[i] = (line1[i] + line2[i] + 1) >> 1; + } + } + } + } + } + for (k = 1; k < 3; k++) { height = GST_VIDEO_FRAME_COMP_HEIGHT (dest_frame, k); width = GST_VIDEO_FRAME_COMP_WIDTH (dest_frame, k); for (j = 0; j < height; j++) {