From aa143934f01dd229eb6dce7d000b755e9578e857 Mon Sep 17 00:00:00 2001 From: Jiyong Date: Fri, 12 Jan 2024 13:56:30 +0900 Subject: [PATCH] tizenwlsink: Keep per display wayland buffer caches 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 | 4 +-- tizenwlsink/src/gsttizenwlsink.c | 10 +++---- tizenwlsink/src/wlbuffer.c | 56 +++++++++++++++++++++------------------- tizenwlsink/src/wlbuffer.h | 7 ++--- tizenwlsink/src/wldisplay.c | 37 +++++++++++++++++++++----- tizenwlsink/src/wldisplay.h | 6 +++-- 6 files changed, 75 insertions(+), 45 deletions(-) diff --git a/packaging/gst-plugins-tizen.spec b/packaging/gst-plugins-tizen.spec index d1da278..5867a64 100644 --- a/packaging/gst-plugins-tizen.spec +++ b/packaging/gst-plugins-tizen.spec @@ -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+ diff --git a/tizenwlsink/src/gsttizenwlsink.c b/tizenwlsink/src/gsttizenwlsink.c index ed3dc8c..344592c 100644 --- a/tizenwlsink/src/gsttizenwlsink.c +++ b/tizenwlsink/src/gsttizenwlsink.c @@ -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); diff --git a/tizenwlsink/src/wlbuffer.c b/tizenwlsink/src/wlbuffer.c index b453582..5aa2e58 100644 --- a/tizenwlsink/src/wlbuffer.c +++ b/tizenwlsink/src/wlbuffer.c @@ -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; } diff --git a/tizenwlsink/src/wlbuffer.h b/tizenwlsink/src/wlbuffer.h index d9713eb..ffa8027 100644 --- a/tizenwlsink/src/wlbuffer.h +++ b/tizenwlsink/src/wlbuffer.h @@ -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); diff --git a/tizenwlsink/src/wldisplay.c b/tizenwlsink/src/wldisplay.c index bf38be5..892a62d 100644 --- a/tizenwlsink/src/wldisplay.c +++ b/tizenwlsink/src/wldisplay.c @@ -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); } diff --git a/tizenwlsink/src/wldisplay.h b/tizenwlsink/src/wldisplay.h index e9a3b4d..08eedde 100644 --- a/tizenwlsink/src/wldisplay.h +++ b/tizenwlsink/src/wldisplay.h @@ -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); -- 2.7.4