[gst-cvs] gst-plugins-bad: invtelecine: Add 4:2:2 formats

David Schleef ds at kemper.freedesktop.org
Wed Jun 2 11:31:31 PDT 2010


Module: gst-plugins-bad
Branch: master
Commit: c439a6bc364241400eb35571ceb3458e6aa4f001
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=c439a6bc364241400eb35571ceb3458e6aa4f001

Author: David Schleef <ds at schleef.org>
Date:   Sat May 22 11:30:54 2010 -0700

invtelecine: Add 4:2:2 formats

---

 gst/invtelecine/gstinvtelecine.c |  139 +++++++++++++++++++++++++-------------
 1 files changed, 93 insertions(+), 46 deletions(-)

diff --git a/gst/invtelecine/gstinvtelecine.c b/gst/invtelecine/gstinvtelecine.c
index 4707a31..3bd513c 100644
--- a/gst/invtelecine/gstinvtelecine.c
+++ b/gst/invtelecine/gstinvtelecine.c
@@ -92,7 +92,7 @@ static GstStaticPadTemplate gst_invtelecine_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{YUY2,UYVY,I420,YV12}")
     )
     );
 
@@ -100,7 +100,7 @@ static GstStaticPadTemplate gst_invtelecine_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420")
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{YUY2,UYVY,I420,YV12}")
     )
     );
 
@@ -270,23 +270,52 @@ gst_invtelecine_compare_fields (GstInvtelecine * invtelecine, int field1,
     if (j == 0 || j == invtelecine->height - 1)
       continue;
 
-    data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
-        invtelecine->width * j;
-    data2_1 =
-        GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
-        invtelecine->width * (j - 1);
-    data2_2 =
-        GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
-        invtelecine->width * (j + 1);
+    if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
+        invtelecine->format == GST_VIDEO_FORMAT_YV12) {
+      data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
+          invtelecine->width * j;
+      data2_1 =
+          GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
+          invtelecine->width * (j - 1);
+      data2_2 =
+          GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
+          invtelecine->width * (j + 1);
+
+      /* planar 4:2:0 */
+      linesum = 0;
+      for (i = 1; i < invtelecine->width - 1; i++) {
+        have = data1[i - 1] + data1[i + 1];
+        hdiff = abs (data1[i - 1] - data1[i + 1]);
+        vave = data2_1[i] + data2_2[i];
+        vdiff = abs (data2_1[i] - data2_2[i]);
+        den = MAX (1, MAX (hdiff, vdiff));
+        linesum += (have - vave) * (have - vave) / (den * den);
+      }
+    } else {
+      data1 = GST_BUFFER_DATA (invtelecine->fifo[field1].buffer) +
+          invtelecine->width * 2 * j;
+      data2_1 =
+          GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
+          invtelecine->width * 2 * (j - 1);
+      data2_2 =
+          GST_BUFFER_DATA (invtelecine->fifo[field2].buffer) +
+          invtelecine->width * 2 * (j + 1);
+      if (invtelecine->format == GST_VIDEO_FORMAT_UYVY) {
+        data1++;
+        data2_1++;
+        data2_2++;
+      }
 
-    linesum = 0;
-    for (i = 1; i < invtelecine->width - 1; i++) {
-      have = data1[i - 1] + data1[i + 1];
-      hdiff = abs (data1[i - 1] - data1[i + 1]);
-      vave = data2_1[i] + data2_2[i];
-      vdiff = abs (data2_1[i] - data2_2[i]);
-      den = MAX (1, MAX (hdiff, vdiff));
-      linesum += (have - vave) * (have - vave) / (den * den);
+      /* packed 4:2:2 */
+      linesum = 0;
+      for (i = 1; i < invtelecine->width - 1; i++) {
+        have = data1[(i - 1) * 2] + data1[(i + 1) * 2];
+        hdiff = abs (data1[(i - 1) * 2] - data1[(i + 1) * 2]);
+        vave = data2_1[i * 2] + data2_2[i * 2];
+        vdiff = abs (data2_1[i * 2] - data2_2[i * 2]);
+        den = MAX (1, MAX (hdiff, vdiff));
+        linesum += (have - vave) * (have - vave) / (den * den);
+      }
     }
     sum += linesum;
   }
@@ -669,31 +698,44 @@ gst_invtelecine_process (GstInvtelecine * invtelecine, gboolean flush)
 }
 
 static void
-copy_field (GstBuffer * d, GstBuffer * s, int field_index, int width,
-    int height)
+copy_field (GstInvtelecine * invtelecine, GstBuffer * d, GstBuffer * s,
+    int field_index)
 {
   int j;
   guint8 *dest;
   guint8 *src;
-
-  for (j = field_index; j < height; j += 2) {
-    dest = GST_BUFFER_DATA (d) + j * width;
-    src = GST_BUFFER_DATA (s) + j * width;
-    memcpy (dest, src, width);
-  }
-  for (j = field_index; j < height / 2; j += 2) {
-    dest = GST_BUFFER_DATA (d) + width * height + j * width / 2;
-    src = GST_BUFFER_DATA (s) + width * height + j * width / 2;
-    memcpy (dest, src, width / 2);
-  }
-  for (j = field_index; j < height / 2; j += 2) {
-    dest =
-        GST_BUFFER_DATA (d) + width * height + width / 2 * height / 2 +
-        j * width / 2;
-    src =
-        GST_BUFFER_DATA (s) + width * height + width / 2 * height / 2 +
-        j * width / 2;
-    memcpy (dest, src, width / 2);
+  int width = invtelecine->width;
+  int height = invtelecine->height;
+
+  if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
+      invtelecine->format == GST_VIDEO_FORMAT_YV12) {
+    /* planar 4:2:0 */
+    for (j = field_index; j < height; j += 2) {
+      dest = GST_BUFFER_DATA (d) + j * width;
+      src = GST_BUFFER_DATA (s) + j * width;
+      memcpy (dest, src, width);
+    }
+    for (j = field_index; j < height / 2; j += 2) {
+      dest = GST_BUFFER_DATA (d) + width * height + j * width / 2;
+      src = GST_BUFFER_DATA (s) + width * height + j * width / 2;
+      memcpy (dest, src, width / 2);
+    }
+    for (j = field_index; j < height / 2; j += 2) {
+      dest =
+          GST_BUFFER_DATA (d) + width * height + width / 2 * height / 2 +
+          j * width / 2;
+      src =
+          GST_BUFFER_DATA (s) + width * height + width / 2 * height / 2 +
+          j * width / 2;
+      memcpy (dest, src, width / 2);
+    }
+  } else {
+    /* packed 4:2:2 */
+    for (j = field_index; j < height; j += 2) {
+      dest = GST_BUFFER_DATA (d) + j * width * 2;
+      src = GST_BUFFER_DATA (s) + j * width * 2;
+      memcpy (dest, src, width * 2);
+    }
   }
 }
 
@@ -705,14 +747,19 @@ gst_invtelecine_output_fields (GstInvtelecine * invtelecine, int num_fields)
 
   field_index = invtelecine->fifo[0].field_index;
 
-  buffer =
-      gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 3 /
-      2);
+  if (invtelecine->format == GST_VIDEO_FORMAT_I420 ||
+      invtelecine->format == GST_VIDEO_FORMAT_YV12) {
+    buffer =
+        gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 3 /
+        2);
+  } else {
+    buffer =
+        gst_buffer_new_and_alloc (invtelecine->width * invtelecine->height * 2);
+  }
 
-  copy_field (buffer, invtelecine->fifo[0].buffer, field_index,
-      invtelecine->width, invtelecine->height);
-  copy_field (buffer, invtelecine->fifo[1].buffer, field_index ^ 1,
-      invtelecine->width, invtelecine->height);
+  copy_field (invtelecine, buffer, invtelecine->fifo[0].buffer, field_index);
+  copy_field (invtelecine, buffer, invtelecine->fifo[1].buffer,
+      field_index ^ 1);
 
   gst_buffer_set_caps (buffer, GST_BUFFER_CAPS (invtelecine->fifo[0].buffer));
 





More information about the Gstreamer-commits mailing list