tizenwlsink: Keep per display wayland buffer caches 06/304206/2
authorJiyong <jiyong.min@samsung.com>
Fri, 12 Jan 2024 04:56:30 +0000 (13:56 +0900)
committerJiyong <jiyong.min@samsung.com>
Wed, 17 Jan 2024 04:46:06 +0000 (13:46 +0900)
Apply below gstreamer's wayland patches for frame reordering issue

- Keep per display wayland buffer caches
  https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/commit/ff5f26404594f0e96d53d0c0a558baf93aee28a1
- use GstMemory instead of GstBuffer for cache lookup
  https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/commit/e6944da13453e3861b0fd7e50c5c560dc93b5c63
- Update stale GstBuffer references in wayland buffer cache
  https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/commit/deefedd002a91dcb66351cee6f3f92b5f62bcac7

Change-Id: I3c70afc33d24d8b5bb6647f89480fd45ba7690a8

packaging/gst-plugins-tizen.spec
tizenwlsink/src/gsttizenwlsink.c
tizenwlsink/src/wlbuffer.c
tizenwlsink/src/wlbuffer.h
tizenwlsink/src/wldisplay.c
tizenwlsink/src/wldisplay.h

index d1da278..5867a64 100644 (file)
@@ -3,9 +3,9 @@
 %define gst_branch 1.0
 
 Name:       gst-plugins-tizen
-Version:    1.22.0
+Version:    1.22.8
 Summary:    GStreamer tizen plugins (common)
-Release:    11
+Release:    0
 Group:      Multimedia/Framework
 Url:        http://gstreamer.freedesktop.org/
 License:    LGPL-2.1+
index ed3dc8c..344592c 100644 (file)
@@ -711,7 +711,7 @@ gst_tizen_wl_sink_update_last_buffer_geometry (GstTizenWlSink * sink)
   FUNCTION;
   g_return_if_fail (sink != NULL);
   g_return_if_fail (sink->last_buffer != NULL);
-  wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer);
+  wlbuffer = gst_buffer_get_wl_buffer (sink->display, sink->last_buffer);
 
   g_return_if_fail (wlbuffer != NULL);
 
@@ -1967,7 +1967,7 @@ render_last_buffer (GstTizenWlSink * sink)
   g_return_if_fail (sink->window != NULL);
 #endif
 
-  wlbuffer = gst_buffer_get_wl_buffer (sink->last_buffer);
+  wlbuffer = gst_buffer_get_wl_buffer (sink->display, sink->last_buffer);
   surface = gst_wl_window_get_wl_surface (sink->window);
 
   sink->redraw_pending = TRUE;
@@ -1999,7 +1999,7 @@ gst_tizen_wl_sink_has_wlbuffer (GstTizenWlSink * sink, GstBuffer * buffer)
   g_return_val_if_fail (sink != NULL, FALSE);
   g_return_val_if_fail (buffer != NULL, FALSE);
 
-  gstwlbuffer = gst_buffer_get_wl_buffer (buffer);
+  gstwlbuffer = gst_buffer_get_wl_buffer (sink->display, buffer);
   if (gstwlbuffer && gstwlbuffer->display == sink->display
       && !gst_tizen_wl_sink_flush_event_available (sink)
       && !sink->request_camera_flush_buf) {
@@ -2101,7 +2101,7 @@ gst_tizen_wl_sink_create_wlbuffer_with_previous_plugin_tbm (GstTizenWlSink *
     return ret;
   }
 
-  wlbuffer = gst_buffer_get_wl_buffer (buffer);
+  wlbuffer = gst_buffer_get_wl_buffer (sink->display, buffer);
   if (G_UNLIKELY (!wlbuffer)) {
     wbuf =
         gst_tizen_wl_shm_memory_construct_wl_buffer (mem, sink->display,
@@ -2156,7 +2156,7 @@ static GstFlowReturn
   }
   /* the first time we acquire a buffer,
    * we need to attach a wl_buffer on it */
-  wlbuffer = gst_buffer_get_wl_buffer (buffer);
+  wlbuffer = gst_buffer_get_wl_buffer (sink->display, buffer);
   if (G_UNLIKELY (!wlbuffer)) {
     mem = gst_buffer_peek_memory (sink->to_render, 0);
 
index b453582..5aa2e58 100644 (file)
@@ -38,7 +38,7 @@
  *   -----------------     -------------     ---------------
  *
  * A GstBufferPool normally holds references to its GstBuffers and each buffer
- * holds a reference to a GstWlBuffer (saved in the GstMiniObject qdata).
+ * holds a reference to a GstWlBuffer (saved in the GstMiniObject weak ref data).
  * When a GstBuffer is in use, it holds a reference back to the pool and the
  * pool doesn't hold a reference to the GstBuffer. When the GstBuffer is unrefed
  * externally, it returns back to the pool and the pool holds again a reference
@@ -83,8 +83,6 @@ GST_DEBUG_CATEGORY_EXTERN (gst_tizen_wl_debug);
 
 G_DEFINE_TYPE (GstWlBuffer, gst_wl_buffer, G_TYPE_OBJECT);
 
-static G_DEFINE_QUARK (GstWlBufferQDataQuark, gst_wl_buffer_qdata);
-
 static void
 gst_wl_buffer_dispose (GObject * gobject)
 {
@@ -98,7 +96,7 @@ gst_wl_buffer_dispose (GObject * gobject)
    * block and in the end the display will increase the refcount
    * of this GstWlBuffer, so it will not be finalized */
   if (self->display)
-    gst_wl_display_unregister_buffer (self->display, self);
+    gst_wl_display_unregister_buffer (self->display, self->gstmem);
 
   G_OBJECT_CLASS (gst_wl_buffer_parent_class)->dispose (gobject);
 }
@@ -152,22 +150,24 @@ static void
 buffer_release (void *data, struct wl_buffer *wl_buffer)
 {
   GstWlBuffer *self = data;
+  GstBuffer *buf = self->current_gstbuffer;
   FUNCTION;
   g_return_if_fail (self != NULL);
 
   GST_INFO_OBJECT (self,
       "get event : wl_buffer@%p ::release GstBuffer@%p:: tsurface@%p",
-      wl_buffer, self->gstbuffer, self->tsurface);
+      wl_buffer, buf, self->tsurface);
 
   self->used_by_compositor = FALSE;
+  self->current_gstbuffer = NULL;
 
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
-  GST_LOG_OBJECT (self, "gstbuffer(%p), ref_count(%d)", self->gstbuffer,
-      GST_OBJECT_REFCOUNT_VALUE (self->gstbuffer));
+  GST_LOG_OBJECT (self, "gstbuffer(%p), ref_count(%d)", buf,
+      GST_OBJECT_REFCOUNT_VALUE (buf));
   /* If the buffer pool is not used, gstbuffer_disposed will be called immediately after gstbuffer is disposed by codec.
      Unref should be last, because it may end up destroying the GstWlBuffer */
 #endif
-  gst_buffer_unref (self->gstbuffer);
+  gst_buffer_unref (buf);
 }
 
 static const struct wl_buffer_listener buffer_listener = {
@@ -175,14 +175,13 @@ static const struct wl_buffer_listener buffer_listener = {
 };
 
 static void
-gstbuffer_disposed (GstWlBuffer * self)
+gstmemory_disposed (GstWlBuffer * self)
 {
   FUNCTION;
   g_assert (!self->used_by_compositor);
-  GST_INFO ("GstBuffer: %p", self->gstbuffer);
-  self->gstbuffer = NULL;
+  GST_INFO ("GstBuffer: %p", self->current_gstbuffer);
 
-  GST_TRACE_OBJECT (self, "owning GstBuffer was finalized");
+  GST_TRACE_OBJECT (self, "owning GstMemory was finalized");
 
   /* this will normally destroy the GstWlBuffer, unless the display is
    * finalizing and it has taken an additional reference to it */
@@ -197,9 +196,10 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
   FUNCTION;
 
   self = g_object_new (GST_TYPE_WL_BUFFER, NULL);
-  self->gstbuffer = gstbuffer;
+  self->current_gstbuffer = gstbuffer;
   self->wlbuffer = wlbuffer;
   self->display = display;
+  self->gstmem = gst_buffer_peek_memory (gstbuffer, 0);
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
   if (display->tsurface)
     self->tsurface = display->tsurface;
@@ -213,7 +213,7 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
     self->is_flush_request = TRUE;
 #endif
 
-  gst_wl_display_register_buffer (self->display, self); //register GstWlBuffer
+  gst_wl_display_register_buffer (self->display, self->gstmem, self); //register GstWlBuffer
 
   GST_INFO
       ("wl_buffer_add_listener (wl_buffer@%p, wl_buffer_listener@%p, GstWlBuffer@%p)",
@@ -222,24 +222,27 @@ gst_buffer_add_wl_buffer (GstBuffer * gstbuffer, struct wl_buffer *wlbuffer,
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT //need to contribute to upstream !!
   wl_proxy_set_queue ((struct wl_proxy *) self->wlbuffer, self->display->queue);
 #endif
-  /* called gstbuffer_disposed when the gstbuffer is disposed,
+  /* called gstmemory_disposed when the gstbuffer is disposed,
      or the same gstbuffer is being overwritten by below api */
-  gst_mini_object_set_qdata ((GstMiniObject *) gstbuffer,
-      gst_wl_buffer_qdata_quark (), self, (GDestroyNotify) gstbuffer_disposed);
+  gst_mini_object_weak_ref (GST_MINI_OBJECT (self->gstmem),
+      (GstMiniObjectNotify) gstmemory_disposed, self);
   GST_LOG ("GstWlBuffer (%p)", self);
   return self;
 }
 
 GstWlBuffer *
-gst_buffer_get_wl_buffer (GstBuffer * gstbuffer)
+gst_buffer_get_wl_buffer (GstWlDisplay * display, GstBuffer * gstbuffer)
 {
   FUNCTION;
-  return gst_mini_object_get_qdata ((GstMiniObject *) gstbuffer,
-      gst_wl_buffer_qdata_quark ());
+  GstMemory *mem0 = gst_buffer_peek_memory (gstbuffer, 0);
+  GstWlBuffer *wlbuf = gst_wl_display_lookup_buffer (display, mem0);
+  if (wlbuf)
+    wlbuf->current_gstbuffer = gstbuffer;
+  return wlbuf;
 }
 
 void
-gst_wl_buffer_force_release_and_unref (GstWlBuffer * self)
+gst_wl_buffer_force_release_and_unref (GstBuffer * buf, GstWlBuffer * self)
 {
   FUNCTION;
   /* Force a buffer release.
@@ -248,9 +251,9 @@ gst_wl_buffer_force_release_and_unref (GstWlBuffer * self)
    * at the same time from the event loop thread */
   if (self->used_by_compositor) {
     GST_DEBUG_OBJECT (self, "forcing wl_buffer::release (GstBuffer: %p)",
-        self->gstbuffer);
+        self->current_gstbuffer);
     self->used_by_compositor = FALSE;
-    gst_buffer_unref (self->gstbuffer);
+    gst_buffer_unref (self->current_gstbuffer);
   }
 
   /* Finalize this GstWlBuffer early.
@@ -264,6 +267,7 @@ gst_wl_buffer_force_release_and_unref (GstWlBuffer * self)
   wl_buffer_destroy (self->wlbuffer);
   self->wlbuffer = NULL;
   self->display = NULL;
+  self->current_gstbuffer = NULL;
 #ifdef TIZEN_FEATURE_WLSINK_ENHANCEMENT
   GST_LOG ("self->tsurface(%p)", self->tsurface);
   if (self->tsurface)
@@ -290,8 +294,8 @@ gst_wl_buffer_attach (GstWlBuffer * self, struct wl_surface *surface)
      so, we need not to increase ref count. */
   if (!self->is_flush_request)
 #endif
-    gst_buffer_ref (self->gstbuffer);
-  GST_LOG_OBJECT (self, "gstbuffer(%p), ref_count(%d)", self->gstbuffer,
-      GST_OBJECT_REFCOUNT_VALUE (self->gstbuffer));
+    gst_buffer_ref (self->current_gstbuffer);
+  GST_LOG_OBJECT (self, "gstbuffer(%p), ref_count(%d)", self->current_gstbuffer,
+      GST_OBJECT_REFCOUNT_VALUE (self->current_gstbuffer));
   self->used_by_compositor = TRUE;
 }
index d9713eb..ffa8027 100644 (file)
@@ -38,7 +38,8 @@ struct _GstWlBuffer
   GObject parent_instance;
 
   struct wl_buffer *wlbuffer;
-  GstBuffer *gstbuffer;
+  GstBuffer *current_gstbuffer;
+  GstMemory *gstmem;
 
   GstWlDisplay *display;
 
@@ -59,9 +60,9 @@ GType gst_wl_buffer_get_type (void);
 
 GstWlBuffer *gst_buffer_add_wl_buffer (GstBuffer * gstbuffer,
     struct wl_buffer *wlbuffer, GstWlDisplay * display);
-GstWlBuffer *gst_buffer_get_wl_buffer (GstBuffer * gstbuffer);
+GstWlBuffer *gst_buffer_get_wl_buffer (GstWlDisplay * display, GstBuffer * gstbuffer);
 
-void gst_wl_buffer_force_release_and_unref (GstWlBuffer * self);
+void gst_wl_buffer_force_release_and_unref (GstBuffer *buf, GstWlBuffer * self);
 
 void gst_wl_buffer_attach (GstWlBuffer * self, struct wl_surface *surface);
 
index bf38be5..892a62d 100644 (file)
@@ -88,6 +88,12 @@ gst_wl_display_init (GstWlDisplay * self)
 }
 
 static void
+gst_wl_ref_wl_buffer (gpointer key, gpointer value, gpointer user_data)
+{
+  g_object_ref (value);
+}
+
+static void
 gst_wl_display_finalize (GObject * gobject)
 {
   GstWlDisplay *self = GST_WL_DISPLAY (gobject);
@@ -101,7 +107,7 @@ gst_wl_display_finalize (GObject * gobject)
    * at the same time, take their ownership */
   g_mutex_lock (&self->buffers_mutex);
   self->shutting_down = TRUE;
-  g_hash_table_foreach (self->buffers, (GHFunc) g_object_ref, NULL);
+  g_hash_table_foreach (self->buffers, gst_wl_ref_wl_buffer, NULL);
   g_mutex_unlock (&self->buffers_mutex);
 
   g_hash_table_foreach (self->buffers,
@@ -505,26 +511,43 @@ gst_wl_display_new_existing (struct wl_display * display,
 }
 
 void
-gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf)
+gst_wl_display_register_buffer (GstWlDisplay * self, gpointer gstmem,
+    gpointer wlbuffer)
 {
   FUNCTION;
   g_assert (!self->shutting_down);
 
-  GST_TRACE_OBJECT (self, "registering GstWlBuffer %p", buf);
+  GST_TRACE_OBJECT (self, "registering GstWlBuffer %p to GstMem %p",
+      wlbuffer, gstmem);
+
+  g_mutex_lock (&self->buffers_mutex);
+  g_hash_table_replace (self->buffers, gstmem, wlbuffer);
+  g_mutex_unlock (&self->buffers_mutex);
+}
 
+gpointer
+gst_wl_display_lookup_buffer (GstWlDisplay * self, gpointer gstmem)
+{
+  FUNCTION;
+  gpointer wlbuffer;
   g_mutex_lock (&self->buffers_mutex);
-  g_hash_table_add (self->buffers, buf);
+  wlbuffer = g_hash_table_lookup (self->buffers, gstmem);
   g_mutex_unlock (&self->buffers_mutex);
+
+  GST_TRACE_OBJECT (self, "lookup GstWlBuffer %p from GstBuffer %p",
+      wlbuffer, gstmem);
+
+  return wlbuffer;
 }
 
 void
-gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf)
+gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer gstmem)
 {
   FUNCTION;
-  GST_TRACE_OBJECT (self, "unregistering GstWlBuffer %p", buf);
+  GST_TRACE_OBJECT (self, "unregistering GstWlBuffer owned by %p", gstmem);
 
   g_mutex_lock (&self->buffers_mutex);
   if (G_LIKELY (!self->shutting_down))
-    g_hash_table_remove (self->buffers, buf);
+    g_hash_table_remove (self->buffers, gstmem);
   g_mutex_unlock (&self->buffers_mutex);
 }
index e9a3b4d..08eedde 100644 (file)
@@ -119,8 +119,10 @@ GstWlDisplay *gst_wl_display_new_existing (struct wl_display *display,
     gboolean take_ownership, GError ** error);
 
 /* see wlbuffer.c for explanation */
-void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf);
-void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf);
+void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer gstmem,
+    gpointer wlbuffer);
+void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer gstmem);
+gpointer gst_wl_display_lookup_buffer (GstWlDisplay * self, gpointer gstmem);
 
 gboolean gst_wl_display_check_format_for_shm (GstWlDisplay * display,
     GstVideoFormat format);