va: allocator: Fix translation of VADRMPRIMESurfaceDescriptor
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 8 Jun 2022 13:02:52 +0000 (09:02 -0400)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Fri, 24 Jun 2022 12:14:03 +0000 (14:14 +0200)
VADRMPRIMESurfaceDescriptor structure describes the offsets from the
point of view of the specific handle (DMABuf). While GstVideoInfo
(and the meta) describes offsets from the point of the view of the
GstBuffer, an aggregate of all the GstMemory (1 per handle).

This changes combined with [Mesa Fix](https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16813)
fixes decoding failure with AMD driver.

Fixes #1223

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2574>

subprojects/gst-plugins-bad/gst-libs/gst/va/gstvaallocator.c

index 5651c46cc502fa78c3971df98c49e2d78b1cf060..e54142674e9fd01a9383375bf74a2b59fb383253 100644 (file)
@@ -520,6 +520,7 @@ gst_va_dmabuf_allocator_setup_buffer_full (GstAllocator * allocator,
   VASurfaceID surface;
   guint32 i, fourcc, rt_format, export_flags;
   GDestroyNotify buffer_destroy = NULL;
+  gsize object_offset[4];
 
   g_return_val_if_fail (GST_IS_VA_DMABUF_ALLOCATOR (allocator), FALSE);
 
@@ -598,6 +599,7 @@ gst_va_dmabuf_allocator_setup_buffer_full (GstAllocator * allocator,
     GstMemory *mem = gst_dmabuf_allocator_alloc (allocator, fd, size);
     guint64 *drm_mod = g_new (guint64, 1);
 
+    object_offset[i] = gst_buffer_get_size (buffer);
     gst_buffer_append_memory (buffer, mem);
     buf->mems[i] = mem;
 
@@ -620,19 +622,23 @@ gst_va_dmabuf_allocator_setup_buffer_full (GstAllocator * allocator,
         drm_mod, g_free);
 
     if (G_UNLIKELY (info))
-      GST_VIDEO_INFO_SIZE (info) += size;
+      GST_VIDEO_INFO_PLANE_OFFSET (info, i) = GST_VIDEO_INFO_SIZE (info);
 
     GST_LOG_OBJECT (self, "buffer %p: new dmabuf %d / surface %#x [%dx%d] "
         "size %" G_GSIZE_FORMAT " drm mod %#" G_GINT64_MODIFIER "x",
         buffer, fd, surface,
         GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info),
-        GST_VIDEO_INFO_SIZE (&self->info), *drm_mod);
+        size, *drm_mod);
   }
 
   if (G_UNLIKELY (info)) {
+    GST_VIDEO_INFO_SIZE (info) = gst_buffer_get_size (buffer);
+
     for (i = 0; i < desc.num_layers; i++) {
       g_assert (desc.layers[i].num_planes == 1);
-      GST_VIDEO_INFO_PLANE_OFFSET (info, i) = desc.layers[i].offset[0];
+      GST_VIDEO_INFO_PLANE_OFFSET (info, i) =
+          object_offset[desc.layers[i].object_index[0]] +
+          desc.layers[i].offset[0];
       GST_VIDEO_INFO_PLANE_STRIDE (info, i) = desc.layers[i].pitch[0];
     }
   } else {