glmemory: Add GstAllocationParams and alignment support
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Wed, 25 Feb 2015 23:07:03 +0000 (18:07 -0500)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:55 +0000 (19:31 +0000)
This implements support for GstAllocationParams and memory alignments.
The parameters where simply ignored which could lead to crash on
certain platform when used with libav and no luck.

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

ext/gl/gstgloverlay.c
gst-libs/gst/gl/gstglbufferpool.c
gst-libs/gst/gl/gstglcolorconvert.c
gst-libs/gst/gl/gstglmemory.c
gst-libs/gst/gl/gstglmemory.h
gst-libs/gst/gl/gstglupload.c

index 4ba1b79..de32482 100644 (file)
@@ -638,7 +638,8 @@ gst_gl_overlay_load_jpeg (GstGLFilter * filter)
         overlay->image_width, overlay->image_height);
 
   overlay->image_memory =
-      (GstGLMemory *) gst_gl_memory_alloc (filter->context, &v_info, 0, NULL);
+      (GstGLMemory *) gst_gl_memory_alloc (filter->context, NULL, &v_info, 0,
+      NULL);
 
   if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
           GST_MAP_WRITE)) {
@@ -740,7 +741,8 @@ gst_gl_overlay_load_png (GstGLFilter * filter)
 
   gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, width, height);
   overlay->image_memory =
-      (GstGLMemory *) gst_gl_memory_alloc (filter->context, &v_info, 0, NULL);
+      (GstGLMemory *) gst_gl_memory_alloc (filter->context, NULL, &v_info, 0,
+      NULL);
 
   if (!gst_memory_map ((GstMemory *) overlay->image_memory, &map_info,
           GST_MAP_WRITE)) {
index 1c62c1f..6cb2957 100644 (file)
@@ -254,7 +254,8 @@ gst_gl_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
   }
 #endif
 
-  if (!gst_gl_memory_setup_buffer (glpool->context, info, valign, buf))
+  if (!gst_gl_memory_setup_buffer (glpool->context, &priv->params, info,
+          valign, buf))
     goto mem_create_failed;
 
   if (priv->add_uploadmeta)
index 3d2b507..f6d5368 100644 (file)
@@ -1428,7 +1428,7 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert)
   }
 
   convert->outbuf = gst_buffer_new ();
-  if (!gst_gl_memory_setup_buffer (convert->context, &convert->out_info,
+  if (!gst_gl_memory_setup_buffer (convert->context, NULL, &convert->out_info,
           NULL, convert->outbuf)) {
     convert->priv->result = FALSE;
     return;
@@ -1478,7 +1478,8 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert)
 
       if (!convert->priv->out_tex[j])
         convert->priv->out_tex[j] =
-            (GstGLMemory *) gst_gl_memory_alloc (context, &temp_info, 0, NULL);
+            (GstGLMemory *) gst_gl_memory_alloc (context, NULL, &temp_info, 0,
+            NULL);
     } else {
       convert->priv->out_tex[j] = out_tex;
     }
index 18a364b..2a6f5f4 100644 (file)
@@ -421,7 +421,7 @@ _find_plane_frame_start (GstGLMemory * gl_mem)
 
   /* offset between the plane data start and where the video frame starts */
   return (GST_VIDEO_INFO_PLANE_OFFSET (&gl_mem->info,
-          gl_mem->plane)) - plane_start;
+          gl_mem->plane)) - plane_start + gl_mem->mem.offset;
 }
 
 static void
@@ -699,10 +699,12 @@ error:
 
 static void
 _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
-    GstGLContext * context, GstVideoInfo * info, GstVideoAlignment * valign,
-    guint plane, gpointer user_data, GDestroyNotify notify)
+    GstGLContext * context, GstAllocationParams * params, GstVideoInfo * info,
+    GstVideoAlignment * valign, guint plane, gpointer user_data,
+    GDestroyNotify notify)
 {
-  gsize maxsize;
+  gsize size, maxsize;
+  gsize align = gst_memory_alignment, offset = 0;
 
   g_return_if_fail (plane < GST_VIDEO_INFO_N_PLANES (info));
 
@@ -712,10 +714,16 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
   else
     gst_video_alignment_reset (&mem->valign);
 
-  maxsize = gst_gl_get_plane_data_size (info, valign, plane);
+  size = maxsize = gst_gl_get_plane_data_size (info, valign, plane);
 
-  gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, parent, maxsize, 0, 0,
-      maxsize);
+  if (params) {
+    align |= params->align;
+    offset = params->prefix;
+    maxsize += params->prefix + params->padding + align;
+  }
+
+  gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, parent, maxsize, align,
+      offset, size);
 
   mem->context = gst_object_ref (context);
   mem->tex_type =
@@ -726,7 +734,6 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
   mem->plane = plane;
   mem->notify = notify;
   mem->user_data = user_data;
-  mem->data_wrapped = FALSE;
   mem->texture_wrapped = FALSE;
 
   g_mutex_init (&mem->lock);
@@ -741,13 +748,14 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
 
 static GstGLMemory *
 _gl_mem_new (GstAllocator * allocator, GstMemory * parent,
-    GstGLContext * context, GstVideoInfo * info, GstVideoAlignment * valign,
-    guint plane, gpointer user_data, GDestroyNotify notify)
+    GstGLContext * context, GstAllocationParams * params, GstVideoInfo * info,
+    GstVideoAlignment * valign, guint plane, gpointer user_data,
+    GDestroyNotify notify)
 {
   GstGLMemory *mem;
   GenTexture data = { 0, };
   mem = g_slice_new0 (GstGLMemory);
-  _gl_mem_init (mem, allocator, parent, context, info, valign, plane,
+  _gl_mem_init (mem, allocator, parent, context, params, info, valign, plane,
       user_data, notify);
 
   data.width = mem->tex_width;
@@ -773,6 +781,32 @@ _gl_mem_new (GstAllocator * allocator, GstMemory * parent,
   return mem;
 }
 
+static GstGLMemory *
+_gl_mem_alloc_data (GstGLMemory * mem)
+{
+  guint8 *data;
+  gsize align, aoffset;
+
+  data = g_try_malloc (mem->mem.maxsize);
+  mem->alloc_data = mem->data = data;
+
+  if (data == NULL) {
+    gst_memory_unref ((GstMemory *) mem);
+    return NULL;
+  }
+
+  /* do alignment */
+  align = mem->mem.align;
+  if ((aoffset = ((guintptr) data & align))) {
+    aoffset = (align + 1) - aoffset;
+    data += aoffset;
+    mem->mem.maxsize -= aoffset;
+    mem->data = data;
+  }
+
+  return mem;
+}
+
 static gpointer
 _gl_mem_map (GstGLMemory * gl_mem, gsize maxsize, GstMapFlags flags)
 {
@@ -1009,17 +1043,22 @@ _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
   g_mutex_lock (&((GstGLMemory *) src)->lock);
 
   if (GST_GL_MEMORY_FLAG_IS_SET (src, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
-    dest = _gl_mem_new (src->mem.allocator, NULL, src->context, &src->info,
-        &src->valign, src->plane, NULL, NULL);
-    dest->data = g_try_malloc (src->mem.maxsize);
-    if (dest->data == NULL) {
+    GstAllocationParams params = { 0, src->mem.align, 0, 0 };
+
+    dest = _gl_mem_new (src->mem.allocator, NULL, src->context, &params,
+        &src->info, &src->valign, src->plane, NULL, NULL);
+    dest = _gl_mem_alloc_data (dest);
+
+    if (dest == NULL) {
       GST_WARNING ("Could not copy GL Memory");
       gst_memory_unref ((GstMemory *) dest);
-      return NULL;
+      goto done;
     }
-    memcpy (dest->data, src->data, src->mem.maxsize);
+
+    memcpy (dest->data, (guint8 *) src->data + src->mem.offset, src->mem.size);
     GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
   } else {
+    GstAllocationParams params = { 0, src->mem.align, 0, 0 };
     GstGLMemoryCopyParams copy_params;
 
     copy_params.src = src;
@@ -1033,26 +1072,22 @@ _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
 
     gst_gl_context_thread_add (src->context, _gl_mem_copy_thread, &copy_params);
 
-    dest = g_slice_new0 (GstGLMemory);
-    _gl_mem_init (dest, src->mem.allocator, NULL, src->context, &src->info,
-        &src->valign, src->plane, NULL, NULL);
-
     if (!copy_params.result) {
       GST_WARNING ("Could not copy GL Memory");
-      gst_memory_unref ((GstMemory *) dest);
-      return NULL;
+      goto done;
     }
 
+    dest = g_slice_new0 (GstGLMemory);
+    _gl_mem_init (dest, src->mem.allocator, NULL, src->context, &params,
+        &src->info, &src->valign, src->plane, NULL, NULL);
+
     dest->tex_id = copy_params.tex_id;
-    dest->data = g_try_malloc (src->mem.maxsize);
-    if (dest->data == NULL) {
-      GST_WARNING ("Could not copy GL Memory");
-      gst_memory_unref ((GstMemory *) dest);
-      return NULL;
-    }
+    dest->tex_target = copy_params.tex_target;
+    dest = _gl_mem_alloc_data (dest);
     GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
   }
 
+done:
   g_mutex_unlock (&((GstGLMemory *) src)->lock);
 
   return (GstMemory *) dest;
@@ -1107,8 +1142,9 @@ _gl_mem_free (GstAllocator * allocator, GstMemory * mem)
   if (gl_mem->notify)
     gl_mem->notify (gl_mem->user_data);
 
-  if (gl_mem->data && !gl_mem->data_wrapped) {
-    g_free (gl_mem->data);
+  if (gl_mem->alloc_data) {
+    g_free (gl_mem->alloc_data);
+    gl_mem->alloc_data = NULL;
     gl_mem->data = NULL;
   }
 
@@ -1189,18 +1225,14 @@ gst_gl_memory_wrapped_texture (GstGLContext * context,
   GstGLMemory *mem;
 
   mem = g_slice_new0 (GstGLMemory);
-  _gl_mem_init (mem, _gl_allocator, NULL, context, info, valign, plane,
+  _gl_mem_init (mem, _gl_allocator, NULL, context, NULL, info, valign, plane,
       user_data, notify);
 
   mem->tex_id = texture_id;
   mem->tex_target = texture_target;
   mem->texture_wrapped = TRUE;
-  mem->data = g_try_malloc (mem->mem.maxsize);
-  if (mem->data == NULL) {
-    gst_memory_unref ((GstMemory *) mem);
-    return NULL;
-  }
 
+  mem = _gl_mem_alloc_data (mem);
   GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
 
   return mem;
@@ -1209,6 +1241,7 @@ gst_gl_memory_wrapped_texture (GstGLContext * context,
 /**
  * gst_gl_memory_alloc:
  * @context:a #GstGLContext
+ * @params: a #GstAllocationParams
  * @info: the #GstVideoInfo of the memory
  * @plane: the plane this memory will represent
  * @valign: the #GstVideoAlignment applied to @info
@@ -1219,19 +1252,14 @@ gst_gl_memory_wrapped_texture (GstGLContext * context,
  *          from @context
  */
 GstMemory *
-gst_gl_memory_alloc (GstGLContext * context, GstVideoInfo * info,
-    guint plane, GstVideoAlignment * valign)
+gst_gl_memory_alloc (GstGLContext * context, GstAllocationParams * params,
+    GstVideoInfo * info, guint plane, GstVideoAlignment * valign)
 {
   GstGLMemory *mem;
 
-  mem = _gl_mem_new (_gl_allocator, NULL, context, info, valign, plane, NULL,
-      NULL);
-
-  mem->data = g_try_malloc (mem->mem.maxsize);
-  if (mem->data == NULL) {
-    gst_memory_unref ((GstMemory *) mem);
-    return NULL;
-  }
+  mem = _gl_mem_new (_gl_allocator, NULL, context, params, info, valign, plane,
+      NULL, NULL);
+  mem = _gl_mem_alloc_data (mem);
 
   return (GstMemory *) mem;
 }
@@ -1259,11 +1287,10 @@ gst_gl_memory_wrapped (GstGLContext * context, GstVideoInfo * info,
 {
   GstGLMemory *mem;
 
-  mem = _gl_mem_new (_gl_allocator, NULL, context, info, valign, plane,
+  mem = _gl_mem_new (_gl_allocator, NULL, context, NULL, info, valign, plane,
       user_data, notify);
 
   mem->data = data;
-  mem->data_wrapped = TRUE;
 
   GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
 
@@ -1349,6 +1376,7 @@ gst_is_gl_memory (GstMemory * mem)
 /**
  * gst_gl_memory_setup_buffer:
  * @context: a #GstGLContext
+ * @param: a #GstAllocationParams
  * @info: a #GstVideoInfo
  * @valign: the #GstVideoAlignment applied to @info
  * @buffer: a #GstBuffer
@@ -1359,7 +1387,8 @@ gst_is_gl_memory (GstMemory * mem)
  * Returns: whether the memory's were sucessfully added.
  */
 gboolean
-gst_gl_memory_setup_buffer (GstGLContext * context, GstVideoInfo * info,
+gst_gl_memory_setup_buffer (GstGLContext * context,
+    GstAllocationParams * params, GstVideoInfo * info,
     GstVideoAlignment * valign, GstBuffer * buffer)
 {
   GstGLMemory *gl_mem[GST_VIDEO_MAX_PLANES] = { NULL, };
@@ -1368,7 +1397,8 @@ gst_gl_memory_setup_buffer (GstGLContext * context, GstVideoInfo * info,
   n_mem = GST_VIDEO_INFO_N_PLANES (info);
 
   for (i = 0; i < n_mem; i++) {
-    gl_mem[i] = (GstGLMemory *) gst_gl_memory_alloc (context, info, i, valign);
+    gl_mem[i] =
+        (GstGLMemory *) gst_gl_memory_alloc (context, params, info, i, valign);
     if (gl_mem[i] == NULL)
       return FALSE;
 
index ec23577..0d745e4 100644 (file)
@@ -92,9 +92,9 @@ struct _GstGLMemory
   gfloat                tex_scaling[2];
 
   /* <private> */
+  gpointer              alloc_data;
   gpointer              data;
 
-  gboolean              data_wrapped;
   gboolean              texture_wrapped;
   GDestroyNotify        notify;
   gpointer              user_data;
@@ -155,8 +155,8 @@ struct _GstGLMemory
 void          gst_gl_memory_init (void);
 gboolean      gst_is_gl_memory (GstMemory * mem);
 
-GstMemory *   gst_gl_memory_alloc   (GstGLContext * context, GstVideoInfo * info, guint plane,
-                                     GstVideoAlignment *valign);
+GstMemory *   gst_gl_memory_alloc   (GstGLContext * context, GstAllocationParams *params,
+                                     GstVideoInfo * info, guint plane, GstVideoAlignment *valign);
 GstGLMemory * gst_gl_memory_wrapped (GstGLContext * context, GstVideoInfo * info, guint plane,
                                      GstVideoAlignment *valign, gpointer data,
                                      gpointer user_data, GDestroyNotify notify);
@@ -169,8 +169,8 @@ gboolean      gst_gl_memory_copy_into_texture (GstGLMemory *gl_mem, guint tex_id
                                                gint width, gint height, gint stride,
                                                gboolean respecify);
 
-gboolean      gst_gl_memory_setup_buffer  (GstGLContext * context, GstVideoInfo * info, GstVideoAlignment *valign,
-                                           GstBuffer * buffer);
+gboolean      gst_gl_memory_setup_buffer  (GstGLContext * context, GstAllocationParams * params,
+                                           GstVideoInfo * info, GstVideoAlignment *valign, GstBuffer * buffer);
 gboolean      gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info, GstVideoAlignment *valign,
                                            gpointer data[GST_VIDEO_MAX_PLANES],
                                            GstGLMemory *textures[GST_VIDEO_MAX_PLANES]);
index dbf79fe..c84602e 100644 (file)
@@ -347,7 +347,7 @@ _egl_image_upload_perform_gl_thread (GstGLContext * context,
   /* FIXME: buffer pool */
   *image->outbuf = gst_buffer_new ();
   gst_gl_memory_setup_buffer (image->upload->context,
-      &image->upload->priv->out_info, NULL, *image->outbuf);
+      NULL, &image->upload->priv->out_info, NULL, *image->outbuf);
 
   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&image->upload->priv->in_info); i++) {
     GstMemory *mem = gst_buffer_peek_memory (image->buffer, i);
@@ -556,7 +556,7 @@ _upload_meta_upload_perform (gpointer impl, GstBuffer * buffer,
   /* FIXME: buffer pool */
   *outbuf = gst_buffer_new ();
   gst_gl_memory_setup_buffer (upload->upload->context,
-      &upload->upload->priv->in_info, NULL, *outbuf);
+      NULL, &upload->upload->priv->in_info, NULL, *outbuf);
 
   for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
     guint tex_id = 0;