gstgl: Fix handling of padded tile formats
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Tue, 8 Nov 2022 17:47:10 +0000 (17:47 +0000)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 9 Nov 2022 17:15:32 +0000 (17:15 +0000)
When a tile format is padded and imported as DMABuf, the stride
contains the information about the actual width and height in
number of tiles. This information is needed by the detiling shader
in order accuratly calculate the location of pixels. To fix that,
we also copy the offset and strides into the otuput format and
the converter will ensure that the shader is recompiled whenever
the stride changes.

This fixes video corruptions observed when decoding on MT8195
with videos that aren't not aligned to 64bytes in width.

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

subprojects/gst-plugins-base/gst-libs/gst/gl/gstglcolorconvert.c
subprojects/gst-plugins-base/gst-libs/gst/gl/gstglupload.c

index f3656cf..6506059 100644 (file)
@@ -3055,6 +3055,18 @@ _do_convert (GstGLContext * context, GstGLColorConvert * convert)
       gst_gl_color_convert_reset_shader (convert);
   }
 
+  if (GST_VIDEO_FORMAT_INFO_IS_TILED (convert->in_info.finfo)) {
+    GstVideoMeta *vmeta = gst_buffer_get_video_meta (convert->inbuf);
+    gsize stride;
+
+    stride = GST_VIDEO_INFO_PLANE_STRIDE (&convert->in_info, 0);
+
+    if (vmeta && vmeta->stride[0] != stride) {
+      GST_VIDEO_INFO_PLANE_STRIDE (&convert->in_info, 0) = vmeta->stride[0];
+      gst_gl_color_convert_reset_shader (convert);
+    }
+  }
+
   if (!_init_convert (convert)) {
     convert->priv->result = FALSE;
     return;
index eaae86e..5d17ec1 100644 (file)
@@ -676,6 +676,21 @@ _dma_buf_upload_accept (gpointer impl, GstBuffer * buffer, GstCaps * in_caps,
     dmabuf->out_caps = out_caps;
     if (!gst_video_info_from_caps (out_info, out_caps))
       return FALSE;
+
+    /*
+     * When we zero-copy tiles, we need to propagate the strides, which contains
+     * the tile dimension. This is because the shader needs to know the padded
+     * size in order to correctly sample into these special buffer.
+     */
+    if (meta && GST_VIDEO_FORMAT_INFO_IS_TILED (out_info->finfo)) {
+      out_info->width = meta->width;
+      out_info->height = meta->height;
+
+      for (i = 0; i < meta->n_planes; i++) {
+        out_info->offset[i] = meta->offset[i];
+        out_info->stride[i] = meta->stride[i];
+      }
+    }
   }
 
   if (dmabuf->params)