multiqueue: Optimize multiqueue sizes based on interleave
authorEdward Hervey <edward@centricular.com>
Mon, 26 Oct 2015 07:06:01 +0000 (08:06 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 2 Dec 2015 15:03:20 +0000 (16:03 +0100)
commit72c31876aa979992beadf783ed59e26d8af33428
treeceb7ec794cf8cc13d22c4fc78da73d03fe65e4d2
parentf6069c2c728e74db370bbf5de0e2e4bf60c30c04
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)
plugins/elements/gstmultiqueue.c
plugins/elements/gstmultiqueue.h