mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 19:42:26 +00:00
amcviddec: use gstcontext to retreive the OpenGL context
This commit is contained in:
parent
7dbb6681a3
commit
c322806227
2 changed files with 136 additions and 51 deletions
|
@ -105,6 +105,8 @@ static void gst_amc_video_dec_finalize (GObject * object);
|
|||
static GstStateChangeReturn
|
||||
gst_amc_video_dec_change_state (GstElement * element,
|
||||
GstStateChange transition);
|
||||
static void gst_amc_video_dec_set_context (GstElement * element,
|
||||
GstContext * context);
|
||||
|
||||
static gboolean gst_amc_video_dec_open (GstVideoDecoder * decoder);
|
||||
static gboolean gst_amc_video_dec_close (GstVideoDecoder * decoder);
|
||||
|
@ -118,6 +120,8 @@ static GstFlowReturn gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
|||
static GstFlowReturn gst_amc_video_dec_finish (GstVideoDecoder * decoder);
|
||||
static gboolean gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec,
|
||||
GstQuery * query);
|
||||
static gboolean gst_amc_video_dec_src_query (GstVideoDecoder * bdec,
|
||||
GstQuery * query);
|
||||
|
||||
static GstFlowReturn gst_amc_video_dec_drain (GstAmcVideoDec * self);
|
||||
static gboolean gst_amc_video_dec_check_codec_config (GstAmcVideoDec * self);
|
||||
|
@ -268,6 +272,8 @@ gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass)
|
|||
|
||||
element_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_amc_video_dec_change_state);
|
||||
element_class->set_context =
|
||||
GST_DEBUG_FUNCPTR (gst_amc_video_dec_set_context);
|
||||
|
||||
videodec_class->start = GST_DEBUG_FUNCPTR (gst_amc_video_dec_start);
|
||||
videodec_class->stop = GST_DEBUG_FUNCPTR (gst_amc_video_dec_stop);
|
||||
|
@ -280,6 +286,7 @@ gst_amc_video_dec_class_init (GstAmcVideoDecClass * klass)
|
|||
videodec_class->finish = GST_DEBUG_FUNCPTR (gst_amc_video_dec_finish);
|
||||
videodec_class->decide_allocation =
|
||||
GST_DEBUG_FUNCPTR (gst_amc_video_dec_decide_allocation);
|
||||
videodec_class->src_query = GST_DEBUG_FUNCPTR (gst_amc_video_dec_src_query);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -364,6 +371,17 @@ gst_amc_video_dec_finalize (GObject * object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_amc_video_dec_set_context (GstElement * element, GstContext * context)
|
||||
{
|
||||
GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (element);
|
||||
|
||||
gst_gl_handle_set_context (element, context, &self->gl_display,
|
||||
&self->other_gl_context);
|
||||
|
||||
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_amc_video_dec_change_state (GstElement * element, GstStateChange transition)
|
||||
{
|
||||
|
@ -1831,6 +1849,54 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_amc_video_dec_src_query (GstVideoDecoder * bdec, GstQuery * query)
|
||||
{
|
||||
GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (bdec);
|
||||
gboolean ret;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CONTEXT:
|
||||
{
|
||||
const gchar *context_type;
|
||||
GstContext *context, *old_context;
|
||||
|
||||
ret = gst_gl_handle_context_query ((GstElement *) self, query,
|
||||
&self->gl_display, &self->other_gl_context);
|
||||
gst_query_parse_context_type (query, &context_type);
|
||||
|
||||
if (g_strcmp0 (context_type, "gst.gl.local_context") == 0) {
|
||||
GstStructure *s;
|
||||
|
||||
gst_query_parse_context (query, &old_context);
|
||||
|
||||
if (old_context)
|
||||
context = gst_context_copy (old_context);
|
||||
else
|
||||
context = gst_context_new ("gst.gl.local_context", FALSE);
|
||||
|
||||
s = gst_context_writable_structure (context);
|
||||
gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT, self->gl_context,
|
||||
NULL);
|
||||
gst_query_set_context (query, context);
|
||||
gst_context_unref (context);
|
||||
|
||||
ret = self->gl_context != NULL;
|
||||
}
|
||||
GST_LOG_OBJECT (self, "context query of type %s %i", context_type, ret);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (bdec, query);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_caps_are_rgba_with_gl_memory (GstCaps * caps)
|
||||
{
|
||||
|
@ -1853,12 +1919,43 @@ _caps_are_rgba_with_gl_memory (GstCaps * caps)
|
|||
GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_find_local_gl_context (GstAmcVideoDec * self)
|
||||
{
|
||||
GstQuery *query;
|
||||
GstContext *context;
|
||||
const GstStructure *s;
|
||||
|
||||
if (self->gl_context)
|
||||
return TRUE;
|
||||
|
||||
query = gst_query_new_context ("gst.gl.local_context");
|
||||
if (!self->gl_context && gst_gl_run_query (GST_ELEMENT (self), query, GST_PAD_SRC)) {
|
||||
gst_query_parse_context (query, &context);
|
||||
if (context) {
|
||||
s = gst_context_get_structure (context);
|
||||
gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &self->gl_context,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "found local context %p", self->gl_context);
|
||||
|
||||
gst_query_unref (query);
|
||||
|
||||
if (self->gl_context)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
|
||||
{
|
||||
GstCaps *caps = NULL;
|
||||
gboolean need_pool = FALSE;
|
||||
GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (bdec);
|
||||
gboolean need_pool = FALSE;
|
||||
GstCaps *caps = NULL;
|
||||
// GError *error = NULL;
|
||||
|
||||
if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
|
||||
return FALSE;
|
||||
|
@ -1866,68 +1963,54 @@ gst_amc_video_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
|
|||
self->downstream_supports_gl = FALSE;
|
||||
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||
if (_caps_are_rgba_with_gl_memory (caps)) {
|
||||
guint i, n_allocation_pools;
|
||||
GstGLBufferPool *gl_pool = NULL;
|
||||
GstGLContext *gl_context = NULL;
|
||||
GstGLDisplay *gl_display = NULL;
|
||||
|
||||
n_allocation_pools = MAX (gst_query_get_n_allocation_pools (query), 1);
|
||||
for (i = 0; i < n_allocation_pools; i++) {
|
||||
GstBufferPool *pool = NULL;
|
||||
GstStructure *config = NULL;
|
||||
guint min, max, size;
|
||||
|
||||
gst_query_parse_nth_allocation_pool (query, i, &pool, &size, &min, &max);
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
if (!config) {
|
||||
gst_object_unref (pool);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GST_IS_GL_BUFFER_POOL (pool)) {
|
||||
gst_object_unref (pool);
|
||||
continue;
|
||||
}
|
||||
|
||||
gl_pool = GST_GL_BUFFER_POOL (pool);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gl_pool) {
|
||||
GST_WARNING_OBJECT (bdec, "Failed to get gl pool from downstream");
|
||||
gst_object_unref (gl_pool);
|
||||
if (!gst_gl_ensure_element_data (self, &self->gl_display,
|
||||
&self->other_gl_context))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gl_context = gl_pool->context;
|
||||
if (!gl_context) {
|
||||
GST_WARNING_OBJECT (bdec, "Failed to get gl context from downstream");
|
||||
gst_object_unref (gl_pool);
|
||||
return FALSE;
|
||||
if (!_find_local_gl_context (self))
|
||||
goto out;
|
||||
#if 0
|
||||
if (!self->gl_context) {
|
||||
GST_OBJECT_LOCK (self->gl_display);
|
||||
do {
|
||||
if (self->gl_context) {
|
||||
gst_object_unref (self->gl_context);
|
||||
self->gl_context = NULL;
|
||||
}
|
||||
/* just get a GL context. we don't care */
|
||||
self->gl_context =
|
||||
gst_gl_display_get_gl_context_for_thread (self->gl_display, NULL);
|
||||
if (!self->gl_context) {
|
||||
if (!gst_gl_display_create_context (self->gl_display,
|
||||
self->other_gl_context, &self->gl_context, &error)) {
|
||||
GST_OBJECT_UNLOCK (mix->display);
|
||||
goto context_error;
|
||||
}
|
||||
}
|
||||
} while (!gst_gl_display_add_context (self->gl_display, self->gl_context));
|
||||
GST_OBJECT_UNLOCK (self->gl_display);
|
||||
}
|
||||
|
||||
if (self->gl_context) {
|
||||
gst_object_unref (self->gl_context);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (self->renderer) {
|
||||
gst_amc_2d_texture_renderer_free (self->renderer);
|
||||
self->renderer = NULL;
|
||||
}
|
||||
|
||||
// gl_display = gst_gl_context_get_display (gl_context);
|
||||
// self->gl_context = gst_gl_context_new (gl_display);
|
||||
// gst_object_unref (gl_display);
|
||||
self->gl_context = gst_object_ref (gl_context);
|
||||
|
||||
// gst_gl_context_create (self->gl_context, gl_context, NULL);
|
||||
|
||||
gst_object_unref (gl_pool);
|
||||
|
||||
self->downstream_supports_gl = TRUE;
|
||||
}
|
||||
|
||||
out:
|
||||
return gst_amc_video_dec_check_codec_config (self);
|
||||
#if 0
|
||||
context_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, ("%s", error->message),
|
||||
(NULL));
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -94,7 +94,9 @@ struct _GstAmcVideoDec
|
|||
|
||||
GstAmcSurface *surface;
|
||||
|
||||
GstGLDisplay *gl_display;
|
||||
GstGLContext *gl_context;
|
||||
GstGLContext *other_gl_context;
|
||||
GstAmc2DTextureRenderer *renderer;
|
||||
|
||||
gboolean downstream_supports_gl;
|
||||
|
|
Loading…
Reference in a new issue