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
In my opinion this is not really necessary, since there's only a single
user of update_video(), but others reading this code would probably hate
me for using magic integer values instead of symbolic constants.
This should be a purely cosmetic commit; any changes in behavior are
bugs.
Instead of blocking on the demuxer when reading a packet, let packets be
read asynchronously. Basically, it polls whether a packet is available,
and if not, the playloop goes to sleep until the demuxer thread wakes it
up.
Note that the player will still block for I/O, because audio is still
read synchronously. It's much harder to do the same change for audio
(because of the design of the audio decoding path and especially
initialization), so audio will have to be done later.
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.
Mouse cursor handling, --heartbeat-cmd, and OSD messages basically
relied on polling. For this reason, the playloop always used a small
timeout (not more than 500ms).
Fix these cases, and raise the timeout to 100 seconds. There is no
reason behind this number; for this specific purpose it's as close to
infinity as any other number.
On MS Windows, or if vo_sdl is used, the timeout remains very small.
In these cases the GUI code doesn't do proper event handling in the
first place, and fixing it requires much more effort.
getch2_poll() still does polling, because as far as I'm aware no event-
based way to detect this state change exists.
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
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.
There was confusion about what should go into audio pts calculation and
what not (mainly due to the audio push thread). This has been fixed by
using the playing - not written - audio pts (which properly takes into
account the ao's buffer), and incrementing the samples count only by the
amount of samples actually taken from the buffer (unfortunately this
now forces us to keep the lock too long for my taste).
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.
Until now, changing the properties showed the VO colorspace parameters
on OSD. This didn't work quite well, because it showed the VO parameters
_before_ the change. This is because at least one video frame with the
new parameters has to be shown, and this doesn't happen right after
changing the property, but a bit later.
Also fix a random typo in unrelated code.
The final goal is all mp_msg calls produce complete lines. We want this
because otherwise, race conditions could corrupt the terminal output,
and it's inconvenient for the client API too. This commit works towards
this goal. There's still code that has this not fixed yet, though.
demux_seek() actually doesn't return seek success. Instead, it fails if
the demuxer is flagged as unseekable (but this is checked explicitly at
the beginning of this function), or if the seek target PTS is
MP_NOPTS_VALUE (which can never happen).
No reason to wait until the audio has been played. This isn't a problem
with gapless audio disabled, and since gapless is now default, this
behavior might be perceived as regression.
CC: @mpv-player/stable
Logic for this was missing from pull.c. For push.c it was missing if the
driver didn't support it. But even if the driver supported it (such as
with ao_alsa), strange behavior was observed by users. See issue #933.
Always check explicitly whether the AO is in paused mode, and if so,
don't drain.
Possibly fixes#933.
CC: @mpv-player/stable
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.
Happens when playing from a pipe.
Note that seeking forward doesn't work. It would be possible to create a
workaround for that by reading and skipping data until the target
position is reached (and writing the skipped data into the cache file),
but I'm not sure about that.
Fixes#928.
CC: @mpv-player/stable
There is no standard mechanism for detecting endianess. Doing it at
compile time in a portable way is probably hard. Doing it properly
with a configure check is probably hard too. Using the endian
definitions in <sys/types.h> (usually includes <endian.h>, which is
not available everywhere) works under circumstances, but the previous
commit broke it on OSX.
Ideally all code should be endian dependent, but that is not possible
due to the dependencies (such as FFmpeg, some video output APIs, some
audio output APIs).
Create a header osdep/endian.h, which contains various fallbacks.
Note that the last fallback uses libavutil; however, it's not clear
whether AV_HAVE_BIGENDIAN is a public symbol, or whether including
<libavutil/bswap.h> really makes it visible. And in fact we don't want
to pollute the namespace with libavutil definitions either. Thus it's
only the last fallback.
_GNU_SOURCE defines the kitchen sink, and also prefers glibc definitions
where glibc and POSIX conflict. Even though POSIX is worth less than
toilet paper, we still prefer the POSIX definitions.
rar.c needs asprintf(), which is _GNU_SOURCE-only. So we define
_GNU_SOURCE too specifically for this file.
This approach is similar to what other vo_opengl backends do. It can also be
used in the future to create another cocoa backend that renders offscreen
with IOSurfaces or FBOs.
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.