summaryrefslogtreecommitdiffstats
path: root/filters
Commit message (Collapse)AuthorAgeFilesLines
* options: change how option range min/max is handledwm42020-03-132-5/+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.
* options: split m_config.c/hwm42020-03-131-1/+1
| | | | | | | | | | | | | | | | | Move the "old" mostly command line parsing and option management related code to m_config_frontend.c/h. Move the the code that enables other part of the player to access options to m_config_core.c/h. "frontend" is out of lack of creativity for a better name. Unfortunately, the separation isn't quite clean yet. m_config_frontend.c still references some m_config_core.c implementation details, and m_config_new() is even left in m_config_core.c for now. There some odd functions that should be removed as well (marked as "Bad functions"). Fixing these things requires more changes and will be done separately. struct m_config is left with the current name to reduce diff noise. Also, since there are a _lot_ source files that include m_config.h, add a replacement m_config.h that "redirects" to m_config_core.h.
* options: remove min/max support from strings and string listswm42020-03-131-4/+4
| | | | | We don't really use this anymore. Only --playlist and vf_lavfi filter names did (to error on empty parameters), but it doesn't really matter.
* filter: minor cosmetic naming issuewm42020-03-084-39/+45
| | | | | Just putting some more lipstick on the pig, maybe it looks a bit nicer now.
* f_decoder_wrapper: make decoder thread responsive while filling queuewm42020-03-051-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | The mp_filter_run() invocation blocks as long as the demuxer provides packets and the queue can be filled. That means it may block quite a long time of the decoder queue size is large (since we use libavcodec in a blocking manner; it regrettably does not have an async. API). This made the main thread freeze in certain situations, because it has to wait on the decoder thread. Other than I suspected (I wrote that code, but that doesn't mean I know how the hell it works), this did not freeze during seeking: seek resets flushed the queue, which also prevented the decoder thread from adding more frames to it, thus stopping decoding and responding to the main thread in time. But it does fix the issue that exiting the player waited for the decoder to finish filling the queue when stopping playback. (This happened because it called mp_decoder_wrapper_set_play_dir() before any resets. Related to the somewhat messy way play_dir is generally set. But it affects all "synchronous" decoder wrapper API calls.) This uses pretty weird mechanisms in filter.h and dispatch.h. The resulting durr hurr interactions are probably hard to follow, and this whole thing is a sin. On the other hand, this is a _very_ user visible issue, and I'm happy that it can be fixed in such an unintrusive way.
* f_decoder_wrapper: use proper log prefix for all involved filterswm42020-03-051-1/+1
| | | | | | p->log has a prefix set that gives some context and distinguishes audio and video decoders. The "public" wrapper filter didn't use it, which is a regression since commit a3823ce0e03.
* filter: add functions to suspend filtering temporarilywm42020-03-052-1/+66
| | | | | | | | | | | | | | Filtering is integrated into an event loop, which is something the filter API user provides. To make interacting with the event loop easier, and in particular to avoid filtering to block event handling, add functions the event loop code can suspend filtering. While we cannot actually suspend a single filter, it's pretty easy to suspend the filter graph run loop itself, which is responsible for selecting which filter to run next. This commit shouldn't change behavior at all, but the functions will be used in later commits.
* f_decoder_wrapper: enable DR and hwdec with --vd-queue-enablewm42020-03-051-0/+10
| | | | | | | | | | | | | | This was forgotten. Hardware decoding typically breaks immediately, because many hw decoding APIs require allocating all surfaces in advance (and/or libavcodec was not made flexible enough to add new surfaces later). If the queue is large enough, it will run out of surfaces, fail decoding, and fall back to software decoding. We consider this the user's fault. --hwdec-extra-frames can be used to avoid this, if you have enough GPU memory, and the needed number of frames is lower than the arbitrary mpv-set maximum limit of that option.
* f_decoder_wrapper: make most queue options runtime changeablewm42020-03-011-13/+21
| | | | Why not.
* options: make decoder options local to decoder wrapperwm42020-03-011-19/+90
| | | | | | | | | | | | | | | Instead of having f_decoder_wrapper create its own copy of the entire mpv option tree, create a struct local to that file and move all used options to there. movie_aspect is used by the "video-aspect" deprecated property code. I think it's probably better not to remove the property yet, but fortunately it's easy to work around without needing special handling for this option or so. correct_pts is used to prevent use of hr-seek in playloop.c. Ignore that, if you use --no-correct-pts you're asking for trouble anyway. This is the only behavior change.
* player: add optional separate video decoding threadwm42020-02-291-54/+325
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This has been a topic in MPlayer/mplayer2/mpv since forever. But since libavcodec multi-threaded decoding was added, I've always considered this pointless. libavcodec requires you to "preload" it with packets, and then you can pretty much avoid blocking on it, if decoding is fast enough. But in some cases, a decoupled decoder thread _might_ help. Users have for example come up with cases where decoding video in a separate process and piping it as raw video to mpv helped. (Or my memory is false, and it was about vapoursynth filtering, who knows.) So let's just see whether this helps with anything. Note that this would have been _much_ easier if libavcodec had an asynchronous (or rather, non-blocking) API. It could probably have easily gained that with a small change to its multi-threading code and a small extension to its API, but I guess not. Unfortunately, this uglifies f_decoder_wrapper quite a lot. Part of this is due to annoying corner cases like legacy frame dropping and hardware decoder state. These could probably be prettified later on. There is also a change in playloop.c: this is because there is a need to coordinate playback resets between demuxer thread, decoder thread, and playback logic. I think this SEEK_BLOCK idea worked out reasonably well. There are still a number of problems. For example, if the demuxer cache is full, the decoder thread will simply block hard until the output queue is full, which interferes with seeking. Could also be improved later. Hardware decoding will probably die in a fire, because it will run out of surfaces quickly. We could reduce the queue to size 1... maybe later. We could update the queue options at runtime easily, but currently I'm not going to bother. I could only have put the lavc wrapper itself on a separate thread. But there is some annoying interaction with EDL and backward playback shit, and also you would have had to loop demuxer packets through the playloop, so this sounded less annoying. The food my mother made for us today was delicious. Because audio uses the same code, also for audio (even if completely pointless). Fixes: #6926
* filter: add async queue filterwm42020-02-293-1/+392
| | | | | | | | | | | | | | | | | | | | | | | | | | This is supposed to enable communication between filter graphs on separate threads. Having multiple threads makes only sense if they can run concurrently with each other, which requires such an asynchronous queue as a building block. (Probably.) The basic idea is that you have two independent filters, which can be each part of separate filter graphs, but which communicate into one direction with an explicit queue. This is rather similar to unix pipes. Just like unix pipes, the queue is limited in size, so that still some data flow control enforced, and runaway memory usage is avoided. This implementation is pretty dumb. In theory, you could avoid avoid waking up the filter graphs in quite a lot of situations. For example, you don't need to wake up the consumer filter if there are already frames queued. Also, you could add "watermarks" that set a threshold at which producer or consumer should be woken up to produce/consume more frames (this would generally serve to "batch" multiple frames at once, instead of performing high-frequency wakeups). But this is hard, so the code is dumb. (I just deleted all related code when I still got situations where wakeups were lost.) This is actually salvaged and modified from a much older branch I had lying around. It will be used in the next commit.
* filter: decide how multi-threading is supposed to workwm42020-02-292-8/+24
| | | | | | | | | | Instead of vague ideas about making different filter graphs on different threads interact directly, this have no direct support. Instead, helpers are required (such as added with the next commit). Document it. Different root filters (i.e. separate filter graphs) are now considered to be part of separate threads, so assert() if they're found to accidentally interact.
* filter: fix possibly lost async wakeupswm42020-02-291-5/+5
| | | | | | | | | | | mp_filter_mark_async_progress() can asynchronously mark a filter for processing, without waking up the filter thread. (It's some sort of idiotic micro-optimization I guess?) But since it sets async_pending without doing the wakeup, a mp_filter_wakeup() after this will do nothing, and the wakeup is lost. Fix it by checking for the needed wakeup separately. Fortunately, nothing used this function yet, so there is no impact.
* f_decoder_wrapper: replace most public fields with setters/getterswm42020-02-292-49/+99
| | | | | | | | | | | | | | | | | | | I may (optionally) move decoding to a separate thread in a future change. It's a bit attractive to move the entire decoder wrapper to there, so if the demuxer has a new packet, it doesn't have to wake up the main thread, and can directly wake up the decoder. (Although that's bullshit, since there's a queue in between, and libavcodec's multi-threaded decoding plays cross-threads ping pong with packets anyway. On the other hand, the main thread would still have to shuffle the packets around, so whatever, just seems like better design.) As preparation, there shouldn't be any mutable state exposed by the wrapper. But there's still a large number of corner-caseish crap, so just use setters/getters for them. This recorder thing will inherently not work, so it'll have to be disabled if threads are used. This is a bit painful, but probably still the right thing. Like speculatively pulling teeth.
* f_lavfi: don't propagate filter failure if creation failswm42020-02-161-3/+0
| | | | | | | | | | | | | Filters that fail to create are not supposed to do this. Generally it should happen in process() only. This fixes the previous commit. If a filter could not be created, it "trashed" the wrapper filter with the failure. (Even if the wrapper were to handle were to handle failures of sub-filter, it couldn't handle init failure because it cannot call mp_filter_set_error_handler() before the newly created filter is actually returned.) Fixes: #7465 (attempt 2)
* f_auto_filters: always fall back to hw-download+yadif if no hw deint filterwm42020-02-161-3/+8
| | | | | | | | | | | If hw decoding is used, but no hw deinterlacer is available, even though we expect that it is present, fall back to using hw-download and yadif anyway. Until now, it was over if the hw filter was somehow missing; for example, yadif_cuda apparently requires a full Cuda SDK, so it can be missing, even if nvdec is available. (Whether this particular case works was not tested with this commit.) Fixes: #7465
* Remove remains of Libav compatibilitywm42020-02-162-75/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* f_decoder_wrapper, sd_add: accept "null" codecwm42020-02-151-1/+7
| | | | | | | | | | | | | This is for easier use with the "delay_open" feature added in the previous commit. The "null" codec is reported if the codec is unknown (because the stream was not opened yet at time the tracks were added). The rest of the timeline mechanism will set the correct codec at runtime. But this means every time a delay-loaded track is selected, it wants to initialize a decoder for the "null" codec. Accept a "null" decoder. But since FFmpeg has no such codec, and out of my own laziness, just let it fall back to "common" codecs that need no other initialization data.
* f_autoconvert: remove subfmt conversion BSwm42020-01-173-71/+1
| | | | | | This was used to convert e.g. P010 to NV12 within the filter chain, which hopefully a thing that is not needed anymore. (And has been dead code since the ANGLE "RGB" interop code was removed.)
* f_hwtransfer: extend vaapi whitelist with some working formatswm42020-01-171-1/+2
| | | | | | Notably, BGR0, which is the only additional format listed as supported by the texture mapper, results in broken colors. This is most likely not a mpv issue, so the whitelist fulfils its purpose.
* f_hwtransfer: minor debug logging improvementwm42020-01-171-2/+5
|
* f_hwtransfer: move format fields to private structwm42020-01-122-40/+37
| | | | | A user can barely do anything useful with it, and there are no users which access these anyway, so private is better.
* f_hwtransfer: restructure and error properly on broken caseswm42020-01-121-20/+24
| | | | | | | | | | | I think the previous code didn't consider the situation if the input format was not any of the upload formats. It then could have possibly tried to upload the wrong format (and not sure what the underlying APIs do with it). Take care of this, also improve logging, and change it such that mp_hwupload_find_upload_format() does not unnecessarily change the state (although it doesn't really matter).
* f_autoconvert: usw f_hwtransfer properlywm42020-01-121-2/+4
| | | | | | | | | | | | | | | With the recent change how f_hwtransfer could select formats, it's possible that the upload_fmts list contains formats that are never selected, and the filter would have failed. The way it works now is that f_hwtransfer gets to select the format (which honestly doesn't make sense, but whatever), and f_autoconvert gets only a single format. It would be more ideal if f_hwtransfer provided a list of possible input formats, but that's absurdly too complex for now. Maybe I'll change it back at some later point, but I expect this shit to be in a perpetual state of complexity and brokenness.
* f_hwtransfer: slightly better loggingwm42020-01-111-3/+4
|
* f_hwtransfer: whitelist vaapi formats that actually appear to workwm42020-01-111-3/+50
| | | | | | | | | | | | | | | | | (Oh yes, we could have skipped all the complexity, and hardcoded the cases that work in the first place. This wouldn't be an issue if FFmpeg or libva exported correct information. Also possible that FFmpeg's filter chain does not allow to do this correctly in the first place, since filters expose next to no meta information about what hw formats etc. they need.) Note that uploading yuv420p to a nv12 vaapi surface actually works, but the blacklist excludes it. So this might get a bit slower. I'm not bothering with this case because it's rarely needed, and the blacklist specification would become a bit more complex if you had to specify sw/upload format pairs. Fixes: #7350
* f_hwtransfer: change order in which hwdec upload formats are consideredwm42020-01-111-26/+28
| | | | | | | | | | | | | | | | | | | | | Basically, instead of trusting the upload format, and picking the first sw format that has a desired upload format, trust the sw format. So now we pick the sw format first, and then select from the set of upload formats supported by it. This is probably more straightforward, and works around a crash with vaapi: mpv 8bit.mkv --vf=format=vaapi --gpu-hwdec-interop=all (Forces vaapi upload if hw decoding is not enabled.) Unfortunately, this still does not work, because vaapi, FFmpeg, the VO interop code, or all of them are doing something stupid. In particular, this picks the yuv420p sw format, which doesn't really exist despiter advertised (???????????????????????????????????????), and simply breaks. See: #7350
* options: fix filter list comparison (again)wm42019-12-181-2/+1
| | | | | | | | | | | This was completely broken: it compared the first item of the filter list only. Apparently I forgot that this is a list. This probably broke aspects of runtime filter changing probably since commit b16cea750f52. Fix this, and remove some redundant code from obj_settings_equals(). Which is not the same as m_obj_settings_equal(), so rename it to make confusing them harder. (obj_setting_match() has these very weird label semantics that should probably just be killed. Or not.)
* f_lavfi: add gross workaround for af_dynaudnorm bugwm42019-12-181-0/+35
| | | | | | | | | | | | | Better do this here than deal with the moronic project we unfortunately depend on. The workaround is generic; unknown whether it works correctly with multi-input/output filters or filter graphs. It assumes that if all inputs are EOF, and all outputs are EAGAIN, the bug happened. This is pretty tricky, because anything could happen. Any time some form of progress is made, the got_eagain state needs to be reset, because the filter pad's state could have changed.
* build: downgrade EGL requirement from 1.5 to 1.4wm42019-12-161-1/+1
| | | | | | | | | | With the previous commit, there's no need for 1.5 anymore. And in fact, it's just too dangerous to rely on 1.5 because of all the EGL craziness. For example, you might get a 1.5 EGL system library, but a driver might still give you 1.4 at runtime. If you assume that you can call 1.5 functions, you will probably get random crashes in this case. What a cursed API. (The same problem exists with EGL 1.3, but fortunately nothing seems to use that anymore. We can just ignore that problem.)
* filters: move prefix check from f_lavfi.c to user_filters.cwm42019-12-072-6/+10
| | | | | | | | It's user_filters.c which allows the "lavfi-" prefix to distinguish libavfilter filters from mpv builtin filters. f_lavfi.c is a layer below, and strictly passes anything it gets to libavfilter. So the correct place for this is in user_filters.c, which also has the code for stripping the prefix in the normal filter instantiation code.
* f_lavfi: mp_lavfi_is_usable: check for "lavfi-" prefixekisu2019-12-061-0/+4
| | | | | Without this, adding filters with the prefix would fail, and some filters that have conflicting names with mpv ones were unusable.
* filters: fix incorrect #if for vf_gpuwm42019-11-301-1/+1
| | | | | | | This didn't match what is in wscript_build.py. Also, it should work on non-X11 platforms... probably. (The condition is convoluted and almost nonsensical, but the offscreen context creation needs to be cleaned up anyway as soon as other backends, e.g. for win32, are added.)
* vf_gpu: add video filter using vo_gpu's rendererwm42019-11-292-0/+4
| | | | | | | | | Probably pretty useless in this form (see: the wall of warnings), but someone wanted this. I think this should be useful to perform some automated tests, maybe. Fixes: #7194
* options: get rid of GLOBAL_CONFIG hackwm42019-11-291-1/+1
| | | | | | | Just an implementation detail that can be cleaned up now. Internally, m_config maintains a tree of m_sub_options structs, except for the root it was not defined explicitly. GLOBAL_CONFIG was a hack to get access to it anyway. Define it explicitly instead.
* f_output_chain: use m_option_equal()wm42019-11-291-30/+3
| | | | | | | | | This is used to detect whether any filters were changed. This code was essentially ported to m_option.c. One possible difference is how the old code did name comparison. It did not actually compare the name (!?!?), so this might change behavior, hopefully to the better.
* options: pre-check filter names when using vf/af libavfilter bridgewm42019-11-253-0/+21
| | | | | | | | | | | | | Until now, using a filter not in mpv's builtin filter list would assume it's a libavfilter filter. If it wasn't, the option value was still accepted, but creating the filter simply failed. But since this happens after option parsing, so the result is confusing. Improve this slightly by checking filter names. This will reject truly unknown filters at option parsing time. Unfortunately, this still does not check filter arguments. This would be much more complex, because you'd have to create a dummy filter graph and allocate the filter. Maybe another time.
* f_output_chain: fix possible crash when changing filterswm42019-11-251-2/+4
| | | | | | When changing filters at runtime (vf/af commands/properties), this could crash due to a NULL pointer access. The code for comparing the old and new option values (to detect changes) was simply buggy.
* f_decoder_wrapper: put coverart through image output logicwm42019-11-171-2/+4
| | | | | | This wasn't done, probably regression from one of the last dozen of times this special code path was touched. This meant coverart images ignored the user-set aspect ratio completely, and some other things.
* vd_lavc: simplify fallback handling for full stream hw decoderwm42019-11-021-1/+1
| | | | | | | | | | | | Shovel the code around to make the data flow slightly simpler (?). At least there's only one send_packet function now. The old code had the problem that send_packet() could be called even if there were queued packets; due to sending the queued packets in the receive_frame function, this should not happen anymore (the code checking for this case in send_packet should normally never be called). Untested with actual full stream hw decoders (none available here); I created a test case by making hwaccel decoding fail.
* video: mess with the filte chain to enable zimg IMGFMT_RGB30 outputwm42019-11-023-8/+6
| | | | | | | | | | | This was too hardcoded to libswscale. In particular, IMGFMT_RGB30 output is only possible with the zimg wrapper, so the context needs to be taken into account (since this depends on the --sws-allow-zimg option dynamically). This is still slightly risky, because zimg currently will still fall back to swscale in some cases, such as when it refuses to initialize the particular color conversion that is requested. f_autoconvert.c could actually handle this better, but I'm tool fucking lazy right now, and nobody cares anyway, so go away, OK?
* f_decoder_wrapper: reduce uninit message log levelwm42019-11-011-1/+1
| | | | For vd/ad.
* sws_utils: shuffle around some shitwm42019-10-311-3/+1
| | | | | | | | | | | Purpose uncertain. I guess it's slightly better, maybe. The move of the sws/zimg options from VO opts (vo_opt_list) to the top-level option list is tricky. VO opts have some helper code in vo.c, that sends VOCTRL_SET_PANSCAN to the VO on every VO opts change. That's because updating certain VO options used to be this way (and not just the panscan option). This isn't needed anymore for sws/zimg options, so explicitly move them away.
* f_decoder_wapper: trust frame return over error codewm42019-10-251-5/+5
| | | | | | | | | | | | | | | |