Commit graph

211 commits

Author SHA1 Message Date
Matej Knopp
efb1955ffb multiqueue: Ignore time when determining whether sparse stream limits have been reached
Basically, sq->max_size.visible is never increased for sparse streams in
overruncb when empty queue has been found;

If the queue is sparse it just skip the entire logic determining whether
max_size.visible should be increased, deadlocking the demuxer.

What should be done instead is that when determining if limits have been
reached, to ignore time for sparse streams, as the buffer may be far in the
future.

https://bugzilla.gnome.org/show_bug.cgi?id=765736
2016-04-29 16:09:23 +03:00
Carlos Rafael Giani
3bd5aeac52 multiqueue: Recheck buffering status after changing low threshold
https://bugzilla.gnome.org/show_bug.cgi?id=763757
2016-04-15 16:04:54 +03:00
Carlos Rafael Giani
a1d2f387c6 multiqueue: Recalculate fill level after changing high-threshold
This ensures the following special case is handled properly:

1. Queue is empty
2. Data is pushed, fill level is below the current high-threshold
3. high-threshold is set to a level that is below the current fill level

Since mq->percent wasn't being recalculated in step #3 properly, this
caused the multiqueue to switch off its buffering state when new data is
pushed in, and never post a 100% buffering message. The application will
have received a <100% buffering message from step #2, but will never see
100%.

Fix this by recalculating the current fill level percentage during
high-threshold property changes in the same manner as it is done when
use-buffering is modified.

https://bugzilla.gnome.org/show_bug.cgi?id=763757
2016-04-15 16:04:54 +03:00
Vincent Penquerc'h
53a7a991e2 multiqueue: catch errors and flushing case after lock
This ensures we can not get into an indefinite wait on the
following cond var wait.

https://bugzilla.gnome.org/show_bug.cgi?id=764999
2016-04-14 09:12:27 +01:00
Jan Schmidt
c9b6848885 multiqueue: Fix not-linked pad handling at EOS
Ensure that not-linked pads will drain out at EOS by
correctly detecting the EOS condition based on the EOS
pad flag (which indicates we actually pushed an EOS),
and make sure that not-linked pads are woken when doing
EOS processing on linked pads.

https://bugzilla.gnome.org/show_bug.cgi?id=763770
2016-03-18 21:21:44 +11:00
Tim-Philipp Müller
cf0680017e elements: use new gst_element_class_add_static_pad_template()
https://bugzilla.gnome.org/show_bug.cgi?id=762778
2016-02-28 13:10:07 +00:00
Tim-Philipp Müller
469475f06b multiqueue: two small fixes for when an existing pad is requested
Unlock when returning NULL from gst_single_queue_new(), and don't
crash with debug logging enabled if NULL is returned.

Spotted by Steven Hoving.
2016-01-20 10:06:14 +00:00
Sebastian Dröge
33ded76ab8 queue/multiqueue: Don't special-case CAPS events in the event handlers
For CAPS events we will never ever have a FALSE return value here, so just
remove the dead code instead of causing future confusion.
2015-12-14 11:20:43 +01:00
Edward Hervey
5f1764232f multiqueue: Don't use random segment.position from upstream
segment.position is meant for internal usage only, but the various
GST_EVENT_SEGMENT creationg/parsing functions won't clear that field.

Use the appropriate segment boundary as an initial value instead
2015-12-09 17:41:49 +01:00
Edward Hervey
906a50b995 multiqueue: Fix set/get property
Blame it on the rebasing :)
2015-12-02 16:28:58 +01:00
Edward Hervey
56d4650789 pad: Implement GstPadEventFullFunction
API: GstPadEventFullFunction

Returns a GstFlowReturn, allows asynchronous elements to properly
propagate flow returns

https://bugzilla.gnome.org/show_bug.cgi?id=757821
2015-12-02 16:04:03 +01:00
Edward Hervey
4d96e5b834 multiqueue: Use signed clock values for running time calculation
This improves the accuracy of queue levels and when to push buffers
for buffers falling outside of the segment

https://bugzilla.gnome.org/show_bug.cgi?id=757193
2015-12-02 16:03:20 +01:00
Edward Hervey
c51d2b2a37 multiqueue: Add an extra cache time for unlinked streams
When synchronizing the output by time, there are some use-cases (like
allowing gapless playback downstream) where we want the unlinked streams
to stay slightly behind the linked streams.

The "unlinked-cache-time" property allows the user to specify by how
much time the unlinked streams should wait before pushing again.
2015-12-02 16:03:20 +01:00
Edward Hervey
72c31876aa multiqueue: Optimize multiqueue sizes based on interleave
Multiqueue should only be used to cope with:
* decoupling upstream and dowstream threading (i.e. having separate threads
  for elementary streams).
* Ensuring individual queues have enough space to cope with upstream interleave
  (distance in stream time between co-located samples). This is to guarantee
  that we have enough room in each individual queues to provide new data in
  each, without being blocked.
* Limit the queue sizes to that interleave distance (and an extra minimal
  buffering size). This is to ensure we don't consume too much memory.

Based on that, multiqueue now continuously calculates the input interleave
(per incoming streaming thread). Based on that, it calculates a target
interleave (currently 1.5 x real_interleave + 250ms padding).

If the target interleave is greater than the current max_size.time, it will
update it accordingly (to allow enough margin to not block).
If the target interleave goes down by more than 50%, we re-adjust it once
we know we have gone past a safe distance (2 x current max_size.time).

This mode can only be used for incoming streams that are guaranteed to be
properly timestamped.

Furthermore, we ignore sparse streams when calculating interleave and maximum
size of queues.

For the simplest of use-cases (single stream), multiqueue acts as a single
queue with a time limit of 250ms.
If there are multiple inputs, but each come from a different streaming thread,
the maximum time limit will also end up being 250ms.

On regular files (more than one input stream from the same upstream streaming
thread), it can reduce the total memory used as much as 10x, ending up with
max_size.time around 500ms.

Due to the adaptive nature, it can also cope with changing interleave (which
can happen commonly on some files at startup/pre-roll time)
2015-12-02 16:03:20 +01:00
Vincent Penquerc'h
f6069c2c72 multiqueue: use new stream-start event sparse flag to avoid overreading subtitles
This will mean a much lower delay before a subtitles track changes take
effect. Also avoids excessive memory usage in many cases.

This will also consider sparse streams as (individually) never full, so
as to avoid blocking all playback due to one sparse stream.

https://bugzilla.gnome.org/show_bug.cgi?id=600648
2015-12-02 16:03:20 +01:00
Edward Hervey
785edec270 multiqueue: Fix high_time computation
* Avoid the computation completely if we know we don't need it (not in
  sync time mode)
* Make sure we don't override highest time with GST_CLOCK_TIME_NONE on
  unlinked pads
* Ensure the high_time gets properly updated if all pads are not linked
* Fix the comparision in the loop whether the target high time is the same
  as the current time
* Split wake_up_next_non_linked method to avoid useless calculation

https://bugzilla.gnome.org/show_bug.cgi?id=757353
2015-12-02 16:03:16 +01:00
Edward Hervey
692c0dc060 multiqueue: Use buffer DTS if present, else PTS
In order to accurately determine the amount (in time) of data
travelling in queues, we should use an increasing value.

If buffers are encoded and potentially reordered, we should be
using their DTS (increasing) and not PTS (reordered)

https://bugzilla.gnome.org/show_bug.cgi?id=756507
2015-10-27 08:38:42 +01:00
Edward Hervey
7c8f76a39f multiqueue: Improve incoming SEGMENT handling
Previously this code was just blindly setting the cached flow return
of downstream to GST_FLOW_OK when we get a SEGMENT.

The problem is that this can not be done blindly. If downstream was
not linked, the corresponding sinqlequeue source pad thread might be
waiting for the next ID to be woken up upon.

By blindly setting the cached return value to GST_FLOW_OK, and if that
stream was the only one that was NOT_LINKED, then the next time we
check (from any other thread) to see if we need to wake up a source pad
thread ... we won't even try, because none of the cached flow return
are equal to GST_FLOW_NOT_LINKED.

This would result in that thread never being woken up

https://bugzilla.gnome.org/show_bug.cgi?id=756645
2015-10-19 14:31:05 +02:00
Edward Hervey
14ad763698 multiqueue: Accept STREAM_START after EOS
In the same way core now allows STREAM_START to remove the flushing
state from pads, we need to do the same thing in multiqueue
2015-10-15 17:21:40 +02:00
Duncan Palmer
0ad06434da multiqueue: Don't automatically enter the buffering state when use-buffering is set.
There is no reason I can see to set mq->buffering = TRUE when
use_buffering is set; the code here also calls update_buffering(), which
will set mq->buffering = TRUE if this is warranted because of low buffer
levels.

https://bugzilla.gnome.org/show_bug.cgi?id=745937
2015-04-10 10:40:00 -03:00
Sebastian Dröge
5fc2a3fd66 multiqueue: Don't grow queue infinitely if only one pad is linked
This was introduced by
https://bugzilla.gnome.org/show_bug.cgi?id=719893
https://bugzilla.gnome.org/show_bug.cgi?id=722891
but it doesn't make any sense at all and causes huge memory leaks.

https://bugzilla.gnome.org/show_bug.cgi?id=744253
2015-03-15 14:19:17 +00:00
Mark Nauwelaerts
c3454a85c5 multiqueue: avoid returning downstream GST_FLOW_EOS from previous segment to current upstream segment 2015-02-23 20:08:20 +01:00
Thiago Santos
5a759011a0 multiqueue: percentage is an absolute value
multiqueue's queues stored percent value is the percentage from 0
to 100 (max-size-*) and should be compared with the requested limit
(high_percentage) set by the user and not with 100% to check if
buffering should stop. Otherwise we are only stopping buffering when the
queue gets completely full.
2014-11-23 05:51:12 -03:00
Andrei Sarakeev
ee93c807e1 multiqueue: Wake up any waiting streams if the current one goes EOS
Otherwise we might have unlinked streams waiting.

https://bugzilla.gnome.org/show_bug.cgi?id=738198
2014-10-20 12:31:42 +02:00
Aleix Conchillo Flaqué
41fa9ad9f2 multiqueue: don't lock multiqueue when pushing serialized queries
If we are pushing a serialized query into a queue and the queue is
filled, we will end in a deadlock. We need to release the lock before
pushing and acquire it again afterward.

https://bugzilla.gnome.org/show_bug.cgi?id=737794
2014-10-09 11:49:49 +03:00
Matej Knopp
b5bf41a771 multiqueue: update segment position on GAP events to calculate levels properly
https://bugzilla.gnome.org/show_bug.cgi?id=737498
2014-10-02 10:56:03 +03:00
Thiago Santos
3f83ca9c43 multiqueue: do not post messages holding the lock
It might cause deadlocks to post messages while holding the multiqueue
lock. To avoid this a new boolean flag is set whenever a new buffering percent
is found. The message is posted after the lock can be released.

To make sure the buffering messages are posted in the right order, messages
are posted holding another lock. This prevents 2 threads trying to post
messages at the same time.

https://bugzilla.gnome.org/show_bug.cgi?id=736295
2014-09-16 16:56:53 -03:00
Tim-Philipp Müller
49c6f923de coreelements: mark properties with MUTABLE_PLAYING 2014-09-14 16:08:07 +01:00
Thibault Saunier
78e2264544 multiqueue: Not post BUFFERING message if one of the singlequeue doesn't need it
Imagine the following 'pipeline'

                --------------
            p1/| 'fullqueue'  |--- 'laggy' downstream
  ---------  / |              |
-| demuxer |   | multiqueue   |
  ---------  \ |              |
            p2\| 'emptyqueue' |--- 'fast' downstream
                --------------

In the case downstream of one single queue (fullqueue) has (a lot of) latency
(for example for reverse playback with video), we can end up having the other
SingleQueue (emptyqueue) emptied, before that fullqueue gets
unblocked. In the meantime, the demuxer tries to push on fullqueue, and
is blocking there.

In that case the current code will post a BUFFERING message on the bus when
emptyqueue gets emptied, that leads to the application setting the pipeline state to
PAUSED. So now we end up in a situation where 'laggy downstream' is
prerolled and will not unblock anymore because the pipeline is set to
PAUSED, the fullequeue does not have a chance to be emptied and
the emptyqueue can not get filled anymore so no more BUFERRING message
will be posted and the pipeline is stucked in PAUSED for the eternity.

Making sure that we do not try to "buffer" if one of the single queue
does not need buffering, prevents this situtation from happening though it lets the
oportunity for buffering in all other cases.

That implements a new logic where we need all singlequeue to need
buffering for the multiqueue to actually state buffering is needed,
taking the maximum buffering of the single queue as the reference point.

https://bugzilla.gnome.org/show_bug.cgi?id=734412
2014-08-13 18:25:12 +03:00
Sebastian Dröge
3032a369a7 multiqueue: Only handle flow returns < EOS as errors, not e.g. flushing 2014-08-13 13:01:23 +03:00
Sebastian Dröge
afcc93254b multiqueue: Post errors ourselves if they are received after EOS
After EOS there will be no further buffer which could propagate the
error upstream, so nothing is going to post an error message and
the pipeline just idles around.
2014-08-13 12:10:39 +03:00
Thiago Santos
463ccd96eb multiqueue: avoid using infinite buffers limit if finite is requested
If the current max-buffers limit it infinite and a finite value is
requested, switch to the MAX (requested, current-value) to set some
limit but not below what we know that we've needed so far.

https://bugzilla.gnome.org/show_bug.cgi?id=733637

https://bugzilla.gnome.org/show_bug.cgi?id=733837
2014-07-29 15:26:51 -03:00
Thiago Santos
01c9ae2630 multiqueue: post buffering message when queues flush
The buffering status goes back to 0, so inform the application about it

https://bugzilla.gnome.org/show_bug.cgi?id=726423
2014-05-29 16:51:41 -03:00
Wim Taymans
35a1822d7a pads: update docs for request pads
We would like to encourage the use of gst_element_request_pad()
2014-05-08 09:13:04 +02:00
Thiago Santos
0a3bc6be1f multiqueue: avoid signaling overrun on the first segment
When the first segment has position != 0 and position > max-size-time
it will immediatelly cause the multiqueue to signal overrun.

This can happen easily with adaptive streams when switching bitrates
and starting a new group. The segment for this new group will have
a position that is much greater than 0 and will lead to this issue.
This is particularly harmful when the adaptive stream uses mpegts
that doesn't emit no-more-pads and it might happen that only one
of the stream pads was added when the multiqueue overruns and gets
the group ready for exposing. So the user will only get audio or
video.

The solution is to fallback to the sink segment while the source pad
has no segment.

https://bugzilla.gnome.org/show_bug.cgi?id=729124
2014-04-28 17:08:57 -03:00
Tim-Philipp Müller
6eb6d9ec38 docs: remove outdated and pointless 'Last reviewed' lines from docs
They are very confusing for people, and more often than not
also just not very accurate. Seeing 'last reviewed: 2005' in
your docs is not very confidence-inspiring. Let's just remove
those comments.
2014-04-26 21:21:51 +01:00
Sebastian Dröge
eba6f7d972 multiqueue: Wake up the queues if limits are changing in a way that would unblock the queue 2014-04-09 15:57:35 +02:00
Sebastian Dröge
f53f4ddca4 multiqueue: Update buffering status and maybe post buffering message right when enabling buffering 2014-03-19 09:48:45 +01:00
Tim-Philipp Müller
a6cd61b86a docs: fix multiqueue docs for new template names foo_%d -> foo_%u
https://bugzilla.gnome.org/show_bug.cgi?id=726358
2014-03-14 18:40:31 +00:00
Thiago Santos
0e2f63654b multiqueue: if buffering is disabled while buffering, post 100% message
Avoids stall waiting for buffering to reach 100%
2014-03-10 09:49:05 -03:00
Thiago Santos
b6470a7b3f multiqueue: do not reset last push result when pushing events
Use the last result as a default when pushing a item from a single queue,
otherwise the status gets reset to _OK when pushing events.

This causes problems when mistakenly activating a not-linked stream
that is being ignored upstream as it is not being used (adaptive
scenarios), it will make the multiqueue post a buffering message
on a pad that won't receive buffers

https://bugzilla.gnome.org/show_bug.cgi?id=725917
2014-03-10 09:48:58 -03:00
Sebastian Dröge
5737f4f367 multiqueue: If we only have a single pad, don't consider all pads not linked and grow the queue indefinitely 2014-02-20 15:35:11 +01:00
Arnaud Vrac
a93615aea1 multiqueue: do not reduce single queue below current level
When the single queue size was just bumped by 1 to allow more buffers to
be added, the buffers limit could be reduced to the current level when
setting the max-size-buffers property. This would result in a stall
since the queue would not grow anymore at this point.

Prevent this by not reducing a single queue size below the current
number of buffers + 1.

https://bugzilla.gnome.org/show_bug.cgi?id=712597
2014-01-27 19:57:35 +01:00
Sebastian Dröge
454ee04a22 multiqueue: Break the loop immediately if we found an empty queue
No need to continue looking at all the others
2014-01-24 09:28:05 +01:00
Per x Johansson
4f928547a8 multiqueue: Allow growing a queue if all other queues are not linked
In the case where one singlequeue is full and all other are not linked, the
growing of the full queue does not work correctly. The result depends on if
the full queue is last in the queue list or not.

https://bugzilla.gnome.org/show_bug.cgi?id=722891
2014-01-24 09:27:28 +01:00
Thiago Santos
139c96c129 multiqueue: prevent buffering forever with playbin
When prerolling/buffering, multiqueue has its buffers limit set
to 0, this means it can take an infinite amount of buffers.

When prerolling/buffering finishes, its limit is set back to 5, but
only if the current level is lower than 5. It should (almost) never be
and this will cause prerolling/buffering to need to wait to reach the
hard bytes and time limits, which are much higher.

This can lead to a very long startup time. This patch fixes this
by setting the single queues to the max(current, new_value) instead
of simply ignoring the new value and letting it as infinite(0)

https://bugzilla.gnome.org/show_bug.cgi?id=712597
2014-01-15 09:51:35 -03:00
Sebastian Dröge
c343ebd454 multiqueue: Allow growing a queue if all other queues are not linked
See https://bugzilla.gnome.org/show_bug.cgi?id=719893
2014-01-08 09:54:01 +01:00
YanpingZhang
1de533735b multiqueue: Fix hanging if shut down while handling a serialized query
https://bugzilla.gnome.org/show_bug.cgi?id=721253
2014-01-03 11:15:33 +01:00
Thiago Santos
1f71f191be multiqueue: post 100% buffering if single queue is not linked
This makes buffering stop in case a stream switch happens. This is
important for adaptive streams that can disable not-linked streams
to avoid consuming the network bandwidth.

https://bugzilla.gnome.org/show_bug.cgi?id=719575
2013-12-20 01:10:47 -03:00
Sebastian Rasmussen
53ae1b2c9c docs: Fix typos in function/object descriptions
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=720029
2013-12-07 17:11:12 +00:00