This commit kind of mixes several related things together. The main
thing is to avoid calling any XPresent functions or internal functions
related to presentation when the feature is not auto-whitelisted or
enabled by the user. Internally rework this so it all works off of a
use_present bool (have_present is eliminated because having a non-zero
present_code covers exactly the same thing) and make sure it updates on
runtime. Finally, put some actual logging in here whenever XPresent is
enabled/disabled. Fixes#10326.
Previously if the raw command_native_async returned an error then the
callback function was run directly. This meant that script writers
potentially had to account for both synchronous and asynchronous logic
in the callback, which can happen even with seemingly 'safe' commands
if the mpv event queue is full.
This was at odds with the Javascript implementation of
the function, which always runs the callback asynchronously.
Now the mp.add_timeout function is used to run the callback
asynchronously on error, replicating the Javascript implementation.
This provides consistency for developers in how the callback is handled
in Lua, and increases consistency between the Lua and Javascript APIs.
With the recent addition of the libxpresent, it should improve frame
timings for most users. However, there were known cases of bad behavior
(Nvidia) which lead to a construction of a whitelist instead of just
enabling this all the time. Since there's no way to predict whatever
combination of hardware/drivers/etc. may work correctly, just give users
an option to switch the usage of xorg's presentation statistics on/off.
The default value, auto, works like before (basically, Mesa drivers and
no Nvidia are allowed), but now one can force it on/off if needed.
The old logic always reset the x11->has_mesa/has_nvidia values on every
loop through the provider. This meant that it would always just match
whatever the last provider happened to be. So in the case of a dual GPU
system, if nvidia was the very first provider and the integrated
intel/amd card was the second (in practice, this is probably mostly the
other way around), then mpv would set has_mesa to true and has_nvidia to
false and thus try to use presentation. This is not the intended
behavior. Just rework this by also checking x11->has_mesa/has_nvidia in
the loop so a true value from the previous iteration is preserved.
This code was taken from the older vo_vaapi driver, which does
use the vaapi format list, but the new driver has no use for
these formats, as it is only interested in va surfaces that
can be mapped to wl buffers. The format doesn't enter into
it at all.
Immediately after this, d3d11 is defined again and the rest of the
meson.build uses that. Probably, this dictionary was from the original
meson PR and removing it was forgotten at some point while stuff was
being rewritten.
This builds off of present_sync which was introduced in a previous
commit to support xorg's present extension in all of the X11 backends
(sans vdpau) in mpv. It turns out there is an Xpresent library that
integrates the xorg present extention with Xlib (which barely anyone
seems to use), so this can be added without too much trouble. The
workflow is to first setup the event by telling Xorg we would like to
receive PresentCompleteNotify (there are others in the extension but
this is the only one we really care about). After that, just call
XPresentNotifyMSC after every buffer swap with a target_msc of 0. Xorg
then returns the last presentation through its usual event loop and we
go ahead and use that information to update mpv's values for vsync
timing purposes. One theoretical weakness of this approach is that the
present event is put on the same queue as the rest of the XEvents. It
would be nicer for it be placed somewhere else so we could just wait
on that queue without having to deal with other possible events in
there. In theory, xcb could do that with special events, but it doesn't
really matter in practice.
Unsurprisingly, this doesn't work on NVIDIA. Well NVIDIA does actually
receive presentation events, but for whatever the calculations used make
timings worse which defeats the purpose. This works perfectly fine on
Mesa however. Utilizing the previous commit that detects Xrandr
providers, we can enable this mechanism for users that have both Mesa
and not NVIDIA (to avoid messing up anyone that has a switchable
graphics system or such). Patches welcome if anyone figures out how to
fix this on NVIDIA.
Unlike the EGL/GLX sync extensions, the present extension works with any
graphics API (good for vulkan since its timing extension has been in
development hell). NVIDIA also happens to have zero support for the
EGL/GLX sync extensions, so we can just remove it with no loss. Only
Xorg ever used it and other backends already have their own present
methods. vo_vdpau VO is a special case that has its own fancying timing
code in its flip_page. This presumably works well, and I have no way of
testing it so just leave it as it is.
Unfortunately there's a certain company that makes graphics drivers that
are harder to deal with. The next commit aims to implement presentation,
but some empirical testing from users show that it's actually broken.
Give up and just tap into Xrandr so we can figure what drivers (or well,
providers by the extension terminology) are driving the screen.
Basically if we find intel, amd, or radeon, assume it's a Mesa driver.
If we find nvidia, then it must be nvidia. This detection requires randr
1.4 (which means using presentation in mpv secretly depends on randr
1.4), but this protocol version is nearly a decade old anyway so
probably 99.9% of users are fine. Do the version query check and all
that anyway just to be on the safe side.
Wayland had some specific code that it used for implementing the
presentation time protocol. It turns out that xorg's present extension
is extremely similar, so it would be silly to duplicate this whole mess
again. Factor this out to separate, independent code and introduce the
mp_present struct which is used for handling the ust/msc values and some
other associated values. Also, add in some helper functions so all the
dirty details live specifically in present_sync. The only
wayland-specific part is actually obtaining ust/msc values. Since only
wayland or xorg are expected to use this, add a conditional to the build
that only adds this file when either one of those are present.
You may observe that sbc is completely omitted. This field existed in
wayland, but was completely unused (presentation time doesn't return
this). Xorg's present extension also doesn't use this so just get rid of
it all together. The actual calculation is slightly altered so it is
correct for our purposes. We want to get the presentation event of the
last frame that was just occured (this function executes right after the
buffer swap). The adjustment is to just remove the vsync_duration
subtraction. Also, The overly-complicated queue approach is removed.
This has no actual use in practice (on wayland or xorg). Presentation
statistics are only ever used after the immediate preceding swap to
update vsync timings or thrown away.
Technically this was wrong. If you passed -Dvdpau=enabled but did not
have x11 (a requirement for this), the build would silently just not
build the vdpau VO. The correct behavior is for it to be a hard error.
Accomplish this by using the require function and making sure that x11
is indeed being used before attempting to find the library.
In win32 build, if libass and libfontconfig appear after libmingwex
during linking, crash happens whenever fontconfig calls to opendir().
Moving them before ffmpeg makes sure they always appear first.
More info on https://github.com/shinchiro/mpv-winbuild-cmake/issues/217.
The first set iterates through all standard FFmpeg layouts and
checks that those which fit MP_NUM_CHANNELS succeed.
The second set iterates through built-in named channel layouts,
and attempts to convert them to AVChannelLayouts.
This is the new FFmpeg channel layout structure, which now
combines channel count and layout into a single location.
Only unspecified (channel count only) and native (channel layout
mask based) layouts are currently supported for the initial move
towards non-deprecated APIs.
This shouldn't have mattered but apparently qtile is unable to get the
app id if you set it after the initial surface commit. Wayland is a mess
anyway so just shuffle this around so that the frame callback and
surface commit are the last things registered in vo_wayland_init. This
works around qtile and, in theory, doesn't appear to break anything
else. Fixes#10280.
Some wayland compositors (i.e. weston) get extremely picky about
committed buffer sizes not matching the configured state. In particular,
weston throws an error on you if you attempt to launch with
--window-maximized and use opengl (vo_vaapi_wayland actually errors as
well in this case, but that's a different issue). The culprit here is
actually wl_egl_window_create. This creates an initial buffer at the
sizes passed in the arguments which is what weston doesn't like.
Instead, move the egl_window creation call to the resize function. This
ensures that mpv is using the size obtained via the toplevel event, and
it should always be the buffer size we want.
The `absolute` value was incorrectly labelled as the default instead of
the value named `default`, which was somewhat confusing. When the newer
default option was added in 679e410 it seems like wm4 forgot to remove
the label in the manual on the previous default.
TL;DR: previously a JavaScript VM was created + destroyed whenever
a sub track was initialized, even if no jsre filter was set.
Now a JS VM is created only if jsre filters were set.
Sub filters are initialized once when a subtitle track is chosen, and
then whenever the sub track changes or when some sub options change.
Sub filters init is synchronous - playback is suspended till it ends.
A filter can abort init early (get disabled) depending on conditions
specific to each filter. The regex and jsre filters aborted early
if the filter is disabled (default is enabled) or if the track is not
ass (relativey rare, e.g. bitmap subs).
The init then iterates over the filter strings, and if the result is
empty (common - no filter was added, but also if all strings failed
regex init) then it's also aborted during init.
While this iteration step is cheap with filter regex, with jsre it
requires instanciating the JS VM (mujs) in advance in order to parse
the filter strings at the list, and the VM is then destroyed if the
list ends up empty.
This VM create+destroy is fast but measurable (0.2 - 0.7 ms, slowest
measured on 2010 MacBook Air), but can be avoided altogether if we
check that the filter list is not empty before we create the VM.
So now we do just that.
This way mingw-w64 becomes the first CI workflow to build gpu-next.
Unfortunately, currently neither wscript or meson has gpu-next or
libplacebo-next as an option that one can require.
This was actually always bugged, but we just got lucky that compositors
ignored it. The egl window was created only using wl->geometry's
coordinates but those do not include the scale factor. So technically,
the initial window creation always had the wrong size (off by whatever
the scaling factor is). The resize call later fixes it because that
correctly uses wl->scaling so in practice nothing bad was seen.
wlroots's master branch has started sending an error in this case
however and this is what trips it. Fix it correctly by using the scale
factor. This is what cd3b4edea0 tried to
fix (but was incorrect).
cd3b4edea0 is not correct and had some
unexpected breakage with geometry/resizing. Rather than completely
revert it, this commit restores the set_surface_scaling call as well as
rearranges some other things in the wayland init/reconfig process to
make it simplier. The next commit properly fixes what
cd3b4edea0 tried to fix.
Just a couple of small changes. First, the obvious one is to remove the
bogus wl->window_size = wl->vdparams; line in the configure conditional.
The reconfig always unconditionally sets the window_size here so there's
no need to duplicate it. The more important change is to remove the
usage of set_surface_scaling. This function is just to handle when
scaling changes and for setting the initial scale, it was called in the
reconfig. This, however, causes some weird issues in the latest
sway/wlroots where it can try to divide a buffer by an inappropriate
scale factor. This is possibly due to some weird ordering of events and
only occured in opengl for some reason.
Luckily, it turns it out it's not neccessary to set the scaling here at
all. The surface enter event is already setup to handle scale changes.
On an HIDPI display, mpv will initially assume a scale of 1 but the
surface actually enters the wl_output, it will automatically readjust
and resize itself to the appropriate scale value. This works on the
initial launch of the mpv window as well, so there's no need to special
case this in the reconfig event. This has the nice bonus of avoiding
that sway/wlroots issue as well since the buffer_scale is set much
later. Fixes#10263.
One downside of this approach is that it bypasses the mixer cache, but
while this is not ideal for performance reasons, the status quo is also
simply broken so I'd rather have a slower implementation that works than
a faster implementation that does not.
And as it turns out, updating the OSD state and invalidating the mixer
cache correctly is sufficiently nontrivial to do in a clean way, so I'd
rather have this code that I can be reasonably certain does the right
thing.
Fixes#9923 as discussed. Also fixes#9928.
This is mainly for other user scripts that may conflict with the osc
logo in some way. Although it is possible to listen for
shared-script-properties, this has many edge cases that could easily pop
up. A user could want other OSC things to happen at the same time (say
osc-message). They just don't want the logo. The idlescreen option
disables all idlescreen related things (including the santa hat) if it
is set to "no". A new script message (osc-idlescreen) is also added so
users can easily toggle the value (passing "cycle" or just explictly
setting "yes" or "no"). Some more discussion on this is found in the
below github issues.
https://github.com/mpv-player/mpv/issues/10201https://github.com/CogentRedTester/mpv-file-browser/issues/55
Apparently _t names are reserved, and in this case it wasn't very
useful anymore (it was useful while developing it, but this code is
almost 10 years old now).
Fixes a compilation error on Solaris.