[aravis] gstreamer: fix row stride of gstreamer image buffer.



commit f8af9bdba794701c159ce5fd4379659d3b772c97
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Fri Jan 11 11:17:01 2013 +0100

    gstreamer: fix row stride of gstreamer image buffer.
    
    Gstreamer requires row stride to be a multiple of 4, while
    it's not always the case in aravis buffers. If so, create
    a new data buffer with the right row stride.

 docs/reference/aravis/aravis-sections.txt |    1 +
 gst/gstaravis.c                           |   29 ++++++++++++++++++++++++++---
 src/arvenums.h                            |    2 ++
 viewer/arvviewer.c                        |   29 ++++++++++++++++++++++++++---
 4 files changed, 55 insertions(+), 6 deletions(-)
---
diff --git a/docs/reference/aravis/aravis-sections.txt b/docs/reference/aravis/aravis-sections.txt
index 7340e65..dc9cc9a 100644
--- a/docs/reference/aravis/aravis-sections.txt
+++ b/docs/reference/aravis/aravis-sections.txt
@@ -71,6 +71,7 @@ ArvCameraClass
 <FILE>arvpixelformat</FILE>
 <TITLE>ArvPixelFormat</TITLE>
 ArvPixelFormat
+ARV_PIXEL_FORMAT_BIT_PER_PIXEL
 ARV_PIXEL_FORMAT_BAYER_BG_10
 ARV_PIXEL_FORMAT_BAYER_BG_12
 ARV_PIXEL_FORMAT_BAYER_GR_12_PACKED
diff --git a/gst/gstaravis.c b/gst/gstaravis.c
index 132ffb7..f4046c8 100644
--- a/gst/gstaravis.c
+++ b/gst/gstaravis.c
@@ -314,6 +314,7 @@ gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer)
 {
 	GstAravis *gst_aravis;
 	ArvBuffer *arv_buffer;
+	int arv_row_stride;
 
 	gst_aravis = GST_ARAVIS (push_src);
 
@@ -328,9 +329,31 @@ gst_aravis_create (GstPushSrc * push_src, GstBuffer ** buffer)
 
 	*buffer = gst_buffer_new ();
 
-	GST_BUFFER_DATA (*buffer) = arv_buffer->data;
-	GST_BUFFER_MALLOCDATA (*buffer) = NULL;
-	GST_BUFFER_SIZE (*buffer) = gst_aravis->payload;
+	arv_row_stride = arv_buffer->width * ARV_PIXEL_FORMAT_BIT_PER_PIXEL (arv_buffer->pixel_format) / 8;
+
+	/* Gstreamer requires row stride to be a multiple of 4 */
+	if ((arv_row_stride & 0x3) != 0) {
+		int gst_row_stride;
+		size_t size;
+		void *data;
+		int i;
+
+		gst_row_stride = (arv_row_stride & ~(0x3)) + 4;
+
+		size = arv_buffer->height * gst_row_stride;
+		data = g_malloc (size);	
+
+		for (i = 0; i < arv_buffer->height; i++)
+			memcpy (data + i * gst_row_stride, arv_buffer->data + i * arv_row_stride, arv_row_stride);
+
+		GST_BUFFER_DATA (buffer) = data;
+		GST_BUFFER_MALLOCDATA (buffer) = data;
+		GST_BUFFER_SIZE (buffer) = size;
+	} else {
+		GST_BUFFER_DATA (*buffer) = arv_buffer->data;
+		GST_BUFFER_MALLOCDATA (*buffer) = NULL;
+		GST_BUFFER_SIZE (*buffer) = arv_buffer->size;
+	}
 
 	if (gst_aravis->timestamp_offset == 0) {
 		gst_aravis->timestamp_offset = arv_buffer->timestamp_ns;
diff --git a/src/arvenums.h b/src/arvenums.h
index 4595f52..3770307 100644
--- a/src/arvenums.h
+++ b/src/arvenums.h
@@ -76,6 +76,8 @@ ArvAcquisitionMode 	arv_acquisition_mode_from_string	(const char *string);
 
 typedef guint32 ArvPixelFormat;
 
+#define ARV_PIXEL_FORMAT_BIT_PER_PIXEL(pixel_format) (((pixel_format) >> 16) & 0xff)
+
 /* Grey pixel formats */
 
 #define	ARV_PIXEL_FORMAT_MONO_8			0x01080001
diff --git a/viewer/arvviewer.c b/viewer/arvviewer.c
index 34fdc3d..9ab270c 100644
--- a/viewer/arvviewer.c
+++ b/viewer/arvviewer.c
@@ -155,11 +155,34 @@ arv_viewer_new_buffer_cb (ArvStream *stream, ArvViewer *viewer)
 		return;
 
 	if (arv_buffer->status == ARV_BUFFER_STATUS_SUCCESS) {
+		int arv_row_stride;
 		buffer = gst_buffer_new ();
 
-		GST_BUFFER_DATA (buffer) = arv_buffer->data;
-		GST_BUFFER_MALLOCDATA (buffer) = NULL;
-		GST_BUFFER_SIZE (buffer) = arv_buffer->size;
+		arv_row_stride = arv_buffer->width * ARV_PIXEL_FORMAT_BIT_PER_PIXEL (arv_buffer->pixel_format) / 8;
+
+		/* Gstreamer requires row stride to be a multiple of 4 */
+		if ((arv_row_stride & 0x3) != 0) {
+			int gst_row_stride;
+			size_t size;
+			void *data;
+			int i;
+
+			gst_row_stride = (arv_row_stride & ~(0x3)) + 4;
+
+			size = arv_buffer->height * gst_row_stride;
+			data = g_malloc (size);	
+
+			for (i = 0; i < arv_buffer->height; i++)
+				memcpy (data + i * gst_row_stride, arv_buffer->data + i * arv_row_stride, arv_row_stride);
+
+			GST_BUFFER_DATA (buffer) = data;
+			GST_BUFFER_MALLOCDATA (buffer) = data;
+			GST_BUFFER_SIZE (buffer) = size;
+		} else {
+			GST_BUFFER_DATA (buffer) = arv_buffer->data;
+			GST_BUFFER_MALLOCDATA (buffer) = NULL;
+			GST_BUFFER_SIZE (buffer) = arv_buffer->size;
+		}
 
 		if (viewer->timestamp_offset == 0) {
 			viewer->timestamp_offset = arv_buffer->timestamp_ns;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]