The problem with the previous code - which used mp.get_user_path, is
that it returns a path even with --no-config, and even if the file
doesn't exist.
This is why we tested the "config" property, and also used
mp.utils.file_info to check that the file exists.
mp.find_config_file doesn't return a path with no-cofig and doesn't
return a path if the file doesn't exists. It's simpler and better.
Upstream libplacebo got refactored to use byte-sized strides rather than
texel-sized strides. This commit makes mpv's ra_pl wrapper take
advantage of that, rather than forcing a stride-fixing memcpy.
Note that, technically, we would still need a stride fixing memcpy in
cases when the true stride is not a multiple of the format's texel
*alignment*, however this is a much rarer case and extremely unlikely to
occur in practice, since all relevant formats use power-of-two texel
alignments.
In the reconfig event, the keepaspect option was checked before setting
the window_size geometry to the new params obtained from the vo. This is
incorrect. If a user disabled keepaspect on wayland, the video's size
would not change on a reconfigure event (i.e. loading a new video in the
playlist with a different size). No other windowing backend (x11, win32,
etc.) behaves like this or uses keepaspect in its code like wayland did
in this case. Clearly, this is not correct. Such functionality should be
handled by a separate option entirely. Just remove this if statement.
The bytes_read struct member in AVIOContext is now officially public,
so its usage no longer has to be specified as non-compliance with
FFmpeg's ABI/API rules.
That said, unfortunately there was a short period of time between
August 2021 and October 2021 where the struct member did not exist
in FFmpeg's git master, so keep a feature check for it alive for
now to enable building with those versions. Thankfully, no release
version of FFmpeg will be without this field, so it should be
possible to drop this check with time.
Finally, simplify the function in case the struct member is not
found. After all, there is zero reason to iterate through the AVIO
contexts if we cannot get the information we require.
Based on the idea behind emersion's change to drm_info
(https://github.com/ascent12/drm_info/commit/869e789a645b92a99e592a230fe39b0c59a2cd7d).
Lets us by default skip devices which are not capable of doing what
the DRM master output requires (not primary devices), as some devices
have card0 actually not be such.
Negative part is that the number given to drm-connector is no
longer a direct mapping against a file name.
Upon re-examination I have no idea why this code was ever written or
what problem it was trying to solve. But, getting rid of it fixes#9291.
It might be a remnant from before 2af2fa7a27. Who knows. This code will
be replaced soon(tm) anyways.
Regression from e13fe1299d. Apparently,
Broadcom's EGL does not support the EGL_CONTEXT_FLAGS_KHR attribute nor
EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR. Just define these as EGL_NONE and 0
respectively if we do not have them.
editorconfig configuration files hold editor style hints, and
is supported by many popular editors. See https://editorconfig.org/ .
The vast majority of the mpv source/text files are already styled as
4 space indentation, trailing newline at EOF, and UTF-8 encoding.
This commit adds a single .editorconfig root file which applies these
rules to all files using the glob "[*]".
If it turns out to be too inclusive then we can narrow it down later.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Normally there was no issue, but when the code converted a deeply
nested table into an mpv node - it didn't ensure the stack has room.
Lua doesn't check stack overflow when invoking lua_push* functions,
and leaves this responsibility to the (c) user via lua_checkstack.
Normally that's not an issue because when a lua (or autofree) function
is called, it's guaranteed at least LUA_MINSTACK (20) pushes.
However, pushnode and makenode are recursive, and each iteration can
add few values at the stack (which are popped when the recursion
unwinds), so checkstack must be used on (recursive) entry.
pushnode already checked the stack, makenode did not.
This commit checks the stack at makenode as well. The value of 6
(stack places to reserve) is with some room to spare, and in pratice
each iteration needs 2-3 at most (pushnode also leaves room).
Example which could previously corrupt the stack:
utils.format_json({d1={d2={<8 more times>}}}
This uses makenode to convert the lua table into an mpv node which
the json writer uses as input, and if the depth is 10 or more then
corruption could occur. mp.command_native is also affected, as well as
any other mp/utils command which takes a lua table as input.
While at it, fix the error string which pushnode used (luaL_checkstack
uses the provided string with "Stack overflow (%s)", so the user
message only needs to be additional info).
The speedup is due to moving big part of the autofree runtime overhead
(new lua c closure) to happen once on init at af_pushcclosure, instead
of on every call. This also allows supporting upvalues trivially, even
if mpv doesn't use it currently, and is more consistent with lua APIs.
While x2 infrastructure speedup is meaningful - and similar between
lua 5.1/5.2/jit, in practice it's a much smaller improvement because
the autofree overhead is typically small compared to the "real" work
(the actual functionality, and talloc+free which is needed anyway).
So with this commit, fast functions improve more in percentage.
E.g. utils.parse_json("0") is relatively fast and is now about 25%
faster, while a slower call like mp.command_native("ignore") is now
about 10% faster than before. If we had mp.noop() which does nothing
(but still "needs" alloc/free) - it would now be about 50% faster.
Overall, it's a mild performance improvements, the API is now more
consistent with lua, and without increasing code size or complexity.
mpv doesn't have other dot files in its config dir, and it also
shouldn't be "invisible".
The new name ~~/init.js now replaces ~~/.init.js
While mpv usually deprecates things before outright removing them,
in this case the old (dot) name is replaced without deprecation:
- It's a bad idea to execute hidden scripts, even if at a config dir,
and we don't want to do that for the next release cycle too.
- We warn if the old (dot) name exists and the new name doesn't,
which should be reasonably visible for affected users.
- It's likely niche enough to not cause too much pain.
If for some reason both names are needed, e.g. when using also an old
mpv versions, then the old name could be symlinked to the new one, or
simply have one line: `require("~~/init")` to load the new name, while
a new mpv version will load (only) the new name without warning.
With the recent refactor and quick look against the GLX code path, it's
fairly obvious, and trivial, how to add support for debug contexts.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Drop the gl3 suffix from the function name - it's no longer needed, with
the _old function gone.
Push the mpgl_min_required_gl_versions[] looping within the function,
reducing the identical glXGetProcAddress/glXQueryExtensionsString calls
while making the code neater.
v2:
- tabs -> spaces indentation
- mpgl_preferred_gl_versions -> mpgl_min_required_gl_versions
- 320 -> 300 (in glx code path)
v3:
- legacy code path is gone \o/
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The old/legacy code-path isn't really needed for mpv use-cases.
In particular:
All Mesa drivers (even GL 2.1 ones like lima/vc4) work fine with the
"non-legacy" path.
From proprietary/binary drivers - the vendor either does not support
desktop GL or the drivers/HW is not actively supported.
Looking at the Nvidia HW - anything GeForce 7 and older is GL 2.1 and
lacks decent video acceleration. The latest official drivers are from
2017.
All newer Nvidia HW is GL 3.3+ thus must have GLX_ARB_create_context as
in the non-legacy path, while also good acceleration albeit via VDPAU
in some cases.
With the old path gone, provide meaningful error message in the very
unlikely case that GLX_ARB_create_context is missing.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
With earlier commit f8e62d3d82 ("egl_helpers: fix create_context
fallback behavior") we added a fallback for creating OpenGL context
while EGL_KHR_create_context is missing.
While it looked correct at first, it is missing the eglMakeCurrent()
call after creating the EGL context. Thus calling glGetString() fails.
Instead of doing that we can just remove some code - simply pass the
CLIENT_VERSION 2, as attributes which is honoured by EGL regardless of
the client API. This allows us to remove the special case and drop some
code.
v2:
- mpgl_preferred_gl_versions -> mpgl_min_required_gl_versions
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The ra_gl_ctx_test_version() helper is quite clunky, in that it pushes a
simple check too deep into the call chain. As such it makes it hard to
reason, let alone have the GLX and EGL code paths symmetrical.
Introduce a simple helper ra_gl_ctx_get_glesmode() which returns the
current glesmode, so the platforms can clearly reason about should and
should not be executed.
v2:
- mpgl_preferred_gl_versions -> mpgl_min_required_gl_versions
- 320 -> 300 (in glx code path)
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
As the documentation of the toggle says - the implementation can (and
will actually if they follow the GLX/EGL spec) return context version
greater than the one requested.
This happens with all Mesa drivers that I've tested as well as the
Nvidia binary drivers.
This toggle seems like a workaround for buggy drivers, yet it's lacking
context about the vendor and version.
Remove it for now - I'll be happy to reinstate it (partially or in full)
as we get concrete details.
This allows us to simplify ra_gl_ctx_test_version() making the whole
context creation business easier to follow by mere mortals.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Alike the GL commit earlier - the EGL spec essentially mandates that
implementation will return GLES 3.0+ (if supported by the driver), even
though only GLES 2 is requested.
The only thing we should watch out is - we should add both ES2_BIT and
ES3_BIT as EGL_RENDERABLE_TYPE.
This has been verified against the Mesa drivers (i965, iris, swrast) and
Nvidia binary drivers.
v2:
- int es_version -> bool es
- unloop create_context() execution
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Currently mpv requires a bare minimum of GL 2.1, although it tries to
use 3.2+ core contexts when possible.
The GLX and EGL spec effectively guarantee that the implementation will
give you the highest compatible version possible. In other words:
Requesting 3.2 core profile will always give you core profile and the
version will be in the 3.2 .. 4.6 range - as supported by the drivers.
Similarly for 2.1 - implementation will give you either:
- 2.1 .. 3.1, or
- 3.2 .. 4.6 compat profile
This has been verified against the Mesa drivers (i965, iris, swrast) and
Nvidia binary drivers.
As such, drop the list to 320, 210 and terminating 0.
v2:
- mpgl_preferred_gl_versions -> mpgl_min_required_gl_versions
- update ^^ comment
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The ioctls were disabled a while back since they error out and allegedly
cause problem with X running in another VT.
Omitting the ioctls is not cool, even as a workaround.
If they fail, the user is supposed to fallback appropriately - use a suid
wrapper, logind-like daemon or otherwise.
As of kernel 5.10, they should just work in nearly all cases, so let's
just reinstate the calls.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
The ioctls were disabled a while back since they error out and allegedly
cause problem with X running in another VT.
Omitting the ioctls is not cool, even as a workaround.
If they fail, the user is supposed to fallback appropriately - use a suid
wrapper, logind-like daemon or otherwise.
As of kernel 5.10, they should just work in nearly all cases, so let's
just reinstate the calls.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This behavior is more convenient and allows profile conditions like:
[video]
profile-cond=get('current-tracks/video/image') == false
[image]
profile-cond=get('current-tracks/video/image')
Otherwise, these profiles have to be manually applied and restored in a
script.
The note about discouraging the use of current-tracks in scripts is
removed, because it makes people avoid using this convenient property.
It was added in 720bcd79d0 without leaving an explanation of why you
shouldn't use it, and the only reason seems to be that it doesn't work
with lavfi-complex, but this commit changes that.
This exposes whether a video track is detected as an image, which is
useful for profile conditions, property expansion and lavfi-complex.
The lavf demuxer sets image to true when the existing check detects an
image.
When the lavf demuxer fails, the mf one guesses if the file is an image
by its extension, so sh->image is set to true when the mf demuxer
succeds and there's only one file.
The mkv demuxer just sets image to true for any attached picture.
The timeline demuxer just copies the value of image from source to
destination. This sets image to true for attached pictures, standalone
images and images added with !new_stream in EDL playlists, but it is
imperfect since you could concatenate multiple images in an EDL playlist
(which should be done with the mf demuxer anyway). This is good enough
anyway since the comment of the modified function already says it is
"Imperfect and arbitrary".
This moves the image check to where the number of frames is available of
comparison, which allows not detecting jpg and png videos as images, and
detecting 1-frame gifs as images. This works with the mjpeg and png
videos in the FATE suite, though unfortunately the bmp video is still
detected as an image since it has nb_frames = 0.
aliaspix streams are also now considered images.
Attached pictures are now treated like standalone images, so audio with
attached pictures now has mf-fps as container-fps instead of
unavailable, which makes it consistent with external cover art, which
was already being assigned mf-fps.
Unfortunately images in a codec commonly used for videos are never
detected, and detection was inaccurate even using the now private
codec_info_nb_frames field in AVStream, and mediainfo gets them wrong
too, so I guess it's just a lost cause.
The custom init script should be considered a configuration file, and
as such it should be ignored when the user wants vanilla mpv - and now
it is ignored with --no-config.
This is similar to [no-]input-default-bindings, but affects only
builtin bindings (while input-default-bindings affects anything which
config files can override, like scripting mp.add_key_binding).
Arguably, this is what input-default-binding should have always done,
however, it does not.
The reason we add a new option rather than repurpose/modify the
existing option is that it behaves differently enough to raise
concerns that it will break some use cases for existing users:
- The new option is only applied once on startup, while
input-default-bindings can be modified effectively at runtime.
- They affects different sets of bindings, and it's possible that
the set of input-default-bindings is useful enough to keep.
Implementation-wise, both options are trivial, so keeping one or the
other or both doesn't affect code complexity.
It could be argued that it would be useful to make the new option
also effective for runtime changes, however, this opens a can of
worms of how the bindings are stored beyond the initial setup.
TL;DR: it's impossible to differentiate correctly at runtime between
builtin bindings, and those added with mp.add_key_bindings.
The gist is that technically mpv needs/uses two binding "classes":
- weak/builtin bindings - lower priority than config files.
- "user" bindings - config files and "forced" runtime bindings.
input-default-bindings affects the first class trivially, but
input-builtin-bindings would not be able split this class further
at runtime without meaningful changes to a lot of delicate code.
So a new option it is. It should be useful to some libmpv clients
(players) which want to disable mpv's builtin bindings without
breaking mp.add_key_bindings for scripts.
Fixes#8809
(again. the previous fix 8edfe70b only improved the docs, while
now we're actually making the requested behavior possible)
Currently using mpv --msg-level=help, shows an instance of --msglevel
(missing dash). Seems like the help message was only partially updated
with the -msglevel -> --msg-level transition.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Before this commit, animation-end was handled at render(), however,
it's not called on idle, which resulted in state.anitype ~= nil, with
nothing to reset it during idle, which caused in an infinite tick()
loop (starts on first mouse move).
Now tick resets the animation on idle, and also, as a safety measure,
if we're past 1s after the animation deadline.
The safety measure is because the osc states are complex, and it's
easier to detect a "we really shouldn't be animating now" at tick()
itself rather than detecting the exact states where animation should
be reset. Generally, the safety mmeasure is not needed.
TL;DR: use --lua=XXX for pkg-config name XXX, e.g. --lua=lua-5.1 .
For unversioned 'lua.pc', use the name luadef51/luadef52 .
Autodetection remains the same (5.2 names, luajit, 5.1 names).
The old names are still supported, but not auto-detected.
Before this patch, if one wanted to choose a specific lua version when
more than one is installed, then the names were a mess, e.g. 51obsd is
also the name detected on Arch linux, and other (distro) names are
also not unique to a specific distro/platform.
So to ask mpv to choose the package name (specifically, the pkg-config
file name), one needs to look at the mpv sources and find the
(arbitrary) distro name which has the same lua version naming as they
do on their own system, e.g. --lua=51obsd on Arch. This is a pain.
Now we add generic names:
- luadef51/luadef52 - generic pkg-config lua.pc (version is inside).
- lua* - exactly the pkg-config name, e.g. --lua=lua-51 for lua-51.pc
(the names are curated, e.g. --lua=foo won't detect foo.pc).
- The legacy names (e.g. 51deb) are still supported, but undocumented,
and the new generic names take precedence during auto-detection.
The fact that the generic names all start with "lua" has an additional
benefit that it shows right after "lua" at the output of mpv -v,
while the old names start with numbers, so they're first at the list,
making it hard to understand that e.g. "51obsd" is the lua version.
None of these names are actually used at the mpv code. The C code
checks the version using the lua headers (LUA_VERSION_NUM).
The lua version names which are autodetected/chosen (such as "51deb")
are used for two things:
- as key for storing the pkg-config compile/link flags.
- as ID for config.h and elsewhere - they're sanitized to use "_".
Due to some inconsistensies, if the sanitized ID is different than
the original name, then the compile/link flags are stored with the
original name as key, while the retrieval happens with the sanitized
ID - and therefore fails to find the correct flags.
The solution is to use the original name only for display purpose at
the output of configure, while using the sanitized version for
everything else, so that storage and retrieval use the same key.
Currently there's no issue and the patch has no effect, because the
sanitizer considers all the current names as valid IDs.
However, the next commit will add names which the sanitizer modifies,
such as "lua-5.1", so this commit makes such names work too.
Unfortunately, this functionality in large part based on a struct
member that was made private in FFmpeg/FFmpeg@7489f63281
in May. Unfortunately, this was not noticed during review.
This reverts commit 0862664ac9.
This CI builder bases on openSUSE Tumbleweed, and recently had
its glibc updated. This led to new syscalls such as 'clone3' not
being allowed through the security layer.
Can be reverted after Github Actions updates their security policy.
actions/virtual-environments#3812
This exposes whether a video track is detected as an image. This is
useful for profile conditions, property expansion and lavfi-complex, and
is more accurate than any detection even Lua scripts can perform, since
they can't differentiate between images and videos without container-fps
and audio and with duration 1 (which is the duration set by the mf
demuxer with the default --mf-fps=1).
The lavf demuxer image check is moved to where the number of frames is
available for comparison, and is modified to check the number of frames
and duration instead of the video codec. This doesn't misdetect videos
in a codec commonly used for images (e.g. mjpeg) as images, and can
detect images in a codec commonly used for videos (e.g. 1-frame gifs).
pix files are also now detected as images, while before they weren't
since the condition was checking if the AVInputFormat name ends with
_pipe, and alias_pix doesn't.
Both nb_frames and codec_info_nb_frames are checked because nb_frames is
0 for some video codecs (hevc, av1, vc1, mpeg1video, vp9 if forcing
--demuxer=lavf), and codec_info_nb_frames is 1 for others (mpeg, mpeg4,
wmv3).
The duration is checked as well because for some uncommon codecs and
containers found in FFMpeg's FATE suite, libavformat returns nb_frames =
0 and codec_info_nb_frames = 1. For some of them it even returns
duration = 0, so they are blacklisted in order to never be considered
images.
The extra codecs that would have to be blacklisted without checking the
duration are AV_CODEC_ID_4XM, AV_CODEC_ID_BINKVIDEO,
AV_CODEC_ID_DSICINVIDEO, AV_CODEC_ID_ESCAPE130, AV_CODEC_ID_MMVIDEO,
AV_CODEC_ID_NUV, AV_CODEC_ID_RL2, AV_CODEC_ID_SMACKVIDEO and
AV_CODEC_ID_XAN_WC3, while the containers are film-cpk, ivf and ogg.
The lower limit for duration is 10 because that's the duration of
1-frame gifs.
Streams with codec_info_nb_frames 0 are not considered images because
vp9 and av1 have nb_frames = 0 and codec_info_nb_frames = 0, and we
can't rely on just the duration to detect them because they could be
livestreams without an initial duration, and actually even if we could
for these codecs libavformat returns huge negative durations like
-9223372036854775808.
Some more images in the FATE suite that are really frames cut from a
video in an uncommon codec and container, like cine/bayer_gbrg8.cine,
could be detected by allowing codec_info_nb_frames = 0, but then any
present and future video codec with nb_frames = 0 and
codec_info_nb_frames = 0 would need to be added to the blacklist. Some
even have duration > 10, so to detect these images the duration check
would have to be removed, and all the previously mentioned extra codecs
and containers would have to be added added to the blacklists, which
means that images that use them (if they exist anywhere) will never be
detected. These FATE images aren't detected as such by mediainfo either
anyway, nor can a Lua script reliably detect them as images since they
have container-fps and duration > 0 and != 1, and you probably will
never see files like them anywhere else.
For attached pictures the lavf demuxer always set image to true, which
is necessary because they have duration > 10. There is a minor change in
behavior for which audio with attached pictures now has mf-fps as
container-fps instead of unavailable, but this makes it consistent with
external cover art, which was already being assigned mf-fps.
When the lavf demuxer fails, the mf one guesses if the file is an image
by its extension, so sh->image is set to true when the mf demuxer
succeds and there's only one file.
Even if you add a video's file type to --mf-type and open it with the mf
protocol, only the first frame is used, so setting image to true is
still accurate.
When converting an image to the extensions listed in demux/demux_mf.c,
tga and pam files are currently the only ones detected by the mf demuxer
rather than lavf. Actually they are detected with the image2 format, but
it is blacklisted; see d0fee0ac33.
The mkv demuxer just sets image to true for any attached picture.
The timeline demuxer just copies the value of image from source to
destination. This sets image to true for attached pictures, standalone
images and images added with !new_stream in EDL playlists, but it is
imperfect since you could concatenate multiple images in an EDL playlist
(which should be done with the mf demuxer anyway). This is good enough
anyway since the comment of the modified function already says it is
"Imperfect and arbitrary".
Previously, loading ~~/.init.js was inside a try block, in order to
quietly ignore errors if the file doesn't exist.
However, that also prevented any real errors from showing up even when
the file does exist, and the script continued as if everything is OK,
while in fact the custom init script didn't complete correctly.
Now we first check if the file exists, and then load it without
try/catch, so that any error shows up normally (and abort the script).
The value of the border option should always match what the actual state
of the window is. Previously if a compositor rejected the request by
mpv, it did not correct itself. Also add some code to keep track of
decoration requests. Anytime the state is changed, make the last saved
request again (doesn't hurt and seems like intuitive behavior).
Unfortunately, this isn't foolproof since options only send callback if
the value is changed. (ex. on sway if the floating window has no border,
and then is titled, setting the border value to "yes" does nothing since
tiling the window already set the border value to "yes").
Fixes handle leak that happened whenever tvservice callback was invoked.
Powering on the TV causes HDMI unplug and attached events to be sent to
the tvservice callback.
This meant you could only power on/off your TV a finite number of times
before you were unable to allocate additional resources from VideoCore
(usually resulting in a "Could not get DISPMANX objects." error).
Furthermore because the VideoCore kernel driver does not cleanup handles
when a process dies, the only way to recover from the leak was to reboot
the RPI.
Because youtube-dl is inactive and the yt-dlp fork is becoming more
popular, make mpv use yt-dlp without any extra configuration.
yt-dlp is ordered before youtube-dl because it's more obscure, so users
who have yt-dlp installed are more likely to want to use it rather than
youtube-dl.
Fixes#9208.
In Linux kernel commit 819fbd3d8ef36c09576c2a0ffea503f5c46e9177
these two header files were moved to staging (though they've since
been moved out again by Linus.)
We do not actually use this, and it's in a state of maybe-removal
from the kernel as of Linux 5.14. Get rid of it; mpv still builds
fine without it, so it wasn't needed anyways.
Fixes#9233.
Without this, cases where the parser cannot return data right away
will end up utilizing the following fed packet's timestamps. This
will in turn cause an unnecessary offset in the audio stream
timestamps.
An example of such buffered parser in libavcodec is the EAC3 one.
Before this commit, timeBeginPeriod(1) was set once when mpv starts,
and the timers remained hi-res till mpv exits.
Now we do the same as before on Windows version < 10.
On Windows 10+ we now use timeBeginPeriod if needed, per timeout.
To force a mode regardless of Windows version, set env MPV_HRT:
- "always": the old behavior - hires timers as long as mpv runs.
- "perwait": sets 1ms timer resolution if timeout <= 50ms.
- "never": don't use timeBeginPeriod at all.
It was observed that on Windows 10 we lose about 0.5ms accuracy of
timeouts with "perwait" mode (acceptable), but otherwise it works
well for continuous timeouts (one after the other) and random ones.
On Windows 7 with "perwait": continous timeouts are accurate, but
random timeouts (after some time without timeouts) have bad
accuracy - roughly 16ms resolution instead of the requested 1ms.
Windows 8 was not tested, so to err on the side of caution, we keep
the legacy behavior "always" by default.
This brings enabled features on the same level as disabled and
auto-detected features by having both alternatives available.
Looking at the commit message of 652895abdc
this seems to have been the intent from the start, but this specific
definition was missing from the option creation in Features.
In wayland_common, wl->window_size keeps track of the window's size when
it is not in the fullscreen or maximized state. GET_UNFS_WINDOW_SIZE is
meant to report the size except for when it is fullscreen (hence UNFS).
However, the actual function was merely returning the wl->window_size so
it was wrong for maximized windows. Workaround this by returning
wl->geometry instead when we have the maximized case. Fixes#9207.
Its define (HAVE_FFMPEG_STRICT_ABI) is now utilized in a single
location, where an internal libavformat struct member is utilized.
This struct member is now (after around 10 years) finally removed
from public visibility in FFmpeg's master.
After a review of functionality, the information in bytes_read is
passed onto the demuxer layer, and then utilized for
{cache,hack}_unbuffered_read_bytes. This information is then utilized
for:
1. Calculation of bytes_per_second in demux/demux.c::update_cache,
which fills the information for properties "cache-speed" as well as
"raw-input-rate" (of which stats.lua is the most prominent user).
2. bytes_per_second also affects how often update_cache is called in
addition to the two locations it is called unconditionally in
(read_packet, demux_update).
In other words, the information provided does not appear to control
crucial mpv functionality, but rather its lack would seem to mostly
affect the speed of certain properties updating, or having valid
values. For the former, stream size as well as timed metadata get
updated in update_cache - although the demux layer does throttle
the update of certain things to once per second in that function.
For the latter, "cache-speed" and "raw-input-rate" lose read data
statistics from AVIOContexts opened by the opened FFmpeg AVFormatContext
itself, as opposed to the primary one - which goes through mpv's
stream reading implementation.
By enabling this feature, and disabling this abuse of private API
lets users build mpv by default with the latest master FFmpeg, thus
giving us the breathing room to look into some of the details of
this case, and either decide to:
1. Post a patch to add this information back to FFmpeg proper.
2. Remove or replace this functionality in another manner.
End user impact:
Any IO not handled by mpv itself - but rather by IO contexts newly
opened by the input format - is not visible through the properties
"cache-speed" and "raw-input-rate". Examples of such input formats
are the HLS and DASH readers in FFmpeg.
Historical git references:
- Addition of unbuffered_read_bytes: 4dfaa37384
- Rework to have the reporting function: ebf183eeecFixes#9159
Last time it was extended was de3ecc60 from 8K to 512K two years ago.
The issue currently is that youtube EDL files can get very big.
Size of about 520K (one line), was observed, at the time of writing:
mpv https://youtube.com/watch?v=DBzFQgSMHdQ --ytdl-format=299
ytdl_hook.lua is unaffected by this because EDL lists don't go through
the file reader at demux_playlist.c (where each line was limited to
512K before this commit), however, EDL files on disk which are
loaded with --playlist=file.edl do.
Increase the limit to 2M so that such EDL files can also be loaded
from disk.
Fixes#9186
Previously, the initial positioning and fit ignored the borders, and
centered the content (the video itself) at the working area.
Now, the initial positioning centers the window, by subtracting the
borders (if needed) from the target area for the initial fit/position.
While this does mean that the initial maximum content area is now
smaller than before, ultimately this has no impact on the window size,
because fit_on_screen is called later and, if needed, further shrinks
the window to fit the borders too - but without centering the window.
So the net impact of this commit is only the initial positioning (same
size as before), which now centers the window instead of the content.
Note that on Windows 10 the borders include invisible areas at the
sides and bottom of the window (for mouse edge-drag), so visibly the
window is nearer to the top than to the bottom, but these are the
metrics we have (fit_on_screen uses the same border size values).
On Windows 7 it looks perfectly centered.
The --monitoraspect value is calculated at vo_calc_window_geometry2
(VCWG2) or VCWG3, and applied via vo_apply_window_geometry.
Before this commit, the screen size which the win32 VO used with
VCWG2 was the working area (screen minus taskbar). This allows better
fitting, but breaks the pixelaspect calculation which is derived from
the --monitoraspect value and this rectangle.
VCWG3 allows an independent size for the aspect calculations, and now
we use it independently of the fit size.
vo_calc_window_geometry2 (VCWG2) calculates both the pixelaspect and
the autofit sizes based on one "screen" rectangle.
However, these two calculations might need two different "screen"
rects if the fit should take into account decorations and/or taskbar
etc, while pixelaspect should be based on the full (monitor) rect.
VCWG3 does just that. It's the same as VCWG2, but with an additional
monitor rect which is used exclussively to calculate pixelaspect,
while the "screen" argument is used for fitting (like before).
VCWG2 now uses/calls VCWG3 with the same screen and monitor rects.
Currently yet unused.
If bash_completion wasn't installed, _filedir wouldn't be defined which
led to all filename-based completions to error out. Specifically
autocompletion would fail when a filename was expected and when
bash_completion wasn't installed. Now we fall back to `compgen -f` if
_filedir fails. According to _filedir's comments, compgen doesn't
handle files with spaces well, but it is still better to complete most
files than none.
If an unknown ESC sequence is detected where an ASCII char <X> follows
the ESC, mpv interprets it as ALT+<X>, which is the traditional
terminal encoding of ALT+letter.
However, if <X> is '[' then it's a CSI sequence which continues after
the '[', and has its own termination rules (can be many chars).
Previously, mpv interpreted unknown CSI sequences as (incorrect) ALT+[
followed by (incorrect) "keys" from the rest of the sequence.
In this commit, if a unknown CSI sequence is detected, mpv ignores
exactly the complete sequence.
The "cycle" command _declaration_ enables repeatability by default,
however, the command handler applies additional logic to augment it,
based on the property which is being cycled - using some guesswork.
Specifically, properties with discrete values are not repeatable
(like sub or osd-level), while continuous properties are repeatable
(like volume).
Previously, the "repeatable" prefix could not override this additional
logic.
This commit changes the behavior so that the logic affects only the
default repeatability (still based on the property like before),
however, the "repeatable" prefix is now allowed to override it.
This is an artificial background box with the original colors,
rendered as a plain rectangle instead of libass's opaque-box.
Fixes#9134 (together with the previous commit)
This breaks the rendering in various ways, so first workaround is to
simply disable the opaque box for the bar.
Next commit will add an artificial background box.
This read-only property reflects the VO's dpi-scale value, and wasn't
supported on win32 until now (it is supported on wayland/x11/osx).
Currently in mpv it's only used by the builtin script console.lua,
and assumed 1 if unavailable.
When --window-scale=NUM is set from CLI, the dpi_scale value was/is
taken into account when the win32 VO calls vo_calc_window_geometry2.
However, when [current]-window-scale is read or set at runtime, it uses
the VOCTRL_{GET,SET}_UNFS_WINDOW_SIZE interface, where other VOs apply
the dpi_scale value internally (wayland, x11, osx), but the win32 VO
didn't before this commit.
Fixes two issues when --hidpi-window-scale=yes and dpi_scale != 1 :
- Incorrect window-size when setting [current-]window-scale at runtime.
- Incorrect current-window-scale value when reading it.
vo_calc_window_geometry2(...) is called to initialize the window
size with the dpi_scale value as one of the arguments.
dpi_scale is 0 initially, and set to a valid value at update_dpi(),
which is called from [force_]update_display_info().
However, no measures were taken to ensure that dpi_scale is set
correctly before vo_calc_window_geometry2() is called, which could
result in incorrect window size if it's not initialized.
It did happen to get initialized on time, by luck, because
VOCTRL_GET_DISPLAY_FPS is used early, which happens to call
update_display_info to read the fps value (other update_display_info()
calls are after the first vo_calc_window_geometry2() call).
This commit ensures that dpi_scale is initialized on time if needed.
Also, update_dpi() now ensures that dpi_scale is never 0.
Previously, a list of commands was always considered repeatable.
This behavior was added at 6710527a (and moved around since then),
in order to fix#807 (impossible to make a repeatable list).
The problem was that a list doesn't have the normal repeatability
flags and so it was never repeatable, so it was hardcoded to be
repeatable instead. Presumably it was deemed good enough.
However, this made it impossible to have a non-repeatable list.
This commit changes the behavior so that a list repeatability is
that of the first command at the list.
This way, any list can be made either repeatable or non-repeatable
using the following idiom (e.g. at input.conf), based on the fact
that the "ignore" command is not repeatable by default:
x ignore; cmd1...; cmd2... # non-repeatable
y repeatable ignore; cmd1...; cmd2... # repeatable
Fixes#7841
Discovered with:
find . -type f \( -name '*.md' -o -name '*.rst' \) -exec grep -n 'http://' {} +
All real, i.e. non-example, links found were moved to https. There are
some dead links and websites with no https available which were not
converted.
Discovered with:
find . -type f \( -name '*.md' -o -name '*.rst' \) -exec grep -n 'http://' {} +
All links to mpv.io or github.com/mpv-player that were http were
converted to https.
This is a regression from cbbd81bb (the previous commit):
print_seq1 (which prints a sequence with 1 parametric byte value) is
used with 256 colors output, and apparently was never tested.
Two issues were introduced at the offending commit:
1. The ";5" part was incorrectly removed from the strings
ESC_COLOR256_{BG,FG} (affects both *nix and Windows).
2. On windows only - a semicolon was not used after the prefix.
Both issues resulted in an invalid 256 colors sequences and output.
- Replace the legacy --osd-status-msg with the newer --osd-msg3.
- Escape \b in show-text "This is ${osd-ass-cc/0}{\b1}bold text".
- Link the Flat command syntax section because it's no longer true that
you always need to escape \, since C escape sequences are not
interpreted with single and custom quotes.
On windows the UTF-8 strings are translated to wchar_t when printed to
the console, and some escape sequences are also translated, however,
this only works when printf is mapped to mp_printf, and for that to
happen we need to include osdep/io.h .
Normally in wayland, you receive a keymap event from the compositor
which is what allows the client to setup what is needed for xkb.
However, it turns out that this doesn't occur in the case of virtual
keyboards, such as from wtype, that come from the custom
virtual-keyboard protocol. What happens in this case is that mpv only
receives a keyboard entrance event. According to the wayland protocol
documentation [1], "the compositor must send wl_keyboard.modifiers event
after [the wl_keyboard.enter] event". It is possible for this to occur
before the physical keyboard is properly mapped (i.e: using a virtual
keyboard to start mpv). What this results in is a segfault once
xkb_state_update_mask is called in the modifiers event. The fix is to
simply not always assume we have created the xkb state if we get this
event and check for its existence first. Closes#9119.
https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_keyboard
When changing video track with subtitles with unknown duration, they
aren't shown until you seek, cycle sub back and forth, or apply a video
filter. This is caused by reinit_video_chain_src() calling
reset_subtitle_state() -> sub/sd_ass.c:reset() -> ass_flush_events()
when ctx->duration_unknown is true.
The ass_flush_events() call was added in a714f8e so subs with unknown
duration wouldn't multiply on seek, i.e. when reset_subtitle_state() is
called from reset_playback_state(). So keep calling it from there, and
in reinit_video_chain_src() use just term_osd_set_subs(mpctx, NULL)
instead to clear any subtitles printed to the terminal. The
reset_subtitle_state() call was added in c1ac97b to "reset the state
correctly when switching between video/no-video", but with it removed I
no longer notice any issue doing that.
Previous fullscreen handling code was removed in 59cdfe50b2 during
deprecation of VOCTRL_FULLSCREEN. Lack of this code caused the OSD layer
to be to be not resized along with the video layer when fullscreen is
toggled.
If a user attempted to change the window scale of a maximized window on
x11, nothing would happen since the window manager holds the size of the
window constant. Just do an unmaximize first before performing the
resize.
When the VT switch out is triggered, the decode thread (VD) falls back
to sw decoding. However, on the VO thread, which is responsible for
handling display preemption and presentation, vo_vdpau.c:reconfig() is
called. The reconfig() function returned -1 when the check_preemption()
returned 0. The vo_reconfig2() (which calls reconfig()) returned -1 in
turn which entered into an error handling path. This led to a series of
functions calls that ultimately set the in_terminate flag to TRUE.
This led the vo_thread to exit which ultimately led to the
MPV application exit.
The fix is to return 0 instead of -1 after the check_preemption() in
the vo_vpdau.c:reconfig(). Returning 0 instead of -1 is not fatal and
does not have any side effects. This is confirmed by testing the VT
switching behaviour. And as far as the frames that are going to the
display are concerned, they are now dropped. Since the display is
preempted, it is okay to drop the frames and continue.
Without this entry, when starting mpv as a flatpak application on
elementaryOS, the Dock icon would get duplicated, as if the application
was detached from its launcher. This entry fixes that by allowing the
dock to associate the app's window with the desktop entry.
Fixes#9109
29e15e6248 prefixed youtube-dl's subs url with an edl prefix to not
download them until they're selected, which is useful when there are
many sub languages. But this prefix broke the alignment of secondary
subs, which would overlap the primary subs instead of always being
placed at the top. This can be tested with
--sub-file='edl://!no_clip;!delay_open,media_type=sub;secondary_sub.srt'
When a sub is added, sub.c:reinit_sub() is called. This calls in
init_subdec() -> dec_sub.c:sub_create() -> init_decoder() ->
sd_ass:init(). Then reinit_sub() calls
sub_control(track->d_sub, SD_CTRL_SET_TOP, &(bool){!!order}) which sets
sd_ass_priv.on_top = true for secondary subs.
But for EDL subs the real sub is initialized again when in
dec_sub.c:sub_read_packets() is_new_segment() returns true and
update_segment() is called, or when sub_get_bitmaps() calls
update_segment(). update_segment() then calls init_decoder(), which
calls sd_ass:init(), so sd_ass_priv is reinitialized, and its on_top
property is left false. This commit sets it to true again.
For URLs that need to be downloaded it seems that the update_segment()
call that reinitializes sd_ass_priv is always the one in
sub_read_packets(), but with local subs sub_get_bitmaps() is usually
called earlier (though there shouldn't be a reason to use the EDL URL
for local subs), so I added the order parameter to sub_create(), rather
than adding it to all of update_segment(), sub_read_packets() and
sub_get_bitmaps().
Also removes the cast to bool in the other sub_control call, since
sub/sd_ass.c:control already casts arg to bool when cmd is
SD_CTRL_SET_TOP.
Right after the listener is constructed, request a mode based on the
value of the border option. If border, then request SSD. If no border,
request CSD. The decoration listener handles it from there.
The previous wording gave the false impression that there was no media
key support for OSes besides Windows and macOS. This is untrue, the
option may only exist on those two platforms but it simply means that
media keys will always be enabled on other OSes as long as they are
supported.
The current usage of the xdg-decoration protocol is quite a bit crude.
There's a specific listener struct for this like with most wayland
things, but mpv wasn't even using it. It also made no attempt to detect
if the compositor was telling mpv to use client side decorations. To
implement this correctly, first of all we need to create the decoration
listener object and add it like how most wayland things work. Secondly,
set_border_decorations needs to be changed to accept the uint32_t mode
given by the compositor. When we get the decoration event, pass the mode
obtained from the compositor to set_border_decorations. Update the mpv
border option, based on whether or not we have server side decorations
(yes if we have them; no if we don't). mpv can actually request either
client side or server side decorations with this protocol. This function
doesn't belong in set_border_decorations but rather it should be called
when the border option changes. Whether or not this request actually
works depends on the compositor (Plasma appears to allow it; sway does
not). If the compositor allows this request, then it gets handled by
configure_decorations. Note that the enum strangely starts at 1 hence
why there is an extra +1.
When performing the scaling calculations, the window scale properties do
not bother checking for potential monitor par. The vo keeps track of
this via vo->monitor_par. Simply multiply/divide the video's width or
height depending on the value of monitor_par. We also clamp the values
to avoid the values running away to infinity in extreme cases.
The vo currently handles rotations in 90 degree steps and some VOs set
this via VO_CAP_ROTATE90. When the rotation exactly hits either 90 or
270 degrees, this causes the values of dwidth and dheight to perfectly
swap like one would expect. However, the mp_image_params_get_dsize
function call in both of the window scale functions do not take this
special case into account. So the width/height values returned will be
incorrectly flipped in the 90 and 270 degree cases if the vo driver does
implement VO_CAP_ROTATE90 (like vo=gpu). Fortunately, the
mp_image_params struct keeps track of the rotation for us. So all we
need to do is check if the image is rotated at 90 or 270 degrees and
check that the current vo driver supports VO_CAP_ROTATE90. If so, then
swap vid_w and vid_h to their true, correct values.
Based on a small patch originally written by @avih. Instead of
duplicating the window-scale logic in update_window_scale, just call the
mp_property_current_window_scale function with the M_PROPERTY_SET action
and a NULL property.
So the resizing mechanism is actually supposed to match the video size
to the window size while preserving the aspect ratio. In wayland, the
current logic behaves as if --no-keepaspect-window was set. Fix this by
simply multiplying the height by the same scale factor the width is
multiplied by. Also get rid of the pointless (width > height) test (it
makes no difference in any case) as well as some unneccesary checks for
the keepaspect-window option. The use of ceil here is to make sure the
window coordinates can never possibly have be 0 due to truncation
(weston can still give you a 1x1 window which is fun). Fixes#9098.
There's currently some touch related code in mpv wayland, but clearly
nobody actually uses because it's a broken mess. Initially an attempt to
distinguish between two finger touches and one finger touch was made,
but there's not a good way to make this work. For whatever reason,
initiating either xdg_toplevel_resize or xdg_toplevel_move blocks any
other touch events from occurring (at least in plasma). Trying to call
these functions anywhere else is not really useful since the serial will
be invalid outside of the touch down events (well it would work in the
touch up event but that's just silly).
Anyways, let's just make this work sanely. Eliminate the touch entries
variable completely because it's pointless. Only one finger event is
ever considered at a time. Touches besides the initial one are all
ignored. If a user touches and drags within the touch edge radius, then
a resize event occurs. If the user touches and drags elsewhere on the
window, a move event occurs. A single tap displays the osc (which is
clickable if you tap again). A double tap toggles fullscreen.
Additionally, the default touch edge radius of 64 pixels is way too big
(at least I think so). Cut this in half to 32 which feels a lot better
(on a pinephone using plasma mobile anyway).
The way the window-scale option is supposed to behave wasn't really ever
documented until 25cfc81. It turns out that different OS/WMs may do
slightly different things. For wayland, we need to fix two things.
First, only return the wl->window_size in GET_UNFS (aka don't return the
fullscreen size). For SET_UNFS, we need to change the behavior for the
maximized window case. If the window is maximized, first attempt to
unmaximize it and send the wayland event. If the compositor allows this
to happen, then go ahead and set the new dimensions and resize it. In
the case that the attempt to unmaximize is not successful, then don't
attempt the resize and just save the window size dimensions for later to
be used when the user unmaximizes the window.
The window-scale property mirrors the respective option (not the
effective scale derived from the current window size), and as such
setting its value to the same value it had before has no effect.
Specifically - the window will not resize.
This is consistent as far as property-option bridge behavior goes,
but we do end up with an issue that we can't set an arbitrary scale
and expect the window to always resize accordingly.
We do also have a current-window-scale property which does reflect
the actual window size, however, it's been read-only till now.
This commit makes current-window-scale RW so that it's now always
possible to set an arbitrary scale and expect the window to resize
accordingly (without affecting window-scale - like manual resize).
Also, mention window-scale no-effect-if-not-changed at the docs.
Based on code by @Dudemanguy from commit 873ae0d, with same effect.
This reverts commit 873ae0de2a.
The next commit will restore this functionality, with the
following differences from the reverted commit:
- Smaller and simpler code change.
- On bad scale: use "Invalid value" (compared to "no such property").
- Doesn't combine the docs for window-scale and current-window-scale.
- Doesn't remove the docs for window-scale behavior prior to 0.31.0.
Regression from 24357cb. It's ugly but unfortunately keeping tracking of
the last toplevel width and height really is the best way to solve this
problem and removing it was a mistake. Compositors don't always send
width/height coordinates of the actual window. The easiest way to
trigger this is by changing window-scale/current-window-scale and then
unfocusing the window. The compositor will send another toplevel
configure event with coordinates of the window before the resize. Maybe
compositors could be smarter but multiple ones do this (sway, gnome,
plasma), so just keep the old workaround. The only difference this time
is that the toplevel width/height is saved at the very beginning which
also covers the case where it equals 0 (i.e. weston).
Somewhat confusingly, mpv has both a window-scale option and a
current-window-scale property. The documentation lists window-scale
under properties (and it is technically is one), but at its core it is
actually an option which means it behaves subtly different. Options in
mpv are runtime-configurable, but they only change anything if the value
of the option itself changes. window-scale is an option and not meant to
keep track of the actual scale of the window (intended behavior
introduced by d07b7f0). This causes window-scale to do nothing in
certain cases (ex: the window is manually resized and window-scale is
set to 1.00 again). This is logical and consistent with the behavior of
the rest of the mpv options, but it also makes it a poor candidate for
setting the mpv window scale dynamically.
As a remedy, we can just make current-window-scale writeable instead.
current-window-scale is intended to always report the actual scale of
the window and keep track of any window size changes made by the user.
By making this property also writeable, it allows the user to have more
intuitive behavior (i.e. setting current-window-scale to 1.00 always
sets the window to a scale of 1). Additionally, the default input.conf
is changed to use current-window-scale instead of window-scale. The
window-scale documentation under property list is removed since it is
already documented under options and users should probably set the
current-window-scale property instead in most cases.
Using --sub-filter-regex-plain (default:no)
The ass-to-plaintext functionality already existed at sd_ass.c, but
it's internal and uses a private buffer type, so a trivial utility
wrapper was added with standard char*/bstr interface.
The plaintext can be multi-line, and the multi-line regexp flag is now
always set, but only affects plaintext (the ASS source is one line).
Pretty much identical to filter-regex but with JS expressions and
requires only JS support. Shares the filter-regex-* control options.
The target audience is Windows users - where filter-regex doesn't
work due to missing APIs, but mujs builds cleanly on Windows, and JS
is usually enabled in 3rd party Windows mpv builds.
Lua could have been used with similar effort, however, the JS regex
syntax is more extensive and also much more similar to POSIX.
1. On a pathological case where event_format is NULL, previously the
filter was trying to use it with each new sub - and re-failed. Now
the filter gets disabled on init (event_format doesn't change).
2. Previously, if the filter didn't modify the text or if the text
could not be extracted - it still allocated a new packet with same
content. Now it returns the original, saving a whole lot of no-ops
(there are still few allocations in this case though).
1 above is preparation for the next commit, and 2 was trivial, but
there's more to do if anyone cares (NIH string functions instead of
bstr, unused arguments, messages could be improved, and more).
Add two stand-alone function to help with the text-extraction task
which ass filters need. Makes it easier to add new filters without
cargo-culting this functionality.
Currently, on malformed event (which shouldn't happen), a warning is
printed when a filter tries to extract the text, so if few filters
are enabled, we'll get multiple warnings (like before) - not critical.
The regex filter now uses these utils, the SDH filter not yet.
The source of many geometry woes. There's some loosely related toplevel
things that should be cleaned up/fixed. First of all,
VO_EVENT_LIVE_RESIZING is actually completely useless. It might have
been useful sometime in the past, but there's no point. It doesn't
"speed up" resizing in any way and appears to be originally for cocoa.
Just remove it.
Way back in the day, toplevel_width/height was added as a workaround for
when we got uncoorperative (i.e. wrong) width/height coordinates from
the compositor in this event. Basically it could happen due to numerous
reasons but a lack of atomic commits was part of the reason and also
mpv's geometry handling then was a lot rougher. We *shouldn't* need this
workaround anymore. The width/height values are only used exactly when
we need them. If mpv sets geometry on its own, it should still be the
right dimensions.
Related to the above, mpv never actually propertly handled the case
where width or height was equal to 0. According to the xdg-shell spec,
"If the width or height arguments are zero, it means the client should
decided its own window dimension." An example of a compositor doing this
is weston. It's, unsurprisingly, broken. Getting out of fullscreen or a
maximized state does not restore the old window size like it should. The
right way to handle this is to just return near the end of the function
if we have a 0 for either argument and before any geometry is set
(wl->geometry's width or height can never be zero). Luckily, state
changes are already being detected so they just trigger the goto when
needed.
Finally, e2c24ad mistakenly removed the VO_EVENT_EXPOSE. There are edge
cases where this is needed and it's safer to just force a redraw here
when the window gets activated again. Just force wl->hidden to false
first and then trigger the expose.
Since 1d1d1fbff9 option-info/<name>/set-locally was being set to true
for every option. This broke setting start from ytdl-hook, which doesn't
overwrite start if it was set-locally. Fix this so that only adding an
option to reset-on-next-file or setting file-local-options/<name> make
set-locally true like before.
However, it's arguable that just adding an option to
reset-on-next-file without ever changing it should not make set-locally
true, so that e.g.
--reset-on-next-file=start 'https://youtube.com/watch?v=...&t=30'
will start at 30, though it currently doesn't.
Fixes#9081.
Previously we assumed the key-name string occupies strlen(name) cells,
now we count codepoints instead.
This improves alignment of non-english key names. Still not perfect
because we don't know if the key name is single or double width, but
wcwidth not available to scripts, notoriously unreliable (depends on
locale, correct and updated tables, etc), and also not always
available (Windows).
Still, better than nothing, and we err by at most one cell - vs up to
three before this commit (4 bytes keyname codepoint).
In the future we could do the alignment using libass tags, however,
this both complicates the ass-output generation, and also not available
when we output for the terminal, so for now only count codepoints.
Also, if the key name was in a right-to-left language, then previously
the name/command were swapped visually. Now we inject a left-to-right
marker before the name to ensure direction. This works also when
harfbuzz is disabled for libass (--sub-ass-shaper=simple).
Users expect single quotes to work when the value includes literal
backslashes or double-quotes (or as general quoting like in shell).
The updated docs also include some previously-missing notes:
- newline is only supported in double quotes.
- adjacent (quoted) arguments don't join into one.
Supporting mixed quoting (adjacent quoted strings) would make
mpv's parsing more complete, but would require delicate effort of
larger scope, for two reasons:
- We'd need to also support escaping outside of quotes and do our
best about backward compatibility.
- The parsed value can either be a substring of the input or
a newly-allocated string, which would be delicate when joining.
Not critical to add right now.
Custom quotes were added in 4f129a3e and began with !, however, this
required quoting "!reverse" (used for the cycle-values command), which
is inconvenient, and was not taken into account when ! was chosen for
custom quotes. Also, ` is more natural for quoting than !.
This does break backward compatibility with the earlier form of custom
quotes, but at least we didn't make a release yet since custom quotes
were added (the last release - 0.33[.1] doesn't support it).
Let audio-display determine whether embedded images or external cover
art tracks should be selected when both are present.
Attached pictures are given priority by default as requested in #8539.
Also updates references to attached pictures in the log and manpage to
refer to cover art as well.
Closes#8539.
This fix the warnings shown below when compiling the manual for
any of its three common formats:
```
DOCS/man/mpv.rst:46: (ERROR/3) Unknown target name: "--input-test".
DOCS/man/stats.rst:183: (ERROR/3) Unknown target name: "--input-test".
```
In rst, double-backtick starts a code string only if it's followed by
a non-space char, otherwise it's taken literally, hence, `` x2.0``
was taken literally rather than code string.
Because having these on every video is annoying, and when you resume
from watch later files, the filters are applied immediately so they hide
your osd-playing-msg or equivalent show-text commands.
More wayland weirdness. So previously, flipping a hidden state from true
to false was done in vo_wayland_wait_frame. In theory, this would be
after you get the frame callback and all those events so there's no
problem. However since the function also does a bunch of
flushing/dispatching/etc. to the default display queue so a lot of
unknown things can happen before we actually set the hidden variable
back to false. For example if a single image was paused and left on
another virtual desktop long enough (~5 minutes) while also not having
focus, switching back to that desktop could render it a black frame.
This edge case was supposed to be handled by the surface being activated
again in the toplevel event but apparently that doesn't always work. The
fix is to just delete all of that junk and set wl->hidden = false in the
frame callback. What's actually happening is kind of a mystery honestly.
Probably the compositor drops the buffers after a while as an
optimization (sensible) and forces a repaint if you switch back to the
virtual desktop. Somehow wl->hidden not being set to false would not
properly trigger a repaint (likely because it also sends a toplevel
event which does stuff) thus you just get a black window. If you just
make sure to set hidden in the frame callback, it appears like all of
these problems and edge cases are solved. Since this event must happen
first, that makes sense. That simplifies a lot of stuff and fixes some
subtle bugs at the same time so just go with this approach.
The EGL stuff is really complicated because of historical reasons
(tl;dr: blame EGL). There was one edge case with EGL context creation
that lead to incorrect behavior. EGL_KHR_create_context was created with
EGL 1.4 (which mpv does support) but it is still possible for an EGL 1.4
device to not implement this extension. That means that none of the EGL
attrs that pass a specific opengl version work. So for this obscure
case, there is a fallback context creation at the very end which simply
creates an EGLContext without passing any special attrs.
This has another problem however. mpv has a hard requirement on at least
desktop opengl 2.1 or opengl ES 2.0 to function (we're not asking for
much here). Since the fallback EGL context creation has no version
checking, it is entirely possible to create an EGL context with a
desktop opengl version under 2.1. As you get further along in the code,
the user will encounter the hard opengl version check and then error
out. However, we're supposed to also actually check if GLES works
(that's what the opengl-es=auto option is for) so this is a bug.
The fix is to do a bit of code duplication and make a mpgl_check_version
specifically for if we hit the edge case of needing to create an EGL
context without the EGL_KHR_create_context extension. Grab the version
with the function pointer, check if it's under 210, if so destroy the
EGL context and set it to NULL. After that, if the user has set
opengl-es to auto, mpv will try GLES next. If it is set to no, then mpv
will simply fail as desired. Fixes#5915.
Sidenote: the ra_gl_ctx_test_version originally testing 140 doesn't make
any sense. Passing the version number in that function only does
something if the user has set opengl-restrict. What we need to do is to
pass the version of the created context to that function. If the version
is higher than the opengl-restrict option, then make this a failure.
When changing image-display-duration at runtime, make the new value take
effect immediately, rather than from the next playlist-position change.
This allows toggling the slideshow mode while viewing images (without
hacks like executing playlist-play-index current afterwards).
All the conditions are just to be safe since even if you set time_frame
while playing a video, it's immediately overwritten by the next value.
mpv has two methods to display output from text input:
- show-text (scripting: mp.osd_message) has ass disabled by default
(escaped), and the property osd-ass-cc can control escaping.
- osd-overlay (scripting: mp.set_osd_ass or mp.create_osd_overlay)
has ass enabled (unescaped), and osd-ass-cc is NOT supported.
By default, stats.lua uses mp.osd_message which does support escaping.
That's persistent_overlay=no.
When using persistent_overlay=yes then mp.set_osd_ass is used.
Due to this, the no_ASS(..) function - which is supposed to escape
ass, simply returned its input unmodified when persistent_overlay
is enabled.
This is not a new issue, and the filters on page 1 use no_ASS() to no
avail in persistent mode, however, this content (filter name and value
strings) rarely actually needs escaping, and users didn't notice.
However, the new page 4 (keys) does break visibly when no_ASS doesn't
work, because it tries to escape arbitrary key-names and command
strings, and at the very least the key '{' is bound by default, which
is displayed incorrectly if escaping doesn't work.
Fix this by rolling our own escaping when using mp.set_osd_ass,
similar to how the mpv code does it for mp.osd_message (substrings
replacements).
However, this means that the set_ASS(..) function can no longer
behave correctly because escaping requires going through the whole
content string rather than only inserting a marker.
Luckily, other than at no_ASS, set_ASS was only used at one place
(text_style), which is only called from two places:
- generate_graph() only needs to restore styles - not to enable ass.
- add_header() is only used at the begining of page output, and
uses set_ASS to enable ass initially when using mp.osd_message.
So remove the set_ASS function, and instead enable ass directly at
print_page using osd-ass-cc when mp.osd_message is used.
Fixes#9022
This was explictly coded to avoid the autoprobe way back when in
2015[1] with no real explanation. In theory, there shouldn't be any
issues allowing this. If a user runs mpv in tty, this is probably what
they actually want in most cases. Perhaps something strange happens on
nvidia, but it should just fail anyway during the autoprobe.
[1]: https://github.com/mpv-player/mpv/commit/f757163058c2e5c7136213b0f79923fcea34b71a
As it turns out, js_try can throw if it runs out of try-stack
(without/before entering either the try part or the catch part).
If it happens, then C code which does allocation -> try will leak.
In mpv there were two places which do alloc and then try, one of
them as part of the autofree system. On both cases the leak is the
smallest possible (zero allocation) - talloc_new(NULL);
It's very unlikely to trigger - an autofree mpv API should be called
when the try-stack is exactly full, and our next try will throw
(and guaranteed to get caught at an outer level, but with a leak).
Fix that by doing the allocation inside the try block, so that if
try throws before it's entered then nothing got allocated/leaked.
Mujs internal code also has/had similar leaks, which are getting
fixed around this time (July 2021, post mujs 1.1.3).
[1] exhaust the try-stack or call-stack, whichever comes first:
function kaboom() { try { kaboom() } catch(e) {} }
--watch-later-options-remove doesn't accept multiple options, so split
the example.
Also suggest the more correct -clr to empty the list, and remove the
workaround to not print an error with --watch-later-options=
Previously, if a script bound the same key more than once to different
functions (without removing the older bindings first), then pressing
the key triggered any of the bound functions arbitrarily[1].
Now the newest binding for the same key is always the active one.
If the newest binding is then removed - the second-newest will become
active, etc. (same mechanism as before, except that the active key
was not always the newest).
[1] The order was implementation-defined, however `for (name in obj)'
happens to iterate. With mujs that's currently alhabetic order,
and name is from mp.add_[forced_]key_binding(key, name...)
or generated internally if name is not provided. So a binding with
higher alphabetic `name' value had priority over lower name value.
This allows configuring which options are saved by quit-watch-later.
Fixes#4126, #4641 and #5567.
Toggling a video or audio filter twice would treat the option as changed
because the backup value is NULL, and the current value of vf/af is a
list with one empty item, so obj_settings_list_equal had to be changed.
Unlike the page switching/scrolling keys which are bound at runtime
and therefore we need to know which (configured) keys to bind, the
main keys (i/I by default) are static and can be bound via input.conf.
And indeed, the builtin bindings at etc/input.conf have them already.
- The video filter to turn the video upside-down is vflip. There is no
filter called "flip" so using it just causes an error.
- Reword a sentence.
- Add exact and all to the values accepted by cover-art-auto. They were
implemented in 029ff1049b but not added to the accepted arguments.
Page 4 bindings listing wants to exclude the interactive keys of the
stats script itself - so that they don't hide the normal keys which
are bound when stats is not interactive.
It did so by testing that the bound command includes stats/__key
which is how it usually looks when a script binds keys.
However, if a script uses a name for the binding - like stats.lua does
for the interative keys (because it later removes them by name when
interactive mode ends), then the command has stats/name rather than
stats/__key...
To fix this, we change the names of the forced interactive bindings
to start with __forced_, and that's now also what the page-4 listing
excludes.
This reverts commit 0f1654811bda0dfdd337734ec33c59b67522234a.
It was an incorrect fix, because the key names do get used - to remove
the forced bindings once stats exits the interactive mode.
And without names - the interactive keys remained active even after
stats exited interactive mode.
The page 4 keybinding list tries to skip the interactive bindings of
stats itself (because they would hide the normal bindings of these
keys when stats is not visible), and to do that it excludes commands
containing "script-binding stats/__key" - which is how script-added
bindings usually look like.
However, keys which are added with a "name" bind stats/name rather
than stats/__key... - and that's what stats.lua did till now with its
interactive force-bindings.
Now the interactive forced bindings are added without a name, and so
they do end up using the automatic stats/__key... and get excluded.
While --input-test is useful, and so is page 4 of stats, until now
there was no way to simply print the list in a help-like fashion.
This commit adds such printout, invoked by the script opt
stats-bindlist=yes, which uses the existing page 4 code. This prints
the list on startup and quits immediately - like any help page.
It's awkward to invoke compared to other help pages, and it does
require the stats page to be enabled (it is by default), however
it is a script-generated output, and currently there's no other
method to print a help page generated by a script.
The printout itself is performed using lua's io.write. While reliable,
it's not the standard way for mpv to print to the terminal.
Other possible printout methods are mp.msg.info - which also prints
"[stats]" prefix on each line (ugly), or forcing term-osd and setting
an osd-message which mpv will then print at the terminal - however
that's printed to stderr, and could also be subject to timing concerns
since we quit right afterwards.
In the future we can consider changing/integrating the invocation so
that mpv itself could print a help page generated by a script, thus
solving both the awkward invocation and printout-method issues.
This is a scrollable page which also works nicely with the terminal
OSD. Typically there are more than 100 bound keys.
It groups the binding using fuzzy property/command/script name after
simple analysis of the command string, and then further sorts the
binding in each group according to the "complexity" of the key itself
(plain keys -> keys with modifiers, alphabetically, etc).
The alignment/grouping style is heavily inspired by @medhefgo's #8924
but otherwise it's an independent implementation.
Typically the current page is rebuilt and rendered once per second,
howeve, scrolling can invoke the rebuild function very frequently,
even at a rate which is too fast for the rebuild function to keep
up. This can result in high CPU usage and input lag.
This commit adds an argument to the page-rebuild function, letting it
know whether or not it's called following a scroll keypress, thus
allowing it to cache intermediate data so that it doesn't have to
re-calculate the whole page from scratch.
This additional argument is unused currently, but it could be useful
for the internal performance page - which can be relatively heavy.
When playing a new file, if paused_for_cache was true before being reset
the AO would never be unpaused because that state was thrown away, leaving it stuck.
Fix this by updating the pause state before resetting that variable. Note that this
does not make the second update_internal_pause_state() call redundant.
This fixes the same bug fb5d976cb0 was supposed to.
The previous code tried to disable autocrop for cover-art by testing
that track-list/$vid/albumart is false, however, $vid is completely
unrelated to the track-list index.
It only sometimes succeeded to disable for albumart, by accident,
e.g. with one audio track and one video track where $vid==1 and
track-list/1 happens to be the video (cover art) track.
The new code detects the currently-used video track by finding a track
with type=="video" and selected==true. Unlike the previous code, it
also works in scenarios with many audio/video/sub tracks.
Additionally, autocrop is now enabled also with lavfi-complex, which
should be considered an improvement. The previous code implicitly
disabled it with lavfi-complex because $vid is nil on such case.
in->byte_level_seeks field is written and modified inside
update_bytes_read at the same time when demux_get_reader_state
is executing, which locks the demux thread mutex. This results
in a data race, reported by Thread Sanitizer when playing mp3 file
of sufficient long length.
reinit_audio_filters_and_output function will free mpctx->ao_chain
when there is a failure during audio initialization. So modify it
to return -1 in case of init failure. The return value is checked
to avoid use after free. Reported by Address Sanitizer when manually
specifying --ao which triggers "Failed to initialize audio driver" error.
When using "stty susp ''" to disable sending the TSTP signal with ^Z,
mpv didn't recognize ^Z correctly in the terminal:
[input] No key binding found for key 'Ctrl+2'.
Because ASCII 26 (^Z) and above were incorrectly considered ^<NUMBER>.
This commit moves the cutoff between letters/numbers from 25 to 26 so
that ^Z is now detected correctly as ^<LETTER>.
Additionally, it rephrases the ^<NUMBER> formula for clarity.
The --secondary-sub-visibility options was previously undocumented in
the pull request that added it. This commit adds documentation for it
and clarifies its behavior.
Modifies the sub-seek and sub-step commands with a second <flags>
argument to specify whether to seek/step on the primary or secondary
subtitles. The flag is used to index into the current_track array in
cmd_sub_step_seek.
Adds secondary-sub-start and secondary-sub-end properties by setting
the current_track index in the m_property's priv variable which later
gets accessed in get_times. Also adds a test of the secondary subtitle
time properties in tests/subtimes.js bound to 'T'.
Though, only when the output format is matroska, to avoid muxing errors.
This is quite useful when the input has ASS subtitles, as they tend to
rely on embedded fonts.
I've looked and studied the flow in the recorder, and to my
understanding, the packet queue is moot after the initial sync, maybe
even then - but that's beyond me right now.
With the previous choice to mux trailing packets whatever the case, this
doesn't result in any new ill effects (and some missing packets at the
end is no big deal).
Notably, since we don't have to hold onto the packets after we get
muxing, we'll never run into any issues with veeery long GOPs filling up
our queue (resulting in dropped packets and much user chagrin).
For muxing, FFmpeg expects the FLAC extradata to be just the bare STREAMINFO,
and passing the full FLAC extradata (fLaC header and block size, with any
additional channel layout metadata) will result in malformed output, as
ffmpeg will simply prefix another fLaC header in front.
This can be considered to be a bug.
FFmpeg's own demuxers only store the STREAMINFO, hence the naivety, while
our common source of FLAC streams, the matroska demuxer, holds onto the
full extradata. It has been deemed preferable to adjust the extradata upon
muxing, instead of in the demuxer (ffmpeg's FLAC decoder knows to read
the full fLaC extradata).
This fixes muxing FLAC streams, meaning recorder.c or dump-cache.
dump_cache() calls qsort() to order an array of pointers, while the
comparator forgets it's receiving pointers to pointers.
Since cache-dumping over multiple cache ranges is fairly rare, this
seems to have gone unnoticed.
In commit f7678575a5, wm4 chooses to mux
all remaining packets when mp_recorder_mark_discontinuity() is called and
adds a call to mux_packets(). However, it is called only after flush_packets(),
which clears the packets before they can be muxed out. This has no ill
effects per se - recordings end on keyframes, as before - but judging from
his commit message, the intention explicitly was to output the inter
frames, since long GOPs can mean several seconds of missing content from
the output. So, clear the stream packet queues only after the final mux.
Also, flushing can mean both discarding and committing. What a country!
osc-visibility can already be changed at runtime via script-message
or other means, but until now there was no way to tell what the
current state is.
Now shared-script-properties/osc-visibility reflects this state.
It's output-only by the osc - changing it does not affect the osc.
Useful if a script wants to change osc-visibility temporarily, and
later restore to its original state.
There's no way to coordinate if more than one script wants to change
it, but that would be a hard problem to solve anyway, even if the
osc itself tried to coordinate such requests from different sources.
Another day, another wayland refactor. Way back when, dcc3c2e added
support for the hidpi-window-scale option (something you probably should
never set to no but whatever) to wayland. Well technically, it never had
any runtime toggling support (don't remember if detecting when vo_opts
changed was possible or not then; maybe not). Anyways in the process of
fixing that, I went ahead and refactored how this is all handled. The
key difference is that when hidpi-window-scale is disabled, wl->scaling
is directly set to 1 instead of forcibly setting
wl->current_output->scale to 1. Note that scaling operations don't
always require a geometry reset/resize so set_surface_scaling needs to
be separate from set_geometry. The logic here is kind of complicated but
it (should) be correct.
The wl_surface lives for the entire lifetime of the vo. It's only
neccesary to set the scale initially and when the output scaling changes
(the surface moves to a different output with a different scale or the
output itself changes it scale). All of the calls that were being made
in the egl/vulkan resize functions are not needed. vo_wlshm wasn't
correctly rescaling itself before this commit since it had no logic to
handle scale changes. This should all be shared, common code in the
surface/output listeners.
A subtle regression from c26d833. On sway if mpv was set to be a
floating window in the config, set_buffer_scale would actually get
applied twice according to the wayland log. That meant a 1920x1080
window would appear as a 960x540 window if the scale of the wl_output
was set to 2. This only affected egl on sway (didn't occur on weston and
was too lazy to try anything else; probably they were fine). Since
wl->render is initially false, that meant that the very first run
through the render loop returns false. This probably caused something
weird to happen with the set_buffer_scale calls (the egl window gets
created and everything but mpv doesn't write to it just yet) which makes
the set_buffer_scale call happen an extra time. Since it was always
intended for mpv to initally render, this is worth fixing. Just chnage
wl->render to wl->hidden (again) and flip the bools around. That way,
the initial false value results in render == true and mpv tries to draw
on the first pass. This fixes the weird scaling behavior because
reasons.
Not sure what I was on when I wrote this. wayland-app-id is supposed to
default to "mpv". Just set that in the vo_sub_opts and don't do this
weird m_config_cache_write_opt thing. Also make the doc entry nicer.
Mostly a cosmetic change that (hopefully) makes things look better. Some
functions and structs that were previously being exported in the wayland
header were made static to the wayland_common.c file (these shouldn't be
accessed by anyone else).
When the current file is hidden and `ignore_hidden` is true,
autoload will skip loading other files in the current directory. Make
sure that the current file is always counted for autoloading even if it
is hidden.
In 8a7614a0fb files that start with a '.'
were blacklisted from autoload.lua. Since then
35e8710b86 was introduced and explicitly
whitelisted file extensions. With this change, there is no longer a
reason to blacklist all files starting with '.', because it is valid to
have a file called '.hidden.mkv', and there is no chance of hidden files
such as '.bashrc', '.DS_STORE', '.gitignore', etc. being autoloaded by
mpv.
This commit tries to keep the same behavior as before, which is to by
default not load hidden files, but allows the user to optionally allow
hidden files to be autoloaded.
Commits 4d1ffec and 6e481d0 renamed sub-ass-style-override to
sub-ass-override. But in commit bd603c2, when renaming it in
quit-watch-later's backup_properties, which determines which properties
are saved by quit-watch-later/write-watch-later-config, it was
incorrectly renamed to sub-style-override instead, and thus never got
saved even if modified at runtime. Instead mpv attempted to save the
non-existing property "sub-style-override", but since no error is raised
when saving non-existing properties with quit-watch-later, no one
noticed it. This commit renames the saved property to the correct new
name "sub-ass-override" so that it does get saved.
This fixes two issues, both of which resulted from the timers-wait
period not being re-calculated after idle-observers were executed:
- If timers were added from an idle observer then they could fire long
after they were due (only when/if the next mpv event arrives).
- Idle observers don't execute in zero time, and the wait period for
the next timer was implicitly extended by the idle observers
execution time (because it was calculated before the idle observers).
This commit ensures that if idle-observers were executed, then the
timers wait period is re-calculated, which solves both issues.
Previously, process_timers() kept going as long as there were due
timers, which could be for extended periods of time or even forever
if there were slow timer callbacks with either periodic timers or if
timers were added repeatedly.
This prevented dequeuing mpv events, and subsequently, among others,
prevented mpv from quitting until process_timers() completed.
For instance, this caused process_timers() to never return:
function render() <longer than 1/60 s on a slow system> end
mp.add_periodic_timer(1/60, render)
Similarly, it never returned if a timer callback always added a new
one-shot which was already due by the time the callback completed.
This commit ensures that process_timers() only executes callbacks which
were due when it started, so that timers which are added (or repeated)
during process_timers() will wait for the next iteration - after mpv
events are dequeued.
This has no performance impact under normal conditions (when callbacks
complete before the next timer is due).
Additionally, previously idle-observers were executed unconditionally
after the timers because indeed there was nothing due when (if...)
process_timers() completed. However, now process_timers() can return
even if there are due timers, so skip idle-observers on such case.
This fixes a long-standing apparent issue where mpv would display the last
frame with no subtitles at EOF. This is caused by sub rendering switching from
video timestamps to audio timestamps when the video ends, and audio streams
often running past the timestamp of the last video frame. However, authoring
tools (most notably Aegisub) don't tend to provide easy ways to add meaningful
subtitles after the end of the video, so this is rarely actually useful.
This makes cover-art-auto behave more like sub-auto and audio-file-auto:
- load cover art with a language, e.g. if playing foo.mp3, foo.en.jpg
will be loaded with lang=en
- load cover art containing the media filename with fuzzy and all, e.g.
'foo (large).jpg'
- make all/2 load all images in the directory, and make fuzzy/1 the
default
These are all uncommon use cases, but synchronizing the behavior of the
external file options simplifies the code.
The idle-observers block has at least 3 function calls, and it was
entered every time the script went into idle, however, we can save these
calls by checking first that there are indeed such observers.
Remove the check that the external filename is not the same as the
currently playing one, which prevents mpv from loading images again as
external cover art, but this isn't necessary because cover art is only
added when playing standalone audio. I had only added this check because
I would otherwise get a segfault only when compiling with gcc 10.2 with
optimize and changing position within a playlist of multiple images (and
this couldn't even be reproduced by Dudemanguy on the same gcc version),
but this was caused by the uninitialized lang variable which is now
fixed.
Commit 029ff10 added a goto statement which skipped initializing the
`lang' variable. This could crash depending on compiler optimizations
and other factors: if the lang bstr pointer happened to end up NULL
(which is apparently the case with most compilers) then it's validly
empty, but if it pointed to a random and incorrect memory address then
it crashed.
The crash was observed when mpv was compiled using gcc 10.2 with
optimizations enabled, and affected some third party Windows builds.
This commit ensures the goto doesn't skip the initialization.
Thanks to votemp for figuring this out.
Fixes#8922.
Previously tick() was ensured unconditionally only after mouse-move,
but there are other mouse-events which need re-rendering (tick), like
mouse-down (icons may get grayed-out) or mouse-up (icons may change).
For instance: mpv --pause --myclip.mkv
then move the mouse over the volume/mute OSC button, then - without
moving the mouse - press and release the left mouse button.
The osc was not re-rendered because it's paused and the mouse didn't
move, so the volume icon didn't get grayed-out when held down, and the
icon doesn't change on mouse-up (to reflect the new mute state).
Now both these changes are rendered correctly.
This is not a new issue, however, until the last commit - 96b246d
init probably didn't happen much (or at all) between mouse-down and
mouse-up, but after this commit, if there are chapters in a live-stream
then osc_init() is used to re-render the markers at the adjusted
position - which breaks the OSC buttons functionality if init happened
between mouse-down and mouse-up.
Commit 6abb7e3 updates the markers when the chapters change, but it
doesn't update their relative position at the bar when the duration
changes.
This means that adding chapters to a live stream would result in
corresponding chapter markers which were static while the duration
changed and thus their positions became incorrect over time until the
OSC was reinitialized.
This is fixed by observing the duration property if chapters are present
and reinitializing the OSC when the duration changes.
The live_markers user option, which determines whether the duration
property is observed when there are chapters, has been added in order to
allow disabling this behaviour as calling request_init() frequently
might have some impact on low-end systems.
The impact of request_init() on render() was measured to increase from
1-1.5 ms to 2-3 ms on a 2010 MacBook Air, while the impact was neglible
on a 2016 Surface Book (increasing only to an average of 1.4 ms from
1.3 ms for n=1500 render cycles).
The live_markers option is enabled by default.
If a plane is not connected to any displays, we won't set an entry in
the mapping of planes to displays. So ensure these unset entries are
null and skip them.
Fixes#8913
This is the Vulkan equivalent of the drm context for OpenGL, with
the big difference that it's implemented purely in terms of Vulkan
calls and doesn't actually require drm or kms.
The basic idea is to identify a display, mode, and plane on a device,
and then create a display backed surface for the swapchain. In theory,
past that point, everything is the same, and this is in fact the case
on Intel hardware. I can get a video playing on a vt.
On nvidia, naturally, things don't work that way. Instead, nvidia only
implemented the extension for scenarios where a VR application is
stealing a display from a running window system, and not for
standalone scenarios. With additional code, I've got this scenario to
work but that's a separate incremental change.
Other people have tested on AMD, and report roughly the same behaviour
as on Intel.
Note, that in this change, the VT will not be correctly restored after
qutting. The only way to restore the VT is to introduce some drm
specific code which I will illustrate in a separate change.
The VkDisplayKHR context type requires making calls against the
physical device before the libplacebo context is initialised.
That means we can't simply use the physical device object that
libplacebo would create - instead we have to create a separate one,
but make sure it's referring to the same physical device.
To that end, we need the device name that the user may have requested
so we can pass it on.
This moves the JSON parsing above the main youtube-dl error-handling
block and integrates parsing errors into that block. Now, if a parsing
error occurs, youtube-dl's stderr will be logged as it is with other
errors. This also catches errors that cause youtube-dl to output
"null", which would previously be mishandled as a parsing error and
crash ytdl_hook when it attempted to concatenate the error string from
parse_json.
This was originally just a bugfix for a race condition, but the scope
expanded a bit. Currently, the wayland code does a prepare_read ->
dispatch_pending -> display_flush -> read_events -> dispatch_pending
routine that's basically straight from the wayland client API
documentation. This essentially just queues up all the wayland events
mpv has and dispatches them to the compositor. We do this for blocking
purposes on every frame we render. A very similar thing is done for
wait_events from the VO.
This code can pretty easily be unified and split off into a separate
function, vo_wayland_dispatch_events. vo_wayland_wait_frame will call
this function in a while loop (which will break either on timeout or if
we receive frame callback from the compositor). wait_events needs to
just check this in case we get some state change on the wakeup_pipe
(i.e. waking up from the paused state).
As for the actual bugfix part of this, it's a slight regression from
c26d833. The toplevel config event always forced a redraw when a surface
became activated again. This is for something like displaying cover art
on a music file. If the window was originally out of view and then later
brought back into focus, no picture would be rendered (i.e. the window
is just black). That's because something like cover art is just 1 frame
and the VO stops doing any other additional rendering. If you miss that
1 frame, nothing would show up ever again. The fix in this case is to
always just force a redraw when the mpv window comes back into view.
Well with the aforementioned commit, we stopped doing
wl_display_roundtrip calls on every frame. That means we no longer do
roundtrip blocking calls. We just be sure to queue up all of the events
we have and then dispatch them. Because wayland is fundamentally an
asynchronous protocol, there's no guarantee what order these events
would be processed in. This meant that on occasion, a
vo_wayland_wait_frame call (this could occur multiple times depending on
the exact situation) would occur before the compositor would send back
frame callback. That would result in the aforementioned bug of having
just a black window. The fix, in this case, is to just do a
vo_wayland_wait_frame call directly before we force the VO to do a
redraw. Note that merely dispatching events isn't enough because we
specifically need to wait for the compositor to give us frame callback
before doing a new render.
P.S. fix a typo too.
And also change the existing WM_KILLFOCUS handler to return 0 instead
of 'break' (which later calls DefWindowProcW), as MSDN says we should
do for WM_{KILL,SET}FOCUS.
It seems that the 'focused' property is now supported by all main VOs:
x11, macOS, wayland, Windows.
TCT/sixel/caca probably don't support it, and unknown with SDL.
Fixes#8868
When the OSC initializes, it checks whether the current video has
chapters, and if it does not, it disables its chapter functionality
(chapter buttons are grayed out and unusable, chapter indicators don't
show on the seek bar). If another script changed the chapter list
after the video has loaded, those changes would be ignored by the OSC
until some other event causes it to re-initialize, because it did not
observe the chapter list property. This is fixed by adding
observation of chapter-list alongside the other properties that
trigger re-initialization.
Avoiding blindly copying the codec_tag between different formats allows
us to mux packets from, say, mpegts streams to matroska, making the
recorder (dump-cache) much more usable as unsupported codec_tags can
make the muxer reject the streams.
This brings my scaletempo2 benchmark down from ~22s to ~7s on my machine
(-march=native), and down to ~11s with a generic compile.
Guarded behind an appropriate #ifdef to avoid being ableist against
people who have the clinical need to run obscure platforms.
Closes#8848
Not only does this have semantics that make far more sense, it also has
a default that makes far more sense. (Equivalent to the old
`icc-contrast=inf`)
This removes the weird 1000:1 contrast default assumption which
especially broke perceptual profiles and also screws things up for
OLED/CRT/etc.
Should probably close some issues but I honestly can't be bothered to
figure out which of the thousands colorimetry-related issues are
affected.
Take two. f4e89dd went wrong by moving vo_wayland_wait_frame before
start_frame was called. Whether or not this matters depends on the
compositor, but some weird things can happen. Basically, it's a
scheduling issue. vo_wayland_wait_frame queues all events and sends them
to the server to process (with no blocking if presentation time is
available). If mpv changes state while rendering (and this function is
called before every frame is drawn), then that event also gets
dispatched and sent to the compositor. This, in some cases, can cause
some funny behavior because the next frame gets attached to the surface
while the old buffer is getting released. It's safer to call this
function after the swap already happens and well before mpv calls its
next draw. There's no weird scheduling of events, and the compositor log
is more normal.
The second part of this is to fix some stuttering issues. This is mostly
just conjecture, but probably what was happening was this thing called
"composition". The easiest way to see this is to play a video on the
default audio sync mode (probably easiest to see on a typical 23.976
video). Have that in a window and float it over firefox (floating
windows are bloat on a tiling wm anyway). Then in firefox, do some short
bursts of smooth scrolling (likely uses egl). Some stutter in video
rendering could be observed, particularly in panning shots.
Compositors are supposed to prevent tearing so what likely was happening
was that the compositor was simply holding the buffer a wee bit longer
to make sure it happened in sync with the smooth scrolling. Because the
mpv code waits precisely on presentation time, the loop would timeout on
occasion instead of receiving the frame callback. This would then lead
to a skipped frame when rendering and thus causing stuttering.
The fix is simple: just only count consecutive timeouts as not receiving
frame callback. If a compositor holds the mpv buffer slightly longer to
avoid tearing, then we will definitely receive frame callback on the
next round of the render loop. This logic also appears to be sound for
plasma (funfact: Plasma always returns frame callback even when the
window is hidden. Not sure what's up with that, but luckily it doesn't
matter to us.), so get rid of the goofy 1/vblank_time thing and just
keep it a simple > 1 check.
Checking against 1.0 is wrong for this code, because it's in an absolute
luminance scale relative to reference white. We should be normalizing
this by `dst.sig_peak`.
This is actually a very nice simplification that should have been
thought of years ago (sue me). In a nutshell, the story with the
wayland code is that the frame callback and swap buffer behavior doesn't
fit very well with mpv's rendering loop. It's been refactored/changed
quite a few times over the years and works well enough but things could
be better. The current iteration works with an external swapchain to
check if we have frame callback before deciding whether or not to
render. This logic was implemented in both egl and vulkan.
This does have its warts however. There's some hidden state detection
logic which works but is kind of ugly. Since wayland doesn't allow
clients to know if they are actually visible (questionable but
whatever), you can just reasonably assume that if a bunch of callbacks
are missed in a row, you're probably not visible. That's fine, but it is
indeed less than ideal since the threshold is basically entirely
arbitrary and mpv does do a few wasteful renders before it decides that
the window is actually hidden.
The biggest urk in the vo_wayland_wait_frame is the use of
wl_display_roundtrip. Wayland developers would probably be offended by
the way mpv abuses that function, but essentially it was a way to have
semi-blocking behavior needed for display-resample to work. Since the
swap interval must be 0 on wayland (otherwise it will block the entire
player's rendering loop), we need some other way to wait on vsync. The
idea here was to dispatch and poll a bunch of wayland events, wait (with
a timeout) until we get frame callback, and then wait for the compositor
to process it. That pretty much perfectly waits on vsync and lets us
keep all the good timings and all that jazz that we want for mpv. The
problem is that wl_display_roundtrip is conceptually a bad function. It
can internally call wl_display_dispatch which in certain instances,
empty event queue, will block forever. Now strictly speaking, this
probably will never, ever happen (once I was able to to trigger it by
hardcoding an error into a compositor), but ideally
vo_wayland_wait_frame should never infinitely block and stall the
player. Unfortunately, removing that function always lead to problems
with timings and unsteady vsync intervals so it survived many refactors.
Until now, of course. In wayland, the ideal is to never do wasteful
rendering (i.e. don't render if the window isn't visible). Instead of
wrestling around with hidden states and possible missed vblanks, let's
rearrange the wayland rendering logic so we only ever draw a frame when
the frame callback is returned to use (within a reasonable timeout to
avoid blocking forever).
This slight rearrangement of the wait allows for several simplifications
to be made. Namely, wl_display_roundtrip stops being needed. Instead, we
can rely entirely on totally nonblocking calls (dispatch_pending, flush,
and so on). We still need to poll the fd here to actually get the frame
callback event from the compositor, but there's no longer any reason to
do extra waiting. As soon as we get the callback, we immediately draw.
This works quite well and has stable vsync (display-resample and audio).
Additionally, all of the logic about hidden states is no longer needed.
If vo_wayland_wait_frame times out, it's okay to assume immediately that
the window is not visible and skip rendering.
Unfortunately, there's one limitation on this new approach. It will only
work correctly if the compositor implements presentation time. That
means a reduced version of the old way still has to be carried around in
vo_wayland_wait_frame. So if the compositor has no presentation time,
then we are forced to use wl_display_roundtrip and juggle some funny
assumptions about whether or not the window is hidden or not. Plasma is
the only real notable compositor without presentation time at this stage
so perhaps this "legacy" mechanism could be removed in the future.
when using the bundle with activated big enough cache, very slow and
wasteful memory allocations lead to jittery playback and lot of dropped
frames. the cache had to have a certain size so it would constantly
allocate new memory to reproduce this. this never happens when started
from the terminal.
the source of the problem is a different malloc allocation policy,
MALLOC_NANO, that allocated a huge amount of virtual memory without
actually using it. the usage was between 0% to 25% of that virtual
memory. the binaries allocation policy on the other hand used >80% of
that allocated virtual memory and was a lot more efficient, it would use
MALLOC_TINY instead.
this is fixed by setting the MallocNanoZone environment variable to 0
to use the V1 of the allocation policy. when started from the bundle via
launchd this is forced to 1 and V2 policy which causes this problem.
some more info can be found in following file and its comments on the
Apple open source site:
https://opensource.apple.com/source/libmalloc/libmalloc-317.40.8/src/nano_malloc_common.c.auto.htmlFixes#7405
Shows uploader, channel, description fields. This works only if the
media media is constructed as EDL (for youtube it usually does this),
and if the all_formats option is not set to true (does anyone even use
it?). The former usually happens because youtube serves audio and video
separately, though it will not for live HLS/DASH. The latter uses
delayed media opening, which breaks the global_tags mechanism (see
previous commit).
Add new header which shows up as tags/metadata (associated with
--display-tags). The way this is added means it doesn't always work,
because root->meta (see code) can be NULL for some absurd reason. But it
works for the one case I intended to use it (ytdl_hook, see next
commit), though only in default configurations.
When trying to use completion for mpv binaries specified with some shell
glob, e.g. ~/dev/mpv/build/mpv, the current code doesn't substitute the
homedir prefix into the path name, resulting in runtime errors about
the file '~/dev/mpv/build/mpv' not being found.
The simple fixed is to use $~var instead of $var whenever expanding the
filename, which performs the same globbing that would otherwise be
performed when executing the command.
This reverts commit b8156a9a86.
Apparently there are two problems here. One on Linux (fixed by the
original change and this revert) and one on alternative-medicine-Job's
OS. Since the latter has deprecated OpenGL and OpenGL is a second-class
citizen, I think it's better to prefer the fix for a platform that is
still alive.
When inserting vf_sub, the VO OSD is directed not to draw itself. But
this flag was never unset, even when removing vf_sub.
The fix is pretty shit, but appears to work.
Switching to a new file while keeping the AO didn't update the volume.
While there's an explicit audio_update_volume() call in
reinit_audio_chain_src(), it doesn't work, because at that point
ao_chain->ao is still NULL, and it does nothing. That's pretty weird and
might cause other problems (what happens if you try to mute while the AO
is "floating"?). Regarding gapless, trying to use the AO gain for
replaygain is also gross nonsense, because the new replaygain computed
gain would affect audio from the previous file. It looks like replaygain
should be in an af_volume filter maybe. On the other hand, I enjoy
setting ridiculous replaygain-preamp values and compensating with a low
volume setting, which would not work well if both gains were applied to
the audio independently.
For now, just add the missing call. This is orthogonal to fixing
replaygain "properly".
This reverts commit 3239e41277.
I'm fairly sure this is wrong, and my next commit should fix it
properly. I'm not really sure, though. Normally, the AO is set again
by reinit_audio_filters_and_output() after the new audio chain has
decoded a frame and knows the new format. The reason replaygain (and
apparently the thing the reverted commit tried to fix) didn't work is
because they work asynchronously to the audio played by the AO (i.e.
buggy and hard to fix).
For some reason, this never existed before. Add VOCTRL_GET_DISPLAY_RES
and use it to obtain the current display's resolution from each
vo/windowing backend if applicable. Users can then access the current
display resolution as display-width and display-height as per the client
api. Note that macOS/cocoa was not attempted in this commit since the
author has no clue how to write swift.
This commit describes more accurately what currently gets disabled
by this option - specifically also keys from mp.add_key_binding.
It's not necessarily the best behavior because libmpv clients might
want to disable mpv's own builtin keybindings while still allowing
scripts to define keys which `input.conf' can override.
In the future we might exclude mp.add_key_binding from this option,
but for now at least document this option accurately.
Fixes#8809
3909e4cdfc seems to have replaced this 0.5 constant by 0.75, using its
presence in glumpy as justification.
0.75 is clearly a bug in glumpy, as its own source code doesn't even
match the comment immediately above it. Every other implementation of
this window I could find uses 0.5, including e.g. ImageMagick.
The ctime member on Windows uses FILE_BASIC_INFO.ChangeTime, which is
pretty much the same as st_ctime on POSIX.
See https://devblogs.microsoft.com/oldnewthing/20100709-00/?p=13463 :
... The LastWriteTime covers writes to the file’s data stream
(which you accomplish via the WriteFile function). On the other
hand, the ChangeTime also includes changes to the file metadata,
such as changing its file attributes ...
Fixes#8801
We now have at least 3 scripting APIs which are trivial wrappers
around properties: mp.get_mouse_pos, utils.getcwd, utils.getpid.
After some discussion on IRC it was decided that it's easier for us to
maintain them as trivial wrappers than to deprecate them and inflict
pain on users and script authors, so currently no plan to deprecate.
Some subproperties in osd-dimensions were returned as doubles despite
actually being integers. Additionally, correct a highly misleading line
in the osd-width/osd-height documentation.
This fixes a bug where using boxvideo with showfullscreen=no or
showwindowed=no resulted in the margins not resetting when the OSC
wasn't visible.
For example, using:
script-opts=osc-visibility=always,osc-boxvideo=yes,osc-showfullscreen=no
and then going fullscreen would make the OSC disappear but the video
margins would remain. This is because boxvideo was missing a dependence
on the showfullscreen and showwindowed user options.
This is fixed by adding the corresponding conditions to update_margins()
and setting state.marginsREQ on fullscreen changes. update_margins() is
called on tick() if there's a margins update pending, which guarantees
the boxvideo margins are reset appropriately.
It turns out that if a user specifies fullscreen=yes and a width/height
in an autoprofile, the compositor can execute its toplevel listener
event. This can happen before we have any mpv window rendered at all so
we end up performing a bunch of geometry operations and state checks
when we shouldn't. It subtly messes up a lot of things like state
detection. Just return from this function if the geometry has no width
or height yet.
Clearing state.osd.data with an empty string at render_wipe() fixes an
issue where changing the OSC visibility from "never" directly to
"always" didn't immediately update the display when the player was
paused. This could be verified by starting the player with
`--script-opts=osc-visibility=always --pause` and then running
`script-message osc-visibility never` followed by
`script-message osc-visibility always`.
Removing the overlay without changing the contents meant the overlay
wouldn't update and display when enabled again until the fields changed
in some way (e.g. seeking, mousing over the OSC area, etc.). Clearing
state.osd.data before removal of the OSC makes sure set_osd doesn't
return on re-enable and instead displays the OSC immediately as the data
is now different.
render_wipe() is now also used when the OSC needs to be cleared at
tick() as using set_osd to clear it with an empty string did not call
state.osd:remove() which can allow cleanups related to bitmap memory
allocations etc.
this is a regression of af26402, where we changed the geometry
calculation to use the visible frame and consider its origin. though the
origin is not screen relative but relative to the main screen. the rest
of the code expects a screen relative rectangle. because of that windows
would be placed out of the screen bounds when not on the main screen.
recalculate to origin to be screen relative and use those values for the
rest of the calculations. to make the code a bit more comprehensible
be a bit more explicit about what is done where with temporary variables
and comments. also move the mp_rect calculation that moves the origin
and flips the y position to a separate function, so we can reuse it
later.
The fit_on_screen logic was a bit twisted. Simplify it a bit
and update few comments to explain better what it's used for.
Note that the new logic is not identical to before, but its intent
should now be clearer. This means there might be regressions or
improvements at edge cases. If followup fixes are needed, then we
should keep the intent clear. Most likely though that it's fine.
fit_on_screen is called only from reinit_window_state.
Move the yes/no logic unmodified from fit_on_screen to
reinit_window_state, and remove the w32->parent condition because it's
already checked earlier at reinit_window_state.
Previously, because the video (client area) was centered but the top
and bottom borders are uneven (title is taller), then if the window
is shrunk vertically to just-fit the desktop - the top edge of the
title bar ended above the top edge of the display.
This is a state which Windows prevents during manual move, but
apparently it's not rejected at the Windows API.
Now we ensure it doesn't happen, and nudge the window down to align
the top edges if necessary.
This is a commulative regression of commits 981048e0 and 364af7c6.
To clarify functionality, this includes a no-op change: fit_rect was
renamed to fit_rect_size and it now takes explicit width and height,
because it only used the width/height of rc2 anyway.
Fixes#6695
The accurate description of this option was:
- fit-border is enabled by default. When disabled, it adds a bug where
if the window has borders and mpv shrinks it to fit the desktop, then
the calculation ignores the borders and adds incorrect video crop.
The option was added at commits 70f64f3c and 949247d6, in order to
solve an issue (#2935) where if mpv wanted to display a video with
size WxH, then w32_common.c incorrectly set the window to WxH, while
down-scaling the video slightly to fit (even with small sizes).
It was addressed with a new option which is enabled by default, but
does the right thing (sets the client area to WxH) only when disabled,
so that everyone who prefers their video slightly downscaled could
keep their default behavior.
(#2935 also addressed an off-by-one issue, fixed before fit-border)
While disabling the option did avoid unnecessary downscaling, it also
added a bug when disabled: the borders are no longer taken into
account when the size is too big for the desktop. Most users don't
notice and are unaffected as it's enabled by default.
Shortly later (981048e0) the core issue is fixed, and now the client
area is correctly set to WxH instead of the window (and together with
the three following commits which center the video, adds a new bug
where the window title can be outside the display - addressed next).
However, fit-border remained, now without any effect, except that it
still has the same bug when disabled and the window is too big.
Later code changes and refactoring preserved this issue with great
attention to details, and it remained in identical form until now.
Simply rip out fit-border.
See #8137 for justification.
This is not ideal, because a large cache results in a lot of `strcmp`
invocations for every single shader invocation. But it's way better than
resulting in a lot of shader recompilations for every single shader
invocation.
The only reason I don't want to uncap it altogether is because there are
conceivable edge cases in which users load dynamically generated shaders
with updated parameters (indeed, I've seen IRC discussions to this
effect), and in this case, we don't want to grow the cache infinitely as
a result of something like a floating point parameter being continuously
updated. (Never mind that this *would* actually trigger worst case
behavior for the `strcmp`, since the updated float constant is likely to
be near the bottom of the shader body)
Whatever. vo_placebo will liberate us all in the end.
The wayland code uses a heuristic to determine whether or not the mpv
window is hidden since the xdg-shell protocol does not provide a way for
a client to directly know this. We don't render with the frame callback
function for various, complicated reasons but the tl;dr is that it
doesn't work well with mpv's core (maybe an essay should be written on
this one day).
Currently, the aforementioned heuristic considers a window hidden if we
miss more frames in a row than the display's current refresh rate
(completely arbitrary number). However, the wayland protocol does allow
for the display's refresh rate to be 0 in certain cases (like a virtual
output). This completely wrecks the heuristic and basically causes only
every other frame to be rendered (real world example: nested sway
sessions).
Instead let's slightly redesign this mechanism to be a little smarter.
For coming up with the vblank time (to predict when to timeout on the
wait function), instead use the vsync interval calculated using
presentation time. That is the most accurate measure available. If that
number is not available/invalid, then we try to use the vsync interval
predicted by the presentation event.
If we still don't have that (i.e. no presentation time supported by the
compositor), we can instead use the old way of using the expected vsync
interval from the display's reported refresh rate. If somehow we still
do not have a usable number, then just give up and makeup shit. Note
that at this point we could technically ask the vo for the estimated
vsync jitter, but that would involve locking/unlocking vo which sounds
horrifying. Ideally, you never reach here.
See https://github.com/swaywm/wlroots/issues/2566 for the actual target
of this fix. wlroots uses presentation time so in practice we are mostly
just using that calculated vsync interval number.
Seems to be a slight corner case with the audio API rewrite. When
switching from one file to another one, the volume of the ao would never
be set because the audio chain's ao wasn't set. This caused a bug with
the reset-set-on-file option. The volume/property would be correctly set
internally, but the gain was not actually set when the file switched.
Fixes#8287.
The wayland output listener can update whenever something about the
output changes (resolution, scale). Currently, the mpv VO updates
correctly when the refresh rate changes, but changes of both scale and
resolution were not considered. This causes a bug in certain cases like
the mouse surface not being shown at certain scale factors due to the
cursor scale not being updated correctly. Also autofit type options
would not update if the resolution changes.
To fix this, we must always reset the window geometry and wl scaling
whenever the output event occurs on wl->current_output. There is no way
to know precisely what changed from the previous state, so all of the
parameters must be reset and then resized.
As an aside, this apparently doesn't fix all cursor problem as there's
apparently a bug in libwayland-cursor(*). It's still something we should
be doing regardless.
*: https://gitlab.freedesktop.org/wayland/wayland/-/issues/194
So apparently this property had existed since 2019. Internally, it's
used as a part of the console.lua script for scaling. Yours truly
somehow didn't bat an eye at the fact that the text in the console was
super small (made worse by the fact that xwayland does scale) and just
ignored it for all this time. Oh well.
To report dpi changes to mpv's core, we need to use VO_EVENT_DPI in a
couple of places. One place is, of course, the surface listener if the
scale value reported by the wayland server changes. The other place is
in the very first reconfig since mpv's core will not find the correct
scale value until we actually get a wl_output from the wayland server.
This fixes audio encoding crashing under ASan.
When extended_data != data, FFmpeg copies more pointers from
extended_data (= the number of channels) than there really
are for non-planar formats (= exactly 1), but that's not our fault.
Regardless, this commit makes it work in all common cases.
The args struct is reused to attempt opening an URL with
different stream layers, overwriting args->url not only
breaks this but also causes the freed buffer to be used again.
Before this commit, the user could specify a printf format string
which wasn't verified, and could result in:
- Undefined behavior due to missing or non-matching arguments.
- Buffer overflow due to untested result length.
The offending code was added at commit 103a9609 (2002, mplayer svn):
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4566 b3059339-0415-0410-9bf9-f77b7e298cf2
It moved around but was not modified meaningfully until now.
Now we reject all conversion specifiers at the format except %%
and a simple subset of the valid specifiers. Also, we now use
snprintf to avoid buffer overflow.
The format string is provided by the user as part of mf:// URI.
Report and initial patch by Stefan Schiller.
Patch reviewed by @jeeb, @sfan5, Stefan Schiller.
When mpv attempts to play a video that is, on average, 60 FPS on a
display that is not exactly 60.00 Hz, two options try to fight each
other: `video-sync-max-video-change` and `interpolation-threshold`.
Normally, container FPS in something such as an .mp4 or a .mkv is
precise enough such that the video can be retimed exactly to the display
Hz and interpolation is not activated.
In the case of something like certain live streaming videos or other scenario
where container FPS is not known, the default option of 0.0001 for
`interpolation-threshold` is extremely low, and while
`video-sync-max-video-change` retimes the video to what it approximately
knows as the "real" FPS, this may or may not be outside of
`interpolation-threshold`'s logic at any given time, which causes
interpolation to be frequently flipped on and off giving an appearance
of stuttering or repeated frames that is oftern quite jarring and makes
a video unwatchable.
This commit changes the default of `interpolation-threshold` to 0.01,
which is the same value as `video-sync-max-video-change`, and guarantees
that if the user accepts a video being retimed to match the display,
they do not additionally have to worry about a much more
precise interpolation threshold randomly flipping on or off. No internal
logic is changed so setting `interpolation-threshold` to -1 will still
disable this logic entirely and always enable interpolation.
The documentation has been updated to reflect this change and give
context to the user for which scenarios they might want to disable
`interpolation-threshold` logic or change it to a smaller value.
Today, validation is only possible for string type options. But there's
no particular reason why it needs to be restricted in this way, and
there are potential uses, to allow other options to be validated
without forcing the option to have to reimplement parsing from
scratch.
The first part, simply making the validation function an explicit
field instead of overloading priv is simple enough. But if we only do
that, then the validation function still needs to deal with the raw
pre-parsed string. Instead, we want to allow the value to be parsed
before it is validated. That in turn leads to us having validator
functions that should be type aware. Unfortunately, that means we need
to keep the explicit macro like OPT_STRING_VALIDATE() as a way to
enforce the correct typing of the function. Otherwise, we'd have to
have the validator take a void * and hope the implementation can cast
it correctly.
For help, we don't have this problem, as help doesn't look at the
value.
Then, we turn validators that are really help generators into explicit
help functions and where a validator is help + validation, we split
them into two parts.
I have, however, left functions that need to query information for both
help and validation as single functions to avoid code duplication.
In this change, I have not added an other OPT_FOO_VALIDATE() macros as
they are not needed, but I will add some in a separate change to
illustrate the pattern.
This fixes an issue where dithering was effectively broken on libplacebo
versions >= 103 because the dither texture was being sampled with
edge-clamped rather than repeating semantics.
Changes:
- code refactored;
- mixer options removed;
- new mpv sound API used;
- add sound devices detect (mpv --audio-device=help will show all available devices);
- only OSSv4 supported now;
Tested on FreeBSD 12.2 amd64.
There was a simple oversight that meant audio outputs were
uninitialized during an encoding, which is not allowed, the encoding
would stop with numerous errors.
I added a single line to prevent the call of uninit_audio_out in
reinit_audio_chain if the encoder was active and this appears to have
fixed the problem without breaking anything else.
Fixes#8568
Gopher over TLS (gophers) is a community-adopted protocol and has recently
been merged in:
- curl (a1f06f32b8603427535fc21183a84ce92a9b96f7)
- ffmpeg (51367267c8a9f1a840f5e810f8c788e6e03712a5)
Now loading cover art through mp_add_external_file requires an
additional argument to be set to true. This way not all video-add
commands end up being marked as cover art when they move through
mp_add_external_file, as originally changed in 55d7f9ded1 .
Additionally, this lets us clean up some logic that would otherwise be
duplicated between open_external_files and autoload_external_files, if
the logic had been kept split from mp_add_external_file.
Fixes#8358
This makes the behavior of all control messages consistent,
fixing an inconsistency that has been with us since
4d8266c739 - which is the initial
rework of the polyaudio AO into the pulseaudio AO.
Muting the stream also directly triggers an update to the OSD.
When not waiting for the command completion this read of the mute
property may read the old state. A stale read.
Note that this somehow was not triggered on native Pulseaudio, but it is
an issue on Pipewire.
See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/868
Some tracks happen to lack bitrate information (ie. no tbr value).
In that case, just ignore the track while computing the max bitrate.
For an example, this is a stream in which all audio tracks
have no bitrate: https://www.raiplay.it/dirette/rai1
The wayland code takes mouse dragging into account in order to trigger a
client-side request for a window move or window resize. According to the
xdg-shell spec*, "[t]he server may ignore move[/resize] requests
depending on the state of the surface (e.g. fullscreen or maximized)".
Since it is not actually a hard requirement, that means the compositor
could actually respond to a clientside move/resize request even if the
mpv window was fullscreen. For example, it was pointed out that in sway,
if mpv is a floating window, you could drag it around off screen even
though the window is fullscreen.
This kind of behavior does not really have any practical use. A user can
should pan a video if he/she wishes to move its orientation while
fullscreen (or maximized for that manner). Naturally, a maximized or
fullscreened window should never be manually resized (every compositor
likely ignores this anyway). The fix is to simply just not trigger the
smecial mouse dragging case if the wayland surface is fullscreened or
maximized.
*:https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/master/stable/xdg-shell/xdg-shell.xml
the fullscreen style mask is not supported on macOS 11 anymore outside
of the native fullscreen animation. this can lead to a none working fs
or in the worst case a crash.
to fix this we will simulate a fullscreen window with a borderless
window with the size of the whole screen, though only on macOS 11.
Fixes#8490
It's about a year old, and packaged pretty much everywhere that bothers
to package libplacebo at all. Older versions are only a thing on LTS,
which will probably also use older mpv so it works out.
Starting with v2.72.0, libplacebo validates all of its parameters
internally and turns them into function failures. Doing it twice is
awfully redundant, so we can drop the parameter validation.
Also allows us to drop some preprocessor macros.
if log-file and really-quiet options were used together it could lead to
a completely empty log-file. this is unexpected because we need the
log-file option to work in all cases and produces at least a log of
verbosity -v -v. this is a regression of commit
a600d152d2
move the really quiet check back up, so it's set before the evaluation
of the actual log level, where check for log file, terminal, etc take
place.
the slider on the touch bar was always updated when any of the related
properties changed their value. this is partially dependent on the
refresh rate of the video, in the case of time-pos. too many updates to
touch bar impact the render performance.
to prevent this we only update the slider when necessary, when the touch
bar or the touch bar item is visible. the touch bar items only need a
granularity of seconds without any decimals, but the time-pos property
provides a granularity with decimals. we floor those values and only
update the touch bar items when we have at least a 1 second difference.
we also check for the visibility of the touch bar and its items.
Fixes#8477
the NSSliderTouchBarItem seem to be broken in a way it can't be fixed.
it has constraints set by default that can't be removed and lead to
warnings and render performance regressions.
instead of using the preconfigured NSSliderTouchBarItem we use a custom
touch bar item (NSCustomTouchBarItem) with a slider, which essential are
the same. this way we can configure our constraints ourselves, which
aren't needed in the first place.
Fixes: #7047
initialising UnsafeMutableRawPointer the way we did won't free those
pointers and we get dangling pointers. explicitly define a scope those
pointers are alive and auto freed.
this drops support for swift <4.1 and with this support for xcode <=9.2.
this was the last setup that is officially working on macOS 10.12.
our old legacy build macOS 10.12 + xcode 9.2 is replaced by macOS 10.13
+ xcode 9.4.1 with swift 4.1. the macOS 10.13 + xcode 10.1 VM is
replaced by the latest macOS 10.14 + xcode 11.3.1 VM. this is the oldest
version officially supported by Apple.
this is in preparations for the following commit.
the pointer used to initialise the respective structs is only guaranteed
to be alive within this constructor. the struct itself is used later and
the data it points to, is not guaranteed to be the same.
to fix this we define a scope that pointer is definitely valid and use
it within this scope. a helper function was added to get the pointers
for several data at once. otherwise we would need to nest
withUnsafeMutableBytes several times, which would make it hard to read.
Apple has decided that Mac OS X is now named macOS for the time
being. For consistency, it makes sense to use the same name for the
operating system in all places where it occurs. This commit renames
OS X to macOS in the documentation in places where it was otherwise
still using the old name.
Where X is any ASCII char chosen by the user. An argument is only
interpreted as custom-quoted if it starts with '!' and the line doesn't
end right after it. Custom quotes don't interpret backslash-escape.
This change only affects command arguments which mpv parses (not array
commands), and not tokens before the arguments (where applicable - key
name, input section, command prefixes, command name).
This enables us to get more of a message than just "Download failed.",
possibly helping people help themselves to get the download going.
References #8417
Should result in: "You manually enabled the feature 'lua', but the
autodetection check failed."
The moved bit of code was probably intended to do that all along, but it
was running too late, so the code that actually checked for Lua didn't
know it was explicitly asked for and quietly disabled it if not found.
Oversight when the modifier checking was split out to a separate
function. Instead of immediately returning on a match, be sure to loop
through all modifiers and catch every single one that is pressed before
we return them.
currently we use the whole screen rectangle to calculate the window
geometry. this doesn't take the menu bar or the Dock into account.
by default use the visible screen rectangle instead. this is also a
change in behaviour, since the window can't be placed outside of this
rectangle anymore. also add an option to change to the old behaviour,
because it can still be useful in certain cases, like placing the window
directly underneath the menu bar when used a desktop background.
Fixes#8272
when exiting fullscreen we set the window frame to a aspect fit frame of
the fullscreen frame to prevent aspect ration problems when animating.
though that intermediate frame was set too early and before the system
knew we already exited the fullscreen. because of that the frame we set
could not be properly set and its origin was defaulted to the bottom
left corner for exactly one display refresh and only after that the
wanted frame was set. this led to a (dark) grey area on the right or
top depending on the aspect ratio difference of the screen and video.
to prevent this set the intermediate frame in the animation group to
make it sync with the system's fullscreen behaviour.
Fixes#8371
Originally when presentation time was implemented, the frame callback
and presentation feedback functions were called in each rendering api's
separate backend (egl and vulkan). This meant that their respective
structs were basically copy and pasted across both files. Plus later
vo_wlshm started using frame callbacks too. Things got refactored a few
times and it turns out there's actually no need to have these things
separate anymore. The frame callback can just be initialized in
vo_wayland_init and then everything else will follow from there. Just
move all of this code to wayland_common and get rid of the duplication.
Sidenote: This means that vo_wlshm can actually receive presentation
feedback now. It's really simple to do so might as well. See the next
commit.
If the window is maximized, we can't change the size immediately. In
that case, we set a bool and wait for the state to change before
triggering the resize.
Additionally, do some cleanups in the resize/autofitting code to make
sure we don't do any wasteful VO_EVENT_RESIZE calls. Note that if
set_geometry is called, we must always perform a resize.
--alpha=yes doesn't affect only transparent videos and images, but also
the background. I spent time researching how to implement transparent
backgrounds and had no idea that they already worked at least on
Wayland.
Background transparency will work on X11 when
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2376 is
merged. It doesn't work on Windows. No idea about macOS. Either way,
this paragraph already says that it only works on certain environments
twice.
References #6590
With the current wording, I thought that playlist-prefetch doesn't
prefetch the next url within a playlist of m3u8 urls, but it makes a big
difference, and I would have enabled it earlier if it wasn't for this
paragraph.
This makes it clear that you can prefetch any file, but that it won't
prefill the cache with the video data. This is true for any video,
there's nothing unique about HLS streams in the behavior of this option.
There's a bit of a catch-22 in the wayland backend. mpv needs to know
several things about the wl_output the surface is on (geometry, scale,
etc.) for lots of its options. You still have to render something
somewhere before you can know what wl_output the surface is actually on.
So this means that when initializing the player, it is entirely possible
to calculate initial parameters using the wrong wl_output. The surface
listener is what will eventually correct this and pick the correct
output. However not everything was technically working correctly in a
multi-output setup.
The first rule here is to rework find_output so that it returns a
vo_wayland_output instead of internally setting wl->current_output. The
reason is simply because the output found here is not guaranteed to be
the output the surface is actually on. Note that for initialization of
the player, we must set the output returned from this function as the
wl->current_output even if it is not technically correct. The surface
listener will fix it later.
vo_wayland_reconfig has to confusingly serve two roles. It must ensure
some wayland-related things are configured as well as setup things for
mpv's vo. The various functions are shuffled around and some things are
removed here which has subtle implications. For instance, there's no
reason to always set the buffer scale. It only needs to be done once
(when the wl->current_output is being created). A roundtrip needs to be
done once after a wl_surface_commit to ensure there are no configuration
errors.
surface_handle_enter is now handles two different things: scaling as
well as mpv's autofit/geometry options. When a surface enters a new
output, the new scaling value is applied to all of the geometry-related
structs (previously, this wasn't done). This ensures, in a multi-monitor
case with mixed scale values, the surface is rescaled correctly to the
actual output it is on if the initial selection of wl->current_output is
incorrect.
Additionally, autofit/geometry values are recalculated if they exist.
This means that dragging a surface across different outputs will autofit
correctly to the new output and not always be "stuck" on the old one.
A very astute observer may notice that set_buffer_scale isn't set when
the surface enters a new output. The API doesn't really indicate this,
but a WAYLAND_DEBUG log reveals that the compositor (well at least
sway/wlroots anyway) magically sets this for you. That's quite fortunate
because setting in the surface handler caused all sorts of problems.
in the original commit, that removed the conditional clearing, an
incorrect assumption was made that clearing "should be practically free"
and can be done always. though, at least on macOS + intel this can have
a performance impact of up to 50% increased usage. it might have an
impact on other platforms and setups as well, but this is unconfirmed.
the reason for removing the conditional clearing was to partially work
around a driver bug on very specific setups, X11 with amdgpu and OpenGL,
to clear garbled frames on start. though it still has issues with
garbled frames in other situation like fullscreening. there is also an
open bug report on the mesa bug tracker about this. setting the
radeonsi_zerovram flag works around all of those issues.
since the flag works around all these issues and the original fix
doesn't work completely we revert it and keep our optimisation.
Fixes#8273
the screen-name and fs-screen-name option allow for specifying screens
based on their name. this is the name of the NSScreen and also reported
by the VOCTRL_GET_DISPLAY_NAMES event. the old screen and fs-screen
options by id, respectively, are preferred over these new ones.
In wayland, setting the surface on a specific monitor only works in
fullscreen so only --fs-screen-name can be implemented. Like with x11,
we prefer --fs-screen over --fs-screen-name if it is set. This may be
more useful than setting by ids because there's no guaranteed order in
which screens are added in wayland. In wayland, the name used here is
the model name detected by the output_listener.
The --screen-name and --fs-screen-name options allow for specifying
screens based on their name. For x11, this is the display name reported
by xrandr. --screen-name and --fs-screen-name mimic the --screen and
--fs-screen options respectively. If --screen is set, then --screen-name
will always do nothing. Likewise, --fs-screen-name does nothing if
--fs-screen is set.
Simple groundwork for adding a couple of user options that allow
selecting the screen with a string name. The next two commits implements
these options for xorg and wayland.
While this says that _ is replaced with -, it doesn't say that you HAVE
to use _. This isn't obvious and I didn't understand why my profile
conditions with - weren't working at first. Seeing as the person who
reproted #8324 ran into this as well, this may be worth clarifying.
Zlib has had a .pc file since 2010, and the default search paths we use
here can break the build on some distros (notably openSUSE Tumbleweed,
which our Travis builds use). Just check pkg-config instead.
Our canvas size calculation is affected by few factors, and rounded
down more than once - which can result in 0 width or (more typically)
height - e.g. when terminal height is one row.
If the width or height are 0 then all bets are off, so simply skip
the setups and rendering on this case. We can still recover
automatically if the terminal is resized to become bigger.
The obvious approach would be SIGWINCH, however, integrating it would
be tricky, so instead we simply poll the size on draw_frame.
This means the image won't resize automatically when still - e.g.
cover art or when paused, though it would re-fit on OSD changes.
This is commonly used by UHD/HDR sources, and mpv hilariously ignores it
up until now, just blindly mapping it to MP_CHROMA_AUTO without even so
much as a warning message.
It would be justified to add all the other chroma locations as well, but
I'm lazy and just wanted to quickly fix this bug.
homebrew is removing 10.13 support and some of the dependencies start
building rom source now. we will just pin the last working homebrew
version, similar to the 10.12 build
The reference is allocated at reconfig and happens at least once (and
leaked at least once), but can also be called more, e.g. on zoom or
pan-and-scan changes.
The reference is allocated at reconfig (and leaked at least once), but
could theoretically be called more than once by mpv, or in the future
when the tct code is enhanced to hande e.g. pan-and-scan changes.
testdither was being created irrespective of whether
opt_fixedpal is set or not. In case of opt_fixedpal=1,
testdither is not used in the `prepare_static_palette`
code. Hence only initialize it when opt_fixedpal is 0.
In sixel_dither_initialize, replace 3 with the libsixel
SIXEL_PIXELFORMAT_RGB888. Also in sixel_encode, the 4th
parameter is supposed to be depth, which also happens
to be the value of PIXELFORMAT_RGB888, so replacing that
constant with the depth value.
Since 0.33.0 mpv does not support python2. This commit removes
python2 support from the file completely with the following
changes:
- __future__ import of print_function is python2 only
- unicode literals are legacy in python3
- 'sys.version_info.major < 3' check is redundant
In 0.33.0 python2 support has been removed from mpv's build system. This
commit removes python2 compatibility code from bootstrap.py with the
following changes:
- __future__ import for print_function is not needed
- urllib2 is python2 only
For two reasons:
1. It was counter intuitive that there's an "auto" value (which is
actually a libsixel value and not an mpv one), but it's not the
default value - our default was Atkinson.
2. "auto" provides better dithering than Atkinson with libsixel, which
is especially noticeable with smooth gradients - where Atkinson has
visible banding.
In libsixel 1.8.2 the "auto" value maps to Atkinson if the output
palette has up to 16 colors, or to Floyd-Steinberg otherwise (e.g.
using fixed palette with 256 colors chooses Floyd-Steinberg).
The issue was that we only uploaded the palette to the terminal when it
changed (once on init with fixed palette, every frame with dynamic
palette with trheshold=-1, only on scene change with threshold >= 0).
Now we upload it on every frame, and it seems to fix the mlterm image
corruption both with fixed palette and also with dynamic palette with
threshold (i.e. at frames which did not upload a palette).
It's not entirely clear why it's required with mlterm.
It would seem that the palette which libsixel uses with fixed palette
matches the built in default palette in xterm, but not in mlterm.
With dynamic palette we can guess that mlterm resets the palette after a
sixel image, but that's not confirmed.
Uploading the palette on every frame doesn't seem to slow down xterm
when using fixed palette - not clear yet why uploading a different
palette (when using fixedpalette=no) slows it down while same palette
on every frame doesn't.
In mlterm there's no slowdown either way - and now also no corruption.
By default we still clear the screen, but now it's possible to leave the
last sixel image on screen.
Allows mpv to be used as img2sixel of sorts, but with our auto-fit and
various mpv scaling/filters etc.
When mpv is in the background because it was started with
`mpv foo.mp3 &`, or the user did ctrl+z bg, and is then brought to the
foreground with fg, it buffers input until you press enter. This makes
it accept input almost immediately. Having a short interval isn't
important, since input is buffered until the next loop iteration.
Closes#8120.
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.