mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
playbin2: Remove QOS event adjustments for gapless playback mode
This commit is contained in:
parent
ed271ff809
commit
f835533cb4
1 changed files with 1 additions and 158 deletions
|
@ -267,10 +267,6 @@ struct _GstSourceSelect
|
||||||
GstPad *sinkpad; /* the sinkpad of the sink when the selector
|
GstPad *sinkpad; /* the sinkpad of the sink when the selector
|
||||||
* is linked
|
* is linked
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gulong src_event_probe_id;
|
|
||||||
gulong sink_event_probe_id;
|
|
||||||
GstClockTime group_start_accum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_SOURCE_GROUP_GET_LOCK(group) (((GstSourceGroup*)(group))->lock)
|
#define GST_SOURCE_GROUP_GET_LOCK(group) (((GstSourceGroup*)(group))->lock)
|
||||||
|
@ -406,8 +402,6 @@ struct _GstPlayBin
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gint64 duration;
|
gint64 duration;
|
||||||
} duration[5]; /* cached durations */
|
} duration[5]; /* cached durations */
|
||||||
|
|
||||||
GstSegment segments[3]; /* Video/Audio/Text segments */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstPlayBinClass
|
struct _GstPlayBinClass
|
||||||
|
@ -2327,118 +2321,6 @@ notify_tags_cb (GObject * object, GParamSpec * pspec, gpointer user_data)
|
||||||
ntdata->stream_id);
|
ntdata->stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GstPlayBin *playbin;
|
|
||||||
GstSourceGroup *group;
|
|
||||||
GstPlaySinkType type;
|
|
||||||
} PlaySinkEventProbeData;
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_playsink_src_event_probe_cb (GstPad * pad, GstEvent * event,
|
|
||||||
PlaySinkEventProbeData * data)
|
|
||||||
{
|
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_QOS) {
|
|
||||||
GstEvent *new_event;
|
|
||||||
GstStructure *s;
|
|
||||||
gdouble proportion;
|
|
||||||
GstClockTimeDiff diff;
|
|
||||||
GstClockTime group_start_accum =
|
|
||||||
data->group->selector[data->type].group_start_accum;
|
|
||||||
GstClockTime timestamp;
|
|
||||||
|
|
||||||
s = (GstStructure *) gst_event_get_structure (event);
|
|
||||||
if (gst_structure_has_field (s, "playbin2-adjusted-event"))
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* If we have no group start accumulator yet, this is
|
|
||||||
* a QOS event for the previous group or this stream
|
|
||||||
* has a non-time segment.
|
|
||||||
*/
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (group_start_accum))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* If the group start accumulator is 0, this is the first
|
|
||||||
* group and we don't need to do everything below
|
|
||||||
*/
|
|
||||||
if (group_start_accum == 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
gst_event_parse_qos (event, &proportion, &diff, ×tamp);
|
|
||||||
|
|
||||||
/* If the running time timestamp is smaller than the accumulator,
|
|
||||||
* the event is for a buffer from the previous group
|
|
||||||
*/
|
|
||||||
if (timestamp >= group_start_accum)
|
|
||||||
timestamp -= group_start_accum;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* That case is invalid for QoS events, also it means that
|
|
||||||
* we have switched the group but receive QoS events of
|
|
||||||
* the previous group.
|
|
||||||
*/
|
|
||||||
if (diff < 0 && -diff > timestamp)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
new_event = gst_event_new_qos (proportion, diff, timestamp);
|
|
||||||
s = (GstStructure *) gst_event_get_structure (new_event);
|
|
||||||
gst_structure_set (s, "playbin2-adjusted-event", G_TYPE_BOOLEAN, TRUE,
|
|
||||||
NULL);
|
|
||||||
gst_pad_send_event (pad, new_event);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_playsink_sink_event_probe_cb (GstPad * pad, GstEvent * event,
|
|
||||||
PlaySinkEventProbeData * data)
|
|
||||||
{
|
|
||||||
guint index;
|
|
||||||
|
|
||||||
if (data->type == GST_PLAY_SINK_TYPE_VIDEO
|
|
||||||
|| data->type == GST_PLAY_SINK_TYPE_VIDEO_RAW)
|
|
||||||
index = 0;
|
|
||||||
else if (data->type == GST_PLAY_SINK_TYPE_AUDIO
|
|
||||||
|| data->type == GST_PLAY_SINK_TYPE_AUDIO_RAW)
|
|
||||||
index = 1;
|
|
||||||
else if (data->type == GST_PLAY_SINK_TYPE_TEXT)
|
|
||||||
index = 2;
|
|
||||||
else
|
|
||||||
g_assert_not_reached ();
|
|
||||||
|
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
|
|
||||||
GstPlayBin *playbin = data->playbin;
|
|
||||||
GstSegment *segment;
|
|
||||||
gboolean update;
|
|
||||||
GstFormat format;
|
|
||||||
gdouble rate, applied_rate;
|
|
||||||
gint64 start, stop, pos;
|
|
||||||
|
|
||||||
segment = &playbin->segments[index];
|
|
||||||
|
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
|
|
||||||
&format, &start, &stop, &pos);
|
|
||||||
if (segment->format != format)
|
|
||||||
gst_segment_init (segment, format);
|
|
||||||
gst_segment_set_newsegment_full (segment, update, rate, applied_rate,
|
|
||||||
format, start, stop, pos);
|
|
||||||
|
|
||||||
if (format != GST_FORMAT_TIME)
|
|
||||||
data->group->selector[data->type].group_start_accum = GST_CLOCK_TIME_NONE;
|
|
||||||
else if (!GST_CLOCK_TIME_IS_VALID (data->group->selector[data->type].
|
|
||||||
group_start_accum))
|
|
||||||
data->group->selector[data->type].group_start_accum = segment->accum;
|
|
||||||
} else if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
|
|
||||||
gst_segment_init (&data->playbin->segments[index], GST_FORMAT_UNDEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this function is called when a new pad is added to decodebin. We check the
|
/* this function is called when a new pad is added to decodebin. We check the
|
||||||
* type of the pad and add it to the selector element of the group.
|
* type of the pad and add it to the selector element of the group.
|
||||||
*/
|
*/
|
||||||
|
@ -2514,8 +2396,6 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select->srcpad == NULL) {
|
if (select->srcpad == NULL) {
|
||||||
PlaySinkEventProbeData *data = g_new (PlaySinkEventProbeData, 1);
|
|
||||||
|
|
||||||
if (select->selector) {
|
if (select->selector) {
|
||||||
/* save source pad of the selector */
|
/* save source pad of the selector */
|
||||||
select->srcpad = gst_element_get_static_pad (select->selector, "src");
|
select->srcpad = gst_element_get_static_pad (select->selector, "src");
|
||||||
|
@ -2524,17 +2404,6 @@ pad_added_cb (GstElement * decodebin, GstPad * pad, GstSourceGroup * group)
|
||||||
select->srcpad = gst_object_ref (pad);
|
select->srcpad = gst_object_ref (pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Install an event probe */
|
|
||||||
data->playbin = playbin;
|
|
||||||
data->group = group;
|
|
||||||
data->type = select->type;
|
|
||||||
select->src_event_probe_id =
|
|
||||||
gst_pad_add_event_probe_full (select->srcpad,
|
|
||||||
G_CALLBACK (_playsink_src_event_probe_cb), data,
|
|
||||||
(GDestroyNotify) g_free);
|
|
||||||
|
|
||||||
select->group_start_accum = -1;
|
|
||||||
|
|
||||||
/* block the selector srcpad. It's possible that multiple decodebins start
|
/* block the selector srcpad. It's possible that multiple decodebins start
|
||||||
* pushing data into the selectors before we have a chance to collect all
|
* pushing data into the selectors before we have a chance to collect all
|
||||||
* streams and connect the sinks, resulting in not-linked errors. After we
|
* streams and connect the sinks, resulting in not-linked errors. After we
|
||||||
|
@ -2749,21 +2618,10 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
|
||||||
* and link it. We only do this if we have not yet requested the sinkpad
|
* and link it. We only do this if we have not yet requested the sinkpad
|
||||||
* before. */
|
* before. */
|
||||||
if (select->srcpad && select->sinkpad == NULL) {
|
if (select->srcpad && select->sinkpad == NULL) {
|
||||||
PlaySinkEventProbeData *data = g_new (PlaySinkEventProbeData, 1);
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (playbin, "requesting new sink pad %d", select->type);
|
GST_DEBUG_OBJECT (playbin, "requesting new sink pad %d", select->type);
|
||||||
select->sinkpad =
|
select->sinkpad =
|
||||||
gst_play_sink_request_pad (playbin->playsink, select->type);
|
gst_play_sink_request_pad (playbin->playsink, select->type);
|
||||||
|
|
||||||
/* Install an event probe */
|
|
||||||
data->playbin = playbin;
|
|
||||||
data->group = group;
|
|
||||||
data->type = select->type;
|
|
||||||
select->sink_event_probe_id =
|
|
||||||
gst_pad_add_event_probe_full (select->sinkpad,
|
|
||||||
G_CALLBACK (_playsink_sink_event_probe_cb), data,
|
|
||||||
(GDestroyNotify) g_free);
|
|
||||||
|
|
||||||
res = gst_pad_link (select->srcpad, select->sinkpad);
|
res = gst_pad_link (select->srcpad, select->sinkpad);
|
||||||
GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
|
GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
|
||||||
select->media_list[0], res);
|
select->media_list[0], res);
|
||||||
|
@ -3358,21 +3216,12 @@ deactivate_group (GstPlayBin * playbin, GstSourceGroup * group)
|
||||||
GST_LOG_OBJECT (playbin, "unlinking from sink");
|
GST_LOG_OBJECT (playbin, "unlinking from sink");
|
||||||
gst_pad_unlink (select->srcpad, select->sinkpad);
|
gst_pad_unlink (select->srcpad, select->sinkpad);
|
||||||
|
|
||||||
if (select->sink_event_probe_id)
|
|
||||||
gst_pad_remove_event_probe (select->sinkpad,
|
|
||||||
select->sink_event_probe_id);
|
|
||||||
select->sink_event_probe_id = 0;
|
|
||||||
|
|
||||||
/* release back */
|
/* release back */
|
||||||
GST_LOG_OBJECT (playbin, "release sink pad");
|
GST_LOG_OBJECT (playbin, "release sink pad");
|
||||||
gst_play_sink_release_pad (playbin->playsink, select->sinkpad);
|
gst_play_sink_release_pad (playbin->playsink, select->sinkpad);
|
||||||
select->sinkpad = NULL;
|
select->sinkpad = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select->src_event_probe_id)
|
|
||||||
gst_pad_remove_event_probe (select->srcpad, select->src_event_probe_id);
|
|
||||||
select->src_event_probe_id = 0;
|
|
||||||
|
|
||||||
gst_object_unref (select->srcpad);
|
gst_object_unref (select->srcpad);
|
||||||
select->srcpad = NULL;
|
select->srcpad = NULL;
|
||||||
}
|
}
|
||||||
|
@ -3544,22 +3393,16 @@ gst_play_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
g_mutex_unlock (playbin->elements_lock);
|
g_mutex_unlock (playbin->elements_lock);
|
||||||
memset (&playbin->duration, 0, sizeof (playbin->duration));
|
memset (&playbin->duration, 0, sizeof (playbin->duration));
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:{
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
guint i;
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (playbin, "clearing shutdown flag");
|
GST_LOG_OBJECT (playbin, "clearing shutdown flag");
|
||||||
memset (&playbin->duration, 0, sizeof (playbin->duration));
|
memset (&playbin->duration, 0, sizeof (playbin->duration));
|
||||||
g_atomic_int_set (&playbin->shutdown, 0);
|
g_atomic_int_set (&playbin->shutdown, 0);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
gst_segment_init (&playbin->segments[i], GST_FORMAT_UNDEFINED);
|
|
||||||
|
|
||||||
if (!setup_next_source (playbin, GST_STATE_READY)) {
|
if (!setup_next_source (playbin, GST_STATE_READY)) {
|
||||||
ret = GST_STATE_CHANGE_FAILURE;
|
ret = GST_STATE_CHANGE_FAILURE;
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
/* FIXME unlock our waiting groups */
|
/* FIXME unlock our waiting groups */
|
||||||
GST_LOG_OBJECT (playbin, "setting shutdown flag");
|
GST_LOG_OBJECT (playbin, "setting shutdown flag");
|
||||||
|
|
Loading…
Reference in a new issue