mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 14:06:23 +00:00
plugins: create a GL context on certain conditions
If a GstVaapiDisplay is not found in the GStreamer context sharing, then VAAPI elements look for a local GstGLContext in gst context sharing mechanism ('gst.gl.local.context'). If this GstGLContext not found either then, only the VAAPI decoders and the VAAPI post-processor, will try to instantiate a new GstGLContext. If a valid GstGLContext is received, then a new GstVaapiDisplay will be instantiated with the platform, API and windowing specified by the instantiated GstGLContext. Original-Patch-By: Matt Fischer <matt.fischer@garmin.com> https://bugzilla.gnome.org/show_bug.cgi?id=777409
This commit is contained in:
parent
43d4f0bfb5
commit
0968ce468d
3 changed files with 95 additions and 15 deletions
|
@ -30,6 +30,9 @@
|
|||
#include "gstvaapivideocontext.h"
|
||||
#include "gstvaapivideometa.h"
|
||||
#include "gstvaapivideobufferpool.h"
|
||||
#if USE_GST_GL_HELPERS
|
||||
# include <gst/gl/gl.h>
|
||||
#endif
|
||||
|
||||
/* Default debug category is from the subclass */
|
||||
#define GST_CAT_DEFAULT (plugin->debug_category)
|
||||
|
@ -75,6 +78,12 @@ gst_vaapi_plugin_base_set_context (GstVaapiPluginBase * plugin,
|
|||
|
||||
if (gst_vaapi_video_context_get_display (context, &display))
|
||||
plugin_set_display (plugin, display);
|
||||
|
||||
#if USE_GST_GL_HELPERS
|
||||
gst_gl_handle_set_context (GST_ELEMENT_CAST (plugin), context,
|
||||
(GstGLDisplay **) & plugin->gl_display,
|
||||
(GstGLContext **) & plugin->gl_other_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,17 +224,6 @@ plugin_reset_texture_map (GstVaapiPluginBase * plugin)
|
|||
gst_vaapi_display_reset_texture_map (plugin->display);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_plugin_base_find_gl_context (GstVaapiPluginBase * plugin)
|
||||
{
|
||||
GstObject *gl_context;
|
||||
|
||||
if (!gst_vaapi_find_gl_local_context (GST_ELEMENT_CAST (plugin), &gl_context))
|
||||
return;
|
||||
gst_vaapi_plugin_base_set_gl_context (plugin, gl_context);
|
||||
gst_object_unref (gl_context);
|
||||
}
|
||||
|
||||
void
|
||||
gst_vaapi_plugin_base_class_init (GstVaapiPluginBaseClass * klass)
|
||||
{
|
||||
|
@ -292,6 +290,8 @@ gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin)
|
|||
|
||||
gst_vaapi_display_replace (&plugin->display, NULL);
|
||||
gst_object_replace (&plugin->gl_context, NULL);
|
||||
gst_object_replace (&plugin->gl_display, NULL);
|
||||
gst_object_replace (&plugin->gl_other_context, NULL);
|
||||
|
||||
gst_caps_replace (&plugin->sinkpad_caps, NULL);
|
||||
gst_video_info_init (&plugin->sinkpad_info);
|
||||
|
@ -386,10 +386,6 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin)
|
|||
return TRUE;
|
||||
gst_vaapi_display_replace (&plugin->display, NULL);
|
||||
|
||||
/* Query for a local GstGL context. If it's found, it will be used
|
||||
* to create the VA display */
|
||||
gst_vaapi_plugin_base_find_gl_context (plugin);
|
||||
|
||||
if (!gst_vaapi_ensure_display (GST_ELEMENT (plugin),
|
||||
plugin->display_type_req))
|
||||
return FALSE;
|
||||
|
@ -1121,6 +1117,56 @@ gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin,
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_vaapi_plugin_base_create_gl_context:
|
||||
* @plugin: a #GstVaapiPluginBase
|
||||
*
|
||||
* It queries downstream and upstream for a #GstGLDisplay and a other
|
||||
* #GstGLContext. If not found, a new #GstGLDisplay and #GstGLContext
|
||||
* are created, if it is possible.
|
||||
*
|
||||
* Returns: (transfer full) a new created #GstGLContext or %NULL
|
||||
**/
|
||||
GstObject *
|
||||
gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin)
|
||||
{
|
||||
#if USE_GST_GL_HELPERS
|
||||
GstGLContext *gl_other_context, *gl_context = NULL;
|
||||
GstGLDisplay *gl_display;
|
||||
|
||||
gst_gl_ensure_element_data (plugin, (GstGLDisplay **) & plugin->gl_display,
|
||||
(GstGLContext **) & plugin->gl_other_context);
|
||||
|
||||
gl_display = (GstGLDisplay *) plugin->gl_display;
|
||||
if (!gl_display ||
|
||||
gst_gl_display_get_handle_type (gl_display) == GST_GL_DISPLAY_TYPE_ANY) {
|
||||
gst_object_replace (&plugin->gl_display, NULL);
|
||||
gst_object_replace (&plugin->gl_other_context, NULL);
|
||||
return NULL;
|
||||
}
|
||||
gl_other_context = (GstGLContext *) plugin->gl_other_context;
|
||||
|
||||
GST_INFO_OBJECT (plugin, "creating a new GstGL context");
|
||||
|
||||
GST_OBJECT_LOCK (gl_display);
|
||||
do {
|
||||
if (gl_context)
|
||||
gst_object_unref (gl_context);
|
||||
gl_context = gst_gl_display_get_gl_context_for_thread (gl_display, NULL);
|
||||
if (!gl_context) {
|
||||
if (!gst_gl_display_create_context (gl_display, gl_other_context,
|
||||
&gl_context, NULL))
|
||||
break;
|
||||
}
|
||||
} while (!gst_gl_display_add_context (gl_display, gl_context));
|
||||
GST_OBJECT_UNLOCK (gl_display);
|
||||
|
||||
return GST_OBJECT_CAST (gl_context);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_allowed_raw_caps (GstVaapiPluginBase * plugin)
|
||||
{
|
||||
|
|
|
@ -140,6 +140,8 @@ struct _GstVaapiPluginBase
|
|||
gchar *display_name;
|
||||
|
||||
GstObject *gl_context;
|
||||
GstObject *gl_display;
|
||||
GstObject *gl_other_context;
|
||||
|
||||
GstCaps *allowed_raw_caps;
|
||||
GstAllocator *sinkpad_allocator;
|
||||
|
@ -236,6 +238,10 @@ void
|
|||
gst_vaapi_plugin_base_set_gl_context (GstVaapiPluginBase * plugin,
|
||||
GstObject * object);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstObject *
|
||||
gst_vaapi_plugin_base_create_gl_context (GstVaapiPluginBase * plugin);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstCaps *
|
||||
gst_vaapi_plugin_base_get_allowed_raw_caps (GstVaapiPluginBase * plugin);
|
||||
|
|
|
@ -241,6 +241,29 @@ gst_vaapi_create_display_from_gl_context (GstObject * gl_context_object)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_vaapi_find_gl_context (GstElement * element)
|
||||
{
|
||||
GstObject *gl_context;
|
||||
GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (element);
|
||||
|
||||
/* if the element is vaapisink or any vaapi encoder it doesn't need
|
||||
* to know a GstGLContext in order to create an appropriate
|
||||
* GstVaapiDisplay. Let's them to choose their own
|
||||
* GstVaapiDisplay */
|
||||
if (GST_IS_VIDEO_SINK (element) || GST_IS_VIDEO_ENCODER (element))
|
||||
return;
|
||||
|
||||
gl_context = NULL;
|
||||
if (!gst_vaapi_find_gl_local_context (element, &gl_context))
|
||||
gl_context = gst_vaapi_plugin_base_create_gl_context (plugin);
|
||||
|
||||
if (gl_context) {
|
||||
gst_vaapi_plugin_base_set_gl_context (plugin, gl_context);
|
||||
gst_object_unref (gl_context);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type)
|
||||
{
|
||||
|
@ -255,6 +278,11 @@ gst_vaapi_ensure_display (GstElement * element, GstVaapiDisplayType type)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Query for a local GstGL context. If it's found, it will be used
|
||||
* to create the VA display */
|
||||
if (!plugin->gl_context)
|
||||
gst_vaapi_find_gl_context (element);
|
||||
|
||||
/* If no neighboor, or application not interested, use system default */
|
||||
if (plugin->gl_context)
|
||||
display = gst_vaapi_create_display_from_gl_context (plugin->gl_context);
|
||||
|
|
Loading…
Reference in a new issue