window->check_geometry = TRUE;
gst_vaapi_window_ensure_size (window);
}
+
+/**
+ * gst_vaapi_window_unblock:
+ * @window: a #GstVaapiWindow
+ *
+ * Unblocks a rendering surface operation.
+ */
+gboolean
+gst_vaapi_window_unblock (GstVaapiWindow * window)
+{
+ const GstVaapiWindowClass *klass;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ klass = GST_VAAPI_WINDOW_GET_CLASS (window);
+
+ if (klass->unblock)
+ return klass->unblock (window);
+
+ return TRUE;
+}
+
+/**
+ * gst_vaapi_window_unblock_cancel:
+ * @window: a #GstVaapiWindow
+ *
+ * Cancels the previous unblock request.
+ */
+gboolean
+gst_vaapi_window_unblock_cancel (GstVaapiWindow * window)
+{
+ const GstVaapiWindowClass *klass;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ klass = GST_VAAPI_WINDOW_GET_CLASS (window);
+
+ if (klass->unblock_cancel)
+ return klass->unblock_cancel (window);
+
+ return TRUE;
+}
void
gst_vaapi_window_reconfigure (GstVaapiWindow * window);
+gboolean
+gst_vaapi_window_unblock (GstVaapiWindow * window);
+
+gboolean
+gst_vaapi_window_unblock_cancel (GstVaapiWindow * window);
+
G_END_DECLS
#endif /* GST_VAAPI_WINDOW_H */
const GstVaapiRectangle * dst_rect);
typedef guintptr (*GstVaapiWindowGetVisualIdFunc) (GstVaapiWindow * window);
typedef guintptr (*GstVaapiWindowGetColormapFunc) (GstVaapiWindow * window);
+typedef gboolean (*GstVaapiWindowSetUnblockFunc) (GstVaapiWindow * window);
+typedef gboolean (*GstVaapiWindowSetUnblockCancelFunc) (GstVaapiWindow * window);
/**
* GstVaapiWindow:
* create the window
* @get_colormap: virtual function to get the desired colormap used to
* create the window, or the currently allocated one
+ * @unblock: virtual function to unblock a rendering surface operation
+ * @unblock_cancel: virtual function to cancel the previous unblock
+ * request.
*
* Base class for system-dependent windows.
*/
GstVaapiWindowRenderPixmapFunc render_pixmap;
GstVaapiWindowGetVisualIdFunc get_visual_id;
GstVaapiWindowGetColormapFunc get_colormap;
+ GstVaapiWindowSetUnblockFunc unblock;
+ GstVaapiWindowSetUnblockCancelFunc unblock_cancel;
};
GstVaapiWindow *
GstVideoFormat surface_format;
GstVaapiVideoPool *surface_pool;
GstVaapiFilter *filter;
+ GstPoll *poll;
+ GstPollFD pollfd;
guint is_shown:1;
guint fullscreen_on_show:1;
guint use_vpp:1;
struct wl_display *const wl_display =
GST_VAAPI_OBJECT_NATIVE_DISPLAY (window);
+ if (priv->pollfd.fd < 0) {
+ priv->pollfd.fd = wl_display_get_fd (wl_display);
+ gst_poll_add_fd (priv->poll, &priv->pollfd);
+ gst_poll_fd_ctl_read (priv->poll, &priv->pollfd, TRUE);
+ }
+
while (g_atomic_int_get (&priv->num_frames_pending) > 0) {
while (wl_display_prepare_read_queue (wl_display, priv->event_queue) < 0) {
if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
if (wl_display_flush (wl_display) < 0)
goto error;
+
+ again:
+ if (gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE) < 0) {
+ int saved_errno = errno;
+ if (saved_errno == EAGAIN || saved_errno == EINTR)
+ goto again;
+ if (saved_errno == EBUSY) { /* closing */
+ wl_display_cancel_read (wl_display);
+ break;
+ }
+ goto error;
+ }
+
if (wl_display_read_events (wl_display) < 0)
goto error;
if (wl_display_dispatch_queue_pending (wl_display, priv->event_queue) < 0)
&shell_surface_listener, priv);
wl_shell_surface_set_toplevel (priv->shell_surface);
+ priv->poll = gst_poll_new (TRUE);
+ gst_poll_fd_init (&priv->pollfd);
+
if (priv->fullscreen_on_show)
gst_vaapi_window_wayland_set_fullscreen (window, TRUE);
gst_vaapi_filter_replace (&priv->filter, NULL);
gst_vaapi_video_pool_replace (&priv->surface_pool, NULL);
+
+ gst_poll_free (priv->poll);
}
static gboolean
return TRUE;
}
+static gboolean
+gst_vaapi_window_wayland_unblock (GstVaapiWindow * window)
+{
+ GstVaapiWindowWaylandPrivate *const priv =
+ GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
+
+ gst_poll_set_flushing (priv->poll, TRUE);
+
+ return TRUE;
+}
+
+static gboolean
+gst_vaapi_window_wayland_unblock_cancel (GstVaapiWindow * window)
+{
+ GstVaapiWindowWaylandPrivate *const priv =
+ GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
+
+ gst_poll_set_flushing (priv->poll, FALSE);
+
+ return TRUE;
+}
+
static void
gst_vaapi_window_wayland_class_init (GstVaapiWindowWaylandClass * klass)
{
window_class->render = gst_vaapi_window_wayland_render;
window_class->resize = gst_vaapi_window_wayland_resize;
window_class->set_fullscreen = gst_vaapi_window_wayland_set_fullscreen;
+ window_class->unblock = gst_vaapi_window_wayland_unblock;
+ window_class->unblock_cancel = gst_vaapi_window_wayland_unblock_cancel;
}
#define gst_vaapi_window_wayland_finalize \
}
}
+static gboolean
+gst_vaapisink_unlock (GstBaseSink * base_sink)
+{
+ GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink);
+
+ if (sink->window)
+ return gst_vaapi_window_unblock (sink->window);
+
+ return TRUE;
+}
+
+static gboolean
+gst_vaapisink_unlock_stop (GstBaseSink * base_sink)
+{
+ GstVaapiSink *const sink = GST_VAAPISINK_CAST (base_sink);
+
+ if (sink->window)
+ return gst_vaapi_window_unblock_cancel (sink->window);
+
+ return TRUE;
+}
+
static void
gst_vaapisink_set_bus (GstElement * element, GstBus * bus)
{
basesink_class->set_caps = gst_vaapisink_set_caps;
basesink_class->query = GST_DEBUG_FUNCPTR (gst_vaapisink_query);
basesink_class->propose_allocation = gst_vaapisink_propose_allocation;
+ basesink_class->unlock = gst_vaapisink_unlock;
+ basesink_class->unlock_stop = gst_vaapisink_unlock_stop;
videosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_vaapisink_show_frame);