44a2c33939 tried to do this in a cute way by unsetting the hwdev to
be used for hwdec, but this doesn't prevent -copy variants from being
probed. Instead explicitly disallow it for grouped streams
This fixes dynamic hwdec switching, which would often fails, because
hw decoder were feed data without context, which caused decoding errors,
which in turn disabled hwdec.
command.c does queue_seek() after decoder reinit, but it may already be
too late, by the time seek to keyframe finishes.
Fix this, by just discarding the data until we have safe point to start
decoding again. Limit this only for hwdec to avoid formats that may not
have ffmpeg parser and not give us keyframe information and limit to 96
frames, just as safety to not lock the player, but this shouldn't happen
in practice.
This should also fix cases, when media file is cut in a way that would
cause decoding errors at the start.
Fixes: #17484
Unlike all other codecs, ProRes RAW is pretty much guaranteed to be slow
as hell on the CPU, always having thousands of tiles. And even on a very
slow GPU, a CPU decode won't be anywhere near to usable to make a difference.
Let us fallback fully to software decoder. There is an issue in ffmpeg
where if we return software format here for hwdec threading context it
will be assumed to be usable, but not accelerated, which would be fine,
but later it causes assertion failure when copying avctx context
between decoding threads in ffmpeg.
Avoid this issue, but returing NONE format after we failed.
No reason to not enable threads if lavc supports them, same as for
software decoding. Might help with pipelining of decoding and filtering.
Performance difference may vary, but in my testing everything is working
as expected and I didn't notice any regressions.
Set to 2 threads by default as conservative value that should resolve
stalling issue, while also not spawn too many cpu threads, which won't
help with hwdec anyway and only can cause too deep queue of hardware
surfaces.
Fixes: #16578
When using more than one threads, the callback can be called from
different thread from sibling avctx, we cannot use our main one to query
codec/hw_frames paramters.
Use context provided in callback arg to fix that.
If Vulkan hwdec is exposed by the system, use this as it provides better
compatibility with native Vulkan rendering.
This avoid issues with importing VkImages through DMABUF interop from
nvdec or vaapi on drivers that doesn't support DMABUF.
Try native Vulkan hwdec first which will resolve compatibility issues if
available. If not it will fallback to using vaapi/nvdec like before.
FFmpeg recently got a hardware accelerated decoder for FFv1.
The decoder has been tested on all major vendors and operating systems.
Intel support is currently disabled as all of their drivers have issues
with buffer device addresses.
Since its a software-defined implementation, internal issues can be fixed
and the overall implementation optimized further.
With that, I think it should be safe to enable it by default.
a3823ce0e0 made this request a special
case because of all the threading considerations. Unfortunately, the
implementation made it so that VDCTRL_GET_HWDEC always would return
CONTROL_UNKNOWN when using mp_decoder_wrapper_control. This didn't
matter because VDCTRL_GET_HWDEC in vd_lavc would always succeed, but in
reality it shouldn't. It takes some time before we actually know what
the hwdec is and if you query during that time, you'll could get some
bogus value (e.g. during hwdec auto probing). So fix that by returning
false in vd_lavc if hwdec_notified isn't there yet and adjust the
wrapper control logic to take this into account.
343a5fd345 killed all mmal hardware
decoding, but there was still some junk lying around. There's
IMGFMT_MMAL still, but that's harmless to keep around.
Users basically never need --hwdec=auto in reality and sometimes it
bites them unexpectedly (e.g. #15814). Unfortunately the name is kind of
nice sounding and if you don't read the manual closely, you might
inadvertently end up using it. So just make auto the same as auto-safe.
auto-unsafe is introduced to have the old behavior of auto instead. A
similar thing is done with the -copy variants. Try to update the
documentation of this section a little bit and discourage people from
using auto-unsafe because it's kind of dumb.
This update introduces a demux_packet_pool, allowing for the reuse of
previously allocated packets when needed.
sizeof(AVPacket) is not a part of the lavc public ABI, which prevents us
to allocate memory in larger blocks. However, we can substantially
decrease the amount of alloc/free operations during playback by reusing
both mpv's demux_packet and AVPacket.
This adjustment addresses the root cause of issue #12076, which,
although resolved upstream, did not fully tackle the persistent problem
of allocating small blocks of aligned memory. This issue largely stems
from the FFmpeg design of the AVPacket API. After this change memory
will no longer be allocated once cache limits is reached.
The demux_packet_pool is shared as a global pool of packets for a given
MPContext.
This change significantly speeds up the demuxer deinitialization,
benefiting file switching scenarios, especially when a large demuxer
cache is used.
See: #12294
See: #12563
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
The options in vd_lavc are all related, but they don't all require the
same thing for runtime changes. To avoid having to manually add UPDATE_*
to every single option flag, the options can be split into two separate
structs. The vd_lavc_conf becomes a catch all for all the --vd-lavc
options that require the full UPDATE_VD flag. The rest of the options
are split off into the new hwdec_conf instead. Additionally,
--vd-lavc-software-fallback is renamed to --hwdec-software-fallback and
moved to the hwdec_conf as well. The new name better reflects what it
does and it logically fits with those more. UPDATE_* flags are added on
everything now so these should all now be changeable on runtime.
On platforms where it is unstable/experimental, it is disabled behind
environmental variable, so safe to probe it there too.
Fixes usage of hwdec=yes with gpu-api=vulkan, where hwdec would be not
enabled. Position it after older and more stable variants. That means
the -copy variant of the other API will likely be prefered.
Now that we have identified the device types associated with each hwdec, we
can take advantage of this to ensure that get the right hwdec is chosen when
decoding frames and there are multiple choices available with different device
types.
This is also plumbed into the filter initialisation logic, although in practice
the decision on the hwdec has already been made at this point - still it's
easier than retaining the ambiguous look up logic and worrying that it might
lead to an inconsistent result.
Adds support for extracting codec profile. Old properties are redirected
to new one and removed from docs. Likely will stay like that forever as
there is no reason to remove them.
As a effect of unification of properties between audio and video,
video-codec will now print codec (format) descriptive name, not decoder
long name as it were before. In practice this change fixes what docs
says. If you really need decoder name, use the `track-list/N/decoder-desc`.
Lots of filters have generic internal function names like "process".
On a stack trace, all of the different filters use this name,
which causes confusion of the actual filter being processed.
This renames these internal function names to carry the filter names.
This matches what had already been done for some filters.
While this resolves limitations of lavc decoder crop, it also introduces
artifacts with some of the source files or hwdec.
Depending on chroma sampler it is possible to sample outside the decoder
crop area, pulling dirty pixels into the image. Some decoders left them
zeroed, not black. To fix that we would need specifc solution during
mapping of avframes.
As most of the files require the crop only in bottom/right area, the
AVCodecContext::apply_cropping works ok for those.
For all other cases that require more fancy cropping like 1440x1080+240+0
user can manually set `--vd-apply-cropping=no`.
Limitations of the lavc crop are explained here:
https://ffmpeg.org/doxygen/trunk/structAVCodecContext.html#a4745c7455c317272c4e139d6f369936c
Fixes: 826ce82cad
Cropping by decoder has limitations with regards to aligment and hwdec.
It doesn't work to offset top left corner with hwdec and even with
software decoding it don't crop fully when resulting data would not be
aligned.
VO cropping is way more robust.
In the same way that fallback in receive_frame() needs to be repeated
until we get a working decoder, we have to do the same thing in
reinit(). Calling force_fallback() only once can still yield a non
functional decoder.
The reason why we have these multiple paths which each require their
own fallback logic is that we can fail at different stages:
* hwdec init
* decoder init <- repeated fallback was missing here
* frame decoding
Fixes#12084
It's a bit of an edge case, but since we now allow the disabling of the
software fallback it's possible to have a situation where hwdec
completely fails and the mpv window is still lingering from the previous
item in the playlist. What needs to happen is simply that the vo_chain
should uninit itself and handle force_window if needed. In order to do
that, a new VDCTRL is added that checks vd_lavc if force_eof was set.
player/video will then start the uninit process if needed after getting
this.
There's an option that's supposed to stop mpv from falling back to
software decoding if hardware decoding fails. Except that it doesn't
work and can fallback to software decoding anyway. Correct this by
checking if all possible hwdec failed after the loop in
select_and_set_hwdec and that we have this option. If so, flag a bool to
force eof. In decode_frame afterwards, we then simply immediately return
an EOF.
There is an additional failure path I didn't account for in my previous
work. While I ensured that a late hwdec failure in receive_frame can be
recovered from by trying the next hwdec, there is a specific
combination where if an hwdec fails in receive_frame, and the next
hwdec is a full decoder (eg: v4l2m2m), and that also fails, we are left
with no decoder and so the entire decoding process ends and playback is
stopped.
Basically, we must keep re-attempting the fallback in receive_frame
until we get a valid decoder (software or hardware). This edge case
will rarely be encountered as there are only a couple of decoder based
hwdecs.
Fixes#11947
To remain consistent with our belief that `auto-safe` should be the
recommended mode when turning on hw decoding, let's remap `yes` from
`auto` to `auto-safe`.
We have supported `hwdec=drm` for some time now, and on devices where
this method is present, it is the preferred, and only, method
available. Combine that with the fact that software decoding on
embedded devices will not turn out well, and it's clear that we should
put `drm` and `drm-copy` on the `auto-safe` list to maximise usability
in simple configurations.
Today, if hwdec initialisation succeeds, we move on to attempting
decoding, and if decoding fails, we enter a fallback path that will
only do software decoding.
This is suboptimal because some hwdecs and codec combinations can
pass hwdec init, but then fail at hwaccel init, or even frame decoding.
In these situations, we will never attempt other hwdecs in the `auto`
or manually specified lists which might work.
One good example is someone tries to use `vulkan,auto` and tries to
play av1 content. The vulkan decoding will fail at hwaccel init time,
and then fallback to software instead of going through the auto list
which would allow vaapi, nvdec, etc to play the file.
Instead, let's not give up immediately, and try the next hwdec after
a failure, just like we do if hwdec init fails.
The key part of this change is to keep track of the hwdecs we have
tried, so that each time we run through hwdec selection, we don't try
the same one over and over again. If we really get through the whole
list with no success, we will then fall back to software decoding.
Fixes#11865
In case there are no packets from demuxer we cannot send EAGAIN, because
we will not proceed and get stuck with one frame in queue and never
output it. Just respect avcodec_receive_frame ret code and act
accordingly. The only case to care about is EOF when we have to drain
already queued frames.
Fixes playback of 1-2 frame videos.
Today, the only way to make mpv consider multiple hwdecs and pick the
first one that works is to use one of the `auto` modes. But the list
that is considered in those cases is hard-coded. If the user wants to
provide their own list, they are out of luck.
And I think that there is now a significant reason to support this -
the new Vulkan hwdec is definitely not ready to be in the auto list,
but if you want to use it by default, it will not work with many codecs
that are normally hardware decodable (only h.264, hevc and av1 if you
are very lucky). Everything else will fall back to software decoding.
Instead, what you really want to say is: use Vulkan for whatever it
supports, and fall back to my old hwdec for everything else.
One side-effect of this implementation is that you can freely mix
hwdec names and special values like `auto` and `no`. The behaviour will
be correct, so I didn't try and prohibit any combinations. However,
some combinations will be silly - eg: sticking any further values after
`no` will result in them being ignored. On the other hand, a
combination like `vulkan,auto` could be very useful as that will use
Vulkan if possible, and if not, run the normal auto routine.
Fixes#11797
For hwdecs without devices we can't get instant feedback during probing
whether the hwdec can possibly work or not, so we definitely want to try them last.
Independently this would also have solved the issue addressed by the previous commit.
This fixes an issue where mpv would try mediacodec (which may not
be available depending on Android version) and pick v4l2m2m next
which ends up failing even though mediacodec-copy would have been available.
c784820454 introduced a bool option type
as a replacement for the flag type, but didn't actually transition and
remove the flag type because it would have been too much mundane work.
--vd-lavc-dr defaulted to "yes", which caused issues on certain
hardware. Instead of disabling it, add a new "auto" value and
make it the default.
The "auto" choice will enable DR only when we can request host-cached
buffers (as signalled by the new VO_DR_FLAG_HOST_CACHED).
Co-authored-by: Nicolas F. <ovdev@fratti.ch>
Co-authored-by: Niklas Haas <git@haasn.dev>