summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-02-20 20:28:23 +0100
committerwm4 <wm4@nowhere>2015-02-20 20:30:05 +0100
commit44411674ebb764adeb806040d24700bc4cc493cc (patch)
tree7bc11ca505f3847c9ccf4e1f2cec1ccc330f0341 /player
parent2c305d5b2990d31911d7faa4c9117bf4eb89c88b (diff)
downloadmpv-44411674ebb764adeb806040d24700bc4cc493cc.tar.bz2
mpv-44411674ebb764adeb806040d24700bc4cc493cc.tar.xz
player: move timeline scanning (ordered chapters etc.) to a thread
Do timeline building (scanning & opening reference files for ordered chapters, and more) in a thread. As a result, this process can actually be stopped without having to kill the player. This is pretty simple: just reuse the demuxer opening thread. We have to give up on the idea that open_demux_reentrant() is reusable, though. (Althoughthe timeline readers still need some fixes before they react to the quit request.)
Diffstat (limited to 'player')
-rw-r--r--player/loadfile.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/player/loadfile.c b/player/loadfile.c
index f74cd49d32..0d7b732f69 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -960,7 +960,10 @@ static struct stream *open_stream_reentrant(struct MPContext *mpctx,
struct demux_open_args {
struct stream *stream;
struct mpv_global *global;
- struct demuxer *demux; // result
+ struct mp_log *log;
+ // results
+ struct demuxer *demux;
+ struct timeline *tl;
};
static void open_demux_thread(void *pctx)
@@ -969,19 +972,25 @@ static void open_demux_thread(void *pctx)
struct stream *s = args->stream;
struct mpv_global *global = args->global;
args->demux = demux_open(s, global->opts->demuxer_name, NULL, global);
+ if (args->demux)
+ args->tl = timeline_load(global, args->log, args->demux);
}
-static struct demuxer *open_demux_reentrant(struct MPContext *mpctx,
- struct stream *stream)
+static void open_demux_reentrant(struct MPContext *mpctx)
{
- struct demux_open_args args = {stream, create_sub_global(mpctx)};
+ struct demux_open_args args = {
+ .global = create_sub_global(mpctx),
+ .stream = mpctx->stream,
+ .log = mpctx->log,
+ };
mpctx_run_reentrant(mpctx, open_demux_thread, &args);
if (args.demux) {
talloc_steal(args.demux, args.global);
+ mpctx->demuxer = args.demux;
+ mpctx->tl = args.tl;
} else {
talloc_free(args.global);
}
- return args.demux;
}
static void load_timeline(struct MPContext *mpctx)
@@ -990,7 +999,6 @@ static void load_timeline(struct MPContext *mpctx)
MP_TARRAY_APPEND(NULL, mpctx->sources, mpctx->num_sources, mpctx->demuxer);
- mpctx->tl = timeline_load(mpctx->global, mpctx->log, mpctx->demuxer);
if (mpctx->tl) {
mpctx->timeline = mpctx->tl->parts;
mpctx->num_timeline_parts = mpctx->tl->num_parts;
@@ -1113,7 +1121,7 @@ goto_reopen_demuxer: ;
mp_nav_reset(mpctx);
- mpctx->demuxer = open_demux_reentrant(mpctx, mpctx->stream);
+ open_demux_reentrant(mpctx);
if (!mpctx->demuxer) {
MP_ERR(mpctx, "Failed to recognize file format.\n");
mpctx->error_playing = MPV_ERROR_UNKNOWN_FORMAT;