summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-11-10 02:55:02 +0100
committerwm4 <wm4@nowhere>2017-11-10 02:55:02 +0100
commitc494049e766a169c2abd25c99c3cdeff33cdc532 (patch)
tree65301a765ef64114dd4bbb4620b7d449fa210f2e
parent935e406d6398062ea7978d546f4da6ca8e6a216f (diff)
downloadmpv-c494049e766a169c2abd25c99c3cdeff33cdc532.tar.bz2
mpv-c494049e766a169c2abd25c99c3cdeff33cdc532.tar.xz
demux: reduce difference between threaded and non-threaded mode
This fixes an endless loop with threading disabled, such as for example when playing a file with an external subtitle file, and seeking to the beginning. Something will set in->seeking, but the seek is never executed, which made demux_read_packet() loop endlessly. (External subtitles will use non-threaded mode for whatever reasons.) Fix this by by making the unthreaded code to execute the worker thread body, which reduces the difference in logic.
-rw-r--r--demux/demux.c62
1 files changed, 35 insertions, 27 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 9558605bad..ae7ac7afe3 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -1385,37 +1385,45 @@ static void execute_seek(struct demux_internal *in)
pthread_mutex_lock(&in->lock);
}
+// Make demuxing progress. Return whether progress was made.
+static bool thread_work(struct demux_internal *in)
+{
+ if (in->run_fn) {
+ in->run_fn(in->run_fn_arg);
+ in->run_fn = NULL;
+ pthread_cond_signal(&in->wakeup);
+ return true;
+ }
+ if (in->tracks_switched) {
+ execute_trackswitch(in);
+ return true;
+ }
+ if (in->seeking) {
+ execute_seek(in);
+ return true;
+ }
+ if (!in->eof) {
+ if (read_packet(in))
+ return true; // read_packet unlocked, so recheck conditions
+ }
+ if (in->force_cache_update) {
+ pthread_mutex_unlock(&in->lock);
+ update_cache(in);
+ pthread_mutex_lock(&in->lock);
+ in->force_cache_update = false;
+ return true;
+ }
+ return false;
+}
+
static void *demux_thread(void *pctx)
{
struct demux_internal *in = pctx;
mpthread_set_name("demux");
pthread_mutex_lock(&in->lock);
while (!in->thread_terminate) {
- if (in->run_fn) {
- in->run_fn(in->run_fn_arg);
- in->run_fn = NULL;
- pthread_cond_signal(&in->wakeup);
- continue;
- }
- if (in->tracks_switched) {
- execute_trackswitch(in);
+ if (thread_work(in))
continue;
- }
- if (in->seeking) {
- execute_seek(in);
- continue;
- }
- if (!in->eof) {
- if (read_packet(in))
- continue; // read_packet unlocked, so recheck conditions
- }
- if (in->force_cache_update) {
- pthread_mutex_unlock(&in->lock);
- update_cache(in);
- pthread_mutex_lock(&in->lock);
- in->force_cache_update = false;
- continue;
- }
pthread_cond_signal(&in->wakeup);
pthread_cond_wait(&in->wakeup, &in->lock);
}
@@ -1509,7 +1517,7 @@ struct demux_packet *demux_read_packet(struct sh_stream *sh)
pthread_cond_signal(&in->wakeup);
pthread_cond_wait(&in->wakeup, &in->lock);
} else {
- read_packet(in);
+ thread_work(in);
}
if (ds->eof)
break;
@@ -1586,8 +1594,8 @@ struct demux_packet *demux_read_any_packet(struct demuxer *demuxer)
return pkt;
}
// retry after calling this
- pthread_mutex_lock(&in->lock); // lock only because read_packet unlocks
- read_more = read_packet(in);
+ pthread_mutex_lock(&in->lock); // lock only because thread_work unlocks
+ read_more = thread_work(in);
read_more &= !in->eof;
pthread_mutex_unlock(&in->lock);
}