Commit Graph

16 Commits

Author SHA1 Message Date
wm4 d1bb1bf8af demux: fix timestamp type for seek calls
mpv/mplayer2/MPlayer use double for timestamps, but the demuxer API used
float.
2014-07-21 19:29:58 +02:00
wm4 34fdf082d8 dvd, bd: fix A/V sync
Slightly less robust, but simpler, and usually guarantees that audio
and video are properly in sync.
2014-07-18 01:26:46 +02:00
wm4 9faa131959 demux: drop some unused definitions 2014-07-17 21:53:44 +02:00
wm4 1301a90761 demux: add a demuxer thread
This adds a thread to the demuxer which reads packets asynchronously.
It will do so until a configurable minimum packet queue size is
reached. (See options.rst additions.)

For now, the thread is disabled by default. There are some corner cases
that have to be fixed, such as fixing cache behavior with webradios.

Note that most interaction with the demuxer is still blocking, so if
e.g. network dies, the player will still freeze. But this change will
make it possible to remove most causes for freezing.

Most of the new code in demux.c actually consists of weird caches to
compensate for thread-safety issues (with the previously single-threaded
design), or to avoid blocking by having to wait on the demuxer thread.

Most of the changes in the player are due to the fact that we must not
access the source stream directly. the demuxer thread already accesses
it, and the stream stuff is not thread-safe.

For timeline stuff (like ordered chapters), we enable the thread for the
current segment only. We also clear its packet queue on seek, so that
the remaining (unconsumed) readahead buffer doesn't waste memory.

Keep in mind that insane subtitles (such as ASS typesetting muxed into
mkv files) will practically disable the readahead, because the total
queue size is considered when checking whether the minimum queue size
was reached.
2014-07-16 23:25:56 +02:00
wm4 23a7257cca Revert "Remove DVD and Bluray support"
This reverts commit 4b93210e0c.

*shrug*
2014-07-15 01:49:02 +02:00
wm4 4b93210e0c Remove DVD and Bluray support
It never worked well. Just remux your DVD and BD images to mkv.
2014-07-14 14:34:14 +02:00
wm4 b505cab597 dvdnav: fix time display when starting in the middle of the DVD
libdvdnav can actually jump into the middle of the DVD (e.g. scene
selection menus do that). Then time display is incorrect: we start from
0, even though playback time is somewhere else. This really matters when
seeking. If the display time mismatches, a small relative seek will
apparently jump to the beginning of the movie.

Fix this by initializing the PTS stuff on opening. We have to do this
after some small amount of data has been read from the stream (because
libdvdnav is crap and doesn't always update the time between seeks and
the first read; also see STREAM_CTRL_GET_CURRENT_TIME remarks in
cache.c; although this was not observed when testing with scene
selection menus). On the other hand, we want to do it before opening the
demuxer, because that will read large amounts of data and likely will
change the stream position.

Also see commit 49813670.
2014-07-13 20:05:25 +02:00
wm4 5b820ff1b4 dvd: potentially fix video aspect ratio
This overwrote the source stream header, instead of the stream header
exported to the decoder.
2014-07-12 20:17:19 +02:00
wm4 469ec23f85 demux_disc: flush slave demuxer packet queue on resync
Technically needed, but not strictly. It seems it works without in
practice, because demux_lavf.c reads exactly one packet for fill_buffer
call, so there are never packets queued.
2014-07-07 19:24:22 +02:00
wm4 4981367021 cache, dvd, bluray: simplify stream time handling
We used a complicated and approximate method to cache the stream
timestamp, which is basically per-byte. (To reduce overhead, it was only
cached per 8KB-block, so it was approximate.)

Simplify this, and read/keep the timestamp only on discontinuities. This
is when demux_disc.c actually needs the timestamp.

Note that caching is currently disabled for dvdnav, but we still read
the timestamp only after some data is read. libdvdread behaves well, but
I don't know about libbluray, and the previous code also read the
timestamp only after reading data, so try to keep it safe.

Also drop the start_time offset. It wouldn't be correct anymore if used
with the cache, and the idea behind it wasn't very sane either (making
the player to offset the initial playback time to 0).
2014-07-07 19:09:37 +02:00
wm4 f512604f02 dvd, bd: enable precise seeking
This should work now, at least kind of. Note that actual success depends
on the behavior of the underlying lib{dvd{nav,read},bluray}
implementation, which could go very wrong.

In the worst case, it could happen that the underlying implementation
seeks a long time before the seek target time. In this case, the player
will just decode video until the target time is reached, even if that
requires e.g. decoding 30 mintues of video before refreshing.

In the not-so-bad but still bad case, it would just miss the seek
target, and seek past it.

In my tests, it works mostly ok, though. Seeking backwards usually
fails, unless something like --hr-seek-demuxer-offset=1 is used (this
makes it seek to 1 second before the target, which may or may not be
enough to compensate for the DVD/BD imprecision).
2014-07-06 19:03:43 +02:00
wm4 7bf090ad24 dvd, bluray: handle playback display time handling differently
This is a pretty big change. Instead of doing a half-hearted passthrough
of the playback timestamp, we attempt to rewrite the raw MPEG timestamps
such that they match with the playback time.

We add the offset between raw start timestamp and playback time to the
packet timestamps. This is the easy part; but the problem is with
timestamp resets. We simply detect timestamp discontinuities by checking
whether they are more than 500ms apart (large enough for all video
faster than 2 FPS and audio with reasonable framesizes/samplerates), and
adjust the timestamp offset accordingly.

This should work pretty well. There may be some problems with subtitles.
If the first packet after a timestamp reset is a subtitle instead of
video, it will fail. Also, selecting multiple audio or video streams
won't work (but mpv doesn't allow selecting several anyway). Trying to
demux subtitles with no video stream enabled will probably fail.

Untested with Bluray, because I have no Bluray sample.

Background:

libdvdnav/libdvdread/libbluray make this relatively hard. They return a
raw MPEG (PS/TS) byte stream, and additionally to that provide a
function to retrieve the current "playback" time. The playback time is
what should be displayed to the user, while the MPEG timestamps can be
completely different. Even worse, the MPEG timestamps can reset. Since
we use the libavformat demuxer (instead of parsing the MPEG packets in
the DVD/BD code), it's hard to associate between these timestamps. As a
result, the time display is special cased in the playloop, and of low
quality (updates only all 1 or 2 seconds, sometimes is incorrect). The
fact that the stream cache can be between demuxer and the stream source
makes things worse.

All the libs seem to provide an event that tells whether timestamps are
resetting. But since this signalling is byte based, it's hard to connect
it to the demuxed MPEG packets. It might be possible to create some sort
of table mapping file positions to discontinuities and new timestamps.
(For simplicity, this table could be 2 entries large, sufficient to
catch all discontinuities if the distance between them is larger than
the total buffering.)
2014-07-06 19:03:12 +02:00
wm4 e3a3b764c8 dvd: fix first subtitle with delayed subtitle streams
This was accidentally broken with moving the DVD code to demux_disc.c.

Also remove an abort() call meant for debugging.
2014-07-06 19:02:49 +02:00
wm4 de28876222 demux: minor simplification
Oops, should have been part of commit 37085788.
2014-07-06 19:02:21 +02:00
wm4 37085788e4 demux: minor simplification to internal API
Also some other unrelated minor changes.
2014-07-05 17:07:15 +02:00
wm4 338004bcfc dvd, bluray, cdda: add demux_disc containing all related hacks
DVD and Bluray (and to some extent cdda) require awful hacks all over
the codebase to make them work. The main reason is that they act like
container, but are entirely implemented on the stream layer. The raw
mpeg data resulting from these streams must be "extended" with the
container-like metadata transported via STREAM_CTRLs. The result were
hacks all over demux.c and some higher-level parts.

Add a "disc" pseudo-demuxer, and move all these hacks and special-cases
to it.
2014-07-05 17:07:15 +02:00