summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* packet: change memory estimation heuristicswm42019-09-191-2/+5
| | | | | | | | | | | | | | | | | | | | Determining how much memory something uses is very hard, especially in high level code (yes we call code using malloc high level). There's no way to get an exact amount, especially since the malloc arena is shared with the entire process anyway. So the demuxer packet cache tries to get by with an estimate using a number of rough guesses. It seems this wasn't quite good. In some ways, it was too optimistic, in others it seemed to account for too much data. Try to get it closer to what malloc and ta probably do. In particular, talloc adds some singificant overhead (using talloc for mass-data was a mistake, and it's even my fault). The result appears to match better with measured memory usage. This is still extremely dependent on malloc implementation and so on. The effect is that you may need to adjust the demuxer cache limits to cache as much data as it did before this commit. In any case, seems to be better for me.
* packet: free some unnecessary memory in disk cache casewm42019-09-191-1/+2
| | | | | | | | | If the disk cache is used, the AVPacket is not used anymore and is completely deallocated when the packet is written to disk. As a minor bug, the AVPacket allocation itself was not freed (although it wasn't a memory leak, since talloc still automatically freed it when the entire demux_packet was freed). For very large caches, this could easily add up to over hundred MB, so actually free the unneeded allocation.
* vd_lavc: put vaapi before vdpau in autoprobe orderwm42019-09-191-2/+2
| | | | | | | | | --hwdec=auto-copy was preferring vdpau over vaapi. In the HEVC 10 bit case, this also led to hardware decoding not being enabled. (Probably because the probing can't start over after enabling hw decoding fails at runtime, or something like that.) Possible that this subtly breaks on some setups. You can't always win.
* vo_gpu: hwdec_vaegl: silence confusing message during probingwm42019-09-191-2/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During probing on a system with AMD GPU, mpv used to output the following messages if hardware decoding was enabled: [ffmpeg] AVHWFramesContext: Failed to create surface: 2 (resource allocation failed). [ffmpeg] AVHWFramesContext: Unable to allocate a surface from internal buffer pool. This commit removed the message, with hopefully no other side effects. Long explanations follow, better don't read them, it's just tedious drivel about the details. People should learn to write concise commit messages, not drone on and on endlessly all while they have no fucking point. The code probes supported hardware pixel format, and checks whether they can be mapped as textures. av_hwdevice_get_hwframe_constraints() returns a list of hardware pixel formats in the valid_sw_formats field (the "sw" means software, but they're still hardware pixel formats, makes sense). This contained the format yuv420p, even though this is not a valid hardware format. Trying to create a surface of this type results in VA surface creation failure, upon which FFmpeg prints the error messages above. We'd be fine with this, except FFmpeg has a global log callback, and there's no way to suppress these messages without creating other issues. It turns out that FFmpeg's vaapi implementation returns all formats from vaQueryImageFormats() if no "hwconfig" is provided. This list includes yuv420p, which is probably supported for surface upload/download, but not as native format. Following FFmpeg's logic, it should not appear in the valid_sw_formats list, because formats for transfers are returned by another roundabout API. Idiotically, there doesn't seem to be any vaapi call that determines whether a format is a valid surface format. All mechanisms to do this are bound to a VAConfigID (= video codec or video processor), all while the actual surface creation API strangely does not take a VAConfigID (a big WTF). Also, calling the vaCreateSurfaces() API ourselves for probing is out of the question, because that functions is utterly and idiotically complex. Look at the FFmpeg code and how much effort it requires to setup a complete set of attributes - we can't duplicate this. So the only way left to do this is the most idiotic and tedious way: enumerating all VAProfile (and VAEntrypoints) to create all possible VAConfigIDs. Each of the VAConfigIDs is associated with a list of formats, which FFmpeg can return (by passing the ID along with the "hwconfig"), and which is probed separately. Note that VAConfigID actually refers to a dynamic instance of something, and creating a VAConfigID takes not only the VAProfile and the VAEntrypoint, but also an arbitrary attribute array. In theory, this means our attempt to get to know all possible configurations cannot work, but in practice this attribute array seems to be pointless for decoding and video processing, and FFmpeg doesn't use it (though the encoding path does use it). This probably just makes it _barely_ OK to do it this way. Could we discard all this probing shit, and somehow do it another way? Probably not. The EGL API for mapping surfaces doesn't even seem to provide a way to enumerate supported formats, we may not even know whether DRM/dmabuf interop is actually supported (AFAIR the EGL extensions are present even if they don't work), nor do we know whether the VAAPI driver supports this interop (not sure). So actually trying is the only way. Further, mpv initializes the decoder on a another thread, where you can't just access OpenGL state. This suckage is mostly to be blamed on OpenGL itself and its crazy thread boundedness. In theory, this could be done anyway (see how software decoding "direct rendering" tries to get around this). But to make it worse, the decoder never cares about the list of supported formats determined by this code; instead, f_autoconvert.c tries to deal with it and insert a video processor (well, good luck with this crap, I bet it doesn't even work). So this whole endeavor might be pointless, other than the fact that failed probing can disable use of vaapi (which is correct and necessary). But if you have a shovel, you don't use it to smash the flat end on the heap of shit that's piled up before you, or do you? While this method probably works, it's still orgasmically tedious. It was tedious before: we had to create a real surface, create a GL texture, map the surface with it, then destroy everything again. But the added code is tedious on its own. Highlights include the need to malloc a FFmpeg struct just to pass a single damn integer, the need to enumerate "entrypoints" for each VA profile, even though all profiles have exactly 1 entrypoint, and the kind of obnoxious way how vaapi requires you to preallocate arrays for returned things, even they could for example reasonably be returned as immutable arrays or have some other simpler API. The main grand fuckup is of course that vaapi requires a VAConfigID to query surface properties, but not for creating surfaces. This awkwardness even affected the FFmpeg API design, which has a "hwconfig" concept that is only used by vaapi (vaapi is only 1 out of 10 hardware decoding APIs supported by the FFmpeg hwcontext stuff). Maybe I'm just missing something. It's as if vaapi required setting radioactive shit on fire. Look how clean the native D3D11 code is instead. (Even the ANGLE code manages to avoid being this fucked up. Or the VDPAU code, despite supporting multiple mapping methods.) Another only barely related change is that the valid_sw_formats field can be NULL, and the API explicitly documents this. Technically, the mpv code was buggy for not checking this, although until now the FFmpeg implementation so far could not return it when we still passed NULL for the hwconfig parameter.
* vo_gpu: hwdec_vaegl: refactor format probingwm42019-09-191-40/+64
| | | | | | | | | | | No functional changes, just preparation for the next commit. Split the probing into multiple functions. Prepare for the yet unused possibility to pass AVVAAPIHWConfig to probing. try_format_pixfmt() now assumes it can be called multiple times with the same format, so it filters the format. The format probing is now something like O(n^2) for n formats, but n will most likely remain something under 50 or so.
* m_config: fix typo in commentwm42019-09-191-1/+1
|
* recorder: use shared PTS macroswm42019-09-191-9/+7
| | | | | | | | These macros explicitly honor MP_NOPTS_VALUE, instead of implicitly relying on the fact that this value is the lowest allowed value. In addition, this changes one case to use MP_NOPTS_VALUE instead of INFINITY, also a cosmetic change.
* demux: honor seek discontinuities with --stream-recordwm42019-09-191-0/+3
| | | | Do the same thing --record-file does when seeks happen.
* demux: runtime option changing for cache and stream recordingwm42019-09-192-35/+106
| | | | | | | | | Make most of the demuxer options runtime-changeable. This includes the cache options and stream recording. The manpage documents some of the possibly weird issues related to this. In particular, the disk cache isn't shuffled around if the setting changes at runtime.
* m_config: add an assert for a theoretical issuewm42019-09-191-1/+6
| | | | | | | | | | Or at least I hope it's theoretical. This function is supposed to unset any old listeners for the given cache, and the code works only if there's at most 1. Add a defense break to avoid UB if there's more than one, and add an assert() to check the assumption that there's at most one. The added comment is unrelated.
* demux: enable --stream-record for things using timelinewm42019-09-191-0/+2
| | | | | | | | | | | | Although this is not useful in general, it makes --stream-record work with a certain video streaming service by a large dystopian company. In the general case, this fails because normal muxing can, quite obviously, not handle the segmented metadata in the packets. (There isn't even a file format which could handle these, except possibly mp4.) On the other hand, ytdl merely uses timeline/EDL to emulate DASH streaming (unfortunately), which does not use the segmented stuff, and stream recording will actually work.
* win32: remove -municode from mpv binarywm42019-09-192-9/+7
| | | | | | | | | | | | | If this is used, the runtime expects that wmain() instead of main() is defined. This caused me severe problems in a certain now irrelevant case. I think it's a good idea to avoid this special case. We can just use main() and call GetCommandLineW() instead. This function returns a single string, so use CommandLineToArgvW() to split it, and hope it has the same semantics. Should this ever return NULL, hope that it leaves argc at 0. Untested, I think.
* build: stop defining _LARGEFILE[64]_SOURCEwm42019-09-191-3/+1
| | | | | | | | | | _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE are not required for 64 bit off_t, only _FILE_OFFSET_BITS. See somewhere on: https://wiki.musl-libc.org/faq.html I didn't test this anywhere except 64 bit Linux. It's probably a good idea to test on Windows and all Android versions.
* build: better POSIX checkwm42019-09-191-3/+1
| | | | This is the "official" method to do this.
* vf_vapourynth: remove Lua backendwm42019-09-196-283/+4
| | | | | | | | | | | | | | | I once created this because someone wanted to use vapoursynth without the Python dependency. No idea if anyone ever actually used it. It's sort of icky (it calls itself "lazy" to preempt complaints about how much it sucks), and complicates the build process. Kill it. It seems much more promising to have something like this: https://github.com/vapoursynth/vapoursynth/issues/386 This would either solve the build distribution problem by relaxing the Python dependency, and/or allow a Lua backend to be included without pain.
* audio: remove unreferenced af_lavrresamplewm42019-09-193-151/+0
| | | | | | | | | | | | | | This filter wasn't referenced anywhere and thus was dead code. It should have been in the audio filter list in user_filters.c. This was intended as compatibility wrapper (to avoid breaking old command lines and config files), and has no real use. Apparently I forgot to add it to the filter list (did I even test this shit?), and so it was rotting around for 1.5 years doing nothing (just like myself). Note that users can just use the libavfilter provided filter to force resampling, just that it has a different name and different options. There's also af_format to force inserting auto conversion through the internal f_swsresample filter.
* vo_gpu: remove vdpau/GLX backendwm42019-09-193-422/+0
| | | | | | | Useless garbage. This was once added to test whether vdpau presentation feedback could be used. Results were always unsatisfactory, and now vdpau is dead.
* vo_gpu: remove mali-fbdevwm42019-09-195-176/+2
| | | | | Useless at this point, I don't even know if it still works, or how to test it.
* manpage: fix minor typowm42019-09-191-1/+1
|
* stats.lua: add graphs for readahead time and total byte usagewm42019-09-191-6/+58
| | | | | | | | | | | | | The readahead time should be interesting for latency vs. underruns (which idiot protocols like HLS suffer from). The total byte usage is less interesting than I hoped; maybe the frequency at which it samples should be reduced. (Kind of dumb - you want high frequency for the readahead field, but much lower for byte usage.) Of course, the code was copy&pasted from the DS ratio/jitter stuff. Some of the choices may not make any sense for the new code.
* msg: remove unnecessary conditionwm42019-09-191-4/+0
| | | | Atomics were made mandatory some time ago.
* demux_mkv: add hacks to avoid a single warningwm42019-09-191-9/+26
| | | | | | | | | | | | | | It prints "Unexpected end of file (no clusters found)" when opening a webm init fragment. The warning is correct, but unwanted in this case. Add tons of kludges to avoid it. (Actually it prints that twice, for audio and video each.) Also, suppress another warning about a seek head entry that points exactly to the end of the file. This is a MATROSKA_ID_CUES, which is harmless, and, very strangely, doesn't point at any cues when you concatenate the init fragment with a media fragment. No idea what that crap is supposed to be.
* demux: make webm dash work by using init fragment on all demuxerswm42019-09-192-32/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Retarded webshit streaming protocols (well, DASH) chop a stream into small fragments, and move unchanging header parts to an "init" fragment to save some bytes (in the case at hand about 300 bytes for each fragment that is 100KB-200KB, sure was worth it, fucking idiots). Since mpv uses an even more retarded hack to inefficiently emulate DASH through EDL, it opens a new demuxer for every fragment. Thus the fragment needs to be virtually concatenated with the init fragment. (To be fair, I'm not sure whether the alternative, reusing the demuxer and letting it see a stream of byte-wise concatenated fragmenmts, would actually be saner.) demux_lavc.c contained a hack for this. Unfortunately, a certain shitty streaming site by an evil company, that will bestow dytopia upon us soon enough, sometimes serves webm based DASH instead of the expected mp4 DASH. And for some reason, libavformat's mkv demuxer can't handle the init fragment or rejects it for some reason. Since I'd rather eat mushrooms grown in Chernobyl than debugging, hacking, or (god no) contributing to FFmpeg, and since Chernobyl is so far away, make it work with our builtin mkv demuxer instead. This is not hard. We just need to copy the hack in demux_lavf.c to demux_mkv.c. Since I'm not _that_ much of a dumbfuck to actually do this, remove the shitty gross demux_lavf.c hack, and replace it by a slightly less bad generic implementation (stream_concat.c from the previous commit), and use it on all demuxers. Although this requires much more code, this frees demux_lavf.c from a hack, and doesn't require adding a duplicated one to demux_mkv.c, so to the naive eye this seems to be a much better outcome. Regarding the code, for some reason stream_memory_open() is never meant to fail, while stream_concat_open() can in extremely obscure situations, and (currently) not in this case, but we handle failure of it anyway. Yep.
* stream: add a generic concat implementationwm42019-09-193-0/+165
| | | | | | This is not available to users. It can be used only though the stream_concat_open(). It's unused yet; to be used in the following commit.
* demux: never set demux->stream for timeline messwm42019-09-191-27/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Timeline (demux_timeline, for EDL and mkv ordered chapters) are a mess, because it's the only nested demuxer case. Part of the mess comes from shared struct stream pointers. This makes no sense, because the wrapper (demux_timeline) doesn't have any business setting it. Try to lessen it by not passing down streams. Instead, pass down NULL. This prevents unintended interference, and tightens the ownership rules. Now a demuxer always owns its stream. On the other hand, demuxer->stream can now be NULL. This was never the case before, and consequently there will be new bugs. At least they will be spotted, because they've been bugs before. struct stream is also used to access stream properties (such as whether something is considered a network stream). Most of these have been mirrored in struct demuxer (because the frontend has been forbidden to access struct stream because of threading). But during initialization was still used, so introduce an awkward struct parent_stream_info, which unifies these. Commit e0419fb181b3d2 changed demux_is_network_cached() to use demuxer->stream->streaming instead of demuxer->is_network. To enable timeline stuff to use the cache anyway, change it so that both flags can contribute to it. The stream NULL-check is obviously due to changes in this commit.
* stream: create memory streams in more straightforward waywm42019-09-197-44/+62
| | | | | | | | | | | | | | | Instead of having to rely on the protocol matching, make a function that creates a stream from a stream_info_t directly. Instead of going through a weird indirection with STREAM_CTRL, add a direct argument for non-text arguments to the open callback. Instead of creating a weird dummy mpv_global, just pass an existing one from all callers. (The latter one is just an artifact from the past, where mpv_global wasn't available everywhere.) Actually I just wanted a function that creates a stream without any of that bullshit. This goal was slightly missed, since you still need this heavy "constructor" just to setup a shitty struct with some shitty callbacks.
* demux_playlist: extend maximum line sizewm42019-09-191-1/+1
| | | | | | | | Raise it from 8KB to 512KB. Do this because ytdl_hook.lua generated a 40KB EDL file (from 80KB youtube-dl JSON output), and putting it into a .m3u file for easier debugging failed due to the size limit.
* common: add macro for checking whether a value is a power of twowm42019-09-191-0/+1
| | | | | | | I think I repeated this inline in some places (or maybe not), and some experimental but discarded code used it. Add it anyway, maybe it'll be useful. Or it'll give someone a chance to get a contribution into mpv by removing an unused macro.
* demux: fix backward demuxing not grabbing all audio packetswm42019-09-191-5/+5
| | | | | | | | | | | | | | | | The previous commit broke audio playback (maybe this is what 4. was about?). But it wasn't the fault of the commit; it just exposed pre-existing issues. If the packet queue search can't get all packets, it checked queue->is_bof to see whether there could be previous packets. But obviously, is_bof can be set, even if the search start packet wasn't the first one. This was especially observable with audio, because audio by default needs preroll packets, and plays artifacts if they're missing. Fix by using the BOF playback condition for this purpose too.
* demux: another questionable backwards playback mud partywm42019-09-191-5/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In theory, backward demuxing does way too much work by doing a full cache seek every time you need to step back through a packet queue. In theory, it would be exceedingly more efficient to just iterate backwards through the queue, but this is not possible because I'm too stingy to add 8 bytes per packet for backlinks. (In theory, you could probably come up with some sort of deque, that'd allow efficient iteration into any direction, but other requirements make this tricky, and I'm currently too dumb/lazy to do this. For example, the queue can grow to millions of elements, all while packet pointers need to stay valid.) Another possibility is to "locally" seek the queue. This still has less overhead than a full seek. Also, it just so happens that, as a side effect, this avoids performing range merging, which commit f4b0e7e942 "broke". That wasn't a bug at all, but since range joining is relatively slow, avoiding it is good. This is really just a coincidental side effect, I'm not even quite sure why it happens this way. There are 4 ugly things about this change: 1. To get a keyframe "before" a certain one, we recompute the target PTS, and then subtract 0.001 as arbitrary number to "fudge" it. This isn't the first place where this is done, and hey, it wasn't my damn idea that MPlayer should use floats for timestamps. (At first, it even used 32 bit timestamps.) 2. This is the first time reader_head is reset to an earlier position outside of the seek code. This might cause conceptual problems since this code is now "duplicated". 3. In theory, find_backward_restart_pos() needs to be run again after the backstep. Normally, the seek code calls it explicitly. We could call it right in the new code, but then the damn function would be recursive. We could shuffle the code around to make it a loop, but even then there'd be an offchance into running into an unexpected corner case (aka subtle bug), where it would loop forever. To avoid refactoring the code and having to think too hard about it, make it deferred - add some new state and the check_backward_seek() function for this. Great, even more subtle mutable state for this backwards shit. 4. I forgot this one, but I can assure you, it's bad. Without doubt someone will have to clean up this slightly in the future (or rip it out), but it won't be me.
* demux: remove some redundancy in backward playback codewm42019-09-191-6/+5
| | | | | | | | | | | This code tries to determine the "current" position, which is used as base for the seek target when it needs to seek back more (the point is to prevent seeking back too far). But compute_keyframe_times() almost computes the same thing, so use that. Unfortunately needs a forward declaration. ("Almost", because it differs in some details that should not really matter.)
* demux_mkv: fix subtitle preroll in some caseswm42019-09-191-7/+6
| | | | | | | | | | | | | | | | | | | | | | Subtitle packets with a timestamp before the seek target may overlap with the seek target anyway. This is why this subtitle preroll crap exists: it needs to return packets before the seek target to ensure that the subtitle is displayed at the seek target. This didn't always work. Maybe it's a regression, but it must have been an old one. The breakage is triggered by heuristic that is to prevent excessive queuing of packets in garbage files (this heuristic apparently became immediately necessary when this preroll mechanism was implemented). If a video keyframe packet was found, but no audio packet yet, then subtitle_preroll was set to 0, and since a_skip_to_keyframe was still 0, the subtitle packet was discarded. The dumb thing is that subtitle and video seeking is finished at this point, so the preroll crap should not be applied at all. Fix this by moving the preoll overflow code into the block that handles preroll.
* osc: add feature to bottombar to not cover the videowm42019-09-192-1/+67
| | | | | | | | | | | | | | | | | | | | | | Normally I use the OSC like this: not at all, but have a key binding that does "cycle osc" to show it. And in that case, I don't really want it to overlap the damn video. I could use the zoom/pan options to move the video out of the way, but this is also sort of annoying. Likewise, you could write a script or so which does this automatically if the OSC appears, but that's still annoying, and computing values for these options such that the video is moved correctly is tricky. So I added a bunch of options that set explicit video borders (previous commit), and a option for the OSC to use them (this commit). Disabled by default, since I'm afraid this is too awkward and unpolished, especially with OSC default settings. I'm also using "osc-visibility=always". Effectively, making the OSC appear will box the video, and making it disappear (by unloading osc.lua) will restore the video back to normal.
* aspect: add video margin optionswm42019-09-194-5/+73
| | | | | | | | | | | | | | | Semantics a bit questionable. This is done for the OSC (next commit), and a comment added the manpage explicitly states this. Meaning this is probably garbage and needs to revisit when the OSC changes and/or someone wants to use this margin feature for something else. Not sure about the subtitle thing. It's imaginable that someone uses these options to create empty borders for subtitles on the bottom, so subtitles should be located there. On the other hand, this gives a rather unpolished user experience when using the (later added) OSC feature to not overlap with the video. There's not much of a point if the OSC still overlaps the video. However, I'm too lazy to think about this, so it stays like it is.
* aspect: fix some UB problems in corner caseswm42019-09-191-6/+6
| | | | | | | | | | | --video-margin-ratio-left=0.2 --video-margin-ratio-right=0.9 (added in the the next commit) will set f_w to inf, resulting in some garbage being propagated. Later, the OSD margins are computed from values before various sanity clamping is applied, which makes libass suffer from bullshit values. I'm very sure it's OK and more correct to compute the OSD margins using the later values, but I'm not sure about that.
* stats.lua: add cache info pagewm42019-09-191-4/+69
| | | | Uses page 3, which was apparently reserved for filter info.
* manpage: fix false statementwm42019-09-191-2/+2
|
* demux: turn some redundant assignments into assertswm42019-09-191-3/+5
| | | | | | | | demux_packet.next should not be used outside of demux.c, and in this case it's a packet that was just passed to demux.c from the outside. demux_packet.stream is already set by the demuxer, and this is assured by the add_packet_locked() caller.
* demux: move a functionwm42019-09-191-14/+12
| | | |