demux: make track switching asynchronous

Because why not.

This can lead to reordering of operations between seeking and track
switching (happens when the demuxer wakes up after seek and track
switching operations were queued). Do the track switching strictly
before seeks if there is a chance of reordering, which guarantees that
the seek position will always start with key frames. The reverse
(seeking, then switching) does not really have any advantages.

(Not sure if the player relies on this behavior.)
This commit is contained in:
wm4 2014-08-06 19:25:37 +02:00
parent b38ac38aec
commit 64e1132d39
1 changed files with 21 additions and 0 deletions

View File

@ -113,6 +113,8 @@ struct demux_internal {
int min_packs;
int min_bytes;
bool tracks_switched; // thread needs to inform demuxer of this
bool seeking; // there's a seek queued
int seek_flags; // flags for next seek (if seeking==true)
double seek_pts;
@ -404,6 +406,18 @@ static void ds_get_packets(struct demux_stream *ds)
}
}
static void execute_trackswitch(struct demux_internal *in)
{
in->tracks_switched = false;
pthread_mutex_unlock(&in->lock);
if (in->d_thread->desc->control)
in->d_thread->desc->control(in->d_thread, DEMUXER_CTRL_SWITCHED_TRACKS, 0);
pthread_mutex_lock(&in->lock);
}
static void execute_seek(struct demux_internal *in)
{
int flags = in->seek_flags;
@ -429,6 +443,10 @@ static void *demux_thread(void *pctx)
pthread_cond_wait(&in->wakeup, &in->lock);
continue;
}
if (in->tracks_switched) {
execute_trackswitch(in);
continue;
}
if (in->seeking) {
execute_seek(in);
continue;
@ -1128,6 +1146,9 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
c->res = r;
return DEMUXER_CTRL_OK;
}
case DEMUXER_CTRL_SWITCHED_TRACKS:
in->tracks_switched = true;
return DEMUXER_CTRL_OK;
}
return DEMUXER_CTRL_DONTKNOW;
}