From 953ff6b3908bcfdd69a9189c991e55f362d2d2dc Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 9 Mar 2016 23:55:16 +0100 Subject: demux: replace demux_pause/demux_unpause with demux_run_on_thread This pause stuff is bothersome and is needed only for a few corner- cases. This commit removes it from the demuxer public API and replaces it with a demux_run_on_thread() function and refactors the code which needed demux_pause(). The next commit will change the implementation. --- demux/demux.c | 56 ++++++++++++++++++++++++++++++++++++++++++-------------- demux/demux.h | 3 +-- player/command.c | 24 +++++++++++++++++------- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index a7241d9a9f..2770413938 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1533,20 +1533,22 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg) return DEMUXER_CTRL_DONTKNOW; } -int demux_control(demuxer_t *demuxer, int cmd, void *arg) +struct demux_control_args { + struct demuxer *demuxer; + int cmd; + void *arg; + int *r; +}; + +static void thread_demux_control(void *p) { + struct demux_control_args *args = p; + struct demuxer *demuxer = args->demuxer; + int cmd = args->cmd; + void *arg = args->arg; struct demux_internal *in = demuxer->in; - - if (in->threading) { - pthread_mutex_lock(&in->lock); - int cr = cached_demux_control(in, cmd, arg); - pthread_mutex_unlock(&in->lock); - if (cr != DEMUXER_CTRL_DONTKNOW) - return cr; - } - int r = DEMUXER_CTRL_NOTIMPL; - demux_pause(demuxer); + if (cmd == DEMUXER_CTRL_STREAM_CTRL) { struct demux_ctrl_stream_ctrl *c = arg; if (in->threading) @@ -1561,7 +1563,26 @@ int demux_control(demuxer_t *demuxer, int cmd, void *arg) if (demuxer->desc->control) r = demuxer->desc->control(demuxer->in->d_thread, cmd, arg); } - demux_unpause(demuxer); + + *args->r = r; +} + +int demux_control(demuxer_t *demuxer, int cmd, void *arg) +{ + struct demux_internal *in = demuxer->in; + + if (in->threading) { + pthread_mutex_lock(&in->lock); + int cr = cached_demux_control(in, cmd, arg); + pthread_mutex_unlock(&in->lock); + if (cr != DEMUXER_CTRL_DONTKNOW) + return cr; + } + + int r = 0; + struct demux_control_args args = {demuxer, cmd, arg, &r}; + demux_run_on_thread(demuxer, thread_demux_control, &args); + return r; } @@ -1575,7 +1596,7 @@ int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg) // Make the demuxer thread stop doing anything. // demux_unpause() wakes up the thread again. // Can be nested with other calls, but trying to read packets may deadlock. -void demux_pause(demuxer_t *demuxer) +static void demux_pause(demuxer_t *demuxer) { struct demux_internal *in = demuxer->in; assert(demuxer == in->d_user); @@ -1593,7 +1614,7 @@ void demux_pause(demuxer_t *demuxer) pthread_mutex_unlock(&in->lock); } -void demux_unpause(demuxer_t *demuxer) +static void demux_unpause(demuxer_t *demuxer) { struct demux_internal *in = demuxer->in; assert(demuxer == in->d_user); @@ -1608,6 +1629,13 @@ void demux_unpause(demuxer_t *demuxer) pthread_mutex_unlock(&in->lock); } +void demux_run_on_thread(struct demuxer *demuxer, void (*fn)(void *), void *ctx) +{ + demux_pause(demuxer); + fn(ctx); + demux_unpause(demuxer); +} + bool demux_cancel_test(struct demuxer *demuxer) { return mp_cancel_test(demuxer->stream->cancel); diff --git a/demux/demux.h b/demux/demux.h index 2c1e3a20fa..a26dada6c8 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -285,8 +285,7 @@ double demuxer_get_time_length(struct demuxer *demuxer); int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg); -void demux_pause(demuxer_t *demuxer); -void demux_unpause(demuxer_t *demuxer); +void demux_run_on_thread(struct demuxer *demuxer, void (*fn)(void *), void *ctx); void demux_changed(demuxer_t *demuxer, int events); void demux_update(demuxer_t *demuxer); diff --git a/player/command.c b/player/command.c index fe2eb3eb22..d2a8308a58 100644 --- a/player/command.c +++ b/player/command.c @@ -419,6 +419,17 @@ static int mp_property_stream_path(void *ctx, struct m_property *prop, return m_property_strdup_ro(action, arg, stream->url); } +struct change_stream_capture_args { + char *filename; + struct demuxer *demux; +}; + +static void do_change_stream_capture(void *p) +{ + struct change_stream_capture_args *args = p; + stream_set_capture_file(args->demux->stream, args->filename); +} + static int mp_property_stream_capture(void *ctx, struct m_property *prop, int action, void *arg) { @@ -427,10 +438,8 @@ static int mp_property_stream_capture(void *ctx, struct m_property *prop, return M_PROPERTY_UNAVAILABLE; if (action == M_PROPERTY_SET) { - char *filename = *(char **)arg; - demux_pause(mpctx->demuxer); - stream_set_capture_file(mpctx->demuxer->stream, filename); - demux_unpause(mpctx->demuxer); + struct change_stream_capture_args args = {*(char **)arg, mpctx->demuxer}; + demux_run_on_thread(mpctx->demuxer, do_change_stream_capture, &args); // fall through to mp_property_generic_option } return mp_property_generic_option(mpctx, prop, action, arg); @@ -1077,11 +1086,12 @@ static int mp_property_angle(void *ctx, struct m_property *prop, if (angle < 0 || angle > angles) return M_PROPERTY_ERROR; - demux_pause(demuxer); demux_flush(demuxer); ris = demux_stream_control(demuxer, STREAM_CTRL_SET_ANGLE, &angle); - demux_control(demuxer, DEMUXER_CTRL_RESYNC, NULL); - demux_unpause(demuxer); + if (ris == STREAM_OK) { + demux_control(demuxer, DEMUXER_CTRL_RESYNC, NULL); + demux_flush(demuxer); + } reset_audio_state(mpctx); reset_video_state(mpctx); -- cgit v1.2.3