mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 04:00:37 +00:00
playbin2: Properly change subtitles
Conflicts: gst/playback/gstplaysink.c
This commit is contained in:
parent
605d5c110c
commit
b41d19fa5f
2 changed files with 72 additions and 19 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -2526,7 +2550,7 @@ setup_audio_chain (GstPlaySink * playsink, gboolean raw)
|
||||||
} else if (conv) {
|
} else if (conv) {
|
||||||
/* no volume, we need to add a volume element when we can */
|
/* no volume, we need to add a volume element when we can */
|
||||||
g_object_set (chain->conv, "use-volume",
|
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");
|
GST_DEBUG_OBJECT (playsink, "the sink has no volume property");
|
||||||
|
|
||||||
/* Disconnect signals */
|
/* Disconnect signals */
|
||||||
|
@ -3647,14 +3671,14 @@ caps_notify_cb (GstPad * pad, GParamSpec * unused, GstPlaySink * playsink)
|
||||||
|
|
||||||
if (pad == playsink->audio_pad) {
|
if (pad == playsink->audio_pad) {
|
||||||
raw = is_raw_pad (pad);
|
raw = is_raw_pad (pad);
|
||||||
reconfigure = (! !playsink->audio_pad_raw != ! !raw)
|
reconfigure = (!!playsink->audio_pad_raw != !!raw)
|
||||||
&& playsink->audiochain;
|
&& playsink->audiochain;
|
||||||
GST_DEBUG_OBJECT (pad,
|
GST_DEBUG_OBJECT (pad,
|
||||||
"Audio caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
"Audio caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
||||||
reconfigure, caps);
|
reconfigure, caps);
|
||||||
} else if (pad == playsink->video_pad) {
|
} else if (pad == playsink->video_pad) {
|
||||||
raw = is_raw_pad (pad);
|
raw = is_raw_pad (pad);
|
||||||
reconfigure = (! !playsink->video_pad_raw != ! !raw)
|
reconfigure = (!!playsink->video_pad_raw != !!raw)
|
||||||
&& playsink->videochain;
|
&& playsink->videochain;
|
||||||
GST_DEBUG_OBJECT (pad,
|
GST_DEBUG_OBJECT (pad,
|
||||||
"Video caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
"Video caps changed: raw %d reconfigure %d caps %" GST_PTR_FORMAT, raw,
|
||||||
|
|
Loading…
Reference in a new issue