[gst-cvs] gst-plugins-bad: pnm: Correctly convert from/to GStreamer rowstride

Sebastian Dröge slomo at kemper.freedesktop.org
Sun Sep 13 10:34:15 PDT 2009


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

Author: Sebastian Dröge <sebastian.droege at collabora.co.uk>
Date:   Sun Sep 13 19:33:57 2009 +0200

pnm: Correctly convert from/to GStreamer rowstride

---

 gst/pnm/gstpnmdec.c |   30 ++++++++++++++++++++++++++++--
 gst/pnm/gstpnmenc.c |   18 ++++++++++++++++--
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/gst/pnm/gstpnmdec.c b/gst/pnm/gstpnmdec.c
index d88f295..0d2dd5a 100644
--- a/gst/pnm/gstpnmdec.c
+++ b/gst/pnm/gstpnmdec.c
@@ -59,6 +59,32 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
     GST_STATIC_CAPS (MIME_ALL));
 
 static GstFlowReturn
+gst_pnmdec_push (GstPnmdec * s, GstPad * src, GstBuffer * buf)
+{
+  /* Need to convert from PNM rowstride to GStreamer rowstride */
+  if ((s->mngr.info.type == GST_PNM_TYPE_PIXMAP_ASCII ||
+          s->mngr.info.type == GST_PNM_TYPE_PIXMAP_RAW)
+      && s->mngr.info.width % 4 != 0) {
+    guint i_rowstride = 3 * s->mngr.info.width;
+    guint o_rowstride = GST_ROUND_UP_4 (3 * s->mngr.info.width);
+    GstBuffer *obuf =
+        gst_buffer_new_and_alloc (o_rowstride * s->mngr.info.height);
+    guint i;
+
+    gst_buffer_copy_metadata (obuf, buf, GST_BUFFER_COPY_ALL);
+
+    for (i = 0; i < s->mngr.info.height; i++)
+      memcpy (GST_BUFFER_DATA (obuf) + i * o_rowstride,
+          GST_BUFFER_DATA (buf) + i * i_rowstride, i_rowstride);
+
+    gst_buffer_unref (buf);
+    return gst_pad_push (src, obuf);
+  } else {
+    return gst_pad_push (src, buf);
+  }
+}
+
+static GstFlowReturn
 gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
 {
   GstPnmdec *s = GST_PNMDEC (gst_pad_get_parent (pad));
@@ -121,7 +147,7 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
     memset (&s->mngr, 0, sizeof (GstPnmInfoMngr));
     s->size = 0;
     gst_buffer_set_caps (buf, GST_PAD_CAPS (src));
-    r = gst_pad_push (src, buf);
+    r = gst_pnmdec_push (s, src, buf);
     goto out;
   }
 
@@ -143,7 +169,7 @@ gst_pnmdec_chain (GstPad * pad, GstBuffer * data)
   /* Do we now have the full image? If yes, push. */
   if (GST_BUFFER_SIZE (s->buf) == s->size) {
     gst_buffer_set_caps (s->buf, GST_PAD_CAPS (src));
-    r = gst_pad_push (src, s->buf);
+    r = gst_pnmdec_push (s, src, s->buf);
     s->buf = NULL;
     memset (&s->mngr, 0, sizeof (GstPnmInfoMngr));
     s->size = 0;
diff --git a/gst/pnm/gstpnmenc.c b/gst/pnm/gstpnmenc.c
index 7c4537a..c94ed17 100644
--- a/gst/pnm/gstpnmenc.c
+++ b/gst/pnm/gstpnmenc.c
@@ -79,8 +79,22 @@ gst_pnmenc_chain (GstPad * pad, GstBuffer * buf)
   if ((r = gst_pad_push (s->src, out)) != GST_FLOW_OK)
     goto out;
 
-  /* Pass through the data. */
-  buf = gst_buffer_make_metadata_writable (buf);
+  /* Need to convert from GStreamer rowstride to PNM rowstride */
+  if (s->info.type == GST_PNM_TYPE_PIXMAP_RAW && s->info.width % 4 != 0) {
+    guint i_rowstride = GST_ROUND_UP_4 (s->info.width * 3);
+    guint o_rowstride = s->info.width * 3;
+    GstBuffer *obuf = gst_buffer_new_and_alloc (o_rowstride * s->info.height);
+    guint i;
+
+    for (i = 0; i < s->info.height; i++)
+      memcpy (GST_BUFFER_DATA (obuf) + o_rowstride * i,
+          GST_BUFFER_DATA (buf) + i_rowstride * i, o_rowstride);
+    gst_buffer_unref (buf);
+    buf = obuf;
+  } else {
+    /* Pass through the data. */
+    buf = gst_buffer_make_metadata_writable (buf);
+  }
   gst_buffer_set_caps (buf, GST_PAD_CAPS (s->src));
   r = gst_pad_push (s->src, buf);
 





More information about the Gstreamer-commits mailing list