summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
Commit message (Collapse)AuthorAgeFilesLines
* demux: average reported download speed some morewm42020-03-211-1/+5
| | | | | | Currently, this reported the number of received bytes per second. Improve this slightly by averaging over 2 seconds (but still updating every second).
* options: fix OPT_BYTE_SIZE upper limitswm42020-03-181-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | As an unfortunate disaster, min/max values use the type double, which causes tons of issues with int64_t types. Anyway, OPT_BYTE_SIZE is often used as maximum for size_t quantities, which can have a size different from (u)int64_t. OPT_BYTE_SIZE still uses in64_t, because in theory, you could use it for file sizes. (demux.c would for example be capable of caching more than 2GB on 32 bit platforms if a file cache is used. Though for some reason the accounting code still uses size_t, so that use case is broken. But still insist that it _could_ be used this way.) There were various inconsistent attempts to set m_option.max to a value such that the size_t/int64_t upper limit is not exceeded. Due to the double max field, this didn't really work correctly. Try to fix this with the M_MAX_MEM_BYTES constant. It's a good approximation, because on 32 bit it should allow 2GB (untested, also would probably exhaust address space in practice but whatever), and something "high enough" in 64 bit. For some reason, clang 11 still warns. But I think this might be a clang bug, or I'm crazy. The result is correct anyway.
* options: change option macros and all option declarationswm42020-03-181-27/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* options: change how option range min/max is handledwm42020-03-131-4/+6
| | | | | | | | | | | | | | | | | 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.
* demux: bump --cache-secs default valuewm42020-03-071-1/+1
| | | | | | Change to it 1000 hours, which is "infinite" enough. (Hesitant to use INFINITY, as that is not in the option's range. The option parser rejects it because it causes only problems in API users and so on.)
* demux: mark recently added debug option as deprecatedwm42020-03-071-1/+2
| | | | | It was the intention to remove it again after a release or two; mark it was deprecated so nobody thinks it gets to stay.
* demux: deprecate --cache-secswm42020-03-051-1/+2
| | | | | Because it's confusing and useless. If nobody complains, we'll have one weird cache configuration option less.
* demux: another hack to deal with track switching refreshwm42020-02-291-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The demuxer cache employs a strange method to make track switching instant with caching enabled. Normally this would mean you have to wait until the cache has played out (and you get new packets, including packets from the newly selected track), or you have to perform a slow high level seek (decoding video again etc.). The strange method is that it performs a demuxer-level seek without a high level seek so it looks like a continuous stream to the decoder, and the newly select stream gets packets at the current playback position. This is called a refresh seek. This works only if some weird heuristics work. It needs a packet "unique ID", for which it uses either dts or pts. The value must be strictly monotonic increasing. If this doesn't work, the referesh seek can't be executed, and the user has to wait until the end of the cache. Sometimes there are files that simply do not work. In the present case, there's actually a hack that we can extend. Packets with unset position are likely generated by the parser, and the hack which this commit touches simply attempts to make up a new (hopefully unique) position value, even if the value itself makes no sense. It only ha to be deterministic. It turns out libavcodec sometimes output packets with repeating position values. This commit tries to handle this case too with the same hack. Fixes: #7498
* demux: add a way to block reading after seekswm42020-02-291-0/+5
| | | | | | Preparation for a future commit. The demuxer queues might be read from other threads than the one to issue the seek, and passing SEEK_BLOCK with such a seek will provide a convenient way to synchronize this.
* demux: make seek ranges work for static images + audiowm42020-02-281-1/+3
| | | | | | | | | | | | | In this case the video track has seek_start == seek_end, and due to the "seek_start >= seek_end" condition, this was considered broken, and no seek range was created, breaking cached seeking. Fix this by allowing the case if they're equal, and a valid timestamp. (NB: seeking backward in this will still jump to position 0, because it is the video timestamp. This is unfortunately how it's supposed to work. HR-seeks will also do this, but decode and skip the entire audio until the seek target, so it will mostly appear to work.)
* demux: simplify some internals, stop trying to read packets after EOFwm42020-02-271-27/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | Remove some redundant fields that controlled or indicated whether the demuxer was/could/should prefetch. Redefine how the eof/reading fields work. The in->eof field is now always valid, instead of weirdly being reset to false in random situations. The in->reading field now corresponds to whether the demuxer thread is working at all, and is reset if it stops doing anything. Also, I always found it stupid that dequeue_packet() forced the demuxer thread to retry reading if it was EOF. This makes little sense, but was probably added for files that are being appended to (running downloads). It makes no sense, because if the cache really tried to read until file EOF, it would encounter partial packets and throw errors, so all is lost anyway. Plus stream_file now handles this better. So stop this behavior, but add a temporary option that enables the old behavior. I think checking for ds->eager when enabling prefetching never really made sense (could be debated, but no, not really). On the other hand, the change above exposed a missing wakeup in the backward demuxing code. Some chances of regressions that could make it stuck in certain states or so, or incorrect demuxer cache state reporting to the player frontend.
* sub, demux: improve behavior with negative subtitle delay/muxed subswm42020-02-271-4/+39
| | | | | | | | | | | | | | | | | | | | | | | | A negative subtitle delay means that subtitles from the future should be shown earlier. With muxed subtitles, subtitle packets are demuxed along with audio and video packets. But since they are demuxed "lazily", nothing guarantees that subtitle packets from the future are available in time. Typically, the user-observed effect is that subtitles do not appear at all (or too late) with large negative --sub-delay values, but that using --cache might fix this. Make this behave better. Automatically extend read-ahead to as much as needed by the subtitles. It seems it's the easiest to pass the subtitle render timestamp to the demuxer in order to guarantee that everything is read. This timestamp based approach might be fragile, so disable it if no negative sub-delay is used. As far as the player frontend part is concerned, this makes use of the code path for external subtitles, which are not lazily demuxed, and may already trigger waiting. Fixes: #7484
* demux: avoid some queue management corner cases with subtitleswm42020-02-271-2/+3
| | | | | | | | | | | | | | | | | | | Subtitle tracks are usually "lazy" (ds->eager=false), There are a number of weird special cases associated with it. One of them is that they have some sort of "temporary" EOF (to signal that there isn't a packet right now, and the decoder should not block playback by waiting for more packets). In a the next commit, I want to call mark_stream_eof() in case of (some) of these temporary EOFs. The problem is that mark_stream_eof() also calls the functions touched by this commit. Basically they shouldn't do any complex work due to these temporary EOFs (because they might happen very often). It turns out that lazy tracks barely matter here: they do not extend the seek range of a packet/EOF happens on them, they do not trigger seek range joining, and they do not support backward demuxing. This change should enable the following commit, while not causing any behavior changes (i.e. bugs) with the current state.
* demux: fix seek range caching with delay_open hackwm42020-02-201-1/+2
| | | | | | These have ->segmented set (so the codec can be initialized properly), but have no segment start or end times. This code was (probably) the only thing which didn't handle this case.
* demux: cosmetic changewm42020-02-171-2/+1
| | | | This was sort of asymmetric and annoying.
* demux: update file-size property even when pausedwm42020-02-161-0/+3
| | | | | | | | | | | While paused, the decoders typically stop reading data from the demuxer. But for some reason, the file size is returned as a public field in struct demuxer (wat...), and updated only when the packet reading function is called. This caused the file size property to always return the same value when paused, even though the demuxer thread was reading new data, and the internal file size was updated. Fix with a simple hack.
* demux: only query stream size at most once per secondwm42020-02-161-5/+9
| | | | | | | | | | Instead of every packet. Doing it every packet led to the performance regression mentioned in the fstat() commit. This should now be over, but out of being careful, don't query the file size that often. This is only used for user interface things, so this should not cause any problems. For the sake of leaving the code compact, abuse another thing that is updated only every second (speed statistics).
* demux: invert update_cache() lockingwm42020-02-161-9/+7
| | | | Equivalent, just slightly more convenient for the following change.
* edl: add mechanism for delay loading streamswm42020-02-151-0/+1
| | | | | | | | | | | | | Add something that will access an URL embedded in EDL only when the track it corresponds to is actually selected. This is meant to help with ytdl_hook.lua and to improve loading speeds. In theory, all this stuff is available to any mpv user, but discourage using it, as it's so specialized towards ytdl_hook.lua, that there's danger we'll just break this once ytdl_hook.lua stops using it, or similar. Mostly untested.
* demux: add option to disable "sharing" between back and forward bufferswm42020-02-071-1/+4
| | | | | | | As requested. I guess option name and manpage text could be better and clearer. Closes: #7442
* demux: add per-demuxer sub-optionswm42020-01-041-0/+11
| | | | | | Until now, they were all just added to options.c (e.g. demux_mkv_conf). This adds a mechanism which can be used to add future options in a (very) slightly more elegant way.
* demux: make track switching instant with certain mpegts fileswm42019-12-311-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When switching tracks, the data for the new track is missing by the amount of data prefetched. This is because all demuxers return interleaved data, and you can't just seek the switched track alone. Normally, this would mean that the new track simply gets no data for a while (e.g. silence if it's an audio track). To avoid this, mpv performs a special "refresh seek" in the demuxer, which tries to resume demuxing from an earlier position, in a way that does not disrupt decoding for the non-changed tracks. (Could write a lot about the reasons for doing something so relatively complex, and the alternatives and their weaknesses, but let's not.) This requires that the demuxer can tell whether a packet after a seek was before or after a previously demuxed packet, sort of like an unique ID. The code can use the byte position (pos) and the DTS for this. The DTS is normally strictly monotonically increasing, the position in most sane file formats too (notably not mp4, in theory). The file at hand had DTS==NOPTS packets (which is fine, usually this happens when PTS can be used instead, but the demux.c code structure doesn't make it easy to use this), and pos==-1 at the same time. The latter is what libavformat likes to return when the packet was produced by a "parser" (or in other words, packets were split or reassembled), and the packet has no real file position. That means the refresh seek mechanism has no packet position and can't work. Fix this by making up a pseudo-position if it's missing. This needs to set the same value every time, which is why it does not work for keyframe packets (which, by definition, could be a seek target). Fixes: #7306 (sort of)
* demux: fix --stream-record runtime change handlingwm42019-12-291-1/+1
| | | | Well, if that wasn't particularly dumb.
* demux: stop setting dummy stream on demux_close_stream()wm42019-12-231-4/+2
| | | | | | | | | | | | | | Demuxers can call demux_close_stream() to close the underlying stream if it's not needed anymore. (Useful to release "heavy" resources like FDs and sockets. Plus merely keeping a file open can have visible side effects such as inability to unmount a filesystem or, on Windows, to do anything with the file.) Until now, this set demuxer->stream to a dummy stream, because most code used to assume that the stream field is non-NULL. But this requirement disappeared (in some cases, the stream field is already NULL), so stop doing that. demux_lavf.c, one of the demuxers which calls this function, still had some of this, though.
* demux: remove debug abort()wm42019-12-221-1/+1
| | | | | | WHAT THE FUCK Fixes: #7279
* demux: add an option to control tag charsetwm42019-12-201-0/+82
| | | | | | Fucking gross that you need this in almost-2020. Fixes: #7255
* stream, demux: redo origin policy thingwm42019-12-201-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* demux: do not make up demuxer_idwm42019-12-031-7/+2
| | | | | | | | | | | | | | | | | | The demuxer_id (exported in as "src-id" property) is supposed to be the native stream ID, as it exists in the file, or -1 if that does not exist (actually any negative value), or if it is unknown. Until now, an ID was made up if it was missing. That seems like strange non-sense, and I can't find the reason why it was done. But it was probably for convenience by the EDL stuff or so. Stop doing this. Fortunately, the src-id property was documented as being unavailable if the ID is not known. Even the code for this was present, it was just inactive until now. Extend input.rst with some explanations. Also fixing 3 other places where negative demuxer_id was ignored or avoided.
* stats, demux: log byte level stream seekswm42019-11-071-0/+7
|
* demux: unconditionally reposition stream to start before openingwm42019-11-061-2/+3
| | | | | | | | | | | The old code made it depend on ->seekable. If it isn't seekable, and something discarded the data, then it'll just show an error message, which will at least be somewhat informative. If no data was discarded, the seek call is always a no-op. There's a weird "timeline" condition in the old code; this doesn't matter anymore, because timeline stuff does not pass streams down to nested demuxers anymore.
* demux: reduce log level for cache index resizingwm42019-11-011-2/+2
| | | | Now that I probably removed all bugs in this (?), this is uninteresting.
* demux: restore some of the DVD/BD/CDDA interaction layerswm42019-10-031-9/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This partially reverts commit a9d83eac40c94f44d19fab7b6955331f10efe301 ("Remove optical disc fancification layers"). Mostly due to the timestamp crap, this was never really going to work. The playback layer is sensitive to timestamps, and derives the playback time directly from the low level packet timestamps. DVD/BD works differently, and libdvdnav/libbluray do not make it easy at all to compensate for this. Which is why it never worked well, but not doing it at all is even more awful. demux_disc.c tried this and rewrote packet timestamps from low level TS to playback time. So restore demux_disc.c, which should bring behavior back to the old often non-working but slightly better state. I did not revert anything that affects components above the demuxer layer. For example, the properties for switching DVD angles or listing disc titles are still gone. (Disc titles could be reimplemented as editions. But not by me.) This commit modifies the reverted code a bit; this can't be avoided, because the internal API changed quite a bit. The old seek resync in demux_lavf.c (which was a hack) is replaced with a hack. SEEK_FORCE and demux_params.external_stream are new additions. Some of this could/should be further cleaned up. If you don't want "proper" DVD/BD support to disappear, you should probably volunteer. Now why am I wasting my time for this? Just because some idiot users are too lazy to rip their ever-wearing out shitty physical discs? Then why should I not be lazy and drop support completely? They won't even be thankful for me maintaining this horrible garbage for no compensation.
* demux: make --record-file/cache dump command work with disabled streamswm42019-09-291-5/+18
| | | | | | | | | | | | | | | | This passed all streams to mp_recorder_create(), even disabled ones. The disabled streams never get packets, so recorder.c eventually errors out with unrelated-looking errors. The reason is that recorder.c waits for packets to appear on other streams, which in turn is because libavformat refuses to mux empty streams anyway. recorder.c could call demux_stream_is_selected(), which would have made the patch much smaller. But this feels like a bad idea, since recorder.c should use sh_stream only for metadata (and not in an "active" way), nor should it care what demux.c is currently doing with it. So make the API user (demux.c) pass only the streams it really wants. Fixes: #6999
* recorder: don't use a magic index for mp_recorder_get_sink()wm42019-09-291-2/+3
| | | | | | | | | | | | | | | | | | | Although this was sort of elegant, it just seems to complicate things slightly. Originally, the API meant that you cache mp_recorder_sink yourself (which would avoid the mess of passing an index around), but that too seems slightly roundabout. In a later change, I want to change the set of streams passed to mp_recorder_create(), and then I'd have to keep track of the index for each stream, which would suck. With this commit, I can just pass the unambiguous sh_stream to it, and it will be guaranteed to match the correct stream. The disadvantages are barely worth discussing. It's a new linear search per packet, but usually only 2 to 4 streams are active at a time. Also, in theory a user could want to write 2 streams using the same sh_stream (same metadata, just writing different packets or so), but in practice this is never done.
* demux: force reading packets again after seekswm42019-09-241-1/+1
| | | | | | | | | | | | | | | | in->eof is used as an indicator whether reading packets still makes sense. (Without this, the prefetcher would obviously burn CPU by retrying reading even though everything has been read.) This was not reset properly after seeks were performed. It led to getting stuck in at least one corner case: when enabling a track, the demuxer would seek backwards to get new packets from the current playback position ("refresh seeks"). But if playback was paused, and EOF was previously reached, it would not try to read packers again due to in->eof being false. There was not anything else that would make it retry reading, so it was stuck in a weird underrun/buffering state. Fixes: #6986
* demux: remove redundant seek range updateGunnar Marten2019-09-241-2/+0
| | | | | This was a leftover from commit b2752321 which fixed #6522 but after the recent demux refactoring this fix is superseded by commit 0f6cda4ab. Remove the redundant update call.
* demux: propagate streaming flag through demux_timelinewm42019-09-201-2/+5
| | | | | | | | | | | | | | Before this commit, EDL or CUE files did not properly enable the cache if they were on "slow" media (stream->streaming==true). This happened because the stream is unset for demux_timeline, so the streaming flag could not be queried anymore. Fix this by adding this flag to struct demuxer, and propagate it exactly like the is_network flag. is_network is not used for checking the cache options anymore, and its main function seems to be something else. Normal http streams set the streaming flag already. This should fix #6958.
* demux: fix another incorrect BOF cache flag issuewm42019-09-191-2/+5
|
* command, demux: add AB-loop keyframe cache align commandwm42019-09-191-0/+77
| | | | | | | | | | | | | | | Helper for the ab-loop-dump-cache command, see manpage additions. This is kind of shit. Not only is this a very "special" feature, but it also vomits more messy code into the big and already bloated demux.c, and the implementation is sort of duplicated with the dump-cache code. (Except it's different.) In addition, the results sort of depend what a video player would do with the dump-cache output, or what the user wants (for example, a user might be more interested in the range of output audio, instead of the video). But hey, I don't actually need to justify it. I'm only justifying it for fun.
* demux, command: add a third stream recording mechanismwm42019-09-191-0/+204
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | That's right, and it's probably not the end of it. I'll just claim that I have no idea how to create a proper user interface for this, so I'm creating multiple partially-orthogonal, of which some may work better in each of its special use cases. Until now, there was --record-file. You get relatively good control about what is muxed, and it can use the cache. But it sucks that it's bound to playback. If you pause while it's set, muxing stops. If you seek while it's set, the output will be sort-of trashed, and that's by design. Then --stream-record was added. This is a bit better (especially for live streams), but you can't really control well when muxing stops or ends. In particular, it can't use the cache (it just dumps whatever the underlying demuxer returns). Today, the idea is that the user should just be able to select a time range to dump to a file, and it should not affected by the user seeking around in the cache. In addition, the stream may still be running, so there's some need to continue dumping, even if it's redundant to --stream-record. One notable thing is that it uses the async command shit. Not sure whether this is a good idea. Maybe not, but whatever. Also, a user can always use the "async" prefix to pretend it doesn't. Much of this was barely tested (especially the reinterleaving crap), let's just hope it mostly works. I'm sure you can tolerate the one or other crash?