`xdg_toplevel_decoration` exists on SSD compositors independent of if
there is a border or not, so resizing didn't work on those.
Checking the border option makes more sense and also works on such
compositors.
Screenshots using the hardware renderer should now include color tags
that map directly from the libplacebo tags, so the if/else logic only
needs to be included once.
mp_trc_to_pl, mp_prim_to_pl, and mp_levels_to_pl have forward but not
inverse mappings. This commit adds mp_trc_from_pl, mp_prim_from_pl, and
mp_levels_from_pl inverse mapping functions, which just map the enums
in the other direction.
There is a very subtle race in vo that can manifest itself on pause
events. In the renderloop, render_frame, unsurprisingly, does the heavy
lifting of actually queuing up and flipping the frames. This is called
during normal playback. Sometimes various parts of the player can make a
redraw request which will latter trigger another render of the frame
later down in the loop (do_redraw). Because these requests can happen at
essentially anytime, sometimes the redraw request will happen *before*
do_redraw and it'll be caught in render_frame. When this happens,
the existing render_frame run works perfectly fine as a redraw so it
clears out the request which is sensible. Normally this is all locked of
course, but there's one catch. render_frame has to unlock itself when
propagating down into specific VOs/backends. That's what causes this
bug.
While render_frame is unlocked, other parts of the player can send
redraw requests which will cause in->request_redraw to become true. The
logic in the code always clears out this parameter after a successful
render, but this isn't correct. When in->request_become becomes true in
the middle of render_frame, there needs to be one more draw afterwards
to reflect whatever actually changed (usually the OSD). Instead, this
gets simply discarded. If you rapidly spam pause while rendering things
to the OSD at the same time, it's possible to for the last render to
be behind a frame and appear as if your osd event was ignored.
Once you realize what is happening, the fix is quite simple. Just store
the initial value of in->request_redraw before the unlock step. After we
do the render step and unlock again, only set in->request_redraw to
false if there was an initial redraw request. We just finished doing a
redraw, so it is safe to clear. Otherwise, leave in->request_redraw
alone. If it is initially false, then it will still be false and nothing
changes. However if it updated to true in the middle of the rendering,
this value is now preserved so we can go and call do_redraw later and
show what that last frame was meant to be when you pause. One
unfortunate thing about this design is that it is technically possible
for other internal things in vo to update during that unlocked period.
Hopefully, that doesn't actually happen and only redraw requests work
like this.
Fixes#8172 and #8350.
This reworks all of mpv's unit tests so they are compiled as separate
executables (optional) and run via meson test. Because most of the tests
are dependant on mpv's internals, existing compiled objects are
leveraged to create static libs and used when necessary. As an aside, a
function was moved into video/out/gpu/utils for sanity's sake (otherwise
most of vo would have been needed). As a plus, meson multithreads
running tests automatically and also the output no longer pollutes the
source directory. There are tests that can break due to ffmpeg changes,
so they require a specific minimum libavutil version to be built.
mpv's window resizing logic always automatically resized the window
whenever the video resolution changed (i.e. advancing forward in a
playlist). This simply introduces the option to make this behavior
configurable. Every windowing backend would need to implement this
behavior in their code since a reconfigure event must always be a
resize. The params of the frame changed so you either have to resize the
window to the new size of the params or make the params the same size as
the window. This commit implements it for wayland, win32, and x11.
This came up in #9828. According to the header comments, creating a 1D
ra_tex requires height and depth to be set to 1. For a 2D texture, it
requires depth be set to 1. There were a couple of spots in mpv's code
where this wasn't being followed. Although there was no known bug from
this, the rest of the code works like this so it was a good idea to go
ahead and sync it up. As a followup, let's just add some simple asserts
to ra.c to enforce this so it doesn't go unnoticed in the future.
Which is wl->video_surface for vo_dmabuf_wayland.
Listening on wl->surface results in freezes if it is occluded and
culled by the compositor. Which mutter does, and the wl_surface::frame
spec warns about:
> A server should avoid signaling the frame callbacks if the
> surface is not visible in any way, e.g. the surface is off-screen,
> or completely obscured by other opaque surfaces.
ra_ctx_opts.want_alpha and vo_wayland_set_opaque_region's alpha
argument are only used as bool but both are ints. Particularly for the
function argument, passing a 0 or 1 is confusing - at first glance it
looks like you're specifying an alpha value of 0 or 1.
Since they're only used as bools, make them bools.
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.
This was originally dropped because it was thought to be unneeded at the
time, but at least some devices (rockchip) apparently are still on old
compositors that use linux-dmabuf v2. It's not much code, and for
testing purposes it's good to have around since it's hard to test
drmprime otherwise. Some minor additions are here to support the newly
added vaapi-format mapping in v2 of the protocol.
This reverts commit a5b9d529ee.
effort=4 has a significant increase in quality/bpp compared to effort=3
with a very minor increase in encoding time. It's worth the trade-off
as a default setting for lossy encoding.
After commit c98e7353, we blindly pass the screenshot colorspace to the
image writer. But since we want to introduces the ability to save images
in HDR and other exotic formats, we should strip this for unsupported
formats.
See-Also: #10988
When taking window screenshots with a colorspace override, tag them
appropriately, based on the best-known colorspace info. Note that this
is imperfect, we should ideally also attach the output ICC profile if
one exists. But this is better than nothing.
Also force 1:1 PAR in this case. In all other cases, default to sRGB.
When taking an unscaled screenshot, always render to an unspecified
SDR-like space. (Subject to change) Apply output-specific options (ICC
profile, color space overrides, custom LUT) only in window screenshot
mode.
I decided to split this off from subsequent refactors because it is IMO
a bug fix deserving of its own commit.
Screenshots are currently always RGB. Subject to change, but needs to be
communicated clearly if changed. This commit is not a functional change,
it's merely for code clarity.
Based on the new upstream helper function `pl_map_hdr_metadata` and the
existing AV_FRAME_DATA_DYNAMIC_HDR_PLUS. This allows us to use SMPTE
2094-40 dynamic HDR tonemapping in mpv, albeit with the limitation of
requiring `--tone-mapping=auto` in order to pick this curve upstream.
3a9e661e92 officially made this video
filter deprecated roughly 6 years ago. Every other video filter in that
commit has actually been removed since then except for vf_sub. ffmpeg
does have its own subtitles filter, but it doesn't have the same control
over scale like vf_sub does. That's probably why wm4 never actually
removed it. Let's stop scaring users with a warning since this filter
probably won't ever get removed. Closes#9254.
With significant improvements to the color tagging support in various
screenshot formats, e.g. cICP in FFmpeg, and JPEG XL's generally robust
color support, it's safe to default this to yes.
Writing an image either with vo_image or with a screenshot will strip
the colorspace info because it allocates a new mp_image that contains
the same data as the old image after calling mp_image_params_guess_csp.
However, mp_image_params_guess_csp cannot always guess the appropriate
colorspace, so it picks a "sane default." Since this function also
changes parameters so the space always makes sense, this extra info
isn't harmful and allows screenshots and vo_image outs to be properly
tagged with the correct colorspace.
Fixes#10988.
Previously, this defaulted to yes and configure-bounds from the
compositor would always apply. In the case where the user explicitly set
autofit or geometry, this could be confusing because configure-bounds
would take precedence over it. Instead, let's add an auto choice and
make that the default. If we detect that the option is on auto and that
there is autofit/geometry being set, then ignore the event. This should
be more intuitive since someone who bothers to explicitly set mpv's
geometry would naturally expect that geometry to actually apply.
Semi-regression although this option never really did what the manual
said until recently. In the past, this option also controlled whether or
not mpv set the wayland buffer_scale to the value of the wl_output or
force it 1. This had varying effects depending on the exact compositor
configuration. That logic has now all been removed and this option now
only controls whether or not to scale the window with the hidpi scale
factor we get from the compositor. i.e. it actually does what the
manual says now.
Regressed from 879824a47f. The geometry
needs to be explictly recalculated now. Change up this function a little
bit also give it the ability to directly perform a resize after the
fact. This is a common workflow and we'll be using it in the next
commit.
PresentNotifyMSC turns out to be not only redundant, but also harmful with
mesa-backed egl/glx/vulkan VOs because for all of them, mesa uses
PresentPixmap behind the scenes when DRI3 is available, which already
spawns a PresentCompleteNotify event when the buffer swap actually
finishes. This is important because without using the timing information
from these PresentCompleteKindPixmap events, there's no way for mpv to know
exactly when a frame becomes visible on the display.
By using PresentNotifyMSC in conjunction with DRI3-enabled mesa, two
problems are created:
1. mpv assumes that a vblank won't elapse (i.e., it assumes the current MSC
won't change) between the time when mesa enqueues the buffer swap and
the time when mpv calls PresentNotifyMSC to ask xorg for a notification
at the next MSC, relative to the current MSC at the time that xorg reads
it for the PresentNotifyMSC call. This means that mpv could get a
notification one or more vblanks later than it expects, since the
intention here is for mpv to get a notification at the MSC that the
buffer swap completes.
2. mpv assumes that a buffer swap always takes one vblank to complete,
which isn't always true. A buffer swap (i.e., a page flip) could take
longer than that depending on hardware conditions (if the GPU is running
slowly or needs to exit a low-power state), scheduling delays (under
heavy system or GPU load), or unfortunate timing (if the raster scan
line happens to be at one of the last few rows of pixels and a vblank
elapses just before the buffer swap is enqueued).
This causes mpv to have a faulty assumption of when frames become visible.
Since mpv already receives the PresentCompleteNotify events generated by
mesa's buffer swaps under the hood, the PresentNotifyMSC usage is unneeded
and just throws a wrench in mpv's vsync timing when xpresent is enabled.
Simply removing the PresentNotifyMSC usage from the egl, glx, and vulkan
VOs fixes the xpresent vsync timing.
This protocol is pretty important since it finally lets us solve the
longstanding issue of fractional scaling in wayland (no more mpv doing
rendering over the target resolution and then being scaled down). This
protocol also can completely replace the buffer_scale usage that we are
currently using for integer scaling so hopefully this can be removed
sometime in the future. Note that vo_dmabuf_wayland is omitted from the
fractional scale handling because we want the compositor to handle all
the scaling for that VO.
Fixes#9443.
This is in preparation for fractional scaling support. Basically, redo
all the coordinates in wayland so that wl->geometry is equal exactly to
what is being put out to the screen (no extra wl->scaling multiplication
required). The wl->vdparams variable is also eliminated for simplicity.
This changes mpv's behavior on wayland with hidpi scaling but that will
be addressed in more detail with the next commit.
For OpenGL, this is based on simply comparing GL_VENDOR strings against
a list of allowed vendors.
Co-authored-by: Nicolas F. <ovdev@fratti.ch>
Co-authored-by: Niklas Haas <git@haasn.dev>
--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>
A longstanding pain point of the drm VOs is the relative lack of state
sharing. While drm_common does provide some sharing, it's far less than
other platforms like x11 or wayland. What we do here is essentially copy
them by creating a new vo_drm_state struct and using it in vo_drm and
context_drm_egl. Much of the functionality that was essentially
duplicated in both VOs/contexts is now reduced simple functions in
drm_common. The usage of the term 'kms' was also mostly eliminated since
this is libdrm nowadays from a userspace perspective.
This handle type was only needed for backwards compatibility with
windows 7. Dropping it allows us to simplify the code: there is no
longer a need for runtime checks, as the handle type can now be
statically assigned based on the platform.
The motivating usecase here, apart from code simplification, is a
desired switch to timeline semaphores, which (in the CUDA API) only
supports the non-KMT win32 handles.
It's worth pointing out that we need no runtime check for
IsWindows8OrGreater(), because the `export_caps.sync` check will already
fail on versions of windows not supporting PL_HANDLE_WIN32.
Officially, the most cursed part of the wayland code in mpv (third or
fourth try now?) This time, let's allocate a pool during init
(arbitrarily set to the maximum swapchain length mpv allows, 8; don't
even know if this actually works in wayland). Then we add/remove
feedbacks from the pool during the lifecycle of the VO, and clean it up
all at the end. Hopefully, this does the trick for good this time.
This ended up being a bad idea. The problem is that it introduces
ordering when destroying events (something we weren't worried about
before) and Lynne pointed out a problem with the callback not also being
destroyed before the surface in IRC. Just undo this and go with a
different approach (next commit). P.S. the wayland_dispatch_events name
change is kept though because I like that better.
This reverts commit aa8ddfcdf3.
In debug mode the macro causes an assertion failure.
In release mode it works differently and tells the compiler that it can
assume the codepath will never execute. For this reason I was conversative
in replacing it, e.g. in mpv-internal code that exhausts all valid values
of an enum or when a condition is clear from directly preceding code.
The only real reason this was ever supported is because it was
dramatically simpler than v4, so it was put in as an initial
implementation. Later, v4 support was added and we left v2 for
compatibility, but let's just drop it. Compositors all use v4 nowadays,
and v2 is significantly limited (no modifier support for example). It's
better to just remove this dead code for simplicity.
This was already returning true/false but the type was int. Also
simplify a few places in the wayland contexts where we can just return
the value of this function instead of doing redundant checks.
Instead of just returning true/false, it's better to have this function
cleanup itself. We can eliminate some redundant uninit calls elsewhere
in the code as well.
There's several functions that are used for initializing mpv on a
certain platform (x11, wayland, etc.). These currently are all int, but
they actually return 1 and 0 like a boolean. This gets a bit confusing
because actual vo preinit functions return 0 and -1 instead. Just make
these all bool instead and return true/false to make it clearer.
vk->surface is a handle and not a pointer, so assign VK_NULL_HANDLE.
This fixes the following build error on 32bit Windows when using clang for example,
which errors out when assigning a 32bit pointer to a 64bit integer:
../mpv-0.35.0/video/out/vulkan/utils.c:37:21:
error: incompatible pointer to integer conversion assigning to 'VkSurfaceKHR' (aka 'unsigned long long') from 'void *' [-Wint-conversion]
vk->surface = NULL;
^ ~~~~
Similar to some other issues we've had with unprocessed compositor
events. When quitting mpv, there's two things we should be doing:
dispatching any last minute wayland events and then waiting for a
compositor reply. Luckily, there's already an internal helper for this
(renamed to wayland_dispatch_events for consistency) that we can use.
All of the special casing of wl->feedback becomes unneccesary and we can
remove this from vo_wayland_state with this method. Fixes#110022.
In the event of a failed wayland initalization, the display_fd is
actually 0 instead of -1 which would correctly indicate it doesn't
exist. Also move the fd check inside vo_wayland_dispatch_events since
that function shouldn't ever do anything if we don't actually have a
display fd.
We have a use_present bool that keeps track of whether or not to use
presentation time. However, the creation of the feedback listener
actually wasn't checking this and was instead checking for the existence
of wl->presentation. There's no point in always creating the
listener and feedback if mpv isn't actually going to use it. Just change
it to use_present instead.
This change enables mpv to work in the WSL2 (WSLg) environment where
OpenGL is implemented on top of D3D12.
This reverts commit 149d98d244.
Mentioned OpenGL implementation (GDI Generic) in the original change
will be rejected by version check, so there is no need to handle it
manually.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Since the modesetting driver now has TearFree support with integration into
xpresent, it's important that xpresent is used with the modesetting driver
to get the correct vsync timing when a frame is delayed by one vblank
interval due to a pending page-flip enqueued by a different entity. The
modesetting driver ensures that the xpresent extension reports the correct
presentation timing when TearFree is used; mpv just needs to listen to it.
Add the modesetting driver to the xpresent whitelist so mpv can get the
correct presentation completion timing when modesetting TearFree is used.
This is also helpful for when xpresent performs page flips directly in the
modesetting driver and a natural delay in the display pipeline causes a
page flip to be delayed by one vblank interval or more.
See https://sw.kovidgoyal.net/kitty/graphics-protocol/
This makes no attempt at querying terminal features or handling
terminal errors, as it would require mpv to pass the response codes
from the terminal to the vo instead of interpreting them as
keystrokes made by the user and acting very unpredictably.
Tested with kitty and konsole.
Fixes#9605
This new hwaccel flag was added to allow us to request that an hwaccel
decode not implicitly copy output frames before passing them out. The
only hwaccel that would implicitly copy frames is nvdec due to how it
has a small output pool that cannot be grown very much. However, we
already copy frames as soon as we get our hands on them (in our hwdec)
so we're already safe from pool exhaustion, and the extra copy doesn't
help us.
H264 hardware decode with v4l2m2m wasn't working on the RPi 4. Mpv would
report the image format (yuv420p) wasn't supported. The change to
hwdec_drmprime.c is to explicitly say that the format now is supported.
The change to dmabuf_interop_gl.c is to specify the colour format of the
planes before generating egl images. These changes were tested on a Pi 4
with this fork of ffmpeg: https://github.com/jc-kynesim/rpi-ffmpeg.
Signed-off-by: EmperorPenguin18 <60635017+EmperorPenguin18@users.noreply.github.com>
currently only supported on x11.
one practical use-case of this is wanting to embed something (such as
dmenu) into the mpv window to use as a menu/selection. there might be
other use-cases as well (e.g doing some shenanigans with `xdotool` or
whatnot).
it's currently possible to:
* listen for 'current-window-scale' change (to check if the
window has been created or not)
* call an external tool like `xdo` or `xdotool` and grab the xid
from mpv's pid.
however it adds unnecessary dependency on external tools when mpv is
fully capable of easily providing this information.
closes: #10918
This has been a long standing annoyance - ffmpeg is removing
sizeof(AVPacket) from the API which means you cannot stack-allocate
AVPacket anymore. However, that is something we take advantage of
because we use short-lived AVPackets to bridge from native mpv packets
in our main decoding paths.
We don't think that switching these to `av_packet_alloc` is desirable,
given the cost of heap allocation, so this change takes a different
approach - allocating a single packet in the relevant context and
reusing it over and over.
That's fairly straight-forward, with the main caveat being that
re-initialising the packet is unintuitive. There is no function that
does exactly what we need (what `av_init_packet` did). The closest is
`av_packet_unref`, which additionally frees buffers and side-data.
However, we don't copy those things - we just assign them in from our
own packet, so we have to explicitly clear the pointers before calling
`av_packet_unref`. But at least we can make a wrapper function for
that.
The weirdest part of the change is the handling of the vtt subtitle
conversion. This requires two packets, so I had to pre-allocate two in
the context struct. That sounds excessive, but if allocating the
primary packet is too expensive, then allocating the secondary one for
vtt subtitles must also be too expensive.
This change is not conditional as heap allocated AVPackets were
available for years and years before the deprecation.
Now that 0.35 has been released, we can consider increasing our minimum
required ffmpeg version. Currently, we think 4.4 is the most recent
version we can move to (from the current requirement of 4.0).
This allows us to remove a few conditionals. There are more that we
won't be able to remove unless we move further up to 5.1.
8300830951 rearranged/simplified some of
the wayland touch code mainly because what was there before was
completely broken on my machine in those days (dragging was unreliable,
resizing was really buggy, etc.). However, one user said that touch
input no longer worked for him after that change. I could not ever
reproduce it, but it seems the issue was putting down the key before
testing for resize/move in the code. Now who knows why this actually
matters, but apparently it works for the user in question and I don't
observe any unexpected behavior on my end when swapping the order. Like
the mouse/pointer code, we also now do a test for dragging before
actually trying a resize/move which is a little more consistent than
before. Fixes#9771.
Flushing the cache is a hammer-for-a-screw operation, because it nukes
*all* renderer state, including the HDR peak detection state. When
enabling e.g. --hdr-compute-peak, or any other future methods of dynamic
tone mapping, this would lead to bad results (e.g. brightness
fluctuations) whenever the OSD state is updated.
Instead of flushing the cache to force an OSD re-render, instead just
update the frame signature directly whenever its osd_sync value changes.
This accomplishes effectively the same thing but without touching the
HDR state.
This is slightly violating the libplacebo abstraction in a way that
isn't publicly documented. To be on the safe side we could make a carbon
copy of the array before modifying it, but given that this is unlikely
to change upstream I'll probably just end up explicitly documenting it
instead of forcing the copy in mpv.
Currently, the lcms-related options are only defined when lcms2 is
enabled at build time. However, this causes issues (e.g. segfault) for
vo_gpu_next, which relies on the presence of these options (to forward
them to libplacebo).
(That libplacebo internally depends on lcms2 as well is an
implementation detail - compiling mpv *without* lcms against libplacebo
*with* lcms should be possible in principle)
Fixes: #10891Closes: #10856
The new single-pixel-buffer protocol is designed to optimize the case
for using a solid color as an underlay wl_surface. It works the same as
the wl_shm 1x1 pixel trick currently used, but it allows the compositor
to make optimizations with more certainty than the wl_shm trick.
This was previously implicitly included by the order of headers in
vo_dmabuf_wayland.c, but it is better to make it an explicit and reorder
the headers properly.
When the alpha channel is the first component, this code block gets
skipped by the continue, meaning the check for c==0 never passes.
Fix it by explicitly keeping track of whether bits have been set.
The legacy DRM API adds some complexity to the DRM code. There
are only 4 drivers that do not support the DRM Atomic API:
1. radeon (early GCN amd cards)
2. gma500 (ancient intel GPUs)
3. ast (ASPEED SoCs)
4. nouveau
Going forward, new DRM drivers will be guaranteed to support the atomic
API so this is a safe removal.
The content-type protocol allows mpv to send compositor a hint about the
type of content being displayed on its surface so it could potentially
make some sort of optimization. Fundamentally, this is pretty simple but
since this requires a very new wayland-protocols version (1.27), we have
to mess with the build to add a new define and add a bunch of if's in
here. The protocol itself exposes 4 different types of content: none,
photo, video, and game.
To do that, let's add a new option (wayland-content-type) that lets
users control what hint to send to the compossitor. Since the previous
commit adds a VOCTRL that notifies us about the content being displayed,
we can also add an auto value to this option. As you'd expect, the
compositor hint would be set to photo if mpv's core detects an image,
video for other things, and it is set to none for the special case of
forcing a window when there is not a video track. For completion's sake,
game is also allowed as a value for this option, but in practice there
shouldn't be a reason to use that.
mpv's core already keeps track of whether or not it thinks a track is an
image. Some VOs (i.e. wayland) would benefit from knowing if what is
currently being displayed is an image or not so add a new VOCTRL that
signals this anytime we load a new file with a VO. Additionally, let's
add a helper enum for signaling the kind of content that is being
displayed. There is now MP_CONTENT_NONE (strictly for force window being
used on a track with no image/video), MP_CONTENT_IMAGE, and
MP_CONTENT_VIDEO. See the next commit for the actual usage of this (with
wayland).
mpv has an internal optimization on a couple of platforms where it will
not render any frames if the window is minimized or hidden. There's at
least once possible use case for wanting to force a render anyway
(screensharing with pipeware) so let's just add a simple switch for
this that always forces mpv to render. Closes#10846.
Related issue: #10868. While most protocols are in theory optional, a
small amount of them are absolutely essential and nothing will work
without them. We should make sure to error out in those cases and not
try to actually do anything. For wayland support in general,
wl_compositor support is obviously required. If there is no wl_surface,
you can't do anything. Additionally, vo_wlshm quite obviously requires
wl_shm so mark that one as well. vo_dmabuf_wayland needs linux_dmabuf,
viewporter, wl_shm, and wl_subcompositor. In practice, these are all
very standard protocols and shouldn't be missing but the linked issue
above is at least one example where a compositor was stuck on an ancient
version of a wayland interface.
This is a very simple but easy way of doing it. Ideally, it would be
nice if we could also add some sort of introspection about shader
parameters at runtime, ideally exposing the entire list of parameters as
a custom property dict. But that is a lot of effort for dubious gain.
It's worth noting that, as currently implemented, re-setting
`glsl-shader-opts` to a new value doesn't reset back previously mutated
values to their defaults.
In practice this never led to any issues due to implementation
details of bstr_sanitize_utf8_latin1, but there's no guarantee that
a bstr is correctly null-terminated.
I was confused in d3a28f12c9 why it
actually even worked, but after not being stupid, it's quite obviously
just a dangling pointer. The reason it only happens with
wp_presentation_feedback is because the object and listener actually
created in frame_callback not the presentation events itself (for vsync
timing reasons). So it is possible to free the object, but not
immediately recreate it again before quitting (unlike with the frame
callback). The actual comment is moved into feedback_presented (which is
first) but as of this commit it doesn't have the NULL setting logic
(that's the next one).
964692ad4c added some code to destroy
presentation_feedback we get in the presentation_discarded event. This
is the correct thing to do since the compositor could send us this
instead of feedback_presented. Without that change, mutter could
potentially leak memory on every frame.
Unfortunately, life is not so simple and wlroots and weston act
differently. These compositors only send one presentation_discarded
event if the mpv window is hidden. Not on every single missed frame like
mutter. Now in theory this shouldn't matter, but it also turns out that
mpv attempts to free the presentation feedback twice if you quit it
while it is hidden away (on weston and wlroots compositors only). The
inital wp_presentation_feedback_destroy in feedback_discarded fires, but
then the function goes off again in vo_wayland_uninit because
wl->feedback is apparently not NULL for some reason. Possibly, this is
some race condition but we can't just get rid of what's in
feedback_discarded since mutter needs this line. Instead, just hack it
by explicitly setting wl->feedback to NULL in feedback_discarded after we
destroy the presentation feedback. Some valgrind testing in mutter,
sway, and weston shows that this works correctly on all of those
compositors with various combinations of mpv being visible or not while
quitting. feedback_presented doesn't appear to exhibit this behavior so
we just leave that as-is.
666cb91cf1 added dmabuf_feedback, but it
was never actually free'd on uninit. Because this function requires
wayland protocols 1.24, we have to wrap it in an #if. Also throw in some
minor cosmetic changes in here.
This mapping isn't actually relevant until we have the Vulkan interop
merged, and it requires a newer version of libavutil than our minimum
requirement. So I'm going to remove it from master and put it in the
interop PR.
Fixes#10813
666cb91cf1 added support for v4 of the
dmabuf protocol. This was meant to be optional and the fallback support
for the old v2 (dates back to 2017[0] well before the 1.15
wayland-protocol version we depend on) was maintained. However, v4 added
several new functions and structs that of course aren't defined in old
protocol versions so naturally this breaks the build on those systems.
Since this is just a niche feature and not really critical to overall
wayland support in mpv, just give in and add another check in the build
system and #if out the newer stuff in wayland_common. v4 of linux-dmabuf
depends on wayland protocols 1-24[1], so go ahead and make that our new
check. Fixes#10807.
[0]: a840b3634a
[1]: 8a5cd28a0e
vo_dmabuf_wayland has its own ra and context so it can handle all the
different hwdec correctly. Unfortunately, this API was pretty clearly
designed with vo_gpu/vo_gpu_next in mind and has a lot of concepts that
don't make sense for vo_dmabuf_wayland. We still want to bolt on a
ra_ctx, but instead let's rework the ra_ctx logic a little bit. First,
this introduces a hidden bool within the ra_ctx_fns that is used to hide
the wldmabuf context from users as an option (unlike the other usual
contexts). We also want to make sure that hidden contexts wouldn't be
autoprobed in the usual ra_ctx_create, so we be sure to skip those in
that function. Additionally, let's create a new ra_ctx_create_by_name
function which does exactly what says. It specifically selects a context
based on a passed string. This function has no probing or option logic
is simplified just for what vo_dmabuf_wayland needs. The api/context
validations functions are modified just a little bit to make sure hidden
contexts are skipped and the documentation is updated to remove this
entries. Fixes#10793.
vo_gpu and vo_gpu_next typically load hwdec interops on demand and
vo_dmabuf_wayland naively copied this logic. This is actually wrong
however since draw_frame in the VO always inherently relies on hwdec
being fully loaded. This can lead to a race condition during startup
which happens with --force-window=immediate. Avoid this by simply always
loading all the interops. In the case of vo_dmabuf_wayland, this is not
really a big deal since there's only vaapi and drmprime to load. Also
fixes#10791 (the other half).
We really need two roundtrips in the init function. The first one is for
running the registry and then second one is for ensuring the xdg_surface
and other potential wayland objects are configured at least once before
mpv does anything. We've been getting away with only doing the first for
a while via luck, but really we should do at least one more wait on the
compositor. Fixes#10791 (half of it).
Building on DRM platform without VAAPI broke because of misuse of
HAVE_VAAPI with #ifdef in place of #if. Also, the hwcontext_drm.h
header is not required for VAAPI builds, only DRM builds.
Originally, I considered warning once to be useful for figuring
out whether the change in logic regarding resetting requested
mode actually fixed the reported issue or not, but alas not everyone
was happy with that decision. Thus the log level will always be
debug. This enables us to lose one level of indent as well as a
variable, which is always positive.
Additionally, make the message more explicit regarding what could
possibly be implied by the mismatch, as it seems like this was
not always clear.
Otherwise mpv and the compositor can end up in an eternal loop where
mpv requests one mode, and compositor tells that the mode is not
that (and will most likely not change).
Additionally, log these mismatches - first time as a warning, and
later as debug logging.
It is verbose, but makes it more explicit that requested_decoration
takes in three values:
* 0: no specific mode requested by mpv
* ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: (!border)
* ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: (border)
Pulled from https://github.com/mpv-player/mpv/pull/10382
The zwp_linux_dmabuf_v1 protocol version 4 provides a file descriptor
containing both formats and modifiers, which makes it possible for the
compositor to import the buffers onto planes using explicit modifiers.
This is an extremely important efficiency improvement, as the 3D
hardware can be left powered off altogether, the vaapi buffer being sent
directly from the video hardware to the display controller.
It could be possible to support zwp_linux_dmabuf_v1 version 3 as well,
but there is no reason beyond compatibility with old stacks. I would
recommend to ditch version 2 as well, as modifier-less formats aren’t
very useful nowadays.
Wayland VO that can display images from either vaapi or drm hwdec
The PR adds the following changes:
1. a context_wldmabuf context with no gl dependencies
2. no-op ra_wldmabuf and dmabuf_interop_wldmabuf objects
no-op because there is no need to map/unmap the drmprime buffer,
and there is no need to manage any textures.
Tested on both x86_64 and rk3399 AArch64
dmabuf-wayland vo supports both DRMPRIME and VAAPI formats.
If upload filter is needed, we want to try VAAPI hwdec first
since most users will be using VAAPI, and there is a several second
delay when DRMPRIME hwdec is tried and fails.
This has been a long standing problem that I think was the root cause
for wm4's vaapi shitlist. As DRM explicit supports all possible rgba
orderings, but OpenGL only guarantees support for 'rgba8', something
has to happen to support import of dmabufs with non-native ordering.
Although undocumented, it appears that somewhere in the import on the
GL side, the ordering is swizzled to rgba - which makes sense as that's
the only way to be able to support importing all the different formats.
But we didn't know this, and we do our own swizzling based on the
original imgfmt - which matches the drm format. So we get double
swizzling and messed up colours.
As there is no way for us to express that the GL swizzle happened to
the rest of mpv, the easiest thing to do is fudge the format to the
natural ordering so the GL doesn't change anything, then our swizzling
will do the right thing in the end.
Note that this change doesn't handle 0rgb and 0bgr because they seem to
be affected by some additional feature/bug that is mangling the
ordering somewhere that equally affects Vulkan interop. That could be a
vaapi driver bug or something going on in ffmpeg.
The logic around trying to establish what formats are supported by
vaapi is confusing, and it turns out that we've been doing it wrong.
Up until now, we've been going through the list of decoding profile
endpoints and checking the formats declared in those profiles to build
our list.
However, the set of formats that the vaapi driver can actually support
is potentially a superset of those supported by any given profile
endpoint. This master list is exposed by libavutil via the
av_hwframe_transfer_get_formats() function, and so we should use that
list as our starting point.
Perhaps surprisingly, this change actually removes no code, because we
still want the logic that enumerates endpoints and finds supported
formats for endpoints. We need this because we must have at least one
known sw format to initialise the hwframe_ctx with.
Additionally, while in the general case,
av_hwframe_transfer_get_formats can return different formats depending
on what format you initialise the hwframe_ctx with, I happen to have
read the libavutil code, and it doesn't care, so we just need to call
it once, we know we'll get back all known formats.
In practice, with an Intel vaapi driver, this will result in us
supporting a handful of extra formats for hwuploads - particularly
yuv420p (so no need to convert to nv12 first) and various orderings
of rgb(a).
We've had some annoying names for interops, which we can't simply
rename because that would break config files and command lines. So we
need to put a little more effort in and add a concept of legacy names
that allow us to continue loading them, but with a warning.
The two I'm renaming here are:
* vaapi-egl -> vaapi (vaapi works with Vulkan too)
* drmprime-drm -> drmprime-overlay (actually describes what it does)
* cuda-nvdec -> cuda (cuda interop is not nvdec specific)
mpv set _NET_WM_DESKTOP to 0xFFFFFFFF, which behaves differently with each window manager.
Instead, set the window property to STICKY, and let the window managers deal with it.
The new status quo is simple: all messages coming from libplacebo are
marked "vo/gpu{-next}/libplacebo", regardless of the backend API (vulkan
vs opengl/d3d11).
Messages coming from mpv's internal vulkan code will continue to come
from "vo/gpu{-next}/vulkan", and messages coming from the vo module
itself will be marked "vo/gpu{-next}".
This is significantly better than the old status quo of vulkan messages
coming from "vo/gpu{-next}/vulkan/libplacebo" whereas opengl/d3d11
messages simply came from "vo/gpu{-next}", even when those messages
originated from libplacebo.
(It's worth noting that the the destructor for the log is redundant
because it's attached to the ctx which is freed on uninit anyway)
Managed to go completely unnoticed for months (who was the bad person
that introduced these*). Fairly self-explanatory. After getting
ProviderInfo from randr, we need to free it. The other one is pretty bad
because it leaked every frame (ouch). It turns out that you're supposed
to free any event data after you cast a generic event to an
XGenericEventCookie. Free that as well.
*: It was me.
The wayland presentation time code currently always assumes that only
CLOCK_MONOTONIC can be used. There is a naive attempt to ignore clocks
other than CLOCK_MONOTONIC, but the logic is actually totally wrong and
the timestamps would be used anyway. Fix this by checking a use_present
bool (similar to use_present in xorg) which is set to true if we receive
a valid clock in the clockid event. Additionally, allow
CLOCK_MONOTONIC_RAW as a valid clockid. In practice, it should be the
same as CLOCK_MONOTONIC for us (ntp/adjustime difference wouldn't
matter). Since this is a linux-specific clock, add a define for it if it
is not found.
This has had no effect since libplacebo v4.192.0, and was deprecated
upstream a year ago. No deprecation period in mpv is justified by this
being a debug / work-around option.
This brings vo_gpu_next's behavior more in line with vo_gpu. Currently,
the status quo was that `vo_gpu_next` generated subtitles with the full
resolution of the dst crop, even though practical limitations of
libplacebo meant that such subtitles inevitably got cut off at the video
boundaries. This was actually a worse status quo than `vo_gpu`, which
simply constrained subtitles to the video dimensions to prevent these
issues.
With this change, the behavior is the same as `vo_gpu`, which has the
exact same problem w.r.t interpolation. Users are back to choosing
between --blend-subtitles=yes and not having subtitles in margins,
and using --blend-subtitles=no and not having subtitle interpolation.
There are different pros and cons to each approach, and I still
ultimately plan on allowing libplacebo to interpolate subtitles even in
the black bars, to solve this issue once and for all. But for now, let's
not let perfect be the enemy of good.
No attempt is made to implement `--blend-subs=video`, which I consider
deprecated.
Fixes: https://github.com/mpv-player/mpv/issues/10272
I actually don't quite understand why this is needed, since in theory we
should already be doing the rotation as part of applying the crop. But I
guess that code doesn't quite work. This is the only way it works, so
it's probably correct. (And note that `vo_gpu` does the same internally)
This fixes an issue where blend stages with multiple passes got
overwritten by later passes, with only the final pass (typically the
overlayp pass) actually being shown.
Certain combinations of hardware formats require the use of hwmap to
transfer frames between the formats, rather than hwupload, which will
fail if attempted.
To keep the usage of vf_format for HW -> HW transfers as intuitive as
possible, we should detect these cases and do the map operation instead
of uploading.
For now, the relevant cases are moving between VAAPI and Vulkan, and
VAAPI and DRM Prime, in both directions. I have introduced the IMGFMT
entry for Vulkan here so that I can put in the complete mapping table.
It's actually not useless, as you can map to Vulkan, use a Vulkan
filter and then map back to VAAPI for display output.
Historically, HW -> HW uploads did not exist, so the current code
assumes they will never happen. But as part of introducing Vulkan
support into ffmpeg, we added HW -> HW support to enable transfers
between Vulkan and CUDA.
Today, that means you can use the lavfi hwupload filter with the
correct configuration (and previous changes in this series) but it
would be more convenient to enable HW -> HW in the format filter so
that the transfers can be done more intuitively:
```
--vf=format=fmt=cuda
```
and
```
--vf=format=fmt=vulkan
```
Most of the work here is skipping logic that is specific to SW -> HW
uploads doing format conversion. There is no ability to do inline
conversion when moving between HW formats, so the format must be
mutually understood to begin with.
Additional work needs to be done to enable transfers between VAAPI
and Vulkan which uses mapping, rather than uploads. I'll tackle that
in the next change.
Today, lavfi filters are provided a hw_device from the first
hwdec_interop that was loaded, regardless of whether it's the right one
or not. In most situations where a hardware based filter is used, we
need more control over the device.
In this change, a `hwdec_interop` option is added to the lavfi wrapper
filter configuration and this is used to pick the correct hw_device to
inject into the filter or graph (in the case of a graph, all filters
get the same device).
Note that this requires the use of the explicit lavfi syntax to allow
for the extra configuration.
eg:
```
mpv --vf=hwupload
```
becomes
```
mpv --vf=lavfi=[hwupload]:hwdec_interop=cuda-nvdec
```
or
```
mpv --vf=lavfi-bridge=[hwupload]:hwdec_interop=cuda-nvdec
```