DVD/BD menu support never worked right, and are a pain to maintain. In
particular, DVD menus never actually worked correctly, because
highlights were not rendered correctly. Fixing this requires major
effort, which I'm not interested to spend.
Most importantly, the requirement to switch streams without losing the
DVD/BD state caused major weirdness in the playback core. It was
implemented by somehow syncing the playback state to the DVD/BD
implementation (in stream_dvdnav.c etc.), and then reloading the demuxer
without destroying and recreating the stream. This caused a bunch of
special-cases which I'm looking forward to remove.
For now, don't just remove everything related to menu support and just
disable it. If someone volunteers, it can be restored (i.e. rewritten)
in a reasonable way. If nobody volunteers soon, it goes.
Normally, the cache keeps 50% of the buffer for seeking backwards. Until
now, the cache just used the full buffer size at the beginning of a
file, because the 50% normally reserved for the backbuffer are unused.
This caused a problem: when streaming from http, the player would first
read about 150MB (default cache size), then stop until 75MB of the cache
has been played. (Until the 75MB position, the cache is fully used, so
nothing new can be read. After that, part of the backbuffer starts
getting unreserved, and can be used for readahead.) This long read pause
can cause the server to terminate the connection. Reconnecting may be
possible, but if youtube-dl is used, the media URL may have become
invalid.
Fix this by limiting readahead to 50% even if unnecessary. The only
exception is when the whole file would fit in the cache. In this case,
it won't matter if we can't reconnect, because the cache covers
everything anyway, and hopefully the cache will stay valid.
Likely fixes#2000.
There is not much of a reason to have these wrappers around. Use POSIX
standard functions directly, and use a separate utility function to take
care of the timespec calculations. (Course POSIX for using this weird
format for time values.)
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.
An approximate measure to make it exit possibly slightly earlier.
Relatively speaking, some time will pass between cancellation and
the cache actually being requested to exit, so it's good if the
cache returns EOF immediately.
The caller can check for cache interruption instead. There's no need to
define special return values and such. It would be rather hard to make
waiting for the condition and stream cancellation atomic too (and
pointless, since the underlying stream will also be "cancelled" and exit
early), so nothing about cancellation being a separate call will change.
This put some effort into distinguishing between two messages to print -
all worthless. Even more so, this kept printing the message, which
doesn't feel overly useful either. (The message will be printed
repeatedly anyway if network recovers for a while and then gets stuck
again.)
All in all, the demuxer cache triggering the buffering state does a
better job here. But don't remove it completely, since knowing that the
network did nothing for a relatively short time is still useful.
If a directory is encountered, replace it with its contents in the
internal playlist.
This is messed into demux_playlist.c, because why not. STREAMTYPE_DIR
could be avoided by unconditonally trying opendir() in demux_playlist.c,
but it seems nicer not to do weird things like calling it on real files.
This does not work on Windows, because msvcrt is retarded.
The libavformat rtmp protocol's "timeout" option has two problems:
1) Unlike all other protocols, it's in seconds and not microseconds
2) It enables "listen" mode, which breaks playback
Make the --network-timeout do nothing in the rtmp case.
Fixes#1704.
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.)
This causes the cache to be enabled with --cache=auto. It was not done
previously because the small cache size 320k actually led to worse
performance. However, with the current default cache size of 25000kb,
caching notably improves performance.
If we're caching a stream with unknown size, and we reach EOF, then
consider the EOF position the file size. Typically makes sense when
reading from a pipe or a http connection that did not send a size.
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.
It is also used for initialization in channel-list setup.
Should fix compilation on FreeBSD, and is more correct
since it is used unconditionally.
Reverts 6445648 .
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
This message will be printed relatively often once EOF is reached. In
some cases this is rather annoying, for example when playing HLS. (With
HLS, the stream is just a playlist file, while libavformat opens actual
media files without mpv's knowledge, so the cache is completely useless
and hits EOF instantly.)
That it retries reading is apparently a good thing: at least local files
can grow, and even after the player got the EOF, playback _could_ be
resumed by basically polling and detecting that there is more data. So
I'm not changing this behavior yet.
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.
Looks like a bunch of off-by-one errors.
The track number was mistakenly offset by 1 - this shifted all chapters
by one, and make the first chapter start on the second track (so the
"chapter" property returned -1 in the first track since it was before
the first chapter).
Also, the calculation of the sector destination was messed up. This
comes from commit 32d818f0, where I apparently attempted to calculate
the position to one byte before the section, but unfortunately math
doesn't work this way and it was nonsense. Just drop this idea; while it
may help with seeking (probably...), it also returns slightly different
times. The user shall use hr-seeks if accurate seeking is required.
Hopefully fixes#1560.
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.
libdvdnav is garbage. Seeking by time is incredibly inexact, which is in
part due to the fact that it does not use the DVD seek tables. Instead,
it assumes CBR for certain ranges within the DVD, which makes especially
small seeks unreliable.
I have no good fix for this, other than hacking libdvdnav (I'd rather
prefer to remove mpv DVD support completely than doing this). So here's
a shitty hack that tries to workaround these problems. A basic
observation is that seeking in VLC seems to work quite well; however it
seems to be based on seeking by blocks (unless there is a subtle "trick"
I didn't see in the source code). mpv usually seeks by timestamps, so
this is not an option for us. However, we can pretend we are doing this
in the DVD layer.
The previous commit added a way to pass through relative seeks. This
commit uses the relative seek. STREAM_CTRL_SEEK_TO_TIME is backwards
compatible (there's still dvdread and bluray), so most code is about
extracing the relative seek information and turning it into a block
seek.
(Another way would have been using SEEK_FACTOR stuff, but that would
probably make for a less reliable way to handle this situation.)
Additionally, if a hr-seek is done, add an offset by 10 seconds. As long
as the error done by libdvdnav is not worse, this should help with hr-
seeks - although it makes them much slower.
This complains within dvb_strtok_r() that savePtr is uninitialized.
There doesn't seem to be any code path where this can happen though, so
it's probably a false positive. Silence it anyway.
This causes more constant reading from the DVB device,
and seems not to hurt the stream-controls.
As the device cache seems to fill up when not
reading from it for several seconds, reading
into the cache fixes desync-issues after
the initial analyzeduration of the demuxer.
Was already possible before by injecting the magic PID
8192 into channels.conf, the flag makes this much more
useable and we also have it documented.
Useful not only for debugging, but also for incomplete
channels.conf (mplayer format...), multi-channel
recording, or channels which do dynamic PID switchng.
full-transponder is also useful for channels which switch PIDs on-the-fly.
ffmpeg can handle this, but it needs the full stream with all PIDs.
There is the STD which contains service-names
(ffmpeg can understand it),
and the EIT which contains the EPG
(ffmpeg does not parse it, but e.g. VLC does).
As we now have more PIDs in general, increase the maximum
number of demuxers we can open. ffmpeg has an internal
limit of 64 PIDs, we are still far from that.
If VDR-channel-config is used, we know the service_id.
Using that, PMT can be extracted from PAT (code for that
inspired by szap-s2 again).
For this, we need to demux PAT with a special filter-setup,
and once PMT was found it can be added to the PID-list.
PMT is only resolved the first time one tunes to a channel,
then stored in the channel-list in memory.
With PMT available, ffmpeg can safely decode the teletext-pids.
I also added a comment explaining the potentially occuring structures for future reference.
For tokenization, a custom strtok_r implementation is used,
inspired by strtok_r as implemented in musl and ffmpeg,
hopefully slightly more readable (av_strtok_r is not available in libav,
and strtok_r is not available everywhere).
Move PID-string parsing into a separate function, reduces code-duplication.
Drop TPID-parsing again since teletext-stream seems not really correctly identified (ffmpeg guessed mp3 in my test...).
Parsing now done using strtok + sscanf instead of sscanfs with fixed numbers of expected fields -
gives more correct checking of PID-overflow, will allow VDR-style PID-field parsing.
The PID-parsing is not really nicely done and also does not yet handle the special VDR-style syntax.
A later commit will move the parsing to a separate function handling that which also checks that the maximum PID-count is not exceeded.
In mplayer-style channels-config, we had a LNB-field used for that.
In old VDR times, the location-field was also containing DISEQc information,
now it does that only indirectly (location => LNB => vdr knows from lnb-config).
We only accept it as this if the field is fully numeric.
Now also "stream ID" (for DVB-S2) and "inversion" are understood.
The parameter-string can also provide information on FEC, rolloff etc. For DVB-S, "auto" which mpv uses by default should be fine, I can also confirm it works. For non-DVB-S cards, it might be useful to also parse this information in case of a vdr-channel list.
As I have no such hardware and thus would have to do it blindly, I added a FIXME.
Mostly complete vdr-channels.conf format documentation is at http://www.vdr-wiki.de/wiki/index.php/Channels.conf (german only).
Still incomplete. Initialize is_dvb_s2 boolean in channel-struct.
We first check whether the channels.conf-line at hand is sscanf'able with a vdr-style pattern. If yes, we assume it is a vdr-channel-config (we check whether sscanf consumed the full line).
The vdr-style config also contains a parameter-string which contains information about polarization + delivery type (e.g. DVB-S2).
With this change, S2-tuning works with a VDR-channel list.
Missing (later commits):
- vdr-parameter-string also contains other information, e.g. invert-flag, needs to be parsed.
- Diseqc-lnb-number is not present in VDR-config (I believe it is handled via the location-parameter + lnb-config there). For backwards compatibility, the location-parameter can be the lnb-number - we should test whether it is an int and assume this in this case.
- VID, AID and TID-lists are extremely ugly in their syntax for VDR. At the moment, only the first number is parsed (and TID fully ignored), needs to be fixed.
It contains now also a boolean which tells whether this is an DVB-S2 channel (not initialized yet - tbd in next commit).
We could also pass through the type of the delivery system (would be more flexible), but the delivery-system-enum is only available with S2API, so this is more backwards-compatible.
If someone has DVB-T2 / DVB-C2 hardware and extends the code to deal with it, this should be changed.
Also allows demuxers to buffer, and we explicitly discard stale QPSK events.
Inspiration taken from the szap-s2 implementation.
S2API is only used if available and for DVB-S cards - it might also be useful to have that for DVB-T2 / DVB-C2 tuning later, but I do not have the HW / no DVB-T2 broadcasting station nearby to test functionality.
This should do no functional changes, only usage of the different API. The S2API is more extensible and a requirement for all the HD-deliveries (e.g. DVB-S2) and since 2.6.28 is the successor of the old API.
Tuning to DVB-S2 channels actually already "works" like this if the delivery is hardcoded in - for a fully working implementation, the channels.conf.sat would need an additional field indicating the delivery type (VDR-type channels.conf have that).
This commit also:
- Cleans up some debug output.
- Moves an unneeded usleep(100000) (only needed for diseqc switching for SAT) into the DVB-S-only part of the implementation.
Define a new macro "DVB_USE_S2API" to be used to switch to S2API if available,
also document what is the main difference in the new S2API.
StreamID-handling is only supported since API 5.2, and some macros
were renamed or only added later with 5.8 (somewhere around kernel 3.6),
so some define-fixups are needed to support these intermediate
kernel header versions.
Apparently this is what users would expect.
Going the way of least resistance (in terms of messing with this old,
rarely used code), sorting them by some kind of addition timestamp
(called priority in the patch) is the easiest.
Fixes#1390.
stream_edl merely makes demux_edl act "special", which checks for the
stream type explicitly and then does something with its URL. If a cache
is added before the stream, it'll try to use the cache's URL (i.e. an
empty string), and will then obviously fail to parse the URL. While this
is slightly stupid, just disabling the entirely useless cache is the
most effective solution.
Fixes#1378.
As suggested in issue #1251. I think the main point is that it acts as
a hack to return to the DVD menu when jumping past the last chapter,
because it will reach title-EOF, instead of explicitly jumping to the
next file (which usually exits the player).
This basically reverts commit 8b7418d, except it doesn't include an
off-by-1 error (apparently).
Closes#1251.
This was requested.
It seems libdvdread can't get the duration for titlesets other than the
currently opened title. The data structures contain dangling pointers
for these, and MPlayer works this around by opening every title
separately for the purpose of dumping the title list.
Apparently, we treat different tracks as titles, so returning the number
of titles (which is user-visible as "disc-titles" property) is
completely misguided.
Apparently, libdvdnav always reports a last chapter that points to the
exact end of the title. This is useless for us.
Again, same possible caveats as with the previous commit.
This way, chapter 0 will always point to the start of the title.
At least this is the intention; it's likely that DVDs as well as
libdvdnav do random things that lead to random results.
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.
...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.
Thanks to STREAM_CTRL_HAS_AVSEEK, we actually know whether CTRL_AVSEEK
is implemented at all, and we can avoid a blocking wait on the cache if
demux_lavf sends CTRL_AVSEEK even if it won't wait. I'm hoping this
can't currently happen, but why hope if we can explicitly prevent it.
It'll make us more robust against future changes in libavformat.
Basically, this will mark the demuxer as seekable with rtmp* and mmsh
protocols. These protocols have network-level time seeking, and whether
you can seek on the byte level does not matter.
Until now, seeking was typically only enabled because of the cache, and
a (nonsensical) warning was shown accordingly.
It still could happen that the server doesn't actually support thse
requests (or simply rejects them), so this is somewhat imperfect.
No development activity (or even any sign of life) for almost a year.
A replacement based on youtube-dl will probably be provided before the
next mpv release. Ask on the IRC channel if you want to test.
Simplify the Lua check too: libquvi linking against a different Lua
version than mpv was a frequent issue, but with libquvi gone, no
direct dependency uses Lua, and such a clash is rather unlikely.
The immediate mode (which is the default) uses a tiny ringbuffer and
doesn't grab timestamps. This leads to quite bad behavior due to the
fact that there's an additional buffer between playloop and TV code (the
demuxer thread, which doesn't exist in MPlayer).
Always grab the timestamps and use a decently-sized buffer. I still have
no clue what I'm doing, and hacked it until it appeared to work. Report
regressions if you experience any.
I can't believe how shitty this (MPlayer-derived) code is. Maybe it
should be fixed or be replaced with using libavdevice, but that doesn't
seem worth the effort.
Anyway, for now reduce the time it's blocking to wait for new frames
from 10ms to 1ms, because 10ms might be a bit too tight: it could
deliver the frame up to 10ms late - now it's only up to 1ms. (And yes,
it does that instead of using condition variables. It also abuses
volatile variables as atomics. It's hilarious.)
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.
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.
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.
Normally, we pass libavformat demuxers a wrapped mpv stream. But in some
cases, such as HLS and RTSP, we let libavformat open the stream itself.
In these cases, set typical network properties like useragent according
to the mpv options.
(We still don't set it for the cases where libavformat opens other
streams on its own, e.g. when opening the companion .sub file for .idx
files - not sure if we maybe should always set these options.)
Apparently there's an use for this; see #1178.
I won't redocument obscure FFmpeg features, so add a hint to the
manpage that some protocols are documented in FFmpeg instead.
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.
This makes no sense to use with DVD/BD/DVB and some others, and these
streams happen to be unseekable.
Also, other kinds of unseekable streams (like reading from pipe) should
work, but will exhibit sketchy behavior if they need to seek. So just
disable it, and leave these problems to the memory cache (cache.c).