multiqueue: Improve interleave calculation at startup and EOS
* When a stream receives EOS, it will no longer change, we shouldn't take that stream into account for interleave calculation. * When streams (re)appear, we do not want to grow the initial interleave values to excessive values. Instead of setting it to a default of 5s, progressively grow it to that maximum. * When the status of input streams change (i.e. going to/from "some haven't received data yet" and "all have received data"), update the interleave immediately instead of waiting for (potentially) 5s of data before updating it. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1892>
This commit is contained in:
parent
b6ffad41ca
commit
b141324eae
@ -1295,6 +1295,7 @@ gst_multi_queue_change_state (GstElement * element, GstStateChange transition)
|
|||||||
sq->last_query = FALSE;
|
sq->last_query = FALSE;
|
||||||
g_cond_signal (&sq->query_handled);
|
g_cond_signal (&sq->query_handled);
|
||||||
}
|
}
|
||||||
|
mqueue->interleave_incomplete = FALSE;
|
||||||
GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
|
GST_MULTI_QUEUE_MUTEX_UNLOCK (mqueue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1569,6 +1570,7 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
{
|
{
|
||||||
GstClockTimeDiff low, high;
|
GstClockTimeDiff low, high;
|
||||||
GstClockTime interleave, other_interleave = 0;
|
GstClockTime interleave, other_interleave = 0;
|
||||||
|
gboolean some_inactive = FALSE;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
|
||||||
low = high = GST_CLOCK_STIME_NONE;
|
low = high = GST_CLOCK_STIME_NONE;
|
||||||
@ -1579,16 +1581,12 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
/* Ignore sparse streams for interleave calculation */
|
/* Ignore sparse streams for interleave calculation */
|
||||||
if (oq->is_sparse)
|
if (oq->is_sparse)
|
||||||
continue;
|
continue;
|
||||||
/* If a stream is not active yet (hasn't received any buffers), set
|
|
||||||
* a maximum interleave to allow it to receive more data */
|
/* If some streams aren't active yet (haven't received any buffers), we will
|
||||||
|
* grow interleave accordingly */
|
||||||
if (!oq->active) {
|
if (!oq->active) {
|
||||||
GST_LOG_OBJECT (mq,
|
some_inactive = TRUE;
|
||||||
"queue %d is not active yet, forcing interleave to 5s", oq->id);
|
continue;
|
||||||
mq->interleave = 5 * GST_SECOND;
|
|
||||||
/* Update max-size time */
|
|
||||||
mq->max_size.time = mq->interleave;
|
|
||||||
SET_CHILD_PROPERTY (mq, time);
|
|
||||||
goto beach;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate within each streaming thread */
|
/* Calculate within each streaming thread */
|
||||||
@ -1598,7 +1596,8 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_CLOCK_STIME_IS_VALID (oq->cached_sinktime)) {
|
/* If the stream isn't EOS, update the low/high input value */
|
||||||
|
if (GST_CLOCK_STIME_IS_VALID (oq->cached_sinktime) && !oq->is_eos) {
|
||||||
if (low == GST_CLOCK_STIME_NONE || oq->cached_sinktime < low)
|
if (low == GST_CLOCK_STIME_NONE || oq->cached_sinktime < low)
|
||||||
low = oq->cached_sinktime;
|
low = oq->cached_sinktime;
|
||||||
if (high == GST_CLOCK_STIME_NONE || oq->cached_sinktime > high)
|
if (high == GST_CLOCK_STIME_NONE || oq->cached_sinktime > high)
|
||||||
@ -1612,6 +1611,7 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GST_CLOCK_STIME_IS_VALID (low) && GST_CLOCK_STIME_IS_VALID (high)) {
|
if (GST_CLOCK_STIME_IS_VALID (low) && GST_CLOCK_STIME_IS_VALID (high)) {
|
||||||
|
gboolean do_update = high == low;
|
||||||
interleave = high - low;
|
interleave = high - low;
|
||||||
/* Padding of interleave and minimum value */
|
/* Padding of interleave and minimum value */
|
||||||
interleave = (150 * interleave / 100) + mq->min_interleave_time;
|
interleave = (150 * interleave / 100) + mq->min_interleave_time;
|
||||||
@ -1620,11 +1620,28 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
|
|
||||||
interleave = MAX (interleave, other_interleave);
|
interleave = MAX (interleave, other_interleave);
|
||||||
|
|
||||||
|
/* Progressively grow up the interleave up to 5s if some streams were inactive */
|
||||||
|
if (some_inactive && interleave <= mq->interleave) {
|
||||||
|
interleave = MIN (5 * GST_SECOND, mq->interleave + 100 * GST_MSECOND);
|
||||||
|
do_update = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We force the interleave update if:
|
||||||
|
* * the interleave was previously set while some streams were not active
|
||||||
|
* yet but they now all are
|
||||||
|
* * OR the interleave was previously based on all streams being active
|
||||||
|
* whereas some now aren't
|
||||||
|
*/
|
||||||
|
if (mq->interleave_incomplete != some_inactive)
|
||||||
|
do_update = TRUE;
|
||||||
|
|
||||||
|
mq->interleave_incomplete = some_inactive;
|
||||||
|
|
||||||
/* Update the stored interleave if:
|
/* Update the stored interleave if:
|
||||||
* * No data has arrived yet (high == low)
|
* * No data has arrived yet (high == low)
|
||||||
* * Or it went higher
|
* * Or it went higher
|
||||||
* * Or it went lower and we've gone past the previous interleave needed */
|
* * Or it went lower and we've gone past the previous interleave needed */
|
||||||
if (high == low || interleave > mq->interleave ||
|
if (do_update || interleave > mq->interleave ||
|
||||||
((mq->last_interleave_update + (2 * MIN (GST_SECOND,
|
((mq->last_interleave_update + (2 * MIN (GST_SECOND,
|
||||||
mq->interleave)) < low)
|
mq->interleave)) < low)
|
||||||
&& interleave < (mq->interleave * 3 / 4))) {
|
&& interleave < (mq->interleave * 3 / 4))) {
|
||||||
@ -1637,7 +1654,6 @@ calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
|
||||||
GST_DEBUG_OBJECT (mq,
|
GST_DEBUG_OBJECT (mq,
|
||||||
"low:%" GST_STIME_FORMAT " high:%" GST_STIME_FORMAT " interleave:%"
|
"low:%" GST_STIME_FORMAT " high:%" GST_STIME_FORMAT " interleave:%"
|
||||||
GST_TIME_FORMAT " mq->interleave:%" GST_TIME_FORMAT
|
GST_TIME_FORMAT " mq->interleave:%" GST_TIME_FORMAT
|
||||||
|
@ -85,6 +85,7 @@ struct _GstMultiQueue {
|
|||||||
|
|
||||||
GstClockTime interleave; /* Input interleave */
|
GstClockTime interleave; /* Input interleave */
|
||||||
GstClockTimeDiff last_interleave_update;
|
GstClockTimeDiff last_interleave_update;
|
||||||
|
gboolean interleave_incomplete; /* TRUE if not all streams were active */
|
||||||
|
|
||||||
GstClockTime unlinked_cache_time;
|
GstClockTime unlinked_cache_time;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user