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 * input-selector, so that we only post a
* warning once */ * 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 *audio_sink; /* configured audio sink, or NULL */
GstElement *video_sink; /* configured video sink, or NULL */ GstElement *video_sink; /* configured video sink, or NULL */
GstElement *text_sink; /* configured text 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, gst_play_bin_suburidecodebin_block (group, group->suburidecodebin,
TRUE); TRUE);
/* activate the selected pad */
g_object_set (selector, "active-pad", sinkpad, NULL);
src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src"); src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src");
peer = gst_pad_get_peer (src); peer = gst_pad_get_peer (src);
if (peer) { 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"); s = gst_structure_new_empty ("subtitleoverlay-flush-subtitle");
event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s); event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s);
gst_pad_send_event (peer, event); gst_pad_send_event (peer, event);
playbin->pending_flush_finish = TRUE;
gst_object_unref (peer); gst_object_unref (peer);
} }
gst_object_unref (src); gst_object_unref (src);
/* activate the selected pad */
g_object_set (selector, "active-pad", sinkpad, NULL);
/* Unblock pads if necessary */ /* Unblock pads if necessary */
if (need_unblock) if (need_unblock)
gst_play_bin_suburidecodebin_block (group, group->suburidecodebin, gst_play_bin_suburidecodebin_block (group, group->suburidecodebin,
@ -2574,12 +2579,36 @@ selector_active_pad_changed (GObject * selector, GParamSpec * pspec,
property = "current-text"; property = "current-text";
playbin->current_text = get_current_stream_number (playbin, playbin->current_text = get_current_stream_number (playbin,
group->text_channels); 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; break;
default: default:
property = NULL; property = NULL;
} }
GST_PLAY_BIN_UNLOCK (playbin); GST_PLAY_BIN_UNLOCK (playbin);
notify:
if (property) if (property)
g_object_notify (G_OBJECT (playbin), property); g_object_notify (G_OBJECT (playbin), property);
} }

View file

@ -258,7 +258,9 @@ struct _GstPlaySink
gint colorbalance_values[4]; gint colorbalance_values[4];
GstSegment text_segment; GstSegment text_segment;
gboolean text_flush; gboolean custom_flush_finished;
gboolean ignore_wrong_state;
gboolean pending_flush_stop;
}; };
struct _GstPlaySinkClass struct _GstPlaySinkClass
@ -1870,7 +1872,16 @@ gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
GST_DEBUG_OBJECT (pad, GST_DEBUG_OBJECT (pad,
"Custom subtitle flush event received, marking to flush text"); "Custom subtitle flush event received, marking to flush text");
GST_PLAY_SINK_LOCK (playsink); 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); GST_PLAY_SINK_UNLOCK (playsink);
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) { } else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
GST_DEBUG_OBJECT (pad, 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)); GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin)); 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) { if (playsink->pending_flush_stop) {
GstEvent *event;
GstSegment *text_segment; GstSegment *text_segment;
GstEvent *event;
GstStructure *structure; GstStructure *structure;
GST_DEBUG_OBJECT (pad, // it will be replaced in flush_stop
"Ignoring wrong state due to flush text being marked");
GST_PLAY_SINK_LOCK (playsink);
playsink->text_flush = FALSE;
text_segment = gst_segment_copy (&playsink->text_segment); text_segment = gst_segment_copy (&playsink->text_segment);
GST_PLAY_SINK_UNLOCK (playsink);
/* make queue drop all cached data. /* make queue drop all cached data.
* This event will be dropped on the src pad. */ * 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); structure = gst_event_writable_structure (event);
gst_structure_id_set (structure, gst_structure_id_set (structure,
_playsink_reset_segment_event_marker_id, G_TYPE_BOOLEAN, TRUE, NULL); _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: %" "Pushing flush-stop event with reset segment marker set: %"
GST_PTR_FORMAT, structure); GST_PTR_FORMAT, event);
gst_pad_send_event (pad, event); gst_pad_send_event (pad, event);
/* Re-sync queue segment info after flush-stop. /* 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); "segment marker set: %" GST_PTR_FORMAT, event1);
gst_pad_send_event (pad, event1); gst_pad_send_event (pad, event1);
} }
gst_segment_free (text_segment); 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; ret = GST_FLOW_OK;
} }
GST_PLAY_SINK_UNLOCK (playsink);
gst_object_unref (playsink); gst_object_unref (playsink);
gst_object_unref (tbin); gst_object_unref (tbin);