Skip to content
Permalink
Browse files

cache: redo options and default settings

Some options change from percentages to number of kilobytes; there are
no cache options using percentages anymore.

Raise the default values. The cache is now 25000 kilobytes, although if
your connection is slow enough, the maximum is probably never reached.
(Although all the memory will still be used as seekback-cache.)

Remove the separate --audio-file-cache option, and use the cache default
settings for it.
  • Loading branch information...
wm4
wm4 committed May 19, 2014
1 parent ac66bcc commit 4664f8b3b7cd5089463623df02655ec11e258671
Showing with 95 additions and 101 deletions.
  1. +1 βˆ’1 DOCS/man/en/changes.rst
  2. +16 βˆ’15 DOCS/man/en/options.rst
  3. +0 βˆ’1 options/m_config.c
  4. +17 βˆ’15 options/options.c
  5. +9 βˆ’5 options/options.h
  6. +7 βˆ’14 player/loadfile.c
  7. +8 βˆ’4 player/playloop.c
  8. +2 βˆ’6 player/timeline/tl_matroska.c
  9. +1 βˆ’5 player/timeline/tl_mpv_edl.c
  10. +7 βˆ’5 stream/cache.c
  11. +22 βˆ’24 stream/stream.c
  12. +5 βˆ’6 stream/stream.h
@@ -146,7 +146,7 @@ Command Line Switches
``-aspect`` ``--video-aspect``
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
``-ass`` ``--sub-ass``
``-audiofile-cache`` ``--audio-file-cache``
``-audiofile-cache`` (removed; the main cache settings are used)
``-audiofile`` ``--audio-file``
``-benchmark`` ``--untimed`` (no stats)
``-capture`` ``--stream-capture=<filename>``
@@ -275,10 +275,6 @@ OPTIONS
Play audio from an external file (WAV, MP3 or Ogg Vorbis) while viewing a
movie.

``--audio-file-cache=<kBytes>``
Enables caching for the stream used by ``--audio-file``, using the
specified amount of memory.

``--audio-format=<format>``
Select the sample format used for output from the audio filter layer to
the sound card. The values that ``<format>`` can adopt are listed below in
@@ -395,28 +391,33 @@ OPTIONS
because no space is reserved for seeking back yet.

``--cache-default=<kBytes|no>``
Set the size of the cache in kilobytes (default: 320 KB). Using ``no``
Set the size of the cache in kilobytes (default: 25000 KB). Using ``no``
will not automatically enable the cache e.g. when playing from a network
stream. Note that using ``--cache`` will always override this option.

``--cache-pause=<no|percentage>``
If the cache percentage goes below the specified value, pause and wait
until the percentage set by ``--cache-min`` is reached, then resume
playback (default: 10). If ``no`` is specified, this behavior is disabled.
``--cache-pause-below=<kBytes|no>``
If the cache size goes below the specified value (in KB), pause and wait
until the size set by ``--cache-pause-restart`` is reached, then resume
playback (default: 500). If ``no`` is specified, this behavior is disabled.

When the player is paused this way, the status line shows ``Buffering``
instead of ``Paused``, and the OSD uses a clock symbol instead of the
normal paused symbol.

``--cache-min=<percentage>``
Playback will start when the cache has been filled up to ``<percentage>`` of
the total (default: 20).
``--cache-pause-restart=<kBytes>``
If the cache is paused due to the ``--cache-pause-below`` functionality,
then the player unpauses as soon as the cache has this much data (in KB).
(Default: 1000)

``--cache-initial=<kBytes>``
Playback will start when the cache has been filled up with this many
kilobytes of data (default: 0).

``--cache-seek-min=<percentage>``
If a seek is to be made to a position within ``<percentage>`` of the cache
``--cache-seek-min=<kBytes>``
If a seek is to be made to a position within ``<kBytes>`` of the cache
size from the current position, mpv will wait for the cache to be
filled to this position rather than performing a stream seek (default:
50).
500).

This matters for small forward seeks. With slow streams (especially http
streams) there is a tradeoff between skipping the data between current
@@ -881,7 +881,6 @@ static const char *replaced_opts =
"|aspect#--video-aspect"
"|ass-bottom-margin#--vf=sub=bottom:top"
"|ass#--sub-ass"
"|audiofile-cache#--audio-file-cache"
"|audiofile#--audio-file"
"|benchmark#--untimed (no stats)"
"|capture#--stream-capture=<filename>"
@@ -238,18 +238,16 @@ const m_option_t mp_opts[] = {

// ------------------------- stream options --------------------

OPT_CHOICE_OR_INT("cache", stream_cache_size, 0, 32, 0x7fffffff,
OPT_CHOICE_OR_INT("cache", stream_cache.size, 0, 32, 0x7fffffff,
({"no", 0},
{"auto", -1}),
OPTDEF_INT(-1)),
OPT_CHOICE_OR_INT("cache-default", stream_cache_def_size, 0, 32, 0x7fffffff,
({"no", 0}),
OPTDEF_INT(320)),
OPT_FLOATRANGE("cache-min", stream_cache_min_percent, 0, 0, 99),
OPT_FLOATRANGE("cache-seek-min", stream_cache_seek_min_percent, 0,
0, 99),
OPT_CHOICE_OR_INT("cache-pause", stream_cache_pause, 0,
0, 40, ({"no", -1})),
{"auto", -1})),
OPT_CHOICE_OR_INT("cache-default", stream_cache.def_size, 0, 32, 0x7fffffff,
({"no", 0})),
OPT_INTRANGE("cache-initial", stream_cache.initial, 0, 0, 0x7fffffff),
OPT_INTRANGE("cache-seek-min", stream_cache.seek_min, 0, 0, 0x7fffffff),
OPT_CHOICE_OR_INT("cache-pause-below", stream_cache_pause, 0, 0, 0x7fffffff,
({"no", 0})),
OPT_INTRANGE("cache-pause-restart", stream_cache_unpause, 0, 0, 0x7fffffff),

{"cdrom-device", &cdrom_device, CONF_TYPE_STRING, 0, 0, 0, NULL},
#if HAVE_DVDREAD || HAVE_DVDNAV
@@ -319,7 +317,6 @@ const m_option_t mp_opts[] = {

// demuxer.c - select audio/sub file/demuxer
OPT_STRING("audio-file", audio_stream, 0),
OPT_INTRANGE("audio-file-cache", audio_stream_cache, 0, 50, 65536),
OPT_STRING("demuxer", demuxer_name, 0),
OPT_STRING("audio-demuxer", audio_demuxer_name, 0),
OPT_STRING("sub-demuxer", sub_demuxer_name, 0),
@@ -692,9 +689,14 @@ const struct MPOpts mp_default_opts = {
.hr_seek_framedrop = 1,
.load_config = 1,
.position_resume = 1,
.stream_cache_min_percent = 20.0,
.stream_cache_seek_min_percent = 50.0,
.stream_cache_pause = 10.0,
.stream_cache = {
.size = -1,
.def_size = 25000,
.initial = 0,
.seek_min = 500,
},
.stream_cache_pause = 500,
.stream_cache_unpause = 1000,
.network_rtsp_transport = 2,
.chapterrange = {-1, -1},
.edition_id = -1,
@@ -40,6 +40,13 @@ typedef struct mp_vo_opts {
int fs_missioncontrol;
} mp_vo_opts;

struct mp_cache_opts {
int size;
int def_size;
int initial;
int seek_min;
};

typedef struct MPOpts {
int use_terminal;
char *msglevels;
@@ -108,12 +115,10 @@ typedef struct MPOpts {
int load_config;
char *force_configdir;
int use_filedir_conf;
int stream_cache_size;
int stream_cache_def_size;
float stream_cache_min_percent;
float stream_cache_seek_min_percent;
int network_rtsp_transport;
struct mp_cache_opts stream_cache;
int stream_cache_pause;
int stream_cache_unpause;
int chapterrange[2];
int edition_id;
int correct_pts;
@@ -170,7 +175,6 @@ typedef struct MPOpts {
char *sub_cp;

char *audio_stream;
int audio_stream_cache;
char *demuxer_name;
char *audio_demuxer_name;
char *sub_demuxer_name;
@@ -743,7 +743,7 @@ static void open_subtitles_from_options(struct MPContext *mpctx)
}

static struct track *open_external_file(struct MPContext *mpctx, char *filename,
char *demuxer_name, int stream_cache,
char *demuxer_name,
enum stream_type filter)
{
struct MPOpts *opts = mpctx->opts;
@@ -755,10 +755,8 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
struct stream *stream = stream_open(filename, mpctx->global);
if (!stream)
goto err_out;
stream_enable_cache_percent(&stream, stream_cache,
opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
if (filter != STREAM_SUB)
stream_enable_cache(&stream, &opts->stream_cache);
struct demuxer_params params = {
.expect_subtitle = filter == STREAM_SUB,
};
@@ -799,13 +797,13 @@ static void open_audiofiles_from_options(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
open_external_file(mpctx, opts->audio_stream, opts->audio_demuxer_name,
opts->audio_stream_cache, STREAM_AUDIO);
STREAM_AUDIO);
}

struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename)
{
struct MPOpts *opts = mpctx->opts;
return open_external_file(mpctx, filename, opts->sub_demuxer_name, 0,
return open_external_file(mpctx, filename, opts->sub_demuxer_name,
STREAM_SUB);
}

@@ -821,7 +819,7 @@ static void open_subtitles_from_resolve(struct MPContext *mpctx)
if (!s)
s = talloc_asprintf(NULL, "memory://%s", sub->data);
struct track *t =
open_external_file(mpctx, s, opts->sub_demuxer_name, 0, STREAM_SUB);
open_external_file(mpctx, s, opts->sub_demuxer_name, STREAM_SUB);
talloc_free(s);
if (t) {
t->lang = talloc_strdup(t, sub->lang);
@@ -1125,12 +1123,7 @@ static void play_current_file(struct MPContext *mpctx)
// Must be called before enabling cache.
mp_nav_init(mpctx);

// CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts)
int res = stream_enable_cache_percent(&mpctx->stream,
opts->stream_cache_size,
opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
int res = stream_enable_cache(&mpctx->stream, &opts->stream_cache);
if (res == 0)
if (demux_was_interrupted(mpctx))
goto terminate_playback;
@@ -650,17 +650,21 @@ static void handle_metadata_update(struct MPContext *mpctx)
static void handle_pause_on_low_cache(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
int cache = mp_get_cache_percent(mpctx);
if (!mpctx->stream)
return;
int64_t fill = -1;
stream_control(mpctx->stream, STREAM_CTRL_GET_CACHE_FILL, &fill);
int cache_kb = fill > 0 ? (fill + 1023) / 1024 : -1;
bool idle = mp_get_cache_idle(mpctx);
if (mpctx->paused && mpctx->paused_for_cache) {
if (cache < 0 || cache >= opts->stream_cache_min_percent || idle) {
if (cache_kb < 0 || cache_kb >= opts->stream_cache_unpause || idle) {
mpctx->paused_for_cache = false;
if (!opts->pause)
unpause_player(mpctx);
}
} else {
if (cache >= 0 && cache <= opts->stream_cache_pause && !idle &&
opts->stream_cache_pause < opts->stream_cache_min_percent)
if (cache_kb >= 0 && cache_kb <= opts->stream_cache_pause && !idle &&
opts->stream_cache_pause < opts->stream_cache_unpause)
{
bool prev_paused_user = opts->pause;
pause_player(mpctx);
@@ -119,7 +119,7 @@ static int enable_cache(struct MPContext *mpctx, struct stream **stream,
{
struct MPOpts *opts = mpctx->opts;

if (opts->stream_cache_size <= 0)
if (!stream_wants_cache(*stream, &opts->stream_cache))
return 0;

char *filename = talloc_strdup(NULL, (*demuxer)->filename);
@@ -132,11 +132,7 @@ static int enable_cache(struct MPContext *mpctx, struct stream **stream,
return -1;
}

stream_enable_cache_percent(stream,
opts->stream_cache_size,
opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
stream_enable_cache(stream, &opts->stream_cache);

*demuxer = demux_open(*stream, "mkv", params, mpctx->global);
if (!*demuxer) {
@@ -129,11 +129,7 @@ static struct demuxer *open_file(char *filename, struct MPContext *mpctx)
struct demuxer *d = NULL;
struct stream *s = stream_open(filename, mpctx->global);
if (s) {
stream_enable_cache_percent(&s,
opts->stream_cache_size,
opts->stream_cache_def_size,
opts->stream_cache_min_percent,
opts->stream_cache_seek_min_percent);
stream_enable_cache(&s, &opts->stream_cache);
d = demux_open(s, NULL, NULL, mpctx->global);
}
if (!d) {
@@ -56,6 +56,7 @@
#include "osdep/threads.h"

#include "common/msg.h"
#include "options/options.h"

#include "stream.h"
#include "common/common.h"
@@ -655,18 +656,18 @@ static void cache_uninit(stream_t *cache)

// return 1 on success, 0 if the function was interrupted and -1 on error, or
// if the cache is disabled
int stream_cache_init(stream_t *cache, stream_t *stream, int64_t size,
int64_t min, int64_t seek_limit)
int stream_cache_init(stream_t *cache, stream_t *stream,
struct mp_cache_opts *opts)
{
if (size < 1)
if (opts->size < 1)
return -1;

struct priv *s = talloc_zero(NULL, struct priv);
s->log = cache->log;

s->seek_limit = seek_limit;
s->seek_limit = opts->seek_min * 1024ULL;

if (resize_cache(s, size) != STREAM_OK) {
if (resize_cache(s, opts->size * 1024ULL) != STREAM_OK) {
MP_ERR(s, "Failed to allocate cache buffer.\n");
talloc_free(s);
return -1;
@@ -687,6 +688,7 @@ int stream_cache_init(stream_t *cache, stream_t *stream, int64_t size,
cache->control = cache_control;
cache->close = cache_uninit;

int64_t min = opts->initial * 1024ULL;
if (min > s->buffer_size - FILL_LIMIT)
min = s->buffer_size - FILL_LIMIT;

@@ -41,6 +41,7 @@
#include "common/global.h"
#include "bstr/bstr.h"
#include "common/msg.h"
#include "options/options.h"
#include "options/path.h"
#include "osdep/timer.h"
#include "stream.h"
@@ -772,36 +773,33 @@ stream_t *open_memory_stream(void *data, int len)
return s;
}

static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
int64_t seek_limit);

/**
* \return 1 on success, 0 if the function was interrupted and -1 on error, or
* if the cache is disabled
*/
int stream_enable_cache_percent(stream_t **stream, int64_t stream_cache_size,
int64_t stream_cache_def_size,
float stream_cache_min_percent,
float stream_cache_seek_min_percent)
static struct mp_cache_opts check_cache_opts(stream_t *stream,
struct mp_cache_opts *opts)
{
if (stream_cache_size == -1)
stream_cache_size = (*stream)->streaming ? stream_cache_def_size : 0;
struct mp_cache_opts use_opts = *opts;
if (use_opts.size == -1)
use_opts.size = stream->streaming ? use_opts.def_size : 0;

stream_cache_size = stream_cache_size * 1024; // input is in KiB
return stream_enable_cache(stream, stream_cache_size,
stream_cache_size *
(stream_cache_min_percent / 100.0),
stream_cache_size *
(stream_cache_seek_min_percent / 100.0));
if (stream->mode != STREAM_READ || !stream->allow_caching || use_opts.size < 1)
use_opts.size = 0;
return use_opts;
}

static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
int64_t seek_limit)
bool stream_wants_cache(stream_t *stream, struct mp_cache_opts *opts)
{
struct mp_cache_opts use_opts = check_cache_opts(stream, opts);
return use_opts.size > 0;
}

// return: 1 on success, 0 if the function was interrupted and -1 on error, or
// if the cache is disabled
int stream_enable_cache(stream_t **stream, struct mp_cache_opts *opts)
{
stream_t *orig = *stream;
struct mp_cache_opts use_opts = check_cache_opts(*stream, opts);

if (orig->mode != STREAM_READ || !orig->allow_caching)
return 1;
if (use_opts.size < 1)
return -1;

stream_t *cache = new_stream();
cache->uncached_type = orig->type;
@@ -822,7 +820,7 @@ static int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,

cache->log = mp_log_new(cache, cache->global->log, "cache");

int res = stream_cache_init(cache, orig, size, min, seek_limit);
int res = stream_cache_init(cache, orig, &use_opts);
if (res <= 0) {
cache->uncached_stream = NULL; // don't free original stream
free_stream(cache);

0 comments on commit 4664f8b

Please sign in to comment.
You can’t perform that action at this time.