From: Matthew Waters Date: Tue, 4 Feb 2020 02:58:06 +0000 (+1100) Subject: gl/mixer: support GstGLDisplay changes X-Git-Tag: 1.19.3~511^2~761 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=55e80b550e4ad02aaf44b30ec8b03da9ee485ac6;p=platform%2Fupstream%2Fgstreamer.git gl/mixer: support GstGLDisplay changes --- diff --git a/ext/gl/gstglbasemixer.c b/ext/gl/gstglbasemixer.c index 0284c8d..fc61e84 100644 --- a/ext/gl/gstglbasemixer.c +++ b/ext/gl/gstglbasemixer.c @@ -41,11 +41,19 @@ static void gst_gl_base_mixer_set_context (GstElement * element, static GstStateChangeReturn gst_gl_base_mixer_change_state (GstElement * element, GstStateChange transition); +static void gst_gl_base_mixer_gl_start (GstGLContext * context, gpointer data); +static void gst_gl_base_mixer_gl_stop (GstGLContext * context, gpointer data); + struct _GstGLBaseMixerPrivate { gboolean negotiated; GstGLContext *other_context; + + gboolean gl_started; + gboolean gl_result; + + GRecMutex context_lock; }; #define gst_gl_base_mixer_parent_class parent_class @@ -95,21 +103,37 @@ gst_gl_base_mixer_pad_set_property (GObject * object, guint prop_id, static gboolean _find_local_gl_context (GstGLBaseMixer * mix) { - if (gst_gl_query_local_gl_context (GST_ELEMENT (mix), GST_PAD_SRC, - &mix->context)) - return TRUE; - if (gst_gl_query_local_gl_context (GST_ELEMENT (mix), GST_PAD_SINK, - &mix->context)) - return TRUE; + GstGLContext *context = mix->context; + + if (gst_gl_query_local_gl_context (GST_ELEMENT (mix), GST_PAD_SRC, &context)) { + if (context->display == mix->display) { + mix->context = context; + return TRUE; + } + if (context != mix->context) + gst_clear_object (&context); + } + if (gst_gl_query_local_gl_context (GST_ELEMENT (mix), GST_PAD_SINK, &context)) { + if (context->display == mix->display) { + mix->context = context; + return TRUE; + } + if (context != mix->context) + gst_clear_object (&context); + } return FALSE; } static gboolean -_get_gl_context (GstGLBaseMixer * mix) +_get_gl_context_unlocked (GstGLBaseMixer * mix) { GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix); + gboolean new_context = FALSE; GError *error = NULL; + if (!mix->context) + new_context = TRUE; + if (!gst_gl_ensure_element_data (mix, &mix->display, &mix->priv->other_context)) return FALSE; @@ -139,10 +163,20 @@ _get_gl_context (GstGLBaseMixer * mix) } GST_OBJECT_UNLOCK (mix->display); - { - GstGLAPI current_gl_api = gst_gl_context_get_gl_api (mix->context); - if ((current_gl_api & mix_class->supported_gl_api) == 0) - goto unsupported_gl_api; + if (new_context || !mix->priv->gl_started) { + if (mix->priv->gl_started) + gst_gl_context_thread_add (mix->context, gst_gl_base_mixer_gl_stop, mix); + + { + if ((gst_gl_context_get_gl_api (mix-> + context) & mix_class->supported_gl_api) == 0) + goto unsupported_gl_api; + } + + gst_gl_context_thread_add (mix->context, gst_gl_base_mixer_gl_start, mix); + + if (!mix->priv->gl_started) + goto error; } return TRUE; @@ -168,6 +202,22 @@ context_error: g_clear_error (&error); return FALSE; } +error: + { + GST_ELEMENT_ERROR (mix, LIBRARY, INIT, + ("Subclass failed to initialize."), (NULL)); + return FALSE; + } +} + +static gboolean +_get_gl_context (GstGLBaseMixer * mix) +{ + gboolean ret; + g_rec_mutex_lock (&mix->priv->context_lock); + ret = _get_gl_context_unlocked (mix); + g_rec_mutex_unlock (&mix->priv->context_lock); + return ret; } static gboolean @@ -193,9 +243,13 @@ gst_gl_base_mixer_sink_query (GstAggregator * agg, GstAggregatorPad * bpad, switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: { - if (gst_gl_handle_context_query ((GstElement *) mix, query, - mix->display, mix->context, mix->priv->other_context)) - return TRUE; + gboolean ret; + g_rec_mutex_lock (&mix->priv->context_lock); + ret = gst_gl_handle_context_query ((GstElement *) mix, query, + mix->display, mix->context, mix->priv->other_context); + g_rec_mutex_unlock (&mix->priv->context_lock); + if (ret) + return ret; break; } default: @@ -232,6 +286,7 @@ gst_gl_base_mixer_src_activate_mode (GstAggregator * aggregator, static gboolean gst_gl_base_mixer_stop (GstAggregator * agg); static gboolean gst_gl_base_mixer_start (GstAggregator * agg); +static void gst_gl_base_mixer_finalize (GObject * object); static void gst_gl_base_mixer_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_gl_base_mixer_get_property (GObject * object, guint prop_id, @@ -240,6 +295,9 @@ static void gst_gl_base_mixer_get_property (GObject * object, guint prop_id, static gboolean gst_gl_base_mixer_decide_allocation (GstAggregator * agg, GstQuery * query); +static gboolean gst_gl_base_mixer_default_gl_start (GstGLBaseMixer * src); +static void gst_gl_base_mixer_default_gl_stop (GstGLBaseMixer * src); + static void gst_gl_base_mixer_class_init (GstGLBaseMixerClass * klass) { @@ -252,6 +310,7 @@ gst_gl_base_mixer_class_init (GstGLBaseMixerClass * klass) gobject_class = (GObjectClass *) klass; element_class = GST_ELEMENT_CLASS (klass); + gobject_class->finalize = gst_gl_base_mixer_finalize; gobject_class->get_property = gst_gl_base_mixer_get_property; gobject_class->set_property = gst_gl_base_mixer_set_property; @@ -267,6 +326,9 @@ gst_gl_base_mixer_class_init (GstGLBaseMixerClass * klass) agg_class->decide_allocation = gst_gl_base_mixer_decide_allocation; agg_class->propose_allocation = gst_gl_base_mixer_propose_allocation; + klass->gl_start = gst_gl_base_mixer_default_gl_start; + klass->gl_stop = gst_gl_base_mixer_default_gl_stop; + g_object_class_install_property (gobject_class, PROP_CONTEXT, g_param_spec_object ("context", "OpenGL context", @@ -283,6 +345,58 @@ static void gst_gl_base_mixer_init (GstGLBaseMixer * mix) { mix->priv = gst_gl_base_mixer_get_instance_private (mix); + + g_rec_mutex_init (&mix->priv->context_lock); +} + +static void +gst_gl_base_mixer_finalize (GObject * object) +{ + GstGLBaseMixer *mix = GST_GL_BASE_MIXER (object); + + g_rec_mutex_clear (&mix->priv->context_lock); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +gst_gl_base_mixer_default_gl_start (GstGLBaseMixer * src) +{ + return TRUE; +} + +static void +gst_gl_base_mixer_gl_start (GstGLContext * context, gpointer data) +{ + GstGLBaseMixer *src = GST_GL_BASE_MIXER (data); + GstGLBaseMixerClass *src_class = GST_GL_BASE_MIXER_GET_CLASS (src); + + GST_INFO_OBJECT (src, "starting"); + gst_gl_insert_debug_marker (src->context, + "starting element %s", GST_OBJECT_NAME (src)); + + src->priv->gl_started = src_class->gl_start (src); +} + +static void +gst_gl_base_mixer_default_gl_stop (GstGLBaseMixer * src) +{ +} + +static void +gst_gl_base_mixer_gl_stop (GstGLContext * context, gpointer data) +{ + GstGLBaseMixer *src = GST_GL_BASE_MIXER (data); + GstGLBaseMixerClass *src_class = GST_GL_BASE_MIXER_GET_CLASS (src); + + GST_INFO_OBJECT (src, "stopping"); + gst_gl_insert_debug_marker (src->context, + "stopping element %s", GST_OBJECT_NAME (src)); + + if (src->priv->gl_started) + src_class->gl_stop (src); + + src->priv->gl_started = FALSE; } static void @@ -290,12 +404,26 @@ gst_gl_base_mixer_set_context (GstElement * element, GstContext * context) { GstGLBaseMixer *mix = GST_GL_BASE_MIXER (element); GstGLBaseMixerClass *mix_class = GST_GL_BASE_MIXER_GET_CLASS (mix); + GstGLDisplay *old_display, *new_display; + g_rec_mutex_lock (&mix->priv->context_lock); + old_display = mix->display ? gst_object_ref (mix->display) : NULL; gst_gl_handle_set_context (element, context, &mix->display, &mix->priv->other_context); - if (mix->display) gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); + new_display = mix->display ? gst_object_ref (mix->display) : NULL; + + if (old_display && new_display) { + if (old_display != new_display) { + gst_clear_object (&mix->context); + _get_gl_context_unlocked (mix); + gst_pad_mark_reconfigure (GST_AGGREGATOR_SRC_PAD (mix)); + } + } + gst_clear_object (&old_display); + gst_clear_object (&new_display); + g_rec_mutex_unlock (&mix->priv->context_lock); GST_ELEMENT_CLASS (parent_class)->set_context (element, context); } @@ -307,11 +435,15 @@ gst_gl_base_mixer_activate (GstGLBaseMixer * mix, gboolean active) gboolean result = TRUE; if (active) { + g_rec_mutex_lock (&mix->priv->context_lock); if (!gst_gl_ensure_element_data (mix, &mix->display, - &mix->priv->other_context)) + &mix->priv->other_context)) { + g_rec_mutex_lock (&mix->priv->context_lock); return FALSE; + } gst_gl_display_filter_gl_api (mix->display, mix_class->supported_gl_api); + g_rec_mutex_unlock (&mix->priv->context_lock); } return result; @@ -346,9 +478,13 @@ gst_gl_base_mixer_src_query (GstAggregator * agg, GstQuery * query) switch (GST_QUERY_TYPE (query)) { case GST_QUERY_CONTEXT: { - if (gst_gl_handle_context_query ((GstElement *) mix, query, - mix->display, mix->context, mix->priv->other_context)) - return TRUE; + gboolean ret; + g_rec_mutex_lock (&mix->priv->context_lock); + ret = gst_gl_handle_context_query ((GstElement *) mix, query, + mix->display, mix->context, mix->priv->other_context); + g_rec_mutex_unlock (&mix->priv->context_lock); + if (ret) + return ret; break; } default: @@ -407,10 +543,11 @@ gst_gl_base_mixer_stop (GstAggregator * agg) { GstGLBaseMixer *mix = GST_GL_BASE_MIXER (agg); - if (mix->context) { - gst_object_unref (mix->context); - mix->context = NULL; - } + g_rec_mutex_lock (&mix->priv->context_lock); + if (mix->priv->gl_started) + gst_gl_context_thread_add (mix->context, gst_gl_base_mixer_gl_stop, mix); + gst_clear_object (&mix->context); + g_rec_mutex_unlock (&mix->priv->context_lock); return TRUE; } @@ -449,10 +586,9 @@ gst_gl_base_mixer_change_state (GstElement * element, GstStateChange transition) mix->priv->other_context = NULL; } - if (mix->display) { - gst_object_unref (mix->display); - mix->display = NULL; - } + g_rec_mutex_lock (&mix->priv->context_lock); + gst_clear_object (&mix->display); + g_rec_mutex_unlock (&mix->priv->context_lock); break; default: break; @@ -460,3 +596,24 @@ gst_gl_base_mixer_change_state (GstElement * element, GstStateChange transition) return ret; } + +/** + * gst_gl_base_mixer_get_gl_context: + * @mix: a #GstGLBaseMixer + * + * Returns: (transfer full) (nullable): the #GstGLContext found by @mix + * + * Since: 1.18 + */ +GstGLContext * +gst_gl_base_mixer_get_gl_context (GstGLBaseMixer * mix) +{ + GstGLContext *ret; + + g_return_val_if_fail (GST_IS_GL_BASE_MIXER (mix), NULL); + + g_rec_mutex_lock (&mix->priv->context_lock); + ret = mix->context ? gst_object_ref (mix->context) : NULL; + g_rec_mutex_unlock (&mix->priv->context_lock); + return ret; +} diff --git a/ext/gl/gstglbasemixer.h b/ext/gl/gstglbasemixer.h index e9684ab..c823479 100644 --- a/ext/gl/gstglbasemixer.h +++ b/ext/gl/gstglbasemixer.h @@ -89,10 +89,15 @@ struct _GstGLBaseMixerClass GstVideoAggregatorClass parent_class; GstGLAPI supported_gl_api; + gboolean (*gl_start) (GstGLBaseMixer * mix); + void (*gl_stop) (GstGLBaseMixer * mix); + gpointer _padding[GST_PADDING]; }; GType gst_gl_base_mixer_get_type(void); +GstGLContext * gst_gl_base_mixer_get_gl_context (GstGLBaseMixer * mix); + G_END_DECLS #endif /* __GST_GL_BASE_MIXER_H__ */ diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index 682622d..d3046f0 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -392,6 +392,9 @@ static void gst_gl_mixer_get_property (GObject * object, guint prop_id, static gboolean gst_gl_mixer_decide_allocation (GstAggregator * agg, GstQuery * query); +static gboolean gst_gl_mixer_gl_start (GstGLBaseMixer * mix); +static void gst_gl_mixer_gl_stop (GstGLBaseMixer * mix); + static void gst_gl_mixer_finalize (GObject * object); static void @@ -402,6 +405,7 @@ gst_gl_mixer_class_init (GstGLMixerClass * klass) GstVideoAggregatorClass *videoaggregator_class = (GstVideoAggregatorClass *) klass; GstAggregatorClass *agg_class = (GstAggregatorClass *) klass; + GstGLBaseMixerClass *base_class = (GstGLBaseMixerClass *) klass; GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "glmixer", 0, "OpenGL mixer"); @@ -426,6 +430,8 @@ gst_gl_mixer_class_init (GstGLMixerClass * klass) videoaggregator_class->aggregate_frames = gst_gl_mixer_aggregate_frames; videoaggregator_class->find_best_format = _find_best_format; + base_class->gl_start = gst_gl_mixer_gl_start; + base_class->gl_stop = gst_gl_mixer_gl_stop; /* Register the pad class */ g_type_class_ref (GST_TYPE_GL_MIXER_PAD); @@ -528,30 +534,17 @@ _mixer_create_fbo (GstGLContext * context, GstGLMixer * mix) } static gboolean -gst_gl_mixer_decide_allocation (GstAggregator * agg, GstQuery * query) +gst_gl_mixer_gl_start (GstGLBaseMixer * base_mix) { - GstGLBaseMixer *base_mix = GST_GL_BASE_MIXER (agg); GstGLMixer *mix = GST_GL_MIXER (base_mix); GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); - GstGLContext *context; - GstBufferPool *pool = NULL; - GstStructure *config; - GstCaps *caps; - guint min, max, size; - gboolean update_pool; - - if (!GST_AGGREGATOR_CLASS (gst_gl_mixer_parent_class)->decide_allocation (agg, - query)) - return FALSE; - - context = base_mix->context; g_mutex_lock (&mix->priv->gl_resource_lock); mix->priv->gl_resource_ready = FALSE; if (mix->fbo) gst_object_unref (mix->fbo); - gst_gl_context_thread_add (context, + gst_gl_context_thread_add (base_mix->context, (GstGLContextThreadFunc) _mixer_create_fbo, mix); if (!mix->fbo) { g_cond_signal (&mix->priv->gl_resource_cond); @@ -559,15 +552,62 @@ gst_gl_mixer_decide_allocation (GstAggregator * agg, GstQuery * query) goto context_error; } - gst_query_parse_allocation (query, &caps, NULL); - if (mixer_class->set_caps) - mixer_class->set_caps (mix, caps); + mixer_class->set_caps (mix, mix->out_caps); mix->priv->gl_resource_ready = TRUE; g_cond_signal (&mix->priv->gl_resource_cond); g_mutex_unlock (&mix->priv->gl_resource_lock); + return GST_GL_BASE_MIXER_CLASS (parent_class)->gl_start (base_mix); + +context_error: + { + GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("Context error"), (NULL)); + return FALSE; + } +} + +static void +gst_gl_mixer_gl_stop (GstGLBaseMixer * base_mix) +{ + GstGLMixer *mix = GST_GL_MIXER (base_mix); + GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); + + if (mixer_class->reset) + mixer_class->reset (mix); + + if (mix->fbo) { + gst_object_unref (mix->fbo); + mix->fbo = NULL; + } + + GST_GL_BASE_MIXER_CLASS (parent_class)->gl_stop (base_mix); +} + +static gboolean +gst_gl_mixer_decide_allocation (GstAggregator * agg, GstQuery * query) +{ + GstGLBaseMixer *base_mix = GST_GL_BASE_MIXER (agg); + GstGLContext *context; + GstBufferPool *pool = NULL; + GstStructure *config; + GstCaps *caps; + guint min, max, size; + gboolean update_pool; + + if (!GST_AGGREGATOR_CLASS (gst_gl_mixer_parent_class)->decide_allocation (agg, + query)) + return FALSE; + + context = gst_gl_base_mixer_get_gl_context (base_mix); + if (!context) { + GST_WARNING_OBJECT (agg, "No OpenGL context"); + return FALSE; + } + + gst_query_parse_allocation (query, &caps, NULL); + if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); @@ -598,13 +638,9 @@ gst_gl_mixer_decide_allocation (GstAggregator * agg, GstQuery * query) gst_object_unref (pool); - return TRUE; + gst_clear_object (&context); -context_error: - { - GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("Context error"), (NULL)); - return FALSE; - } + return TRUE; } gboolean @@ -615,7 +651,6 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) GstVideoFrame out_frame; GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); - GstGLMixerPrivate *priv = mix->priv; GST_TRACE ("Processing buffers"); @@ -626,12 +661,12 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) out_tex = (GstGLMemory *) out_frame.map[0].memory; - g_mutex_lock (&priv->gl_resource_lock); - if (!priv->gl_resource_ready) - g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock); + g_mutex_lock (&mix->priv->gl_resource_lock); + if (!mix->priv->gl_resource_ready) + g_cond_wait (&mix->priv->gl_resource_cond, &mix->priv->gl_resource_lock); - if (!priv->gl_resource_ready) { - g_mutex_unlock (&priv->gl_resource_lock); + if (!mix->priv->gl_resource_ready) { + g_mutex_unlock (&mix->priv->gl_resource_lock); GST_ERROR_OBJECT (mix, "fbo used to render can't be created, do not run process_textures"); res = FALSE; @@ -640,7 +675,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) mix_class->process_textures (mix, out_tex); - g_mutex_unlock (&priv->gl_resource_lock); + g_mutex_unlock (&mix->priv->gl_resource_lock); out: gst_video_frame_unmap (&out_frame); @@ -659,12 +694,18 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf) static GstFlowReturn gst_gl_mixer_aggregate_frames (GstVideoAggregator * vagg, GstBuffer * outbuf) { + GstGLBaseMixer *base_mix = GST_GL_BASE_MIXER (vagg); gboolean res = FALSE; GstGLMixer *mix = GST_GL_MIXER (vagg); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (vagg); - GstGLContext *context = GST_GL_BASE_MIXER (mix)->context; + GstGLContext *context = gst_gl_base_mixer_get_gl_context (base_mix); GstGLSyncMeta *sync_meta; + if (!context) { + GST_DEBUG_OBJECT (vagg, "No OpenGL context, try again later"); + return GST_AGGREGATOR_FLOW_NEED_DATA; + } + if (mix_class->process_buffers) res = gst_gl_mixer_process_buffers (mix, outbuf); else if (mix_class->process_textures) @@ -674,6 +715,8 @@ gst_gl_mixer_aggregate_frames (GstVideoAggregator * vagg, GstBuffer * outbuf) if (sync_meta) gst_gl_sync_meta_set_sync_point (sync_meta, context); + gst_clear_object (&context); + return res ? GST_FLOW_OK : GST_FLOW_ERROR; } @@ -709,15 +752,6 @@ static gboolean gst_gl_mixer_stop (GstAggregator * agg) { GstGLMixer *mix = GST_GL_MIXER (agg); - GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix); - - if (mixer_class->reset) - mixer_class->reset (mix); - - if (mix->fbo) { - gst_object_unref (mix->fbo); - mix->fbo = NULL; - } gst_gl_mixer_reset (mix); diff --git a/ext/gl/gstglvideomixer.c b/ext/gl/gstglvideomixer.c index 0002c85..1c3a468 100644 --- a/ext/gl/gstglvideomixer.c +++ b/ext/gl/gstglvideomixer.c @@ -472,7 +472,8 @@ static GstCaps *_update_caps (GstVideoAggregator * vagg, GstCaps * caps); static GstCaps *_fixate_caps (GstAggregator * agg, GstCaps * caps); static gboolean gst_gl_video_mixer_propose_allocation (GstAggregator * agg, GstAggregatorPad * agg_pad, GstQuery * decide_query, GstQuery * query); -static void gst_gl_video_mixer_reset (GstGLMixer * mixer); +static gboolean gst_gl_video_mixer_gl_start (GstGLBaseMixer * base_mix); +static void gst_gl_video_mixer_gl_stop (GstGLBaseMixer * base_mix); static gboolean gst_gl_video_mixer_set_caps (GstGLMixer * mixer, GstCaps * outcaps); @@ -918,10 +919,11 @@ gst_gl_video_mixer_class_init (GstGLVideoMixerClass * klass) DEFAULT_BACKGROUND, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); GST_GL_MIXER_CLASS (klass)->set_caps = gst_gl_video_mixer_set_caps; - GST_GL_MIXER_CLASS (klass)->reset = gst_gl_video_mixer_reset; GST_GL_MIXER_CLASS (klass)->process_textures = gst_gl_video_mixer_process_textures; + GST_GL_BASE_MIXER_CLASS (klass)->gl_stop = gst_gl_video_mixer_gl_stop; + GST_GL_BASE_MIXER_CLASS (klass)->gl_start = gst_gl_video_mixer_gl_start; vagg_class->update_caps = _update_caps; @@ -1057,7 +1059,6 @@ _update_caps (GstVideoAggregator * vagg, GstCaps * caps) GST_OBJECT_UNLOCK (vagg); return NULL; } - } GST_OBJECT_UNLOCK (vagg); @@ -1180,34 +1181,11 @@ _reset_gl (GstGLContext * context, GstGLVideoMixer * video_mixer) gst_element_foreach_sink_pad (GST_ELEMENT (video_mixer), _reset_pad_gl, NULL); } -static void -gst_gl_video_mixer_reset (GstGLMixer * mixer) -{ - GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mixer); - GstGLContext *context = GST_GL_BASE_MIXER (mixer)->context; - - GST_DEBUG_OBJECT (mixer, "context:%p", context); - - if (video_mixer->shader) - gst_object_unref (video_mixer->shader); - video_mixer->shader = NULL; - - if (video_mixer->checker) - gst_object_unref (video_mixer->checker); - video_mixer->checker = NULL; - - if (GST_GL_BASE_MIXER (mixer)->context) - gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _reset_gl, - mixer); -} - static gboolean gst_gl_video_mixer_set_caps (GstGLMixer * mixer, GstCaps * outcaps) { GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mixer); - g_clear_object (&video_mixer->shader); - /* need reconfigure output geometry */ video_mixer->output_geo_change = TRUE; @@ -1215,23 +1193,44 @@ gst_gl_video_mixer_set_caps (GstGLMixer * mixer, GstCaps * outcaps) } static void -_video_mixer_process_gl (GstGLContext * context, GstGLVideoMixer * video_mixer) +gst_gl_video_mixer_gl_stop (GstGLBaseMixer * base_mix) { - GstGLMixer *mixer = GST_GL_MIXER (video_mixer); + GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (base_mix); + + gst_clear_object (&video_mixer->shader); + gst_clear_object (&video_mixer->checker); + + _reset_gl (base_mix->context, video_mixer); + + GST_GL_BASE_MIXER_CLASS (parent_class)->gl_stop (base_mix); +} + +static gboolean +gst_gl_video_mixer_gl_start (GstGLBaseMixer * base_mix) +{ + GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (base_mix); if (!video_mixer->shader) { gchar *frag_str = g_strdup_printf ("%s%s", - gst_gl_shader_string_get_highest_precision (GST_GL_BASE_MIXER - (mixer)->context, GST_GLSL_VERSION_NONE, + gst_gl_shader_string_get_highest_precision (base_mix->context, + GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_ES | GST_GLSL_PROFILE_COMPATIBILITY), video_mixer_f_src); - gst_gl_context_gen_shader (GST_GL_BASE_MIXER (mixer)->context, + gst_gl_context_gen_shader (base_mix->context, gst_gl_shader_string_vertex_mat4_vertex_transform, frag_str, &video_mixer->shader); g_free (frag_str); } + return GST_GL_BASE_MIXER_CLASS (parent_class)->gl_start (base_mix); +} + +static void +_video_mixer_process_gl (GstGLContext * context, GstGLVideoMixer * video_mixer) +{ + GstGLMixer *mixer = GST_GL_MIXER (video_mixer); + gst_gl_framebuffer_draw_to_texture (mixer->fbo, video_mixer->out_tex, gst_gl_video_mixer_callback, video_mixer); }