From: Andre Moreira Magalhaes (andrunko) Date: Sun, 20 May 2012 15:51:17 +0000 (-0300) Subject: playbin2: Properly change subtitles X-Git-Tag: 1.19.3~511^2~6359 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b41d19fa5ff557667a76155eda24ef6233a401f2;p=platform%2Fupstream%2Fgstreamer.git playbin2: Properly change subtitles Conflicts: gst/playback/gstplaysink.c --- diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 85425d0..32b877c3 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -410,6 +410,10 @@ struct _GstPlayBin * input-selector, so that we only post a * warning once */ + gboolean pending_flush_finish; /* whether we are pending to send a custom + * subtitleoverlay-flush-subtitle-finish event + * on pad activation */ + GstElement *audio_sink; /* configured audio sink, or NULL */ GstElement *video_sink; /* configured video sink, or NULL */ GstElement *text_sink; /* configured text sink, or NULL */ @@ -1922,9 +1926,6 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream) gst_play_bin_suburidecodebin_block (group, group->suburidecodebin, TRUE); - /* activate the selected pad */ - g_object_set (selector, "active-pad", sinkpad, NULL); - src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src"); peer = gst_pad_get_peer (src); if (peer) { @@ -1937,10 +1938,14 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream) s = gst_structure_new_empty ("subtitleoverlay-flush-subtitle"); event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s); gst_pad_send_event (peer, event); + playbin->pending_flush_finish = TRUE; gst_object_unref (peer); } gst_object_unref (src); + /* activate the selected pad */ + g_object_set (selector, "active-pad", sinkpad, NULL); + /* Unblock pads if necessary */ if (need_unblock) gst_play_bin_suburidecodebin_block (group, group->suburidecodebin, @@ -2574,12 +2579,36 @@ selector_active_pad_changed (GObject * selector, GParamSpec * pspec, property = "current-text"; playbin->current_text = get_current_stream_number (playbin, group->text_channels); + + if (playbin->pending_flush_finish) { + GstEvent *ev; + GstStructure *s; + GstPad *src, *peer; + + playbin->pending_flush_finish = FALSE; + GST_PLAY_BIN_UNLOCK (playbin); + + /* Flush the subtitle renderer to remove any + * currently displayed subtitles. This event will + * never travel outside subtitleoverlay! + */ + src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src"); + peer = gst_pad_get_peer (src); + s = gst_structure_new_empty ("subtitleoverlay-flush-subtitle-finish"); + ev = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s); + gst_pad_send_event (peer, ev); + gst_object_unref (peer); + gst_object_unref (src); + + goto notify; + } break; default: property = NULL; } GST_PLAY_BIN_UNLOCK (playbin); +notify: if (property) g_object_notify (G_OBJECT (playbin), property); } diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 19bce39..eda375f 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -258,7 +258,9 @@ struct _GstPlaySink gint colorbalance_values[4]; GstSegment text_segment; - gboolean text_flush; + gboolean custom_flush_finished; + gboolean ignore_wrong_state; + gboolean pending_flush_stop; }; struct _GstPlaySinkClass @@ -1870,7 +1872,16 @@ gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent, GST_DEBUG_OBJECT (pad, "Custom subtitle flush event received, marking to flush text"); GST_PLAY_SINK_LOCK (playsink); - playsink->text_flush = TRUE; + playsink->ignore_wrong_state = TRUE; + playsink->custom_flush_finished = FALSE; + GST_PLAY_SINK_UNLOCK (playsink); + } else if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB && + structure && strcmp (gst_structure_get_name (structure), + "subtitleoverlay-flush-subtitle-finish") == 0) { + GST_DEBUG_OBJECT (pad, "Custom subtitle flush finish event received"); + GST_PLAY_SINK_LOCK (playsink); + playsink->pending_flush_stop = TRUE; + playsink->custom_flush_finished = TRUE; GST_PLAY_SINK_UNLOCK (playsink); } else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) { GST_DEBUG_OBJECT (pad, @@ -1910,20 +1921,17 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent, { GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad)); GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin)); + GstFlowReturn ret; - GstFlowReturn ret = gst_proxy_pad_chain_default (pad, parent, buffer); + GST_PLAY_SINK_LOCK (playsink); - if (ret == GST_FLOW_FLUSHING && playsink->text_flush) { - GstEvent *event; + if (playsink->pending_flush_stop) { GstSegment *text_segment; + GstEvent *event; GstStructure *structure; - GST_DEBUG_OBJECT (pad, - "Ignoring wrong state due to flush text being marked"); - GST_PLAY_SINK_LOCK (playsink); - playsink->text_flush = FALSE; + // it will be replaced in flush_stop text_segment = gst_segment_copy (&playsink->text_segment); - GST_PLAY_SINK_UNLOCK (playsink); /* make queue drop all cached data. * This event will be dropped on the src pad. */ @@ -1931,9 +1939,10 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent, structure = gst_event_writable_structure (event); gst_structure_id_set (structure, _playsink_reset_segment_event_marker_id, G_TYPE_BOOLEAN, TRUE, NULL); - GST_DEBUG_OBJECT (playsink, + + GST_DEBUG_OBJECT (pad, "Pushing flush-stop event with reset segment marker set: %" - GST_PTR_FORMAT, structure); + GST_PTR_FORMAT, event); gst_pad_send_event (pad, event); /* Re-sync queue segment info after flush-stop. @@ -1947,11 +1956,26 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent, "segment marker set: %" GST_PTR_FORMAT, event1); gst_pad_send_event (pad, event1); } - gst_segment_free (text_segment); + playsink->pending_flush_stop = FALSE; + } + GST_PLAY_SINK_UNLOCK (playsink); + + ret = gst_proxy_pad_chain_default (pad, parent, buffer); + + GST_PLAY_SINK_LOCK (playsink); + if (ret == GST_FLOW_FLUSHING && playsink->ignore_wrong_state) { + GST_DEBUG_OBJECT (pad, "Ignoring wrong state during flush"); + if (playsink->custom_flush_finished) { + GST_DEBUG_OBJECT (pad, + "custom flush finished, stop ignoring wrong state"); + playsink->ignore_wrong_state = FALSE; + } + ret = GST_FLOW_OK; } + GST_PLAY_SINK_UNLOCK (playsink); gst_object_unref (playsink); gst_object_unref (tbin); @@ -2526,7 +2550,7 @@ setup_audio_chain (GstPlaySink * playsink, gboolean raw) } else if (conv) { /* no volume, we need to add a volume element when we can */ g_object_set (chain->conv, "use-volume", - ! !(playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME), NULL); + !!(playsink->flags & GST_PLAY_FLAG_SOFT_VOLUME), NULL); GST_DEBUG_OBJECT (playsink, "the sink has no volume property"); /* Disconnect signals */ @@ -3647,14 +3671,14 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink) if (pad == playsink->audio_pad) { raw = is_raw_pad (pad); - reconfigure = (! !playsink->audio_pad_raw != ! !raw) + reconfigure = (!!playsink->audio_pad_raw != !!raw) && playsink->audiochain; GST_DEBUG_OBJECT (pad, "Audio caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw, reconfigure, caps); } else if (pad == playsink->video_pad) { raw = is_raw_pad (pad); - reconfigure = (! !playsink->video_pad_raw != ! !raw) + reconfigure = (!!playsink->video_pad_raw != !!raw) && playsink->videochain; GST_DEBUG_OBJECT (pad, "Video caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,