diff options
author | Hyunjun Ko <zzoon@igalia.com> | 2017-04-21 15:30:09 +0200 |
---|---|---|
committer | Víctor Manuel Jáquez Leal <vjaquez@igalia.com> | 2017-04-24 13:16:03 +0200 |
commit | 824974e657445401d9d7b56c556c0a1a9f4c22c7 (patch) | |
tree | ae617337e9e4ba9906f2b71f85d0fb40c0d3f1c0 | |
parent | 3b314ba93e61bad3d8decbe45bcb12717b595a55 (diff) | |
download | gstreamer-824974e657445401d9d7b56c556c0a1a9f4c22c7.tar.gz |
libs: window: wayland: mark frames as done
When the frame listener callbacks 'done', the number of pending
frames are decreased. Nonetheless, there might be occasions where
the buffer listener callbacks 'release', without calling previously
frame's 'done'. This leads to problem with
gst_vaapi_window_wayland_sync() operation.
This patch marks as done those frames which were callbacked, but if
the buffer callbacks 'release' and associated frame is not marked
as 'done' it is so, thus the number of pending frames keeps correct.
https://bugzilla.gnome.org/show_bug.cgi?id=780442
Signed-off-by: Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
-rw-r--r-- | gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index 1cdf6d22c0..80f0f5e633 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -62,6 +62,7 @@ struct _FrameState GstVaapiSurface *surface; GstVaapiVideoPool *surface_pool; struct wl_callback *callback; + gboolean done; }; static FrameState * @@ -77,6 +78,7 @@ frame_state_new (GstVaapiWindow * window) frame->surface = NULL; frame->surface_pool = NULL; frame->callback = NULL; + frame->done = FALSE; return frame; } @@ -372,15 +374,21 @@ gst_vaapi_window_wayland_resize (GstVaapiWindow * window, return TRUE; } -static void -frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) +static inline gboolean +frame_done (FrameState * frame) { - FrameState *const frame = data; GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); + g_atomic_int_set (&frame->done, TRUE); g_atomic_pointer_compare_and_exchange (&priv->last_frame, frame, NULL); - g_atomic_int_dec_and_test (&priv->num_frames_pending); + return g_atomic_int_dec_and_test (&priv->num_frames_pending); +} + +static void +frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) +{ + frame_done (data); } static const struct wl_callback_listener frame_callback_listener = { @@ -390,8 +398,12 @@ static const struct wl_callback_listener frame_callback_listener = { static void frame_release_callback (void *data, struct wl_buffer *wl_buffer) { + FrameState *const frame = data; + + if (!frame->done) + frame_done (frame); wl_buffer_destroy (wl_buffer); - frame_state_free (data); + frame_state_free (frame); } static const struct wl_buffer_listener frame_buffer_listener = { |