From 990a49fe4f1fb2f0bb9bfa9ea1defb0c371781aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 15 Sep 2015 11:34:12 +0100 Subject: [PATCH] gl: bufferpool take into account video stride alignment requirements when allocating memory. Fixes crashes with avdec_h265 in the AVX2 code path which requires 32-byte stride alignment, but the GstAllocationParams only specified a 16-byte alignment. https://bugzilla.gnome.org/show_bug.cgi?id=754120 --- gst-libs/gst/gl/gstglbufferpool.c | 20 ++++++++++++++++++++ gst-libs/gst/gl/gstglmemory.c | 15 +++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c index 78c6a7747f..69ac2d891f 100644 --- a/gst-libs/gst/gl/gstglbufferpool.c +++ b/gst-libs/gst/gl/gstglbufferpool.c @@ -93,6 +93,7 @@ gst_gl_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) GstVideoInfo info; GstCaps *caps = NULL; guint min_buffers, max_buffers; + guint max_align, n; GstAllocator *allocator = NULL; GstAllocationParams alloc_params; gboolean reset = TRUE; @@ -152,12 +153,21 @@ gst_gl_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) priv->want_eglimage = FALSE; #endif + max_align = alloc_params.align; + if (gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)) { priv->add_videometa = TRUE; gst_buffer_pool_config_get_video_alignment (config, &priv->valign); + + for (n = 0; n < GST_VIDEO_MAX_PLANES; ++n) + max_align |= priv->valign.stride_align[n]; + + for (n = 0; n < GST_VIDEO_MAX_PLANES; ++n) + priv->valign.stride_align[n] = max_align; + gst_video_info_align (&priv->info, &priv->valign); gst_buffer_pool_config_set_video_alignment (config, &priv->valign); @@ -165,6 +175,16 @@ gst_gl_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) gst_video_alignment_reset (&priv->valign); } + if (alloc_params.align < max_align) { + GST_WARNING_OBJECT (pool, "allocation params alignment %u is smaller " + "than the max specified video stride alignment %u, fixing", + (guint) alloc_params.align, max_align); + + alloc_params.align = max_align; + gst_buffer_pool_config_set_allocator (config, allocator, &alloc_params); + priv->params = alloc_params; + } + if (reset) { if (glpool->upload) gst_object_unref (glpool->upload); diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c index 5d3f73a05c..b1bef1eb04 100644 --- a/gst-libs/gst/gl/gstglmemory.c +++ b/gst-libs/gst/gl/gstglmemory.c @@ -631,6 +631,21 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent, else gst_video_alignment_reset (&mem->valign); + /* double-check alignment requirements (caller should've taken care of this) */ + if (params) { + guint max_align, n; + + max_align = gst_memory_alignment; + max_align |= params->align; + for (n = 0; n < GST_VIDEO_MAX_PLANES; ++n) + max_align |= mem->valign.stride_align[n]; + + if (params->align < max_align && max_align > gst_memory_alignment) { + GST_WARNING ("allocation params alignment %" G_GSIZE_FORMAT " is smaller " + "than the max required video alignment %u", params->align, max_align); + } + } + size = gst_gl_get_plane_data_size (info, valign, plane); /* we always operate on 2D textures unless we're dealing with wrapped textures */