gl: bufferpool take into account video stride alignment requirements
authorTim-Philipp Müller <tim@centricular.com>
Tue, 15 Sep 2015 10:34:12 +0000 (11:34 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Tue, 15 Sep 2015 15:11:23 +0000 (16:11 +0100)
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
gst-libs/gst/gl/gstglmemory.c

index 78c6a77..69ac2d8 100644 (file)
@@ -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);
index 5d3f73a..b1bef1e 100644 (file)
@@ -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 */