1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 01:22:30 +00:00
Commit Graph

470 Commits

Author SHA1 Message Date
wm4
1483fd443a demux: fix playback abort if --demuxer-thread is not used
Switching tracks caused cached_demux_control() to catch the command to
switch tracks, even if no thread was running. Thus, the tracks were
never really switched, and EOF happened immediately on playback start.

Fix it by not using the cache at all if the demuxer thread is disabled.
The cache code still has to be called somewhere, though, because it
handles stream metadata update.

Regression from today.
2014-08-07 00:34:14 +02:00
wm4
64e1132d39 demux: make track switching asynchronous
Because why not.

This can lead to reordering of operations between seeking and track
switching (happens when the demuxer wakes up after seek and track
switching operations were queued). Do the track switching strictly
before seeks if there is a chance of reordering, which guarantees that
the seek position will always start with key frames. The reverse
(seeking, then switching) does not really have any advantages.

(Not sure if the player relies on this behavior.)
2014-08-06 20:30:47 +02:00
wm4
d68a759fa4 Improve setting AVOptions
Use OPT_KEYVALUELIST() for all places where AVOptions are directly set
from mpv command line options. This allows escaping values, better
diagnostics (also no more "pal"), and somehow reduces code size.

Remove the old crappy option parser (av_opts.c).
2014-08-02 03:12:33 +02:00
wm4
0dd5228626 demux_lavf: don't consider EAGAIN as EOF condition
This happens apparently randomly with rtmp:// and after seeks. This
eventually leads to audio decoding returning an EOF status, which
basically disables audio sync. This will lead to audio desync, even if
audio decoding later "recovers" when the demuxer actually returns audio
packets.

Hack-fix this by special-casing EAGAIN.
2014-07-30 03:32:56 +02:00
wm4
6856d81c68 stream: hack-fix rtmp-level seeking
This didn't work, because the timebase was wrong. According to the
ffmpeg doxygen, if the stream index is -1 (which is what we used), the
timebase is AV_TIME_BASE. But this didn't work, and it really expected
the stream's timebase. Quite "surprising", since this feature
(avio_seek_time) is used by rtmp only.

Fixing this properly is too hard, so hack-fix our way around it.
STREAM_CTRL_SEEK_TO_TIME is also used by DVD/BD, so a new
STREAM_CTRL_AVSEEK is added. We simply pass-through the request
verbatim.
2014-07-30 02:21:51 +02:00
wm4
6b928fa2a0 demux_mf: allow seeking past the end
How's this for a corner case.
2014-07-30 00:23:16 +02:00
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
4b4bd9e5f7 demux: asynchronous seeking
This tells the demuxer thread that it should seek, instead of waiting
until the demuxer thread is ready.

Care has to be taken about the state between seek request and actual
seeking: newly demuxed packets have to be discarded. We can't just
flush when doing the actual seek, because the user thread could read
these packets.

I'm wondering if this could lead to issues due to relaxed ordering of
operations. But it should be fine, since seeking influences packet
reading only, and seeking is always strictly done before that.

Currently, this will have no advantages; unless audio is disabled. Then
seeking as well as normal playback can be non-blocking.
2014-07-21 19:29:50 +02:00
wm4
5526603a43 demux: don't start reading if no packets were requested yet
Instead of starting to fill the packet queue if at least 1 stream is
selected, wait until there is at least 1 stream had new packets
requested.

In theory this is cleaner, because it allows you to e.g. do a seek and
then reselect streams without losing packets. Seeking marks all streams
as inactive, and without this new logic, the thread would read new
packets anyway right after seek.
2014-07-20 20:13:08 +02:00
wm4
ded02bb78c demux: make the cache refresh cached STREAM_CTRLs
This fixes the same symptom as the previous commit, but when the demuxer
thread is enabled. In this case, if nothing was read from the demuxer,
the STREAM_CTRLs weren't updated either. To the player, this looked like
the stream cache was never making progress, so playback was kept paused.
2014-07-20 00:19:58 +02:00
wm4
887140b7d4 demux: fix a corner case (2)
It can happen that read_packet() doesn't read a packet, even if it
succeeds. Typically this is because a packet was read, but then thrown
away, because it's not part of a selected stream. The result would be a
bogus EOF condition.

Fix by explicitly checking for EOF.
2014-07-19 12:34:07 +02:00
wm4
cfdb1312da demux: ensure demux_read_packet_async() always reads
In corner cases, it might be possible that a demux_read_packet_async()
call fails to make the demuxer thread to read more packets.

If a packet is queued, the function will simply return a packet, without
marking the stream as active. As a consequence, read_packet() might
decide not to read any further packets, and the demuxer will never read
a packet and wake up the playback thread.

This was originally done to align it with demux_read_packet() semantics;
just drop this.
2014-07-19 12:27:25 +02:00
wm4
24efaa3ad7 demux: fix a corner case
demux_read_any_packet() attempts to call read_packet(), but if no stream
is active, it can decide not to read anything. The function will return
NULL, which implies EOF. Fix this by explicitly
setting demux_stream->active if needed.

Also use dequeue_packet() instead of demux_read_packet(), because it's
cleaner. (Shouldn't change behavior.)

Possibly fixes #938.
2014-07-19 12:27:21 +02:00
wm4
1942e424e3 demux: fix opening pipes with demux_lavf
We told the demuxer that a pipe (if stream cache is enabled) is
seekable. This is because the stream cache is technically seekable, it's
just that seeking may fail at runtime if a non-cached byte range is
requested.

This caused libavformat to issue seeks on initialization (at least when
piping mp4 youtube videos). Initialization failed completely after
spamming tons of error messages.

So, if an unseekable stream is cached, tell the demuxer that the file is
not seekable. This gets reversed later (when printing a message about
caching an unseekable stream), so the user can still try his luck by
issuing a seek command. The important part is that libavformat
initialization will not take code paths that will unnecessarily seek for
whatever reasons.

CC: @mpv-player/stable: regression from 0.3.x
2014-07-18 16:16:05 +02:00
wm4
848546f2de demux: fix problems with EOF
It was easy to get into a wakeup feedback loop on EOF. The reason that
EOF is complicated is that we try to retry reading when EOF is reached,
in case the EOF state actually disappears (e.g. when watching a
currently downloaded file).

This feature is probably worthless, since in practice you have to do a
seek to "unstuck" it anyway, but since the old code also did this, we
want to keep this behavior for now.

Avoid the feedback loop by introducing another EOF flag (last_eof), that
contains the actual previous EOF state, and is not overwritten when
retrying reading. Wakeup is skipped if the EOF state didn't change.

Also, actually call the wakeup callback when EOF is detected.

The line that adds "ds->active = false;" actually does nothing, but in
theory it's cleaner.
2014-07-18 15:08:38 +02:00
wm4
152a099c3a demux: add function to read packets asychronously 2014-07-18 15:08:31 +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
1d7a68d75c demux: fix debug log output
It printed the PTS instead of the DTS.
2014-07-17 22:03:12 +02:00
wm4
9faa131959 demux: drop some unused definitions 2014-07-17 21:53:44 +02:00
wm4
30542456c3 demux_lavf: reverse rotation direction with new API
The old FFmpeg API and the new Libav API disagree about mp4 display
rotation direction. Well, whatever, fix it trial-and-error-style.

CC: @mpv-player/stable: add
2014-07-17 00:30:03 +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
c129e3f666 demux_lavf: don't let metadata update mess up ogm playback
For OGG audio files, we usually merge the per-stream metadata back to
the file-global metadata. Don't do that for OGM, because with OGM most
metadata is actually per-stream.
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
f8c2dd1b78 build: include <strings.h> for strcasecmp()
It happens to work without strings.h on glibc or with _GNU_SOURCE, but
the POSIX standard requires including <strings.h>.

Hopefully fixes OSX build.
2014-07-10 08:29:32 +02:00
wm4
93f63214e0 demux: remove accurate_seek field
It's unused now. (Only the dvd code used it until recently.)
2014-07-08 22:20:39 +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
19dde186a0 demux: print initial metadata
This was accidentally broken in 7e209185, and metadata was printed only
when it changed.
2014-07-07 18:00:41 +02:00
wm4
acd60736ef Remove stream_pts stuff
This was used by DVD/BD, but its usage was removed with one of the
previous commits.
2014-07-06 19:05:59 +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
f3604fc3fb demux: fix a corner case related to demux_disc
It can happen that demux_fill_buffer() adds more than 1 packet, and then
the packets would add up. Affects demux_disc.c only (nothing else uses
this function).
2014-07-06 19:02:58 +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
54a4a25fe9 tv: move demuxer parts to separate file
Now all demuxer implementations (at least demuxer API-wise) are in the
demux directory.
2014-07-05 17:07:15 +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
de71b50249 dvd: move angle switching code
No need to provide a "nice" API for it; just do this stuff directly in
the command code.
2014-07-05 17:07:15 +02:00
wm4
0cc3594623 dvd: flush buffers properly on seek
Suggested by tholin on github issue #882.

This is not entirely clean, but the fields we're accessing might be
considered internal to libavformat. On the other hand, existence of the
fields is guaranteed by the ABI, and nothing in the libavformat doxygen
suggestes they're not allowed to be accessed.

CC: @mpv-player/stable
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
wm4
942619c779 demux: set filepos field when dequeuing a packet
Otherwise the position can be too far ahead.
2014-07-05 17:07:15 +02:00
wm4
85eb2bee3a demux: cosmetics: minimize code 2014-07-05 17:07:15 +02:00
wm4
8d40b1e8ab demux: make start time a simple field
Simpler, especially for later changes.
2014-07-05 17:07:15 +02:00
wm4
7e209185f1 demux, stream: change metadata notification
(Again.)

This time, we simply make it event-based, as it should be. This is done
for both demuxer metadata and stream metadata.

For some ogg-over-icy streams, 2 updates are reported on stream start.
This is because libavformat reports an update right on start, while
including the same info in the "static" metadata. I don't know if that's
a bug or a feature.
2014-07-05 17:07:14 +02:00
wm4
58880c00ee demux: make replaygain per-track
It's unlikely that files with multiple audio tracks and with replaygain
actually happen, but this change might help avoid minor corner cases
with later changes.
2014-07-05 17:07:14 +02:00
wm4
a97256c1d5 demux: move packet functions to a separate source file 2014-07-05 17:07:14 +02:00
wm4
e4221f3189 demux: move packet list functions
Move them to the only place where they are used, demux_subreader.c.
2014-07-05 17:07:14 +02:00
wm4
18e6d07612 demux_lavf: for now, ignore the new libavformat image demuxers
Recently, libavformat added demuxers to open image files like normal
demuxers. This is a good thing, but for now they interfere with the
operation of demux_mf. Add them to the blacklist until there is a proper
solution.

(The list doesn't contain _all_ recognized image formats, just those
that might interfere with demux_mf.)

CC: @mpv-player/stable
2014-07-05 17:07:14 +02:00