diff mbox

[04/19] dvdspu: add NV12 support

Message ID 1325628171-4803-4-git-send-email-rob@ti.com
State New
Headers show

Commit Message

Rob Clark Jan. 3, 2012, 10:02 p.m. UTC
---
See: https://bugzilla.gnome.org/show_bug.cgi?id=667220

 gst/dvdspu/gstdvdspu-render.c     |   11 +++++++----
 gst/dvdspu/gstdvdspu.c            |   32 ++++++++++++++++++++++----------
 gst/dvdspu/gstdvdspu.h            |    2 ++
 gst/dvdspu/gstspu-pgs.c           |    8 ++------
 gst/dvdspu/gstspu-vobsub-render.c |    8 ++------
 5 files changed, 35 insertions(+), 26 deletions(-)
diff mbox

Patch

diff --git a/gst/dvdspu/gstdvdspu-render.c b/gst/dvdspu/gstdvdspu-render.c
index 7731aed..8e61124 100644
--- a/gst/dvdspu/gstdvdspu-render.c
+++ b/gst/dvdspu/gstdvdspu-render.c
@@ -85,10 +85,13 @@  gstspu_blend_comp_buffers (SpuState * state, guint8 * planes[3])
      * inverse alpha is (4 * 0xff) - in_A[x] */
     guint16 inv_A = (4 * 0xff) - in_A[x];
 
-    tmp = in_U[x] + inv_A * out_U[x];
-    out_U[x] = (guint8) (tmp / (4 * 0xff));
+    tmp = in_U[x] + inv_A * *out_U;
+    *out_U = (guint8) (tmp / (4 * 0xff));
 
-    tmp = in_V[x] + inv_A * out_V[x];
-    out_V[x] = (guint8) (tmp / (4 * 0xff));
+    tmp = in_V[x] + inv_A * *out_V;
+    *out_V = (guint8) (tmp / (4 * 0xff));
+
+    out_U += state->UV_pixstride;
+    out_V += state->UV_pixstride;
   }
 }
diff --git a/gst/dvdspu/gstdvdspu.c b/gst/dvdspu/gstdvdspu.c
index 89b63d8..c1b97f3 100644
--- a/gst/dvdspu/gstdvdspu.c
+++ b/gst/dvdspu/gstdvdspu.c
@@ -55,7 +55,7 @@  static GstStaticPadTemplate video_sink_factory =
 GST_STATIC_PAD_TEMPLATE ("video",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+    GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420, NV12 }, "
         "width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
     /* FIXME: Can support YV12 one day too */
     );
@@ -63,7 +63,7 @@  GST_STATIC_PAD_TEMPLATE ("video",
 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420 }, "
+    GST_STATIC_CAPS ("video/x-raw-yuv, " "format = (fourcc) { I420, NV12 }, "
         "width = (int) [ 16, 4096 ], " "height = (int) [ 16, 4096 ]")
     /* FIXME: Can support YV12 one day too */
     );
@@ -320,13 +320,15 @@  gst_dvd_spu_video_set_caps (GstPad * pad, GstCaps * caps)
   gint w, h;
   gint i;
   gint fps_n, fps_d;
+  guint32 format;
   SpuState *state;
 
   s = gst_caps_get_structure (caps, 0);
 
   if (!gst_structure_get_int (s, "width", &w) ||
       !gst_structure_get_int (s, "height", &h) ||
-      !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
+      !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d) ||
+      !gst_structure_get_fourcc (s, "format", &format)) {
     goto done;
   }
 
@@ -341,14 +343,24 @@  gst_dvd_spu_video_set_caps (GstPad * pad, GstCaps * caps)
   state->Y_height = GST_ROUND_UP_2 (h);
   state->UV_height = state->Y_height / 2;
 
-  if (state->vid_width != w) {
-    state->vid_width = w;
-    state->Y_stride = GST_ROUND_UP_4 (w);
+  state->vid_width = w;
+  state->Y_stride = GST_ROUND_UP_4 (w);
+
+  state->U_offset  = state->Y_height * state->Y_stride;
+
+  if (format == GST_STR_FOURCC("NV12")) {
+    state->UV_stride = GST_ROUND_UP_4 (state->Y_stride);
+    state->V_offset  = 1;
+    state->UV_pixstride = 2;
+  } else {
     state->UV_stride = GST_ROUND_UP_4 (state->Y_stride / 2);
-    for (i = 0; i < 3; i++) {
-      state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
-          sizeof (guint32) * state->UV_stride);
-    }
+    state->V_offset  = state->UV_stride * state->UV_height;
+    state->UV_pixstride = 1;
+  }
+
+  for (i = 0; i < 3; i++) {
+	  state->comp_bufs[i] = g_realloc (state->comp_bufs[i],
+			  sizeof (guint32) * state->UV_stride);
   }
   DVD_SPU_UNLOCK (dvdspu);
 
diff --git a/gst/dvdspu/gstdvdspu.h b/gst/dvdspu/gstdvdspu.h
index 22b48d1..d78f60f 100644
--- a/gst/dvdspu/gstdvdspu.h
+++ b/gst/dvdspu/gstdvdspu.h
@@ -73,6 +73,8 @@  struct SpuState {
   gint16 vid_width, vid_height;
   gint16 Y_stride, UV_stride;
   gint16 Y_height, UV_height;
+  gint32 U_offset, V_offset;
+  gint8  UV_pixstride;
 
   guint32 *comp_bufs[3]; /* Compositing buffers for U+V & A */
   guint16 comp_left;
diff --git a/gst/dvdspu/gstspu-pgs.c b/gst/dvdspu/gstspu-pgs.c
index b860b29..abfa539 100644
--- a/gst/dvdspu/gstspu-pgs.c
+++ b/gst/dvdspu/gstspu-pgs.c
@@ -194,12 +194,8 @@  pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state,
 
   /* Store the start of each plane */
   planes[0] = GST_BUFFER_DATA (dest_buf);
-  planes[1] = planes[0] + (state->Y_height * state->Y_stride);
-  planes[2] = planes[1] + (state->UV_height * state->UV_stride);
-
-  /* Sanity check */
-  g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
-      GST_BUFFER_DATA (dest_buf) + GST_BUFFER_SIZE (dest_buf));
+  planes[1] = planes[0] + state->U_offset;
+  planes[2] = planes[1] + state->V_offset;
 
   y = MIN (obj->y, state->Y_height);
 
diff --git a/gst/dvdspu/gstspu-vobsub-render.c b/gst/dvdspu/gstspu-vobsub-render.c
index 830017d..b945592 100644
--- a/gst/dvdspu/gstspu-vobsub-render.c
+++ b/gst/dvdspu/gstspu-vobsub-render.c
@@ -396,12 +396,8 @@  gstspu_vobsub_render (GstDVDSpu * dvdspu, GstBuffer * buf)
 
   /* Store the start of each plane */
   planes[0] = GST_BUFFER_DATA (buf);
-  planes[1] = planes[0] + (state->Y_height * state->Y_stride);
-  planes[2] = planes[1] + (state->UV_height * state->UV_stride);
-
-  /* Sanity check */
-  g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
-      GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf));
+  planes[1] = planes[0] + state->U_offset;
+  planes[2] = planes[1] + state->V_offset;
 
   GST_DEBUG_OBJECT (dvdspu,
       "Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",