diff options
author | Seungha Yang <sh.yang@lge.com> | 2017-07-03 15:17:33 +0900 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2017-07-19 17:19:14 +0200 |
commit | 1b0059e0c5ae4de4c02d8b849e1d440431f60cb5 (patch) | |
tree | 9c293ddeaaccd81747450a779e48da028edb7a99 /plugins | |
parent | ad6a655cf702c81d48eea6601594959b0561d30e (diff) |
multiqueue: Calculate interleave only within each streaming thread
... and use the biggest interleave value among streaming threads.
This is to optimize multiqueue size adaptation on adaptive streaming
use case with "use-interleave" property.
https://bugzilla.gnome.org/show_bug.cgi?id=784448
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/elements/gstmultiqueue.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/plugins/elements/gstmultiqueue.c b/plugins/elements/gstmultiqueue.c index d8c6ca188..b2d7d4415 100644 --- a/plugins/elements/gstmultiqueue.c +++ b/plugins/elements/gstmultiqueue.c @@ -168,7 +168,8 @@ struct _GstSingleQueue GstQuery *last_handled_query; /* For interleave calculation */ - GThread *thread; + GThread *thread; /* Streaming thread of SingleQueue */ + GstClockTime interleave; /* Calculated interleve within the thread */ }; @@ -203,7 +204,7 @@ static void recheck_buffering_status (GstMultiQueue * mq); static void gst_single_queue_flush_queue (GstSingleQueue * sq, gboolean full); -static void calculate_interleave (GstMultiQueue * mq); +static void calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq); static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink_%u", GST_PAD_SINK, @@ -806,7 +807,7 @@ gst_multi_queue_set_property (GObject * object, guint prop_id, GST_MULTI_QUEUE_MUTEX_LOCK (mq); mq->min_interleave_time = g_value_get_uint64 (value); if (mq->use_interleave) - calculate_interleave (mq); + calculate_interleave (mq, NULL); GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); break; default: @@ -1259,41 +1260,49 @@ recheck_buffering_status (GstMultiQueue * mq) } static void -calculate_interleave (GstMultiQueue * mq) +calculate_interleave (GstMultiQueue * mq, GstSingleQueue * sq) { GstClockTimeDiff low, high; - GstClockTime interleave; + GstClockTime interleave, other_interleave = 0; GList *tmp; low = high = GST_CLOCK_STIME_NONE; interleave = mq->interleave; /* Go over all single queues and calculate lowest/highest value */ for (tmp = mq->queues; tmp; tmp = tmp->next) { - GstSingleQueue *sq = (GstSingleQueue *) tmp->data; + GstSingleQueue *oq = (GstSingleQueue *) tmp->data; /* Ignore sparse streams for interleave calculation */ - if (sq->is_sparse) + if (oq->is_sparse) 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 (!sq->active) { + if (!oq->active) { GST_LOG_OBJECT (mq, - "queue %d is not active yet, forcing interleave to 5s", sq->id); + "queue %d is not active yet, forcing interleave to 5s", oq->id); mq->interleave = 5 * GST_SECOND; /* Update max-size time */ mq->max_size.time = mq->interleave; SET_CHILD_PROPERTY (mq, time); goto beach; } - if (GST_CLOCK_STIME_IS_VALID (sq->cached_sinktime)) { - if (low == GST_CLOCK_STIME_NONE || sq->cached_sinktime < low) - low = sq->cached_sinktime; - if (high == GST_CLOCK_STIME_NONE || sq->cached_sinktime > high) - high = sq->cached_sinktime; + + /* Calculate within each streaming thread */ + if (sq && sq->thread != oq->thread) { + if (oq->interleave > other_interleave) + other_interleave = oq->interleave; + continue; + } + + if (GST_CLOCK_STIME_IS_VALID (oq->cached_sinktime)) { + if (low == GST_CLOCK_STIME_NONE || oq->cached_sinktime < low) + low = oq->cached_sinktime; + if (high == GST_CLOCK_STIME_NONE || oq->cached_sinktime > high) + high = oq->cached_sinktime; } GST_LOG_OBJECT (mq, "queue %d , sinktime:%" GST_STIME_FORMAT " low:%" GST_STIME_FORMAT " high:%" GST_STIME_FORMAT, sq->id, - GST_STIME_ARGS (sq->cached_sinktime), GST_STIME_ARGS (low), + GST_STIME_ARGS (oq->cached_sinktime), GST_STIME_ARGS (low), GST_STIME_ARGS (high)); } @@ -1301,6 +1310,9 @@ calculate_interleave (GstMultiQueue * mq) interleave = high - low; /* Padding of interleave and minimum value */ interleave = (150 * interleave / 100) + mq->min_interleave_time; + sq->interleave = interleave; + + interleave = MAX (interleave, other_interleave); /* Update the stored interleave if: * * No data has arrived yet (high == low) @@ -1359,7 +1371,7 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq) sq->sink_tainted = FALSE; if (mq->use_interleave) { sq->cached_sinktime = sink_time; - calculate_interleave (mq); + calculate_interleave (mq, sq); } } } else @@ -2101,7 +2113,7 @@ gst_multi_queue_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer) "Queue %d cached sink time now %" G_GINT64_FORMAT " %" GST_STIME_FORMAT, sq->id, sq->cached_sinktime, GST_STIME_ARGS (sq->cached_sinktime)); - calculate_interleave (mq); + calculate_interleave (mq, sq); } GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); } @@ -2260,7 +2272,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) stime = my_segment_to_running_time (&sq->sink_segment, val); if (GST_CLOCK_STIME_IS_VALID (stime)) { sq->cached_sinktime = stime; - calculate_interleave (mq); + calculate_interleave (mq, sq); } GST_MULTI_QUEUE_MUTEX_UNLOCK (mq); } |