summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
Commit message (Collapse)AuthorAgeFilesLines
* demux: get rid of an unnecessary fieldwm42017-11-101-15/+13
|
* demux: attempt to accurately reflect seek range with muxed subtitleswm42017-11-101-5/+33
| | | | | | | | | | | | | | | | If subtitles are part of the stream, determining the seekable range becomes harder. Subtitles are sparse, and can have packets in irregular intervals, or even completely lack packets. The usual logic of computing the seek range by the min/max packet timestamps fails. Solve this by making the only assumption we can make: subtitle packets are implicitly demuxed along with other packets. We also assume perfect interleaving for this, but you really can't do anything with sparse packets that makes sense without this assumption. One special case is if we prune sparse packets within the current seekable range. Obviously this should limit the seekable range to after the pruned packet.
* demux: reduce indentation for two functionswm42017-11-101-37/+36
| | | | | Remove the single-exit, that added a huge if statement containing everything, just for some corner case.
* demux: some minor mostly cosmeticswm42017-11-101-13/+15
| | | | | None of these change functionality in any way (although the log level changes obviously change the terminal output).
* demux: simplify a functionwm42017-11-101-21/+19
| | | | | update_stream_selection_state() doesn't need all these arguments. Not sure what I was thinking here.
* demux: change how refreshes on track switching are handledwm42017-11-101-66/+59
| | | | | | Instead of weirdly deciding this on every packet read and having the code far away from where it's actually needed, just run it where it's actually needed.
* demux: get rid of weird backwards loopwm42017-11-101-1/+1
| | | | | | A typical idiom for calling functions that remove something from the array being iterated, but it's not needed here. I have no idea why this was ever done.
* demux: avoid broken readahead when joining rangeswm42017-11-101-4/+5
| | | | | | | | | | Setting ds->refreshing for unselected streams could lead to a nonsensical queue overflow warning, because read_packet() took it as a reason to continue reading. Also add some more information to the queue overflow warning (even if that one doesn't have anything to do with this bug - it was for unselected streams only).
* demux: reduce difference between threaded and non-threaded modewm42017-11-101-27/+35
| | | | | | | | | | | This fixes an endless loop with threading disabled, such as for example when playing a file with an external subtitle file, and seeking to the beginning. Something will set in->seeking, but the seek is never executed, which made demux_read_packet() loop endlessly. (External subtitles will use non-threaded mode for whatever reasons.) Fix this by by making the unthreaded code to execute the worker thread body, which reduces the difference in logic.
* demux: support multiple seekable cached rangeswm42017-11-091-223/+602
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Until now, the demuxer cache was limited to a single range. Extend this to multiple range. Should be useful for slow network streams. This commit changes a lot in the internal demuxer cache logic, so there's a lot of room for bugs and regressions. The logic without demuxer cache is mostly untouched, but also involved with the code changes. Or in other words, this commit probably fucks up shit. There are two things which makes multiple cached ranges rather hard: 1. the need to resume the demuxer at the end of a cached range when seeking to it 2. joining two adjacent ranges when the lowe range "grows" into it (and resuming the demuxer at the end of the new joined range) "Resuming" the demuxer means that we perform a low level seek to the end of a cached range, and properly append new packets to it, without adding packets multiple times or creating holes due to missing packets. Since audio and video never line up exactly, there is no clean "cut" possible, at which you could resume the demuxer cleanly (for 1.) or which you could use to detect that two ranges are perfectly adjacent (for 2.). The way how the demuxer interleaves multiple streams is also unpredictable. Typically you will have to expect that it randomly allows one of the streams to be ahead by a bit, and so on. To deal with this, we have heuristics in place to detect when one packet equals or is "behind" a packet that was demuxed earlier. We reuse the refresh seek logic (used to "reread" packets into the demuxer cache when enabling a track), which checks for certain packet invariants. Currently, it observes whether either the raw packet position, or the packet DTS is strictly monotonically increasing. If none of them are true, we discard old ranges when creating a new one. This heavily depends on the file format and the demuxer behavior. For example, not all file formats have DTS, and the packet position can be unset due to libavformat not always setting it (e.g. when parsers are used). At the same time, we must deal with all the complicated state used to track prefetching and seek ranges. In some complicated corner cases, we just give up and discard other seek ranges, even if the previously mentioned packet invariants are fulfilled. To handle joining, we're being particularly dumb, and require a small overlap to be confident that two ranges join perfectly. (This could be done incrementally with as little overlap as 1 packet, but corner cases would eat us: each stream needs to be joined separately, and the cache pruning logic could remove overlapping packets for other streams again.) Another restriction is that switching the cached range will always trigger an asynchronous low level seek to resume demuxing at the new range. Some users might find this annoying. Dealing with interleaved subtitles is not fully handled yet. It will clamp the seekable range to where subtitle packets are.
* demux: explicitly discard 0 sized packetswm42017-11-061-1/+1
| | | | | | | libavcodec can't deal with them, because its API doesn't distinguish between 0 sized packets and sending EOF. As such, keeping them doesn't do any good, ever. This actually fixes some obscure mkv sample (see previous commit).
* demux: slightly simplify pruningwm42017-11-061-7/+2
| | | | | We can compute the overhead size easily now - no need for awkward incremental updates to cached values on top of it.
* demux: refactoring in preparation for multiple seek range supportwm42017-11-041-83/+214
| | | | | | | | | | | This adds a bunch of stuff (mostly unused or redundant) as preparation for supporting multiple seek ranges. Actual support is probably still far away. One change that messes deeper with the actual code is that we account for total buffered bytes instead of just the backwards bytes now. This way, prune_old_packets() doesn't have to iterate over all seek ranges to determine whether something needs pruning.
* demux: improve and optimize cache pruning and seek range determinationwm42017-11-041-85/+90
| | | | | | | | | | | | | | | | | | | | | | | | | | The main purpose of this commit is avoiding any hidden O(n^2) algorithms in the code for pruning the demuxer cache, and for determining the seekable boundaries of the cache. The old code could loop over the whole packet queue on every packet pruned in certain corner cases. There are two ways how to reach the goal: 1) commit a cardinal sin 2) do everything incrementally The cardinal sin is adding an extra field to demux_packet, which caches the determined seekable range for a keyframe range. demux_packet is a rather general data structure and thus shouldn't have any fields that are not inherent to its use, and are only needed as an implementation detail of code using it. But what are you gonna do, sue me? In the future, demux.c might have its own packet struct though. Then the other existing cardinal sin (the "next" field, from MPlayer times) could be removed as well. This commit also changes slightly how the seek end is determined. There is a note on the manpage in case anyone finds the new behavior confusing. It's somewhat cleaner and might be needed for supporting multiple ranges (although that's unclear).
* demux: reduce overhead when searching over keyframe rangeswm42017-11-041-31/+37
| | | | | | | | | | The demuxer cache seeking mechanism looks at keyframe ranges to determine the earlierst PTS of a packet. Instead of looping over all packets twice (once to find the next keyframe, a second time to find the seek PTS), do it in one go. For that basically turn recompute_keyframe_target_pts() into an iteration functionn. Functionality should be unchanged with this commit.
* demux: avoid excessive readahead after cache seekwm42017-11-041-1/+3
| | | | | | | | | | | | The base_ts field is used to guess the decoder position, and when set to NOPTS, it just read ahead arbitrarily. Also demux_add_packet() sets base_ts to the new timestamp when appending a packet, which would also make it readahead by a too large amount. Fix this by setting base_ts after a seek. This assumes that normally, a cached seek target will always have the timestamp set. This is actually not quite clear (as it calls recompute_keyframe_target_pts(), which looks at multiple packets), but maybe it works well enough.
* demux: make pruning more efficient for unseekable demuxer cachewm42017-11-041-19/+24
| | | | | | | | | Don't do any of the extra work related to pruning the backbuffer if demuxer cache seeking is disabled. As a small extra, always prune packets with no timestamps immediately, or queue heads that are not keyframes. (Both of them would be pruned from the backbuffer by the normal logic anyway.)
* demux: on queue overflow wake up reader thread on EOF onlywm42017-11-031-1/+1
| | | | This seems to make more sense.
* demux: don't show queue overflow warning when merely prefetchingwm42017-11-031-6/+7
| | | | | | | | | | | | | If fulfilling --demuxer-readahead-secs requires more memory than allowed by --demuxer-max-bytes, the queue obviously overflows. But the warning is normally only for the case when trying to find the next video or audio packet fails, and decoding can't continue. Use a separate variable for determining whether to prefetch, and if the queue has overflown, skip the message. In fact, skip the EOF setting and waking up the decoder thread as well, because the EOF flag should not be (have been) set in this situation, and waking up the reader thread helps only if the EOF state changed.
* demux: don't allow subtitles to mess up buffered time displaywm42017-11-031-1/+2
| | | | | | | | | | | In a shit show of subtle corner case interactions, making the demuxer cache buffer the entire file can display a small buffered time if subtitles are enabled. The reason is that some subtitle decoders may read in advance infinitely, i.e. they read the entire subtitle stream. Then, since the other streams (audio/video) have logically reached EOF, and the subtitle stream is set to ds->active==true. This will have to be fixed properly later to account buffering for subtitle-only files (another corner case) correctly, but for now this is less annoying.
* demux: add option to create CC tracks eagerlywm42017-11-031-15/+46
| | | | | | | | | | | | We don't hope to auto-detect them at load time, as that would be too much of a pain - even FFmpeg requires fetching and parsing of video packets, and exposes the information only via deprecated API. But there still needs to be a way to select them by default. This is also needed to get the first CC packet at all (without seeking back). This commit also attempts to clean up locking a bit, which is a PITA, but it's better be careful & clean.
* demux: refactor to export seek rangeswm42017-10-301-29/+29
| | | | | | | | | | | | | | | | | | | | Even though only 1 seek range is supported at the time. Other than preparation for possibly future features, the main gain is actually that we finally separate the reporting for the buffering, and the seek ranges. These can be subtly different, so it's good to have a clear separation. This commit also fixes that the ts_reader wasn't rebased to the start time, which could make the player show "???" for buffered cache amount in some .ts files and others (especially at the end, when ts_reader could become higher than ts_max). It also fixes writing the cache-end field in the demuxer-cache-state property: it checked ts_start against NOPTS, which makes no sense. ts_start was never used (except for the bug mentioned above), so get rid of it completely. This also makes it convenient to move the segment check for last_ts to the demux_add_packet() function.
* demux: better computation of seek start targetwm42017-10-251-8/+24
| | | | | | | | | | | | Avoids that cache seeking is not possible with files that have audio frames with no timestamps (such as avi, sometimes mkv sub-packets from lacing). These would set back_pts (first seekable PTS) to NOPTS, and thus disable cache seeking completely. Instead, prune such packets until we find one with timestamps. One corner case is that the new next good packet might be in the forward cache. In this case we defer dropping until the next time this code is run, and the reader position has possibly moved past the drop point.
* demux: reject cache seeks if parts of the range are unsetwm42017-10-251-2/+3
| | | | | | | | In theory, start/ts_min could be set to NOPTS, in which case "pts < start" for a valid pts would always evaluate to false. Also remove the redundant "in-cache seek is possible.." message, as there's always another message when cache seeks are done.
* demux: fall back to DTS when determining seek targetwm42017-10-251-1/+1
| | | | | Fixes AVI in particular, which abuses DTS for reordered PTS. (It's not really DTS...)
* demux: disallow seeking if there are streams with no timestampswm42017-10-251-3/+7
| | | | | | The seek range computation ignored streams with no timestamps. For things like buffer estimation this is OK and wanted, but the seek range needs to be conservative.
* demux: fix tracking of forward/backward cache sizewm42017-10-251-8/+15
| | | | | | | | | | | | Which parts of the queue are considered forward or backward cache depends on ds->reader_header. The packet at ds->reader_head, as well as all packets following it (via the ->next field) are considered forward. The fw_packs/fw_bytes/bw_bytes must be updated accordingly. This broke in demux_add_packet(), when ds->reader_head was _not_ set on the first packet (or before). This could happen since commit 05ae571241a, which can require skipping packets (so they immediately end up in the backbuffer).
* demux: respect timeline boundaries for cache seekswm42017-10-251-7/+17
| | | | | | | | | With the timeline code, a packet at the start or end of a segment can refer to an invisible frame. So it doesn't extend the seek range, and the timestamp should be clipped to the actual segment range. Also restructure recompute_keyframe_target_pts() to be hopefully less confusing.
* demux: don't report unknown queue state if no packets were addedwm42017-10-251-1/+3
| | | | | | Restores some behavior from before the demuxer cache changes, though affects mostly just OSD display. The unknown queue state is reserved for streams with missing or messed up timestamps.
* demux: set correct stream index for attached pictureswm42017-10-251-1/+5
| | | | | | This fixes .cue files with audio files that contain attached pictures to some degree. demux_timeline.c just discarded packets with unset index, so the picture was never fed to the decoder.
* demux: fix cached SEEK_FORWARD seeks into end of cached regions/EOFwm42017-10-231-3/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Although seeking past the cached range will trigger a low level seek, a seek into the region between cache end and last video key frame would simply seek to the video key frame. This meant that you could get "stuck" at the end of the file instead of terminating playback when trying to seek past the end. One change is that we fix this by _actually_ allowing SEEK_FORWARD to seek past the last video keyframe in find_seek_target(). In that case, or otherwise seeking to cache buffer end, it could happen that we set ds->reader_head=NULL if the seek target is after the current packet. We allow this, because the end of the cached region is defined by the existence of "any" packet, not necessarily a key frame. Seeking there still makes sense, because we know that there is going to be more packets (or EOF) that satisfy the seek target. The problem is that just resuming demuxing with reader_head==NULL will simply return any packets that come its way, even non-keyframe ones. Some decoders will produce ugly soup in this case. (In practice, this was not a problem, because seeking at the end of the cached region was rare before this commit, and also some decoders like h264 will skip broken frames by default anyway.) So the other change of this commit is to enable key frame skipping. As a nasty implementation detail, we use a separate flag, instead of setting reader_head to the first key frame encounted (reader_head being NULL can happen after a normal seek or on playback start, and then we want to mirror the underlying demuxer behavior, for better or worse). This change is relatively untested, so you get to keep the pieces for yourself.
* demux: report buffered duration of 0 during seeking instead of unknownwm42017-10-231-3/+5
| | | | Looks ugly on the status line and could upset the buffering logic.
* demux: drop redundant SEEK_BACKWARD flagwm42017-10-231-9/+5
| | | | | | | | | | | | | Seems like most code dealing with this was for setting it in redundant cases. Now SEEK_BACKWARD is redundant, and SEEK_FORWARD is the odd one out. Also fix that SEEK_FORWARD was not correctly unset in try_seek_cache(). In demux_mkv_seek(), make the arbitrary decision that a video stream is not required for the subtitle prefetch logic to be active. We might want subtitles with long duration even with audio only playback, or if the file is used as external subtitle.
* command: read the diff if you want to knowwm42017-10-211-0/+1
|
* *** empty log message ***wm42017-10-211-2/+0
|
* demux: replace redundant field with a better redundant fieldwm42017-10-211-8/+7
|
* demux: add a back buffer and the ability to seek into itwm42017-10-211-148/+340
| | | | | | | | | | | | | | | | | | | | | | | | This improves upon the previous commit, and partially rewrites it (and other code). It does: - disable the seeking within cache by default, and add an option to control it - mess with the buffer estimation reporting code, which will most likely lead to funny regressions even if the new features are not enabled - add a back buffer to the packet cache - enhance the seek code so you can seek into the back buffer - unnecessarily change a bunch of other stuff for no reason - fuck up everything and vomit ponies and rainbows This should actually be pretty usable. One thing we should add are some properties to report the proper buffer state. Then the OSC could show a nice buffer range. Also configuration of the buffers could be made simpler. Once this has been tested enough, it can be enabled by default, and might replace the stream cache's byte ringbuffer. In addition it may or may not be possible to keep other buffer ranges when seeking outside of the current range, but that would be much more complex.
* demux: optimize seeks within readahead cacheAman Gupta2017-10-211-12/+104
| | | | | If a suitable keyframe cannot be found in each stream's readahead cache, fallback to a regular seek.
* demux: improvements to previous commitswm42017-10-201-9/+18
| | | | | | | | | | | | | | | | | | | | | | | | | More the ignore_eof field to the internal demux_stream struct. This is relatively messy, because the internal struct exists only once the stream is created, and after that setting the ignore_eof flag is a race condition. We could bother with adding demux_add_sh_stream() parameters for this, but let's not. So in theory a tiny race condition is introduced, which can never be triggered since all demux API functions are called by the playback thread only anyway. Fix that ts_offset is accessed without log (this was introduced much earlier by myself). Introduce an alternative way of avoiding the annoying EOF reached messages by not resetting the EOF flags for CC streams when a CC packet is added. This makes the second commit in the PR which added the original fix unnecessary. As another cosmetic change merge the check in cached_demux_control() into a single if(). In the future, the CC pseudo-stream should probably be replaced with an entire pseudo-demuxer or such, which would avoid some of the messiness (or maybe not, we don't know yet).
* demux: ignore false underrun reporting from eia_608 captions decoderAman Gupta2017-10-201-0/+3
|
* demux/demux: avoid redundant conditionRaúl Peñacoba2017-07-011-1/+1
| | | | Closes #4414
* demux: change license to LGPLwm42017-06-201-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | As usual, the history of these files is a bit murky. It starts with the initial commit. (At which some development had already been done, according to the AUTHORS and ChangeLog files at the time, we should be but covered with relicensing agreements, though.) then it goes on with complete lack of modularization, which was cleaned up later (cd68e161). As usual, we don't consider the copyright of the stuff that has been moved out cleanly. There were also contributions to generic code by people who could not be reached or who did not agree to the relicensing, but this was all removed. The only patches that we could not relicense and which were still in the current code in some form are from Dénes Balatoni: 422b0d2a, 32937181. We could not reach him, so commits f34e1a0d and 18905298 remove his additions. It still leaves the demux_control() declaration itself, but we don't consider it copyrightable. It's basically an idiom that existed in MPlayer before that change, applied to the demuxer struct. (We even went as far as making sure to remove all DEMUXER_CTRLs the original author added.) Commit be54f481 might be a bit of a corner case, but this was rewritten, and we consider the old copyright removed long ago.
* demux: get rid of DEMUXER_CTRL_GET_TIME_LENGTHwm42017-06-201-21/+1
| | | | | | | | | | | | Similar purpose as f34e1a0deea45e. Somehow this is much more natural too, and needs less code. This breaks runtime updates to duration. This could easily be fixed, but no important demuxer does this anyway. Only demux_raw and demux_disc might (the latter for BD/DVD). For the latter it might actually have some importance when changing titles at runtime (I guess?), but guess what, I don't care.
* demux: replace custom return codes with CONTROL_ oneswm42017-06-191-10/+10
| | | | | | | | This is more uniform, and potentially gets rid of some past copyrights. It might be that this subtly changes caching behavior (it seems before this, it synced to the demuxer if the length was unknown, which is not what we want.)
* demux: estimate total packet size, deprecate packet number limitswm42017-04-141-4/+5
| | | | | | | It's all explained in the DOCS changes. Although this option was always kind of obscure and pointless. Until it is removed, the only reason for setting it would be to raise the static default limit, so change its default to INT_MAX so that it does nothing by default.
* demux: try not to read packets when cancelledwm42017-02-041-1/+3
| | | | | | Essentially, this will make it abort sooner. Especially with DASH it might avoid confusing error messages, although exact behavior depends on timing.
* player: different way to auto-enable the demuxer cachewm42017-02-021-6/+7
| | | | | | | | | | | | | | | Instead of enabling it only when a stream-cache is enabled, also try to enable it independently from that if the demuxer is marked as is_network. Also add some code to the EDL code, so EDLs containing network streams are automatically cached this way. Extend the OSD info line so that it shows the demuxer cache in this case (more or less). I didn't find where or whether options.rst describes how the demuxer cache is enabled, so no changes there.
* stream: better method signal caching, rename weird uncached_stream fieldwm42017-02-021-3/+2
| | | | | | | | "uncached_stream" is a pretty bad name. It could be mistaken for a boolean, and then its meaning would be inverted. Rename it. Al