1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-29 10:32:15 +00:00
Commit Graph

2039 Commits

Author SHA1 Message Date
Mohammad AlSaleh
ffa9aaa2e4 stream: Implement slice:// for reading slices of streams
Add support for reading a byte range from a stream via
 the `slice://` protocol.

 Syntax is `slice://start[-end]@URL` where end is a maximum
 (read until end or eof).

 Size suffixes support in `m_option` is reused so they can
 be used with start/end.

 This can be very useful with e.g. large MPEGTS streams with
 corruption or time-stamp jumps or other issues in them.

Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
2020-08-19 17:22:53 +02:00
wm4
06033df715 demux_lavf: workaround reading gif from unseekable streams
FFmpeg, being the pile of trash as usual, recently broke this. Add our
own trash hack to trashily workaround this shit.

Fixes: #7893
2020-07-09 12:29:22 +02:00
wm4
ad9f3bfe96 stream: make stream_read_file() more robust
Change it to strictly accept local paths only. No more http://, no more
$HOME expansion with "~/" or mpv config path expansion with "~~/". This
should behave as if passing a path directly to open().

Reduce annoying log noise to further facilitate it using as open()
replacement.
2020-05-10 16:44:35 +02:00
Kevin Mitchell
2aa5964b43
stream_libarchive: remember archive headers from initial open
The header probing hacks were previously all broken. They only worked
the first time the archive file was open. Since subsequent opens (on
seek) occured in the middle of the source stream rather than at the
beginning, the stream_read_peek calls meant to retrieve the headers were
instead returning random bytes in the middle of the file.

Perhaps the worst manifestation of this was when seeking within a
multi-volume .rar archive with the "legacy" file naming pattern. If the
seek required a reopen, the fact that the archive was multi-volume would
be forgotten and the file would appear truncated terminating playback.

To solve this, only perform the header probling the first time the
archive is opened. Save the results and reuse them on subsequent
reopens. Put this in a wrapper so this is transparent to
demux_libarchive.
2020-04-28 22:13:03 -07:00
Kevin Mitchell
9285a1c05e
stream_libarchive: simplify multi-volume rar hate message
I couldn't find any reason for this message to be so far dispalced from
where it's necessity was determined. That necessity is not however in
question.

Also improve the wording and line breaking.
2020-04-27 21:11:31 -07:00
Kevin Mitchell
430b6f9f12
stream_libarchive: put multi_rar check in a function 2020-04-27 21:10:58 -07:00
Oliver Freyermuth
b4c1554f7a stream_dvb: Remove call to stream_drop_buffers in fill_buffer.
The call was hidden very well, via
dvb_streaming_read -> dvb_update_config
-> dvb_streaming_start -> dvb_set_channel,
and broke the stream buffering logic.
Dropping that call does not noticeably slow down channel switches.
2020-04-10 17:12:53 +02:00
wm4
40c8df8a54 stream: actually drop unneeded buffer
The buffer can be larger than the normal size when "peeking" is used
(such as done with some file formats, where a large number of bytes masy
need to be "peeked" at the beginning, because FFmpeg). Once normal
operation resumes, it's supposed to free this buffer again. Apparently
this didn't happen as intended, because normal reading did have no way
to discard back buffer before/while resizing the buffer. There's only a
path for discarding the back buffer when actually reading.

It seems like this unfortunately needs 2 code paths for discarding old
data. Just put it into stream_resize_buffer(), where it's rather
non-tricky (discarding can be done by adjusting the copy offset when
moving data to the new allocation). The function now drops old data if
it doesn't fit into the allocation. The caller must ensure that the new
size is sufficient; the function signature changes only so the size of
the implicitly guaranteed kept part can be checked with assert().
2020-04-10 12:37:12 +02:00
wm4
c3f40e513b stream: add assert, a cosmetic change
This shouldn't change anything.
2020-04-10 12:23:10 +02:00
wm4
8e74b08538 stream: minor adjustment to buffer size limit logic
Instead of having 2 inconsistent limits on the upper possible buffer
size (option limit and allocation code), use a shared constant for them.
2020-04-10 10:59:18 +02:00
wm4
217c47ecb2 stream: fix whitespace within comment
arrrrrrrghh
2020-04-10 10:50:54 +02:00
wm4
26f4f18c06 options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with

   {"name", ...

followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.

I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.

Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.

Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.

In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-18 19:52:01 +01:00
wm4
8d965a1bfb options: change how option range min/max is handled
Before this commit, option declarations used M_OPT_MIN/M_OPT_MAX (and
some other identifiers based on these) to signal whether an option had
min/max values. Remove these flags, and make it use a range implicitly
on the condition if min<max is true.

This requires care in all cases when only M_OPT_MIN or M_OPT_MAX were
set (instead of both). Generally, the commit replaces all these
instances with using DBL_MAX/DBL_MIN for the "unset" part of the range.

This also happens to fix some cases where you could pass over-large
values to integer options, which were silently truncated, but now cause
an error.

This commit has some higher potential for regressions.
2020-03-13 17:34:46 +01:00
wm4
d3ad4e2308 options: remove intpair option type
This was mostly unused, and has certain problems. Just get rid of it.

It was still used in CDDA (--cdda-span) and a debug option for OpenGL
(--opengl-check-pattern). Replace both of these with 2 options, where
each sets the start/end values of the former span. Both were
undocumented somehow (normally we require all options to be documented),
so I'm not caring about compatibility, and not bothering to add it to
the API changelog.
2020-03-13 16:50:27 +01:00
wm4
d0d9ace421 stream_file: mark fd protocols as "unsafe"
Whatever good or bad that might do. In any case, they can easily trigger
UB-like behavior.
2020-03-08 19:38:10 +01:00
wm4
28ea1ed296 stream_lavf: use smb:// for ffmpeg libsmbclient support
If you really want that, you can get it through FFmpeg, I guess.
2020-03-07 13:55:20 +01:00
wm4
3b8b7cb9d4 stream_smb: remove this
This required libsmbclient, which is a heavy dependency, and as a
library, has all kinds of problems. For one, the API requires completely
unacceptable global state (in particular, leaks auth state), and is not
thread-safe (meaning concurrent reads to multiple files block each
other).

There are better replacements: you can use the Linux kernel's builtin
CIFS support, fusesmb, or contribute supoport for libdsm.
2020-03-05 22:00:50 +01:00
wm4
aafc434f00 stream_file: remove file size caching
With the last 3 commits, this caching should be completely unnecessary.
2020-02-16 23:51:21 +01:00
wm4
20eead1813 stream_file: use fstat() instead of lseek() to determine file size
It appears using lseek() to seek to the end and back to determine file
size is inefficient in some cases.

With CIFS, this restores the performance regression that happened when
the stream cache was removed (which called read() from a thread). This
is probably faster than the old code too, because it's the seeking that
was slowing down CIFS.

According to the user who tested this, the size caching does not help
with fstat() (although it did with the old method).

Fixes: #7408, #7152
2020-02-16 23:36:05 +01:00
wm4
7d11eda72e Remove remains of Libav compatibility
Libav seems rather dead: no release for 2 years, no new git commits in
master for almost a year (with one exception ~6 months ago). From what I
can tell, some developers resigned themselves to the horrifying idea to
post patches to ffmpeg-devel instead, while the rest of the developers
went on to greener pastures.

Libav was a better project than FFmpeg. Unfortunately, FFmpeg won,
because it managed to keep the name and website. Libav was pushed more
and more into obscurity: while there was initially a big push for Libav,
FFmpeg just remained "in place" and visible for most people. FFmpeg was
slowly draining all manpower and energy from Libav. A big part of this
was that FFmpeg stole code from Libav (regular merges of the entire
Libav git tree), making it some sort of Frankenstein mirror of Libav,
think decaying zombie with additional legs ("features") nailed to it.
"Stealing" surely is the wrong word; I'm just aping the language that
some of the FFmpeg members used to use. All that is in the past now, I'm
probably the only person left who is annoyed by this, and with this
commit I'm putting this decade long problem finally to an end. I just
thought I'd express my annoyance about this fucking shitshow one last
time.

The most intrusive change in this commit is the resample filter, which
originally used libavresample. Since the FFmpeg developer refused to
enable libavresample by default for drama reasons, and the API was
slightly different, so the filter used some big preprocessor mess to
make it compatible to libswresample. All that falls away now. The
simplification to the build system is also significant.
2020-02-16 15:14:55 +01:00
wm4
5793cb40c8 stream: early-out in stream_seek_skip() if nothing is skipped
stream_seek() might somewhat show up in the profiler, even if it's a
no-OP, because of the MP_TRACE() call. I find this annoying. Otherwise,
this should be of no consequence, and should not break or improve
anything.
2020-02-14 16:08:54 +01:00
wm4
c59ca06a0f stream_file: cache file size
Some cache logic in demux.c queries the raw byte stream size on every
packet read. This is because it reports the value to the user. (It has
to be polled like this because there is no change notification in most
underlying I/O APIs, and also the user can't just block on the demuxer
thread to update it explicitly.)

This causes a very high number of get_size calls with low packet sizes,
so cache the size, and update it on every read. Reads only happen
approximately all 64KB read with default settings, which is way less
frequent than every packet in such extreme cases.

In theory, this could in theory cause problems in some cases. Actually
this is whole commit complete non-sense, because why micro-optimize for
broken cases like patent troll codecs. I don't need to justify it
anyway.

As a minor detail, off_t is actually specified as signed, so the off_t
cast is never needed.
2020-02-14 16:07:13 +01:00
wm4
13624b5c7a stream_libarchive: disable tar support
Unfortunately, libarchive detects a stream of 0s as tar, as demonstrated
by "mpv /dev/zero". This is inconvenient in some cases.

One example is the .cue demuxer trying to open a raw audio .bin file,
which it allows only if probing fails (as .bin is raw and normally will
not look like any real file format). Although this use-case is
worthless.
2020-02-02 17:35:57 +01:00
wm4
f304a79935 stream_cdda: fix operation
The cdio API always reads in sectors (fixed CDIO_CD_FRAMESIZE_RAW
blocks). In the past, mpv/MPlayer streams had a way for a stream to
signal a sector size, so the stream's fill_buffer implementation could
ignore the length argument. Later, that was removed, but stream_cdda.c
was left with assuming that the read size was always larger than the
sector size (rightfully at the time). Even later, this assumption was
broken with commit f37f4de, when it was suddenly possibly that smaller
reads were performed (at ring buffer boundaries). It returned EOF if the
buffer size was too small, so playback stopped very early.

Fix this by explicitly handling arbitrary sizes.

Tested with a .cue/.bin file only.

Fixes: #7384
2020-02-02 02:15:51 +01:00
wm4
b316534902 stream_lavf: remove version from user agent 2020-01-26 14:24:47 +01:00
wm4
65f3c7453d stream_libarchive: more broken garbage
Why the fuck am I even bothering with this crap?
2020-01-20 19:58:51 +01:00
wm4
3ef0754102 Revert "stream_libarchive: remove "old" rar volume pattern"
This reverts commit 1b0129c414.

It turns out most of the files affected by the idiotic use-case actually
use this old naming pattern, which I hoped was unused.

This means for now we'll always assume .rar files are multi-part (until
proven otherwise), but the following commit tries to fix this.
2020-01-20 19:58:51 +01:00
wm4
90c11fa729 stream_libarchive: do not require leading / in archive URLs
The / was added some time ago, because it simplifies some other things.
But there is actually no reason to reject old URLs.
2020-01-19 19:26:51 +01:00
wm4
33e999de82 stream_libarchive: fix unnecessarily opening all volumes on opening
Seems like I'm still not done with rar playback stuff...

It turns out the reason for archive_read_open1() opening all volumes had
nothing to do with libarchive's rar code, but was a consequence of how
multi volume support is implemented in libarchive, and due to the fact
that we enabled archive_read_support_format_zip_seekable() (through
archive_read_support_format_zip()).

The seekable zip format will seek to the end of the file and search for
a zip "header" there. It could possibly be considered a libarchive bug
that it does that even if it's fairly sure that it's a RAR file.

We already do probing on a small buffer read from the start of the file
(i.e. not giving libarchive a way to seek the stream before we think
it's an archive), but that does not help, since libarchive needs to
probe _again_. libarchive does not seem to provide a function to query
the format (no archive_read_get_format()). Which seems quite strange,
but at least I didn't find one.

This commit works this around by doing some manual rar/zip probing. We
could have gone only with rar probing. But detecting zip separately
allows us to avoid that stream_libarchive seeks to the end during early
probing. This is an additional bonus on top of "fixing" multi volume
rar.

The zip probing is from archive_read_format_zip_streamable_bid(). The
rar signature is the common prefix of the rar and rar5 formats in
libarchive (presumably the RAR fixed header parts without version).

If the demuxer seeks to the end of the rar entry, this will still open
all volumes; I'm not sure whether the old/removed rar code in mpv could
handle this better.

See: #7182
2020-01-09 02:25:13 +01:00
wm4
28650e116a stream_libarchive: enable anger management
Well that was too much misery when trying to deal with an idiotic
feature, so it had to be compensated for.
Replace insults with proper explanation, libarchive sort of isn't guilty
in the first place, and their format support is pretty good all things
considered.
2020-01-07 15:32:27 +01:00
wm4
1b0129c414 stream_libarchive: remove "old" rar volume pattern
This turned every "normal" .rar filename into a multi-volume one
accidentally. Since the detection is purely by filename (due to lack of
support by libarchive I guess), it causes the nasty message added in the
previous commit to appear for every .rar file. Just drop it.
2020-01-04 20:49:00 +01:00
wm4
119bad4daa stream_libarchive: add annoying message regarding multi-volume archives
I'm done.
2020-01-04 20:00:43 +01:00
wm4
1b283f6b60 libarchive: some shitty hack to make opening slightly faster
See manpage additions. The libarchive behavior mentioned in the last
paragraph there is technically unrelated, but makes this new option
mostly pointless.

See: #7182
2020-01-04 19:56:09 +01:00
wm4
4231ce6f5f stream_libarchive: log each opened volume
To annoy the user.
2020-01-04 19:48:55 +01:00
wm4
4419d29bb0 stream_libarchive: remove unnecessary string list of volumes
Just add the entries as volumes directly.
2020-01-04 19:31:08 +01:00
wm4
04bde06095 stream_libarchive: some more hacks to improve multi-volume archives
Instead of opening every volume on start just to see if it's there, all
all volumes that could possibly exist, and "handle" it on opening. This
requires working around some of libarchive's amazing stupidity and using
some empirically determined behavior. Will possibly break if libarchive
changes some of this behavior.

See: #7182
2020-01-04 18:59:23 +01:00
wm4
657ce1b15c stream_libarchive: enable rar5 support
We whitelist formats (and not all of them). RAR v5 is a separated format
entry for inexplicable reasons. (It's a separate implementation, but who
really wants to support only either of the rar formats?)

I'm not sure if it was libarchive 3.3.3. Their git history is absolutely
chaotic. These people do not know how to use git. I couldn't be bothered
to dig deeper.
2020-01-04 17:15:09 +01:00
Oliver Freyermuth
1571276d64 stream_dvb: Remove implicit fallthroughs and consistify debug messages.
The code is more explicit now and less confusing,
and debug messages for the channel parsing for the several delivery systems
are now more similar.
2019-12-28 19:16:07 +01:00
wm4
af6652004d stream_concat, stream_memory: more stream_origin stuff
Make concat streams use the "worst" origin of its parts, which may or
may not be what makes sense. stream_memory has no natural way to do
this, so just add a vague comment.
2019-12-23 11:03:44 +01:00
wm4
1cb9e7efb8 stream, demux: redo origin policy thing
mpv has a very weak and very annoying policy that determines whether a
playlist should be used or not. For example, if you play a remote
playlist, you usually don't want it to be able to read local filesystem
entries. (Although for a media player the impact is small I guess.)

It's weak and annoying as in that it does not prevent certain cases
which could be interpreted as bad in some cases, such as allowing
playlists on the local filesystem to reference remote URLs. It probably
barely makes sense, but we just want to exclude some other "definitely
not a good idea" things, all while playlists generally just work, so
whatever.

The policy is:
- from the command line anything is played
- local playlists can reference anything except "unsafe" streams
  ("unsafe" means special stream inputs like libavfilter graphs)
- remote playlists can reference only remote URLs
- things like "memory://" and archives are "transparent" to this

This commit does... something. It replaces the weird stream flags with a
slightly clearer "origin" value, which is now consequently passed down
and used everywhere. It fixes some deviations from the described policy.

I wanted to force archives to reference only content within them, but
this would probably have been more complicated (or required different
abstractions), and I'm too lazy to figure it out, so archives are now
"transparent" (playlists within archives behave the same outside).

There may be a lot of bugs in this.

This is unfortunately a very noisy commit because:
- every stream open call now needs to pass the origin
- so does every demuxer open call (=> params param. gets mandatory)
- most stream were changed to provide the "origin" value
- the origin value needed to be passed along in a lot of places
- I was too lazy to split the commit

Fixes: #7274
2019-12-20 13:00:39 +01:00
wm4
572c32abbe libarchive: prefix entry names in archive URLs with '/'
This has the advantage that playlists within the archive will work as
expected, because demux_playlist will correctly join the archive base
URL and entry name. Before this change, it could skip before the "|",
resulting in a broken URL.
2019-12-20 08:35:08 +01:00
wm4
c84460f61f build: add -Wimplicit-fallthrough
This warning seems to be designed well. It doesn't seem to warn on
fallthrough-only case statements, so it's compatible to well written
code.

stream_dvdnav.c had an obscure bug in inactive code, fix it.
stream_dvb.c is the only place where it intentionally falls through, I
guess I'll just leave it alone.
2019-12-11 17:28:47 +01:00
wm4
c26e80d0fd command: shuffle some crap around
This is preparation to get rid of the option-to-property bridge
(mp_on_set_option). This is a pretty insane thing that redirects
accesses to options to properties. It was needed in the ever ongoing
transition from something to... something else.

A good example for the need of this bridge is applying profiles at
runtime. This obviously goes through the config parser, but should also
make all changes effective, for which traditionally the property layer
is used.

There isn't much left that needs this bridge. This commit changes a
bunch of options (which also have a property implementation) to use
option change notifications instead. Many of the properties are still
left, but perform unrelated functions like OSD formatting.

This should be mostly compatible. There may be some subtle behavior
changes. For example, "hwdec" and "record-file" do not check for changes
anymore before applying them, so writing the current value to them
suddenly does something, while it was ignored before.

DVB changes untested, but should work.
2019-11-25 00:26:36 +01:00
wm4
5a99015acf stream_lavf: set --network-timeout to 60 seconds by default
Until now, we've made FFmpeg use the default network timeout - which is
apparently infinite. I don't know if this was changed at some point,
although it seems likely, as I was sure there was a more useful default.

For most use cases, a smaller timeout is more useful (for example
recording something in the background), so force a timeout of 1 minute.

See: #5793
2019-11-14 13:46:03 +01:00
wm4
ac7f67b3f2 demux_mkv, stream: attempt to improve behavior in unseekable streams
stream_skip() semantics were kind of bad, especially after the recent
change to the stream code. Forward stream_skip() calls could still
trigger a seek and fail, even if it was supposed to actually skip data.
(Maybe the idea that stream_skip() should try to seek is worthless in
the first place.)

Rename it to stream_seek_skip() (takes absolute position now because I
think that's better), and make it always skip if the stream is marked as
forward.

While we're at it, make EOF detection more robust. I guess s->eof
shouldn't exist at all, since it's valid only "sometimes". It should be
removed... but not today. A 1-byte stream_read_peek() call is good to
get the s->eof flag set to a correct value.
2019-11-14 12:59:14 +01:00
wm4
19becc8ea9 stats, demux: log byte level stream seeks 2019-11-07 22:53:13 +01:00
wm4
6487abde79 stream: remove unused read_chunk field
It was set, but its value was never used. The stream cache used to use
it, but it was removed. It controlled how much data it tried to read
from the underlying stream at once.

The user can now control the buffer size with --stream-buffer-size,
which achieves a similar effect, because the stream will in the common
case read half of the buffer size at once. In fact, the new default size
is 128KB, i.e. 64KB read size, which is as much as stream_file and
stream_cb requested by default. stream_memory requested more, but it
doesn't matter anyway. Only stream_smb set a larger size with 128KB.
2019-11-07 22:53:13 +01:00
wm4
e5a9b792ec stream: replace STREAM_CTRL_GET_SIZE with a proper entrypoint
This is overlay convoluted as a stream control, and important enough to
warrant "first class" functionality.
2019-11-07 22:53:13 +01:00
wm4
ca75fedaf4 stream_dvdnav: ok, this makes no sense at all
The dvdnav API reads in 2K blocks (dvdnav_get_next_block()). The mpv
wrapper (fill_buffer() in this file) expects that the read size done by
the mpv core is at least 2K for this reason. If not, it returns an
error.

This used to be OK, because there was a thing called section alignment
in the core code. This was removed because the core shouldn't suffer
from optical disc idiosyncrasies. Which means that ever since, it has
been working only by coincidence, or maybe not at all.

Fixing this would require keeping a buffer in the priv struct, and
returning it piece by piece if the core makes smaller reads. I have no
intention of writing such code, so add an error message asking for a
patch. If anyone actually cares about DVD, maybe it'll get fixed.
2019-11-07 22:53:13 +01:00
wm4
6fc0e7e0a0 stream_bluray: remove size getter
This isn't really needed, since it doesn't support byte seeking (only
for avoiding that demux_disc fucks up even more if the nested demux_lavf
tries to seek in the TS).
2019-11-07 22:53:13 +01:00