diff options
author | wm4 <wm4@nowhere> | 2015-12-23 21:44:53 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-12-23 21:52:16 +0100 |
commit | f9ba1a3ddf5186cb31c2715e3293eef70575a9ee (patch) | |
tree | d74fc10c76c95d05220a5c379e25333031642d2d /demux/demux_mkv.c | |
parent | b0381d27eb19d8f70f4f711d41dd342c616ae843 (diff) | |
download | mpv-f9ba1a3ddf5186cb31c2715e3293eef70575a9ee.tar.bz2 mpv-f9ba1a3ddf5186cb31c2715e3293eef70575a9ee.tar.xz |
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.
Diffstat (limited to 'demux/demux_mkv.c')
-rw-r--r-- | demux/demux_mkv.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 562bddbfc6..af82dc8deb 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -1193,9 +1193,7 @@ static void add_coverart(struct demuxer *demuxer) const char *codec = mp_map_mimetype_to_video_codec(att->type); if (!codec) continue; - struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO); - if (!sh) - break; + struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO); sh->demuxer_id = -1 - sh->index; // don't clash with mkv IDs sh->codec = codec; sh->attached_picture = new_demux_packet_from(att->data, att->data_size); @@ -1205,6 +1203,7 @@ static void add_coverart(struct demuxer *demuxer) sh->attached_picture->keyframe = true; } sh->title = att->name; + demux_add_sh_stream(demuxer, sh); } } @@ -1266,9 +1265,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) { unsigned char *extradata = NULL; unsigned int extradata_size = 0; - struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO); - if (!sh) - return 1; + struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO); init_track(demuxer, track, sh); sh_video_t *sh_v = sh->video; @@ -1277,7 +1274,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC")) { /* AVI compatibility mode */ // The private_data contains a BITMAPINFOHEADER struct if (track->private_data == NULL || track->private_size < 40) - return 1; + goto done; unsigned char *h = track->private_data; if (track->v_width == 0) @@ -1355,7 +1352,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) if (extradata_size > 0x1000000) { MP_WARN(demuxer, "Invalid CodecPrivate\n"); - return 1; + goto done; } sh->extradata = talloc_memdup(sh_v, extradata, extradata_size); @@ -1378,6 +1375,9 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) sh_v->stereo_mode = track->stereo_mode; +done: + demux_add_sh_stream(demuxer, sh); + return 0; } @@ -1469,9 +1469,7 @@ static const char *const mkv_audio_tags[][2] = { static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) { - struct sh_stream *sh = new_sh_stream(demuxer, STREAM_AUDIO); - if (!sh) - return 1; + struct sh_stream *sh = demux_alloc_sh_stream(STREAM_AUDIO); init_track(demuxer, track, sh); sh_audio_t *sh_a = sh->audio; @@ -1680,12 +1678,15 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) sh->extradata = extradata; sh->extradata_size = extradata_len; + demux_add_sh_stream(demuxer, sh); + return 0; error: MP_WARN(demuxer, "Unknown/unsupported audio " "codec ID '%s' for track %u or missing/faulty\n" "private codec data.\n", track->codec_id, track->tnum); + demux_add_sh_stream(demuxer, sh); // add it anyway return 1; } @@ -1717,9 +1718,7 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track) if (track->private_size > 0x10000000) return 1; - struct sh_stream *sh = new_sh_stream(demuxer, STREAM_SUB); - if (!sh) - return 1; + struct sh_stream *sh = demux_alloc_sh_stream(STREAM_SUB); init_track(demuxer, track, sh); sh->codec = subtitle_type; @@ -1734,6 +1733,8 @@ static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track) sh->extradata = track->private_data; sh->extradata_size = track->private_size; + demux_add_sh_stream(demuxer, sh); + if (!subtitle_type) MP_ERR(demuxer, "Subtitle type '%s' is not supported.\n", track->codec_id); |