demux: add options to control maximum queue size

Add --demuxer-max-packets and --demuxer-max-bytes, which control the
maximum size of the packet queue. These can be helpful to avoid
excessive memory usage.

Memory usage is the reason why there's a limit in the first place. If a
file is more or less broken, and audio and video don't line up, the
decoders will fill up the packet queue trying to read more audio or
video, and the maximum sizes are required to avoid unbounded memory
allocation. Being able to override the maximum sizes is useful; either
for restricting memory usage further, or enlarging the sizes when
attempting to play various broken files.
This commit is contained in:
wm4 2015-08-05 23:41:29 +02:00
parent 775d816096
commit beb4f8316a
6 changed files with 27 additions and 6 deletions

View File

@ -21,6 +21,8 @@ Interface changes
--- mpv 0.10.0 will be released ---
- remove --demuxer-readahead-packets and --demuxer-readahead-bytes
add --demuxer-max-packets and --demuxer-max-bytes
(the new options are not replacement and have very different semantics)
- change "video-aspect" property: always settable, even if no video is
running; always return the override - if no override is set, return
the video's aspect ratio

View File

@ -2229,6 +2229,20 @@ Demuxer
``--demuxer-rawvideo-size=<value>``
Frame size in bytes when using ``--demuxer=rawvideo``.
``--demuxer-max-packets=<packets>``, ``--demuxer-max-bytes=<bytes>``
This controls how much the demuxer is allowed to buffer ahead. The demuxer
will normally try to read ahead as much as necessary, or as much is
requested with ``--demuxer-readahead-secs``. The ``--demuxer-max-...``
options can be used to restrict the maximum readahead. This limits excessive
readahead in case of broken files or desynced playback. The demuxer will
stop reading additional packets as soon as one of the limits is reached.
(The limits still can be slightly overstepped due to technical reasons.)
Set these limits highher if you get a packet queue overflow warning, and
you think normal playback would be possible with a larger packet queue.
See ``--list-options`` for defaults and value range.
``--demuxer-thread=<yes|no>``
Run the demuxer in a separate thread, and let it prefetch a certain amount
of packets (default: yes). Having this enabled may lead to smoother

View File

@ -112,6 +112,8 @@ struct demux_internal {
bool idle;
bool autoselect;
double min_secs;
int max_packs;
int max_bytes;
bool tracks_switched; // thread needs to inform demuxer of this
@ -391,7 +393,7 @@ static bool read_packet(struct demux_internal *in)
}
MP_DBG(in, "packets=%zd, bytes=%zd, active=%d, more=%d\n",
packs, bytes, active, read_more);
if (packs >= MAX_PACKS || bytes >= MAX_PACK_BYTES) {
if (packs >= in->max_packs || bytes >= in->max_bytes) {
if (!in->warned_queue_overflow) {
in->warned_queue_overflow = true;
MP_ERR(in, "Too many packets in the demuxer packet queues:\n");
@ -957,6 +959,8 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.d_buffer = talloc(demuxer, struct demuxer),
.d_user = demuxer,
.min_secs = demuxer->opts->demuxer_min_secs,
.max_packs = demuxer->opts->demuxer_max_packs,
.max_bytes = demuxer->opts->demuxer_max_bytes,
};
pthread_mutex_init(&in->lock, NULL);
pthread_cond_init(&in->wakeup, NULL);

View File

@ -30,11 +30,6 @@
#include "packet.h"
#include "stheader.h"
// Maximum total size of packets queued - if larger, no new packets are read,
// and the demuxer pretends EOF was reached.
#define MAX_PACKS 16000
#define MAX_PACK_BYTES (400 * 1024 * 1024)
// DEMUXER control commands/answers
#define DEMUXER_CTRL_NOTIMPL -1
#define DEMUXER_CTRL_DONTKNOW 0

View File

@ -242,6 +242,8 @@ const m_option_t mp_opts[] = {
OPT_STRING("sub-demuxer", sub_demuxer_name, 0),
OPT_FLAG("demuxer-thread", demuxer_thread, 0),
OPT_DOUBLE("demuxer-readahead-secs", demuxer_min_secs, M_OPT_MIN, .min = 0),
OPT_INTRANGE("demuxer-max-packets", demuxer_max_packs, 0, 0, INT_MAX),
OPT_INTRANGE("demuxer-max-bytes", demuxer_max_bytes, 0, 0, INT_MAX),
OPT_FLAG("force-seekable", force_seekable, 0),
@ -718,6 +720,8 @@ const struct MPOpts mp_default_opts = {
.back_buffer = 75000,
.file_max = 1024 * 1024,
},
.demuxer_max_packs = 16000,
.demuxer_max_bytes = 400 * 1024 * 1024,
.demuxer_thread = 1,
.demuxer_min_secs = 1.0,
.network_rtsp_transport = 2,

View File

@ -195,6 +195,8 @@ typedef struct MPOpts {
char **audio_files;
char *demuxer_name;
int demuxer_max_packs;
int demuxer_max_bytes;
int demuxer_thread;
double demuxer_min_secs;
char *audio_demuxer_name;