Always preroll by default if the cue (index) information indicates
overlapping subtitles.
Increase the amount of maximum data it will skip to get such subtitles
to 10 seconds. Since the index information can reliably tell whether
reading earlier is needed, the maximum should be rarely actually used,
thus we can set it high. On the other hand, the "old" prerolling
mechanism always has to skip the maximum amount of data; thus the method
using the index gets its own option to control the maximum amount of
data to skip.
(As more and more files With newer mkvtoolnix versions are muxed, and
with this new and hopefully sane default established, these options can
probably be removed in the future.)
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.
MPlayer traditionally always used the display aspect ratio, e.g. 16:9,
while FFmpeg uses the sample (aka pixel) aspect ratio.
Both have a bunch of advantages and disadvantages. Actually, it seems
using sample aspect ratio is generally nicer. The main reason for the
change is making mpv closer to how FFmpeg works in order to make life
easier. It's also nice that everything uses integer fractions instead
of floats now (except --video-aspect option/property).
Note that there is at least 1 user-visible change: vf_dsize now does
not set the display size, only the display aspect ratio. This is
because the image_params d_w/d_h fields did not just set the display
aspect, but also the size (except in encoding mode).
This is another regression of the recently added start time probing. If
a seek is executed after opening the file (but before reading any
packets), the first block is discarded instead of indexed. If there are
no other keyframes in the file, seeking will fail completely.
Fix it by seeking to the cluster start if there aren't any index entries
yet. This will read the skipped packet again.
Fixes#2498.
While it seemed like a pretty good idea at first, it's just a dead end
and works only in the simplest cases. While it may or may not help
slightly with audio sync mode, the display-sync mode already compensates
this in a better way. The main issue is that timestamps at this layer
are not in order, so it can look at single timestamps only.
MKV files can very well start with timestamps other than 0. While mpv
has support for such files in general, and demux_lavf enables this
feature, demux_mkv didn't export a start time.
Implement this by simply reading the first cluster timestamp. This in
turn is done by reading 1 block. While we don't need the block for this
prupose at all, it's the easiest way to get the cluster timestamp read
correctly without code duplication. In theory this could be wrong, and
a packet could start at a much later time, but in practice this won't
happen.
This commit also adds an option to disable this feature. It's not
documented because nobody should use it. (But I happen to have a need
for this.)
This affects the subtitle preroll mode during seeking. It could matter
somewhat with insane files with ten-thousands of subtitle events, which
now seem to pop up, and will avoid packet queue overflow.
Add a simplistic heuristic for detecting broken indexes. This includes
indexes with very few elements (apparently libavformat sometimes writes
such indexes, or used to), and indexes with broken timestamps.
The latter was apparently produced by very old HandBrake versions:
| + Muxing application: libmkv 0.6.1.2
| + Writing application: HandBrake 0.9.1
These broken files seem to be common enough that libavformat added a
workaround for them in 2008 (and maybe again in 2015). Apparently all
timestamps are multiplied with the file's tc_scale twice, and FFmpeg
attempts to fix them. We should throw away the whole thing.
Actually, this never happened, because there's logic for ignoring
duplicate header elements (which includes the seek index). This is
mostly for robustness and readability.
This doesn't work too well if sections of the file change to a different
framerate. It lowers our chances to guess the correct FPS in the display
sync code.
For normal playback, this (probably) doesn't help that much anyway,
except that the "estimated-vf-fps" property will regress in the simplest
mkv case. This will be fixed with the next commit.
The now disabled code will probably be removed; it's not useful anymore.
Handle a relatively recently introduced hack, that allows FLAC audio to
have arbitrary channel layouts, instead of just the predefined fixed
ones. This is actually supported by FFmpeg, but since the demuxer
(instead of the decoder) handles this in FFmpeg, we need to add special-
code to our mkv demuxer.
(The way FFmpeg does this seems a bit backwards, since now every demuxer
for a format that can handle FLAC needs to contain this logic as well.)
The FLAC hack is relatively terrible: we need to parse the FLAC headers,
look for a VorbisComment, parse the VorbisComment, and then retrieve
the magic WAVEFORMATEXTENSIBLE_CHANNEL_MASK entry. But the hack is
officially endorsed, as the official FLAC tools use it. (Although I
couldn't find a trace of it in the format specification. Should I be
surprised?)
Extend the --demuxer-mkv-probe-video-duration behavior to work with
files that are partial and are missing an index. Do this by finding a
cluster 10MB before the end of the file, and if that fails, just read
the entire file. This is actually pretty trivial to do and requires only
5 lines of code.
Also add a mode that always reads the entire file to estimate the video
duration.
If the EditionFlagOrdered is set, chapters without ChapterTimeEnd make
no sense. Ordered chapters will play the chapters in the order they
appear, but will play the ranges the chapters cover. So if the end time
is missing, the range is incomplete and it's not clear what should be
played. If you assume the start of the next chapter as end time, the
ordered flag will have no observable effect, so that's not a useful
assumption.
This fixes playback of a file which (apparently) had the
EditionFlagOrdered set accidentally, with normal chapters.
At least Matroska files have a "forced" flag (in addition to the
"default" flag). Export this flag. Treat it almost like the default
flag, but with slightly higher priority.
The "FrameRate" element is probably deprecated (it's greyed out in the
"spec", and described as "Informational only" in bold). Normally files
use DefaultDuration. In fact, the FrameRate field was preferred over
DefaultDuration for determining framerate if present. Do not do this and
rely on DefaultDuration only.
Also, if no framerate is set, do not assume PAL (25 FPS). Such a
fallback makes little sense and will cause more problems than it solves.
Use char* for strings instead of bstr (data ptr + length pair). Matroska
actually (probably) allows "padding" strings with \0 bytes, so using
normal C strings instead of byte strings is more appropriate.
MPlayer traditionally had completely separate sh_ structs for
audio/video/subs, without a good way to share fields. This meant that
fields shared across all these headers had to be duplicated. This commit
deduplicates essentially the last remaining duplicated fields.
Always use the already existing extradata[_len] variable, instead of the
awkward switch between manually changed extradata and falling back to
passing through extradata at the end.
The only decoders I could find and which (possibly) require this field
are codecs which can be used via VfW only, and realaudio sipr. For VfW
we still passthrough this field.
Native Matroska codec support has to map the Matroska codec IDs to
libavcodec ones, and also has to undo codec-specific Matroska
strangeness, such as restoring AAC extradata and realaudio handling. The
VfW codec support doesn't need it, because AVI maps well enough to
libavcodec conventions (possibly because AVI was a dominant codec when
libavcodec was created). But there's still some need for generic codec
handling, such as enabling parsers and messing with various codec
parameters.
Separate these two, and move the parts which are guaranteed not to be
needed by VfW to the if-else tree that handles the VfW case
("A_MS/ACM"), making the cases exclusive.
(This should probably be done more radically, since it's very unlikely
that we should or have to mess with the VfW parameters at all - they
should just be passed through to the decoder.)
This removes the last traces of the old MPlayer FourCC-based codec
mapping code. Forcing all codec IDs through a FourCC table and then
back to codec names was confusing at best, so this is a nice cleanup.
Handling of PCM (non-VfW case) is redone to some degree.
Handling of AC3 is moved below realaudio handling, since "A_REAL/DNET"
is apparently AC3, and we must not skip realaudio-specific handling.
(It seems unlikely that anything would actually break, but on the other
hand I don't have any A_REAL/DNET samples for testing.)
Instead of explicitly matching all the specific AAC codec names, just
match them all as prefix.
Some codecs don't need special handling other than their mapping
entries, so they fall away (like Vorbis and Opus).
The prores check in mkv_parse_and_add_packet() is not strictly related
to this, but is done for consistency with the wavpack check above.
The existing code avoided doing this for some codecs. I see no point in
this, and it seems the original reason this exists was due to some
cleanup in 2007. libavformat doesn't do this. So just drop it.
It's well possible that we've always ended up invoking the
AV_CODEC_ID_MPEG1VIDEO codec, but it's hard to tell. Mangling everything
through FourCCs (and then back) makes it hard to analyze. Also,
libavformat's Matroska demuxer uses AV_CODEC_ID_MPEG2VIDEO here, so it
should be quite safe to do anyway.
Inherited from MPlayer times, we used FourCCs to identify video codecs.
This was later changed to libavcodec codec names (which made life a
whole lot simpler). But demux_mkv still uses FourCCs a lot.
Change this for video. It's pretty simple, because some preparation was
done in the past. We just have to replace some "internal" FourCCs with
different handling.
One potentially complicated issue is that there is no natural way to
set the sh->format (AVCodecContext.codec_tag) field anymore. Most
decoders do not need it, though mjpeg is an exception.
Note that the AVI compatibility code still requires codec mappings, but
these are provided by FFmpeg. Also, the audio code is not changed.
For the MKV_V_MPEG2 -> mpeg1video thing see next commit.
The options don't change, but they're now declared and used privately by
demux_mkv.c. This also brings with it a minor refactor of the subpreroll
seek handling - merge the code from playloop.c into demux_mkv.c. The
change in demux.c is pretty much equivalent as well.
This change allows forward seeking even if there are no more video
keyframes in forward direction. This helps with files that e.g. encode
cover art as a single video frame (within a _real_ video stream - ffmpeg
seems to like to produce such files). Seeking backwards will still jump
to the nearest video frame, so this improvement has limited use.
The old code didn't do this because of the logic the min_diff variable
followed. Instead of somehow using the timestamp of the last packet read
for min_diff, use the first index entry for it. This actually makes it
fall back to the first/last index entry as the (removed) comment claims.
Note that last_pts is basically random at this point (because the
demuxer can be far ahead of playback position), so this didn't make
sense in the first place.
Check async abort notification. libavformat already do something
equivalent.
Before this commit, the demuxer could enter resync mode (and print silly
warning messages) when the stream stopped returning data because of an
abort.
A user reported a webm stream that couldn't be played. The issue was
that this stream 1. was on an unseekable HTTP connection, and 2. had a
SeekHead element (wtf?). The code reading the SeekHead marked the
element as unreadable too early: although you can't seek in the stream,
reading the header elements after the SeekHead read them anyway. Marking
them as unreadable only after the normal header reading fixes this.
(The way the failing stream was setup was pretty retarded: inserting
these SeekHead elements makes absolutely no sense for a stream that
cannot be seeked.)
Fixes#1656.