summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-01-18 17:13:26 +0100
committerwm4 <wm4@nowhere>2017-01-18 17:52:05 +0100
commitc54c3b6991ac0273e6b7a42dc42c5103f87ff9f1 (patch)
tree1b543741e9bf171fa9a77fe90e4df9f62396284d /player
parent04858c0b83fd6c1fc60519c2034e263d2e7c3977 (diff)
downloadmpv-c54c3b6991ac0273e6b7a42dc42c5103f87ff9f1.tar.bz2
mpv-c54c3b6991ac0273e6b7a42dc42c5103f87ff9f1.tar.xz
player: restructure cancel callback
As preparation for file prefetching, we basically have to get rid of using mpctx->playback_abort for the main demuxer (i.e. the thing that can be prefetched). It can't be changed on a running demuxer, and always using the same cancel handle would either mean aborting playback would also abort prefetching, or that playback can't be aborted anymore. Make this more flexible with some refactoring. Thi is a quite shitty solution if you ask me, but YOLO.
Diffstat (limited to 'player')
-rw-r--r--player/client.c2
-rw-r--r--player/core.h6
-rw-r--r--player/loadfile.c27
-rw-r--r--player/main.c8
-rw-r--r--player/misc.c2
5 files changed, 40 insertions, 5 deletions
diff --git a/player/client.c b/player/client.c
index 88926f3544..31a55332d2 100644
--- a/player/client.c
+++ b/player/client.c
@@ -982,7 +982,7 @@ static int run_client_command(mpv_handle *ctx, struct mp_cmd *cmd, mpv_node *res
return MPV_ERROR_INVALID_PARAMETER;
if (mp_input_is_abort_cmd(cmd))
- mp_cancel_trigger(ctx->mpctx->playback_abort);
+ mp_abort_playback_async(ctx->mpctx);
cmd->sender = ctx->name;
diff --git a/player/core.h b/player/core.h
index d7ff507524..ad61500741 100644
--- a/player/core.h
+++ b/player/core.h
@@ -430,6 +430,11 @@ typedef struct MPContext {
struct mp_ipc_ctx *ipc_ctx;
struct mpv_opengl_cb_context *gl_cb_ctx;
+
+ pthread_mutex_t lock;
+
+ // --- The following fields are protected by lock
+ struct mp_cancel *demuxer_cancel; // cancel handle for MPContext.demuxer
} MPContext;
// audio.c
@@ -460,6 +465,7 @@ struct playlist_entry *mp_check_playlist_resume(struct MPContext *mpctx,
struct playlist *playlist);
// loadfile.c
+void mp_abort_playback_async(struct MPContext *mpctx);
void uninit_player(struct MPContext *mpctx, unsigned int mask);
struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
enum stream_type filter);
diff --git a/player/loadfile.c b/player/loadfile.c
index 872db20399..e59acbc8d4 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -57,6 +57,17 @@
#include "command.h"
#include "libmpv/client.h"
+// Called by foreign threads when playback should be stopped and such.
+void mp_abort_playback_async(struct MPContext *mpctx)
+{
+ mp_cancel_trigger(mpctx->playback_abort);
+
+ pthread_mutex_lock(&mpctx->lock);
+ if (mpctx->demuxer_cancel)
+ mp_cancel_trigger(mpctx->demuxer_cancel);
+ pthread_mutex_unlock(&mpctx->lock);
+}
+
static void uninit_demuxer(struct MPContext *mpctx)
{
for (int r = 0; r < NUM_PTRACKS; r++) {
@@ -80,6 +91,11 @@ static void uninit_demuxer(struct MPContext *mpctx)
free_demuxer_and_stream(mpctx->demuxer);
mpctx->demuxer = NULL;
+
+ pthread_mutex_lock(&mpctx->lock);
+ talloc_free(mpctx->demuxer_cancel);
+ mpctx->demuxer_cancel = NULL;
+ pthread_mutex_unlock(&mpctx->lock);
}
#define APPEND(s, ...) mp_snprintf_cat(s, sizeof(s), __VA_ARGS__)
@@ -808,11 +824,14 @@ static void open_demux_reentrant(struct MPContext *mpctx)
{
struct demux_open_args args = {
.global = mpctx->global,
- .cancel = mpctx->playback_abort,
+ .cancel = mp_cancel_new(NULL),
.log = mpctx->log,
.stream_flags = mpctx->playing->stream_flags,
.url = talloc_strdup(NULL, mpctx->stream_open_filename),
};
+ pthread_mutex_lock(&mpctx->lock);
+ mpctx->demuxer_cancel = args.cancel;
+ pthread_mutex_unlock(&mpctx->lock);
if (mpctx->opts->load_unsafe_playlists)
args.stream_flags = 0;
mpctx_run_reentrant(mpctx, open_demux_thread, &args);
@@ -820,6 +839,10 @@ static void open_demux_reentrant(struct MPContext *mpctx)
mpctx->demuxer = args.demux;
} else {
mpctx->error_playing = args.err;
+ pthread_mutex_lock(&mpctx->lock);
+ talloc_free(mpctx->demuxer_cancel);
+ mpctx->demuxer_cancel = NULL;
+ pthread_mutex_unlock(&mpctx->lock);
}
talloc_free(args.url);
}
@@ -1170,7 +1193,7 @@ terminate_playback:
if (mpctx->step_frames)
opts->pause = 1;
- mp_cancel_trigger(mpctx->playback_abort);
+ mp_abort_playback_async(mpctx);
// time to uninit all, except global stuff:
uninit_complex_filters(mpctx);
diff --git a/player/main.c b/player/main.c
index 3a07e0f539..8f54b98728 100644
--- a/player/main.c
+++ b/player/main.c
@@ -311,6 +311,12 @@ static int cfg_include(void *ctx, char *filename, int flags)
return r;
}
+static void abort_playback_cb(void *ctx)
+{
+ struct MPContext *mpctx = ctx;
+ mp_abort_playback_async(mpctx);
+}
+
struct MPContext *mp_create(void)
{
char *enable_talloc = getenv("MPV_LEAK_REPORT");
@@ -361,7 +367,7 @@ struct MPContext *mp_create(void)
cocoa_set_input_context(mpctx->input);
#endif
- mp_input_set_cancel(mpctx->input, mpctx->playback_abort);
+ mp_input_set_cancel(mpctx->input, abort_playback_cb, mpctx);
char *verbose_env = getenv("MPV_VERBOSE");
if (verbose_env)
diff --git a/player/misc.c b/player/misc.c
index eb4c1c031e..032342e84a 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -287,7 +287,7 @@ int mpctx_run_reentrant(struct MPContext *mpctx, void (*thread_fn)(void *arg),
mp_idle(mpctx);
if (mpctx->stop_play)
- mp_cancel_trigger(mpctx->playback_abort);
+ mp_abort_playback_async(mpctx);
pthread_mutex_lock(&args.mutex);
success |= args.done;