summaryrefslogtreecommitdiffstats
path: root/filters
Commit message (Collapse)AuthorAgeFilesLines
* 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
| | | | | | | | | | | | | | | | | lavc_process() calls the receive/send callbacks, which mirror libavcodec's send/receive API. The receive API in particular can return both a status code and a frame. Normally, libavcodec is pretty explicit that it can't return both a frame and an error. But the receive callback does more stuff in addition (vd_lavc does hardware decoding fallbacks etc.). The previous commit shows an instance where this happened, and where it leaked a frame in this case. For robustness, check whether the frame is set first, i.e. trust it over the status code. Before this, it checked for an EOF status first. Hopefully is of no consequence otherwise. I made this change after testing everything (can someone implement a test suite which tests this exhaustively).
* ad_lavc, vd_lavc: return full error codes to shared decoder loopwm42019-10-242-14/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
* filters: extend vf_format so that it can convert color parameterswm42019-10-214-3/+69
| | | | | | | | | | | | | | | | | | | | | | | | | Form some reason (and because of my fault), vf_format converts image formats, but nothing else. For example, setting the "colormatrix" sub-parameter would not convert it to the new value, but instead overwrite the metadata (basically "reinterpreting" the image data without changing it). Make the historical mistake worse, and go all the way and extend it such that it can perform a conversion. For compatibility reasons, this needs to be requested explicitly. (Maybe this would deserve a separate filter to begin with, but things are messed up anyway. Feel free to suggest an elegant and simple solution.) This demonstrates how zimg can properly perform some conversions which swscale cannot (see examples added to vf.rst). Stupidly this requires 2 code paths, one for conversion, and one for overriding the parameters. Due to the filter bullshit (what was I thinking), this requires quite some acrobatics that would not be necessary without these abstractions. On the other hand, it'd definitely be more of a mess without it. Oh whatever.
* f_swscale: enable use of zimgwm42019-10-211-0/+1
| | | | The usual opt-in mechanism.
* video, demux: rip out unused spherical metadata codewm42019-10-171-4/+0
| | | | | | This was preparation into something that never happened. Spherical video is a shit idea anyway.
* vf_d3d11vpp: remove RGB conversion hackwm42019-10-162-11/+1
| | | | | | | With the previous commit, this is dead code. This also makes the f_autoconvert.c code for this dead code (fortunately). Will probably remove this later.
* f_auto_filters: use f_autoconvert for hw downloadwm42019-10-021-23/+22
| | | | | | | | Instead of using custom code. Now if only f_lavfi knew what formats FFmpeg's vf_yadif accepts, this could look much nicer, and wouldn't require the additional converter filter setup.
* f_autoconvert: provide a function to determine if conversion workswm42019-10-022-41/+75
| | | | | | This adds the function as seen in the f_autoconvert.h part of the patch. It's pretty simple, but goes along with an intrusive code move. I guess the resulting code is slightly nicer anyway.
* f_autoconvert: add hw->sw download pathwm42019-10-022-18/+71
| | | | | For some reason it could do sw->sw and sw->hw (and, in some ways, even do hw->hw in special cases), but not hw->sw. Add this.
* f_auto_filters: use software conversion if hw deint is not possiblewm42019-10-021-7/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | Before this commit, enabling hardware deinterlacing via the "deinterlace" option/property just failed if no hardware deinterlacing was available. An error message was logged, and playback continued without deinterlacing. Change this, and try to copy the hardware surface to memory, and then use yadif. This will have approximately the same effect as --hwdec=auto-copy. Technically it's implemented differently, because changing the hwdec mode is much more convoluted than just inserting a filter for performing the "download". But the low level code for actually performing the download is the same again. Although performance won't be as good as with a hardware deinterlacer (probably), it's more convenient than forcing the user to switch hwdec modes separately. The "deinterlace" property is supposed to be a convenience thing after all. As far as the code architecture goes, it would make sense to auto-insert such a download filter for all software-only filters that need it. However, libavfilter does not tell us what formats a filter supports (isn't that fucking crazy?), so all attempts to work towards this are kind of hopeless. In this case, we merely have hardcoded knowledge that vf_yadif definitely does not support hardware formats. But yes, this sucks ass.
* f_hwtransfer: add a mp_hwdownload filterwm42019-10-022-0/+62
| | | | | | | | | This just wraps the mp_image_hw_download() function as a filter and adds some minor caching/error logging. (Shame that it needs to much boilerplate, I guess.) Will be used by the following commit. Wrapping it as filter seemed more convenient than other choices.
* filters: add another dumb helperwm42019-10-022-0/+22
| | | | | | | Can be used with mp_chain_filters() to combine multiple filters into a single one. This is a bit silly, but whatever. I'm making it an explicit separate filter, because it lets the user access mp_filter.ppins against all conventions.
* video: remove vf_vavpp from automatic deinterlace propertywm42019-10-021-3/+0
| | | | | | | | | | | | | | This reverts commit 6385a5fd1b8a67c051b82d48c993a6591e8f93c6, and in addition removes the code that automatically inserts the vavpp filter. The reason is the same as the commit that is being reverted: this filter seems to trigger driver bugs. It can cause GPU freezes or just doesn't work. This variant of disabling the filter is better. There was no way to add the "force" parameter to the automatically inserted filter, so the old approach just made manual filter insertion (with the --vf option or "vf" command) more cumbersome.
* f_swscale: fix a typowm42019-09-191-1/+1
|
* video: add vf_fingerprint and a skip-logo scriptwm42019-09-192-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | skip-logo.lua is just what I wanted to have. Explanations are on the top of that file. As usual, all documentation threatens to remove this stuff all the time, since this stuff is just for me, and unlike a normal user I can afford the luxuary of hacking the shit directly into the player. vf_fingerprint is needed to support this script. It needs to scale down video frames as part of its operation. For that, it uses zimg. zimg is much faster than libswscale and generates more correct output. (The filter includes a runtime fallback, but it doesn't even work because libswscale fucks up and can't do YUV->Gray with range adjustment.) Note on the algorithm: seems almost too simple, but was suggested to me. It seems to be pretty effective, although long time experience with false positives is missing. At first I wanted to use dHash [1][2], which is also pretty simple and effective, but might actually be worse than the implemented mechanism. dHash has the advantage that the fingerprint is smaller. But exact matching is too unreliable, and you'd still need to determine the number of different bits for fuzzier comparison. So there wasn't really a reason to use it. [1] https://pypi.org/project/dhash/ [2] http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
* vf_vapourynth: remove Lua backendwm42019-09-192-5/+1
| | | | | | | | | | | | | | | 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.
* f_decoder_wrapper: fix initialization statewm42019-09-191-0/+2
| | | | | | | | | | | Some state wasn't reset when decoding was started without a seek reset before it. The code used to rely on reset_decoder() resetting this state, but since the commit referenced below, reset_decoder() does less than reset(). Fix this by explicitly calling reset() on initialization. Fixes: "f_decoder_wrapper: avoid full reset on timeline switch etc."
* f_decoder_wrapper: reorganize, fix EDL/ordered chapters backward playbackwm42019-09-191-115/+136
| | | | | | | | | | | | | | | | | | | | | | | Before this commit, there was a single process_decoded_frame() function. It handled various aspects of dealing with a newly decoded frame. Move some of these to a separate process_output_frame() function. This new function is called in the order the frames are returned to the playback core. Some correct_audio_pts() (was process_audio_frame()) becomes slightly less awkward due to this, and the timestamp smoothing can actually work in backward playback mode now (thus moving p->pts out of reset_decoder()). Behavior for normal playback also changes subtly. This shouldn't matter in sane cases, but if you mix broken files, --no-correct-pts, and timeline stuff, differences in behavior might be visible. Timeline clipping (EDL/ordered chapters) works now, because it's done before "transforming" the timestamps. Audio timestamp smoothing happens after it, which is a behavior change, but should be more correct. This still runs crazy_video_pts_stuff() before everything else. On the pther hand, --no-correct-pts or missing timestamp processing is done last. But these things didn't really work with timeline before.
* f_decoder_wrapper: avoid full reset on timeline switch etc.wm42019-09-191-20/+19
| | | | | | | | Slightly cleaner. We don't need to awkwardly backup "some" state on backwards playback. Due to not resetting last_format, normal timeline switches don't unconditionally trigger recomputing of certain image parameters. Also probably doesn't reset framedrop parameters, although I don't care about that part.
* f_decoder_wrapper: fully reset timestamp fixup logic on seekswm42019-09-191-0/+4
| | | | | | | | | | | | | This could lead to nonsense when backward playback is involved. Better reduce the possible interactions. Besides, it's better to fully reset things on seeks in general. The only exception is has_broken_packet_pts, which enables hr-seek if everything looks good. It's intended to trigger at the second hr-seek or so if the file is normal, and to disable it if the file is broken. It tries to avoid enabling the hr-seek logic before it can know about whether things are "good", so resetting it on seeks would obviously never enable it. Document it as explicit exception.
* f_decoder_wrapper: move option update to a common entrypointwm42019-09-191-3/+1
| | | | | process() calls these functions. It's a much better place to potentially copy changed option values into the cache struct.
* f_decoder_wrapper: hack for discarding preroll in backward playback modewm42019-09-191-11/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Some audio codecs will discard or cut the first frames when starting decoding. While some of that works through well-defined mechanisms (like initial padding), it's in general very codec/decoder specific, and not really predictable. In addition, libavcodec isn't very good with reporting "dropped" frames (and our internal interface reflects this). It seems our only chance to handle this is through timestamps. In theory, it would be best to discard frames that have timestamps before the "resume" position. But since video has reordered timestamps, we'd need to put some effort into finding this position. The first video packet doesn't necessarily contain this timestamp. (In theory, we could just do this in the demuxer with some trivial additional work, and set it on the packet's kf_seek_pts field. Although this field is supposed to contain just this value, the field is considered demuxer-internal, and I didn't want to make matters worse by reusing it for the interface to the decoder. With some more effort and buffering, we could calculate this value within the decoder, but fuck that.) The approach chosen in this commit is setting the timestamp to NOPTS. This will break in some obscure situations, but backward playback is a pretty obscure feature to begin with, so I considered this a reasonable implementation choice. Before passing a preroll packet to the decoder, its timestamps are set to NOPTS. Frames that are returned from the decoder and have the NOPTS timestamp are considered preroll and are discarded. This happens only during "preroll" mode (preroll_discard==true), so it doesn't affect normal forward playback. It's disabled on the first packet with a timestamp, so it can tolerate some crap even in backward playback mode. We don't check the dts fields out of laziness (decoded audio frames don't even have this field). I considered using an approach using the EDL clipping infrastructure (as mentioned in the last two paragraphs in the commit message of commit " demux_lavf: implement bad hack for backward playback of wav"). This didn't work, and I blamed timestamp rounding within mpv for it. But the problem was actually due to Matroska-rounded timestamps. Since the audio frame size isn't exactly aligned to 1ms, there will be an overlap (or gap) in the timestamps. This overlap is much smaller than 1ms, since it's just the sub-millisecond remainder part of the audio frame size. This makes the timestamps discontinuous and unreliable for the purpose we wanted to use it. We can't just smooth the timestamps in the demuxer either.
* f_decoder_wrapper: remove stale/duplicated commentwm42019-09-191-2/+0
|
* demux, f_decoder_wrapper: fix coverart in backward modewm42019-09-191-2/+6
| | | | | | | | | | | | Shitty ancient hack that wastes my time all the time. demux.c: always return the coverart packet as soon as possible, and don't let the backward demux state machine possibly stop it. f_decoder_wrapper.c: mess with some shit until it somehow starts to work. I think the old code tried to let it cleverly fall through so the packet was processed "normally"; just make it run the "usual" code instead.
* Implement backwards playbackwm42019-09-194-13/+139
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | See manpage additions. This is a huge hack. You can bet there are shit tons of bugs. It's literally forcing square pegs into round holes. Hopefully, the manpage wall of text makes it clear enough that the whole shit can easily crash and burn. (Although it shouldn't literally crash. That would be a bug. It possibly _could_ start a fire by entering some sort of endless loop, not a literal one, just something where it tries to do work without making progress.) (Some obvious bugs I simply ignored for this initial version, but there's a number of potential bugs I can't even imagine. Normal playback should remain completely unaffected, though.) How this works is also described in the manpage. Basically, we demux in reverse, then we decode in reverse, then we render in reverse. The decoding part is the simplest: just reorder the decoder output. This weirdly integrates with the timeline/ordered chapter code, which also has special requirements on feeding the packets to the decoder in a non-straightforward way (it doesn't conflict, although a bugmessmass breaks correct slicing of segments, so EDL/ordered chapter playback is broken in backward direction). Backward demuxing is pretty involved. In theory, it could be much easier: simply iterating the usual demuxer output backward. But this just doesn't fit into our code, so there's a cthulhu nightmare of shit. To be specific, each stream (audio, video) is reversed separately. At least this means we can do backward playback within cached content (for example, you could play backwards in a live stream; on that note, it disables prefetching, which would lead to losing new live video, but this could be avoided). The fuckmess also meant that I didn't bother trying to support subtitles. Subtitles are a problem because they're "sparse" streams. They need to be "passively" demuxed: you don't try to read a subtitle packet, you demux audio and video, and then look whether there was a subtitle packet. This means to get subtitles for a time range, you need to know that you demuxed video and audio over this range, which becomes pretty messy when you demux audio and video backwards separately. Backward display is the most weird (and potentially buggy) part. To avoid that we need to touch a LOT of timing code, we negate all timestamps. The basic idea is that due to the navigation, all comparisons and subtractions of timestamps keep working, and you don't need