summaryrefslogtreecommitdiffstats
path: root/demux
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* demuxer-lavf: udp_multicast rtsp-transport optionmg2020-03-031-1/+4
|
* 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-292-0/+7
| | | | | | 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_lavf: don't interpret errors as EOFwm42020-02-281-3/+9
| | | | | | | | | | | | | | | It seems sporadic errors are possible, such as connection timeouts. Before the recent demuxer change, the demuxer thread retried many times even on EOF, so an error was only interpreted as EOF once the decoder queues ran out. Change it to use EOF only. Since this may actually lead to the demuxer thread being "stuck" and retrying forever (depending on libavformat API behavior), I'm also adding a heuristic to prevent this, using a random retry counter. This should not be necessary, but libavformat cannot be trusted. (This retrying forever could be stopped by the user, but obviously it would still heat the CPU for a longer time if the user is not present.)
* 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_timeline: fix bad EOF reportingwm42020-02-281-11/+10
| | | | | | | | | | | | | | | | Exposed by commit b56e2efd5f3d. demux_timeline reported a bogus EOF if "parallel" streams were used. If a virtual source reported EOF, it was propagated as global EOF, without serving packets of other virtual sources that have not ended yet. Fix this by not reporting global EOF just because a source has not returned a packet. Instead make the reader retry by returning no packet and no EOF state, which will call d_read_packet() again with a different source. Rely on the eof_reached flags to signal global EOF. Since eof_reached is now more important, set it in a certain other case when it apparently should have been set. do_read_next_packet()'s return value is now ignored, so get rid of it.
* demux_mkv: document probe-start-time option and enable it by defaultwm42020-02-271-1/+2
| | | | | | | | | | | | This is useful with live streams, and it's not much worse than the h264 first packet hack, which reads some data anyway. For some reason, the option wasn't even documented, so do that. In addition, print the start time even if it's negative. That should not be possible, but for some reason, the field is an int64_t copied from an uint64_t so... whatever. Keeping the logging slightly more straight forward is better anyway.
* 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-272-4/+41
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* ytdl_hook, edl: add fps, samplerate codec parameterswm42020-02-211-0/+2
| | | | Well, didn't help much in the case I was interested it.
* edl: make it possible to set the track "default" flagwm42020-02-211-0/+11
| | | | | Also, the forced flag (and in the future, potentially a number of other flags not implemented yet). See next commit for purpose.
* demux_edl: correct warning on duplicate parameterswm42020-02-211-2/+4
| | | | | | | | A parameter that is actually used is removed from the param_names[] array, so we can report unused parameters. This also happened on duplicate parameters, so adjust the warning to make it less confusing. (In any case, you're not supposed to provide duplicate parameters.)
* edl: make it possible to delay-load files with multiple trackswm42020-02-213-17/+49
| | | | | | | | | | | | | | Until now, delay-loading was for files with single tracks only (basically what DASH and HLS like to expose, so adaptive streaming and codec selection becomes easier - for sites, not for us). But they also provide some interleaved versions, probably for compatibility. Until now, we were forced to eagerly load it (making startup slightly slower). But there is not much missing. We just need a way to provide multiple metadata entries, and use them to represent each track. A side effect is now that the "track_meta" header can be used for normal EDL files too.
* demux_lavf: signal no seeking for RTSP streams without durationwm42020-02-201-0/+5
| | | | | | | | | | | | RTSP supports seeking, but at least the libavformat implementation makes this dependent on runtime behavior. So you have to perform a seek, and check if it fails. But even if you do this, the stream is interrupted and restarted, and there seem to be other issues. Assume that RTSP with unknown duration means it's a live stream, and disable seeking in this case, as suggested by the issue reporter. Fixes: #7472
* demux_timeline: don't open every delayed-open track on seekingwm42020-02-201-1/+1
| | | | | | | Now this was stupid. To seek a source, it obviously has to be opened... so just don't try to seek any unused source. If the track is actually selected during playback, a seek to the correct position is performed anyway.
* 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_timeline: warn if streams are invisiblewm42020-02-201-0/+6
| | | | | | | | ytdl_hook.lua can do this with all_formats and when delay_open is used, and if the source stream actually contains both audio and video. In this case, it might accidentally hide a media type completely, or waste bandwidth (if the stream has true interleaved audio/video). So it's important to warn.
* player: print manifest per-stream bitrate information to terminalwm42020-02-191-2/+0
| | | | | Aka hls-bitrate. In turn, remove the demux_lavf.c hack, which made the track title use this.
* 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.
* Remove remains of Libav compatibilitywm42020-02-163-12/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* edl: add mechanism for delay loading streamswm42020-02-154-33/+147
| | | | | | | | | | | | | 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_edl: warn if no_clip is used with multiple partswm42020-02-151-0/+3
| | | | Well whatever.
* demux_edl: allow a redundant new_stream at the beginningwm42020-02-151-1/+4
| | | | | | | Normally, the first sub-stream is implicitly created. This change lets the user use more orthogonal syntax, and use a new_stream header for every sub-stream, instead of having to skip the header for the first one.
* demux_edl: accept protocol entries in EDL entries againwm42020-02-151-1/+4
| | | | | | Accidentally broken by commit 99700bc52c1317. mp_path_join() does not check for this, because it's supposed to work on filesystem strings (and e.g. "http://fubar" is a valid relative path in UNIX).
* demux_edl: improve parsing slightlywm42020-02-151-45/+99
| | | | | | | | | | | Add a mp_log context to the parse_edl() function, and report some errors. Previously, this just told you that something was wrong. Add some error reporting to make it slightly less evil. Put all parameters in a list before processing them. This makes adding parameters for special headers easier, and we can report parameters that were not understood. (For "compatibility", which probably doesn't matter at all, still don't count them as errors; as before.)
* demux_timeline: fix another cursed memory management issuewm42020-02-151-3/+7
| | | | | | | | | | | | | The timeline stuff has messed up memory management because there are no clear ownership rules between a some demuxer instances (master or demux_timeline) and the timeline object itself. This is another subtle problem that happened: apparently, demux_timeline.open is supposed to take over ownership of timeline, but only on success. If it fails, it's not supposed to free it. It didn't follow this, which lead to a double-free if demux_timeline.open failed. The failure path in demux.c calls both timeline_destroy() and demux_timeline.close on failure.
* demux_timeline: fix a commentwm42020-02-151-2/+2
|
* demux_timeline: reorder some functionswm42020-02-151-157/+153
| | | | | | Move them around in the source code to get rid of the forward declarations. Other than rearranging the lines and removing the 2 forward declarations, there are no other changes at all.
* 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
* cue: tolerate NBSP as whitespacewm42020-02-031-5/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Apparently such .cue files exist. They fail both probing and parsing. To make it worse, the sample at hand was encoded as Latin1. One part of this is replacing bstr_lstrip() with a version that supports NBSP. One could argue that bstr_lstrip() should always do this, but I don't want to overdo it. There are many more unicode abomination which it could be said it's supposed to handle, so it will stay ASCII instead of going down this rabbit hole. I'm just assuming this cue sheet was generated by some stupid software that inexplicably liked NBSPs (which is how we justify a one-off fix). The new lstrip_whitespace() doesn't look particularly efficient, but it doesn't have to be. The second part is dealing with the fact that the charset is not necessarily UTF-8. We don't want to do conversion before probing thinks it knows it's a cue sheet (would probably make it more fragile all around), so just make it work with Latin1 by assuming invalid code points are Latin1. This fallback is part of why lstrip_whitespace() is sort of roundabout. (You could still rewrite it as much more efficient state machine, instead of using a slow and validating UTF-8 parser that is called per codepoint. Starting to overthink this.) Multimedia is terrible. Legacy charsets are terrible. Everything is terrible. Fixes: #7429
* libarchive: some shitty hack to make opening slightly fasterwm42020-01-041-0/+20
| | | | | | | | See manpage additions. The libarchive behavior mentioned in the last paragraph there is technically unrelated, but makes this new option mostly pointless. See: #7182
* demux: add per-demuxer sub-optionswm42020-01-042-0/+14
| | | | | | 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.
* stream_libarchive: some more hacks to improve multi-volume archiveswm42020-01-041-2/+2
| | | | | | | | | | 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
* demux_edl: restore relative path resolutionwm42020-01-021-0/+12
| | | | | | | Playing e.g. "dir/f.edl" should make all non-absolute paths in f.edl relative to "dir". Commit 0e98b2ad8ec accidentally broke this.
* 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.
* playlist: change from linked list to an arraywm42019-12-283-6/+6
| | | | | | | | | | | | | | | | | | | Although a linked list was ideal at first, there are cases where it sucks, and became increasingly awkward (with the mpv command API preferring integer indexes to access the list). In future, we probably want to add more playlist-related functionality, so better change it to an array now. An array isn't always ideal either. Since playlist entries are still separate objects (because in some cases you need a stable "iterator" to it), but you still need to efficiently get the next/previous playlist entry, there's a pl_index field, that needs to be maintained. E.g. adding an entry at the start of the playlist => update the pl_index field for all other entries. Well, it's not really worth to do something more complicated to avoid these things. This commit is probably buggy as shit. It's not like I bothered to test everything. That's _your_ role.
* demux: stop setting dummy stream on demux_close_stream()wm42019-12-232-7/+9
| | | | | | | | | | | | | | 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_mf: use stream API to open list fileswm42019-12-231-15/+28
| | | | | | | | | | mf:// has an obscure feature that lets you pass a list of filenames separated by newlines. Who knows whether anyone is using that. It opened these listfiles with fopen(), so the recent stream origin bullshit doesn't operate on it. Fix this by using the mpv internal stream API instead. Unfortunately there is no fgets(), so write an ad-hoc one. (An implementation of line reading via "stream" is still in demux_playlist, but it's better to keep it quarantined there.)
* demux: remove debug abort()wm4</