playbin2: Properly change subtitles

Conflicts:

	gst/playback/gstplaysink.c
This commit is contained in:
Andre Moreira Magalhaes (andrunko) 2012-05-20 12:51:17 -03:00 committed by Thiago Santos
parent 605d5c110c
commit b41d19fa5f
2 changed files with 72 additions and 19 deletions

View file

@ -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);
}

View file

@ -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,