[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