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.
Instead, force everyone to use the metadata struct and set a "title"
field. This is only a problem for the timeline producers, which set up
chapters manually. (They do this because a timeline is a separate
struct.)
This fixes the behavior of the chapter-metadata property, which never
returned a "title" property for e.g. ordered chapters.
If the cache is enabled, the demuxer is closed and opened again (because
currently, the cache can not be enabled atfer data was already read).
The call for opening a new demuxer uses the same params struct, which
references the ctx->uids array. But there is a MP_TARRAY_GROW()
invocation somewhere on the way, which can reallocate the ctx->uids
array, making params.uids a dangling pointer.
This issue probably existed for a longer time, probably since 5cd33853
(slightly more obvious since f50b105d).
Again removes some indirections and extra arguments.
Also replace some memcpy/memmoves with assignments. (Assignments became
possible only later, when reference UIDs were turned into a struct.)
The Matroska timeline code was the only thing which still used the
demuxer.type field. This field explicitly identifies a demuxer
implementation. The purpose of the Matroska timeline code was to reject
files that are not Matroska. But it already forces the Matroska format,
meaning loading will explicitly only use the Matroska demuxer. If the
demuxer can't open the file, no other demuxer will be tried, and thus
checking the field is redundant.
The change in demux_mkv_timeline.c removes the if condition, and
unindents the if body.