Commit Graph

179 Commits

Author SHA1 Message Date
wm4 428fc1cbef f_lavfi: use new libavfilter iteration API 2018-04-03 20:08:15 +03:00
wm4 0b4120919a f_decoder_wrapper: retry decoding if libavcodec returns invalid state
At least the libavcodec MediaCodec wrapper sometimes seems to break the
libavcodec API, and does the following sequence:

  send_packet() -> EAGAIN
  receive_frame() -> EAGAIN
  send_packet() -> OK

The libavcodec API never allows returning EAGAIN from both functions, so
we discarded packets in this case. Change it to retrying decoding, for
the sake of MediaCodec. Note that it could also happen due to internal
bugs in the vd_lavc.c hw fallback code, but if there are any remaining,
they should be fixed properly instead.

Requested.
2018-03-26 19:47:08 +02:00
wm4 9b0102dd8b f_hwtransfer: more detailed logging
This also switches the order, because that makes more sense.
2018-03-15 23:13:53 -07:00
wm4 4aa1be44c2 f_hwtransfer: fix a logic error
Jesus Christ, how did I get this wrong, or never verified proper
function. This fixes --vf=vdpaupp not working with yuv420p input.
2018-03-15 23:13:53 -07:00
wm4 4527409c8d audio: improve behavior if filters output nothing during probing
Just bail out immediately (and disable audio) if format probing has no
result, instead of doing nothing and then apparently freezing.

This can happen with bogus filters, cases where the first audio frame is
essentially dropped by filters (can happen with large resampling
factors), and if the audio track contains no packets at all, or all
packets fail to decode.
2018-02-21 22:35:24 -08:00
wm4 13b90bcf91 video: fix --video-rotate in some cases
Which idiot wrote this code? [Yeah, me.]
2018-02-18 16:21:56 +01:00
wm4 fca64d913b filter: fix potential NULL pointer deref
The rest of the function should be executed only if both are set. It
seems like in practice this didn't happen yet with only one of them
unset, but in theory it's possible. Found by Coverity.
2018-02-16 22:04:15 -08:00
wm4 ceca1602e9 f_lavfi: extend filter help output
Also print type and help string. Also print AV_OPT_TYPE_CONST, which are
like the mpv choice option type, except different. Print them as
separate lines because FFmpeg usually has help strings for them too.
2018-02-13 17:45:29 -08:00
wm4 3ffa70e2da filter: extend documentation comments
Add more explanations, and also fix some blatantly wrong things.
2018-02-13 17:45:29 -08:00
wm4 251f4e5d77 filter: simplify/fix external filter graph usage
There was the following problem: if a filter graph had asynchronous
filters, and the filter graph user did not call mp_filter_run() (and
only accessed the mp_pins), then filtering could stall, because using
mp_pin_out_request_data() only recursively invoked filtering if the
data_requested flag wasn't already set. The latter can happen if a
request was tried earlier but failed, and then an asynchronous filter
actually produced output that would satisfy the request. Obviously, it
has to invoke filtering again to get the requested frame.

Fix this by organizing the code differently, and making sure to invoke
mp_filter_run() on every request (if there's nothing to do, it doesn't
do anything anyway). Simplify it a bit by removing things which are not
needed, like connecting filter graphs with different root filters.
2018-02-13 17:45:29 -08:00
wm4 76947798ea f_lavfi: fix typo in comment 2018-02-13 17:45:29 -08:00
wm4 2cce782527 filter: adjust root log prefix
Avoids that the audio decoder shows up with a "[root/ad]" log prefix.

This is an annoying consequence of mp_log_new(): if a log parent doesn't
have a prefix with "!", it'll add the prefix to all mp_logs created from
it. This should probably be fixed in the mp_log code itself, but doing
so would be a big deal as we'd have to make sure all the other log
prefixes are what we want. So work it around for now.
2018-02-13 17:45:29 -08:00
wm4 830f0aed97 video: make --deinterlace and HW deinterlace filters always deinterlace
Before this, we made deinterlacing dependent on the video codec metadata
(AVFrame.interlaced_frame for libavcodec). So even if --deinterlace=yes
was set, we skipped deinterlacing if the flag wasn't set. This is very
unreliable and there are many streams with flags incorrectly set.

The potential problem is that this might upset people who alwase enabled
deinterlace and hoped it worked. But it's likely these people were
screwed by this setting anyway. The new behavior is less tricky and
easier to understand, and this preferable. Maybe one day we could
introduce a --deinterlace=auto, which does the right thing, but of
course this would be hard to implement (esecially with hwdec).

Fixes #5219.
2018-02-13 17:45:29 -08:00
wm4 02f9087de9 audio: move back PTS jump detection to before filter chain
The recent changes to player/audio.c moved PTS jump detection to after
audio filtering. This was mostly done for convenience, because dataflow
between decoder and filters was made "automatic", and jump detection
would have to be done as filter. Now move it back to after decoders,
again out of convenience. The future direction is to make the dataflow
between filters and AO automatic, so this is a bit in the way. Another
reason is that speed changes tend to cause jumps - these are legitimate,
but get annoying quickly.
2018-02-13 17:45:29 -08:00
wm4 b79190561f f_decoder_wrapper: fix log message incorrect for audio
This code is used by both video and audio, so the text should not talk
about video.
2018-02-05 02:47:14 -08:00
wm4 09af5760bb f_demux_in: give it a slightly better filter name
Matters for logging.
2018-02-05 02:47:14 -08:00
wm4 2f6dc93276 filter: don't randomly lose async wakeup notifications
Another "what was I thinking" thing - destroying filters explicitly
skipped async wakeups for no reason. These were notifications for
filters that are not going to be destroyed too, and so their wakeup will
be lost, leading to stalled playback. This is completely unnecessary and
the special code can be removed.

Fixes #5488. (This case destroyed all audio filters due to AO init
failure, which could make clear out the f_demux_in.c wakeup for video,
and "freeze" playback.)
2018-02-05 02:47:14 -08:00
wm4 d7db42d27f
swresample: minor simplification
Cosmetic and no change in behavior. At least I think this looks simpler.
2018-02-03 05:01:34 -08:00
wm4 3d4071e6e5
swresample: remove unnecessary request for new input
We called mp_pin_out_request_data() if there was input _and_ output.
This is not how it should be: we should request new input only if output
was requested, but we could not produce any output.

On the other hand, the upper half of the process() function will request
new input if output is required, but all input was consumed. But this
requires calling mp_filter_internal_mark_progress(), as otherwise the
general filter logic would not know that we can continue.
2018-02-03 05:01:34 -08:00
wm4 87d8f292f5
swresample: actually reinit resampler on large speed changes
If the speed is changed by a large amount, we need to effectively change
the output rate by a large amount, and swr_set_compensation() is
apparently not designed to handle such large changes well. So it's
better to reinitialize the resampler on all large changes.

Also, strictly reinitialize the resampler if the rate changes, otherwise
it could happen that libavresample (which does not automatically
initialize resampling if avresample_set_compensation() is used) would
never apply speed changes properly.

Also document some conditions better that handle corner cases (remove
the inline condition from the if gating the compensation code).

It also appears that we crashed with very large compensation ratios
(when raising audio speed quickly by keeping the "[" key down), and this
commit accidentally mitigates it by not allowing large compensation.
2018-02-03 05:01:33 -08:00
wm4 880ea467ca
f_output_chain: remove unused got_input_eof field
Was used by the player code before decoders were moved to filters.
2018-02-03 05:01:32 -08:00
wm4 a4392168f9
f_utils: fix leak in frame duration filter
vf_vapoursynth used this. Could cause a crash at VO uninit, if the
leaked frame was allocated via VO DR.
2018-02-03 05:01:30 -08:00
wm4 7019e0dcfe
swresample: limit output size of audio frames
Similar to the previous commit, and for the same reasons. Unlike with
af_scaletempo, resampling does not have a natural frame size, so we set
an arbitrary size limit on output frames. We add a new option to control
this size, although I'm not sure whether anyone will use it, so mark it
for testing only.

Note that we go through some effort to avoid buffering data in
libswresample itself. One reason is that we might have to reinitialize
the resampler completely when changing speed, which drops the buffered
data. Another is that I'm not sure whether the resampler will do the
right thing when applying dynamic speed changes.
2018-02-03 05:01:29 -08:00
wm4 debc17663d
filter: add/use a convenience function
I guess this is generally useful for filters which buffer data
internally.
2018-02-03 05:01:28 -08:00
wm4 afb167cfd2
options: slightly improve filter help output for lavfi bridge
--vf=help will now list libavfilter filters, and e.g. --vf=yadif=help
will list libavfilter filter options.

The latter is rather bare, because the AVOption API is really awful
(holy shit how is it so bad), and would require us to handle _every_
option type manually.

Alternatively we could call av_opt_show2(), which ffmpeg uses for help
output in its CLI tools and which is much more detailed. But it's rather
foreign and forces output through av_log(), so I don't really want to
use it.
2018-02-03 05:00:52 -08:00
wm4 76e7e78ce9 audio: move to decoder wrapper
Use the decoder wrapper that was introduced for video. This removes all
code duplication the old audio decoder wrapper had with the video code.

(The audio wrapper was copy pasted from the video one over a decade ago,
and has been kept in sync ever since by the power of copy&paste. Since
the original copy&paste was possibly done by someone who did not answer
to the LGPL relicensing, this should also remove all doubts about
whether any of this code is left, since we now completely remove any
code that could possibly have been based on it.)

There is some complication with spdif handling, and a minor behavior
change (it will restrict the list of codecs to spdif if spdif is to be
used), but there should not be any difference in practice.
2018-01-30 03:10:27 -08:00
wm4 6d36fad83c video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.

One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().

Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.

Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.

I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-30 03:10:27 -08:00
wm4 b9f804b566 audio: rewrite filtering glue code
Use the new filtering code for audio too.
2018-01-30 03:10:27 -08:00
wm4 76276c9210 video: rewrite filtering glue code
Get rid of the old vf.c code. Replace it with a generic filtering
framework, which can potentially handle more than just --vf. At least
reimplementing --af with this code is planned.

This changes some --vf semantics (including runtime behavior and the
"vf" command). The most important ones are listed in interface-changes.

vf_convert.c is renamed to f_swscale.c. It is now an internal filter
that can not be inserted by the user manually.

f_lavfi.c is a refactor of player/lavfi.c. The latter will be removed
once --lavfi-complex is reimplemented on top of f_lavfi.c. (which is
conceptually easy, but a big mess due to the data flow changes).

The existing filters are all changed heavily. The data flow of the new
filter framework is different. Especially EOF handling changes - EOF is
now a "frame" rather than a state, and must be passed through exactly
once.

Another major thing is that all filters must support dynamic format
changes. The filter reconfig() function goes away. (This sounds complex,
but since all filters need to handle EOF draining anyway, they can use
the same code, and it removes the mess with reconfig() having to predict
the output format, which completely breaks with libavfilter anyway.)

In addition, there is no automatic format negotiation or conversion.
libavfilter's primitive and insufficient API simply doesn't allow us to
do this in a reasonable way. Instead, filters can use f_autoconvert as
sub-filter, and tell it which formats they support. This filter will in
turn add actual conversion filters, such as f_swscale, to perform
necessary format changes.

vf_vapoursynth.c uses the same basic principle of operation as before,
but with worryingly different details in data flow. Still appears to
work.

The hardware deint filters (vf_vavpp.c, vf_d3d11vpp.c, vf_vdpaupp.c) are
heavily changed. Fortunately, they all used refqueue.c, which is for
sharing the data flow logic (especially for managing future/past
surfaces and such). It turns out it can be used to factor out most of
the data flow. Some of these filters accepted software input. Instead of
having ad-hoc upload code in each filter, surface upload is now
delegated to f_autoconvert, which can use f_hwupload to perform this.

Exporting VO capabilities is still a big mess (mp_stream_info stuff).

The D3D11 code drops the redundant image formats, and all code uses the
hw_subfmt (sw_format in FFmpeg) instead. Although that too seems to be a
big mess for now.

f_async_queue is unused.
2018-01-30 03:10:27 -08:00