From 4b6f23a997485355aeca22193c317184fe74a28c Mon Sep 17 00:00:00 2001
From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Date: Wed, 15 Feb 2023 12:13:16 -0500
Subject: [PATCH 03/17] waylandsink: Stop modifying the display GstVideoInfo

The video_info is supposed to match the display dimentions, but as soon as we
get a padded video buffer, we modify it. This has side effect later on and
maybe cause bad frames.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3801>
---
 ext/gtk/gstgtkwaylandsink.c  | 22 +++++++++-------------
 ext/wayland/gstwaylandsink.c | 18 +++++++-----------
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/ext/gtk/gstgtkwaylandsink.c b/ext/gtk/gstgtkwaylandsink.c
index 35367ca..dc1e3c3 100644
--- a/ext/gtk/gstgtkwaylandsink.c
+++ b/ext/gtk/gstgtkwaylandsink.c
@@ -982,7 +982,7 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
   GstWlBuffer *wlbuffer;
   GstVideoMeta *vmeta;
   GstVideoFormat format;
-  GstVideoInfo old_vinfo;
+  GstVideoInfo src_vinfo;
   GstMemory *mem;
   struct wl_buffer *wbuf = NULL;
 
@@ -1023,23 +1023,23 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
   /* update video info from video meta */
   mem = gst_buffer_peek_memory (buffer, 0);
 
-  old_vinfo = priv->video_info;
+  src_vinfo = priv->video_info;
   vmeta = gst_buffer_get_video_meta (buffer);
   if (vmeta) {
     gint i;
 
     for (i = 0; i < vmeta->n_planes; i++) {
-      priv->video_info.offset[i] = vmeta->offset[i];
-      priv->video_info.stride[i] = vmeta->stride[i];
+      src_vinfo.offset[i] = vmeta->offset[i];
+      src_vinfo.stride[i] = vmeta->stride[i];
     }
-    priv->video_info.size = gst_buffer_get_size (buffer);
+    src_vinfo.size = gst_buffer_get_size (buffer);
   }
 
   GST_LOG_OBJECT (self,
       "buffer %" GST_PTR_FORMAT " does not have a wl_buffer from our "
       "display, creating it", buffer);
 
-  format = GST_VIDEO_INFO_FORMAT (&priv->video_info);
+  format = GST_VIDEO_INFO_FORMAT (&src_vinfo);
   if (gst_wl_display_check_format_for_dmabuf (priv->display, format)) {
     guint i, nb_dmabuf = 0;
 
@@ -1049,21 +1049,17 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
 
     if (nb_dmabuf && (nb_dmabuf == gst_buffer_n_memory (buffer)))
       wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (buffer, priv->display,
-          &priv->video_info);
+          &src_vinfo);
   }
 
   if (!wbuf && gst_wl_display_check_format_for_shm (priv->display, format)) {
     if (gst_buffer_n_memory (buffer) == 1 && gst_is_fd_memory (mem))
       wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, priv->display,
-          &priv->video_info);
+          &src_vinfo);
 
     /* If nothing worked, copy into our internal pool */
     if (!wbuf) {
       GstVideoFrame src, dst;
-      GstVideoInfo src_info = priv->video_info;
-
-      /* rollback video info changes */
-      priv->video_info = old_vinfo;
 
       /* we don't know how to create a wl_buffer directly from the provided
        * memory, so we have to copy the data to shm memory that we know how
@@ -1115,7 +1111,7 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
               GST_MAP_WRITE))
         goto dst_map_failed;
 
-      if (!gst_video_frame_map (&src, &src_info, buffer, GST_MAP_READ)) {
+      if (!gst_video_frame_map (&src, &src_vinfo, buffer, GST_MAP_READ)) {
         gst_video_frame_unmap (&dst);
         goto src_map_failed;
       }
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index 2f116bf..6dd0807 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -741,7 +741,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
   GstWlBuffer *wlbuffer;
   GstVideoMeta *vmeta;
   GstVideoFormat format;
-  GstVideoInfo old_vinfo;
+  GstVideoInfo src_vinfo;
   GstMemory *mem;
   struct wl_buffer *wbuf = NULL;
 
@@ -794,16 +794,16 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
   /* update video info from video meta */
   mem = gst_buffer_peek_memory (buffer, 0);
 
-  old_vinfo = self->video_info;
+  src_vinfo = self->video_info;
   vmeta = gst_buffer_get_video_meta (buffer);
   if (vmeta) {
     gint i;
 
     for (i = 0; i < vmeta->n_planes; i++) {
-      self->video_info.offset[i] = vmeta->offset[i];
-      self->video_info.stride[i] = vmeta->stride[i];
+      src_vinfo.offset[i] = vmeta->offset[i];
+      src_vinfo.stride[i] = vmeta->stride[i];
     }
-    self->video_info.size = gst_buffer_get_size (buffer);
+    src_vinfo.size = gst_buffer_get_size (buffer);
   }
 
   GST_LOG_OBJECT (self,
@@ -820,7 +820,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
 
     if (nb_dmabuf && (nb_dmabuf == gst_buffer_n_memory (buffer)))
       wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (buffer, self->display,
-          &self->video_info);
+          &src_vinfo);
   }
 
   if (!wbuf && gst_wl_display_check_format_for_shm (self->display, format)) {
@@ -831,10 +831,6 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
     /* If nothing worked, copy into our internal pool */
     if (!wbuf) {
       GstVideoFrame src, dst;
-      GstVideoInfo src_info = self->video_info;
-
-      /* rollback video info changes */
-      self->video_info = old_vinfo;
 
       /* we don't know how to create a wl_buffer directly from the provided
        * memory, so we have to copy the data to shm memory that we know how
@@ -886,7 +882,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
               GST_MAP_WRITE))
         goto dst_map_failed;
 
-      if (!gst_video_frame_map (&src, &src_info, buffer, GST_MAP_READ)) {
+      if (!gst_video_frame_map (&src, &src_vinfo, buffer, GST_MAP_READ)) {
         gst_video_frame_unmap (&dst);
         goto src_map_failed;
       }
-- 
2.25.1

