diff options
Diffstat (limited to 'player')
-rw-r--r-- | player/client.c | 2 | ||||
-rw-r--r-- | player/core.h | 6 | ||||
-rw-r--r-- | player/loadfile.c | 27 | ||||
-rw-r--r-- | player/main.c | 8 | ||||
-rw-r--r-- | player/misc.c | 2 |
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; |