mirror of https://github.com/mpv-player/mpv
core, timeline: cache external ordered chapter files too
Previously, Matroska source files other than the initially opened one were always accessed without caching. Enable cache for extra files too. A separate cache process/thread is started for each file, which is less than optimal but probably better than no caching if the user explicitly enabled cache. This commit only implements caching for Matroska ordered chapters (not for EDL timeline). To build the timeline we need to demux the files in the current directory to look for segments with matching uuid. This first demux is done with no cache since we don't need to read a lot of the stream. If the file is recognized as one of the needed sources it's reopened with cache enabled. Also move the stream_cache_size global variable to the options struct. Conflicts: cfg-mplayer.h mplayer.c stream/stream.h timeline/tl_matroska.c
This commit is contained in:
parent
1959ba006c
commit
70e7d63ba0
|
@ -336,8 +336,9 @@ const m_option_t common_opts[] = {
|
|||
// ------------------------- stream options --------------------
|
||||
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
{"cache", &stream_cache_size, CONF_TYPE_INT, CONF_RANGE, 32, 0x7fffffff, NULL},
|
||||
{"no-cache", &stream_cache_size, CONF_TYPE_FLAG, 0, 1, 0, NULL},
|
||||
OPT_INTRANGE("cache", stream_cache_size, 0, 32, 0x7fffffff, OPTDEF_INT(-1)),
|
||||
OPT_FLAG_CONSTANTS("nocache", stream_cache_size, 0, -1, 0),
|
||||
|
||||
OPT_FLOATRANGE("cache-min", stream_cache_min_percent, 0, 0, 99),
|
||||
OPT_FLOATRANGE("cache-seek-min", stream_cache_seek_min_percent, 0, 0, 99),
|
||||
#endif /* CONFIG_STREAM_CACHE */
|
||||
|
|
19
mplayer.c
19
mplayer.c
|
@ -221,9 +221,6 @@ int vobsub_id = -1;
|
|||
static char *spudec_ifo = NULL;
|
||||
int forced_subs_only = 0;
|
||||
|
||||
// cache2:
|
||||
int stream_cache_size = -1;
|
||||
|
||||
// A-V sync:
|
||||
static float default_max_pts_correction = -1;
|
||||
float audio_delay = 0;
|
||||
|
@ -1252,7 +1249,7 @@ static void print_status(struct MPContext *mpctx, double a_pos, bool at_frame)
|
|||
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
// cache stats
|
||||
if (stream_cache_size > 0)
|
||||
if (opts->stream_cache_size > 0)
|
||||
saddf(line, width, " C: %d%%", cache_fill_status(mpctx->stream));
|
||||
#endif
|
||||
|
||||
|
@ -3286,7 +3283,7 @@ static void run_playloop(struct MPContext *mpctx)
|
|||
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
// The cache status is part of the status line. Possibly update it.
|
||||
if (mpctx->paused && stream_cache_size > 0)
|
||||
if (mpctx->paused && opts->stream_cache_size > 0)
|
||||
print_status(mpctx, MP_NOPTS_VALUE, false);
|
||||
#endif
|
||||
|
||||
|
@ -3804,13 +3801,11 @@ static void play_current_file(struct MPContext *mpctx)
|
|||
|
||||
// CACHE2: initial prefill: 20% later: 5% (should be set by -cacheopts)
|
||||
goto_enable_cache:
|
||||
if (stream_cache_size > 0) {
|
||||
int res;
|
||||
float stream_cache_min_percent = opts->stream_cache_min_percent;
|
||||
float stream_cache_seek_min_percent = opts->stream_cache_seek_min_percent;
|
||||
res = stream_enable_cache(mpctx->stream, stream_cache_size * 1024ull,
|
||||
stream_cache_size * 1024ull * (stream_cache_min_percent / 100.0),
|
||||
stream_cache_size * 1024ull * (stream_cache_seek_min_percent / 100.0));
|
||||
if (opts->stream_cache_size > 0) {
|
||||
int res = stream_enable_cache_percent(mpctx->stream,
|
||||
opts->stream_cache_size,
|
||||
opts->stream_cache_min_percent,
|
||||
opts->stream_cache_seek_min_percent);
|
||||
if (res == 0)
|
||||
if (libmpdemux_was_interrupted(mpctx))
|
||||
goto terminate_playback;
|
||||
|
|
|
@ -31,8 +31,6 @@ extern float audio_delay;
|
|||
|
||||
extern double force_fps;
|
||||
|
||||
extern int stream_cache_size;
|
||||
|
||||
extern int frame_dropping;
|
||||
|
||||
extern int auto_quality;
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct MPOpts {
|
|||
int chapter_merge_threshold;
|
||||
int quiet;
|
||||
int noconfig;
|
||||
int stream_cache_size;
|
||||
float stream_cache_min_percent;
|
||||
float stream_cache_seek_min_percent;
|
||||
int chapterrange[2];
|
||||
|
|
|
@ -434,6 +434,14 @@ static void cache_mainloop(cache_vars_t *s) {
|
|||
} while (cache_execute_control(s));
|
||||
}
|
||||
|
||||
int stream_enable_cache_percent(stream_t *stream, int64_t stream_cache_size,
|
||||
float stream_cache_min_percent, float stream_cache_seek_min_percent)
|
||||
{
|
||||
return stream_enable_cache(stream, stream_cache_size * 1024,
|
||||
stream_cache_size * 1024 * (stream_cache_min_percent / 100.0),
|
||||
stream_cache_size * 1024 * (stream_cache_seek_min_percent / 100.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \return 1 on success, 0 if the function was interrupted and -1 on error
|
||||
*/
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
|
||||
#include <libavutil/avutil.h>
|
||||
|
||||
extern int stream_cache_size;
|
||||
extern int network_bandwidth;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "options.h"
|
||||
|
||||
#include "mp_msg.h"
|
||||
|
||||
|
@ -47,8 +48,6 @@
|
|||
#include "cookies.h"
|
||||
#include "url.h"
|
||||
|
||||
extern int stream_cache_size;
|
||||
|
||||
/* Variables for the command line option -user, -passwd, -bandwidth,
|
||||
-user-agent and -nocookies */
|
||||
|
||||
|
@ -461,13 +460,14 @@ nop_streaming_seek( int fd, off_t pos, streaming_ctrl_t *stream_ctrl ) {
|
|||
|
||||
|
||||
void fixup_network_stream_cache(stream_t *stream) {
|
||||
struct MPOpts *opts = stream->opts;
|
||||
if(stream->streaming_ctrl->buffering) {
|
||||
if(stream_cache_size<0) {
|
||||
if(opts->stream_cache_size<0) {
|
||||
// cache option not set, will use our computed value.
|
||||
// buffer in KBytes, *5 because the prefill is 20% of the buffer.
|
||||
stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5;
|
||||
if( stream_cache_size<64 ) stream_cache_size = 64; // 16KBytes min buffer
|
||||
opts->stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5;
|
||||
if( opts->stream_cache_size<64 ) opts->stream_cache_size = 64; // 16KBytes min buffer
|
||||
}
|
||||
mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes\n", stream_cache_size);
|
||||
mp_tmsg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes\n", opts->stream_cache_size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,6 +184,8 @@ int stream_fill_buffer(stream_t *s);
|
|||
int stream_seek_long(stream_t *s, off_t pos);
|
||||
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
int stream_enable_cache_percent(stream_t *stream, int64_t stream_cache_size,
|
||||
float stream_cache_min_percent, float stream_cache_seek_min_percent);
|
||||
int stream_enable_cache(stream_t *stream,int64_t size,int64_t min,int64_t prefill);
|
||||
int cache_stream_fill_buffer(stream_t *s);
|
||||
int cache_stream_seek_long(stream_t *s,int64_t pos);
|
||||
|
@ -192,6 +194,7 @@ int cache_stream_seek_long(stream_t *s,int64_t pos);
|
|||
#define cache_stream_fill_buffer(x) stream_fill_buffer(x)
|
||||
#define cache_stream_seek_long(x,y) stream_seek_long(x,y)
|
||||
#define stream_enable_cache(x,y,z,w) 1
|
||||
#define stream_enable_cache_percent(x,y,z,w) 1
|
||||
#endif
|
||||
int stream_write_buffer(stream_t *s, unsigned char *buf, int len);
|
||||
|
||||
|
|
|
@ -112,6 +112,50 @@ static char **find_files(const char *original_file, const char *suffix)
|
|||
return results;
|
||||
}
|
||||
|
||||
static struct demuxer *open_demuxer(struct stream *stream,
|
||||
struct MPContext *mpctx, char *filename, unsigned char uid_map[][16])
|
||||
{
|
||||
return demux_open_withparams(&mpctx->opts, stream,
|
||||
DEMUXER_TYPE_MATROSKA, NULL, mpctx->opts.audio_id,
|
||||
mpctx->opts.video_id, mpctx->opts.sub_id, filename,
|
||||
&(struct demuxer_params){.matroska_wanted_uids = uid_map});
|
||||
}
|
||||
|
||||
static int enable_cache(struct MPContext *mpctx, struct stream **stream,
|
||||
struct demuxer **demuxer, unsigned char uid_map[][16])
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
|
||||
if (opts->stream_cache_size <= 0)
|
||||
return 0;
|
||||
|
||||
char *filename = talloc_strdup(NULL, (*demuxer)->filename);
|
||||
free_demuxer(*demuxer);
|
||||
free_stream(*stream);
|
||||
|
||||
int format = 0;
|
||||
*stream = open_stream(filename, &mpctx->opts, &format);
|
||||
if (!*stream) {
|
||||
talloc_free(filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream_enable_cache_percent(*stream,
|
||||
opts->stream_cache_size,
|
||||
opts->stream_cache_min_percent,
|
||||
opts->stream_cache_seek_min_percent);
|
||||
|
||||
*demuxer = open_demuxer(*stream, mpctx, filename, uid_map);
|
||||
if (!*demuxer) {
|
||||
talloc_free(filename);
|
||||
free_stream(*stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
talloc_free(filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int find_ordered_chapter_sources(struct MPContext *mpctx,
|
||||
struct demuxer **sources,
|
||||
int num_sources,
|
||||
|
@ -140,11 +184,7 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
|
|||
struct stream *s = open_stream(filenames[i], &mpctx->opts, &format);
|
||||
if (!s)
|
||||
continue;
|
||||
struct demuxer *d = demux_open_withparams(&mpctx->opts, s,
|
||||
DEMUXER_TYPE_MATROSKA, NULL, mpctx->opts.audio_id,
|
||||
mpctx->opts.video_id, mpctx->opts.sub_id, filenames[i],
|
||||
&(struct demuxer_params){.matroska_wanted_uids = uid_map});
|
||||
|
||||
struct demuxer *d = open_demuxer(s, mpctx, filenames[i], uid_map);
|
||||
|
||||
if (!d) {
|
||||
free_stream(s);
|
||||
|
@ -157,6 +197,10 @@ static int find_ordered_chapter_sources(struct MPContext *mpctx,
|
|||
if (!memcmp(uid_map[i], d->matroska_data.segment_uid, 16)) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_INFO,"Match for source %d: %s\n",
|
||||
i, d->filename);
|
||||
|
||||
if (enable_cache(mpctx, &s, &d, uid_map) < 0)
|
||||
continue;
|
||||
|
||||
sources[i] = d;
|
||||
num_left--;
|
||||
goto match;
|
||||
|
|
Loading…
Reference in New Issue