summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2013-07-31 11:54:06 -0700
committerDavid Schleef <ds@schleef.org>2013-08-03 23:29:10 -0700
commitd5f1ddad859fe7435aec717b81f05bc47f8a0a2e (patch)
tree21af00a5936be140e3debfe740657a43cce60fb3 /gst
parent933965984f96ed231f69996ebbdd4adad5da234d (diff)
downloadgstreamer-plugins-bad-d5f1ddad859fe7435aec717b81f05bc47f8a0a2e.tar.gz
ivtc: implement new edge-directed upsampling
Diffstat (limited to 'gst')
-rw-r--r--gst/ivtc/gstivtc.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/gst/ivtc/gstivtc.c b/gst/ivtc/gstivtc.c
index 3ece8e64d..a3775378b 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++) {