For clang, it's enough to just put (void) around usages we are
intentionally ignoring the result of.
Since GCC does not seem to want to respect this decision, we are forced
to disable the warning globally.
This code evolved into an ifdef mess as support for cancellation on
Windows was added. Make the Windows-specific code completely separate.
It looks cleaner, and it also means that some of the posix code is not
uselessly enabled on Windows. The latter made msvcrt.dll output warnings
because it does not like -1 passed as FD to read/write. (The same would
be harmless on POSIX.)
This is only for specific Hauppage cards. According to the comments in
who is actively using this feature. Get it out of the way.
Anyone who still wants to use this should complain. Keeping this code
would not cause terribly much additional work, and it could be restored
again. (But not if the request comes months later.)
Don't print the URL that is opened twice. stream.c and stream_lavf.c
each printed it once. Remove the logging from stream_lavf.c, and move
the log call to a more interesting point.
This works similar to the existing .rar support, but uses libarchive.
libarchive supports a number of formats, including zip and (most of)
rar.
Unfortunately, seeking does not work too well. Most libarchive readers
do not support seeking, so it's emulated by skipping data until the
target position. On backwards seek, the file is reopened. This works
fine on a local machine (and if the file is not too large), but will
perform not so well over network connection.
This is disabled by default for now. One reason is that we try
libarchive on every file we open, before trying libavformat, and I'm not
sure if I trust libarchive that much yet. Another reason is that this
breaks multivolume rar support. While libarchive supports seeking in
rar, and (probably) supports multivolume archive, our support of
libarchive (probably) does not. I don't care about multivolume rar, but
vocal users do.
This code does not know whether the stream supports reconnecting until
STREAM_CTRL_RECONNECT is called. So the message should be printed after
it. To avoid that reconnects that succeed on the first try go unnoticed,
print a warning on success.
I think this is what I alwass missed ever since I found the MPlayer
cache options: a way to enable the cache on local files with the default
settings, whatever they are.
Seems appropriate, and will probably avoid performance surprises with
scary architectures which don't have trivial implementations for atomic
loads. (Consider that demux_mkv calls this very often now, and
libavformat demuxers and streams did this for a while now.)
It was possible to make the player play local files by putting rar://
links into remote playlists, and some other potentially unsafe things.
Redo the handling of it. Now the rar-redirector (the thing in
demux_playlist.c) sets disable_safety, which makes the player open any
playlist entries returned. This is fine, because it redirects to the
same file anyway (just with different selection/interpretation of the
contents). On the other hand, rar:// itself is now considered fully
unsafe, which means that it is ignored if found in normal playlists.
Refactors an older hack, which for some reason used a more complicated
way. This generates the playlist representing the contents of the rar
file in demux_playlist.c. The pseudo-demuxer could easily be separate
from the the playlist parsers (and in fact there's almost no shared
code), but I don't think this obscure feature deserves a separate file.
Sample files created with:
rar a -v20000k -m0 files.rar file1.mkv file1.mkv
Most things stopped using this field for better support of growing
files. Go through the trouble to repalce the remaining uses, so it can
be removed.
Also move the "streaming" field; saves 4 bytes (wow!).
Fix return types and return values to make them more consistent. Some
reformatting and making code more concise.
In stream_reconnect(), avoid the additional mp_cancel_test() call by
moving the "connection lost" message below the mp_cancel_wait() call,
which effectively leads to the same behavior when the stream was already
canceled. (The goal is not to show the message in this case.)
Merge stream_seek_long() into stream_seek(). It was the only caller.
Always clear the eof flag on seeks.
Reduce access to stream internals in cache.c and stream_lavf.c.
In my opinion, libavformat should be doing this. But a patch handling a
very safe case rejected, so I suppose we have to do it manually. (This
patch was only escaping spaces, which can never work because they break
the basic syntax of the HTTP protocol.)
This commit attempts to do 2 things:
- Try to guess whether libavformat will use the URL for http. This is
not always trivial, because some protocols will recursively pass part
of the user URL to http in some way.
- Try to fix invalid URLs. We fix only the simplest case: only
characters that are never valid are escaped. This excludes invalid
escape codes, which happen with freestanding '%' characters.
Fixes#1495.
...because everything is terrible.
strerror() is not documented as having to be thread-safe by POSIX and
C11. (Which is pretty much bullshit, because both mandate threads and
some form of thread-local storage - so there's no excuse why
implementation couldn't implement this in a thread-safe way. Especially
with C11 this is ridiculous, because there is no way to use threads and
convert error numbers to strings at the same time!)
Since we heavily use threads now, we should avoid unsafe functions like
strerror().
strerror_r() is in POSIX, but GNU/glibc deliberately fucks it up and
gives the function different semantics than the POSIX one. It's a bit of
work to convince this piece of shit to expose the POSIX standard
function, and not the messed up GNU one.
strerror_l() is also in POSIX, but only since the 2008 standard, and
thus is not widespread.
The solution is using avlibc (libavutil, by its official name), which
handles the unportable details for us, mostly. We avoid some pain.
In addition to the messed-up expression, the endianness was also
inverted. The code reads big endian by default.
It "worked" by coincidence, but for little endian, codepoints outside of
latin1 were broken.
The broken expression was found by Coverity.
stream_rar.c peeks the first few bytes when trying to open, which means
that opening any stream reads at least 2KB of data (internal buffer
size) on opening. This broke --stream-dump, which saved only the data
following this initial buffer.
Hack it around by writing the current buffer to the capture file too,
and move stream_capture_write() above stream_set_capture_file() for this
purpose.
Cleaner solutions might include: handling the terrible rar thing
differently, or using the "proper" stream API for dumping. (The latter
is not done, because --stream-dump shares code with the --stream-capture
misfeature.)
Fixes#1215.
On win32, open() is a function-like macro. The line of code changed
with this commit accidentally expanded the macro. Prevent this macro
expansion. Not sure why that happened now. Since as far as I remember
system functions can be defined as macros, this affects in theory not
only win32.
Because 1) Lua is terrible, and 2) popen() is terrible. Unfortunately,
since Unix is also terrible, this turned out more complicated than I
hoped. As a consequence and to avoid that this code has to be maintained
forever, add a disclaimer that any function in Lua's utils module can
disappear any time. The complexity seems a bit ridiculous, especially
for a feature so far removed from actual video playback, so if it turns
out that we don't really need this function, it will be dropped again.
The motivation for this commit is the same as with 8e4fa5fc.
Note that there is an "#ifndef __GLIBC__". The GNU people are very
special people and thought it'd be convenient to actually declare
"environ", even though the POSIX people, which are also very special
people, state that no header declares this and that the user has to
declare this manually. Since the GNU people overtook the Unix world with
their very clever "embrace, extend, extinguish" strategy, but not 100%,
and trying to build without _GNU_SOURCE is hopeless; but since there
might be Unix environments which support _GNU_SOURCE features partially,
this means that in practice "environ" will be randomly declared or not
declared by system headers. Also, gcc was written by very clever people
too, and prints a warning if an external variable is declared twice (I
didn't check, but I suppose redeclaring is legal C, and not even the gcc
people are clever enough to only warn against a definitely not legal C
construct, although sometimes they do this), ...and since we at mpv hate
compiler warnings, we seek to silence them all. Adding a configure test
just for a warning seems too radical, so we special-case this against
__GLIBC__, which is hopefully not defined on other libcs, especially not
libcs which don't implement all aspects of _GNU_SOURCE, and redefine
"environ" on systems even if the headers define it already (because they
support _GNU_SOURCE - as I mentioned before, the clever GNU people wrote
software THAT portable that other libcs just gave up and implemented
parts of _GNU_SOURCE, although probably not all), which means that
compiling mpv will print a warning about "environ" being redefined, but
at least this won't happen on my system, so all is fine. However, should
someone complain about this warning, I will force whoever complained
about this warning to read this ENTIRE commit message, and if possible,
will also force them to eat a printed-out copy of the GNU Manifesto, and
if that is not enough, maybe this person could even be forced to
convince the very clever POSIX people of not doing crap like this:
having the user to manually declare somewhat central symbols - but I
doubt it's possible, because the POSIX people are too far gone and only
care about maintaining compatibility with old versions of AIX and HP-UX.
Oh, also, this code contains some subtle and obvious issues, but writing
about this is not fun.
stream provides a read buffer (so even something like stream_read_char()
is very fast). This means the stream reads ahead by a few KBs, and
implies that the internal position (s->pos, which would match e.g. the
file position in stream_file.c), and the external position
(stream_tell()) can be different. stream_tell() shows how these are
related.
When dropping buffers, which happens on byte-level discontinuities with
a bunch of streams (including DVB), we should not change the position as
seen by the demuxer. On the other hand, the internal position is not
really meaningful, since these streams aren't seekable anyway. So just
change the code such that stream_drop_buffers() doesn't change the
demuxer visible position.
I'm hoping that this will fix a few problems with DVB. (Also see
previous commit.)
Might matter when libavformat tries to do tiny seekbacks in an
unseekable stream, and the seekback buffer isn't large enough. In this
case, seeking would fail, and would drop the current buffer. The
seekback would end up dropping future data.
This change probably doesn't have any observable effects. libavformat
normally has its own stream buffer, and demux_mkv.c tries carefully
never to seek back.
Similar as the previous commits.
Most of the code is actually copied from the stream_dvdnav.c code, but
I'd rather prefer to duplicate it, than to entangle them. The latter
would probably result in terrible things in a few years.
Same hack as with stream_dvd.c.
VIDEO_TS.IFO files are now opened via stream_dvdnav.c. Directories
containing a VIDEO_TS.IFO or VIDEO_TS/VIDEO_TS.IFO file are also
opened with it.
This was once central, but now it's almost unused. Only vf_divtc still
uses it for extremely weird and incomprehensible reasons. The use in
stream.c is trivial. Replace these, and remove mpbswap.h.
This mechanism originates from MPlayer's way of dealing with blocking
network, but it's still useful. On opening and closing, mpv waits for
network synchronously, and also some obscure commands and use-cases can
lead to such blocking. In these situations, the stream is asynchronously
forced to stop by "interrupting" it.
The old design interrupting I/O was a bit broken: polling with a
callback, instead of actively interrupting it. Change the direction of
this. There is no callback anymore, and the player calls
mp_cancel_trigger() to force the stream to return.
libavformat (via stream_lavf.c) has the old broken design, and fixing it
would require fixing libavformat, which won't happen so quickly. So we
have to keep that part. But everything above the stream layer is
prepared for a better design, and more sophisticated methods than
mp_cancel_test() could be easily introduced.
There's still one problem: commands are still run in the central
playback loop, which we assume can block on I/O in the worst case.
That's not a problem yet, because we simply mark some commands as being
able to stop playback of the current file ("quit" etc.), so input.c
could abort playback as soon as such a command is queued. But there are
also commands abort playback only conditionally, and the logic for that
is in the playback core and thus "unreachable". For example,
"playlist_next" aborts playback only if there's a next file. We don't
want it to always abort playback.
As a quite ugly hack, abort playback only if at least 2 abort commands
are queued - this pretty much happens only if the core is frozen and
doesn't react to input.
Because that might be a bad idea.
Note that remote playlists still can use any protocol marked with
is_safe and is_network, because the case of http-hosted playlists
containing URLs using other streaming protocols is not unusual.
Until now, you had to use --load-unsafe-playlists or --playlist to get
playlists loaded. Change this and always load playlists by default.
This still attempts to reject unsafe URLs. For example, trying to invoke
libavdevice pseudo-demuxer is explicitly prevented. Local paths and any
http links (and some more) are always allowed.
bstr.c doesn't really deserve its own directory, and compat had just
a few files, most of which may as well be in osdep. There isn't really
any justification for these extra directories, so get rid of them.
The compat/libav.h was empty - just delete it. We changed our approach
to API compatibility, and will likely not need it anymore.
Don't reconnect to the cache (since the cached stream already handles
reconnection). This is necessary, because since commit 0b428e44 the
"streaming" field (which also controls whether attempting to reconnect
makes sense at all) is inherited to the cache stream wrapper.
Also, let the stream reset its own position on reconnect. This removes
some assumptions and messy handling from the reconnect function.
Make sure the cache is dropped on reconnect. This takes care of
readjusting the stream position if necessary. (Also drop the cache on
DVB channel switching commands.)
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.