mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
playbin2: Send flush events when changing subtitle tracks and use new input-selector modes for subtitle tracks
For audio/video we should flush too for fastest stream switches but this currently isn't possible because the flushes would need to go to the sink, which then causes state changes and causes all timing information to be changed. Should work out of the box in 0.11 with the flush-stop that doesn't reset the times. Conflicts: gst/playback/gstplaybin2.c gst/playback/gstplaysink.c gst/playback/gstsubtitleoverlay.c
This commit is contained in:
parent
9d2e50136e
commit
88d3b7aeee
3 changed files with 331 additions and 98 deletions
|
@ -410,8 +410,14 @@ 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
|
||||
gboolean video_pending_flush_finish; /* whether we are pending to send a custom
|
||||
* custom-video-flush-finish event
|
||||
* on pad activation */
|
||||
gboolean audio_pending_flush_finish; /* whether we are pending to send a custom
|
||||
* custom-audio-flush-finish event
|
||||
* on pad activation */
|
||||
gboolean text_pending_flush_finish; /* whether we are pending to send a custom
|
||||
* custom-subtitle-flush-finish event
|
||||
* on pad activation */
|
||||
|
||||
GstElement *audio_sink; /* configured audio sink, or NULL */
|
||||
|
@ -1667,6 +1673,28 @@ get_current_stream_number (GstPlayBin * playbin, GPtrArray * channels)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_playbin2_send_custom_event (GstObject * selector, const gchar * event_name)
|
||||
{
|
||||
GstPad *src;
|
||||
GstPad *peer;
|
||||
GstStructure *s;
|
||||
GstEvent *event;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src");
|
||||
peer = gst_pad_get_peer (src);
|
||||
if (peer) {
|
||||
s = gst_structure_new_empty (event_name);
|
||||
event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s);
|
||||
gst_pad_send_event (peer, event);
|
||||
gst_object_unref (peer);
|
||||
ret = TRUE;
|
||||
}
|
||||
gst_object_unref (src);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_bin_set_current_video_stream (GstPlayBin * playbin, gint stream)
|
||||
{
|
||||
|
@ -1698,8 +1726,19 @@ gst_play_bin_set_current_video_stream (GstPlayBin * playbin, gint stream)
|
|||
GstObject *selector;
|
||||
|
||||
if ((selector = gst_pad_get_parent (sinkpad))) {
|
||||
GstPad *old_sinkpad;
|
||||
|
||||
g_object_get (selector, "active-pad", &old_sinkpad, NULL);
|
||||
|
||||
if (old_sinkpad != sinkpad) {
|
||||
if (gst_playbin2_send_custom_event (selector,
|
||||
"playsink-custom-video-flush"))
|
||||
playbin->video_pending_flush_finish = TRUE;
|
||||
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
}
|
||||
|
||||
gst_object_unref (selector);
|
||||
}
|
||||
gst_object_unref (sinkpad);
|
||||
|
@ -1745,8 +1784,18 @@ gst_play_bin_set_current_audio_stream (GstPlayBin * playbin, gint stream)
|
|||
GstObject *selector;
|
||||
|
||||
if ((selector = gst_pad_get_parent (sinkpad))) {
|
||||
GstPad *old_sinkpad;
|
||||
|
||||
g_object_get (selector, "active-pad", &old_sinkpad, NULL);
|
||||
|
||||
if (old_sinkpad != sinkpad) {
|
||||
if (gst_playbin2_send_custom_event (selector,
|
||||
"playsink-custom-audio-flush"))
|
||||
playbin->audio_pending_flush_finish = TRUE;
|
||||
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
}
|
||||
gst_object_unref (selector);
|
||||
}
|
||||
gst_object_unref (sinkpad);
|
||||
|
@ -1889,7 +1938,7 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream)
|
|||
|
||||
if (old_sinkpad != sinkpad) {
|
||||
gboolean need_unblock, need_block, need_seek;
|
||||
GstPad *src, *peer = NULL, *oldpeer = NULL;
|
||||
GstPad *peer = NULL, *oldpeer = NULL;
|
||||
GstElement *parent_element = NULL, *old_parent_element = NULL;
|
||||
|
||||
/* Now check if we need to seek the suburidecodebin to the beginning
|
||||
|
@ -1926,22 +1975,9 @@ gst_play_bin_set_current_text_stream (GstPlayBin * playbin, gint stream)
|
|||
gst_play_bin_suburidecodebin_block (group, group->suburidecodebin,
|
||||
TRUE);
|
||||
|
||||
src = gst_element_get_static_pad (GST_ELEMENT_CAST (selector), "src");
|
||||
peer = gst_pad_get_peer (src);
|
||||
if (peer) {
|
||||
GstStructure *s;
|
||||
GstEvent *event;
|
||||
/* Flush the subtitle renderer to remove any
|
||||
* currently displayed subtitles. This event will
|
||||
* never travel outside subtitleoverlay!
|
||||
*/
|
||||
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);
|
||||
if (gst_playbin2_send_custom_event (selector,
|
||||
"playsink-custom-subtitle-flush"))
|
||||
playbin->text_pending_flush_finish = TRUE;
|
||||
|
||||
/* activate the selected pad */
|
||||
g_object_set (selector, "active-pad", sinkpad, NULL);
|
||||
|
@ -2568,38 +2604,39 @@ selector_active_pad_changed (GObject * selector, GParamSpec * pspec,
|
|||
property = "current-video";
|
||||
playbin->current_video = get_current_stream_number (playbin,
|
||||
group->video_channels);
|
||||
|
||||
if (playbin->video_pending_flush_finish) {
|
||||
playbin->video_pending_flush_finish = FALSE;
|
||||
GST_PLAY_BIN_UNLOCK (playbin);
|
||||
gst_playbin2_send_custom_event (GST_OBJECT (selector),
|
||||
"playsink-custom-video-flush-finish");
|
||||
goto notify;
|
||||
}
|
||||
break;
|
||||
case GST_PLAY_SINK_TYPE_AUDIO:
|
||||
case GST_PLAY_SINK_TYPE_AUDIO_RAW:
|
||||
property = "current-audio";
|
||||
playbin->current_audio = get_current_stream_number (playbin,
|
||||
group->audio_channels);
|
||||
|
||||
if (playbin->audio_pending_flush_finish) {
|
||||
playbin->audio_pending_flush_finish = FALSE;
|
||||
GST_PLAY_BIN_UNLOCK (playbin);
|
||||
gst_playbin2_send_custom_event (GST_OBJECT (selector),
|
||||
"playsink-custom-audio-flush-finish");
|
||||
goto notify;
|
||||
}
|
||||
break;
|
||||
case GST_PLAY_SINK_TYPE_TEXT:
|
||||
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;
|
||||
if (playbin->text_pending_flush_finish) {
|
||||
playbin->text_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);
|
||||
|
||||
gst_playbin2_send_custom_event (GST_OBJECT (selector),
|
||||
"playsink-custom-subtitle-flush-finish");
|
||||
goto notify;
|
||||
}
|
||||
break;
|
||||
|
@ -2796,6 +2833,11 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
|||
(_("Missing element '%s' - check your GStreamer installation."),
|
||||
"input-selector"), (NULL));
|
||||
} else {
|
||||
/* sync-mode=1, use clock */
|
||||
if (select->type == GST_PLAY_SINK_TYPE_TEXT)
|
||||
g_object_set (select->selector, "sync-streams", TRUE,
|
||||
"sync-mode", 1, "cache-buffers", TRUE, NULL);
|
||||
else
|
||||
g_object_set (select->selector, "sync-streams", TRUE, NULL);
|
||||
|
||||
g_signal_connect (select->selector, "notify::active-pad",
|
||||
|
|
|
@ -257,10 +257,24 @@ struct _GstPlaySink
|
|||
GList *colorbalance_channels; /* CONTRAST, BRIGHTNESS, HUE, SATURATION */
|
||||
gint colorbalance_values[4];
|
||||
|
||||
/* sending audio/video flushes break stream changes when the pipeline
|
||||
* is paused and played again in 0.10 */
|
||||
#if 0
|
||||
GstSegment video_segment;
|
||||
gboolean video_custom_flush_finished;
|
||||
gboolean video_ignore_wrong_state;
|
||||
gboolean video_pending_flush;
|
||||
|
||||
GstSegment audio_segment;
|
||||
gboolean audio_custom_flush_finished;
|
||||
gboolean audio_ignore_wrong_state;
|
||||
gboolean audio_pending_flush;
|
||||
#endif
|
||||
|
||||
GstSegment text_segment;
|
||||
gboolean custom_flush_finished;
|
||||
gboolean ignore_wrong_state;
|
||||
gboolean pending_flush_stop;
|
||||
gboolean text_custom_flush_finished;
|
||||
gboolean text_ignore_wrong_state;
|
||||
gboolean text_pending_flush;
|
||||
};
|
||||
|
||||
struct _GstPlaySinkClass
|
||||
|
@ -344,6 +358,21 @@ static GstStateChangeReturn gst_play_sink_change_state (GstElement * element,
|
|||
|
||||
static void gst_play_sink_handle_message (GstBin * bin, GstMessage * message);
|
||||
|
||||
/* sending audio/video flushes break stream changes when the pipeline
|
||||
* is paused and played again in 0.10 */
|
||||
#if 0
|
||||
static gboolean gst_play_sink_video_sink_event (GstPad * pad, GstEvent * event);
|
||||
static GstFlowReturn gst_play_sink_video_sink_chain (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
static gboolean gst_play_sink_audio_sink_event (GstPad * pad, GstEvent * event);
|
||||
static GstFlowReturn gst_play_sink_audio_sink_chain (GstPad * pad,
|
||||
GstBuffer * buffer);
|
||||
#endif
|
||||
static gboolean gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event);
|
||||
static GstFlowReturn gst_play_sink_text_sink_chain (GstPad * pad,
|
||||
GstObject * parent, GstBuffer * buffer);
|
||||
|
||||
static void notify_volume_cb (GObject * object, GParamSpec * pspec,
|
||||
GstPlaySink * playsink);
|
||||
static void notify_mute_cb (GObject * object, GParamSpec * pspec,
|
||||
|
@ -1690,8 +1719,17 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
|
|||
|
||||
pad = gst_element_get_static_pad (head, "sink");
|
||||
chain->sinkpad = gst_ghost_pad_new ("sink", pad);
|
||||
gst_object_unref (pad);
|
||||
|
||||
/* sending audio/video flushes break stream changes when the pipeline
|
||||
* is paused and played again in 0.10 */
|
||||
#if 0
|
||||
gst_pad_set_event_function (chain->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_play_sink_video_sink_event));
|
||||
gst_pad_set_chain_function (chain->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_play_sink_video_sink_chain));
|
||||
#endif
|
||||
|
||||
gst_object_unref (pad);
|
||||
gst_element_add_pad (chain->chain.bin, chain->sinkpad);
|
||||
|
||||
return chain;
|
||||
|
@ -1858,37 +1896,52 @@ _generate_update_newsegment_event (GstPad * pad, GstSegment * segment,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event)
|
||||
gst_play_sink_sink_event (GstPad * pad, GstObject * parent, GstEvent * event,
|
||||
const gchar * sink_type,
|
||||
gboolean * sink_ignore_wrong_state,
|
||||
gboolean * sink_custom_flush_finished,
|
||||
gboolean * sink_pending_flush, GstSegment * sink_segment)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_object_get_parent (parent));
|
||||
gboolean ret;
|
||||
const GstStructure *structure = gst_event_get_structure (event);
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB &&
|
||||
structure
|
||||
&& strcmp (gst_structure_get_name (structure),
|
||||
"subtitleoverlay-flush-subtitle") == 0) {
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB && structure) {
|
||||
gchar *custom_flush;
|
||||
gchar *custom_flush_finish;
|
||||
|
||||
custom_flush = g_strdup_printf ("playsink-custom-%s-flush", sink_type);
|
||||
custom_flush_finish =
|
||||
g_strdup_printf ("playsink-custom-%s-flush-finish", sink_type);
|
||||
if (strcmp (gst_structure_get_name (structure), custom_flush) == 0) {
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"Custom subtitle flush event received, marking to flush text");
|
||||
"Custom %s flush event received, marking to flush %s", sink_type,
|
||||
sink_type);
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
playsink->ignore_wrong_state = TRUE;
|
||||
playsink->custom_flush_finished = FALSE;
|
||||
*sink_ignore_wrong_state = TRUE;
|
||||
*sink_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");
|
||||
} else if (strcmp (gst_structure_get_name (structure),
|
||||
custom_flush_finish) == 0) {
|
||||
GST_DEBUG_OBJECT (pad, "Custom %s flush finish event received",
|
||||
sink_type);
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
playsink->pending_flush_stop = TRUE;
|
||||
playsink->custom_flush_finished = TRUE;
|
||||
*sink_pending_flush = TRUE;
|
||||
*sink_custom_flush_finished = TRUE;
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"Resetting text segment because of flush-stop event");
|
||||
gst_segment_init (&playsink->text_segment, GST_FORMAT_UNDEFINED);
|
||||
}
|
||||
|
||||
g_free (custom_flush);
|
||||
g_free (custom_flush_finish);
|
||||
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
GST_DEBUG_OBJECT (pad, "Resetting %s segment because of flush-stop event",
|
||||
sink_type);
|
||||
gst_segment_init (sink_segment, GST_FORMAT_UNDEFINED);
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Forwarding event %" GST_PTR_FORMAT, event);
|
||||
ret = gst_proxy_pad_event_default (pad, parent, gst_event_ref (event));
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
|
||||
|
@ -1897,17 +1950,21 @@ gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
|
|||
gst_event_parse_segment (event, &segment);
|
||||
GST_DEBUG_OBJECT (pad, "Segment event: %" GST_SEGMENT_FORMAT, segment);
|
||||
|
||||
if (playsink->text_segment.format != segment->format) {
|
||||
GST_DEBUG_OBJECT (pad, "Text segment format changed: %s -> %s",
|
||||
gst_format_get_name (playsink->text_segment.format),
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
if (sink_segment->format != segment->format) {
|
||||
GST_DEBUG_OBJECT (pad, "%s segment format changed: %s -> %s",
|
||||
sink_type,
|
||||
gst_format_get_name (sink_segment->format),
|
||||
gst_format_get_name (segment->format));
|
||||
gst_segment_init (sink_segment, segment->format);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "Old text segment: %" GST_SEGMENT_FORMAT,
|
||||
&playsink->text_segment);
|
||||
gst_segment_copy_into (segment, &playsink->text_segment);
|
||||
GST_DEBUG_OBJECT (pad, "New text segment: %" GST_SEGMENT_FORMAT,
|
||||
&playsink->text_segment);
|
||||
GST_DEBUG_OBJECT (pad, "Old %s segment: %" GST_SEGMENT_FORMAT,
|
||||
sink_type, sink_segment);
|
||||
gst_segment_copy_into (&playsink->text_segment, sink_segment);
|
||||
GST_DEBUG_OBJECT (pad, "New %s segment: %" GST_SEGMENT_FORMAT,
|
||||
sink_type, sink_segment);
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
}
|
||||
|
||||
gst_event_unref (event);
|
||||
|
@ -1916,8 +1973,11 @@ gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
|
|||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent,
|
||||
GstBuffer * buffer)
|
||||
gst_play_sink_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer,
|
||||
const gchar * sink_type,
|
||||
gboolean * sink_ignore_wrong_state,
|
||||
gboolean * sink_custom_flush_finished,
|
||||
gboolean * sink_pending_flush, GstSegment * sink_segment)
|
||||
{
|
||||
GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin));
|
||||
|
@ -1925,13 +1985,29 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent,
|
|||
|
||||
GST_PLAY_SINK_LOCK (playsink);
|
||||
|
||||
if (playsink->pending_flush_stop) {
|
||||
GstSegment text_segment;
|
||||
if (*sink_pending_flush) {
|
||||
GstSegment segment_copy;
|
||||
GstEvent *event;
|
||||
GstStructure *structure;
|
||||
|
||||
/* it will be replaced in flush_stop */
|
||||
text_segment = playsink->text_segment;
|
||||
*sink_pending_flush = FALSE;
|
||||
|
||||
/* sink_segment will be updated in flush */
|
||||
segment_copy = *sink_segment;
|
||||
|
||||
GST_PLAY_SINK_UNLOCK (playsink);
|
||||
|
||||
/* make the bin drop all cached data.
|
||||
* This event will be dropped on the src pad, if any. */
|
||||
event = gst_event_new_flush_start ();
|
||||
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 (pad,
|
||||
"Pushing %s flush-start event with reset segment marker set: %"
|
||||
GST_PTR_FORMAT, sink_type, event);
|
||||
gst_pad_send_event (pad, event);
|
||||
|
||||
/* make queue drop all cached data.
|
||||
* This event will be dropped on the src pad. */
|
||||
|
@ -1941,35 +2017,35 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent,
|
|||
_playsink_reset_segment_event_marker_id, G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (pad,
|
||||
"Pushing flush-stop event with reset segment marker set: %"
|
||||
GST_PTR_FORMAT, event);
|
||||
"Pushing %s flush-stop event with reset segment marker set: %"
|
||||
GST_PTR_FORMAT, sink_type, event);
|
||||
gst_pad_send_event (pad, event);
|
||||
|
||||
/* Re-sync queue segment info after flush-stop.
|
||||
* This event will be dropped on the src pad. */
|
||||
if (text_segment.format != GST_FORMAT_UNDEFINED) {
|
||||
if (sink_segment->format != GST_FORMAT_UNDEFINED) {
|
||||
GstEvent *event1;
|
||||
|
||||
_generate_update_newsegment_event (pad, &text_segment, &event1);
|
||||
_generate_update_newsegment_event (pad, sink_segment, &event1);
|
||||
GST_DEBUG_OBJECT (playsink,
|
||||
"Pushing segment event with reset "
|
||||
"segment marker set: %" GST_PTR_FORMAT, event1);
|
||||
gst_pad_send_event (pad, event1);
|
||||
}
|
||||
|
||||
playsink->pending_flush_stop = FALSE;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
if (ret == GST_FLOW_FLUSHING && *sink_ignore_wrong_state) {
|
||||
GST_DEBUG_OBJECT (pad, "Ignoring wrong state for %s during flush",
|
||||
sink_type);
|
||||
if (*sink_custom_flush_finished) {
|
||||
GST_DEBUG_OBJECT (pad, "Custom flush finished, stop ignoring "
|
||||
"wrong state for %s", sink_type);
|
||||
*sink_ignore_wrong_state = FALSE;
|
||||
}
|
||||
|
||||
ret = GST_FLOW_OK;
|
||||
|
@ -1981,6 +2057,111 @@ gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* sending audio/video flushes break stream changes when the pipeline
|
||||
* is paused and played again in 0.10 */
|
||||
#if 0
|
||||
static gboolean
|
||||
gst_play_sink_video_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin));
|
||||
gboolean ret;
|
||||
|
||||
ret = gst_play_sink_sink_event (pad, event, "video",
|
||||
&playsink->video_ignore_wrong_state,
|
||||
&playsink->video_custom_flush_finished,
|
||||
&playsink->video_pending_flush, &playsink->video_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
gst_object_unref (tbin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_play_sink_video_sink_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin));
|
||||
gboolean ret;
|
||||
|
||||
ret = gst_play_sink_sink_chain (pad, buffer, "video",
|
||||
&playsink->video_ignore_wrong_state,
|
||||
&playsink->video_custom_flush_finished,
|
||||
&playsink->video_pending_flush, &playsink->video_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
gst_object_unref (tbin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_sink_audio_sink_event (GstPad * pad, GstEvent * event)
|
||||
{
|
||||
GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin));
|
||||
gboolean ret;
|
||||
|
||||
ret = gst_play_sink_sink_event (pad, event, "audio",
|
||||
&playsink->audio_ignore_wrong_state,
|
||||
&playsink->audio_custom_flush_finished,
|
||||
&playsink->audio_pending_flush, &playsink->audio_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
gst_object_unref (tbin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_play_sink_audio_sink_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
GstBin *tbin = GST_BIN_CAST (gst_pad_get_parent (pad));
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_pad_get_parent (tbin));
|
||||
gboolean ret;
|
||||
|
||||
ret = gst_play_sink_sink_chain (pad, buffer, "audio",
|
||||
&playsink->audio_ignore_wrong_state,
|
||||
&playsink->audio_custom_flush_finished,
|
||||
&playsink->audio_pending_flush, &playsink->audio_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
gst_object_unref (tbin);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
gst_play_sink_text_sink_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event)
|
||||
{
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_object_get_parent (parent));
|
||||
gboolean ret;
|
||||
|
||||
ret = gst_play_sink_sink_event (pad, parent, event, "subtitle",
|
||||
&playsink->text_ignore_wrong_state,
|
||||
&playsink->text_custom_flush_finished,
|
||||
&playsink->text_pending_flush, &playsink->text_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_play_sink_text_sink_chain (GstPad * pad, GstObject * parent,
|
||||
GstBuffer * buffer)
|
||||
{
|
||||
gboolean ret;
|
||||
GstPlaySink *playsink = GST_PLAY_SINK_CAST (gst_object_get_parent (parent));
|
||||
|
||||
ret = gst_play_sink_sink_chain (pad, parent, buffer, "subtitle",
|
||||
&playsink->text_ignore_wrong_state,
|
||||
&playsink->text_custom_flush_finished,
|
||||
&playsink->text_pending_flush, &playsink->text_segment);
|
||||
|
||||
gst_object_unref (playsink);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_play_sink_text_src_event (GstPad * pad, GstObject * parent,
|
||||
GstEvent * event)
|
||||
|
@ -2439,6 +2620,16 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw)
|
|||
GST_DEBUG_OBJECT (playsink, "ghosting sink pad");
|
||||
pad = gst_element_get_static_pad (head, "sink");
|
||||
chain->sinkpad = gst_ghost_pad_new ("sink", pad);
|
||||
|
||||
/* sending audio/video flushes break stream changes when the pipeline
|
||||
* is paused and played again in 0.10 */
|
||||
#if 0
|
||||
gst_pad_set_event_function (chain->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_play_sink_audio_sink_event));
|
||||
gst_pad_set_chain_function (chain->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_play_sink_audio_sink_chain));
|
||||
#endif
|
||||
|
||||
gst_object_unref (pad);
|
||||
gst_element_add_pad (chain->chain.bin, chain->sinkpad);
|
||||
|
||||
|
|
|
@ -2066,7 +2066,7 @@ gst_subtitle_overlay_subtitle_sink_event (GstPad * pad, GstObject * parent,
|
|||
GST_DEBUG_OBJECT (pad, "Got event %" GST_PTR_FORMAT, event);
|
||||
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM_OOB &&
|
||||
gst_event_has_name (event, "subtitleoverlay-flush-subtitle")) {
|
||||
gst_event_has_name (event, "playsink-custom-subtitle-flush")) {
|
||||
GST_DEBUG_OBJECT (pad, "Custom subtitle flush event");
|
||||
GST_SUBTITLE_OVERLAY_LOCK (self);
|
||||
self->subtitle_flush = TRUE;
|
||||
|
|
Loading…
Reference in a new issue