diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 0e1a9a6fb0..71a8520f9f 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -419,6 +419,7 @@ struct _GstPlayBinClass #define DEFAULT_VIDEO_SINK NULL #define DEFAULT_VIS_PLUGIN NULL #define DEFAULT_TEXT_SINK NULL +#define DEFAULT_SUBPIC_SINK NULL #define DEFAULT_VOLUME 1.0 #define DEFAULT_MUTE FALSE #define DEFAULT_FRAME NULL @@ -445,6 +446,7 @@ enum PROP_VIDEO_SINK, PROP_VIS_PLUGIN, PROP_TEXT_SINK, + PROP_SUBPIC_SINK, PROP_VOLUME, PROP_MUTE, PROP_FRAME, @@ -704,6 +706,10 @@ gst_play_bin_class_init (GstPlayBinClass * klass) g_param_spec_object ("text-sink", "Text plugin", "the text output element to use (NULL = default textoverlay)", GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_klass, PROP_SUBPIC_SINK, + g_param_spec_object ("subpic-sink", "Subpicture plugin", + "the subpicture output element to use (NULL = default dvdspu)", + GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_klass, PROP_VOLUME, g_param_spec_double ("volume", "Volume", "The audio volume", @@ -1432,11 +1438,11 @@ gst_play_bin_set_property (GObject * object, guint prop_id, gst_play_bin_set_encoding (playbin, g_value_get_string (value)); break; case PROP_VIDEO_SINK: - gst_play_sink_set_video_sink (playbin->playsink, + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO, g_value_get_object (value)); break; case PROP_AUDIO_SINK: - gst_play_sink_set_audio_sink (playbin->playsink, + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO, g_value_get_object (value)); break; case PROP_VIS_PLUGIN: @@ -1444,7 +1450,11 @@ gst_play_bin_set_property (GObject * object, guint prop_id, g_value_get_object (value)); break; case PROP_TEXT_SINK: - gst_play_sink_set_text_sink (playbin->playsink, + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT, + g_value_get_object (value)); + break; + case PROP_SUBPIC_SINK: + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_SUBPIC, g_value_get_object (value)); break; case PROP_VOLUME: @@ -1571,11 +1581,11 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value, break; case PROP_VIDEO_SINK: g_value_set_object (value, - gst_play_sink_get_video_sink (playbin->playsink)); + gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO)); break; case PROP_AUDIO_SINK: g_value_set_object (value, - gst_play_sink_get_audio_sink (playbin->playsink)); + gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO)); break; case PROP_VIS_PLUGIN: g_value_set_object (value, @@ -1583,7 +1593,12 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value, break; case PROP_TEXT_SINK: g_value_set_object (value, - gst_play_sink_get_text_sink (playbin->playsink)); + gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT)); + break; + case PROP_SUBPIC_SINK: + g_value_set_object (value, + gst_play_sink_get_sink (playbin->playsink, + GST_PLAY_SINK_TYPE_SUBPIC)); break; case PROP_VOLUME: g_value_set_double (value, gst_play_sink_get_volume (playbin->playsink)); @@ -2142,11 +2157,13 @@ autoplug_select_cb (GstElement * decodebin, GstPad * pad, /* get klass to figure out if it's audio or video */ if (strstr (klass, "Audio")) { GST_DEBUG_OBJECT (playbin, "configure audio sink"); - gst_play_sink_set_audio_sink (playbin->playsink, element); + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO, + element); g_object_notify (G_OBJECT (playbin), "audio-sink"); } else if (strstr (klass, "Video")) { GST_DEBUG_OBJECT (playbin, "configure video sink"); - gst_play_sink_set_video_sink (playbin->playsink, element); + gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO, + element); g_object_notify (G_OBJECT (playbin), "video-sink"); } else { GST_WARNING_OBJECT (playbin, "unknown sink klass %s found", klass); diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index b156433ce2..1072feaf57 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -330,70 +330,96 @@ gst_play_sink_finalize (GObject * object) } void -gst_play_sink_set_video_sink (GstPlaySink * playsink, GstElement * sink) +gst_play_sink_set_sink (GstPlaySink * playsink, GstPlaySinkType type, + GstElement * sink) { - GST_PLAY_SINK_LOCK (playsink); - if (playsink->video_sink) - gst_object_unref (playsink->video_sink); + GstElement **elem = NULL, *old = NULL; - if (sink) { - gst_object_ref (sink); - gst_object_sink (sink); + GST_PLAY_SINK_LOCK (playsink); + switch (type) { + case GST_PLAY_SINK_TYPE_AUDIO: + case GST_PLAY_SINK_TYPE_AUDIO_RAW: + elem = &playsink->audio_sink; + break; + case GST_PLAY_SINK_TYPE_VIDEO: + case GST_PLAY_SINK_TYPE_VIDEO_RAW: + elem = &playsink->video_sink; + break; + case GST_PLAY_SINK_TYPE_TEXT: + elem = &playsink->text_sink; + break; + case GST_PLAY_SINK_TYPE_SUBPIC: + elem = &playsink->subp_sink; + break; + default: + break; + } + if (elem) { + old = *elem; + if (sink) { + gst_object_ref (sink); + gst_object_sink (sink); + } + *elem = sink; } - playsink->video_sink = sink; GST_PLAY_SINK_UNLOCK (playsink); + + if (old) { + gst_element_set_state (old, GST_STATE_NULL); + gst_object_unref (old); + } } GstElement * -gst_play_sink_get_video_sink (GstPlaySink * playsink) +gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type) { GstElement *result = NULL; - GstPlayVideoChain *chain; + GstElement *elem = NULL, *chainp = NULL; GST_PLAY_SINK_LOCK (playsink); - if ((chain = (GstPlayVideoChain *) playsink->videochain)) { - /* we have an active chain, get the sink */ - if (chain->sink) - result = gst_object_ref (chain->sink); + switch (type) { + case GST_PLAY_SINK_TYPE_AUDIO: + { + GstPlayAudioChain *chain; + if ((chain = (GstPlayAudioChain *) playsink->audiochain)) + chainp = chain->sink; + elem = playsink->audio_sink; + break; + } + case GST_PLAY_SINK_TYPE_VIDEO: + { + GstPlayVideoChain *chain; + if ((chain = (GstPlayVideoChain *) playsink->videochain)) + chainp = chain->sink; + elem = playsink->video_sink; + break; + } + case GST_PLAY_SINK_TYPE_TEXT: + { + GstPlayTextChain *chain; + if ((chain = (GstPlayTextChain *) playsink->textchain)) + chainp = chain->sink; + elem = playsink->text_sink; + break; + } + case GST_PLAY_SINK_TYPE_SUBPIC: + { + GstPlaySubpChain *chain; + if ((chain = (GstPlaySubpChain *) playsink->subpchain)) + chainp = chain->sink; + elem = playsink->subp_sink; + break; + } + default: + break; + } + if (chainp) { + /* we have an active chain with a sink, get the sink */ + result = gst_object_ref (chainp); } /* nothing found, return last configured sink */ - if (result == NULL && playsink->video_sink) - result = gst_object_ref (playsink->video_sink); - GST_PLAY_SINK_UNLOCK (playsink); - - return result; -} - -void -gst_play_sink_set_audio_sink (GstPlaySink * playsink, GstElement * sink) -{ - GST_PLAY_SINK_LOCK (playsink); - if (playsink->audio_sink) - gst_object_unref (playsink->audio_sink); - - if (sink) { - gst_object_ref (sink); - gst_object_sink (sink); - } - playsink->audio_sink = sink; - GST_PLAY_SINK_UNLOCK (playsink); -} - -GstElement * -gst_play_sink_get_audio_sink (GstPlaySink * playsink) -{ - GstElement *result = NULL; - GstPlayAudioChain *chain; - - GST_PLAY_SINK_LOCK (playsink); - if ((chain = (GstPlayAudioChain *) playsink->audiochain)) { - /* we have an active chain, get the sink */ - if (chain->sink) - result = gst_object_ref (chain->sink); - } - /* nothing found, return last configured sink */ - if (result == NULL && playsink->audio_sink) - result = gst_object_ref (playsink->audio_sink); + if (result == NULL && elem) + result = gst_object_ref (elem); GST_PLAY_SINK_UNLOCK (playsink); return result; @@ -518,76 +544,6 @@ gst_play_sink_get_vis_plugin (GstPlaySink * playsink) return result; } -void -gst_play_sink_set_text_sink (GstPlaySink * playsink, GstElement * sink) -{ - GST_PLAY_SINK_LOCK (playsink); - if (playsink->text_sink) - gst_object_unref (playsink->text_sink); - - if (sink) { - gst_object_ref (sink); - gst_object_sink (sink); - } - playsink->text_sink = sink; - GST_PLAY_SINK_UNLOCK (playsink); -} - -GstElement * -gst_play_sink_get_text_sink (GstPlaySink * playsink) -{ - GstElement *result = NULL; - GstPlayTextChain *chain; - - GST_PLAY_SINK_LOCK (playsink); - if ((chain = (GstPlayTextChain *) playsink->textchain)) { - /* we have an active chain, get the sink */ - if (chain->sink) - result = gst_object_ref (chain->sink); - } - /* nothing found, return last configured sink */ - if (result == NULL && playsink->text_sink) - result = gst_object_ref (playsink->text_sink); - GST_PLAY_SINK_UNLOCK (playsink); - - return result; -} - -void -gst_play_sink_set_subp_sink (GstPlaySink * playsink, GstElement * sink) -{ - GST_PLAY_SINK_LOCK (playsink); - if (playsink->subp_sink) - gst_object_unref (playsink->subp_sink); - - if (sink) { - gst_object_ref (sink); - gst_object_sink (sink); - } - playsink->subp_sink = sink; - GST_PLAY_SINK_UNLOCK (playsink); -} - -GstElement * -gst_play_sink_get_subp_sink (GstPlaySink * playsink) -{ - GstElement *result = NULL; - GstPlaySubpChain *chain; - - GST_PLAY_SINK_LOCK (playsink); - if ((chain = (GstPlaySubpChain *) playsink->subpchain)) { - /* we have an active chain, get the sink */ - if (chain->sink) - result = gst_object_ref (chain->sink); - } - /* nothing found, return last configured sink */ - if (result == NULL && playsink->subp_sink) - result = gst_object_ref (playsink->subp_sink); - GST_PLAY_SINK_UNLOCK (playsink); - - return result; -} - void gst_play_sink_set_volume (GstPlaySink * playsink, gdouble volume) { @@ -1810,8 +1766,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) playsink->audio_tee_vissrc = NULL; } srcpad = - gst_element_get_static_pad (GST_ELEMENT_CAST (playsink-> - vischain->chain.bin), "src"); + gst_element_get_static_pad (GST_ELEMENT_CAST (playsink->vischain-> + chain.bin), "src"); gst_pad_unlink (srcpad, playsink->videochain->sinkpad); } add_chain (GST_PLAY_CHAIN (playsink->videochain), FALSE); @@ -1976,8 +1932,8 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) if (playsink->vischain) { GST_DEBUG_OBJECT (playsink, "setting up vis chain"); srcpad = - gst_element_get_static_pad (GST_ELEMENT_CAST (playsink-> - vischain->chain.bin), "src"); + gst_element_get_static_pad (GST_ELEMENT_CAST (playsink->vischain-> + chain.bin), "src"); add_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE); activate_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE); if (playsink->audio_tee_vissrc == NULL) { @@ -2415,12 +2371,15 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) activate_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE); add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE); } + if (playsink->subpchain) { + activate_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE); + add_chain (GST_PLAY_CHAIN (playsink->subpchain), FALSE); + } do_async_done (playsink); break; default: break; } - return ret; /* ERRORS */ diff --git a/gst/playback/gstplaysink.h b/gst/playback/gstplaysink.h index bbf1db728b..599e87df9f 100644 --- a/gst/playback/gstplaysink.h +++ b/gst/playback/gstplaysink.h @@ -36,6 +36,8 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PLAY_SINK)) #define GST_IS_PLAY_SINK_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PLAY_SINK)) +#define GST_PLAY_SINK_CAST(obj) \ + ((GstPlaySink*)(obj)) /** * GstPlaySinkType: @@ -70,21 +72,12 @@ GType gst_play_sink_get_type (void); GstPad * gst_play_sink_request_pad (GstPlaySink *playsink, GstPlaySinkType type); void gst_play_sink_release_pad (GstPlaySink *playsink, GstPad *pad); -void gst_play_sink_set_video_sink (GstPlaySink * playsink, GstElement * sink); -GstElement * gst_play_sink_get_video_sink (GstPlaySink * playsink); - -void gst_play_sink_set_audio_sink (GstPlaySink * playsink, GstElement * sink); -GstElement * gst_play_sink_get_audio_sink (GstPlaySink * playsink); +void gst_play_sink_set_sink (GstPlaySink * playsink, GstPlaySinkType type, GstElement * sink); +GstElement * gst_play_sink_get_sink (GstPlaySink * playsink, GstPlaySinkType type); void gst_play_sink_set_vis_plugin (GstPlaySink * playsink, GstElement * vis); GstElement * gst_play_sink_get_vis_plugin (GstPlaySink * playsink); -void gst_play_sink_set_text_sink (GstPlaySink * playsink, GstElement * sink); -GstElement * gst_play_sink_get_text_sink (GstPlaySink * playsink); - -void gst_play_sink_set_subp_sink (GstPlaySink * playsink, GstElement * sink); -GstElement * gst_play_sink_get_subp_sink (GstPlaySink * playsink); - void gst_play_sink_set_volume (GstPlaySink *playsink, gdouble volume); gdouble gst_play_sink_get_volume (GstPlaySink *playsink);