mirror of
https://github.com/mpv-player/mpv
synced 2024-12-27 01:22:30 +00:00
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.
This commit is contained in:
parent
04858c0b83
commit
c54c3b6991
@ -144,7 +144,8 @@ struct input_ctx {
|
|||||||
|
|
||||||
struct cmd_queue cmd_queue;
|
struct cmd_queue cmd_queue;
|
||||||
|
|
||||||
struct mp_cancel *cancel;
|
void (*cancel)(void *cancel_ctx);
|
||||||
|
void *cancel_ctx;
|
||||||
|
|
||||||
void (*wakeup_cb)(void *ctx);
|
void (*wakeup_cb)(void *ctx);
|
||||||
void *wakeup_ctx;
|
void *wakeup_ctx;
|
||||||
@ -809,7 +810,7 @@ int mp_input_queue_cmd(struct input_ctx *ictx, mp_cmd_t *cmd)
|
|||||||
input_lock(ictx);
|
input_lock(ictx);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (ictx->cancel && test_abort_cmd(ictx, cmd))
|
if (ictx->cancel && test_abort_cmd(ictx, cmd))
|
||||||
mp_cancel_trigger(ictx->cancel);
|
ictx->cancel(ictx->cancel_ctx);
|
||||||
queue_add_tail(&ictx->cmd_queue, cmd);
|
queue_add_tail(&ictx->cmd_queue, cmd);
|
||||||
mp_input_wakeup(ictx);
|
mp_input_wakeup(ictx);
|
||||||
}
|
}
|
||||||
@ -1335,10 +1336,11 @@ void mp_input_uninit(struct input_ctx *ictx)
|
|||||||
talloc_free(ictx);
|
talloc_free(ictx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_input_set_cancel(struct input_ctx *ictx, struct mp_cancel *cancel)
|
void mp_input_set_cancel(struct input_ctx *ictx, void (*cb)(void *c), void *c)
|
||||||
{
|
{
|
||||||
input_lock(ictx);
|
input_lock(ictx);
|
||||||
ictx->cancel = cancel;
|
ictx->cancel = cb;
|
||||||
|
ictx->cancel_ctx = c;
|
||||||
input_unlock(ictx);
|
input_unlock(ictx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +242,7 @@ void mp_input_wakeup(struct input_ctx *ictx);
|
|||||||
|
|
||||||
// Used to asynchronously abort playback. Needed because the core still can
|
// Used to asynchronously abort playback. Needed because the core still can
|
||||||
// block on network in some situations.
|
// block on network in some situations.
|
||||||
struct mp_cancel;
|
void mp_input_set_cancel(struct input_ctx *ictx, void (*cb)(void *c), void *c);
|
||||||
void mp_input_set_cancel(struct input_ctx *ictx, struct mp_cancel *cancel);
|
|
||||||
|
|
||||||
// If this returns true, use Right Alt key as Alt Gr to produce special
|
// If this returns true, use Right Alt key as Alt Gr to produce special
|
||||||
// characters. If false, count Right Alt as the modifier Alt key.
|
// characters. If false, count Right Alt as the modifier Alt key.
|
||||||
|
@ -982,7 +982,7 @@ static int run_client_command(mpv_handle *ctx, struct mp_cmd *cmd, mpv_node *res
|
|||||||
return MPV_ERROR_INVALID_PARAMETER;
|
return MPV_ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (mp_input_is_abort_cmd(cmd))
|
if (mp_input_is_abort_cmd(cmd))
|
||||||
mp_cancel_trigger(ctx->mpctx->playback_abort);
|
mp_abort_playback_async(ctx->mpctx);
|
||||||
|
|
||||||
cmd->sender = ctx->name;
|
cmd->sender = ctx->name;
|
||||||
|
|
||||||
|
@ -430,6 +430,11 @@ typedef struct MPContext {
|
|||||||
struct mp_ipc_ctx *ipc_ctx;
|
struct mp_ipc_ctx *ipc_ctx;
|
||||||
|
|
||||||
struct mpv_opengl_cb_context *gl_cb_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;
|
} MPContext;
|
||||||
|
|
||||||
// audio.c
|
// audio.c
|
||||||
@ -460,6 +465,7 @@ struct playlist_entry *mp_check_playlist_resume(struct MPContext *mpctx,
|
|||||||
struct playlist *playlist);
|
struct playlist *playlist);
|
||||||
|
|
||||||
// loadfile.c
|
// loadfile.c
|
||||||
|
void mp_abort_playback_async(struct MPContext *mpctx);
|
||||||
void uninit_player(struct MPContext *mpctx, unsigned int mask);
|
void uninit_player(struct MPContext *mpctx, unsigned int mask);
|
||||||
struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
|
struct track *mp_add_external_file(struct MPContext *mpctx, char *filename,
|
||||||
enum stream_type filter);
|
enum stream_type filter);
|
||||||
|
@ -57,6 +57,17 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "libmpv/client.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)
|
static void uninit_demuxer(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
for (int r = 0; r < NUM_PTRACKS; r++) {
|
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);
|
free_demuxer_and_stream(mpctx->demuxer);
|
||||||
mpctx->demuxer = NULL;
|
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__)
|
#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 = {
|
struct demux_open_args args = {
|
||||||
.global = mpctx->global,
|
.global = mpctx->global,
|
||||||
.cancel = mpctx->playback_abort,
|
.cancel = mp_cancel_new(NULL),
|
||||||
.log = mpctx->log,
|
.log = mpctx->log,
|
||||||
.stream_flags = mpctx->playing->stream_flags,
|
.stream_flags = mpctx->playing->stream_flags,
|
||||||
.url = talloc_strdup(NULL, mpctx->stream_open_filename),
|
.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)
|
if (mpctx->opts->load_unsafe_playlists)
|
||||||
args.stream_flags = 0;
|
args.stream_flags = 0;
|
||||||
mpctx_run_reentrant(mpctx, open_demux_thread, &args);
|
mpctx_run_reentrant(mpctx, open_demux_thread, &args);
|
||||||
@ -820,6 +839,10 @@ static void open_demux_reentrant(struct MPContext *mpctx)
|
|||||||
mpctx->demuxer = args.demux;
|
mpctx->demuxer = args.demux;
|
||||||
} else {
|
} else {
|
||||||
mpctx->error_playing = args.err;
|
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);
|
talloc_free(args.url);
|
||||||
}
|
}
|
||||||
@ -1170,7 +1193,7 @@ terminate_playback:
|
|||||||
if (mpctx->step_frames)
|
if (mpctx->step_frames)
|
||||||
opts->pause = 1;
|
opts->pause = 1;
|
||||||
|
|
||||||
mp_cancel_trigger(mpctx->playback_abort);
|
mp_abort_playback_async(mpctx);
|
||||||
|
|
||||||
// time to uninit all, except global stuff:
|
// time to uninit all, except global stuff:
|
||||||
uninit_complex_filters(mpctx);
|
uninit_complex_filters(mpctx);
|
||||||
|
@ -311,6 +311,12 @@ static int cfg_include(void *ctx, char *filename, int flags)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void abort_playback_cb(void *ctx)
|
||||||
|
{
|
||||||
|
struct MPContext *mpctx = ctx;
|
||||||
|
mp_abort_playback_async(mpctx);
|
||||||
|
}
|
||||||
|
|
||||||
struct MPContext *mp_create(void)
|
struct MPContext *mp_create(void)
|
||||||
{
|
{
|
||||||
char *enable_talloc = getenv("MPV_LEAK_REPORT");
|
char *enable_talloc = getenv("MPV_LEAK_REPORT");
|
||||||
@ -361,7 +367,7 @@ struct MPContext *mp_create(void)
|
|||||||
cocoa_set_input_context(mpctx->input);
|
cocoa_set_input_context(mpctx->input);
|
||||||
#endif
|
#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");
|
char *verbose_env = getenv("MPV_VERBOSE");
|
||||||
if (verbose_env)
|
if (verbose_env)
|
||||||
|
@ -287,7 +287,7 @@ int mpctx_run_reentrant(struct MPContext *mpctx, void (*thread_fn)(void *arg),
|
|||||||
mp_idle(mpctx);
|
mp_idle(mpctx);
|
||||||
|
|
||||||
if (mpctx->stop_play)
|
if (mpctx->stop_play)
|
||||||
mp_cancel_trigger(mpctx->playback_abort);
|
mp_abort_playback_async(mpctx);
|
||||||
|
|
||||||
pthread_mutex_lock(&args.mutex);
|
pthread_mutex_lock(&args.mutex);
|
||||||
success |= args.done;
|
success |= args.done;
|
||||||
|
Loading…
Reference in New Issue
Block a user