* 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 */
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) {
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,
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);
}
gint colorbalance_values[4];
GstSegment text_segment;
- gboolean text_flush;
+ gboolean custom_flush_finished;
+ gboolean ignore_wrong_state;
+ gboolean pending_flush_stop;
};
struct _GstPlaySinkClass
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,
{
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. */
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.
"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);
} 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 */
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,