x11: fix alignment in non-XSHM case
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 10 Aug 2012 14:58:47 +0000 (16:58 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 10 Aug 2012 14:58:47 +0000 (16:58 +0200)
Align the allocated memory to 16 bytes. When doing XSHM we are already aligned
to a page boundary but without, we use plain g_malloc, which could allocate
aligned on 8 bytes only.

See https://bugzilla.gnome.org/show_bug.cgi?id=680796

sys/ximage/ximagepool.c
sys/xvimage/xvimagepool.c

index e0f41d4..85f7d2d 100644 (file)
@@ -100,7 +100,7 @@ gst_buffer_add_ximage_meta (GstBuffer * buffer, GstXImageBufferPool * xpool)
   gboolean success = FALSE;
   GstXContext *xcontext;
   GstXImageMeta *meta;
-  gint width, height;
+  gint width, height, align = 15, offset;
   GstXImageBufferPoolPrivate *priv;
 
   priv = xpool->priv;
@@ -165,7 +165,8 @@ gst_buffer_add_ximage_meta (GstBuffer * buffer, GstXImageBufferPool * xpool)
         meta->size, width, meta->ximage->bytes_per_line);
 
     /* get shared memory */
-    meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
+    meta->SHMInfo.shmid =
+        shmget (IPC_PRIVATE, meta->size + align, IPC_CREAT | 0777);
     if (meta->SHMInfo.shmid == -1)
       goto shmget_failed;
 
@@ -218,7 +219,7 @@ gst_buffer_add_ximage_meta (GstBuffer * buffer, GstXImageBufferPool * xpool)
     allocsize =
         GST_ROUND_UP_4 (meta->ximage->bytes_per_line) * meta->ximage->height;
 
-    meta->ximage->data = g_malloc (allocsize);
+    meta->ximage->data = g_malloc (allocsize + align);
     GST_LOG_OBJECT (ximagesink,
         "non-XShm image size is %" G_GSIZE_FORMAT " (alloced: %u), width %d, "
         "stride %d", meta->size, allocsize, width,
@@ -227,13 +228,19 @@ gst_buffer_add_ximage_meta (GstBuffer * buffer, GstXImageBufferPool * xpool)
     XSync (xcontext->disp, FALSE);
   }
 
+  if ((offset = ((guintptr) meta->ximage->data & align)))
+    offset = (align + 1) - offset;
+
+  GST_DEBUG_OBJECT (ximagesink, "memory %p, align %d, offset %d",
+      meta->ximage->data, align, offset);
+
   /* Reset error handler */
   error_caught = FALSE;
   XSetErrorHandler (handler);
 
   gst_buffer_append_memory (buffer,
       gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->ximage->data,
-          meta->size, 0, meta->size, NULL, NULL));
+          meta->size + align, offset, meta->size, NULL, NULL));
 
   g_mutex_unlock (ximagesink->x_lock);
 
index 5be8d6b..435fc22 100644 (file)
@@ -103,7 +103,7 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
   gboolean success = FALSE;
   GstXContext *xcontext;
   GstXvImageMeta *meta;
-  gint width, height, im_format;
+  gint width, height, im_format, align = 15, offset;
   GstXvImageBufferPoolPrivate *priv;
 
   priv = xvpool->priv;
@@ -220,7 +220,8 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
     }
 
     /* get shared memory */
-    meta->SHMInfo.shmid = shmget (IPC_PRIVATE, meta->size, IPC_CREAT | 0777);
+    meta->SHMInfo.shmid =
+        shmget (IPC_PRIVATE, meta->size + align, IPC_CREAT | 0777);
     if (meta->SHMInfo.shmid == -1)
       goto shmget_failed;
 
@@ -256,18 +257,24 @@ gst_buffer_add_xvimage_meta (GstBuffer * buffer, GstXvImageBufferPool * xvpool)
 
     /* we have to use the returned data_size for our image size */
     meta->size = meta->xvimage->data_size;
-    meta->xvimage->data = g_malloc (meta->size);
+    meta->xvimage->data = g_malloc (meta->size + align);
 
     XSync (xcontext->disp, FALSE);
   }
 
+  if ((offset = ((guintptr) meta->xvimage->data & align)))
+    offset = (align + 1) - offset;
+
+  GST_DEBUG_OBJECT (xvimagesink, "memory %p, align %d, offset %d",
+      meta->xvimage->data, align, offset);
+
   /* Reset error handler */
   error_caught = FALSE;
   XSetErrorHandler (handler);
 
   gst_buffer_append_memory (buffer,
       gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, meta->xvimage->data,
-          meta->size, 0, meta->size, NULL, NULL));
+          meta->size + align, offset, meta->size, NULL, NULL));
 
   g_mutex_unlock (xvimagesink->x_lock);