summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c56
-rw-r--r--demux/demux.h3
-rw-r--r--player/command.c24
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);