From f9ba1a3ddf5186cb31c2715e3293eef70575a9ee Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 23 Dec 2015 21:44:53 +0100 Subject: demux: remove weird tripple-buffering for the sh_stream list The demuxer infrastructure was originally single-threaded. To make it suitable for multithreading (specifically, demuxing and decoding on separate threads), some sort of tripple-buffering was introduced. There are separate "struct demuxer" allocations. The demuxer thread sets the state on d_thread. If anything changes, the state is copied to d_buffer (the copy is protected by a lock), and the decoder thread is notified. Then the decoder thread copies the state from d_buffer to d_user (again while holding a lock). This avoids the need for locking in the demuxer/decoder code itself (only demux.c needs an internal, "invisible" lock.) Remove the streams/num_streams fields from this tripple-buffering schema. Move them to the internal struct, and protect them with the internal lock. Use accessors for read access outside of demux.c. Other than replacing all field accesses with accessors, this separates allocating and adding sh_streams. This is needed to avoid race conditions. Before this change, this was awkwardly handled by first initializing the sh_stream, and then sending a stream change event. Now the stream is allocated, then initialized, and then declared as immutable and added (at which point it becomes visible to the decoder thread immediately). This change is useful for PR #2626. And eventually, we should probably get entirely of the tripple buffering, and this makes a nice first step. --- player/loadfile.c | 18 ++++++++++-------- player/misc.c | 4 ++-- player/sub.c | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) (limited to 'player') diff --git a/player/loadfile.c b/player/loadfile.c index 07a32c307a..af60aed3e0 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -212,8 +212,8 @@ void update_demuxer_properties(struct MPContext *mpctx) static bool need_init_seek(struct demuxer *demux) { - for (int n = 0; n < demux->num_streams; n++) { - struct sh_stream *stream = demux->streams[n]; + for (int n = 0; n < demux_get_num_stream(demux); n++) { + struct sh_stream *stream = demux_get_stream(demux, n); // Subtitle streams are not properly interleaved -> force init. seek. if (stream->type != STREAM_SUB && demux_stream_is_selected(stream)) return false; @@ -250,8 +250,8 @@ static struct sh_stream *select_fallback_stream(struct demuxer *d, int index) { struct sh_stream *best_stream = NULL; - for (int n = 0; n < d->num_streams; n++) { - struct sh_stream *s = d->streams[n]; + for (int n = 0; n < demux_get_num_stream(d); n++) { + struct sh_stream *s = demux_get_stream(d, n); if (s->type == type) { best_stream = s; if (index == 0) @@ -396,8 +396,10 @@ static struct track *add_stream_track(struct MPContext *mpctx, void add_demuxer_tracks(struct MPContext *mpctx, struct demuxer *demuxer) { - for (int n = 0; n < demuxer->num_streams; n++) - add_stream_track(mpctx, demuxer, demuxer->streams[n], !!mpctx->timeline); + for (int n = 0; n < demux_get_num_stream(demuxer); n++) { + add_stream_track(mpctx, demuxer, demux_get_stream(demuxer, n), + !!mpctx->timeline); + } } // Result numerically higher => better match. 0 == no match. @@ -708,8 +710,8 @@ struct track *mp_add_external_file(struct MPContext *mpctx, char *filename, demux_set_ts_offset(demuxer, -demuxer->start_time); struct track *first = NULL; - for (int n = 0; n < demuxer->num_streams; n++) { - struct sh_stream *sh = demuxer->streams[n]; + for (int n = 0; n < demux_get_num_stream(demuxer); n++) { + struct sh_stream *sh = demux_get_stream(demuxer, n); if (sh->type == filter) { struct track *t = add_stream_track(mpctx, demuxer, sh, false); t->is_external = true; diff --git a/player/misc.c b/player/misc.c index 0b2548b98b..fc98136e5c 100644 --- a/player/misc.c +++ b/player/misc.c @@ -106,8 +106,8 @@ double get_main_demux_pts(struct MPContext *mpctx) { double main_new_pos = MP_NOPTS_VALUE; if (mpctx->demuxer) { - for (int n = 0; n < mpctx->demuxer->num_streams; n++) { - struct sh_stream *stream = mpctx->demuxer->streams[n]; + for (int n = 0; n < demux_get_num_stream(mpctx->demuxer); n++) { + struct sh_stream *stream = demux_get_stream(mpctx->demuxer, n); if (main_new_pos == MP_NOPTS_VALUE && stream->type != STREAM_SUB) main_new_pos = demux_get_next_pts(stream); } diff --git a/player/sub.c b/player/sub.c index 9ec7ba5e7b..df84e910af 100644 --- a/player/sub.c +++ b/player/sub.c @@ -146,8 +146,8 @@ void reset_subtitle_state(struct MPContext *mpctx) void uninit_stream_sub_decoders(struct demuxer *demuxer) { - for (int i = 0; i < demuxer->num_streams; i++) { - struct sh_stream *sh = demuxer->streams[i]; + for (int i = 0; i < demux_get_num_stream(demuxer); i++) { + struct sh_stream *sh = demux_get_stream(demuxer, i); if (sh->sub) { sub_destroy(sh->sub->dec_sub); sh->sub->dec_sub = NULL; -- cgit v1.2.3