From de79830b05fae0cadcf9b67610218b451b958350 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Wed, 25 Feb 2015 18:07:03 -0500 Subject: [PATCH] glmemory: Add GstAllocationParams and alignment support 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 | 6 +- gst-libs/gst/gl/gstglbufferpool.c | 3 +- gst-libs/gst/gl/gstglcolorconvert.c | 5 +- gst-libs/gst/gl/gstglmemory.c | 132 ++++++++++++++++++++++-------------- gst-libs/gst/gl/gstglmemory.h | 10 +-- gst-libs/gst/gl/gstglupload.c | 4 +- 6 files changed, 97 insertions(+), 63 deletions(-) diff --git a/ext/gl/gstgloverlay.c b/ext/gl/gstgloverlay.c index 4ba1b79..de32482 100644 --- a/ext/gl/gstgloverlay.c +++ b/ext/gl/gstgloverlay.c @@ -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)) { diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c index 1c62c1f..6cb2957 100644 --- a/gst-libs/gst/gl/gstglbufferpool.c +++ b/gst-libs/gst/gl/gstglbufferpool.c @@ -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) diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index 3d2b507..f6d5368 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -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; } diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c index 18a364b..2a6f5f4 100644 --- a/gst-libs/gst/gl/gstglmemory.c +++ b/gst-libs/gst/gl/gstglmemory.c @@ -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, ¶ms, + &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, ©_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, ¶ms, + &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; diff --git a/gst-libs/gst/gl/gstglmemory.h b/gst-libs/gst/gl/gstglmemory.h index ec23577..0d745e4 100644 --- a/gst-libs/gst/gl/gstglmemory.h +++ b/gst-libs/gst/gl/gstglmemory.h @@ -92,9 +92,9 @@ struct _GstGLMemory gfloat tex_scaling[2]; /* */ + 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]); diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index dbf79fe..c84602e 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -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; -- 2.7.4