summaryrefslogtreecommitdiffstats
path: root/filters
Commit message (Collapse)AuthorAgeFilesLines
* player: let frontend decide whether to use cover-art modewm42020-09-282-6/+19
| | | | | | | | | | | | | Essentially, this lets video.c decide whether to consider a video track cover art, instead of having the decoder wrapper use the lower level sh_stream flag. Some pain because of the dumb threading shit. Moving the code further down to make some of it part of the lock should not change behavior, although it could (framedrop nonsense). This commit should not change actual behavior, and is only preparation for the following commit.
* f_decoder_wrapper: make log prefix less verbosewm42020-09-201-2/+2
|
* f_async_queue: add various helper functionswm42020-08-282-2/+105
| | | | | Shouldn't change the behavior if not used. Will probably be used in a later commit.
* f_async_queue: don't count EOF frames as sampleswm42020-08-282-1/+4
| | | | That's dumb.
* f_async_queue: change reset behaviorwm42020-08-282-3/+15
| | | | | | | | | | | | | | | | Do not make resetting the "access" filters reset the queue itself. This is more flexible, and will be used in a later commit. Also, if the queue is not in the reset state while the input access filter is reset, make it immediately request data again. This is more consistent, because it'll enter the state it "should" be, rather when the filter's process function is called at an (essentially) random point in the future. This means the filter graph will resume work on its own if the queue was not reset before filter reset. This could affect the only current user of f_async_queue, the code for the --vd-queue-enable/--ad-queue-enable feature in f_decoder_wrapper. But it looks like this already uses it in a compatible way.
* filter: add filter priority thingwm42020-08-282-6/+31
| | | | | | | This is a kind of bad hack (with bad implementation) to paint over other problems of the filter system. The main problem is that some filters might be left with pending frames if the filter runner is "paused", which we don't want. To be used in a later commit.
* f_demux_in: log EOF "recovery"wm42020-08-271-0/+2
| | | | For debugging.
* f_decoder_wrapper: pass through EOF after EOFwm42020-08-272-0/+8
| | | | | | | | | It's relevant in some obscure corner cases (EDL file that has a segment without audio). Didn't test what's actually going on (is ad_lavc.c behaving wrong? is libavcodec behaving wrong or in an unexpected way? is lavc_process wrong?) and just patched it over with some bullshit, so the fix might be too complicated, and could be reworked at some later point. This sure is a real data flow fuckmess.
* filter: add a helperwm42020-08-272-0/+8
| | | | | Not used yet; probably will, just dumping this to get it out of my sight.
* audio: add scaletempo2 filter based on chromiumDorian Rudolph2020-07-272-0/+2
| | | | | | | | scaletempo2 is a new audio filter for playing back audio at modified speed and is based on chromium commit 51ed77e3f37a9a9b80d6d0a8259e84a8ca635259. It sounds subjectively better than the existing implementions scaletempo and rubberband.
* audio: redo video-sync=display-adropwm42020-05-236-20/+60
| | | | | | | | | | | | | | | | | This mode drops or repeats audio data to adapt to video speed, instead of resampling it or such. It was added to deal with SPDIF. The implementation was part of fill_audio_out_buffers() - the entire function is something whose complexity exploded in my face, and which I want to clean up, and this is hopefully a first step. Put it in a filter, and mess with the shitty glue code. It's all sort of roundabout and illogical, but that can be rectified later. The important part is that it works much like the resample or scaletempo filters. For PCM audio, this does not work on samples anymore. This makes it much worse. But for PCM you can use saner mechanisms that sound better. Also, something about PTS tracking is wrong. But not wasting more time on this.
* f_swscale: let common code guess color levels when RGB->YUVwm42020-04-231-2/+2
| | | | Probably doesn't matter anywhere.
* filters: fix a typo in a commentwm42020-04-231-1/+1
|
* vf_format: add gross mechanism for forcing scaler for testingwm42020-04-134-0/+12
| | | | | | | | | | | This sucks, but is helpful for testing. Obviously, it would be much nicer if there were a way to specify _all_ scaler options per filter (if the user wanted), instead of always using the global options. But this is "too hard" for now. For testing, it is extremely convenient to select the scaler backend, so add this option, but make clear that it could go away. We'd delete it once there is a better mechanism for this.
* filter: reduce redundant re-iterationswm42020-04-101-8/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | When the player core requests new frames from the filter, this is called external/recursive filtering, which acts slightly differently from when filters request new data internally. Mainly this is so the external user doesn't have to call mp_filter_graph_run() just to get a frame. This causes a number of complications, and the short version is that until now, mp_filter_graph_run() has unnecessarily returned true in the current common case, which made the playloop run too often for no reason. The problem is that when a mp_pin is read externally, updating the same mp_pin during recursive filtering flagged external_pending when the result was written, which made mp_filter_graph_run() return true, which made the playloop call mp_filter_graph_run() again. This is redundant because the caller is obviously checking the new state of the mp_pin immediately. The only situation in which external_pending really must be set is if _another_ pin is changed. In theory, we could also unset it if the set of "external" pins that are not in a signaled state becomes empty, but we don't track that in a convenient way. This commit removes the redundant signaling, and avoids running the playloop an additional time for each video and audio frame (as it actually was planned from the beginning, but duh).
* filter: process asynchronous wakeups during filteringwm42020-04-101-4/+5
| | | | | | | | | | | | | If a filter receives an asynchronous wakeup during filtering, then process newly pending filters resulting from that as well, before returning to the user. Might possibly skip some redundant playloop cycles. There is an explicit comment in the code about how this shouldn't be done, but I think it makes no sense. Filters have no business trying to interrupt the mainloop, and mp_filter_graph_interrupt() provides a proper mechanism to do this (though intended to be used by the filter user, not filters).
* f_decoder_wrapper: fix use of destroyed mutexwm42020-03-181-0/+2
| | | | | | | | | After calling the main filter's destroy callback, all child filters are destroyed. But one of them still tried to access the cache_lock mutex (which is destroyed in said destroy callback). This actually caused a crash on Android with _FORTIFY_SOURCE. Fix this by destroying the child filters first.
* options: fix OPT_BYTE_SIZE upper limitswm42020-03-181-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | As an unfortunate disaster, min/max values use the type double, which causes tons of issues with int64_t types. Anyway, OPT_BYTE_SIZE is often used as maximum for size_t quantities, which can have a size different from (u)int64_t. OPT_BYTE_SIZE still uses in64_t, because in theory, you could use it for file sizes. (demux.c would for example be capable of caching more than 2GB on 32 bit platforms if a file cache is used. Though for some reason the accounting code still uses size_t, so that use case is broken. But still insist that it _could_ be used this way.) There were various inconsistent attempts to set m_option.max to a value such that the size_t/int64_t upper limit is not exceeded. Due to the double max field, this didn't really work correctly. Try to fix this with the M_MAX_MEM_BYTES constant. It's a good approximation, because on 32 bit it should allow 2GB (untested, also would probably exhaust address space in practice but whatever), and something "high enough" in 64 bit. For some reason, clang 11 still warns. But I think this might be a clang bug, or I'm crazy. The result is correct anyway.
* options: change option macros and all option declarationswm42020-03-183-38/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Change all OPT_* macros such that they don't define the entire m_option initializer, and instead expand only to a part of it, which sets certain fields. This requires changing almost every option declaration, because they all use these macros. A declaration now always starts with {"name", ... followed by designated initializers only (possibly wrapped in macros). The OPT_* macros now initialize the .offset and .type fields only, sometimes also .priv and others. I think this change makes the option macros less tricky. The old code had to stuff everything into macro arguments (and attempted to allow setting arbitrary fields by letting the user pass designated initializers in the vararg parts). Some of this was made messy due to C99 and C11 not allowing 0-sized varargs with ',' removal. It's also possible that this change is pointless, other than cosmetic preferences. Not too happy about some things. For example, the OPT_CHOICE() indentation I applied looks a bit ugly. Much of this change was done with regex search&replace, but some places required manual editing. In particular, code in "obscure" areas (which I didn't include in compilation) might be broken now. In wayland_common.c the author of some option declarations confused the flags parameter with the default value (though the default value was also properly set below). I fixed this with this change.
* 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