0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 12:02:23 +02:00
Commit Graph

204 Commits

Author SHA1 Message Date
wm4
de0f3747ee demux: fix dropped subtitle packets with the new stream switching
If the previous subtitle packet is too far back, and the refresh seek
won't pick it up, and the packet never comes again. As a consequence,
the refresh mode was never stopped on the subtitle stream, which caused
all packets to be discarded.

Fix by assuming the file position is monotonically increasing; then it
will resume even if a packet _after_ the intended resume point is
returned. This introduces a new requirement on how the demuxer behaves.
(I'm not sure if mp4 actually satisfies this requirement in all cases.)

Fixes a regression introduced by commit f9f2e1cc.
2015-02-14 14:29:21 +01:00
wm4
f9f2e1cc4e demux: hack for instant stream switching
This removes the delay when switching audio tracks in mkv or mp4 files.
Other formats are not enabled, because it's not clear whether the
demuxers fulfill the requirements listed in demux.h. (Many formats
definitely do not with libavformat.)

Background:

The demuxer packet cache buffers a certain amount of packets. This
includes only packets from selected streams. We discard packets from
other streams for various reasons. This introduces a problem: switching
to a different audio track introduces a delay. The delay is as big as
the demuxer packet cache buffer, because while the file was read ahead
to fill the packet buffer, the process of reading packets also discarded
all packets from the previously not selected audio stream. Once the
remaining packet buffer has been played, new audio packets are available
and you hear audio again.

We could probably just not discard packets from unselected streams. But
this would require additional memory and CPU resources, and also it's
hard to tell when packets from unused streams should be discarded (we
don't want to keep them forever; it'd be a memory leak).

We could also issue a player hr-seek to the current playback position,
which would solve the problem in 1 line of code or so. But this can be
rather slow.

So what we do in this commit instead is: we just seek back to the
position where our current packet buffer starts, and start demuxing from
this position again. This way we can get the "past" packets for the
newly selected stream. For streams which were already selected the
packets are simply discarded until the previous position is reached
again.

That latter part is the hard part. We really want to skip packets
exactly until the position where we left off previously, or we will skip
packets or feed packets to the decoder twice. If we assume that the
demuxer is deterministic (returns exactly the same packets after a seek
to a previous position), then we can try to check whether it's the same
packet as the one at the end of the packet buffer. If it is, we know
that the packet after it is where we left off last time.

Unfortunately, this is not very robust, and maybe it can't be made
robust. Currently we use the demux_packet.pos field as unique packet
ID - which works fine in some scenarios, but will break in arbitrary
ways if the basic requirement to the demuxer (as listed in the demux.h
additions) are broken. Thus, this is enabled only for the internal mkv
demuxer and the libavformat mp4 demuxer.

(libavformat mkv does not work, because the packet positions are not
unique. Probably could be fixed upstream, but it's not clear whether
it's a bug or a feature.)
2015-02-13 21:17:17 +01:00
wm4
00b2611352 command: export more details about file seekability
If a file is unseekable (consider e.g. a http server without resume
functionality), but the stream cache is active, the player will enable
seeking anyway. Until know, client API user couldn't know that this
happens, and it has implications on how well seeking will work. So add a
property which exports whether this situation applies.

Fixes #1522.
2015-01-26 13:46:33 +01:00
wm4
966f0a41a4 demux_disc: pass seek flags to stream layer
Pass through the seek flags to the stream layer. The STREAM_CTRL
semantics become a bit awkward, but that's still the least awkward
part about optical disc media.

Make demux_disc.c request relative seeks. Now the player will use
relative seeks if the user sends relative seek commands, and the
demuxer announces it wants these by setting rel_seeks to true. This
change probably changes seek behavior for dvd, dvdnav, bluray, cdda,
and possibly makes seeking useless if the demuxer-cache is set to
a high value.

Will be used in the next commit. (Split to make reverting the next
commit easier.)
2015-01-19 21:26:48 +01:00
wm4
c8052da7de demux: return EOF when reading from unselected stream
Normally the player doesn't read from unselected streams, so this should
be a no-op. But unfortunately, some broken files can severely confuse
the player, and assign the same demuxer stream to multiple front-end
tracks. Then selecting one of the tracks would deselect the other track,
with the end result that the demuxer stream for the selected track is
deselected. This could happen with mkv files that use the same track
number (which is of course broken). timeline_set_part() sets the tracks
using demuxer_stream_by_demuxer_id(), using the broken non-unique IDs.

The observable effect was that the player never quit, because
demux_read_packet_async() told the caller to wait some longer for new
packets. Fix by returning EOF instead.

Fixes #1481.
2015-01-16 20:22:43 +01:00
wm4
8eaa63689a demux_mf: move mf.c contents to demux_mf.c
There's no reason why parts of this demuxer would be in a separate
source file. The existence of this code is already somewhat questionable
anyway, so it may as well be dumped into a single file.

Even stranger that demux.c included mf.h for no reason (it was an
artifact from 2002 when the architecture was uncleaner).
2014-12-29 23:09:50 +01:00
wm4
d17c3b63c3 command: add properties for current bitrate
Fixes #1192.
2014-12-12 01:00:58 +01:00
wm4
47452443c5 demux: don't always make --cache-secs override --demuxer-readahead-secs
It's confusing. Whether the new behavior is less confusing... whatever.
2014-12-12 01:00:51 +01:00
wm4
7df2632f71 demux: silence unseekable message
This message was added in commit a0acb6ea. But it showed up in all sorts
of inappropriate contexts, such as when opening m3u from an unseekable
http URL, or playing DVDs. So I guess this didn't work out. Disabling it
again.
2014-12-05 23:58:04 +01:00
wm4
e1788384cc demux: explicitly wake up playback thread on metadata change etc.
Probably doesn't matter much in practice.
2014-12-04 22:42:07 +01:00
wm4
b723cab19d demux: don't print message if replaygain tags were not found
Even thouhg it was printed in verbose mode only, it was annoying.
2014-12-04 22:42:07 +01:00
wm4
c3d6f4b63b dvd, bd: don't unnecessarily block on demuxer/stream all the time
This was completely breaking any low-level caching. Change it so that at
least demuxer caching will work.

Do this by using the metadata cache mechanism to funnel through the menu
commands.

For some incomprehensible reason, I had to reorder the events (which
affects their delivery priority), or they would be ignored. Probably
some crap about the event state being cleared before it could be
delivered. I don't give a shit.

All this code sucks. It would probably be better to let discnav.c access
the menu event "queue" directly, and to synchronize access with a mutex,
instead of going through all the caching layers, making things
complicated and slow.
2014-12-04 22:42:07 +01:00
wm4
09e08bfe2e demux: update cache state when paused
This was removed in commit 480f82fa. This caused the cache display not
to update while paused, because the update_cache() function is never
called in the thread (now I remember why the extra call was "needed").

The old implementation intentionally run update_cache() only before
waiting on a mutex, with no further checks for the condition variable.
In theory, this is strictly not sane, but since it was just for the
retrieval of the very fuzzy cache status, it was ok. Now we want to call
update_cache() outside of the mutex though - which means that in order
to avoid missed wakeups, a proper condition has to be used.
2014-11-12 21:47:41 +01:00
wm4
a821e72b81 demux: report 0s readahead time as fallback in some situations
If no packets are queued, the readahead time is obviously 0.

If the end time is smaller than the start time, the problem is probably
that audio and video start at slightly different times - report 0 in
this case too.

Do this because seeing "???" as readahead time is a bit annoying.
2014-11-05 03:03:27 +01:00
wm4
5438a8b32e demux: don't account known range for streams that are EOF
This influences the demuxer readahead display. If a stream has reached
EOF, we want to ignore it for the purpose of this calculation.

Note that if a stream contains no packets, it still should cause the
value 0s to be displayed (unless it's EOF), because that's just the
actual situation.
2014-11-03 21:59:20 +01:00
wm4
7c2c1dbe80 demux: fix PTS comparison
This was relying on the fact that timestamps will always be numerically
larger than MP_NOPTS_VALUE, but the trick didn't actually work for
MP_PTS_MIN. Be a bit more sincere, and don't rely on this anymore. This
fixes the comparison, and avoids the readahead amount displaying as
"???" in some situations (since one of the values was NOPTS).
2014-11-03 21:54:49 +01:00
wm4
71d5dd0916 demux: don't consider stream EOF an underrun
In this case, we didn't find any new packets for this stream, even
though we've read ahead as much as possible. (If reading ahead in this
case, the "Too many packets in the demuxer packet queues" error is
normally printed.)

If we do consider this an underrun, handle_pause_on_low_cache() will
pause and show the "buffering" state, which is not useful.

Could also happen on very bad interleaving.
2014-11-03 21:22:12 +01:00
wm4
969757baa0 player: always use demux_chapter
Instead of defining a separate data structure in the core.

For some odd reason, demux_chapter exported the chapter time in
nano-seconds. Change that to the usual timestamps (rename the field
to make any code relying on this to fail compilation), and also remove
the unused chapter end time.
2014-11-02 17:29:41 +01:00
wm4
06bb1e0fc4 demux: fix demux_seek signature
Probably doesn't matter much.
2014-10-29 22:47:25 +01:00
wm4
71e73b6c8e demux: move some seek flag sanitation to generic code
No reason why only demux_mkv.c should do this.
2014-10-29 22:45:21 +01:00
wm4
0da9ee79e7 demux: seek to position 0 when loading, instead of restoring it
This was originally done for DVD/BD/DVB, where the start position could
be something different from 0, and seeking back to 0 would mess it up
completely.

Since we're not quite sure that these streams are unseekable, we can
simplify this somewhat, and also make sure we also start at 0 for normal
files. Helps a little bit with the following edition reloading commit.
2014-10-28 20:30:11 +01:00
wm4
480f82fa96 demux: don't access stream while lock is held
Although this is fine when the stream cache is active (which caches
these and returns the result immediately), it seems cleaner not to
rely on this detail.

Remove the update_cache() call from demux_thread(), because it's sort
of in the way. I forgot why it exists, and there's probably no good
reason for it to exist anyway.
2014-10-24 16:04:56 +02:00
wm4
07cca2500e demux: cache STREAM_CTRL_GET_BASE_FILENAME
It's needed for some obscure feature in combination with .rar reading.
However, it's unconditionally used by the subtitle loader code, so take
care of not blocking the main thread unnecessarily.

(Untested.)
2014-10-24 15:40:01 +02:00
wm4
f0f83ff366 player: add stream selection by ffmpeg index
Apparently using the stream index is the best way to refer to the same
streams across multiple FFmpeg-using programs, even if the stream index
itself is rarely meaningful in any way.

For Matroska, there are some possible problems, depending how FFmpeg
actually adds streams. Normally they seem to match though.
2014-10-21 13:19:20 +02:00
wm4
9ba6641879 Set thread name for debugging
Especially with other components (libavcodec, OSX stuff), the thread
list can get quite populated. Setting the thread name helps when
debugging.

Since this is not portable, we check the OS variants in waf configure.
old-configure just gets a special-case for glibc, since doing a full
check here would probably be a waste of effort.
2014-10-19 23:48:40 +02:00
wm4
a0acb6eaa7 demux: print a warning if stream is not seekable 2014-10-17 18:18:20 +02:00
wm4
9e512c5a98 demux: allow increasing filepos only
The last demuxed file position (demuxer->filepos) is used to estimate
the total playback percentage in files with possible timestamp resets
(like MPEG-PS). Until know, reading from any stream set this position
freely. This makes the position jump around.

Fix this by allowing icnreasing file position only. Reset it on seeking.
With crazy formats, this still could go wrong, but there's only so much
you can do.
2014-09-03 02:00:18 +02:00
wm4
2f537bafa5 demux: get rid of old wrapper
demux_info_get() used to be central, but was turned into a wrapper, and
now there was only one caller left. Get rid of it.
2014-09-01 22:12:39 +02:00
shdown
f49099b94d demux: eliminate redundant check
pkt can't be NULL since it's initialized from ds->head, which is checked
at the beginning.
2014-08-30 15:15:37 +02:00
wm4
cb642e7c84 player: slightly better cache underrun detection
Use the "native" underrun detection, instead of guessing by a low cache
duration. The new underrun detection (which was added with the original
commit) might have the problem that it's easy for the playloop to miss
the underrun event. The underrun is actually not stored as state, so if
the demuxer thread adds a new packet before the playloop happens to see
the state, it's as if it never happened. On the other hand, this means
that network was fast enough, so it should be just fine.

Also, should it happen that we don't know the cached range (the
ts_duration < 0 case), just wait until the demuxer goes idle (i.e.
read_packet() decides to stop). This pretty much should affect broken or
unusual files only, and there might be various things that could go
wrong. But it's more robust in the normal case: this situation also
happens when no packets have been read yet, and we don't want to
consider this as reason to resume playback.
2014-08-27 23:12:49 +02:00
wm4
1c44db2992 demux: reset idle state on seeks 2014-08-27 23:12:49 +02:00
wm4
c7208319d3 player: better cache status on status line
The cache percentage was useless. It showed how much of the total stream
cache was in use, but since the cache size is something huge and
unrelated to the bitrate or network speed, the information content of
the percentage was rather low.

Replace this with printing the duration of the demuxer-cached data, and
the size of the stream cache in KB.

I'm not completely sure about the formatting; suggestions are welcome.
Note that it's not easy to know how much playback time the stream cache
covers, so it's always in bytes.
2014-08-27 23:12:47 +02:00
wm4
dad90f616d player: fix basic playback
The "buffering" logic was active even if the stream cache was disabled.
This is contrary to what the manpage says. It also breaks playback
because of another bug: the demuxer cache is smaller than 2 seconds,
and thus the resume condition never becomes true.

Explicitly run this code only if the stream cache is enabled. Also, fix
the underlying problem of the breakage, and resume when the demuxer
thread stops reading in any case, not just on EOF.

Broken by previous commit. Unbreaks playback of local files.
2014-08-27 10:59:22 +02:00
wm4
0b428e4482 player: redo how stream caching and pausing on low cache works
Add the --cache-secs option, which literally overrides the value of
--demuxer-readahead-secs if the stream cache is active. The default
value is very high (10 seconds), which means it can act as network
cache.

Remove the old behavior of trying to pause once the byte cache runs
low. Instead, do something similar wit the demuxer cache. The nice
thing is that we can guess how many seconds of video it has cached,
and we can make better decisions. But for now, apply a relatively
naive heuristic: if the cache is below 0.5 secs, pause, and wait
until at least 2 secs are available.

Note that due to timestamp reordering, the estimated cached duration
of video might be inaccurate, depending on the file format. If the
file format has DTS, it's easy, otherwise the duration will seemingly
jump back and forth.
2014-08-27 03:39:04 +02:00
wm4
a8513f8b37 demux: reduce wakeups if no cache is active
The purpose of the unconditional pthread_cond_signal() when reading
cached DEMUXER_CTRLs and STREAM_CTRLs was apparently to update the
stream cache state. Otherwise, the cached fields would never be updated
when the stream is e.g. paused.

The same could be said about other CTRLs, but these aren't as important,
since they are normally updated while reading packet data.

In order to reduce wakeups, make this logic explicit.
2014-08-27 00:20:38 +02:00
wm4
c31a91230d demux: avoid unnecessary wakeups
If a packet is appended to a stream, and there were already packets
queued, nothing about the state changed, as far as the user (i.e. the
player) is concerned. Thus no wakeup is needed.

The pthread_cond_signal() call following this is not interesting - it
will simply be a NOP if there are actually no waiters.
2014-08-24 13:21:32 +02:00
wm4
b822faa6cf demux: add option to control the readahead buffer by a duration value
--demuxer-readahead-secs now controls how much the demuxer should
readahead by an amount of seconds. This is based on the raw packet
timestamps. It's not always very exact. For example, h264 in Matroska
does not store any linear timestamps (only PTS values which are going
to be reordered by the decoder), so this heuristic is usually off by
several hundred milliseconds.

The decision whether to readahead is basically OR-ed with the other
--demuxer-readahead-packets options. Change the manpage descriptions
to subtly convey these semantics.
2014-08-16 17:10:08 +02:00
wm4
e6e3bc7cd9 demux: remove unused function 2014-08-16 17:10:08 +02:00
wm4
9dd160ea97 demux: reduce log spam if threading is disabled 2014-08-11 15:55:12 +02:00
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
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