Port to GstVideoContext interface.

This new interface allows for upstream and downstream display sharing
that works in both static and dynamic pipelines.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
This commit is contained in:
Nicolas Dufresne 2011-11-04 16:50:15 -04:00 committed by Gwenole Beauchesne
parent 2df43791d4
commit 99c5d18f41
10 changed files with 348 additions and 224 deletions

View file

@ -29,6 +29,13 @@ m4_define([gst_plugins_base_version],
m4_define([va_api_x11_version], [0.31.0])
m4_define([va_api_glx_version], [0.32.0])
# gst plugins-bad version number
m4_define([gst_plugins_bad_major_version], [0])
m4_define([gst_plugins_bad_minor_version], [10])
m4_define([gst_plugins_bad_micro_version], [22])
m4_define([gst_plugins_bad_version],
[gst_plugins_bad_major_version.gst_plugins_bad_minor_version.gst_plugins_bad_micro_version])
# libva package version number
m4_define([libva_x11_package_version], [1.0.3])
m4_define([libva_glx_package_version], [1.0.9])
@ -61,6 +68,7 @@ dnl Versions for GStreamer and plugins-base
GST_MAJORMINOR=gst_major_minor_version
GST_VERSION_REQUIRED=gst_version
GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version
GST_PLUGINS_BAD_VERSION_REQUIRED=gst_plugins_bad_version
AC_SUBST(GST_MAJORMINOR)
AC_SUBST(GST_VERSION_REQUIRED)
AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED)
@ -168,6 +176,13 @@ PKG_CHECK_MODULES([GST_VIDEO],
AC_SUBST(GST_VIDEO_CFLAGS)
AC_SUBST(GST_VIDEO_LIBS)
dnl Check for GStreamer basevideo
PKG_CHECK_MODULES([GST_BASEVIDEO],
[gstreamer-basevideo-$GST_MAJORMINOR >= $GST_PLUGINS_BAD_VERSION_REQUIRED]
)
AC_SUBST(GST_BASEVIDEO_CFLAGS)
AC_SUBST(GST_BASEVIDEO_LIBS)
dnl Check for GStreamer interfaces
PKG_CHECK_MODULES([GST_INTERFACES],
[gstreamer-interfaces-$GST_MAJORMINOR >= $GST_PLUGINS_BASE_VERSION_REQUIRED]

View file

@ -37,7 +37,6 @@ libgstvaapi_source_c = \
gstvaapisurfacepool.c \
gstvaapisurfaceproxy.c \
gstvaapiutils.c \
gstvaapiutils_gst.c \
gstvaapivalue.c \
gstvaapivideobuffer.c \
gstvaapivideopool.c \
@ -77,7 +76,6 @@ libgstvaapi_source_priv_h = \
gstvaapidisplay_priv.h \
gstvaapiobject_priv.h \
gstvaapiutils.h \
gstvaapiutils_gst.h \
$(libgst_vaapi_ffmpeg_source_priv_h) \
$(NULL)

View file

@ -1,108 +0,0 @@
/*
* gstvaapiutils_gst.c - GST utilties
*
* gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "gstvaapiutils_gst.h"
#include "gstvaapivideosink.h"
#include "gstvaapivideobuffer.h"
#define DEBUG 1
#include "gstvaapidebug.h"
static GstVaapiDisplay *
lookup_through_vaapisink_iface(GstElement *element)
{
GstVaapiDisplay *display;
GstVaapiVideoSink *sink;
GST_DEBUG("looking for a downstream vaapisink");
/* Look for a downstream vaapisink */
sink = gst_vaapi_video_sink_lookup(element);
if (!sink)
return NULL;
display = gst_vaapi_video_sink_get_display(sink);
GST_DEBUG(" found display %p", display);
return display;
}
static GstVaapiDisplay *
lookup_through_peer_buffer(GstElement *element)
{
GstVaapiDisplay *display;
GstPad *pad;
GstBuffer *buffer;
GstFlowReturn ret;
GST_DEBUG("looking for a GstVaapiVideoBuffer from peer");
/* Look for a GstVaapiVideoBuffer from peer */
pad = gst_element_get_static_pad(element, "src");
if (!pad)
return NULL;
buffer = NULL;
ret = gst_pad_alloc_buffer(pad, 0, 0, GST_PAD_CAPS(pad), &buffer);
g_object_unref(pad);
if (ret != GST_FLOW_OK || !buffer)
return NULL;
display = GST_VAAPI_IS_VIDEO_BUFFER(buffer) ?
gst_vaapi_video_buffer_get_display(GST_VAAPI_VIDEO_BUFFER(buffer)) :
NULL;
gst_buffer_unref(buffer);
GST_DEBUG(" found display %p", display);
return display;
}
/**
* gst_vaapi_display_lookup_downstream:
* @element: a #GstElement
*
* Finds a suitable #GstVaapiDisplay downstream from @element.
*
* 1. Check whether a downstream element implements the
* #GstVaapiVideoSinkInterface interface.
*
* 2. Check whether the @element peer implements a custom
* buffer_alloc() function that allocates #GstVaapiVideoBuffer
* buffers.
*
* Return value: a downstream allocated #GstVaapiDisplay object, or
* %NULL if none was found
*/
GstVaapiDisplay *
gst_vaapi_display_lookup_downstream(GstElement *element)
{
GstVaapiDisplay *display;
display = lookup_through_vaapisink_iface(element);
if (display)
return display;
display = lookup_through_peer_buffer(element);
if (display)
return display;
return NULL;
}

View file

@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgstvaapi.la
libgstvaapi_CFLAGS = \
$(LIBVA_CFLAGS) \
-DGST_USE_UNSTABLE_API \
-I$(top_srcdir)/gst-libs
if USE_VAAPI_GLX
@ -16,12 +17,14 @@ libgstvaapi_la_SOURCES = \
gstvaapi.c \
gstvaapiconvert.c \
gstvaapidecode.c \
gstvaapipluginutil.c \
gstvaapisink.c \
$(NULL)
noinst_HEADERS = \
gstvaapiconvert.h \
gstvaapidecode.h \
gstvaapipluginutil.h \
gstvaapisink.h \
$(NULL)
@ -31,6 +34,7 @@ libgstvaapi_la_CFLAGS = \
$(GST_BASE_CFLAGS) \
$(GST_VIDEO_CFLAGS) \
$(GST_INTERFACES_CFLAGS) \
$(GST_BASEVIDEO_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS)
libgstvaapi_la_LIBADD = \
@ -39,6 +43,7 @@ libgstvaapi_la_LIBADD = \
$(GST_BASE_LIBS) \
$(GST_VIDEO_LIBS) \
$(GST_INTERFACES_LIBS) \
$(GST_BASEVIDEO_LIBS) \
$(GST_PLUGINS_BASE_LIBS)
libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)

View file

@ -29,11 +29,14 @@
*/
#include "config.h"
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/videocontext.h>
#include <gst/vaapi/gstvaapivideosink.h>
#include <gst/vaapi/gstvaapivideobuffer.h>
#include <gst/vaapi/gstvaapiutils_gst.h>
#include "gstvaapipluginutil.h"
#include "gstvaapiconvert.h"
#define GST_PLUGIN_NAME "vaapiconvert"
@ -73,11 +76,15 @@ static GstStaticPadTemplate gst_vaapiconvert_src_factory =
GST_PAD_ALWAYS,
GST_STATIC_CAPS(gst_vaapiconvert_vaapi_caps_str));
GST_BOILERPLATE(
#define GstVideoContextClass GstVideoContextInterface
GST_BOILERPLATE_WITH_INTERFACE(
GstVaapiConvert,
gst_vaapiconvert,
GstBaseTransform,
GST_TYPE_BASE_TRANSFORM);
GST_TYPE_BASE_TRANSFORM,
GstVideoContext,
GST_TYPE_VIDEO_CONTEXT,
gst_video_context);
/*
* Direct rendering levels (direct-rendering)
@ -145,6 +152,34 @@ gst_vaapiconvert_prepare_output_buffer(
GstBuffer **poutbuf
);
static gboolean
gst_vaapiconvert_query(
GstPad *pad,
GstQuery *query
);
/* GstVideoContext interface */
static void
gst_vaapiconvert_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
GstVaapiConvert *convert = GST_VAAPICONVERT (context);
gst_vaapi_set_display (type, value, &convert->display);
}
static gboolean
gst_video_context_supported (GstVaapiConvert *convert, GType iface_type)
{
return (iface_type == GST_TYPE_VIDEO_CONTEXT);
}
static void
gst_video_context_interface_init(GstVideoContextInterface *iface)
{
iface->set_context = gst_vaapiconvert_set_video_context;
}
static void
gst_vaapiconvert_destroy(GstVaapiConvert *convert)
{
@ -289,7 +324,7 @@ gst_vaapiconvert_class_init(GstVaapiConvertClass *klass)
static void
gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass)
{
GstPad *sinkpad;
GstPad *sinkpad, *srcpad;
convert->display = NULL;
convert->images = NULL;
@ -310,20 +345,20 @@ gst_vaapiconvert_init(GstVaapiConvert *convert, GstVaapiConvertClass *klass)
gst_vaapiconvert_sinkpad_buffer_alloc
);
g_object_unref(sinkpad);
/* Override query on src pad */
srcpad = gst_element_get_static_pad(GST_ELEMENT(convert), "src");
gst_pad_set_query_function(srcpad, gst_vaapiconvert_query);
}
static gboolean
gst_vaapiconvert_start(GstBaseTransform *trans)
{
GstVaapiConvert * const convert = GST_VAAPICONVERT(trans);
GstVaapiDisplay *display;
/* Look for a downstream display */
display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(trans));
if (!display)
if (!gst_vaapi_ensure_display(convert, &convert->display))
return FALSE;
convert->display = g_object_ref(display);
return TRUE;
}
@ -766,3 +801,20 @@ gst_vaapiconvert_prepare_output_buffer(
*poutbuf = buffer;
return GST_FLOW_OK;
}
static gboolean
gst_vaapiconvert_query(GstPad *pad, GstQuery *query)
{
GstVaapiConvert *convert = GST_VAAPICONVERT (gst_pad_get_parent_element (pad));
gboolean res;
GST_DEBUG ("sharing display %p", convert->display);
if (gst_vaapi_reply_to_query (query, convert->display))
res = TRUE;
else
res = gst_pad_query_default (pad, query);
g_object_unref (convert);
return res;
}

View file

@ -29,12 +29,15 @@
*/
#include "config.h"
#include "gstvaapidecode.h"
#include <gst/vaapi/gstvaapidisplay_x11.h>
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapivideosink.h>
#include <gst/vaapi/gstvaapivideobuffer.h>
#include <gst/vaapi/gstvaapidecoder_ffmpeg.h>
#include <gst/vaapi/gstvaapiutils_gst.h>
#include <gst/video/videocontext.h>
#include "gstvaapidecode.h"
#include "gstvaapipluginutil.h"
#define GST_PLUGIN_NAME "vaapidecode"
#define GST_PLUGIN_DESC "A VA-API based video decoder"
@ -80,11 +83,15 @@ static GstStaticPadTemplate gst_vaapidecode_src_factory =
GST_PAD_ALWAYS,
GST_STATIC_CAPS(gst_vaapidecode_src_caps_str));
GST_BOILERPLATE(
#define GstVideoContextClass GstVideoContextInterface
GST_BOILERPLATE_WITH_INTERFACE(
GstVaapiDecode,
gst_vaapidecode,
GstElement,
GST_TYPE_ELEMENT);
GST_TYPE_ELEMENT,
GstVideoContext,
GST_TYPE_VIDEO_CONTEXT,
gst_video_context);
enum {
PROP_0,
@ -257,24 +264,10 @@ error_commit_buffer:
}
}
static inline gboolean
gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
{
GstVaapiDisplay *display;
if (!decode->display) {
display = gst_vaapi_display_lookup_downstream(GST_ELEMENT(decode));
if (!display)
return FALSE;
decode->display = g_object_ref(display);
}
return TRUE;
}
static gboolean
gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
{
if (!gst_vaapidecode_ensure_display(decode))
if (!gst_vaapi_ensure_display(decode, &decode->display))
return FALSE;
decode->decoder_mutex = g_mutex_new();
@ -339,6 +332,28 @@ gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps)
return gst_vaapidecode_create(decode, caps);
}
/* GstVideoContext interface */
static void
gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
GstVaapiDecode *decode = GST_VAAPIDECODE (context);
gst_vaapi_set_display (type, value, &decode->display);
}
static gboolean
gst_video_context_supported (GstVaapiDecode *decode, GType iface_type)
{
return (iface_type == GST_TYPE_VIDEO_CONTEXT);
}
static void
gst_video_context_interface_init(GstVideoContextInterface *iface)
{
iface->set_context = gst_vaapidecode_set_video_context;
}
static void
gst_vaapidecode_base_init(gpointer klass)
{
@ -494,15 +509,10 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
if (decode->allowed_caps)
return TRUE;
if (gst_vaapidecode_ensure_display(decode))
display = g_object_ref(decode->display);
else {
display = gst_vaapi_display_x11_new(NULL);
if (!display)
goto error_no_display;
}
if (!gst_vaapi_ensure_display(decode, &decode->display))
goto error_no_display;
decode_caps = gst_vaapi_display_get_decode_caps(display);
decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
if (!decode_caps)
goto error_no_decode_caps;
n_decode_caps = gst_caps_get_size(decode_caps);
@ -530,7 +540,6 @@ gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
}
gst_caps_unref(decode_caps);
g_object_unref(display);
return TRUE;
/* ERRORS */
@ -542,14 +551,12 @@ error_no_display:
error_no_decode_caps:
{
GST_DEBUG("failed to retrieve VA decode caps");
g_object_unref(display);
return FALSE;
}
error_no_memory:
{
GST_DEBUG("failed to allocate allowed-caps set");
gst_caps_unref(decode_caps);
g_object_unref(display);
return FALSE;
}
}
@ -621,6 +628,22 @@ gst_vaapidecode_src_event(GstPad *pad, GstEvent *event)
return gst_pad_push_event(decode->sinkpad, event);
}
static gboolean
gst_vaapidecode_query (GstPad *pad, GstQuery *query) {
GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad));
gboolean res;
GST_DEBUG ("sharing display %p", decode->display);
if (gst_vaapi_reply_to_query (query, decode->display))
res = TRUE;
else
res = gst_pad_query_default (pad, query);
g_object_unref (decode);
return res;
}
static void
gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
{
@ -656,5 +679,6 @@ gst_vaapidecode_init(GstVaapiDecode *decode, GstVaapiDecodeClass *klass)
gst_pad_use_fixed_caps(decode->srcpad);
gst_pad_set_event_function(decode->srcpad, gst_vaapidecode_src_event);
gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query);
gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad);
}

View file

@ -0,0 +1,162 @@
/*
* gstvaapipluginutil.h - VA-API plugin helpers
*
* Copyright (C) 2011 Intel Corporation
* Copyright (C) 2011 Collabora
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "gstvaapipluginutil.h"
#include <string.h>
#ifdef USE_VAAPI_GLX
#include <gst/vaapi/gstvaapidisplay_glx.h>
#else
#include <gst/vaapi/gstvaapidisplay_x11.h>
#endif
/* Preferred first */
static const char *display_types[] = {
"gst-vaapi-display",
"vaapi-display",
"x11-display",
"x11-display-name",
NULL
};
gboolean
gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display)
{
GstVideoContext *context;
g_return_val_if_fail (GST_IS_VIDEO_CONTEXT (element), FALSE);
g_return_val_if_fail (display != NULL, FALSE);
/* Already exist ? */
if (*display)
return TRUE;
context = GST_VIDEO_CONTEXT (element);
gst_video_context_prepare (context, display_types);
/* If no neighboor, or application not interested, use system default */
if (!*display)
#if USE_VAAPI_GLX
*display = gst_vaapi_display_glx_new ("");
#else
*display = gst_vaapi_display_x11_new ("");
#endif
/* FIXME allocator should return NULL in case of failure */
if (*display && !gst_vaapi_display_get_display(*display)) {
g_object_unref (*display);
*display = NULL;
}
return (*display != NULL);
}
void
gst_vaapi_set_display (const gchar *type,
const GValue *value,
GstVaapiDisplay **display)
{
GstVaapiDisplay *dpy = NULL;
if (!strcmp (type, "x11-display-name")) {
g_return_if_fail (G_VALUE_HOLDS_STRING (value));
#if USE_VAAPI_GLX
dpy = gst_vaapi_display_glx_new (g_value_get_string (value));
#else
dpy = gst_vaapi_display_x11_new (g_value_get_string (value));
#endif
} else if (!strcmp (type, "x11-display")) {
g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
#if USE_VAAPI_GLX
dpy = gst_vaapi_display_glx_new_with_display (g_value_get_pointer (value));
#else
dpy = gst_vaapi_display_x11_new_with_display (g_value_get_pointer (value));
#endif
} else if (!strcmp (type, "vaapi-display")) {
g_return_if_fail (G_VALUE_HOLDS_POINTER (value));
dpy = gst_vaapi_display_new_with_display (g_value_get_pointer (value));
} else if (!strcmp (type, "gst-vaapi-display")) {
g_return_if_fail (G_VALUE_HOLDS_OBJECT (value));
dpy = g_value_dup_object (value);
}
if (dpy) {
if (*display)
g_object_unref (*display);
*display = dpy;
}
}
gboolean
gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display)
{
const gchar **types;
const gchar *type;
gint i;
gboolean res = FALSE;
if (!display)
return FALSE;
types = gst_video_context_query_get_supported_types (query);
if (!types)
return FALSE;
for (i = 0; types[i]; i++) {
type = types[i];
if (!strcmp (type, "gst-vaapi-display")) {
gst_video_context_query_set_object (query, type, G_OBJECT (display));
} else if (!strcmp (type, "vaapi-display")) {
VADisplay vadpy = gst_vaapi_display_get_display(display);
gst_video_context_query_set_pointer (query, type, vadpy);
} else if (!strcmp (type, "x11-display") &&
GST_VAAPI_IS_DISPLAY_X11(display)) {
GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display);
Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy);
gst_video_context_query_set_pointer (query, type, x11dpy);
} else if (!strcmp (type, "x11-display-name") &&
GST_VAAPI_IS_DISPLAY_X11(display)) {
GstVaapiDisplayX11 *xvadpy = GST_VAAPI_DISPLAY_X11 (display);
Display *x11dpy = gst_vaapi_display_x11_get_display (xvadpy);
gst_video_context_query_set_string (query, type, DisplayString(x11dpy));
} else {
continue;
}
res = TRUE;
break;
}
return res;
}

View file

@ -1,7 +1,9 @@
/*
* gstvaapiutils_gst.h - GST utilties
* gstvaapipluginutil.h - VA-API plugins private helper
*
* gstreamer-vaapi (C) 2010-2011 Splitted-Desktop Systems
* Copyright (C) 2011 Intel Corporation
* Copyright (C) 2011 Collabora
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@ -19,13 +21,10 @@
* Boston, MA 02110-1301 USA
*/
#ifndef GST_VAAPI_UTILS_GST_H
#define GST_VAAPI_UTILS_GST_H
#include <gst/gst.h>
#include <gst/video/videocontext.h>
#include <gst/vaapi/gstvaapidisplay.h>
GstVaapiDisplay *
gst_vaapi_display_lookup_downstream(GstElement *element);
#endif /* GST_VAAPI_UTILS_GST_H */
gboolean gst_vaapi_ensure_display (gpointer element, GstVaapiDisplay **display);
void gst_vaapi_set_display (const gchar *type, const GValue *value, GstVaapiDisplay **display);
gboolean gst_vaapi_reply_to_query (GstQuery *query, GstVaapiDisplay *display);

View file

@ -31,8 +31,9 @@
#include "config.h"
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/gstutils_version.h>
#include <gst/video/video.h>
#include <gst/video/videocontext.h>
#include <gst/vaapi/gstvaapivideobuffer.h>
#include <gst/vaapi/gstvaapivideosink.h>
#include <gst/vaapi/gstvaapidisplay_x11.h>
@ -41,11 +42,13 @@
#include <gst/vaapi/gstvaapidisplay_glx.h>
#include <gst/vaapi/gstvaapiwindow_glx.h>
#endif
#include "gstvaapisink.h"
/* Supported interfaces */
#include <gst/interfaces/xoverlay.h>
#include "gstvaapisink.h"
#include "gstvaapipluginutil.h"
#define HAVE_GST_XOVERLAY_SET_WINDOW_HANDLE \
GST_PLUGINS_BASE_CHECK_VERSION(0,10,31)
@ -84,7 +87,6 @@ enum {
PROP_0,
PROP_USE_GLX,
PROP_DISPLAY,
PROP_FULLSCREEN,
PROP_SYNCHRONOUS,
PROP_USE_REFLECTION
@ -98,7 +100,7 @@ gst_vaapisink_implements_interface_supported(
GType type
)
{
return (type == GST_VAAPI_TYPE_VIDEO_SINK ||
return (type == GST_TYPE_VIDEO_CONTEXT ||
type == GST_TYPE_X_OVERLAY);
}
@ -110,19 +112,18 @@ gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface)
/* GstVaapiVideoSink interface */
static GstVaapiDisplay *
gst_vaapisink_get_display(GstVaapiSink *sink);
static GstVaapiDisplay *
gst_vaapi_video_sink_do_get_display(GstVaapiVideoSink *sink)
static void
gst_vaapisink_set_video_context(GstVideoContext *context, const gchar *type,
const GValue *value)
{
return gst_vaapisink_get_display(GST_VAAPISINK(sink));
GstVaapiSink *sink = GST_VAAPISINK (context);
gst_vaapi_set_display (type, value, &sink->display);
}
static void
gst_vaapi_video_sink_iface_init(GstVaapiVideoSinkInterface *iface)
gst_vaapisink_video_context_iface_init(GstVideoContextInterface *iface)
{
iface->get_display = gst_vaapi_video_sink_do_get_display;
iface->set_context = gst_vaapisink_set_video_context;
}
/* GstXOverlay interface */
@ -191,8 +192,8 @@ gst_vaapisink_iface_init(GType type)
G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
gst_vaapisink_implements_iface_init);
G_IMPLEMENT_INTERFACE(GST_VAAPI_TYPE_VIDEO_SINK,
gst_vaapi_video_sink_iface_init);
G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
gst_vaapisink_video_context_iface_init);
G_IMPLEMENT_INTERFACE(GST_TYPE_X_OVERLAY,
gst_vaapisink_xoverlay_iface_init);
}
@ -204,11 +205,6 @@ gst_vaapisink_destroy(GstVaapiSink *sink)
g_object_unref(sink->display);
sink->display = NULL;
}
if (sink->display_name) {
g_free(sink->display_name);
sink->display_name = NULL;
}
}
/* Checks whether a ConfigureNotify event is in the queue */
@ -262,23 +258,6 @@ configure_notify_event_pending(
return args.match;
}
static inline gboolean
gst_vaapisink_ensure_display(GstVaapiSink *sink)
{
if (!sink->display) {
#if USE_VAAPISINK_GLX
if (sink->use_glx)
sink->display = gst_vaapi_display_glx_new(sink->display_name);
else
#endif
sink->display = gst_vaapi_display_x11_new(sink->display_name);
if (!sink->display || !gst_vaapi_display_get_display(sink->display))
return FALSE;
g_object_set(sink, "synchronous", sink->synchronous, NULL);
}
return sink->display != NULL;
}
static gboolean
gst_vaapisink_ensure_render_rect(GstVaapiSink *sink, guint width, guint height)
{
@ -384,7 +363,7 @@ gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id)
int x, y;
XID xid = window_id;
if (!gst_vaapisink_ensure_display(sink))
if (!gst_vaapi_ensure_display(sink, &sink->display))
return FALSE;
gst_vaapi_display_lock(sink->display);
@ -427,8 +406,6 @@ gst_vaapisink_start(GstBaseSink *base_sink)
{
GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
if (!gst_vaapisink_ensure_display(sink))
return FALSE;
return TRUE;
}
@ -471,6 +448,9 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
sink->video_par_d = video_par_d;
GST_DEBUG("video pixel-aspect-ratio %d/%d", video_par_n, video_par_d);
if (!gst_vaapi_ensure_display(sink, &sink->display))
return FALSE;
gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
if (!gst_vaapisink_ensure_render_rect(sink, display_width, display_height))
return FALSE;
@ -515,6 +495,9 @@ gst_vaapisink_buffer_alloc(
GstStructure *structure;
GstBuffer *buffer;
if (!gst_vaapi_ensure_display(sink, &sink->display))
goto error_ensure_display;
structure = gst_caps_get_structure(caps, 0);
if (!gst_structure_has_name(structure, "video/x-vaapi-surface"))
goto error_invalid_caps;
@ -528,6 +511,11 @@ gst_vaapisink_buffer_alloc(
return GST_FLOW_OK;
/* ERRORS */
error_ensure_display:
{
GST_ERROR("failed to ensure display");
return GST_FLOW_UNEXPECTED;
}
error_invalid_caps:
{
GST_ERROR("failed to validate input caps");
@ -719,6 +707,12 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
guint flags;
gboolean success;
if (sink->display != gst_vaapi_video_buffer_get_display (vbuffer)) {
if (sink->display)
g_object_unref (sink->display);
sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer));
}
if (!sink->window)
return GST_FLOW_UNEXPECTED;
@ -740,6 +734,14 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
return success ? GST_FLOW_OK : GST_FLOW_UNEXPECTED;
}
static gboolean
gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query)
{
GstVaapiSink *sink = GST_VAAPISINK(base_sink);
GST_DEBUG ("sharing display %p", sink->display);
return gst_vaapi_reply_to_query (query, sink->display);
}
static void
gst_vaapisink_finalize(GObject *object)
{
@ -762,10 +764,6 @@ gst_vaapisink_set_property(
case PROP_USE_GLX:
sink->use_glx = g_value_get_boolean(value);
break;
case PROP_DISPLAY:
g_free(sink->display_name);
sink->display_name = g_strdup(g_value_get_string(value));
break;
case PROP_FULLSCREEN:
sink->fullscreen = g_value_get_boolean(value);
break;
@ -795,9 +793,6 @@ gst_vaapisink_get_property(
case PROP_USE_GLX:
g_value_set_boolean(value, sink->use_glx);
break;
case PROP_DISPLAY:
g_value_set_string(value, sink->display_name);
break;
case PROP_FULLSCREEN:
g_value_set_boolean(value, sink->fullscreen);
break;
@ -845,6 +840,7 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
basesink_class->buffer_alloc = gst_vaapisink_buffer_alloc;
basesink_class->preroll = gst_vaapisink_show_frame;
basesink_class->render = gst_vaapisink_show_frame;
basesink_class->query = gst_vaapisink_query;
#if USE_VAAPISINK_GLX
g_object_class_install_property
@ -866,15 +862,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
G_PARAM_READWRITE));
#endif
g_object_class_install_property
(object_class,
PROP_DISPLAY,
g_param_spec_string("display",
"X11 display name",
"X11 display name",
"",
G_PARAM_READWRITE));
g_object_class_install_property
(object_class,
PROP_FULLSCREEN,
@ -903,7 +890,6 @@ gst_vaapisink_class_init(GstVaapiSinkClass *klass)
static void
gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
{
sink->display_name = NULL;
sink->display = NULL;
sink->window = NULL;
sink->window_width = 0;
@ -919,11 +905,3 @@ gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
sink->use_glx = USE_VAAPISINK_GLX;
sink->use_reflection = FALSE;
}
GstVaapiDisplay *
gst_vaapisink_get_display(GstVaapiSink *sink)
{
if (!gst_vaapisink_ensure_display(sink))
return NULL;
return sink->display;
}

View file

@ -67,7 +67,6 @@ struct _GstVaapiSink {
/*< private >*/
GstVideoSink parent_instance;
gchar *display_name;
GstVaapiDisplay *display;
GstVaapiWindow *window;
guint window_width;