mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
Add VA/GLX support to vaapisink.
This commit is contained in:
parent
1165419fd0
commit
5e8b1d678f
3 changed files with 100 additions and 9 deletions
|
@ -3,8 +3,13 @@ plugin_LTLIBRARIES = libgstvaapisink.la
|
|||
libgstvaapi_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs
|
||||
|
||||
if USE_GLX
|
||||
libgstvaapi_LIBS = \
|
||||
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-glx-$(GST_MAJORMINOR).la
|
||||
else
|
||||
libgstvaapi_LIBS = \
|
||||
$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-$(GST_MAJORMINOR).la
|
||||
endif
|
||||
|
||||
libgstvaapisink_la_SOURCES = \
|
||||
gstvaapisink.c \
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include <gst/vaapi/gstvaapivideosink.h>
|
||||
#include <gst/vaapi/gstvaapidisplay_x11.h>
|
||||
#include <gst/vaapi/gstvaapiwindow_x11.h>
|
||||
#if USE_GLX
|
||||
#include <gst/vaapi/gstvaapidisplay_glx.h>
|
||||
#include <gst/vaapi/gstvaapiwindow_glx.h>
|
||||
#endif
|
||||
#include "gstvaapisink.h"
|
||||
|
||||
#define GST_PLUGIN_NAME "vaapisink"
|
||||
|
@ -73,6 +77,7 @@ GST_BOILERPLATE_FULL(
|
|||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_USE_GLX,
|
||||
PROP_DISPLAY,
|
||||
PROP_FULLSCREEN,
|
||||
PROP_SYNCHRONOUS
|
||||
|
@ -114,11 +119,32 @@ gst_vaapisink_destroy(GstVaapiSink *sink)
|
|||
}
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gst_vaapisink_ensure_window(GstVaapiSink *sink, guint width, guint height)
|
||||
{
|
||||
GstVaapiDisplay * const display = sink->display;
|
||||
|
||||
if (!sink->window) {
|
||||
#if USE_GLX
|
||||
if (sink->use_glx)
|
||||
sink->window = gst_vaapi_window_glx_new(display, width, height);
|
||||
else
|
||||
#endif
|
||||
sink->window = gst_vaapi_window_x11_new(display, width, height);
|
||||
}
|
||||
return sink->window != NULL;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gst_vaapisink_ensure_display(GstVaapiSink *sink)
|
||||
{
|
||||
if (!sink->display) {
|
||||
sink->display = gst_vaapi_display_x11_new(sink->display_name);
|
||||
#if USE_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);
|
||||
|
@ -171,6 +197,8 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
|
|||
return FALSE;
|
||||
if (!gst_structure_get_int(structure, "height", &video_height))
|
||||
return FALSE;
|
||||
sink->video_width = video_width;
|
||||
sink->video_height = video_height;
|
||||
|
||||
gst_video_parse_caps_pixel_aspect_ratio(caps, &video_par_n, &video_par_d);
|
||||
gst_vaapi_display_get_size(sink->display, &display_width, &display_height);
|
||||
|
@ -232,11 +260,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps)
|
|||
if (sink->window)
|
||||
gst_vaapi_window_set_size(sink->window, win_width, win_height);
|
||||
else {
|
||||
sink->window = gst_vaapi_window_x11_new(
|
||||
sink->display,
|
||||
win_width, win_height
|
||||
);
|
||||
if (!sink->window)
|
||||
if (!gst_vaapisink_ensure_window(sink, win_width, win_height))
|
||||
return FALSE;
|
||||
gst_vaapi_window_set_fullscreen(sink->window, sink->fullscreen);
|
||||
gst_vaapi_window_show(sink->window);
|
||||
|
@ -260,10 +284,43 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer)
|
|||
return GST_FLOW_UNEXPECTED;
|
||||
|
||||
flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
|
||||
if (!gst_vaapi_window_put_surface(sink->window, surface, NULL,
|
||||
&sink->window_rect, flags))
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
|
||||
#if USE_GLX
|
||||
if (sink->use_glx) {
|
||||
GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window);
|
||||
gst_vaapi_window_glx_make_current(window);
|
||||
if (!sink->texture) {
|
||||
sink->texture = gst_vaapi_texture_new(
|
||||
sink->display,
|
||||
GL_TEXTURE_2D,
|
||||
GL_BGRA,
|
||||
sink->video_width,
|
||||
sink->video_height
|
||||
);
|
||||
if (!sink->texture) {
|
||||
GST_DEBUG("could not create VA/GLX texture");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
if (!gst_vaapi_texture_put_surface(sink->texture, surface, flags)) {
|
||||
GST_DEBUG("could not transfer VA surface to texture");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
}
|
||||
if (!gst_vaapi_window_glx_put_texture(window, sink->texture,
|
||||
NULL, &sink->window_rect)) {
|
||||
GST_DEBUG("could not render VA/GLX texture");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
}
|
||||
gst_vaapi_window_glx_swap_buffers(window);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!gst_vaapi_window_put_surface(sink->window, surface,
|
||||
NULL, &sink->window_rect, flags)) {
|
||||
GST_DEBUG("could not render VA surface");
|
||||
return GST_FLOW_UNEXPECTED;
|
||||
}
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
@ -286,6 +343,9 @@ gst_vaapisink_set_property(
|
|||
GstVaapiSink * const sink = GST_VAAPISINK(object);
|
||||
|
||||
switch (prop_id) {
|
||||
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));
|
||||
|
@ -313,6 +373,9 @@ gst_vaapisink_get_property(
|
|||
GstVaapiSink * const sink = GST_VAAPISINK(object);
|
||||
|
||||
switch (prop_id) {
|
||||
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;
|
||||
|
@ -355,6 +418,17 @@ static void gst_vaapisink_class_init(GstVaapiSinkClass *klass)
|
|||
basesink_class->preroll = gst_vaapisink_show_frame;
|
||||
basesink_class->render = gst_vaapisink_show_frame;
|
||||
|
||||
#if USE_GLX
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_USE_GLX,
|
||||
g_param_spec_boolean("use-glx",
|
||||
"GLX rendering",
|
||||
"Enables GLX rendering",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
#endif
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class,
|
||||
PROP_DISPLAY,
|
||||
|
@ -393,8 +467,13 @@ static void gst_vaapisink_init(GstVaapiSink *sink, GstVaapiSinkClass *klass)
|
|||
{
|
||||
sink->display_name = NULL;
|
||||
sink->display = NULL;
|
||||
sink->window = NULL;
|
||||
sink->texture = NULL;
|
||||
sink->video_width = 0;
|
||||
sink->video_height = 0;
|
||||
sink->fullscreen = FALSE;
|
||||
sink->synchronous = FALSE;
|
||||
sink->use_glx = FALSE;
|
||||
}
|
||||
|
||||
GstVaapiDisplay *
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include <gst/video/gstvideosink.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
#include <gst/vaapi/gstvaapiwindow.h>
|
||||
#if USE_GLX
|
||||
#include <gst/vaapi/gstvaapitexture.h>
|
||||
#endif
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -63,8 +66,12 @@ struct _GstVaapiSink {
|
|||
GstVaapiDisplay *display;
|
||||
GstVaapiWindow *window;
|
||||
GstVaapiRectangle window_rect;
|
||||
GstVaapiTexture *texture;
|
||||
guint video_width;
|
||||
guint video_height;
|
||||
guint fullscreen : 1;
|
||||
guint synchronous : 1;
|
||||
guint use_glx : 1;
|
||||
};
|
||||
|
||||
struct _GstVaapiSinkClass {
|
||||
|
|
Loading…
Reference in a new issue