2012-07-23 13:17:03 +00:00
|
|
|
/*
|
|
|
|
* output.c - Video output helpers
|
|
|
|
*
|
2013-01-29 13:14:45 +00:00
|
|
|
* Copyright (C) 2012-2013 Intel Corporation
|
2013-11-22 04:57:18 +00:00
|
|
|
* Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
|
2012-07-23 13:17:03 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2013-03-20 10:50:15 +00:00
|
|
|
#include "gst/vaapi/sysdeps.h"
|
2012-07-23 13:17:03 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <gst/gst.h>
|
2012-08-01 13:44:49 +00:00
|
|
|
#if USE_DRM
|
|
|
|
# include <gst/vaapi/gstvaapidisplay_drm.h>
|
|
|
|
# include <gst/vaapi/gstvaapiwindow_drm.h>
|
|
|
|
#endif
|
2012-07-23 13:17:03 +00:00
|
|
|
#if USE_X11
|
|
|
|
# include <gst/vaapi/gstvaapidisplay_x11.h>
|
|
|
|
# include <gst/vaapi/gstvaapiwindow_x11.h>
|
2013-07-22 07:03:30 +00:00
|
|
|
# include <gst/vaapi/gstvaapipixmap_x11.h>
|
2012-07-23 13:17:03 +00:00
|
|
|
#endif
|
2012-07-23 13:20:23 +00:00
|
|
|
#if USE_GLX
|
|
|
|
# include <gst/vaapi/gstvaapidisplay_glx.h>
|
|
|
|
# include <gst/vaapi/gstvaapiwindow_glx.h>
|
|
|
|
#endif
|
2014-12-01 13:52:39 +00:00
|
|
|
#if USE_EGL
|
|
|
|
# include <gst/vaapi/gstvaapidisplay_egl.h>
|
|
|
|
# include <gst/vaapi/gstvaapiwindow_egl.h>
|
|
|
|
#endif
|
2012-07-23 10:56:33 +00:00
|
|
|
#if USE_WAYLAND
|
|
|
|
# include <gst/vaapi/gstvaapidisplay_wayland.h>
|
|
|
|
# include <gst/vaapi/gstvaapiwindow_wayland.h>
|
|
|
|
#endif
|
2012-07-23 13:17:03 +00:00
|
|
|
#include "output.h"
|
|
|
|
|
|
|
|
static const VideoOutputInfo *g_video_output;
|
|
|
|
static const VideoOutputInfo g_video_outputs[] = {
|
2016-04-29 10:48:44 +00:00
|
|
|
/* Video outputs are sorted in test order for automatic characterisation */
|
2012-07-23 10:56:33 +00:00
|
|
|
#if USE_WAYLAND
|
2016-04-29 10:48:44 +00:00
|
|
|
{"wayland",
|
|
|
|
gst_vaapi_display_wayland_new,
|
|
|
|
gst_vaapi_window_wayland_new},
|
2012-07-23 10:56:33 +00:00
|
|
|
#endif
|
2012-07-23 13:17:03 +00:00
|
|
|
#if USE_X11
|
2016-04-29 10:48:44 +00:00
|
|
|
{"x11",
|
|
|
|
gst_vaapi_display_x11_new,
|
|
|
|
gst_vaapi_window_x11_new,
|
|
|
|
gst_vaapi_pixmap_x11_new},
|
2012-07-23 13:20:23 +00:00
|
|
|
#endif
|
|
|
|
#if USE_GLX
|
2016-04-29 10:48:44 +00:00
|
|
|
{"glx",
|
|
|
|
gst_vaapi_display_glx_new,
|
|
|
|
gst_vaapi_window_glx_new,
|
|
|
|
gst_vaapi_pixmap_x11_new},
|
2012-08-01 13:44:49 +00:00
|
|
|
#endif
|
|
|
|
#if USE_DRM
|
2016-04-29 10:48:44 +00:00
|
|
|
{"drm",
|
|
|
|
gst_vaapi_display_drm_new,
|
|
|
|
gst_vaapi_window_drm_new},
|
2012-07-23 13:17:03 +00:00
|
|
|
#endif
|
2016-04-29 10:48:44 +00:00
|
|
|
{NULL,}
|
2012-07-23 13:17:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static gchar *g_output_name;
|
|
|
|
static gboolean g_list_outputs = FALSE;
|
2013-01-15 16:47:13 +00:00
|
|
|
static gboolean g_fullscreen = FALSE;
|
2012-07-23 13:17:03 +00:00
|
|
|
|
2014-12-01 13:52:39 +00:00
|
|
|
static gboolean g_egl_mode = FALSE;
|
|
|
|
static guint g_gles_version;
|
|
|
|
|
2012-07-23 13:17:03 +00:00
|
|
|
static GOptionEntry g_options[] = {
|
2016-04-29 10:48:44 +00:00
|
|
|
{"list-outputs", 0,
|
|
|
|
0,
|
|
|
|
G_OPTION_ARG_NONE, &g_list_outputs,
|
|
|
|
"list video outputs", NULL},
|
|
|
|
{"output", 'o',
|
|
|
|
0,
|
|
|
|
G_OPTION_ARG_STRING, &g_output_name,
|
|
|
|
"video output name", NULL},
|
|
|
|
{"fullscreen", 'f',
|
|
|
|
0,
|
|
|
|
G_OPTION_ARG_NONE, &g_fullscreen,
|
|
|
|
"fullscreen mode", NULL},
|
|
|
|
{"egl", 0,
|
|
|
|
0,
|
|
|
|
G_OPTION_ARG_NONE, &g_egl_mode,
|
|
|
|
"enable EGL rendering", NULL},
|
|
|
|
{"gles-version", 0,
|
|
|
|
0,
|
|
|
|
G_OPTION_ARG_INT, &g_gles_version,
|
|
|
|
"OpenGL|ES version (in --egl mode)", NULL},
|
|
|
|
{NULL,}
|
2012-07-23 13:17:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2016-04-29 10:48:44 +00:00
|
|
|
list_outputs (void)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
const VideoOutputInfo *o;
|
2012-07-23 13:17:03 +00:00
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
g_print ("Video outputs:");
|
|
|
|
for (o = g_video_outputs; o->name != NULL; o++)
|
|
|
|
g_print (" %s", o->name);
|
|
|
|
g_print ("\n");
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_init (int *argc, char *argv[], GOptionEntry * options)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
GOptionContext *ctx;
|
|
|
|
gboolean success;
|
2012-07-23 13:17:03 +00:00
|
|
|
|
|
|
|
#if !GLIB_CHECK_VERSION(2,31,0)
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!g_thread_supported ())
|
|
|
|
g_thread_init (NULL);
|
2012-07-23 13:17:03 +00:00
|
|
|
#endif
|
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
ctx = g_option_context_new ("- test options");
|
|
|
|
if (!ctx)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
g_option_context_add_group (ctx, gst_init_get_option_group ());
|
|
|
|
g_option_context_add_main_entries (ctx, g_options, NULL);
|
|
|
|
if (options)
|
|
|
|
g_option_context_add_main_entries (ctx, options, NULL);
|
|
|
|
success = g_option_context_parse (ctx, argc, &argv, NULL);
|
|
|
|
g_option_context_free (ctx);
|
|
|
|
|
|
|
|
if (g_list_outputs) {
|
|
|
|
list_outputs ();
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
return success;
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_exit (void)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
g_free (g_output_name);
|
|
|
|
gst_deinit ();
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const VideoOutputInfo *
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_lookup (const gchar * output_name)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
const VideoOutputInfo *o;
|
2012-07-23 13:17:03 +00:00
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!output_name)
|
2012-07-23 13:17:03 +00:00
|
|
|
return NULL;
|
2016-04-29 10:48:44 +00:00
|
|
|
|
|
|
|
for (o = g_video_outputs; o->name != NULL; o++) {
|
|
|
|
if (g_ascii_strcasecmp (o->name, output_name) == 0)
|
|
|
|
return o;
|
|
|
|
}
|
|
|
|
return NULL;
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GstVaapiDisplay *
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_create_display (const gchar * display_name)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
const VideoOutputInfo *o = g_video_output;
|
|
|
|
GstVaapiDisplay *egl_display, *display = NULL;
|
|
|
|
|
|
|
|
if (!o) {
|
|
|
|
if (g_output_name)
|
|
|
|
o = video_output_lookup (g_output_name);
|
|
|
|
else {
|
|
|
|
for (o = g_video_outputs; o->name != NULL; o++) {
|
|
|
|
display = o->create_display (display_name);
|
|
|
|
if (display) {
|
|
|
|
if (gst_vaapi_display_get_display (display))
|
|
|
|
break;
|
|
|
|
gst_vaapi_display_unref (display);
|
|
|
|
display = NULL;
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
2016-04-29 10:48:44 +00:00
|
|
|
}
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!o || !o->name)
|
|
|
|
return NULL;
|
|
|
|
g_print ("Using %s video output\n", o->name);
|
|
|
|
g_video_output = o;
|
|
|
|
}
|
2012-07-23 13:17:03 +00:00
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!display)
|
|
|
|
display = o->create_display (display_name);
|
2014-12-01 13:52:39 +00:00
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
if (g_egl_mode) {
|
2014-12-01 13:52:39 +00:00
|
|
|
#if USE_EGL
|
2016-04-29 10:48:44 +00:00
|
|
|
egl_display = gst_vaapi_display_egl_new (display, g_gles_version);
|
2014-12-01 13:52:39 +00:00
|
|
|
#else
|
2016-04-29 10:48:44 +00:00
|
|
|
egl_display = NULL;
|
|
|
|
g_print ("error: unsupported EGL renderering mode\n");
|
2014-12-01 13:52:39 +00:00
|
|
|
#endif
|
2016-04-29 10:48:44 +00:00
|
|
|
gst_vaapi_display_unref (display);
|
|
|
|
if (!egl_display)
|
|
|
|
return NULL;
|
|
|
|
display = egl_display;
|
|
|
|
}
|
|
|
|
return display;
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GstVaapiWindow *
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_create_window (GstVaapiDisplay * display, guint width,
|
|
|
|
guint height)
|
2012-07-23 13:17:03 +00:00
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
GstVaapiWindow *window;
|
2013-01-15 16:47:13 +00:00
|
|
|
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!g_video_output)
|
|
|
|
return NULL;
|
2013-01-15 16:47:13 +00:00
|
|
|
|
2014-12-01 13:52:39 +00:00
|
|
|
#if USE_EGL
|
2016-04-29 10:48:44 +00:00
|
|
|
if (g_egl_mode)
|
|
|
|
window = gst_vaapi_window_egl_new (display, width, height);
|
|
|
|
else
|
2014-12-01 13:52:39 +00:00
|
|
|
#endif
|
2016-04-29 10:48:44 +00:00
|
|
|
window = g_video_output->create_window (display, width, height);
|
|
|
|
if (!window)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Force fullscreen mode, should this be requested by the user */
|
|
|
|
if (g_fullscreen)
|
|
|
|
gst_vaapi_window_set_fullscreen (window, TRUE);
|
|
|
|
return window;
|
2012-07-23 13:17:03 +00:00
|
|
|
}
|
2013-07-22 07:03:30 +00:00
|
|
|
|
|
|
|
GstVaapiPixmap *
|
2016-04-29 10:48:44 +00:00
|
|
|
video_output_create_pixmap (GstVaapiDisplay * display, GstVideoFormat format,
|
2013-07-22 07:03:30 +00:00
|
|
|
guint width, guint height)
|
|
|
|
{
|
2016-04-29 10:48:44 +00:00
|
|
|
if (!g_video_output || !g_video_output->create_pixmap)
|
|
|
|
return NULL;
|
|
|
|
return g_video_output->create_pixmap (display, format, width, height);
|
2013-07-22 07:03:30 +00:00
|
|
|
}
|