- supports render to Pixmap for vaapisink
- supports multiple Pixmap with an array in vaapisink
- add 'is-pixmap' attribute to vaapisink
- reset sink->window when _stop
guint create_window : 1;
guint is_mapped : 1;
guint fullscreen_on_map : 1;
guint create_window : 1;
guint is_mapped : 1;
guint fullscreen_on_map : 1;
+/*
+ * is_pixmap will be used by _create(), but _new_with_xid() doesn't have
+ * a chance to set the flag, so add this flag here.
+ * TODO, we'd better add is_pixmap flag to base class: GstVaapiWindow
+*/
+
+static gboolean _is_pixmap = FALSE;
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
#define _NET_WM_STATE_ADD 1 /* add/set property */
if (!priv->create_window && xid) {
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
if (!priv->create_window && xid) {
GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
- XGetWindowAttributes(dpy, xid, &wattr);
- priv->is_mapped = wattr.map_state == IsViewable;
+ if (_is_pixmap) {
+ priv->is_mapped = TRUE;
+ }
+ else {
+ XGetWindowAttributes(dpy, xid, &wattr);
+ priv->is_mapped = wattr.map_state == IsViewable;
+ }
ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
return ok;
ok = x11_get_geometry(dpy, xid, NULL, NULL, width, height);
GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
return ok;
priv->create_window = TRUE;
priv->is_mapped = FALSE;
priv->fullscreen_on_map = FALSE;
priv->create_window = TRUE;
priv->is_mapped = FALSE;
priv->fullscreen_on_map = FALSE;
+ priv->is_pixmap = FALSE;
* Return value: the newly allocated #GstVaapiWindow object
*/
GstVaapiWindow *
* Return value: the newly allocated #GstVaapiWindow object
*/
GstVaapiWindow *
-gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid)
+gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid, gboolean is_pixmap)
+ GstVaapiWindow * window = NULL;
GST_DEBUG("new window from xid 0x%08x", xid);
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(xid != None, NULL);
GST_DEBUG("new window from xid 0x%08x", xid);
g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
g_return_val_if_fail(xid != None, NULL);
-
- return g_object_new(GST_VAAPI_TYPE_WINDOW_X11,
+
+ _is_pixmap = is_pixmap;
+ window = g_object_new(GST_VAAPI_TYPE_WINDOW_X11,
"display", display,
"id", GST_VAAPI_ID(xid),
NULL);
"display", display,
"id", GST_VAAPI_ID(xid),
NULL);
+
+ if (window) {
+ GstVaapiWindowX11Private *priv = GST_VAAPI_WINDOW_X11_GET_PRIVATE(window);
+ priv->is_pixmap = is_pixmap;
+ }
+
+ return window;
return !window->priv->create_window;
}
return !window->priv->create_window;
}
+
+/**
+ * gst_vaapi_window_x11_is_pixmap:
+ * @window: a #GstVaapiWindowX11
+ *
+ * Checks whether the @window XID is Pixmap or Window
+ *
+ * Return value: %TRUE if the underlying X Drawble is Pixmap
+ */
+gboolean
+gst_vaapi_window_x11_is_pixmap(GstVaapiWindowX11 *window)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), FALSE);
+
+ return window->priv->is_pixmap;
+}
+
gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height);
GstVaapiWindow *
gst_vaapi_window_x11_new(GstVaapiDisplay *display, guint width, guint height);
GstVaapiWindow *
-gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid);
+gst_vaapi_window_x11_new_with_xid(GstVaapiDisplay *display, Window xid, gboolean is_pixmap);
Window
gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window);
Window
gst_vaapi_window_x11_get_xid(GstVaapiWindowX11 *window);
PROP_SYNCHRONOUS,
PROP_USE_REFLECTION,
PROP_ROTATION,
PROP_SYNCHRONOUS,
PROP_USE_REFLECTION,
PROP_ROTATION,
};
#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY
};
#define DEFAULT_DISPLAY_TYPE GST_VAAPI_DISPLAY_TYPE_ANY
{
Window rootwin;
unsigned int width, height, border_width, depth;
{
Window rootwin;
unsigned int width, height, border_width, depth;
XID xid = window_id;
if (!gst_vaapisink_ensure_display(sink))
XID xid = window_id;
if (!gst_vaapisink_ensure_display(sink))
sink->window_height = height;
}
sink->window_height = height;
}
- if (sink->window &&
- gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid)
- return TRUE;
-
- g_clear_object(&sink->window);
+ if (sink->is_pixmap) {
+ for (i = 0; i < MAX_PIXMAP_COUNT; i++) {
+ if (sink->pixmap_pool[i])
+ if (sink->pixmap_pool[i] &&
+ gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->pixmap_pool[i])) == xid) {
+ sink->window = sink->pixmap_pool[i];
+ return TRUE;
+ }
+ }
+ }
+ else {
+ if (sink->window &&
+ gst_vaapi_window_x11_get_xid(GST_VAAPI_WINDOW_X11(sink->window)) == xid)
+ return TRUE;
+ g_clear_object(&sink->window);
+ }
switch (sink->display_type) {
#if USE_GLX
switch (sink->display_type) {
#if USE_GLX
break;
#endif
case GST_VAAPI_DISPLAY_TYPE_X11:
break;
#endif
case GST_VAAPI_DISPLAY_TYPE_X11:
- sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid);
+ sink->window = gst_vaapi_window_x11_new_with_xid(sink->display, xid, sink->is_pixmap);
break;
default:
GST_ERROR("unsupported display type %d", sink->display_type);
return FALSE;
}
break;
default:
GST_ERROR("unsupported display type %d", sink->display_type);
return FALSE;
}
+
+ gboolean save_pixmap_to_pool = FALSE;
+ for (i = 0; i < MAX_PIXMAP_COUNT; i++) {
+ if (!sink->pixmap_pool[i]) {
+ sink->pixmap_pool[i] = sink->window;
+ save_pixmap_to_pool = TRUE;
+ break;
+ }
+ }
+
+ if (!save_pixmap_to_pool) {
+ g_clear_object(&sink->pixmap_pool[MAX_PIXMAP_COUNT-1]);
+ sink->pixmap_pool[MAX_PIXMAP_COUNT-1] = sink->window;
+ GST_WARNING("exceed MAX_PIXMAP_COUNT: %d", MAX_PIXMAP_COUNT);
+ }
+
return sink->window != NULL;
}
#endif
return sink->window != NULL;
}
#endif
static gboolean
gst_vaapisink_stop(GstBaseSink *base_sink)
{
static gboolean
gst_vaapisink_stop(GstBaseSink *base_sink)
{
GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
gst_buffer_replace(&sink->video_buffer, NULL);
GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
gst_buffer_replace(&sink->video_buffer, NULL);
- g_clear_object(&sink->window);
+ if (sink->is_pixmap) {
+ for (i=0; i<MAX_PIXMAP_COUNT; i++) {
+ if (sink->pixmap_pool[i]) {
+ g_clear_object(&sink->pixmap_pool[i]);
+ }
+ }
+ }
+ else
+ g_clear_object(&sink->window);
+ sink->window = NULL;
+
g_clear_object(&sink->display);
return TRUE;
g_clear_object(&sink->display);
return TRUE;
case PROP_ROTATION:
sink->rotation_req = g_value_get_enum(value);
break;
case PROP_ROTATION:
sink->rotation_req = g_value_get_enum(value);
break;
+ case PROP_IS_PIXMAP:
+ sink->is_pixmap = g_value_get_boolean(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
case PROP_ROTATION:
g_value_set_enum(value, sink->rotation);
break;
case PROP_ROTATION:
g_value_set_enum(value, sink->rotation);
break;
+ case PROP_IS_PIXMAP:
+ g_value_set_boolean(value, sink->is_pixmap);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
GST_VAAPI_TYPE_ROTATION,
DEFAULT_ROTATION,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
GST_VAAPI_TYPE_ROTATION,
DEFAULT_ROTATION,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_IS_PIXMAP,
+ g_param_spec_boolean("is-pixmap",
+ "IsPixmap",
+ "the X drawable is Pixmap or not",
+ FALSE,
+ G_PARAM_READWRITE));
+
}
static void
gst_vaapisink_init(GstVaapiSink *sink)
{
}
static void
gst_vaapisink_init(GstVaapiSink *sink)
{
sink->caps = NULL;
sink->display = NULL;
sink->window = NULL;
sink->caps = NULL;
sink->display = NULL;
sink->window = NULL;
sink->use_reflection = FALSE;
sink->use_overlay = FALSE;
sink->use_rotation = FALSE;
sink->use_reflection = FALSE;
sink->use_overlay = FALSE;
sink->use_rotation = FALSE;
+ sink->is_pixmap = FALSE;
+
+ for (i=0; i<MAX_PIXMAP_COUNT; i++) {
+ sink->pixmap_pool[i] = NULL;
+ }
typedef struct _GstVaapiTexture GstVaapiTexture;
#endif
typedef struct _GstVaapiTexture GstVaapiTexture;
#endif
+#define MAX_PIXMAP_COUNT 20
+
struct _GstVaapiSink {
/*< private >*/
GstVideoSink parent_instance;
struct _GstVaapiSink {
/*< private >*/
GstVideoSink parent_instance;
guint use_reflection : 1;
guint use_overlay : 1;
guint use_rotation : 1;
guint use_reflection : 1;
guint use_overlay : 1;
guint use_rotation : 1;
+ guint is_pixmap : 1;
+ GstVaapiWindow *pixmap_pool[MAX_PIXMAP_COUNT];
};
struct _GstVaapiSinkClass {
};
struct _GstVaapiSinkClass {
if (!win)
g_error("could not create X window");
if (!win)
g_error("could not create X window");
- window = gst_vaapi_window_x11_new_with_xid(display, win);
+ window = gst_vaapi_window_x11_new_with_xid(display, win, FALSE);
if (!window)
g_error("could not create window");
if (!window)
g_error("could not create window");