Compare commits

...
402 Commits
Author SHA1 Message Date
sfan5 9ca9066d05 Release 0.34.0 2021-11-01 15:44:39 +01:00
Avi Halachmi (:avih) f6b834a2fc js: ~~/init.js: use mp.find_config_file
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.
2021-11-01 14:31:18 +01:00
sfan5 3ea1f8e80a DOCS: clarify what the ~~/ path means
As it turns out the manual was very wrong about this.
2021-11-01 14:30:59 +01:00
Guido Cella 87c9eefb29 console.lua: define remaining emacs keybindings 2021-11-01 23:42:16 +11:00
Niklas Haas c82ffb6670 vo_gpu: libplacebo: simplify tex transfers for libplacebo 168+
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.
2021-10-31 19:39:58 +01:00
Guido Cella 4a80de90d2 DOCS/input: fix subprocess typo 2021-10-26 20:29:18 +00:00
Guido Cella 8778c296b4 DOCS/options: clarify watch-later-options examples
Make it clearer that watch-later-options controls which options are not saved
and not which ones are restored.
2021-10-26 20:27:49 +00:00
Dudemanguy e4ee0c6ebc wayland: remove incorrect keepaspect check
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.
2021-10-26 13:21:08 -05:00
Noralf Trønnes e6ab676d20 drm_common: add connector types USB, SPI and Writeback
Add support for the newly added USB connector type and also SPI and Writeback.
2021-10-26 17:44:54 +00:00
Noralf Trønnes 9cf95baaf3 drm_common: support unknown connector types
Avoid 'Segmentation fault' by using the connector type name UNKNOWN if
the connector type is not known to mpv.
2021-10-26 17:44:54 +00:00
Jan Ekström 78cfeee2b9 {wscript,demux_lavf}: clean up last bits of !FFMPEG_STRICT_ABI
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.
2021-10-26 01:21:56 +03:00
Jan Ekström f560437594 drm_common: enable specific device selection by means of path 2021-10-25 20:37:03 +02:00
Jan Ekström e6cf918eb8 drm_common: utilize drmGetDevices when iterating over cards
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.
2021-10-25 20:37:03 +02:00
Dudemanguy 12056fdcd4 version.sh: bump copyright year
It's been 2021 for a while now.
2021-10-25 10:20:54 -05:00
Niklas Haas 254730d891 vo_gpu: fix rotated compute shader vertex simulation
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.
2021-10-22 19:08:13 +02:00
Jan Ekström a76527772e github/workflows: use xcode 13.1 if image defaults to xcode 13.0
I find it both hilarious and sad that Github decided that defaulting
to XCode 13.0 was a good idea... At least they added 13.1 quickly.

Ref actions/virtual-environments#4180
Ref actions/virtual-environments#4300
2021-10-21 21:29:08 +03:00
Aman Karmani 06392e7ec1 ao_audiotrack: change buffer sizing logic
Previously number of channels was being ignored.

The buffer will now be between 75ms and 150ms

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani fa691e0f69 ao_audiotrack: allocate chunk buffer based on negotiated size
Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani 6473711dce ao_audiotrack: support delay up to 2s as normal
Fixes issues streaming to echo speaker pair from firetv devices.

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani 432c0255bc ao_audiotrack: set device_buffer based on underlying buffer size when available
Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani 7356ee5339 ao_audiotrack: use new style initializer for AudioTrack when available
Fixes deprecation warnings printed when using this driver.

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Dudemanguy 7ad5ad4098 egl_helpers: ensure debug context attrs/bit exist
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.
2021-10-21 03:16:33 +00:00
Emil Velikov ef301893a5 editorconfig: add initial file/config
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>
2021-10-20 12:26:20 +03:00
Avi Halachmi (:avih) 32e851d2bc lua: makenode: prevent lua stack corruption
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).
2021-10-20 12:07:30 +03:00
Avi Halachmi (:avih) 2249f3f81a lua: autofree infrastructure: x2 faster
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.
2021-10-19 15:45:16 +03:00
Avi Halachmi (:avih) 4703b74e6c js: custom-init: use ~~/init.js instead of ~~/.init.js (dot)
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.
2021-10-19 15:43:39 +03:00
Emil Velikov e13fe1299d egl_helpers: add support for debug contexts
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>
2021-10-16 20:33:53 +00:00
Emil Velikov 6354540cf8 vo_gpu: context_glx: cleanup create_context_x11_gl3 code path
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>
2021-10-16 20:33:53 +00:00
Emil Velikov e869d519ba vo_gpu: context_glx: remove legacy create_context_x11_old()
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>
2021-10-16 20:33:53 +00:00
Emil Velikov 20e9c66fa9 egl_helpers: fixup the EGL_KHR_create_context-less codepath
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>
2021-10-16 20:33:53 +00:00
Emil Velikov 538fb6541e video: opengl: rework and remove ra_gl_ctx_test_version()
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>
2021-10-16 20:33:53 +00:00
Emil Velikov e3883512b1 vo_gpu: opengl: remove --opengl-restrict
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>
2021-10-16 20:33:53 +00:00
Emil Velikov e992ebe128 egl_helpers: remove explicit GLES 3 request
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>
2021-10-16 20:33:53 +00:00
Emil Velikov 0b918edfb5 vo_gpu: opengl: reduce versions in mpgl_preferred_gl_versions
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>
2021-10-16 20:33:53 +00:00
Emil Velikov 0282196f4a drm: re-enable drmSet/DropMaster calls
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>
2021-10-15 19:00:34 +02:00
Emil Velikov 899dae41f3 context_drm_egl: re-enable drmSet/DropMaster calls
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>
2021-10-15 19:00:34 +02:00
Guido Cella e16d0dd15d command: with lavfi-complex, make current-tracks return the first one
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.
2021-10-15 15:11:00 +00:00
Guido Cella 9954fe01a9 player: add track-list/N/image sub-property
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".
2021-10-14 15:39:07 +00:00
Guido Cella 00669dabd3 demux_lavf: improve image detection
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.
2021-10-14 15:39:07 +00:00
Avi Halachmi (:avih) f386fd79b2 js: custom init: ignore ~~/.init.js with --no-config
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.
2021-10-12 14:12:24 +03:00
Avi Halachmi (:avih) a3ef4c62fc DOCS/options: refine --no-input-default-bindings 2021-10-11 22:16:51 +03:00
Avi Halachmi (:avih) 2a183c5ca7 input: new option: --no-input-builtin-bindings
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)
2021-10-11 22:16:51 +03:00
sfan5 b3f3c3fec0 ci: update libs used by mingw build 2021-10-07 21:01:48 +03:00
Jan Ekström da58510a14 github/workflows: enable macOS 11.x CI
This image has finally become public.
2021-10-06 21:56:33 +03:00
Niklas Haas 564f3dba56 vo_gpu: libplacebo: add missing include
This was removed from common.h upstream since it was a cyclic
dependency. We need to re-import it into utils.h manually.
2021-10-04 12:09:58 +02:00
Niklas Haas 275c00974e vo_gpu: libplacebo: drop conditional code paths for old versions
No longer needed with the bump to v3.104.
2021-10-04 12:09:58 +02:00
Niklas Haas 48e8cb6a89 vo_gpu: libplacebo: drop code deprecated in libplacebo v3
This is only needed for back-compat with libplacebo v2, and will break
due to upstream removal starting with libplacebo v4.
2021-10-04 12:09:58 +02:00
Niklas Haas ef2cd3a663 wscript: bump libplacebo minimum version
Switching to v3 allows us to drop the use of deprecated/removed members.
2021-10-04 12:09:58 +02:00
Emil Velikov c27c17fcab options: add missing dash in msg-level help message
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>
2021-10-03 23:09:22 +03:00
Avi Halachmi (:avih) ca6108baf4 osc.lua: avoid infinite ticks loop on idle
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.
2021-10-03 19:52:58 +03:00
Avi Halachmi (:avih) bc6dab6d92 osc.lua: unify animation reset function (no-op) 2021-10-03 19:52:58 +03:00
Avi Halachmi (:avih) c3a647ffee build: lua 5.1/5.2: use generic version names
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).
2021-10-03 19:48:29 +03:00
Avi Halachmi (:avih) 7c5cd5ef10 build: lua version: sanitize id before storage (no-op)
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.
2021-10-03 19:48:29 +03:00
Jan Ekström 5304e9fe31 Revert "player: add track-list/N/image sub-property"
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.
2021-10-02 16:55:13 +00:00
Jan Ekström 64fa440c69 github/workflows: disable seccomp for linux native CI
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
2021-10-02 19:20:36 +03:00
Guido Cella 0862664ac9 player: add track-list/N/image sub-property
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".
2021-10-02 14:44:18 +00:00
Avi Halachmi (:avih) 38b55c862f DOCS/javascript.rst: clarifications (file_info, custom init) 2021-09-30 18:28:46 +03:00
Avi Halachmi (:avih) 6123e97e31 js: custom init (~~/.init.js): fail loudly on errors
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).
2021-09-30 18:28:28 +03:00
Dudemanguy 2d348980cb wayland: further xdg-decoration/border refinements
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").
2021-09-28 16:54:09 +00:00
Ho Ming Shun 940f871514 vo_rpi: fix DISPMANX_UPDATE_HANDLE_T leak
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.
2021-09-28 16:46:52 +00:00
Guido Cella cc4ada655a ytdl_hook.lua: search for yt-dlp by default
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.
2021-09-25 13:57:36 +02:00
Nicolas F 5bf92b628d stream/dvbin: remove "full-featured" API includes
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.
2021-09-22 19:48:14 +03:00
Dan Oscarsson fa767b6268 demux_mkv: enable AVCodec parser timestamp usage for parsed audio
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.
2021-09-21 01:28:26 +03:00
Avi Halachmi (:avih) 930b483a68 win32: Windows 10: timeBeginPeriod on demand
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.
2021-09-21 00:45:08 +10:00
Jan Ekström 7b9e024f37 waftools/features: add forgotten enable variants for enabled features
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.
2021-09-20 00:43:12 +02:00
Dudemanguy 560e6c8709 wayland: report correct window size when maximized
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.
2021-09-13 20:49:07 +00:00
Jan Ekström 62b2c5db98 build: enable strict FFmpeg ABI compatibility by default
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: ebf183eeec

Fixes #9159
2021-09-08 22:28:02 +03:00
Guido Cella c2dec023b7 input.conf: remove redundant comments 2021-09-06 10:16:45 +03:00
Avi Halachmi (:avih) 3405f814fb demux_playlist: extend maximum line size (again) to 2M
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
2021-09-06 10:16:25 +03:00
Avi Halachmi (:avih) 8fb4fd9a18 win32: initial position: center with borders
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.
2021-09-06 10:16:10 +03:00
Avi Halachmi (:avih) 73f16b5431 win32: fix incorrect application of --monitoraspect
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.
2021-09-06 10:16:10 +03:00
Avi Halachmi (:avih) 2b1579b1c8 win_state: add vo_calc_window_geometry3
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.
2021-09-06 10:16:10 +03:00
Arthur Williams 6f23aa0d3e bash completion: Allow completions to work without external functions
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.
2021-09-05 16:51:38 -07:00
Nicolas F 8aef22e45d DOCS/options: fix minor typo in compute shaders
This "bw" should most likely be a "be".
2021-08-29 18:31:55 +03:00
Ivan dffb94f94d wayland: set default cursor size to 24
Set it to 24 if it couldn't be read frome $XCURSOR_SIZE for some reason.
Since it seems to be the default value for most distros/DE.
2021-08-28 01:12:38 +00:00
Ivan d092170bf8 wayland: read XCURSOR_THEME to get cursor theme
Read $XCURSOR_THEME environment variable if set and if not then fall
back to "default" (/usr/share/icons/default and ~/.icons/default)
2021-08-28 01:12:38 +00:00
Cloud11665 f3a2275c24 vo_tct: add resize capability
No performance penalty added by getting the terminal size every frame.
2021-08-26 11:29:07 -07:00
a1346054 91b6757875 vo_drm: fix typo in error message 2021-08-26 20:35:13 +03:00
a1346054 7314253180 DOCS: use upstream license files
The current files contain weird formatting characters, new files
obtained from:
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
2021-08-25 15:56:58 +02:00
a1346054 88460b6f86 DOCS: fix spelling 2021-08-24 20:44:52 +03:00
a1346054 b3d41e8286 DOCS: fix spelling in github issue templates 2021-08-24 20:44:52 +03:00
Guido Cella 0b56e1c00a input.conf: remove bindings of removed properties
angle was removed in a9d83eac40, and program in a75b249b0b.
2021-08-19 15:56:25 +03:00
Guido Cella ed26e8dcd5 input.conf: add comments
These will be shown in the new keybinding list.
2021-08-19 15:56:25 +03:00
Avi Halachmi (:avih) 21d434d2db terminal-unix: identify and ignore unknown CSI sequences
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.
2021-08-19 15:39:42 +03:00
Avi Halachmi (:avih) 007c728ad2 command: cycle: respect the prefix "repeatable"
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.
2021-08-19 15:39:19 +03:00
Avi Halachmi (:avih) 8489249af9 osd_libass: --osd-back-color: apply to the progress bar
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)
2021-08-19 15:39:07 +03:00
Avi Halachmi (:avih) c7cdd38ac9 osd_libass: disable --osd-back-color for the progress bar
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.
2021-08-19 15:39:07 +03:00
Avi Halachmi (:avih) 6193f723b0 win32: support the property display-hidpi-scale
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.
2021-08-18 02:21:33 +03:00
Avi Halachmi (:avih) 052220d1c7 win32: apply dpi-scale with [current]-window-scale
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.
2021-08-18 02:21:33 +03:00
Avi Halachmi (:avih) 19e24bbe86 win32: ensure initial dpi-scale value
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.
2021-08-18 02:21:33 +03:00
Avi Halachmi (:avih) 3abb23d70f command: don't hardcode commands list to be repeatable
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
2021-08-17 22:45:39 +03:00
LaserEyess 4c7d7a8001 DOCS: replace dead waf book link with working one 2021-08-17 13:42:21 +00:00
LaserEyess 9aa5cd6f45 DOCS: convert 3rd party http links to https
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.
2021-08-17 13:42:21 +00:00
LaserEyess b7afac3248 DOCS: convert mpv.io and github links to https
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.
2021-08-17 13:42:21 +00:00
Avi Halachmi (:avih) 36de2efebd vo_tct: fix --vo-tct-256
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.
2021-08-16 11:06:43 +03:00
Cloud11665 cbbd81bb4f vo_tct: optimize print function on non-windows platforms
Using fwrite on non-windows platforms yields a ~25% performance increase.
2021-08-16 02:29:25 +03:00
Guido Cella 013985b872 DOCS/input: update osd-ass-cc documentation
- 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.
2021-08-16 01:33:11 +03:00
Avi Halachmi (:avih) 2b5c2c8e44 vo_tct: fix half-block on windows
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 .
2021-08-16 01:16:34 +03:00
Avi Halachmi (:avih) 2780bf32d0 DOCS/contrinute: add commit title example prefixes 2021-08-15 22:15:27 +03:00
Dudemanguy e0df7688f6 wayland: check for xkb state in handle modifiers
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
2021-08-15 09:45:23 -05:00
Stefan de Konink 0c9e1e34fd stats.lua: typo lavfi-complex
Fix typo lavi-complex to lavfi-complex.
2021-08-15 12:27:40 +03:00
Guido Cella d8e5f6ff3a sub: show subs without duration on vid change
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.
2021-08-13 17:16:43 +00:00
Ho Ming Shun 312e29cf7f vo_rpi: restore fullscreen handling
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.
2021-08-13 17:14:31 +00:00
Dudemanguy f4ceea9b8a x11: handle maximized windows with window-scale
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.
2021-08-12 19:35:40 +00:00
sjambekar b692c6599a vo_vdpau: Don't treat preemption as an error when reconfiguring
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.
2021-08-12 11:14:37 -07:00
Stan Janssen acf7ef86d6 desktop entry: fix duplication of the app icon in a dock like Plank
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
2021-08-12 18:01:35 +02:00
Guido Cella b6ebd1a15e sub: align ytdl-hook secondary subs to the top
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.
2021-08-11 18:15:35 +00:00
Dudemanguy f25d446b03 wayland: fix wrong opts struct 2021-08-10 15:46:25 -05:00
Dudemanguy 577ca780b4 wayland: request xdg-decoration mode on startup
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.
2021-08-10 15:37:49 -05:00
Avi Halachmi (:avih) 8a597a484b lua: read_options: quote values at error messages
This makes it easier to understand the error in cases of incorrect
syntax or formatting at .conf files. (js already has this quoting).

Fixes #9105
2021-08-10 11:00:18 +03:00
Dudemanguy e9e1c41060 vo_wlshm: remove empty options struct
This doesn't do anything and isn't needed as there are no wlshm-specific
options.
2021-08-09 16:39:08 -05:00
Avi Halachmi (:avih) 21ab1df014 DOCS/stats.rst: fix quoting 2021-08-09 23:57:04 +03:00
Dudemanguy 162044ade9 wayland: check for xdg-decoration on border update
Oversight in 69c64f5. If there is no xdg_toplevel_decoration, don't
attempt to set the mode.
2021-08-09 15:07:58 -05:00
LaserEyess ec9083d0d8 options: clarify OS support for media keys
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.
2021-08-09 21:14:51 +03:00
Dudemanguy 69c64f5fc4 wayland: handle xdg-decoration protocol better
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.
2021-08-09 12:55:52 -05:00
Dudemanguy 02323a184f command: check for monitor par in window-scale
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.
2021-08-09 16:33:39 +00:00
Dudemanguy 9dc0857b3d command: check for rotation in window-scale
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.
2021-08-09 16:33:39 +00:00
Dudemanguy 77f2fd97f8 command: merge window-scale code together
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.
2021-08-09 16:33:39 +00:00
Dudemanguy 8d4f10fcc0 wayland: fix keepaspect-window during resize
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.
2021-08-08 21:17:02 -05:00
Dudemanguy 8300830951 wayland: improve behavior with touch events
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).
2021-08-08 03:42:26 +00:00
Dudemanguy 84362e820e wayland: correct window-scale behavior
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.
2021-08-07 18:36:41 -05:00
Dudemanguy 25cfc815f5 manpage: clarify window-scale behavior 2021-08-07 19:50:24 +00:00
Dudemanguy a0441ddb5e command: make current-window-scale writeable, 2nd attempt
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.
2021-08-07 17:30:19 +03:00
Avi Halachmi (:avih) 2667dd6643 Revert "command: make current-window-scale writeable"
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.
2021-08-07 17:30:19 +03:00
Dudemanguy 19c4ae004a wayland: keep track of toplevel width/height again
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).
2021-08-06 11:53:59 -05:00
Guido Cella 7eb34d2376 stats.lua: page 4 (keys): group current-window-scale under window
This groups "set current-window-scale ..." under the "window" group
instead of "current" in the list of keybindings.
2021-08-06 10:29:28 +03:00
Dudemanguy 873ae0de2a command: make current-window-scale writeable
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.
2021-08-05 19:13:10 +00:00
Avi Halachmi (:avih) 41650203c3 sub: sub-filter-regex and jsre: support ass-to-plaintext
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).
2021-08-05 21:32:22 +03:00
Avi Halachmi (:avih) 7c264950c0 sub: new: --sub-filter-jsre (js regex)
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.
2021-08-05 21:32:22 +03:00
Avi Halachmi (:avih) d82a073069 sub: SDH filter: use unified text-extraction utils 2021-08-05 21:32:22 +03:00
Avi Halachmi (:avih) 62704e2315 sub: SDH filter: small refinements
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).
2021-08-05 21:32:22 +03:00
Avi Halachmi (:avih) ab689a33a8 sub: add filter text utils, use from filter-regex (no-op)
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.
2021-08-05 21:32:22 +03:00
Dudemanguy 24357cb7b5 wayland: cleanup handle_toplevel_config
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.
2021-08-03 14:53:27 +00:00
Guido Cella dd7a49eb71 options: don't always set set-locally to true
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.
2021-08-03 13:17:12 +00:00
Avi Halachmi (:avih) 416668d3c8 stats.lua: page 4 (keys): better alignment of non-ascii keys
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).
2021-07-31 11:00:07 +03:00
Dudemanguy 6857600c47 player: eac3 to the whitelist of audio extensions
ffmpeg plays these just fine. Fixes #9065.
2021-07-30 08:20:22 -05:00
hooke007 6b828113a8 DOCS/input.rst: key names: add shift modifier note
Fixes #9060
2021-07-30 11:08:19 +03:00
Avi Halachmi (:avih) 8b1930fbd6 stats.lua: page 4 (keys): detect single-quotes 2021-07-30 09:52:34 +03:00
Avi Halachmi (:avih) 9f6cbf3a4d input: arguments quoting: support single-quotes
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.
2021-07-30 09:52:34 +03:00
Avi Halachmi (:avih) 73c9509720 input: argument custom quotes: use ` instead of !
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).
2021-07-30 09:52:34 +03:00
Guido Cella 3f0e8bd506 options: audio-display determines cover priority
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.
2021-07-29 13:38:28 +00:00
garoto 67ddffcc26 DOCS: fix manual compiling warnings
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".
```
2021-07-28 13:56:27 +03:00
Avi Halachmi (:avih) 6808fff132 DOCS/mpv.rst: fix quoting
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.
2021-07-28 12:49:39 +02:00
Jan Beich 743e1c1b15 ci/travis: remove everything as it's nop now 2021-07-27 20:53:44 +03:00
Jan Beich d62df0491b ci/travis: remove freebsd build 2021-07-27 20:53:44 +03:00
Jan Beich abe523c1d0 github/workflows: add freebsd CI 2021-07-27 20:53:44 +03:00
Guido Cella ecd06a5d01 manpage: explain when properties are expanded 2021-07-27 20:35:07 +03:00
Guido Cella 6fe4fc4593 TOOLS/autocrop.lua: allow hiding OSD messages
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.
2021-07-27 20:32:05 +03:00
Dudemanguy e2c24adebe wayland: unset hidden state in frame callback
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.
2021-07-26 15:05:33 -05:00
Dudemanguy f8e62d3d82 egl_helpers: fix create_context fallback behavior
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.
2021-07-25 15:32:53 +00:00
Guido Cella bcf6077b28 command: handle changes to image-display-duration
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.
2021-07-25 15:32:41 +00:00
Jan Ekström 24c05423a4 github/workflows: separate jobs with an endline 2021-07-25 16:49:32 +03:00
Jan Ekström 20c1efb351 ci/travis: remove linux builds 2021-07-25 16:49:32 +03:00
Jan Ekström 08b82f56cd github/workflows: add linux CI 2021-07-25 16:49:32 +03:00
Avi Halachmi (:avih) 955736b7b7 stats.lua: fix ass-escape while persistent_overlay=yes
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
2021-07-25 15:08:44 +03:00
Jan Ekström e2109b606b ci/travis: remove macOS builds
Quite unlikely to be run afterwards, and the macOS runner on
Github actions seems to work.
2021-07-25 11:53:31 +03:00
Jan Ekström 0c26551345 github/workflows: add macOS CI 2021-07-25 11:53:31 +03:00
Dudemanguy 747b152001 context_drm_egl: allow autoprobe selection
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
2021-07-23 17:54:58 +00:00
Avi Halachmi (:avih) 5ed0338eea js: fix tiny leaks if js_try throws(!)
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) {} }
2021-07-23 17:50:24 +03:00
Guido Cella 36b7cff582 manpage: fix watch-later-options examples
--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=
2021-07-21 16:56:54 +00:00
Avi Halachmi (:avih) 7f4841ff39 js: key bindings: ensure priorities for same-key bindings
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.
2021-07-21 17:29:11 +03:00
Guido Cella 1d1d1fbff9 options: add watch-later-options
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.
2021-07-21 13:19:28 +00:00
Guido Cella ccb87ad637 stats.lua: remove script-opts for the main keys (i/I)
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.
2021-07-21 13:55:58 +03:00
Guido Cella 23e3b0ad98 manpage: minor fixes
- 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.
2021-07-21 13:38:11 +03:00
Avi Halachmi (:avih) 70c9d8d5d7 stats.lua: page 4 (keys): fix "excluding stats keys" - attempt 2
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.
2021-07-20 01:00:03 +03:00
Avi Halachmi (:avih) 1e1b5a6e14 Revert "stats.lua: page 4 (keys): fix "excluding stats keys""
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.
2021-07-20 01:00:03 +03:00
Avi Halachmi (:avih) fab25ac004 stats.lua: page 4 (keys): fix "excluding stats keys"
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.
2021-07-20 00:13:35 +03:00
Avi Halachmi (:avih) 0c6ea0c0b0 DOCS/mpv.rst: add cross references to --input-test and stats 2021-07-19 22:06:50 +03:00
Avi Halachmi (:avih) 2335ee5514 stats.lua: page 4 (keys): support help-like terminal printout
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.
2021-07-19 22:06:50 +03:00
Avi Halachmi (:avih) 9fb200b641 stats.lua: add page 4: active key-bindings list
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.
2021-07-19 22:06:50 +03:00
Avi Halachmi (:avih) 59c10274b4 stats.lua: scroll: allow throttling page-rebuild (no-op)
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.
2021-07-19 22:06:50 +03:00
Avi Halachmi (:avih) 50280197e2 stats.lua: move internal performance from page 4 to page 0
This allows adding more pages without the internal performance page
getting stuck at the middle of the list.
2021-07-19 22:06:50 +03:00
sfan5 3e28c8e983 player: fix missed pause state update during reset in some cases
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.
2021-07-18 12:22:55 +02:00
sfan5 d2a56227df Revert "audio: fix ao_reset() not clearing paused state leading to stuck AO"
In hindsight this is obviously broken.
This reverts commit fb5d976cb0.
2021-07-18 12:21:15 +02:00
Kiracus 1e90ec647c osxbundle: use python3 2021-07-17 00:08:54 +02:00
sfan5 fb5d976cb0 audio: fix ao_reset() not clearing paused state leading to stuck AO
This would happen when switching from playback stuck in cache wait
(underrun) to another file.
2021-07-16 20:58:54 +02:00
Guido Cella 075154175d TOOLS/autocrop.lua: improve enable/disable condition
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.
2021-07-14 11:58:29 +03:00
Shreesh Adiga 8ace8e8790 demux: acquire lock before calling update_bytes_read
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.
2021-07-13 15:16:59 +00:00
Shreesh Adiga be81470f54 audio: check ao driver init failure to avoid use after free
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.
2021-07-13 15:16:59 +00:00
Avi Halachmi (:avih) d828652f24 lua: fix timers comment (no-op)
process_timers() doesn't return an absolute time. It returned delta>0
or nil before f73814b1 , and since f73814b1 it can also return 0.
2021-07-13 13:11:34 +03:00
Martin Tournoij 854404a639 terminal-unix: fix ^Z identification
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.
2021-07-13 12:12:56 +03:00
Ripose f223edb616 DOCS/options: adds documentation for secondary-sub-visibility
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.
2021-07-12 21:07:37 +00:00
Ripose c4f982637f command: adds support for secondary subs to sub-seek and sub-step
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.
2021-07-12 21:07:37 +00:00
Ripose 34cfe9d89b command: add secondary-sub-start and secondary-sub-end properties
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'.
2021-07-12 21:07:37 +00:00
Guido Cella 383acd41a8 manpage: DEL key: clarify it refers to the osc 2021-07-12 13:16:10 +03:00
Guido Cella f049acfd43 manpage: fix typo 2021-07-08 13:22:38 +00:00
TheAMM 4d3df1c842 recorder: add support for attachments (fonts)
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.
2021-07-08 12:44:06 +03:00
TheAMM f9527497c6 recorder: ignore packet queue in mux_packets()
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).
2021-07-08 12:44:06 +03:00
TheAMM b0386fc543 av_common: trim FLAC extradata when copying codec params
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.
2021-07-08 12:44:06 +03:00
TheAMM dd9ed47c99 demux, dump-cache: fix demux cache range sorting
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.
2021-07-08 12:44:06 +03:00
TheAMM 27db175ab6 recorder: clear packet queue after they've been muxed
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!
2021-07-08 12:44:06 +03:00
Guido Cella b3fccf0803 player: add append-play flag to loadlist
Closes #5664.
2021-07-06 15:46:45 +00:00
Avi Halachmi (:avih) d2dd4cacb8 osc: expose osc-visibility via shared-script-properties
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.
2021-07-06 16:12:36 +03:00
Dudemanguy f2afae55e9 wayland: refactor surface scaling
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.
2021-06-30 16:37:36 +00:00
rcombs 0c1544e66c sub: fix subs/lyrics on music files with sub-past-video-end=no
Regressed in 11423acf3
2021-06-27 21:02:39 -04:00
Dudemanguy a02901cae7 wayland: fix wl_surface_set_buffer_scale usage
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.
2021-06-27 10:58:59 -05:00
Dudemanguy 76bddaccd6 wayland: always be sure to initially try to render
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.
2021-06-27 10:58:42 -05:00
Dudemanguy 573f696077 wayland: remove unused includes
Presentation time only lives in in wayland_common.
2021-06-27 10:20:05 -05:00
Dudemanguy a1c6762156 wayland: handle app id option less stupidly
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.
2021-06-26 17:28:01 -05:00
Dudemanguy 488581912d wayland: reorganize wayland common code
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).
2021-06-26 17:24:44 -05:00
Dudemanguy 76a53f9de3 stats.lua: add scaled resolution
Calculate the actual scaled size of the video from osd-dimensions and
display it on the stats page.
2021-06-25 17:54:36 +00:00
hooke007 5f76744c61 DOCS: fix typo on seekbarkeyframes 2021-06-24 14:34:33 +00:00
LaserEyess ee27629244 TOOLS/lua/autoload: load files even if current file is hidden
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.
2021-06-24 13:13:53 +00:00
LaserEyess 28c53dbfa0 TOOLS/lua/autoload: add ignore_hidden option
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.
2021-06-24 13:13:53 +00:00
Guido Cella 5e23e81485 player: fix property name
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.
2021-06-24 12:01:22 +03:00
Avi Halachmi (:avih) 5b40db385a lua: idle observers: ensure timers are up-to-date
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.
2021-06-23 23:47:08 +03:00
Avi Halachmi (:avih) f73814b180 lua: timers: don't block forever with slow callbacks
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.
2021-06-23 23:47:08 +03:00
rcombs 11423acf30 sub: by default, don't render timestamps after video EOF
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.
2021-06-23 16:10:29 -04:00
Guido Cella cb56c2f888 player: change cover-art-auto behavior
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.
2021-06-23 16:23:50 +00:00
Avi Halachmi (:avih) 0427fe97e1 js: idle-observers: minor performance improvement
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.
2021-06-22 18:17:11 +03:00
Avi Halachmi (:avih) 76b1ac57a4 osc: seekbar hover/drag: display target chapter at the title
Fixes #8925
2021-06-22 18:12:29 +03:00
Guido Cella a17d79907a manpage: add article in fuzzy explanation 2021-06-21 15:37:18 +00:00
Guido Cella 9eb126a798 player: remove unnecessary check
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.
2021-06-21 15:36:30 +00:00
Guido Cella f70995cc9b player: fix segfault
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.
2021-06-21 15:36:30 +00:00
Avi Halachmi (:avih) 48f3a26746 osc: ensure tick after any mouse-event
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.
2021-06-20 17:37:47 +03:00
Avi Halachmi (:avih) 89efe820a8 osc: don't initialize while mouse-down over an element
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.
2021-06-20 17:37:47 +03:00
Sagnac 96b246d928 osc: update chapter marker positions when duration changes
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.
2021-06-16 02:04:28 +03:00
Avi Halachmi (:avih) bc9d556f3a js: add mp.utils.append_file
Also, for consistency with other APIs, mp.utils.{write,append}_file
now return true on success (and still throw on any error).
2021-06-13 22:53:37 +03:00
Philip Langdale 03b9f8e323 vo_gpu: vulkan: displayvk: Fix handling of unconnected planes
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
2021-06-12 09:52:37 -07:00
Philip Langdale dbbf4a415d vo_gpu: vulkan: implement a VkDisplayKHR backed context
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.
2021-06-11 09:54:16 -07:00
Philip Langdale dbf0fd7d60 vo_gpu: vulkan: provide a helper to access device name option
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.
2021-06-11 09:54:16 -07:00
Dudemanguy 1b8f10f54a vo_rpi: fix argument name
This is data not arg.
2021-06-08 10:28:10 -05:00
Jan Ekström 0043c7d9ee github/issue_template: irc -> IRC
Requested to be changed while at it.
2021-06-08 16:45:22 +02:00
Jan Ekström 9cf5bb2979 {ci,docs,README}: update IRC references to new network 2021-06-08 16:45:22 +02:00
Chris Varenhorst 4989ccbe7a docs: fix leftover reference to the now defunct --video-sync-adrop-size option 2021-06-04 16:42:45 +00:00
Retusthese fd8c673cfc ytdl_hook: improve handling of json parsing errors
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.
2021-05-29 19:54:03 +03:00
Dudemanguy d7f3d1fff7 wayland: refactor dispatching events
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.
2021-05-28 16:11:01 +00:00
Guido Cella 151b039879 manpage: mention cover-art-auto
--cover-art-auto affects rescan-external-files, and --autoload-files
affects cover art.
2021-05-28 16:10:48 +00:00
Guilherme ce0eb9b1e1 README: fix link to feature-request issues 2021-05-28 16:16:40 +02:00
Guido Cella 029ff1049b player: load cover art with the media filename
Closes #8666.
2021-05-27 18:19:16 +00:00
Avi Halachmi (:avih) 89684976ac win32: support the property 'focused'
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
2021-05-27 13:49:07 +03:00
Retusthese 6abb7e385f osc: re-initialize when chapter list changes
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.
2021-05-27 09:12:38 +03:00
TheAMM c68b9424d6 recorder: fix codec_tag / codec_id confusion 2021-05-26 17:57:24 +02:00
TheAMM 643c699f26 recorder: clear codec_tag if no target format support
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.
2021-05-26 17:36:22 +02:00
Niklas Haas ec0006bfa1 af_scaletempo2: use gcc vectors to speed up inner loop
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
2021-05-26 17:35:55 +02:00
Niklas Haas 353cccfa8c vo_gpu: replace --icc-contrast by --icc-force-contrast
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.
2021-05-26 17:35:29 +02:00
Dudemanguy c26d83348b wayland: shuffle around the render loop again
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.
2021-05-24 19:20:31 +00:00
Dudemanguy 193814497b wayland: send VO_EVENT_DPI on output event as well
The display scaling might change here, so we need to signal mpv's core.
2021-05-23 16:59:30 -05:00
Dudemanguy cbd87ddb93 command: add a missing comma to MP_EVENT_WIN_STATE
In my defense, it still compiled.
2021-05-23 16:47:25 -05:00
Niklas Haas 6c1dd02f32 vo_gpu: fix extreme clipping with --gamut-clipping for HDR outputs
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`.
2021-05-22 21:18:51 +02:00
Dudemanguy f4e89dde36 wayland: simplify render loop
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.
2021-05-22 00:59:56 +00:00
Zsolt Vadasz 83b4bc622a player/command: add secondary-sub-text property 2021-05-19 15:57:01 +00:00
Zsolt Vadasz 62f225ef9d sub/osd: hide secondary subtitles if secondary-sub-visibility is false 2021-05-19 15:56:43 +00:00
Niklas Haas da0c1b8404 vo_gpu: hwdec_vaapi: silence errors while probing
Silences warnings related to DRM format modifiers that can show up while
probing formats.
2021-05-19 04:06:52 +02:00
Dudemanguy 8fc8df3d39 stream_lavf: remove uninitialized http_like array
Serves no purpose and can be a fatal error on certain compiler settings.
Just move the other http_like up here instead.
2021-05-18 13:25:06 -05:00
der richter 9fbe000451 osxbundle: fix slow and wasteful memory allocation
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.html

Fixes #7405
2021-05-16 13:50:40 +02:00
der richter f8128f6570 stream_file: disable read ahead for remote files on macOS
this can cause stutter on remote files because in certain cases this
causes a reconnect to the remote that leads to the file not being read
fast enough. VLC had the same problem and fixes it the same way.
https://github.com/videolan/vlc/commit/b8b8c438f8f65a93da82364c8fea1dbf987c4a8e

Fixes #4434
2021-05-16 13:48:45 +02:00
sfan5 3010588d14 build: move mingw jobs to Github actions 2021-05-16 01:55:37 +03:00
sfan5 10d68d06e6 build: move website rebuild into Linux/clang travis job
The mingw ones will be removed in the next commit.
2021-05-16 01:55:37 +03:00
Your Name ded36a4470 options: add some entries to --display-tags defaults
Useful for the previous commit.
2021-05-11 22:22:33 +02:00
Your Name cbb8f534b0 ytdl_hook: expose some JSON fields as tags
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).
2021-05-11 22:21:46 +02:00
Your Name adcf51dccd edl: add a way to add tags
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.
2021-05-11 22:18:40 +02:00
Niklas Haas ea89e813f7 zsh completion: perform globbing on binary path
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.
2021-05-07 22:18:23 +02:00
Your Name c3ebe7eabd vo_gpu: fix trivial memory leak
Nobody noticed this? Seriously?
2021-05-07 15:01:15 +02:00
Your Name d9008d2aa8 Revert "vo_gpu: revert 8a09299 and conditionally clear framebuffer again"
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.
2021-05-07 15:01:15 +02:00
Your Name 623b92465f vf_sub: restore OSD if removed
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.
2021-05-07 15:01:15 +02:00
Your Name f891eefb5c options: extend --replaygain-preamp range
Whether that makes sense or not.
2021-05-07 15:01:15 +02:00
Your Name 3f7d3d5804 audio: fix replaygain being completely broken
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".
2021-05-07 15:01:15 +02:00
Your Name fce994bdc4 Revert "audio: set audio chain ao on reinit"
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).
2021-05-07 15:01:14 +02:00
der richter dd4d239bcb mac: add support for display-width/display-height property
also merge back a helper function that was introduced in commit d3b7732
and for the purpose to be used with the new display res voctrl event.
2021-05-06 17:36:55 +00:00
Dudemanguy a88fdfde0c command: add display-width/display-height property
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.
2021-05-06 17:36:55 +00:00
Avi Halachmi (:avih) 8edfe70b83 DOCS/input.rst: clarify --no-input-default-keybindings docs
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
2021-05-04 17:26:55 +03:00
Niklas Haas f6f9b1e8db filter_kernels: fix quadric window
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.
2021-05-04 13:18:43 +02:00
Avi Halachmi (:avih) b6aedaa726 DOCS/lua.rst: fix docs for utils.file_info
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 Last­Write­Time covers writes to the file’s data stream
  (which you accomplish via the Write­File function). On the other
  hand, the Change­Time also includes changes to the file metadata,
  such as changing its file attributes ...

Fixes #8801
2021-05-03 13:25:21 +03:00
sfan5 39630dc8b6 build: address AVCodec, AVInputFormat, AVOutputFormat const warnings
FFmpeg recently changed these to be const on their side.
2021-05-01 22:07:31 +02:00
Avi Halachmi (:avih) 02fbdf8aaf scripting (lua/js): utils.getpid: make wrapper of pid property
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.
2021-05-01 16:07:05 +03:00
Avi Halachmi (:avih) f3b2ea9de5 command: new property: pid (process id)
Fixes #7562
2021-05-01 16:07:04 +03:00
Dudemanguy 7df9ebda6c DOCS: clarify how client/script names work
This isn't really clearly stated anywhere and could understandably lead
to some confusion.
2021-04-29 15:56:11 -05:00
Dudemanguy 029cd8a813 command: osd-dimensions: return ints and doc fixes
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.
2021-04-29 15:37:33 +00:00
sfan5 96b68358e3 audio: add two minor log messages
This would have made the problem fixed in the previous
commit a bit more obvious from the log output.
2021-04-29 17:14:51 +02:00
sfan5 aa300f8023 ao/pulse: fix incorrect state reported after reset
fixes #8768
2021-04-29 17:06:29 +02:00
ossifrage 0d384592c5 osc: reset margins when using boxvideo with showfullscreen/showwindowed
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.
2021-04-27 14:12:05 +03:00
Dudemanguy 61a387ac95 wayland: ignore toplevel listener if geometry is 0
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.
2021-04-26 00:54:26 +00:00
ossifrage c1568a3a6c osc: display immediately when visibility changes from never to always
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.
2021-04-25 19:24:46 +03:00
der richter d3b7732aaa mac: fix window geometry calculation on secondary screens
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.
2021-04-24 19:58:12 +02:00
der richter 01482c63ca stream_file: add new identifier for macOS FUSE filesystems
the new identifier for osxfusefs is macfuse, but we will keep both since
the older releases are still used.
2021-04-24 14:22:54 +03:00
Avi Halachmi (:avih) ef0aafbd42 DOCS: mpv.rst: minor escaping clarifications
Fixes #8767
2021-04-23 22:45:21 +03:00
Avi Halachmi (:avih) f60e327e49 win32: fit_window_on_screen: simplify, add comments
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.
2021-04-23 10:45:51 +03:00
Avi Halachmi (:avih) 954f6ac7bf win32: fit_window_on_screen: centralize logic (no-op)
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.
2021-04-23 10:45:51 +03:00
Avi Halachmi (:avih) e00ae12bbb win32: fit_window_on_screen: ensure top edge is inside
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
2021-04-23 10:45:51 +03:00
Avi Halachmi (:avih) ef1d0b2cdb options: win32: ignore and deprecate --fit-border
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.
2021-04-23 10:45:51 +03:00
rland jon f665149fc8 demux_lavf: fix minor memory leaks 2021-04-20 13:28:48 +03:00
Niklas Haas 474ee003ed vo_gpu: greatly increase maximum shader cache size
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.
2021-04-18 20:13:43 +02:00
Dudemanguy 2a1a092bc9 wayland: workaround hidden state detection badness
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.
2021-04-18 16:45:40 +00:00
Dudemanguy 3239e41277 audio: set audio chain ao on reinit
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.
2021-04-18 15:47:48 +00:00
Dudemanguy cd7a7a1de8 wayland: update geometry + cursor on output event
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
2021-04-16 15:46:33 +00:00
Dudemanguy 74f5d4940e wayland: support the display-hidpi-scale property
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.
2021-04-12 14:09:28 -05:00
sfan5 f1d0365a6f demux: undeprecate --cache-secs
It serves a purpose and a rework of the cache won't be coming anytime soon.
This partially reverts commit 8427292eb7.
2021-04-08 23:47:35 +03:00
sfan5 3c34e6fec4 audio/aframe: reuse data buffer if less than 8 channels
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.
2021-04-08 23:47:35 +03:00
sfan5 5117fa70af stream: turn stream_info.open2's args argument const
So nobody comes up with the "smart" idea to modify those again.
2021-04-08 23:47:35 +03:00
sfan5 6be613c178 stream_slice: fix use-after-free if inner stream fails to open
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.
2021-04-08 23:47:35 +03:00
sfan5 6479646f41 player/scripting: fix use-after-free when loading script folders 2021-04-08 23:47:35 +03:00
sfan5 9c120dedb3 stream_mf: set correct stream origin
mf:// reads files from the local filesystem and should be
subject to the usual security checks mpv has for such protocols.
2021-04-08 23:47:35 +03:00
Avi Halachmi (:avih) d0c530919d demux_mf: improve format string processing
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.
2021-04-05 18:24:55 +03:00
un.def ef9596f78e manpage: fix a typo in the --aid option note 2021-04-05 14:31:56 +02:00
LaserEyess dd86f195a6 vo_gpu: adjust interpolation_threshold's default
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.
2021-03-28 20:26:41 +03:00
Philip Langdale e5551f775d options: Add validation macro for int type
As an illustrative example.
2021-03-28 19:46:32 +03:00
Philip Langdale c8f474e3e5 demux: Move demuxer help to new standard mechanism
Previously, demux help was handled as a special case in main.c and this
is no longer necessary.
2021-03-28 19:46:32 +03:00
Philip Langdale 3f006eced4 options: Make validation and help possible for all option types
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.
2021-03-28 19:46:27 +03:00
Niklas Haas 6265724f33 vo_gpu: placebo: keep track of texture sample mode
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.
2021-03-21 17:18:20 +01:00
Chris Varenhorst 5824d9fff8 stats.lua: include a filter's @label when displaying filters on page 1 2021-03-15 23:00:42 +02:00
rim 1b2e5137e0 ao_oss: add this audio output again
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.
2021-03-15 12:42:35 +01:00
Tom Wilson e79e455a36 audio: prevent uninit_audio_out during encoding
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
2021-03-15 01:06:10 +01:00
parazyd 6a903a9a08 stream_lavf: add support for Gopher over TLS.
Gopher over TLS (gophers) is a community-adopted protocol and has recently
been merged in:
 - curl (a1f06f32b8603427535fc21183a84ce92a9b96f7)
 - ffmpeg (51367267c8a9f1a840f5e810f8c788e6e03712a5)
2021-03-15 00:56:11 +02:00
Thomas Weißschuh 63d71ba4ec ao/pulse: signal the mainloop when ops are done
Without the explicit signal the call to pa_threaded_mainloop_wait()
will not return as soon as possible.

Fixes 4f07607888
See #8633
2021-03-11 23:37:13 +02:00
Tom WilsonandJan Ekström d7f6eba233 player/command: add albumart argument to video-add
Enables marking of specific video sources as album art.

Co-authored-by: Jan Ekström <jeebjp@gmail.com>
2021-03-09 23:28:21 +02:00
Jan Ekström eef281e89e player/{core,loadfile}: make cover art loading more explicit
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
2021-03-09 23:26:26 +02:00
Thomas Weißschuh 4f07607888 ao/pulse: wait for command completion when setting volume or mute
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
2021-03-09 23:08:16 +02:00
rnhmjoj 45e6804478 ytdl_hook: fix crash on missing track bitrate
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
2021-03-08 14:01:34 +02:00
jimman2003 aac1844179 umpv: Use generator expression for files
Instead of list. potential memory savings.
2021-03-03 21:35:33 +02:00
Dudemanguy 99968e1ce5 wayland: no mouse dragging in fullscreen/maximized
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
2021-03-02 16:40:13 -06:00
Guido Cella 0888e53fc4 manpage: mention rotate limitations with hwdec 2021-03-02 16:14:12 +02:00
sfan5 bbbf3571ed vd_lavc: wrap use of deprecated AVCodecContext.thread_safe_callbacks in #if
For compatibility once FFmpeg removes it entirely.
2021-03-02 15:00:37 +01:00
Guido Cella 8a7ef58b2d manpage: video-rotate supports arbitrary steps
The 90° step limitation must be a leftover from old behavior since any
value between 0 and 359 works now.
2021-03-02 14:00:12 +01:00
der richter d1be8bb606 mac: fix traditional fullscreen on macOS 11
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
2021-02-27 13:12:46 +01:00
der richter c2868bdd39 mac: remove an unused variable 2021-02-27 13:12:46 +01:00
Niklas Haas 09d7c75bfe vo_gpu: libplacebo: require v2.72.0
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.
2021-02-23 12:44:04 +02:00
Biswapriyo Nath b95c7dd6cc appveyor: Use MSYS2's spirv-cross package instead of building it 2021-02-23 01:38:39 +02:00
Biswapriyo Nath 5de72613b9 appveyor: use latest build image for fixed MSYS2 installation
As MSYS2 installer issues are fixed, remove the workaround from previous commits
b8104a013d and ea91162802
2021-02-23 01:38:39 +02:00
der richter 26ec0e3d46 msg: fix really-quiet option to only affect terminal output
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.
2021-02-23 00:56:21 +02:00
Evgeny Zinoviev 56669fb44e mac: add ability to toggle visibility on all workspaces from menubar 2021-02-21 13:38:53 +01:00
Evgeny Zinoviev a4204be50f command: add label for on-all-workspaces command 2021-02-21 13:38:53 +01:00
Evgeny Zinoviev f913570aad mac: support --on-all-workspaces option 2021-02-21 13:38:53 +01:00
Niklas Haas c766e47b70 vo_gpu: don't abort() if plane tex creation fails
In this case, we just treat all uploads as automatically failing. That
error path already exists and is already handled correctly.

Fixes #8566
2021-02-16 14:22:29 +01:00
Jan Ekström b0b37df31f filters/auto_filters: switch from scaletempo to scaletempo2
Part 1 of "look how well it performs, then start cleaning up the
old one."

Closes #8376
2021-02-15 00:13:03 +02:00
Dorian Rudolph 2e45a3d336 af_scaletempo2: fix crash for speed >= 16
The input buffer size was fixed, but the required size depends on the
speed. Now the buffer will be resized dynamically.

Fixes #8081
2021-02-15 00:07:27 +02:00
der richter 93066ff12f travis: fix macOS VMs with older homebrew versions
apparently travis changed the homebrew setup and that broke the build.
reasons was a different homebrew version that doesn't support the new
brew cli.
2021-02-13 15:51:32 +01:00
der richter 7f8d069087 mac: only update touch bar items when necessary
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
2021-02-13 15:51:32 +01:00
der richter aa00ad06aa mac: use custom touch bar item and slider instead of a touch bar slider
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
2021-02-13 15:51:32 +01:00
Niklas Haas 968faef867 vo_gpu: vaapi: export plane pitch properly 2021-02-12 23:31:46 +01:00
Érico Rolim ce3fe08bd4 DOCS: fix cplugins information in libmpv.rst. 2021-02-12 23:25:08 +02:00
Paul B Mahol 0075b76eeb demuxer/demux_mf: add support for more image codecs 2021-02-06 12:30:53 +01:00
Mia Herkt f60725263c man: update deband-threshold default 2021-02-05 15:37:16 +01:00
Mia Herkt 12ffce0f22 vo_gpu: lower default deband threshold
The previous default was found to be too aggressive for most video.
Change to a lower value to prevent destroying too much detail.
2021-02-05 15:15:55 +01:00
Emmanuel Gil Peyrot f8a9654873 vo_wlshm: support big endian systems
The video was otherwise blue, and that’s not how it should be. :)
2021-02-04 21:13:09 +02:00
der richter 8121d958ec README: update libass dependency harfbuzz as non-optional
since libass 0.15 harfbuzz is no longer optional.

Fixes #8412
2021-01-24 16:54:31 +02:00
garoto f6a92659fd manpage: fix PDF build
Not clear what exactly makes it fail with this change, but making
the note paragraph added in d5ab5482a9 a note structure seems to fix it.
2021-01-23 18:24:21 +02:00
Chris Varenhorst 51852aad52 docs: Fix an old style parameter reference
`--vf format:stereo-in=help` no longer works.  It now must be `--vf=format:stereo-in=help`
2021-01-20 01:15:36 +02:00
Jim Manos 5edf22d2e9 umpv: remove unused imports
* fcntl usage was replaced by socket usage in
  518bd4c306
* stat usage was removed in 51a3f13705
  as the socket was created under the user's HOME.
2021-01-19 22:44:59 +02:00
Mia Herkt 8753bd0198 stream_lavf: support rtsps
Fixes #8480
2021-01-19 13:10:58 +01:00
sfan5 a3e440c611 player: make resetting of track selection to "auto" work 2021-01-16 15:17:01 +01:00
der richter dae9ea3fa7 mac: fix dangling pointers
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.
2021-01-13 16:23:47 +01:00
der richter ce1571ac01 mac: drop build support for swift versions earlier than version 4.1
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.
2021-01-13 16:23:47 +01:00
der richter bc58361d86 mac: fix usage of temporary pointers
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.
2021-01-13 16:23:47 +01:00
Leo Izen d5ab5482a9 manpage: document off-by-one loop-file behavior
loop-file counts the number of zero-seeks, not playthroughs,
which makes its counter off by one compared to loop-playlist.
2021-01-07 09:15:29 -05:00
Leo Izen 1251f7bbf9 manpage: rename OS X references to macOS
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.
2021-01-03 12:05:30 -05:00
Niklas Haas 3e175dff4a vo_gpu: don't segfault if 3DLUT texture fails uploading
This failure path was never properly checked.
2021-01-01 17:14:57 +01:00
Avi Halachmi (:avih) 4f129a3eca input.conf syntax: support custom quotes !XstringX!
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).
2020-12-31 12:54:33 +02:00
Avi Halachmi (:avih) bb439efe0d input.rst: fix typo commands -> arguments 2020-12-31 12:54:33 +02:00
Jan Ekström f02ab2aabb csputils: add mappings for DCI-P3 (ST.431-2) and P3-D65 (ST.432-1) 2020-12-30 20:03:54 +02:00
Emmanuel Gil Peyrot 5f2b60a645 vd_lavc: add VP8 to the default allowed hwdec codec list
It is supported at least on Intel, from gen8 to gen11, and still gives a
pretty welcome reduction of CPU usage on my gen9.
2020-12-30 17:30:01 +02:00
Niklas Haas be167c227b vo_gpu: cast bvecN to vecN for mix() on older GLSL
Fixes https://github.com/mpv-player/mpv/issues/8415, among others
2020-12-28 19:39:41 +01:00
Jan Ekström 40ea28c6f9 bootstrap: log caught URLError
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
2020-12-22 19:09:20 +02:00
Philip Sequeira fa903f3eeb Revert "build: recognize Lua 5.1 on Arch Linux"
The existing "51obsd" is identical, and can be used to explicitly select
Lua 5.1 on Arch if necessary.

This reverts commit 36e569b242.
2020-12-22 00:11:05 +01:00
Philip Sequeira 943f56a96b build: fail configure if --lua is specified and Lua isn't found
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.
2020-12-22 00:11:05 +01:00
Dudemanguy 1ba5dc84ca wayland: support multiple modifiers
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.
2020-12-20 10:57:48 -06:00
der richter dde0189279 mac: fix type mismatch Int instead of Int32 2020-12-19 21:47:19 +01:00
der richter af26402948 mac: use visible frame rectangle for window geometry calculation
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
2020-12-19 21:37:55 +02:00
der richter 93d071dbd8 mac: fix a window positioning bug when exiting fullscreen
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
2020-12-19 15:44:59 +01:00
James Ross-Gowan 2bc88a2936 appveyor: use MSYS2 shaderc package
There's a shaderc package in MSYS2 now. Using it should shave ten
minutes off the appveyor build.
2020-12-19 23:46:16 +11:00
Dudemanguy 4029a695b5 vo_wlshm: support presentation time
We get presentation feedback for free thanks to the last commit.
Implementing it in wlshm is pretty straightfoward from there.
2020-12-14 22:44:43 +00:00
Dudemanguy b59eaf57fe wayland: unify frame/presentation callback code
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.
2020-12-14 22:44:43 +00:00
Dudemanguy 8e793bde78 x11: update geometry/autofit opts on runtime
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.
2020-12-14 22:44:05 +00:00
Dudemanguy 04018c3061 wayland: update geometry/autofit opts on runtime
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.
2020-12-14 22:44:05 +00:00
Guido Cella 7ca14d646c console: use wl-paste on Wayland 2020-12-14 22:43:34 +00:00
Dudemanguy bff5416dae wayland: remove unused function declaration
It looks this line was added over 3 years ago, but said function never
actually existed or was used. Funny stuff.
2020-12-13 18:30:19 -06:00
Philip Sequeira df805cfc84 auto_profiles: fix compile_cond on lua 5.1
5.1's load() doesn't accept strings; loadstring must be used instead.

In 5.2, loadstring is deprecated and setfenv is gone.
2020-12-08 17:29:19 +00:00
Philip Sequeira 36e569b242 build: recognize Lua 5.1 on Arch Linux 2020-12-08 17:29:19 +00:00
Guido Cella 6aa7dbdb84 manpage: document background transparency
--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
2020-12-08 17:27:25 +00:00
Guido Cella d4bf179e78 manpage: clarify that you can prefetch m3u8 urls
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.
2020-12-08 17:27:14 +00:00
Dudemanguy 7db17e627c wayland: handle multiple outputs more correctly
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.
2020-12-08 17:20:51 +00:00
der richter b8156a9a86 vo_gpu: revert 8a09299 and conditionally clear framebuffer again
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
2020-12-06 21:46:29 +02:00
der richter 96bcf51c39 mac: support screen-name and fs-screen-name opts
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.
2020-12-06 17:36:43 +00:00
Dudemanguy a700b8130b wayland: support fs-screen-name option
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.
2020-12-06 17:36:43 +00:00
Dudemanguy 9a7b2015e1 x11: support screen-name and fs-screen-name opts
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.
2020-12-06 17:36:43 +00:00
Dudemanguy 08848e76d9 player: add --screen-name and --fs-screen-name
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.
2020-12-06 17:36:43 +00:00
Guido Cella d479dfd67d manpage: clarify profile-cond requires underscores
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.
2020-12-06 17:31:28 +00:00
Mia Herkt a9aa5a1b1c build: restore support for non-pkgconfig zlib
Some platforms do not offer a .pc file for zlib, e.g. Android.
2020-12-06 01:16:12 +01:00
Mia Herkt 8e3fb7566b build: use pkg-config for zlib
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.
2020-12-06 00:05:09 +01:00
Niklas Haas 7c4465cefb vo_gpu: placebo: update for upstream API changes
The concept of sample/address modes was moved from `pl_tex` to
`pl_desc_binding`.

The `pl_tex_blit()` function also underwent an API change.
2020-12-04 23:49:31 +01:00
Avi Halachmi (:avih) 84d0930fa1 vo_sixel: don't divide by zero on small terminal
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.
2020-12-02 17:06:11 +02:00
Shreesh Adiga da48bb6709 vo_sixel: re-fit image on terminal resize
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.
2020-12-02 17:06:11 +02:00
Shreesh Adiga 3fd656ee7b vo_sixel: refactor of resize, reconfig (no-op)
More granular functionality - will be used by the the next commit.
2020-12-02 17:06:11 +02:00
Shreesh Adiga bd8faa8519 vo_sixel: Update description string of vo driver 2020-12-02 17:06:11 +02:00
Niklas Haas a74b6619f2 csputils: add MP_CHROMA_TOPLEFT
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.
2020-12-02 01:36:29 +01:00
der richter f16c6472a1 travis: use newer 10.15 VM with newer xcode 2020-11-29 16:02:45 +01:00
der richter b9a682edcf travis: fix macOS 10.13 build
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
2020-11-29 16:02:45 +01:00
Avi Halachmi (:avih) aba77c64ff vo_sixel: don't leak the frame reference
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.
2020-11-29 14:15:51 +02:00
Avi Halachmi (:avih) 824e569fb5 vo_tct: don't leak the frame reference
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.
2020-11-29 14:15:51 +02:00
Avi Halachmi (:avih) d4233021c7 vo_tct: remove unused variable 2020-11-29 14:15:51 +02:00
sfan5 6ebac1f794 player: allow vo to be switched at runtime 2020-11-27 17:28:59 +01:00
sfan5 10fbd305c8 demux: add function to refresh a track without (de-)selecting it 2020-11-27 17:28:59 +01:00
Shreesh Adiga 4d80314c5c vo_sixel: use draw_frame instead of draw_image
draw_image is deprecated, and draw_frame allows better
behavior, like rendering the osd without image.
e.g. `mpv --vo=sixel --idle --force-window`.
2020-11-27 15:31:24 +02:00
Shreesh Adiga 4dd5fdc087 vo_sixel: skip testdither init in fixed palette
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.
2020-11-27 15:31:24 +02:00
Shreesh Adiga 24525e4ef9 vo_sixel: Update libsixel constant values
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.
2020-11-27 15:31:24 +02:00
LaserEyess 8886f017a1 matroska.py: remove python2 support
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
2020-11-27 11:17:29 +01:00
LaserEyess d7e80dee26 bootstrap.py: remove all python2 support
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
2020-11-27 11:17:29 +01:00
Avi Halachmi (:avih) 62fb374349 vo_sixel: change default dither to "auto"
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).
2020-11-27 00:25:32 +02:00
Avi Halachmi (:avih) 59c32a04b0 vo_sixel: fix the image corruption with mlterm
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.
2020-11-27 00:25:32 +02:00
Avi Halachmi (:avih) 1bb2665e3d vo_sixel: support --vo-sixel-exit-clear[=yes]
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.
2020-11-27 00:25:32 +02:00
Guido Cella 9867f21830 terminal: process input when foregrounded
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.
2020-11-26 23:55:59 +02:00
sfan5 fa7afc3e19 Update VERSION 2020-11-22 18:48:20 +01:00
201 changed files with 6759 additions and 3638 deletions

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
# To use this config on you editor, follow the instructions at:
# http://editorconfig.org
root = true
[*]
charset = utf-8
insert_final_newline = true
indent_style = space
indent_size = 4
+1 -1
View File
@@ -28,7 +28,7 @@ with --no-config try to first find out which option or script causes your issue.
Describe the reproduction steps as precise as possible. It's very likely that
the bug you experience wasn't reproduced by the developer because the workflow
differes from your own.
differs from your own.
### Expected behavior
+1 -1
View File
@@ -26,7 +26,7 @@ with --no-config try to first find out which option or script causes your issue.
Describe the reproduction steps as precise as possible. It's very likely that
the bug you experience wasn't reproduced by the developer because the workflow
differes from your own.
differs from your own.
### Expected behavior
@@ -26,7 +26,7 @@ with --no-config try to first find out which option or script causes your issue.
Describe the reproduction steps as precise as possible. It's very likely that
the bug you experience wasn't reproduced by the developer because the workflow
differes from your own.
differs from your own.
### Expected behavior
+1 -1
View File
@@ -24,7 +24,7 @@ with --no-config try to first find out which option or script causes your issue.
Describe the reproduction steps as precise as possible. It's very likely that
the bug you experience wasn't reproduced by the developer because the workflow
differes from your own.
differs from your own.
### Expected behavior
+1 -1
View File
@@ -16,7 +16,7 @@ Releases are listed here: https://github.com/mpv-player/mpv/releases
Describe the reproduction steps as precise as possible. It's very likely that
the bug you experience wasn't reproduced by the developer because the workflow
differes from your own.
differs from your own.
### Expected behavior
+4 -4
View File
@@ -1,9 +1,9 @@
blank_issues_enabled: false
contact_links:
- name: mpv irc channel
- name: mpv IRC channel
url: https://mpv.io/community/
about: Feel free to ask questions here irc://irc.freenode.net/mpv
- name: mpv irc developer channel
about: Feel free to ask questions here irc://irc.libera.chat/mpv
- name: mpv IRC developer channel
url: https://mpv.io/community/
about: Ask questions related to the development of mpv here
irc://irc.freenode.net/mpv-devel
irc://irc.libera.chat/mpv-devel
+155
View File
@@ -0,0 +1,155 @@
name: build
on:
push:
branches:
- master
- ci
- 'release/**'
pull_request:
branches: [master]
jobs:
mingw:
runs-on: ubuntu-20.04
strategy:
matrix:
target: [i686-w64-mingw32, x86_64-w64-mingw32]
steps:
- uses: actions/checkout@v2
# Increase -N suffix here to force full rebuild after changes
- uses: actions/cache@v2
with:
path: mingw_prefix/
key: "${{ matrix.target }}-1"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y autoconf automake pkg-config g++-mingw-w64 gcc-multilib nasm yasm
./bootstrap.py
- name: Build
run: |
./ci/build-mingw64.sh
env:
TARGET: ${{ matrix.target }}
- name: Print configure log
if: ${{ failure() }}
run: |
cat ./build/config.log
macos:
runs-on: ${{ matrix.os }}
strategy:
matrix:
cc:
- "clang"
os:
- "macos-10.15"
- "macos-11"
steps:
- uses: actions/checkout@v2
- name: Override Xcode 13.0 if it's the default toolchain
run: |
XCODE_PATH="$(xcode-select -p)"
case "${XCODE_PATH}" in
*Xcode_13.0*)
sudo xcode-select -s "/Applications/Xcode_13.1.app"
echo "Updated Xcode path ${XCODE_PATH} -> $(xcode-select -p)"
;;
esac
- name: Install dependencies
run: |
brew update
brew install autoconf automake pkg-config libtool python freetype fribidi little-cms2 luajit libass ffmpeg
- name: Build
run: |
./ci/build-macos.sh
env:
CC: "${{ matrix.cc }}"
TRAVIS_OS_NAME: "${{ matrix.os }}"
- name: Print configure log
if: ${{ failure() }}
run: |
cat ./build/config.log
linux:
runs-on: "ubuntu-20.04"
container:
image: "registry.cirno.systems/kiwi/containers/mpv-ci:stable-deps"
# Disable seccomp until a container manager in GitHub recognizes
# clone3() syscall,
# <https://github.com/actions/virtual-environments/issues/3812>.
options: --security-opt seccomp=unconfined
env:
CC: "${{ matrix.cc }}"
strategy:
matrix:
cc:
- "gcc"
- "clang"
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
./bootstrap.py
- name: Build
run: |
./ci/build-tumbleweed.sh
- name: Print configure log
if: ${{ failure() }}
run: |
cat ./build/config.log
freebsd:
runs-on: macos-10.15 # until https://github.com/actions/runner/issues/385
steps:
- uses: actions/checkout@v2
- name: Test in FreeBSD VM
uses: vmactions/freebsd-vm@v0.1.5 # aka FreeBSD 13.0
with:
usesh: true
prepare: |
# Requested in ci/build-freebsd.sh
pkg install -y \
evdev-proto \
ffmpeg \
libplacebo \
libxkbcommon \
luajit \
openal-soft \
pkgconf \
python3 \
sdl2 \
vulkan-headers \
wayland-protocols \
#
# Optionally auto-enabled
pkg install -y \
alsa-lib \
jackit \
libXv \
libarchive \
libbluray \
libcaca \
libcdio-paranoia \
libdvdnav \
mujs \
pulseaudio \
rubberband \
sekrit-twc-zimg \
uchardet \
v4l_compat \
#
run: |
./ci/build-freebsd.sh
-177
View File
@@ -1,177 +0,0 @@
language: c
_macbase:
- &mac
os: osx
compiler: clang
env:
- HOMEBREW_NO_AUTO_UPDATE=1
- HOMEBREW_NO_INSTALL_CLEANUP=1
before_cache:
- brew cleanup -s
cache:
directories:
- $HOME/Library/Caches/Homebrew
- /usr/local/Homebrew
_mingwbase:
- &mingw
os: linux
addons:
apt:
packages:
- 'autoconf'
- 'automake'
- 'pkg-config'
- 'gcc-mingw-w64'
- 'gcc-multilib'
- 'nasm'
- 'yasm'
cache:
directories:
- mingw_prefix/
matrix:
include:
- <<: *mac
osx_image: xcode11.6
- <<: *mac
osx_image: xcode10.1
- <<: *mac
osx_image: xcode9.2
env:
- HOMEBREW_NO_AUTO_UPDATE=1
- HOMEBREW_NO_INSTALL_CLEANUP=1
- CI_SWIFT_FLAGS="\-target x86_64-apple-macosx10.12"
- os: freebsd
compiler: clang
- os: linux
compiler: gcc
env: CONTAINER=registry.cirno.systems/kiwi/containers/mpv-ci:stable-deps CI_SCRIPT=ci/build-tumbleweed.sh
- os: linux
compiler: clang
env: CONTAINER=registry.cirno.systems/kiwi/containers/mpv-ci:stable-deps CI_SCRIPT=ci/build-tumbleweed.sh
- <<: *mingw
env: CI_SCRIPT=ci/build-mingw64.sh TARGET=i686-w64-mingw32
- <<: *mingw
env: CI_SCRIPT=ci/build-mingw64.sh TARGET=x86_64-w64-mingw32
allow_failures:
- os: osx
osx_image: xcode9.2
fast_finish: true
dist: focal
services:
- docker
env:
global:
# Coverity token
- secure: "H21mSRlMhk4BKS0xHZvCFGJxteCP0hRVUxTuNfM2Z9HBsyutuLEYMtViLO86VtM+Tqla3xXPzUdS4ozLwI72Ax/5ZUDXACROj73yW6QhFB5D6rLut12+FjqC7M33Qv2hl0xwgNBmR5dsm1ToP37+Wn+ecJQNvN8fkTXF+HVzOEw="
# Travis token for mpv.io
- secure: "nlTVLJK6kRhtXvhKCoJ3YdFGHuKaq/eHowfPw25hqRWuBOZd+HjHY5KIYjV7SxuKFDpJE4GpNcvA3Q31nsqomxpkLYgrwjg6TSazN7ZP+x85ZgV1QGFebrPfGm2n5UR5CAPAwFoeF3pZheLi4bajVzwq1fWW+x3grS188P9OZso="
branches:
only:
- master
- ci
- coverity_scan
- /release\/.*$/
before_install:
- if [ "$TRAVIS_COMPILER" = "clang" ]; then export CXX="clang++"; fi
- if [ "$TRAVIS_COMPILER" = "gcc" ]; then export CXX="g++"; fi
- if [ -n "$CONTAINER" ]; then docker pull $CONTAINER; fi
- |
if [ "$TRAVIS_OS_NAME" = "freebsd" ]; then
# Requested in ci/build-freebsd.sh
sudo pkg install -y \
evdev-proto \
ffmpeg \
libplacebo \
libxkbcommon \
luajit \
openal-soft \
pkgconf \
python3 \
sdl2 \
vulkan-headers \
wayland-protocols \
$NULL
# Optionally auto-enabled
sudo pkg install -y \
alsa-lib \
jackit \
libXv \
libarchive \
libbluray \
libcaca \
libcdio-paranoia \
libdvdnav \
mujs \
pulseaudio \
rubberband \
sekrit-twc-zimg \
uchardet \
v4l_compat \
$NULL
fi
- |
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
remove=$(brew list)
keep="gettext pcre2 git"
install="autoconf automake pkg-config libtool python freetype fribidi little-cms2 luajit libass ffmpeg"
for formula in ${keep[@]}; do remove=("${remove[@]/$formula}"); done
for formula in ${install[@]}; do remove=("${remove[@]/$formula}"); done
brew remove --force $remove --ignore-dependencies
if [[ "$TRAVIS_OSX_IMAGE" == "xcode9.2" ]]; then
brew untap caskroom/cask
fi
brew update
if [[ "$TRAVIS_OSX_IMAGE" == "xcode9.2" ]]; then
pushd "/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core"
git checkout --force 55e02323812604add9a69bab8730319b9255a697
fi
brew install $install
brew link --overwrite python
if [[ "$TRAVIS_OSX_IMAGE" == "xcode9.2" ]]; then
git checkout master
popd
fi
fi
script:
- ./bootstrap.py
- |
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ -n "$CONTAINER" ]; then
docker run --env CC --env TARGET -v $TRAVIS_BUILD_DIR:/build $CONTAINER /bin/sh -c "cd /build && $CI_SCRIPT"
else
$CI_SCRIPT
fi
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./ci/build-macos.sh; fi
- if [ "$TRAVIS_OS_NAME" = "freebsd" ]; then ./ci/build-freebsd.sh; fi
after_failure: cat ./build/config.log
after_script: TOOLS/travis-rebuild-website
notifications:
email: false
irc:
if: fork = false
channels:
- "irc.freenode.org#mpv-devel"
on_success: change
on_failure: always
addons:
coverity_scan:
project:
name: "mpv-player/mpv"
description: "Build submitted via Travis CI"
notification_email: mpv-team@googlegroups.com
build_command_prepend: "./bootstrap.py && ./waf configure"
build_command: "./waf build"
branch_pattern: coverity_scan
+2 -2
View File
@@ -22,7 +22,7 @@ When cross-compiling, you have to run mpv's configure with these arguments:
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
```
[MXE](http://mxe.cc) makes it very easy to bootstrap a complete MingGW-w64
[MXE](https://mxe.cc) makes it very easy to bootstrap a complete MingGW-w64
environment from a Linux machine. See a working example below.
Alternatively, you can try [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake),
@@ -38,7 +38,7 @@ Example with MXE
#
# Refer to
#
# http://mxe.cc/#requirements
# https://mxe.cc/#requirements
#
# Scroll down for disto/OS-specific instructions to install them.
+6 -1
View File
@@ -5,7 +5,7 @@ General
-------
The main contact for mpv development is IRC, specifically #mpv
and #mpv-devel on Freenode. Github is used for code review and
and #mpv-devel on Libera.chat. Github is used for code review and
long term discussions.
Sending patches
@@ -68,6 +68,11 @@ Write good commit messages
Having a prefix gives context, and is especially useful when trying to find
a specific change by looking at the history, or when running ``git blame``.
Sample prefixes: ``vo_gpu: ...``, ``command: ...``, ``DOCS/input: ...``,
``TOOLS/osxbundle: ...``, ``osc.lua: ...``, etc. You can always check the git
log for commits which modify specific files to see which prefixes are used.
- The first word after the ``:`` is lower case.
- Don't end the subject line with a ``.``.
- Put an empty line between the subject line and the commit message.
+20
View File
@@ -239,6 +239,26 @@ title. The subtitle stream will use ``ducks`` as title.
The ``track_meta`` header is not part of the core EDL format. It may be changed
or removed at any time, depending on mpv's internal requirements.
Global metadata
===============
The special ``global_tags`` header can set metadata fields (aka tags) of the EDL
file. This metadata is supposed to be informational, much like for example ID3
tags in audio files. Due to lack of separation of different kinds of metadata it
is unspecified what names are allowed, how they are interpreted, and whether
some of them affect playback functionally. (Much of this is unfortunately
inherited from FFmpeg. Another consequence of this is that FFmpeg "normalized"
tags are recognized, or stuff like replaygain tags.)
Example::
!global_tags,title=bla,something_arbitrary=even_more_arbitrary
Any parameter names are allowed. Repeated use of this adds to the tag list. If
``!new_stream`` is used, the location doesn't matter.
May possibly be ignored in some cases, such as delayed media opening.
Delayed media opening
=====================
+24
View File
@@ -26,6 +26,30 @@ Interface changes
::
--- mpv 0.34.0 ---
- deprecate selecting by card number with `--drm-connector`, add
`--drm-device` which can be used instead
- add `--screen-name` and `--fs-screen-name` flags to allow selecting the
screen by its name instead of the index
- add `--macos-geometry-calculation` to change the rectangle used for screen
position and size calculation. the old behavior used the whole screen,
which didn't take the menu bar and Dock into account. The new default
behaviour includes both. To revert to the old behavior set this to
`whole`.
- add an additional optional `albumart` argument to the `video-add` command,
which tells mpv to load the given video as album art.
- undeprecate `--cache-secs` option
- remove `--icc-contrast` and introduce `--icc-force-contrast`. The latter
defaults to the equivalent of the old `--icc-contrast=inf`, and can
instead be used to specifically set the contrast to any value.
- add a `--watch-later-options` option to allow configuring which
options quit-watch-later saves
- make `current-window-scale` writeable and use it in the default input.conf
- add `--input-builtin-bindings` flag to control loading of built-in key
bindings during start-up (default: yes).
- add ``track-list/N/image`` sub-property
- remove `--opengl-restrict` option
- js custom-init: use filename ~~/init.js instead of ~~/.init.js (dot)
--- mpv 0.33.0 ---
- add `--d3d11-exclusive-fs` flag to enable D3D11 exclusive fullscreen mode
when the player enters fullscreen.
+1 -1
View File
@@ -198,7 +198,7 @@ Available filters are:
for each option. The options are not documented here, because they are
merely passed to librubberband. Look at the librubberband documentation
to learn what each option does:
http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
https://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
(The mapping of the mpv rubberband filter sub-option names and values to
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
+8 -5
View File
@@ -14,7 +14,7 @@ in the list.
See ``--ao=help`` for a list of compiled-in audio output drivers. The
driver ``--ao=alsa`` is preferred. ``--ao=pulse`` is preferred on systems
where PulseAudio is used.
where PulseAudio is used. On BSD systems, ``--ao=oss`` is preferred.
Available audio output drivers are:
@@ -35,6 +35,9 @@ Available audio output drivers are:
with automatic upmixing with shared access, so playing stereo
and multichannel audio at the same time will work as expected.
``oss``
OSS audio output driver
``jack``
JACK (Jack Audio Connection Kit) audio output driver.
@@ -65,8 +68,8 @@ Available audio output drivers are:
mode is probably not very useful, other than for debugging or when used
with fixed setups.
``coreaudio`` (Mac OS X only)
Native Mac OS X audio output driver using AudioUnits and the CoreAudio
``coreaudio`` (macOS only)
Native macOS audio output driver using AudioUnits and the CoreAudio
sound server.
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
@@ -92,8 +95,8 @@ Available audio output drivers are:
extreme care.
``coreaudio_exclusive`` (Mac OS X only)
Native Mac OS X audio output driver using direct device access and
``coreaudio_exclusive`` (macOS only)
Native macOS audio output driver using direct device access and
exclusive mode (bypasses the sound server).
``openal``
+55 -23
View File
@@ -14,51 +14,83 @@ Keybindings
ESC
Hide the console.
ENTER
ENTER, Ctrl+J and Ctrl+M
Run the typed command.
Shift+ENTER
Type a literal newline character.
Ctrl+LEFT and Ctrl+RIGHT
Move cursor to previous/next word.
LEFT and Ctrl+B
Move the cursor to the previous character.
UP and DOWN
Navigate command history.
RIGHT and Ctrl+F
Move the cursor to the next character.
Ctrl+LEFT and Alt+B
Move the cursor to the beginning of the current word, or if between words,
to the beginning of the previous word.
Ctrl+RIGHT and Alt+F
Move the cursor to the end of the current word, or if between words, to the
end of the next word.
HOME and Ctrl+A
Move the cursor to the start of the current line.
END and Ctrl+E
Move the cursor to the end of the current line.
BACKSPACE and Ctrl+H
Delete the previous character.
Ctrl+D
Hide the console if the current line is empty, otherwise delete the next
character.
Ctrl+BACKSPACE and Ctrl+W
Delete text from the cursor to the beginning of the current word, or if
between words, to the beginning of the previous word.
Ctrl+DEL and Alt+D
Delete text from the cursor to the end of the current word, or if between
words, to the end of the next word.
Ctrl+U
Delete text from the cursor to the beginning of the current line.
Ctrl+K
Delete text from the cursor to the end of the current line.
Ctrl+C
Clear the current line.
UP and Ctrl+P
Move back in the command history.
DOWN and Ctrl+N
Move forward in the command history.
PGUP
Go to the first command in the history.
PGDN
Stop navigating command history.
Stop navigating the command history.
INSERT
Toggle insert mode.
Ctrl+V
Paste text (uses the clipboard on X11 and Wayland).
Shift+INSERT
Paste text (uses the primary selection on X11).
Paste text (uses the primary selection on X11 and Wayland).
TAB
TAB and Ctrl+I
Complete the command or property name at the cursor.
Ctrl+C
Clear current line.
Ctrl+K
Delete text from the cursor to the end of the line.
Ctrl+L
Clear all log messages from the console.
Ctrl+U
Delete text from the cursor to the beginning of the line.
Ctrl+V
Paste text (uses the clipboard on X11).
Ctrl+W
Delete text from the cursor to the beginning of the current word.
Commands
--------
+143 -49
View File
@@ -62,8 +62,8 @@ character), or a symbolic name (as printed by ``--input-keylist``).
command.
``<command>`` is the command itself. It consists of the command name and
multiple (or none) commands, all separated by whitespace. String arguments
need to be quoted with ``"``. Details see ``Flat command syntax``.
multiple (or none) arguments, all separated by whitespace. String arguments
should be quoted, typically with ``"``. See ``Flat command syntax``.
You can bind multiple commands to one key. For example:
@@ -97,6 +97,12 @@ All key names can be combined with the modifiers ``Shift``, ``Ctrl``, ``Alt``,
``Meta``. They must be prefixed to the actual key name, where each modifier
is followed by a ``+`` (for example ``ctrl+q``).
The ``Shift`` modifier requires some attention. For instance ``Shift+2`` should
usually be specified as key-name ``@`` at ``input.conf``, and similarly the
combination ``Alt+Shift+2`` is usually ``Alt+@``, etc. Special key names like
``Shift+LEFT`` work as expected. If in doubt - use ``--input-test`` to check
how a key/combination is seen by mpv.
Symbolic key names and modifier names are case-insensitive. Unicode key names
are case-sensitive because input bindings typically respect the shift key.
@@ -162,18 +168,36 @@ a number of other places.
|
| ``<command> ::= [<prefixes>] <command_name> (<argument>)*``
| ``<argument> ::= (<string> | " <quoted_string> ")``
| ``<argument> ::= (<unquoted> | " <double_quoted> " | ' <single_quoted> ' | `X <custom_quoted> X`)``
``command_name`` is an unquoted string with the command name itself. See
`List of Input Commands`_ for a list.
Arguments are separated by whitespace. This applies even to string arguments.
For this reason, string arguments should be quoted with ``"``. If a string
argument contains spaces or certain special characters, quoting and possibly
escaping is mandatory, or the command cannot be parsed correctly.
Arguments are separated by whitespaces even if the command expects only one
argument. Arguments with whitespaces or other special characters must be quoted,
or the command cannot be parsed correctly.
Inside quotes, C-style escaping can be used. JSON escapes according to RFC 8259,
minus surrogate pair escapes, should be a safe subset that can be used.
Double quotes interpret JSON/C-style escaping, like ``\t`` or ``\"`` or ``\\``.
JSON escapes according to RFC 8259, minus surrogate pair escapes. This is the
only form which allows newlines at the value - as ``\n``.
Single quotes take the content literally, and cannot include the single-quote
character at the value.
Custom quotes also take the content literally, but are more flexible than single
quotes. They start with ````` (back-quote) followed by any ASCII character,
and end at the first occurance of the same pair in reverse order, e.g.
```-foo-``` or ````bar````. The final pair sequence is not allowed at the
value - in these examples ``-``` and `````` respectively. In the second
example the last character of the value also can't be a back-quote.
Mixed quoting at the same argument, like ``'foo'"bar"``, is not supported.
Note that argument parsing and property expansion happen at different stages.
First, arguments are determined as described above, and then, where applicable,
properties are expanded - regardless of argument quoting. However, expansion
can still be prevented with the ``raw`` prefix or ``$>``. See `Input Command
Prefixes`_ and `Property Expansion`_.
Commands specified as arrays
----------------------------
@@ -196,6 +220,9 @@ quotes and escaping. The array command APIs mentioned above pass strings
directly to the argument parsers, or can sidestep them by the ability to pass
non-string values.
Property expansion is disabled by default for these APIs. This can be changed
with the ``expand-properties`` prefix. See `Input Command Prefixes`_.
Sometimes commands have string arguments, that in turn are actually parsed by
other components (e.g. filter strings with ``vf add``) - in these cases, you
you would have to double-escape in input.conf, but not with the array APIs.
@@ -222,6 +249,9 @@ to use APIs that pass arguments as arrays.
Named arguments are not supported in the "flat" input.conf syntax, which means
you cannot use them for key bindings in input.conf at all.
Property expansion is disabled by default for these APIs. This can be changed
with the ``expand-properties`` prefix. See `Input Command Prefixes`_.
List of Input Commands
----------------------
@@ -314,6 +344,10 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
the minimum, on underflow set it to the maximum. If ``up`` or ``down`` is
omitted, assume ``up``.
Whether or not key-repeat is enabled by default depends on the property.
Currently properties with continuous values are repeatable by default (like
``volume``), while discrete values are not (like ``osd-level``).
``multiply <name> <value>``
Similar to ``add``, but multiplies the property or option with the numeric
value.
@@ -440,6 +474,10 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
Stop playback and replace the internal playlist with the new one.
<append>
Append the new playlist at the end of the current internal playlist.
<append-play>
Append the new playlist, and if nothing is currently playing, start
playback. (Always starts with the new playlist, even if the internal
playlist was not empty before running this command.)
``playlist-clear``
Clear the playlist, except the currently played file.
@@ -507,9 +545,9 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
argument list.
The first array entry is either an absolute path to the executable, or
a filename with no path components, in which case the ``PATH``
environment variable. On Unix, this is equivalent to ``posix_spawnp``
and ``execvp`` behavior.
a filename with no path components, in which case the executable is
searched in the directories in the ``PATH`` environment variable. On
Unix, this is equivalent to ``posix_spawnp`` and ``execvp`` behavior.
``playback_only`` (``MPV_FORMAT_FLAG``)
Boolean indicating whether the process should be killed when playback
@@ -669,16 +707,30 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
This works by unloading and re-adding the subtitle track.
``sub-step <skip>``
``sub-step <skip> <flags>``
Change subtitle timing such, that the subtitle event after the next
``<skip>`` subtitle events is displayed. ``<skip>`` can be negative to step
backwards.
``sub-seek <skip>``
Secondary argument:
primary (default)
Steps through the primary subtitles.
secondary
Steps through the secondary subtitles.
``sub-seek <skip> <flags>``
Seek to the next (skip set to 1) or the previous (skip set to -1) subtitle.
This is similar to ``sub-step``, except that it seeks video and audio
instead of adjusting the subtitle delay.
Secondary argument:
primary (default)
Seeks through the primary subtitles.
secondary
Seeks through the secondary subtitles.
For embedded subtitles (like with Matroska), this works only with subtitle
events that have already been displayed, or are within a short prefetch
range.
@@ -791,8 +843,11 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
``audio-reload [<id>]``
Reload the given audio tracks. See ``sub-reload`` command.
``video-add <url> [<flags> [<title> [<lang>]]]``
Load the given video file. See ``sub-add`` command.
``video-add <url> [<flags> [<title> [<lang> [<albumart>]]]]``
Load the given video file. See ``sub-add`` command for common options.
``albumart`` (``MPV_FORMAT_FLAG``)
If enabled, mpv will load the given video as album art.
``video-remove [<id>]``
Remove the given video track. See ``sub-remove`` command.
@@ -801,9 +856,9 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
Reload the given video tracks. See ``sub-reload`` command.
``rescan-external-files [<mode>]``
Rescan external files according to the current ``--sub-auto`` and
``--audio-file-auto`` settings. This can be used to auto-load external
files *after* the file was loaded.
Rescan external files according to the current ``--sub-auto``,
``--audio-file-auto`` and ``--cover-art-auto`` settings. This can be used
to auto-load external files *after* the file was loaded.
The ``mode`` argument is one of the following:
@@ -881,7 +936,7 @@ Input Commands that are Possibly Subject to Change
.. admonition:: Example for input.conf
- ``a vf set flip`` turn video upside-down on the ``a`` key
- ``a vf set vflip`` turn the video upside-down on the ``a`` key
- ``b vf set ""`` remove all video filters on ``b``
- ``c vf toggle gradfun`` toggle debanding on ``c``
@@ -1161,7 +1216,8 @@ Input Commands that are Possibly Subject to Change
``script-message-to <target> [<arg1> [<arg2> [...]]]``
Same as ``script-message``, but send it only to the client named
``<target>``. Each client (scripts etc.) has a unique name. For example,
Lua scripts can get their name via ``mp.get_script_name()``.
Lua scripts can get their name via ``mp.get_script_name()``. Note that
client names only consist of alphanumeric characters and ``_``.
This command has a variable number of arguments, and cannot be used with
named arguments.
@@ -1173,7 +1229,8 @@ Input Commands that are Possibly Subject to Change
The argument is the name of the binding.
It can optionally be prefixed with the name of the script, using ``/`` as
separator, e.g. ``script-binding scriptname/bindingname``.
separator, e.g. ``script-binding scriptname/bindingname``. Note that script
names only consist of alphanumeric characters and ``_``.
For completeness, here is how this command works internally. The details
could change any time. On any matching key event, ``script-message-to``
@@ -1649,7 +1706,9 @@ prefixes can be specified. They are separated by whitespace.
This is the default for ``input.conf`` commands.
``repeatable``
For some commands, keeping a key pressed doesn't run the command repeatedly.
This prefix forces enabling key repeat in any case.
This prefix forces enabling key repeat in any case. For a list of commands:
the first command determines the repeatability of the whole list (up to and
including version 0.33 - a list was always repeatable).
``async``
Allow asynchronous execution (if possible). Note that only a few commands
will support this (usually this is explicitly documented). Some commands
@@ -1806,6 +1865,9 @@ Property list
.. note:: This is only an estimate. (It's computed from two unreliable
quantities: fps and possibly rounded timestamps.)
``pid``
Process-id of mpv.
``path``
Full path of the currently played file. Usually this is exactly the same
string you pass on the mpv command line or the ``loadfile`` command, even
@@ -2469,6 +2531,15 @@ Property list
(or to be exact, the size the video filters output). ``2`` will set the
double size, ``0.5`` halves the size.
Note that setting a value identical to its previous value will not resize
the window. That's because this property mirrors the ``window-scale``
option, and setting an option to its previous value is ignored. If this
value is set while the window is in a fullscreen, the multiplier is not
applied until the window is taken out of that state. Writing this property
to a maximized window can unmaximize the window depending on the OS and
window manager. If the window does not unmaximize, the multiplier will be
applied if the user unmaximizes the window later.
See ``current-window-scale`` for the value derived from the actual window
size.
@@ -2477,15 +2548,21 @@ Property list
Before mpv 0.31.0, this returned what ``current-window-scale`` returns now,
after the window was created.
``current-window-scale``
``current-window-scale`` (RW)
The ``window-scale`` value calculated from the current window size. This
has the same value as ``window-scale`` if the window size was not changed
since setting the option, and the window size was not restricted in other
ways. The property is unavailable if no video is active.
ways. If the window is fullscreened, this will return the scale value
calculated from the last non-fullscreen size of the window. The property
is unavailable if no video is active.
When setting this property in the fullscreen or maximized state, the behavior
is the same as window-scale. In all ther cases, setting the value of this
property will always resize the window. This does not affect the value of
``window-scale``.
``focused``
Whether the window has focus. Currently works only on X11, Wayland and
macOS.
Whether the window has focus. Might not be supported by all VOs.
``display-names``
Names of the displays that the mpv window covers. On X11, these
@@ -2516,6 +2593,11 @@ Property list
``vsync-jitter``
Estimated deviation factor of the vsync duration.
``display-width``, ``display-height``
The current display's horizontal and vertical resolution in pixels. Whether
or not these values update as the mpv window changes displays depends on
the windowing backend. It may not be available on all platforms.
``display-hidpi-scale``
The HiDPI scale factor as reported by the windowing backend. If no VO is
active, or if the VO does not report a value, this property is unavailable.
@@ -2531,8 +2613,8 @@ Property list
``osd-width``, ``osd-height``
Last known OSD width (can be 0). This is needed if you want to use the
``overlay-add`` command. It gives you the actual OSD size, which can be
different from the window size in some cases.
``overlay-add`` command. It gives you the actual OSD/window size (not
including decorations drawn by the OS window manager).
Alias to ``osd-dimensions/w`` and ``osd-dimensions/h``.
@@ -2602,17 +2684,26 @@ Property list
This property is experimental and might be removed in the future.
``secondary-sub-text``
Same as ``sub-text``, but for the secondary subtitles.
``sub-start``
The current subtitle start time (in seconds). If there's multiple current
subtitles, returns the first start time. If no current subtitle is present
null is returned instead.
``secondary-sub-start``
Same as ``sub-start``, but for the secondary subtitles.
``sub-end``
The current subtitle end time (in seconds). If there's multiple current
subtitles, return the last end time. If no current subtitle is present, or
if it's present but has unknown or incorrect duration, null is returned
instead.
``secondary-sub-end``
Same as ``sub-end``, but for the secondary subtitles.
``playlist-pos`` (RW)
Current position on playlist. The first entry is on position 0. Writing to
this property may start playback at the new position.
@@ -2747,10 +2838,15 @@ Property list
``track-list/N/lang``
Track language as identified by the file. Not always available.
``track-list/N/albumart``
``track-list/N/image``
``yes``/true if this is a video track that consists of a single
picture, ``no``/false or unavailable otherwise. This is used for video
tracks that are really attached pictures in audio files.
picture, ``no``/false or unavailable otherwise. The heuristic used to
determine if a stream is an image doesn't attempt to detect images in
codecs normally used for videos. Otherwise, it is reliable.
``track-list/N/albumart``
``yes``/true if this is an image embedded in an audio file or external
cover art, ``no``/false or unavailable otherwise.
``track-list/N/default``
``yes``/true if the track has the default flag set in the file,
@@ -2844,6 +2940,7 @@ Property list
"src-id" MPV_FORMAT_INT64
"title" MPV_FORMAT_STRING
"lang" MPV_FORMAT_STRING
"image" MPV_FORMAT_FLAG
"albumart" MPV_FORMAT_FLAG
"default" MPV_FORMAT_FLAG
"forced" MPV_FORMAT_FLAG
@@ -2879,15 +2976,8 @@ Property list
For example, ``current-tracks/audio/lang`` returns the current audio track's
language field (the same value as ``track-list/N/lang``).
A sub-entry is accessible only if a track of that type is actually selected.
Tracks selected via ``--lavfi-complex`` never appear under this property.
``current-tracks`` and ``current-tracks/`` are currently not accessible, and
will not return anything.
Scripts etc. should not use this. They should use ``track-list``, loop over
all tracks, and inspect the ``selected`` field to test whether a track is
selected (or compare the ``id`` field to the ``video`` / ``audio`` etc.
options).
If tracks of the requested type are selected via ``--lavfi-complex``, the
first one is returned.
``chapter-list``
List of chapters, current entry marked. Currently, the raw property value
@@ -2971,13 +3061,14 @@ Property list
.. admonition:: Example
- ``--osd-status-msg='This is ${osd-ass-cc/0}{\\b1}bold text'``
- ``show-text "This is ${osd-ass-cc/0}{\b1}bold text"``
- ``--osd-msg3='This is ${osd-ass-cc/0}{\\b1}bold text'``
- ``show-text "This is ${osd-ass-cc/0}{\\b1}bold text"``
Any ASS override tags as understood by libass can be used.
Note that you need to escape the ``\`` character, because the string is
processed for C escape sequences before passing it to the OSD code.
processed for C escape sequences before passing it to the OSD code. See
`Flat command syntax`_ for details.
A list of tags can be found here: http://docs.aegisub.org/latest/ASS_Tags/
@@ -3353,7 +3444,7 @@ You can access (almost) all options as properties, though there are some
caveats with some properties (due to historical reasons):
``vid``, ``aid``, ``sid``
While playback is active, these result the actually active tracks. For
While playback is active, these return the actually active tracks. For
example, if you set ``aid=5``, and the currently played file contains no
audio track with ID 5, the ``aid`` property will return ``no``.
@@ -3371,8 +3462,8 @@ caveats with some properties (due to historical reasons):
the initial filter chain cannot be created.
This behavior changed in mpv 0.31.0. Before this, the new value was rejected
*iff* video (for ``vf``) or audio (for ``af``) was active. If playback was
not active, the behavior was the same as the current behavior.
*iff* a video (for ``vf``) or an audio (for ``af``) track was active. If
playback was not active, the behavior was the same as the current one.
``playlist``
The property is read-only and returns the current internal playlist. The
@@ -3401,8 +3492,11 @@ command is an exception and not a general rule.)
``i show-text "Filename: ${filename}"``
shows the filename of the current file when pressing the ``i`` key
Within ``input.conf``, property expansion can be inhibited by putting the
``raw`` prefix in front of commands.
Whether property expansion is enabled by default depends on which API is used
(see `Flat command syntax`_, `Commands specified as arrays`_ and `Named
arguments`_), but it can always be enabled with the ``expand-properties``
prefix or disabled with the ``raw`` prefix, as described in `Input Command
Prefixes`_.
The following expansions are supported:
+1 -1
View File
@@ -116,7 +116,7 @@ can also be present. See `List of events`_ for a list of all supported events.
Because events can occur at any time, it may be difficult at times to determine
which response goes with which command. Commands may optionally include a
``request_id`` which, if provided in the command request, will be copied
verbatim into the response. mpv does not intrepret the ``request_id`` in any
verbatim into the response. mpv does not interpret the ``request_id`` in any
way; it is solely for the use of the requester. The only requirement is that
the ``request_id`` field must be an integer (a number without fractional parts
in the range ``-2^63..2^63-1``). Using other types is deprecated and will
+19 -6
View File
@@ -58,7 +58,7 @@ Language features - ECMAScript 5
The scripting backend which mpv currently uses is MuJS - a compatible minimal
ES5 interpreter. As such, ``String.substring`` is implemented for instance,
while the common but non-standard ``String.substr`` is not. Please consult the
MuJS pages on language features and platform support - http://mujs.com .
MuJS pages on language features and platform support - https://mujs.com .
Unsupported Lua APIs and their JS alternatives
----------------------------------------------
@@ -179,7 +179,8 @@ success, ``fn`` is called always a-sync, ``error`` is empty string on success.
``mp.utils.readdir(path [, filter])`` (LE)
``mp.utils.file_info(path)`` (LE)
``mp.utils.file_info(path)`` (LE) Note: like lua - this does NOT expand
meta-paths like ``~~/foo`` (other JS file functions do expand meta paths).
``mp.utils.split_path(path)``
@@ -221,7 +222,8 @@ Additional utilities
``mp.utils.get_user_path(path)``
Expands (mpv) meta paths like ``~/x``, ``~~/y``, ``~~desktop/z`` etc.
``read_file``, ``write_file`` and ``require`` already use this internaly.
``read_file``, ``write_file``, ``append_file`` and ``require`` already use
this internally.
``mp.utils.read_file(fname [,max])``
Returns the content of file ``fname`` as string. If ``max`` is provided and
@@ -232,7 +234,12 @@ Additional utilities
prefixed with ``file://`` as simple protection against accidental arguments
switch, e.g. ``mp.utils.write_file("file://~/abc.txt", "hello world")``.
Note: ``read_file`` and ``write_file`` throw on errors, allow text content only.
``mp.utils.append_file(fname, str)``
Same as ``mp.utils.write_file`` if the file ``fname`` does not exist. If it
does exist then append instead of overwrite.
Note: ``read_file``, ``write_file`` and ``append_file`` throw on errors, allow
text content only.
``mp.get_time_ms()``
Same as ``mp.get_time()`` but in ms instead of seconds.
@@ -329,10 +336,16 @@ Custom initialization
---------------------
After mpv initializes the JavaScript environment for a script but before it
loads the script - it tries to run the file ``.init.js`` at the root of the mpv
loads the script - it tries to run the file ``init.js`` at the root of the mpv
configuration directory. Code at this file can update the environment further
for all scripts. E.g. if it contains ``mp.module_paths.push("/foo")`` then
``require`` at all scripts will search global module id's also at ``/foo``.
``require`` at all scripts will search global module id's also at ``/foo``
(do NOT do ``mp.module_paths = ["/foo"];`` because this will remove existing
paths - like ``<script-dir>/modules`` for scripts which load from a directory).
The custom-init file is ignored if mpv is invoked with ``--no-config``.
Before mpv 0.34, the file name was ``.init.js`` (with dot) at the same dir.
The event loop
--------------
+5 -5
View File
@@ -10,9 +10,9 @@ Since libmpv merely allows access to underlying mechanisms that can control
mpv, further documentation is spread over a few places:
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
- http://mpv.io/manual/master/#options
- http://mpv.io/manual/master/#list-of-input-commands
- http://mpv.io/manual/master/#properties
- https://mpv.io/manual/master/#options
- https://mpv.io/manual/master/#list-of-input-commands
- https://mpv.io/manual/master/#properties
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
C PLUGINS
@@ -21,8 +21,8 @@ C PLUGINS
You can write C plugins for mpv. These use the libmpv API, although they do not
use the libmpv library itself.
Currently, they must be explicitly enabled at build time with
``--enable-cplugins``. They are available on Linux/BSD platforms only.
They are available on Linux/BSD platforms only and enabled by default if the
compiler supports linking with the ``-rdynamic`` flag.
C plugins location
------------------
+12 -6
View File
@@ -37,6 +37,12 @@ scripting backend to use for it. For Lua, it is ``.lua``. If the extension is
not recognized, an error is printed. (If an error happens, the extension is
either mistyped, or the backend was not compiled into your mpv binary.)
mpv internally loads the script's name by stripping the ``.lua`` extension and
replacing all nonalphanumeric characters with ``_``. E.g., ``my-tools.lua``
becomes ``my_tools``. If there are several scripts with the same name, it is
made unique by appending a number. This is the name returned by
``mp.get_script_name()``.
Entries with ``.disable`` extension are always ignored.
If a script is a directory (either if a directory is passed to ``--script``,
@@ -474,7 +480,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
the timer callback function fn is run).
Note that these are methods, and you have to call them using ``:`` instead
of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
of ``.`` (Refer to https://www.lua.org/manual/5.2/manual.html#3.4.9 .)
Example:
@@ -500,11 +506,11 @@ The ``mp`` module is preloaded, although it can be loaded manually with
Return the name of the current script. The name is usually made of the
filename of the script, with directory and file extension removed. If
there are several scripts which would have the same name, it's made unique
by appending a number.
by appending a number. Any nonalphanumeric characters are replaced with ``_``.
.. admonition:: Example
The script ``/path/to/fooscript.lua`` becomes ``fooscript``.
The script ``/path/to/foo-script.lua`` becomes ``foo_script``.
``mp.get_script_directory()``
Return the directory if this is a script packaged as directory (see
@@ -618,7 +624,7 @@ are useful only in special situations.
``mp.get_osd_size()``
Returns a tuple of ``osd_width, osd_height, osd_par``. The first two give
the size of the OSD in pixels (for video ouputs like ``--vo=xv``, this may
the size of the OSD in pixels (for video outputs like ``--vo=xv``, this may
be "scaled" pixels). The third is the display pixel aspect ratio.
May return invalid/nonsense values if OSD is not initialized yet.
@@ -763,7 +769,7 @@ strictly part of the guaranteed API.
``mtime``
time of last modification
``ctime``
time of last metadata change (Linux) / time of creation (Windows)
time of last metadata change
``is_file``
Whether ``path`` is a regular file (boolean)
``is_dir``
@@ -775,7 +781,7 @@ strictly part of the guaranteed API.
The booleans ``is_file`` and ``is_dir`` are provided as a convenience;
they can be and are derived from ``mode``.
On error (eg. path does not exist), ``nil, error`` is returned.
On error (e.g. path does not exist), ``nil, error`` is returned.
``utils.split_path(path)``
Split a path into directory component and filename component, and return
+33 -20
View File
@@ -43,6 +43,9 @@ The following listings are not necessarily complete. See ``etc/input.conf`` for
a list of default bindings. User ``input.conf`` files and Lua scripts can
define additional key bindings.
See also ``--input-test`` for interactive binding details by key, and the
`stats`_ built-in script for key bindings list (including print to terminal).
Keyboard Control
----------------
@@ -227,7 +230,7 @@ i and I
`STATS`_ for more information.
del
Cycles visibility between never / auto (mouse-move) / always
Cycle OSC visibility between never / auto (mouse-move) / always
\`
Show the console. (ESC closes it again. See `CONSOLE`_.)
@@ -247,16 +250,16 @@ corresponding adjustment.)
7 and 8
Adjust saturation.
Alt+0 (and command+0 on OSX)
Alt+0 (and command+0 on macOS)
Resize video window to half its original size.
Alt+1 (and command+1 on OSX)
Alt+1 (and command+1 on macOS)
Resize video window to its original size.
Alt+2 (and command+2 on OSX)
Alt+2 (and command+2 on macOS)
Resize video window to double its original size.
command + f (OSX only)
command + f (macOS only)
Toggle fullscreen (see also ``--fs``).
(The following keys are valid if you have a keyboard with multimedia keys.)
@@ -390,6 +393,9 @@ It is started with ``%`` and has the following format::
``mpv --vf=foo:option1=%`expr length "$NAME"`%"$NAME" test.avi``
Note: where applicable with JSON-IPC, ``%n%`` is the length in UTF-8 bytes,
after decoding the JSON data.
Suboptions passed to the client API are also subject to escaping. Using
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
command line (but without shell processing of the string). Some options
@@ -427,23 +433,28 @@ need to escape special characters. To work this around, the path can be
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
(see above).
Some mpv options interpret paths starting with ``~``. Currently, the prefix
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
Some mpv options interpret paths starting with ``~``.
Currently, the prefix ``~~home/`` expands to the mpv configuration directory
(usually ``~/.config/mpv/``).
``~/`` expands to the user's home directory. (The trailing ``/`` is always
required.) The following paths are currently recognized:
================ ===============================================================
Name Meaning
================ ===============================================================
``~~/`` mpv config dir (for example ``~/.config/mpv/``)
``~~/`` If the subpath exists in any of the mpv's config directories
the path of the existing file/dir is returned. Otherwise this
is equivalent to ``~~home/``.
Note that if --no-config is used ``~~/foobar`` will resolve to
``foobar`` which can be unexpected.
``~/`` user home directory root (similar to shell, ``$HOME``)
``~~home/`` same as ``~~/``
``~~home/`` mpv config dir (for example ``~/.config/mpv/``)
``~~global/`` the global config path, if available (not on win32)
``~~osxbundle/`` the OSX bundle resource path (OSX only)
``~~desktop/`` the path to the desktop (win32, OSX)
``~~exe_dir`` win32 only: the path to the directory containing the exe (for
``~~osxbundle/`` the macOS bundle resource path (macOS only)
``~~desktop/`` the path to the desktop (win32, macOS)
``~~exe_dir/`` win32 only: the path to the directory containing the exe (for
config file purposes; ``$MPV_HOME`` overrides it)
``~~old_home`` do not use
``~~old_home/`` do not use
================ ===============================================================
@@ -511,7 +522,7 @@ They support the following operations:
============= ===============================================
Suffix Meaning
============= ===============================================
-set Set a list of items (using the list separator, interprets escapes)
-set Set a list of items (using the list separator, escaped with backslash)
-append Append single item (does not interpret escapes)
-add Append 1 or more items (same syntax as -set)
-pre Prepend 1 or more items (same syntax as -set)
@@ -781,9 +792,11 @@ ignored. This Lua code execution is not sandboxed.
Any variables in condition expressions can reference properties. If an
identifier is not already defined by Lua or mpv, it is interpreted as property.
For example, ``pause`` would return the current pause status. If the variable
name contains any ``_`` characters, they are turned into ``-``. For example,
``playback_time`` would return the property ``playback-time``.
For example, ``pause`` would return the current pause status. You cannot
reference properties with ``-`` this way since that would denote a subtraction,
but if the variable name contains any ``_`` characters, they are turned into
``-``. For example, ``playback_time`` would return the property
``playback-time``.
A more robust way to access properties is using ``p.property_name`` or
``get("property-name", default_value)``. The automatic variable to property
@@ -1001,7 +1014,7 @@ listed.
- ``AV:`` or ``V:`` (video only) or ``A:`` (audio only)
- The current time position in ``HH:MM:SS`` format (``playback-time`` property)
- The total file duration (absent if unknown) (``duration`` property)
- Playback speed, e.g. `` x2.0``. Only visible if the speed is not normal. This
- Playback speed, e.g. ``x2.0``. Only visible if the speed is not normal. This
is the user-requested speed, and not the actual speed (usually they should
be the same, unless playback is too slow). (``speed`` property.)
- Playback percentage, e.g. ``(13%)``. How much of the file has been played.
@@ -1260,7 +1273,7 @@ Currently this happens only in the following cases:
or file associations provided by desktop environments)
- if started from explorer.exe on Windows (technically, if it was started on
Windows, and all of the stdout/stderr/stdin handles are unset)
- started out of the bundle on OSX
- started out of the bundle on macOS
- if you manually use ``--player-operation-mode=pseudo-gui`` on the command line
This mode applies options from the builtin profile ``builtin-pseudo-gui``, but
@@ -1298,7 +1311,7 @@ Linux desktop issues
====================
This subsection describes common problems on the Linux desktop. None of these
problems exist on systems like Windows or OSX.
problems exist on systems like Windows or macOS.
Disabling Screensaver
---------------------
+242 -111
View File
@@ -56,7 +56,7 @@ Track Selection
behavior tends to change around with each mpv release.
The track selection properties will return the option value outside of
playback (as expected), but during playbac, the affective track
playback (as expected), but during playback, the affective track
selection is returned. For example, with ``--aid=auto``, the ``aid``
property will suddenly return ``2`` after playback initialization
(assuming the file has at least 2 audio tracks, and the second is the
@@ -213,7 +213,7 @@ Playback Control
Slow down or speed up playback by the factor given as parameter.
If ``--audio-pitch-correction`` (on by default) is used, playing with a
speed higher than normal automatically inserts the ``scaletempo`` audio
speed higher than normal automatically inserts the ``scaletempo2`` audio
filter.
``--pause``
@@ -392,6 +392,13 @@ Playback Control
difference between the two option is that this option performs a seek on
loop, instead of reloading the file.
.. note::
``--loop-file`` counts the number of times it causes the player to
seek to the beginning of the file, not the number of full playthroughs. This
means ``--loop-file=1`` will end up playing the file twice. Contrast with
``--loop-playlist``, which counts the number of full playthroughs.
``--loop`` is an alias for this option.
``--ab-loop-a=<time>``, ``--ab-loop-b=<time>``
@@ -844,6 +851,29 @@ Program Behavior
- ``--reset-on-next-file=all``
Try to reset all settings that were changed during playback.
``--watch-later-options=option1,option2,...``
The options that are saved in "watch later" files if they have been changed
since when mpv started. These values will be restored the next time the
files are played. The playback position is always saved as ``start``, so
adding ``start`` to this list has no effect.
When removing options, existing watch later data won't be modified and will
still be applied fully, but new watch later data won't contain these
options.
This is a string list option. See `List Options`_ for details.
.. admonition:: Examples
- ``--watch-later-options-remove=fullscreen``
The fullscreen state won't be saved to watch later files.
- ``--watch-later-options-remove=volume``
``--watch-later-options-remove=mute``
The volume and mute state won't be saved to watch later files.
- ``--watch-later-options-clr``
No option will be saved to watch later files except the starting
position.
``--write-filename-in-watch-later-config``
Prepend the watch later config files with the name of the file they refer
to. This is simply written as comment on the top of the file.
@@ -965,9 +995,11 @@ Program Behavior
no). It's disabled ("no") by default for performance reasons.
``ytdl_path=youtube-dl``
Configure path to youtube-dl executable or a compatible fork's.
The default "youtube-dl" looks for the executable in PATH. In a Windows
environment the suffix extension ".exe" is always appended.
Configure paths to youtube-dl's executable or a compatible fork's. The
paths should be separated by : on Unix and ; on Windows. mpv looks in
order for the configured paths in PATH and in mpv's config directory.
The defaults are "yt-dlp", "yt-dlp_x86" and "youtube-dl". On Windows
the suffix extension ".exe" is always appended.
.. admonition:: Why do the option names mix ``_`` and ``-``?
@@ -1196,9 +1228,9 @@ Video
:vdpau-copy: copies video back into system RAM (Linux with some GPUs only)
:vaapi: requires ``--vo=gpu`` or ``--vo=vaapi`` (Linux only)
:vaapi-copy: copies video back into system RAM (Linux with some GPUs only)
:videotoolbox: requires ``--vo=gpu`` (OS X 10.8 and up),
:videotoolbox: requires ``--vo=gpu`` (macOS 10.8 and up),
or ``--vo=libmpv`` (iOS 9.0 and up)
:videotoolbox-copy: copies video back into system RAM (OS X 10.8 or iOS 9.0 and up)
:videotoolbox-copy: copies video back into system RAM (macOS 10.8 or iOS 9.0 and up)
:dxva2: requires ``--vo=gpu`` with ``--gpu-context=d3d11``,
``--gpu-context=angle`` or ``--gpu-context=dxinterop``
(Windows only)
@@ -1477,11 +1509,14 @@ Video
This option is disabled if the ``--no-keepaspect`` option is used.
``--video-rotate=<0-359|no>``
Rotate the video clockwise, in degrees. Currently supports 90° steps only.
If ``no`` is given, the video is never rotated, even if the file has
rotation metadata. (The rotation value is added to the rotation metadata,
which means the value ``0`` would rotate the video according to the
rotation metadata.)
Rotate the video clockwise, in degrees. If ``no`` is given, the video is
never rotated, even if the file has rotation metadata. (The rotation value
is added to the rotation metadata, which means the value ``0`` would rotate
the video according to the rotation metadata.)
When using hardware decoding without copy-back, only 90° steps work, while
software decoding and hardware decoding methods that copy the video back to
system memory support all values between 0 and 359.
``--video-zoom=<value>``
Adjust the video display scale factor by the given value. The parameter is
@@ -1606,7 +1641,7 @@ Video
You can get the list of allowed codecs with ``mpv --vd=help``. Remove the
prefix, e.g. instead of ``lavc:h264`` use ``h264``.
By default, this is set to ``h264,vc1,hevc,vp9,av1``. Note that
By default, this is set to ``h264,vc1,hevc,vp8,vp9,av1``. Note that
the hardware acceleration special codecs like ``h264_vdpau`` are not
relevant anymore, and in fact have been removed from Libav in this form.
@@ -1739,7 +1774,7 @@ Audio
``--audio-pitch-correction=<yes|no>``
If this is enabled (default), playing with a speed different from normal
automatically inserts the ``scaletempo`` audio filter. For details, see
automatically inserts the ``scaletempo2`` audio filter. For details, see
audio filter section.
``--audio-device=<name>``
@@ -2003,14 +2038,17 @@ Audio
want. For example, most A/V receivers connected via HDMI and that can
do 7.1 would be served by: ``--audio-channels=7.1,5.1,stereo``
``--audio-display=<no|attachment>``
Setting this option to ``attachment`` (default) will display image
attachments (e.g. album cover art) when playing audio files. It will
display the first image found, and additional images are available as
video tracks.
``--audio-display=<no|embedded-first|external-first>``
Determines whether to display cover art when playing audio files and with
what priority. It will display the first image found, and additional images
are available as video tracks.
Setting this option to ``no`` disables display of video entirely when
playing audio files.
:no: Disable display of video entirely when playing audio
files.
:embedded-first: Display embedded images and external cover art, giving
priority to embedded images (default).
:external-first: Display embedded images and external cover art, giving
priority to external files.
This option has no influence on files with normal video tracks.
@@ -2091,7 +2129,7 @@ Audio
:no: Don't automatically load external audio files (default).
:exact: Load the media filename with audio file extension.
:fuzzy: Load all audio files containing media filename.
:fuzzy: Load all audio files containing the media filename.
:all: Load all audio files in the current and ``--audio-file-paths``
directories.
@@ -2471,7 +2509,7 @@ Subtitles
:no: Don't automatically load external subtitle files.
:exact: Load the media filename with subtitle file extension and possibly
language suffixes (default).
:fuzzy: Load all subs containing media filename.
:fuzzy: Load all subs containing the media filename.
:all: Load all subs in the current and ``--sub-file-paths`` directories.
``--sub-codepage=<codepage>``
@@ -2575,6 +2613,15 @@ Subtitles
Can be used to disable display of subtitles, but still select and decode
them.
``--secondary-sub-visibility``, ``--no-secondary-sub-visibility``
Can be used to disable display of secondary subtitles, but still select and
decode them.
.. note::
If ``--sub-visibility=no``, secondary subtitles are hidden regardless of
``--secondary-sub-visibility``.
``--sub-clear-on-seek``
(Obscure, rarely useful.) Can be used to play broken mkv files with
duplicate ReadOrder fields. ReadOrder is the first field in a
@@ -2587,6 +2634,13 @@ Subtitles
This works for ``dvb_teletext`` subtitle streams, and if FFmpeg has been
compiled with support for it.
``--sub-past-video-end``
After the last frame of video, if this option is enabled, subtitles will
continue to update based on audio timestamps. Otherwise, the subtitles
for the last video frame will stay onscreen.
Default: disabled
``--sub-font=<name>``
Specify font to use for subtitles that do not themselves
specify a particular font. The default is ``sans-serif``.
@@ -2752,7 +2806,7 @@ Subtitles
List items are matched in order. If a regular expression matches, the
process is stopped, and the subtitle line is discarded. The text matched
against is, currently, always the ``Text`` field of ASS events (if the
against is, by default, the ``Text`` field of ASS events (if the
subtitle format is different, it is always converted). This may include
formatting tags. Matching is case-insensitive, but how this is done depends
on the libc, and most likely works in ASCII only. It does not work on
@@ -2774,6 +2828,17 @@ Subtitles
include replacing the regexes with a very primitive and small subset of
sed, or some method to control case-sensitivity.
``--sub-filter-jsre-...=...``
Same as ``--sub-filter-regex`` but with JavaScript regular expressions.
Shares/affected-by all ``--sub-filter-regex-*`` control options (see below),
and also experimental. Requires only JavaScript support.
``--sub-filter-regex-plain=<yes|no>``
Whether to first convert the ASS "Text" field to plain-text (default: no).
This strips ASS tags and applies ASS directives, like ``\N`` to new-line.
If the result is multi-line then the regexp anchors ``^`` and ``$`` match
each line, but still any match discards all lines.
``--sub-filter-regex-warn=<yes|no>``
Log dropped lines with warning log level, instead of verbose (default: no).
Helpful for testing.
@@ -2799,7 +2864,7 @@ Subtitles
``--sub-font-provider=<auto|none|fontconfig>``
Which libass font provider backend to use (default: auto). ``auto`` will
attempt to use the native font provider: fontconfig on Linux, CoreText on
OSX, DirectWrite on Windows. ``fontconfig`` forces fontconfig, if libass
macOS, DirectWrite on Windows. ``fontconfig`` forces fontconfig, if libass
was built with support (if not, it behaves like ``none``).
The ``none`` font provider effectively disables system fonts. It will still
@@ -2839,6 +2904,12 @@ Window
See also ``--fs-screen``.
``--screen-name=<string>``
In multi-monitor configurations, this option tells mpv which screen to
display the video on based on the screen name from the video backend. The
same caveats in the ``--screen`` option also apply here. This option is
ignored and does nothing if ``--screen`` is explicitly set.
``--fullscreen``, ``--fs``
Fullscreen playback.
@@ -2853,12 +2924,18 @@ Window
This option works properly only with window managers which
understand the EWMH ``_NET_WM_FULLSCREEN_MONITORS`` hint.
.. admonition:: Note (OS X)
.. admonition:: Note (macOS)
``all`` does not work on OS X and will behave like ``current``.
``all`` does not work on macOS and will behave like ``current``.
See also ``--screen``.
``--fs-screen-name=<string>``
In multi-monitor configurations, this option tells mpv which screen to go
fullscreen to based on the screen name from the video backend. The same
caveats in the ``--fs-screen`` option also apply here. This option is
ignored and does nothing if ``--fs-screen`` is explicitly set.
``--keep-open=<yes|no|always>``
Do not terminate when playing or seeking beyond the end of the file, and
there is not next file to be played (and ``--loop`` is not used).
@@ -2956,7 +3033,7 @@ Window
Manager.
``--ontop-level=<window|system|desktop|level>``
(OS X only)
(macOS only)
Sets the level of an ontop window (default: window).
:window: On top of all other windows.
@@ -2973,14 +3050,8 @@ Window
Play video with window border and decorations. Since this is on by
default, use ``--no-border`` to disable the standard window decorations.
``--fit-border``, ``--no-fit-border``
(Windows only) Fit the whole window with border and decorations on the
screen. Since this is on by default, use ``--no-fit-border`` to make mpv
try to only fit client area with video on the screen. This behavior only
applied to window/video with size exceeding size of the screen.
``--on-all-workspaces``
(X11 only)
(X11 and macOS only)
Show the video window on all virtual desktops.
``--geometry=<[W[xH]][+-x+-y][/WS]>``, ``--geometry=<x:y>``
@@ -3006,9 +3077,9 @@ Window
Generally only supported by GUI VOs. Ignored for encoding.
.. admonition: Note (OS X)
.. admonition: Note (macOS)
On Mac OS X the origin of the screen coordinate system is located on the
On macOS, the origin of the screen coordinate system is located on the
bottom-left corner. For instance, ``0:0`` will place the window at the
bottom-left of the screen.
@@ -3176,14 +3247,14 @@ Window
- ``--monitoraspect=16:9`` or ``--monitoraspect=1.7777``
``--hidpi-window-scale``, ``--no-hidpi-window-scale``
(OS X, Windows, X11, and Wayland only)
(macOS, Windows, X11, and Wayland only)
Scale the window size according to the backing scale factor (default: yes).
On regular HiDPI resolutions the window opens with double the size but appears
as having the same size as on non-HiDPI resolutions. This is the default OS X
behavior.
as having the same size as on non-HiDPI resolutions. This is enabled by
default on macOS.
``--native-fs``, ``--no-native-fs``
(OS X only)
(macOS only)
Uses the native fullscreen mechanism of the OS (default: yes).
``--monitorpixelaspect=<ratio>``
@@ -3216,8 +3287,8 @@ Window
``intptr_t``. mpv will create its own window, and set the wid window as
parent, like with X11.
On OSX/Cocoa, the ID is interpreted as ``NSView*``. Pass it as value cast
to ``intptr_t``. mpv will create its own sub-view. Because OSX does not
On macOS/Cocoa, the ID is interpreted as ``NSView*``. Pass it as value cast
to ``intptr_t``. mpv will create its own sub-view. Because macOS does not
support window embedding of foreign processes, this works only with libmpv,
and will crash when used from the command line.
@@ -3699,15 +3770,17 @@ Demuxer
``--prefetch-playlist=<yes|no>``
Prefetch next playlist entry while playback of the current entry is ending
(default: no). This merely opens the URL of the next playlist entry as soon
as the current URL is fully read.
(default: no).
This does not prefill the cache with the video data of the next URL.
Prefetching video data is supported only for the current playlist entry,
and depends on the demuxer cache settings (on by default). This merely
opens the URL of the next playlist entry as soon the current URL is fully
read.
This does **not** work with URLs resolved by the ``youtube-dl`` wrapper,
and it won't.
This does not affect HLS (``.m3u8`` URLs) - HLS prefetching depends on the
demuxer cache settings and is on by default.
This can give subtly wrong results if per-file options are used, or if
options are changed in the time window between prefetching start and next
file played.
@@ -3764,7 +3837,15 @@ Input
configuration directory (usually ``~/.config/mpv/input.conf``).
``--no-input-default-bindings``
Disable mpv default (built-in) key bindings.
Disable default-level ("weak") key bindings. These are bindings which config
files like ``input.conf`` can override. It currently affects the builtin key
bindings, and keys which scripts bind using ``mp.add_key_binding`` (but not
``mp.add_forced_key_binding`` because this overrides ``input.conf``).
``--no-input-builtin-bindings``
Disable loading of built-in key bindings during start-up. This option is
applied only during (lib)mpv initialization, and if used then it will not
be not possible to enable them later. May be useful to libmpv clients.
``--input-cmdlist``
Prints all commands that can be bound to keys.
@@ -3852,8 +3933,15 @@ Input
Support depends on the VO in use.
``--input-media-keys=<yes|no>``
(OS X and Windows only)
Enable/disable media keys support. Enabled by default (except for libmpv).
On systems where mpv can choose between receiving media keys or letting
the system handle them - this option controls whether mpv should receive
them.
Default: yes (except for libmpv). macOS and Windows only, because elsewhere
mpv doesn't have a choice - the system decides whether to send media keys
to mpv. For instance, on X11 or Wayland, system-wide media keys are not
implemented. Whether media keys work when the mpv window is focused is
implementation-defined.
``--input-right-alt-gr``, ``--no-input-right-alt-gr``
(Cocoa and Windows only)
@@ -4555,12 +4643,6 @@ Cache
Turn off input stream caching. See ``--cache``.
``--cache-secs=<seconds>``
Deprecated. Once this option is removed, there will be no way to limit the
cache size by time (only by size with ``--demuxer-max-bytes``). This option
is considered useless, since there is no good reason to limit the cache by
time, and the default value of this option is already something very high.
The interaction with the other cache options is also confusing.
How many seconds of audio/video to prefetch if the cache is active. This
overrides the ``--demuxer-readahead-secs`` option if and only if the cache
is enabled and the value is larger. The default value is set to something
@@ -5159,18 +5241,29 @@ The following video options are currently all specific to ``--vo=gpu`` and
``--interpolation-threshold=<0..1,-1>``
Threshold below which frame ratio interpolation gets disabled (default:
``0.0001``). This is calculated as ``abs(disphz/vfps - 1) < threshold``,
``0.01``). This is calculated as ``abs(disphz/vfps - 1) < threshold``,
where ``vfps`` is the speed-adjusted video FPS, and ``disphz`` the
display refresh rate. (The speed-adjusted video FPS is roughly equal to
the normal video FPS, but with slowdown and speedup applied. This matters
if you use ``--video-sync=display-resample`` to make video run synchronously
to the display FPS, or if you change the ``speed`` property.)
The default is intended to almost always enable interpolation if the
playback rate is even slightly different from the display refresh rate. But
note that if you use e.g. ``--video-sync=display-vdrop``, small deviations
in the rate can disable interpolation and introduce a discontinuity every
other minute.
The default is intended to enable interpolation in scenarios where
retiming with the ``--video-sync=display-*`` cannot adjust the speed of
the video sufficiently for smooth playback. For example if a video is
60.00 FPS and your display refresh rate is 59.94 Hz, interpolation will
never be activated, since the mismatch is within 1% of the refresh
rate. The default also handles the scenario when mpv cannot determine the
container FPS, such as during certain live streams, and may dynamically
toggle interpolation on and off. In this scenario, the default would be to
not use interpolation but rather to allow ``--video-sync=display-*`` to
retime the video to match display refresh rate. See
``--video-sync-max-video-change`` for more information about how mpv
will retime video.
Also note that if you use e.g. ``--video-sync=display-vdrop``, small
deviations in the rate can disable interpolation and introduce a
discontinuity every other minute.
Set this to ``-1`` to disable this logic.
@@ -5263,6 +5356,12 @@ The following video options are currently all specific to ``--vo=gpu`` and
results, as can missing or incorrect display FPS information (see
``--override-display-fps``).
``--vulkan-device=<device name>``
The name of the Vulkan device to use for rendering and presentation. Use
``--vulkan-device=help`` to see the list of available devices and their
names. If left unspecified, the first enumerated hardware Vulkan device will
be used.
``--vulkan-swap-mode=<mode>``
Controls the presentation mode of the vulkan swapchain. This is similar
to the ``--opengl-swapinterval`` option.
@@ -5307,6 +5406,25 @@ The following video options are currently all specific to ``--vo=gpu`` and
with some older drivers / vulkan portability layers that don't provide
working VkEvent support.
``--vulkan-display-display=<n>``
The index of the display, on the selected Vulkan device, to present on when
using the ``displayvk`` GPU context. Use ``--vulkan-display-display=help``
to see the list of available displays. If left unspecified, the first
enumerated display will be used.
``--vulkan-display-mode=<n>``
The index of the display mode, of the selected Vulkan display, to use when
using the ``displayvk`` GPU context. Use ``--vulkan-display-mode=help``
to see the list of available modes. If left unspecified, the first
enumerated mode will be used.
``--vulkan-display-plane=<n>``
The index of the plane, on the selected Vulkan device, to present on when
using the ``displayvk`` GPU context. Use ``--vulkan-display-plane=help``
to see the list of available planes. If left unspecified, the first
enumerated plane will be used.
``--d3d11-exclusive-fs=<yes|no>``
Switches the D3D11 swap chain fullscreen state to 'fullscreen' when
fullscreen video is requested. Also known as "exclusive fullscreen" or
@@ -5388,8 +5506,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
Currently only relevant for ``--gpu-api=d3d11``.
``--wayland-app-id=<string>``
Set the client app id for Wayland-based video output methods. By default, "mpv"
is used.
Set the client app id for Wayland-based video output methods (default: ``mpv``).
``--wayland-disable-vsync=<yes|no>``
Disable vsync for the wayland contexts (default: no). Useful for benchmarking
@@ -5403,7 +5520,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
there are no server side decorations from the compositor.
``--wayland-edge-pixels-touch=<value>``
Defines the size of an edge border (default: 64) to initiate client side
Defines the size of an edge border (default: 32) to initiate client side
resizes events in the wayland contexts with touch events.
``--spirv-compiler=<compiler>``
@@ -5551,7 +5668,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
Specifies that this shader should be treated as a compute shader, with
the block size bw and bh. The compute shader will be dispatched with
however many blocks are necessary to completely tile over the output.
Within each block, there will bw tw*th threads, forming a single work
Within each block, there will be tw*th threads, forming a single work
group. In other words: tw and th specify the work group size, which can
be different from the block size. So for example, a compute shader with
bw, bh = 32 and tw, th = 8 running on a 500x500 texture would dispatch
@@ -5684,7 +5801,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
``--deband-threshold=<0..4096>``
The debanding filter's cut-off threshold. Higher numbers increase the
debanding strength dramatically but progressively diminish image details.
(Default 64)
(Default 32)
``--deband-range=<1..64>``
The debanding filter's initial radius. The radius increases linearly for
@@ -5794,7 +5911,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
Deactivates the automatic graphics switching and forces the dedicated GPU.
(default: no)
OS X only.
macOS only.
``--cocoa-cb-sw-renderer=<yes|no|auto>``
Use the Apple Software Renderer when using cocoa-cb (default: auto). If set
@@ -5803,14 +5920,14 @@ The following video options are currently all specific to ``--vo=gpu`` and
software renderer, and ``auto`` only falls back to the software renderer
when the usual pixel format couldn't be created.
OS X only.
macOS only.
``--cocoa-cb-10bit-context=<yes|no>``
Creates a 10bit capable pixel format for the context creation (default: yes).
Instead of 8bit integer framebuffer a 16bit half-float framebuffer is
requested.
OS X only.
macOS only.
``--macos-title-bar-appearance=<appearance>``
Sets the appearance of the title bar (default: auto). Not all combinations
@@ -5891,7 +6008,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
1000ms since it's possible that Apple or the user changes the system
defaults. Anything higher than 1000ms though seems too long and shouldn't be
set anyway.
OS X and cocoa-cb only
(macOS and cocoa-cb only)
``--macos-app-activation-policy=<regular|accessory|prohibited>``
@@ -5900,6 +6017,16 @@ The following video options are currently all specific to ``--vo=gpu`` and
macOS only.
``--macos-geometry-calculation=<visible|whole>``
This changes the rectangle which is used to calculate the screen position
and size of the window (default: visible). ``visible`` takes the the menu
bar and Dock into account and the window is only positioned/sized within the
visible screen frame rectangle, ``whole`` takes the whole screen frame
rectangle and ignores the menu bar and Dock. Other previous restrictions
still apply, like the window can't be placed on top of the menu bar etc.
macOS only.
``--android-surface-size=<WxH>``
Set dimensions of the rendering surface used by the Android gpu context.
Needs to be set by the embedding application if the dimensions change during
@@ -5918,7 +6045,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
auto
auto-select (default)
cocoa
Cocoa/OS X (deprecated, use --vo=libmpv instead)
Cocoa/macOS (deprecated, use --vo=libmpv instead)
win
Win32/WGL
winvk
@@ -5943,6 +6070,10 @@ The following video options are currently all specific to ``--vo=gpu`` and
VK_KHR_wayland_surface
drm
DRM/EGL
displayvk
VK_KHR_display. This backend is roughly the Vukan equivalent of
DRM/EGL, allowing for direct rendering via Vulkan without a display
manager.
x11egl
X11/EGL
android
@@ -5970,13 +6101,6 @@ The following video options are currently all specific to ``--vo=gpu`` and
no
Only allow desktop/core GL
``--opengl-restrict=<version>``
Restricts all OpenGL versions above a certain version. Versions are encoded
in hundreds, i.e. OpenGL 4.5 -> 450. As an example, --opengl-restrict=300
would restrict OpenGL 3.0 and higher, effectively only allowing 2.x
contexts. Note that this only imposes a limit on context creation APIs, the
actual OpenGL context may still have a higher OpenGL version. (Default: 0)
``--fbo-format=<fmt>``
Selects the internal format of textures used for FBOs. The format can
influence performance and quality of the video output. ``fmt`` can be one
@@ -6013,7 +6137,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
With ambient illuminance of 16 lux, mpv will pick the 1.0 gamma value (no
boost), and slightly increase the boost up until 1.2 for 256 lux.
NOTE: Only implemented on OS X.
NOTE: Only implemented on macOS.
``--target-prim=<value>``
Specifies the primaries of the display. Video colors will be adapted to
@@ -6322,14 +6446,15 @@ The following video options are currently all specific to ``--vo=gpu`` and
Size of the 3D LUT generated from the ICC profile in each dimension.
Default is 64x64x64. Sizes may range from 2 to 512.
``--icc-contrast=<0-1000000|inf>``
Specifies an upper limit on the target device's contrast ratio. This is
detected automatically from the profile if possible, but for some profiles
it might be missing, causing the contrast to be assumed as infinite. As a
result, video may appear darker than intended. This only affects BT.1886
content. The default of 0 means no limit if the detected contrast is less
than 100000, and limits to 1000 otherwise. Use ``--icc-contrast=inf`` to
preserve the infinite contrast (most likely when using OLED displays).
``--icc-force-contrast=<no|0-1000000|inf>``
Override the target device's detected contrast ratio by a specific value.
This is detected automatically from the profile if possible, but for some
profiles it might be missing, causing the contrast to be assumed as
infinite. As a result, video may appear darker than intended. If this is
the case, setting this option might help. This only affects BT.1886
content. The default of ``no`` means to use the profile values. The special
value ``inf`` causes the BT.1886 curve to be treated as a pure power gamma
2.4 function.
``--blend-subtitles=<yes|video|no>``
Blend subtitles directly onto upscaled video frames, before interpolation
@@ -6362,13 +6487,13 @@ The following video options are currently all specific to ``--vo=gpu`` and
black).
yes
Try to create a framebuffer with alpha component. This only makes sense
if the video contains alpha information (which is extremely rare). May
not be supported on all platforms. If alpha framebuffers are
unavailable, it silently falls back on a normal framebuffer. Note that
if you set the ``--fbo-format`` option to a non-default value, a
format with alpha must be specified, or this won't work.
Whether this really works depends on the windowing system and desktop
environment.
if the video contains alpha information (which is extremely rare) or if
you make the background color transparent. May not be supported on all
platforms. If alpha framebuffers are unavailable, it silently falls
back on a normal framebuffer. Note that if you set the ``--fbo-format``
option to a non-default value, a format with alpha must be specified,
or this won't work. Whether this really works depends on the windowing
system and desktop environment.
no
Ignore alpha component.
@@ -6395,7 +6520,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
flipping GL front and backbuffers immediately (i.e. it doesn't call it
in display-sync mode).
On OSX this is always deactivated because it only causes performance
On macOS this is always deactivated because it only causes performance
problems and other regressions.
``--gpu-dumb-mode=<yes|no|auto>``
@@ -6530,11 +6655,10 @@ Miscellaneous
video. (Although it should have the same effects as
``audio``, the implementation is very different.)
:display-adrop: Drop or repeat audio data to compensate desyncing
video. See ``--video-sync-adrop-size``. This mode will
cause severe audio artifacts if the real monitor
refresh rate is too different from the reported or
forced rate. Since mpv 0.33.0, this acts on entire audio
frames, instead of single samples.
video. This mode will cause severe audio artifacts if
the real monitor refresh rate is too different from
the reported or forced rate. Since mpv 0.33.0, this
acts on entire audio frames, instead of single samples.
:display-desync: Sync video to display, and let audio play on its own.
:desync: Sync video according to system clock, and let audio play
on its own.
@@ -6547,6 +6671,9 @@ Miscellaneous
multiple of the display FPS, as long as the speed change does not exceed
the value set by ``--video-sync-max-video-change``.
See ``--interpolation-threshold`` for how this option affects
interpolation.
This is mostly for testing, and the option may be randomly changed in the
future without notice.
@@ -6654,13 +6781,16 @@ Miscellaneous
CLI/config file only alias for ``--cover-art-files-append``. Each use of this
option will add a new external file.
``--cover-art-auto=<no|fuzzy>``
Whether to load _external_ cover art automatically (default: fuzzy). Similar
to ``--sub-auto`` and ``--audio-file-auto``. However, it's currently limited
to picking up a whitelist of "album art" filenames (such as ``cover.jpg``),
so currently only the ``fuzzy`` choice is available. In addition, if a video
already has tracks (which are not marked as cover art), external cover art
will not be loaded.
``--cover-art-auto=<no|exact|fuzzy|all>``
Whether to load _external_ cover art automatically. Similar to
``--sub-auto`` and ``--audio-file-auto``. If a video already has tracks
(which are not marked as cover art), external cover art will not be loaded.
:no: Don't automatically load cover art.
:exact: Load the media filename with an image file extension.
:fuzzy: Load all cover art containing the media filename and filenames
in an internal whitelist, such as ``cover.jpg`` (default).
:all: Load all images in the current directory.
See ``--cover-art-files`` for details about what constitutes cover art.
@@ -6671,8 +6801,9 @@ Miscellaneous
Automatically load/select external files (default: yes).
If set to ``no``, then do not automatically load external files as specified
by ``--sub-auto`` and ``--audio-file-auto``. If external files are forcibly
added (like with ``--sub-files``), they will not be auto-selected.
by ``--sub-auto``, ``--audio-file-auto`` and ``--cover-art-auto``. If
external files are forcibly added (like with ``--sub-files``), they will
not be auto-selected.
This does not affect playlist expansion, redirection, or other loading of
referenced files like with ordered chapters.
+14 -7
View File
@@ -43,7 +43,8 @@ pl next
============= ================================================
title
| Displays current media-title, filename, or custom title
| Displays current media-title, filename, custom title, or target chapter
name while hovering the seekbar.
============= ================================================
left-click show playlist position and length and full title
@@ -179,12 +180,12 @@ Configurable Options
``seekbarkeyframes``
Default: yes
Controls the mode used to seek when dragging the seekbar (default: true). If
set to true, default seeking mode is used (usually keyframes, but player
defaults and heuristics can change it to exact). If set to false, exact
seeking on mouse drags will be used instead. Keyframes are preferred, but
exact seeks may be useful in cases where keyframes cannot be found. Note
that using exact seeks can potentially make mouse dragging much slower.
Controls the mode used to seek when dragging the seekbar. If set to ``yes``,
default seeking mode is used (usually keyframes, but player defaults and
heuristics can change it to exact). If set to ``no``, exact seeking on
mouse drags will be used instead. Keyframes are preferred, but exact seeks
may be useful in cases where keyframes cannot be found. Note that using
exact seeks can potentially make mouse dragging much slower.
``seekrangestyle``
Default: inverted
@@ -375,6 +376,12 @@ Configurable Options
Set to ``yes`` to reduce festivity (i.e. disable santa hat in December.)
``livemarkers``
Default: yes
Update chapter markers positions on duration changes, e.g. live streams.
The updates are unoptimized - consider disabling it on very low-end systems.
Script Commands
~~~~~~~~~~~~~~~
+26 -12
View File
@@ -24,7 +24,8 @@ stats:
1 Show usual stats
2 Show frame timings (scroll)
3 Input cache stats
4 Internal stuff (scroll)
4 Active key bindings (scroll)
0 Internal stuff (scroll)
==== ==================
On pages which support scroll, these key bindings are also active:
@@ -51,13 +52,6 @@ option. The configuration syntax is described in `ON SCREEN CONTROLLER`_.
Configurable Options
~~~~~~~~~~~~~~~~~~~~
``key_oneshot``
Default: i
``key_toggle``
Default: I
Key bindings to display stats.
``key_page_1``
Default: 1
``key_page_2``
@@ -66,6 +60,8 @@ Configurable Options
Default: 3
``key_page_4``
Default: 4
``key_page_0``
Default: 0
Key bindings for page switching while stats are displayed.
@@ -171,18 +167,36 @@ Note: colors are given as hexadecimal values and use ASS tag order: BBGGRR
Different key bindings
~~~~~~~~~~~~~~~~~~~~~~
A different key binding can be defined with the aforementioned options
``key_oneshot`` and ``key_toggle`` but also with commands in ``input.conf``,
for example::
Additional keys can be configured in ``input.conf`` to display the stats::
e script-binding stats/display-stats
E script-binding stats/display-stats-toggle
Using ``input.conf``, it is also possible to directly display a certain page::
And to display a certain page directly::
i script-binding stats/display-page-1
e script-binding stats/display-page-2
Active key bindings page
~~~~~~~~~~~~~~~~~~~~~~~~
Lists the active key bindings and the commands they're bound to, excluding the
interactive keys of the stats script itself. See also ``--input-test`` for more
detailed view of each binding.
The keys are grouped automatically using a simple analysis of the command
string, and one should not expect documentation-level grouping accuracy,
however, it should still be reasonably useful.
Using ``--idle --script-opts=stats-bindlist=yes`` will print the list to the
terminal and quit immediately. By default long lines are shortened to 79 chars,
and terminal escape sequences are enabled. A different length limit can be
set by changing ``yes`` to a number (at least 40), and escape sequences can be
disabled by adding ``-`` before the value, e.g. ``...=-yes`` or ``...=-120``.
Like with ``--input-test``, the list includes bindings from ``input.conf`` and
from user scripts. Use ``--no-config`` to list only built-in bindings.
Internal stuff page
~~~~~~~~~~~~~~~~~~~
+5 -5
View File
@@ -60,7 +60,7 @@ libavfilter bridge.
.. note::
To get a full list of available video filters, see ``--vf=help`` and
http://ffmpeg.org/ffmpeg-filters.html .
https://ffmpeg.org/ffmpeg-filters.html .
Also, keep in mind that most actual filters are available via the ``lavfi``
wrapper, which gives you access to most of libavfilter's filters. This
@@ -310,7 +310,7 @@ Available mpv-only filters are:
``<stereo-in>``
Set the stereo mode the video is assumed to be encoded in. Use
``--vf format:stereo-in=help`` to list all available modes. Check with
``--vf=format:stereo-in=help`` to list all available modes. Check with
the ``stereo3d`` filter documentation to see what the names mean.
``<stereo-out>``
@@ -389,7 +389,7 @@ Available mpv-only filters are:
option gives the flags which should be passed to libswscale. This
option is numeric and takes a bit-wise combination of ``SWS_`` flags.
See ``http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libswscale/swscale.h``.
See ``https://git.videolan.org/?p=ffmpeg.git;a=blob;f=libswscale/swscale.h``.
``<o>``
Set AVFilterGraph options. These should be documented by FFmpeg.
@@ -598,7 +598,7 @@ Available mpv-only filters are:
``reversal-bug=<yes|no>``
:no: Use the API as it was interpreted by older Mesa drivers. While
this interpretation was more obvious and inuitive, it was
this interpretation was more obvious and intuitive, it was
apparently wrong, and not shared by Intel driver developers.
:yes: Use Intel interpretation of surface forward and backwards
references (default). This is what Intel drivers and newer Mesa
@@ -738,7 +738,7 @@ Available mpv-only filters are:
which leads to lost frames.
``print=yes|no``
Print computed fingerprints the the terminal (default: no). This is
Print computed fingerprints to the terminal (default: no). This is
mostly for testing and such. Scripts should use ``vf-metadata`` to
read information from this filter instead.
+24 -17
View File
@@ -253,7 +253,7 @@ Available video output drivers are:
quality or performance by changing the ``--fbo-format`` option to
``rgb16f``, ``rgb32f`` or ``rgb``. Known problems include Mesa/Intel not
accepting ``rgb16``, Mesa sometimes not being compiled with float texture
support, and some OS X setups being very slow with ``rgb16`` but fast
support, and some macOS setups being very slow with ``rgb16`` but fast
with ``rgb32f``. If you have problems, you can also try enabling the
``--gpu-dumb-mode=yes`` option.
@@ -336,7 +336,7 @@ Available video output drivers are:
``tct``
Color Unicode art video output driver that works on a text console.
By default depends on support of true color by modern terminals to display
the images at full color range, but 256-colors outout is also supported (see
the images at full color range, but 256-colors output is also supported (see
below). On Windows it requires an ansi terminal such as mintty.
Since mpv 0.30.0, you may need to use ``--profile=sw-fast`` to get decent
@@ -413,18 +413,22 @@ Available video output drivers are:
to take into account padding at the report - this only works correctly
when the overall padding per axis is smaller than the number of cells.
``--vo-sixel-exit-clear=<yes|no>`` (default: yes)
Whether or not to clear the terminal on quit. When set to no - the last
sixel image stays on screen after quit, with the cursor following it.
Sixel image quality options:
``--vo-sixel-dither=<algo>``
Selects the dither algorithm which libsixel should apply.
Can be one of the below list as per libsixel's documentation.
auto
Choose diffuse type automatically
auto (Default)
Let libsixel choose the dithering method.
none
Don't diffuse
atkinson
Diffuse with Bill Atkinson's method. (Default)
Diffuse with Bill Atkinson's method.
fs
Diffuse with Floyd-Steinberg method
jajuni
@@ -444,20 +448,18 @@ Available video output drivers are:
using ``no`` (at the time of writing) will slow down ``xterm``.
``--vo-sixel-reqcolors=<colors>`` (default: 256)
Set up libsixel to use required number of colors for dynamic palette.
This value depends on the terminal emulator as well. Xterm supports
256 colors. Can set this to a lower value for faster performance.
This option has no effect if fixed palette is used.
Has no effect with fixed palette. Set up libsixel to use required
number of colors for dynamic palette. This value depends on the
terminal emulator as well. Xterm supports 256 colors. Can set this to
a lower value for faster performance.
``--vo-sixel-threshold=<threshold>`` (default: -1)
When using a dynamic palette, defines the threshold to change the
Has no effect with fixed palette. Defines the threshold to change the
palette - as percentage of the number of colors, e.g. 20 will change
the palette when the number of colors changed by 20%. It's a simple
measure to reduce the number of palette changes, because it can be slow
in some terminals (``xterm``), however, it seems that in ``mlterm`` it
causes image corruption. The default (-1) will change the palette
on every frame and will have better quality, and no corruption in
``mlterm``.
in some terminals (``xterm``). The default (-1) will choose a palette
on every frame and will have better quality.
``image``
Output each frame into an image file in the current directory. Each file
@@ -496,7 +498,7 @@ Available video output drivers are:
Specify the directory to save the image files to (default: ``./``).
``libmpv``
For use with libmpv direct embedding. As a special case, on OS X it
For use with libmpv direct embedding. As a special case, on macOS it
is used like a normal VO within mpv (cocoa-cb). Otherwise useless in any
other contexts.
(See ``<mpv/render.h>``.)
@@ -550,8 +552,13 @@ Available video output drivers are:
Select the connector to use (usually this is a monitor.) If ``<name>``
is empty or ``auto``, mpv renders the output on the first available
connector. Use ``--drm-connector=help`` to get a list of available
connectors. When using multiple graphic cards, use the ``<gpu_number>``
argument to disambiguate.
connectors. The ``<gpu_number>`` argument can be used to disambiguate
multiple graphic cards, but is deprecated in favor of ``--drm-device``.
(default: empty)
``--drm-device=<path>``
Select the DRM device file to use. If specified this overrides automatic
card selection and any card number specified ``--drm-connector``.
(default: empty)
``--drm-mode=<preferred|highest|N|WxH[@R]>``
+1 -1
View File
@@ -52,7 +52,7 @@ Input
* Classic LIRC support was removed. Install remotes as input devices instead.
This way they will send X11 key events to the mpv window, which can be bound
using the normal ``input.conf``.
Also see: http://github.com/mpv-player/mpv/wiki/IR-remotes
Also see: https://github.com/mpv-player/mpv/wiki/IR-remotes
* Joystick support was removed. It was considered useless and was the cause
of some problems (e.g. a laptop's accelerator being recognized as joystick).
* Support for relative seeking by percentage.
+1 -1
View File
@@ -46,7 +46,7 @@ mpv's custom configure step on top of waf
To some extents mpv has a custom build system written on top of waf. This
document will not go over the standard waf behaviour as that is documented in
the `Waf book <http://docs.waf.googlecode.com/git/book_17/single.html>`_.
the `Waf book <https://waf.io/book/>`_.
All of the configuration process is handled with a declarative approach. Lists
of dictionaries define the checks, and some custom Python code traverses these
+12 -13
View File
@@ -1,8 +1,8 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,7 +55,7 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
@@ -303,10 +303,9 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+9 -9
View File
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -158,7 +158,7 @@ Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
+12 -12
View File
@@ -21,7 +21,7 @@
* [Wiki](https://github.com/mpv-player/mpv/wiki)
* [FAQ][FAQ]
* [Manual](http://mpv.io/manual/master/)
* [Manual](https://mpv.io/manual/master/)
## Overview
@@ -53,7 +53,7 @@ Releases can be found on the [release list][releases].
For semi-official builds and third-party packages please see
[mpv.io/installation](http://mpv.io/installation/).
[mpv.io/installation](https://mpv.io/installation/).
## Changelog
@@ -85,10 +85,10 @@ detect it, the file `build/config.log` may contain information about the
reasons for the failure.
NOTE: To avoid cluttering the output with unreadable spam, `--help` only shows
one of the two switches for each option. If the option is autodetected by
default, the `--disable-***` switch is printed; if the option is disabled by
default, the `--enable-***` switch is printed. Either way, you can use
`--enable-***` or `--disable-**` regardless of what is printed by `--help`.
one of the two switches for each option. If the option is autodetected or
enabled by default, the `--disable-***` switch is printed; if the option is
disabled by default, the `--enable-***` switch is printed. Either way, you can
use `--enable-***` or `--disable-**` regardless of what is printed by `--help`.
To build the software you can use `./waf build`: the result of the compilation
will be located in `build/mpv`. You can use `./waf install` to install mpv
@@ -121,9 +121,9 @@ Libass dependencies (when building libass):
- gcc or clang, yasm on x86 and x86_64
- fribidi, freetype, fontconfig development headers (for libass)
- harfbuzz (optional, required for correct rendering of combining characters,
particularly for correct rendering of non-English text on OSX, and
Arabic/Indic scripts on any platform)
- harfbuzz (required for correct rendering of combining characters, particularly
for correct rendering of non-English text on OSX, and Arabic/Indic scripts on
any platform)
FFmpeg dependencies (when building FFmpeg):
@@ -181,7 +181,7 @@ changes come and talk to us on IRC before you start working on them. It will
make code review easier for both parties later on.
You can check [the wiki](https://github.com/mpv-player/mpv/wiki/Stuff-to-do)
or the [issue tracker](https://github.com/mpv-player/mpv/issues?q=is%3Aopen+is%3Aissue+label%3A%22feature+request%22)
or the [issue tracker](https://github.com/mpv-player/mpv/issues?q=is%3Aopen+is%3Aissue+label%3Ameta%3Afeature-request)
for ideas on what you could contribute with.
## License
@@ -201,8 +201,8 @@ see the [FAQ][FAQ].
Most activity happens on the IRC channel and the github issue tracker.
- **GitHub issue tracker**: [issue tracker][issue-tracker] (report bugs here)
- **User IRC Channel**: `#mpv` on `irc.freenode.net`
- **Developer IRC Channel**: `#mpv-devel` on `irc.freenode.net`
- **User IRC Channel**: `#mpv` on `irc.libera.chat`
- **Developer IRC Channel**: `#mpv-devel` on `irc.libera.chat`
[FAQ]: https://github.com/mpv-player/mpv/wiki/FAQ
[releases]: https://github.com/mpv-player/mpv/releases
+86 -98
View File
@@ -1,4 +1,4 @@
Release 0.33.0
Release 0.34.0
==============
This release requires FFmpeg 4.0 or newer.
@@ -14,53 +14,34 @@ Features
Added
~~~~~
- scripting: load scripts from directories
- mac: activate logging when started from the bundle
- ytdl_hook.lua: delay load subtitles
- sub: add an option to filter subtitles by regex
- scripting: add a way to run subprocesses as "scripts"
- command: implement asynchronous commands and support for named arguments
- player: add optional separate video decoding thread
- vo_gpu: d3d11: add support for exclusive fullscreen
- w32_common: Support HiDPI on Windows
- vo_x11: add 10 bit support
- vo_gpu: add BT.2390 tone-mapping
- client API: add software rendering API
- audio: add scaletempo2 filter based on chromium
- auto_profiles: add this script
- stream: Implement slice:// for reading slices of streams
- player: add automatic loading of external cover art files
- vo_sixel: implement terminal video output using sixel
- player: allow vo to be switched at runtime
- input.conf syntax: support custom quotes in `XstringX` form & single quotes
- ao_ass: readd OSSv4 audio output, default on *BSD
- player: load cover art with the media filename
- vo_gpu: vulkan: implement a VkDisplayKHR backed context
- osc: seekbar hover/drag: display target chapter at the OSC title
- stats.lua: add page 4 with a list of active key bindings
- sub: add --sub-filter-jsre (JS regex)
- vo_rpi: restore fullscreen handling
- vo_tct: add resize capability
- ytdl_hook.lua: search for yt-dlp by default (preferred over youtube-dl)
Changed
~~~~~~~
- sws_utils: use zimg by default if available
- build: pick up Lua 5.2 by default (preferred over 5.1)
- build: disable RPI vendor blob auto-detection in favor of open-source stack
- build: make C11 atomics mandatory
- build: make libass non-optional
- player: stricter filename matching for external subtitle auto-loading
- lua: support Unicode paths in script loading and IO library
- vo_direct3d: rip out texture video rendering path and dumb down OSD rendering
- audio: rewrite internal audio handling and AO API
- build: disable GLX by default
- vo_sixel: many fixes and improvements
- filters: switch from scaletempo to scaletempo2, used for `speed` option
- audio/vo_pulse: fix various edge cases and issues
- stats.lua: move internal performance info from page 4 to page 0
- command: don't hardcode command lists to be repeatable
Removed
~~~~~~~
- stream_libarchive: disable tar support due to bugs
- Remove remains of Libav compatibility
- stream_smb: remove due to lack of thread safety and the abundance
of alternatives, FFmpeg still includes SMB support
- command: remove legacy hook API (has been deprecated for a long time)
- client API: remove deprecated qthelper.hpp header
- removed audio outputs: sndio, rsound, oss
- x11: remove xdg-screensaver invocations that supported dbus based idle inhibit
- client API: deactivate the opengl_cb API
- build system: drop Python 2 compatbility
- mac: drop build support for swift versions earlier than 4.1
- vo_gpu: drop support for libplacebo older than v3.104.0
Options and Commands
@@ -69,90 +50,97 @@ Options and Commands
Added
~~~~~
- demux: add option to disable cache "sharing" between back and forward buffers
- player: add ab-loop-count option/property
- ytdl_hook: add a way to use ytdl's default formats
- ytdl_hook: add all_formats option that loads all formats that were found
- demux_mkv: document probe-start-time option and enable it by default
- command: extend osd-overlay command with bounds reporting
- player: a number of new playlist contol commands/properties
- ipc: add --input-ipc-client option
- options: add option to control display-sync factor
- vo_gpu: add better gamut clipping option
- vo_gpu: vulkan: add ability to disable events
- x11: add option to make window appear on a specific workspace
- wayland: expose wayland-app-id as a user option
- player: add --subs-with-matching-audio option
- command: add read-only focused property
- screenshot: option to use software rendering for screenshots
- command: add delete-watch-later-config
- command: new property mouse-pos with current position and hover state
- vo_sixel: add --vo-sixel-exit-clear
- player: add --screen-name and --fs-screen-name
- player/command: add albumart argument to video-add
- command: add pid (process id), display-width and display-height properties
- sub: add secondary-sub-text, -start, and -end properties; secondary-sub-visibility option
- vo_gpu: add --icc-force-contrast
- player: add append-play flag to loadlist
- command: add support for secondary subs to sub-seek and sub-step
- options: add watch-later-options to configure which options are saved
- player: add track-list/N/image sub-property
- input: add --no-input-builtin-bindings option
- drm_common: add --drm-device option
Changed
~~~~~~~
- options: remove deprecation warning for "-foo bar" syntax
- player: make audio hr-seek default
- ad_lavc: disable decoder downmix by default
- command: support save-position-on-quit for "stop" command too
- command: extend subprocess command
- options: do not accept ":" as separator anymore in key/value lists
- vo_sixel: change default dither to "auto"
- vd_lavc: add VP8 to the default allowed hwdec codec list
- vo_gpu: lower default deband threshold to preserve more detail
- vo_gpu: adjust interpolation-threshold's default
- demux: undeprecate --cache-secs
- options: add `Uploader`, `Channel_URL` to --display-tags defaults
- options: --audio-display determines cover priority
- command: make current-window-scale writeable
Deprecated
~~~~~~~~~~
- demux: deprecate --cache-secs
- win32: ignore and deprecate --fit-border
- drm_common: deprecate selecting by card number in --drm-connector
Removed
~~~~~~~
- wayland: remove wayland-frame-wait-offset option
- input: remove deprecated --input-file option
- vo_vdpau: remove deprecated/inactive --vo-vdpau-deint option
- vo_gpu: remove --icc-contrast
- stats.lua: remove script-opts for the main keys (i/I)
- vo_gpu: opengl: remove --opengl-restrict
Fixes and Minor Enhancements
----------------------------
- options: stop hiding deprecated options from --help output
- lua, js: add mp.get_script_directory() function
- lua: fix security relevant loading order issue with scripts
- player: make screenshot each-frame mode more accurate
- bash completion: complete ao/af/vo/vf options
- zimg: add alpha support
- wayland: make resizing better
- edl: add mechanism for delay loading streams
- stream_file: fix caching-related performance regression on CIFS
- cocoa-cb: fix crashes and issues with UI updates
- sub, demux: improve behavior with negative subtitle delay/muxed subs
- demux: make seek ranges work for static images + audio
- cocoa-cb: support maximize/minimize on startup
- umpv: change from legacy FIFO to socket
- stats: move input speed to cache page, make it a graph
- stats: add fourth page with performance graphs
- command: print edition title to OSD when cycling
- zimg: add support for big endian input and output
- demux_mkv: add png intra support
- build: detect VT_GETMODE on FreeBSD and DragonFly
- win32: use windows 10 native virtual-terminal if available
- vo_gpu: enable frame caching for still frames
- command: add property to return text subtitles in ASS
- vo_gpu: ra_pl: add timers support
- build: allow vo_wlshm on more Wayland platforms (e.g. FreeBSD)
- zimg: add slice threading and use it by default
- command: add a way to access properties of a current track
- vo_gpu: EGL: fix transparency on X11/EGL/Mesa
- vd_lavc: add AV1 to the default allowed hwdec codec list
- terminal: correctly process input when foregrounded
- vo_wlshm: support presentation time
- mac: fix a window positioning bug when exiting fullscreen
- csputils: add mappings for DCI-P3 (ST.431-2) and P3-D65 (ST.432-1)
- player: make resetting of track selection to "auto" work
- stream_lavf: support rtsps
- vo_wlshm: support big endian systems
- demux_mf: add support for more image codecs
- msg: fix really-quiet option to only affect terminal output
- mac: fix traditional fullscreen on macOS 11
- ao_pulse: fix misbehavior with PipeWire when setting volume or mute
- stats.lua: include a filter's @label when displaying filters on page 1
- wayland, win32: support the display-hidpi-scale property
- win32: keep the window title-bar inside the screen
- filter_kernels: fix incorrect constant for quadric window
- command: add display-width/display-height property
- edl: add a way to add tags
- stream_file: disable readahead for remote files on macOS to fix stutter
- osxbundle: fix slow and wasteful memory allocation that caused stutter
- vo_gpu: fix extreme clipping with --gamut-clipping for HDR outputs
- af_scaletempo2: speed up using vector calculations
- recorder: fix muxing of certain codecs
- win32: support the focused property
- js: add mp.utils.append_file
- subs: fix missing subtitles on last frame
- stats.lua: show scaled resolution
- osc: expose osc-visibility via shared-script-properties
- terminal-unix: fix ^Z identification and ignore unknown CSI sequences
- context_drm_egl: allow autoprobe selection
- wayland: improve behavior with touch events
- command: make current-window-scale writeable
- vo_vdpau: don't treat preemption as an error to fix VT switching
- wayland: read XCURSOR_THEME to get cursor theme
- demux_playlist: extend maximum line size (again) to 2M
- win32: call timeBeginPeriod on demand on Windows 10
- build: allow easier selection of lua version/package
- vo_gpu: fix distortion with certain rotated videos
- drm_common: skip non-primary devices during automatic choosing
- drm_common: support USB, SPI, Writeback and unknown connector types (future proofing)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.32.0..v0.33.0`
A complete changelog can be seen by running `git log v0.33.0..v0.34.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.32.0...v0.33.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.32.0..v0.33.0
https://github.com/mpv-player/mpv/compare/v0.33.0...v0.34.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.33.0..v0.34.0
+2 -20
View File
@@ -23,6 +23,8 @@ pacman -S --noconfirm --needed \
$MINGW_PACKAGE_PREFIX-lua51 \
$MINGW_PACKAGE_PREFIX-ninja \
$MINGW_PACKAGE_PREFIX-rubberband \
$MINGW_PACKAGE_PREFIX-shaderc \
$MINGW_PACKAGE_PREFIX-spirv-cross \
$MINGW_PACKAGE_PREFIX-uchardet \
$MINGW_PACKAGE_PREFIX-vulkan
@@ -50,23 +52,3 @@ pacman -Sc --noconfirm
--enable-schannel
make -j4 install
)
# Compile shaderc
(
git clone --depth=1 https://github.com/google/shaderc && cd shaderc
"$PYTHON" utils/git-sync-deps
mkdir build && cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DSHADERC_SKIP_TESTS=ON \
-DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX ..
ninja install
)
# Compile SPIRV-Cross
(
git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Cross && cd SPIRV-Cross
mkdir build && cd build
cmake -GNinja -DSPIRV_CROSS_SHARED=ON -DCMAKE_INSTALL_PREFIX=$MINGW_PREFIX ..
ninja install
)
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import re
import os
+18 -11
View File
@@ -56,6 +56,9 @@ detect_min_ratio: number[0.0-1.0] - The ratio of the minimum clip
detect_seconds: seconds - How long to gather cropdetect data.
Increasing this may be desirable to allow cropdetect more
time to collect data.
suppress_osd: bool - Whether the OSD shouldn't be used when filters
are applied and removed.
--]]
require "mp.msg"
@@ -67,7 +70,8 @@ local options = {
detect_limit = "24/255",
detect_round = 2,
detect_min_ratio = 0.5,
detect_seconds = 1
detect_seconds = 1,
suppress_osd = false,
}
read_options(options)
@@ -82,6 +86,8 @@ timers = {
detect_crop = nil
}
local command_prefix = options.suppress_osd and 'no-osd' or ''
function is_filter_present(label)
local filters = mp.get_property_native("vf")
for index, filter in pairs(filters) do
@@ -102,17 +108,18 @@ function is_enough_time(seconds)
end
function is_cropable()
local vid = mp.get_property_native("vid")
local is_album = vid and mp.get_property_native(
string.format("track-list/%d/albumart", vid)
) or false
for _, track in pairs(mp.get_property_native('track-list')) do
if track.type == 'video' and track.selected then
return not track.albumart
end
end
return vid and not is_album
return false
end
function remove_filter(label)
if is_filter_present(label) then
mp.command(string.format('vf remove @%s', label))
mp.command(string.format('%s vf remove @%s', command_prefix, label))
return true
end
return false
@@ -156,8 +163,8 @@ function detect_crop()
mp.command(
string.format(
'vf pre @%s:cropdetect=limit=%s:round=%d:reset=0',
labels.cropdetect, limit, round
'%s vf pre @%s:cropdetect=limit=%s:round=%d:reset=0',
command_prefix, labels.cropdetect, limit, round
)
)
@@ -248,8 +255,8 @@ function apply_crop(meta)
-- Apply crop.
mp.command(
string.format("vf pre @%s:lavfi-crop=w=%s:h=%s:x=%s:y=%s",
labels.crop, meta.w, meta.h, meta.x, meta.y
string.format("%s vf pre @%s:lavfi-crop=w=%s:h=%s:x=%s:y=%s",
command_prefix, labels.crop, meta.w, meta.h, meta.x, meta.y
)
)
end
+6 -2
View File
@@ -16,6 +16,7 @@ disabled=no
images=no
videos=yes
audio=yes
ignore_hidden=yes
--]]
@@ -29,7 +30,8 @@ o = {
disabled = false,
images = true,
videos = true,
audio = true
audio = true,
ignore_hidden = true
}
options.read_options(o)
@@ -155,7 +157,9 @@ function find_and_add_entries()
return
end
table.filter(files, function (v, k)
if string.match(v, "^%.") then
-- The current file could be a hidden file, ignoring it doesn't load other
-- files from the current directory.
if (o.ignore_hidden and not (v == filename) and string.match(v, "^%.")) then
return false
end
local ext = get_extension(v)
+2 -6
View File
@@ -21,8 +21,6 @@ Can also be used to directly parse Matroska files and display their contents.
# License along with mpv. If not, see <http://www.gnu.org/licenses/>.
#
# for compatibility with Python 2.x
from __future__ import print_function
elements_ebml = (
'EBML, 1a45dfa3, sub', (
@@ -300,8 +298,8 @@ parse_elems(elements_ebml, 'EBML')
parse_elems(elements_matroska, 'MATROSKA')
def printf(out, *args):
out.write(u' '.join([str(x) for x in args]))
out.write(u'\n')
out.write(' '.join(str(x) for x in args))
out.write('\n')
def generate_C_header(out):
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
@@ -466,8 +464,6 @@ if __name__ == "__main__":
elif sys.argv[1] == '--generate-definitions':
generate_C_definitions(sys.stdout)
else:
if sys.version_info.major < 3:
raise Exception("Dumping requires Python 3.")
s = open(sys.argv[1], "rb")
while 1:
start = s.tell()
+1 -2
View File
@@ -1,5 +1,4 @@
#!/usr/bin/env python
from __future__ import print_function
#!/usr/bin/env python3
import os
import shutil
import sys
@@ -188,6 +188,11 @@
<string>${VERSION}</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSEnvironment</key>
<dict>
<key>MallocNanoZone</key>
<string>0</string>
</dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ "x$TARGET" != "xx86_64-w64-mingw32" ]; then
if [ "$TRAVIS_OS_NAME" != "linux" ] || [ "$CC" != "clang" ]; then
# trigger build only on one of the matrix nodes
exit;
fi
+1 -3
View File
@@ -31,8 +31,6 @@ import os
import socket
import errno
import subprocess
import fcntl
import stat
import string
files = sys.argv[1:]
@@ -52,7 +50,7 @@ def make_abs(filename):
if not is_url(filename):
return os.path.abspath(filename)
return filename
files = [make_abs(f) for f in files]
files = (make_abs(f) for f in files)
SOCK = os.path.join(os.getenv("HOME"), ".umpv_socket")
+1 -1
View File
@@ -1 +1 @@
0.33.0
0.34.0
+4 -12
View File
@@ -1,3 +1,5 @@
image: Visual Studio 2019
branches:
only:
- master
@@ -15,18 +17,8 @@ shallow_clone: true
test: off
install:
# Work around age/brokenness of Appveyor's msys2 by adding the new
# maintainer's keyring.
- bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
- bash -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
- bash -lc "pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig"
- bash -lc "pacman -U --noconfirm msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz"
# Support for Ada and Objective-C was removed from MSYS2. GCC won't update if
# these packages are installed.
- >-
C:\msys64\usr\bin\pacman -R --noconfirm --noprogressbar
mingw-w64-i686-gcc-ada mingw-w64-i686-gcc-objc mingw-w64-x86_64-gcc-ada
mingw-w64-x86_64-gcc-objc
# Disable checking disk space to speed up install time
- C:\msys64\usr\bin\sed -i 's/^CheckSpace/#CheckSpace/g' /etc/pacman.conf
# Update core packages
- C:\msys64\usr\bin\pacman -Syyuu --noconfirm --noprogressbar --ask=20
# Explicitly kill any remaining msys2 processes after core update
+12 -6
View File
@@ -635,18 +635,24 @@ int mp_aframe_pool_allocate(struct mp_aframe_pool *pool, struct mp_aframe *frame
AVFrame *av_frame = frame->av_frame;
if (av_frame->extended_data != av_frame->data)
av_freep(&av_frame->extended_data); // sigh
av_frame->extended_data =
av_mallocz_array(planes, sizeof(av_frame->extended_data[0]));
if (!av_frame->extended_data)
abort();
if (planes > AV_NUM_DATA_POINTERS) {
av_frame->extended_data =
av_mallocz_array(planes, sizeof(av_frame->extended_data[0]));
if (!av_frame->extended_data)
abort();
} else {
av_frame->extended_data = av_frame->data;
}
av_frame->buf[0] = av_buffer_pool_get(pool->avpool);
if (!av_frame->buf[0])
return -1;
av_frame->linesize[0] = samples * sstride;
for (int n = 0; n < planes; n++)
av_frame->extended_data[n] = av_frame->buf[0]->data + n * plane_size;
for (int n = 0; n < MPMIN(planes, AV_NUM_DATA_POINTERS); n++)
av_frame->data[n] = av_frame->extended_data[n];
if (planes > AV_NUM_DATA_POINTERS) {
for (int n = 0; n < AV_NUM_DATA_POINTERS; n++)
av_frame->data[n] = av_frame->extended_data[n];
}
av_frame->nb_samples = samples;
return 0;
+1 -1
View File
@@ -85,7 +85,7 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec,
struct ad_lavc_params *opts =
mp_get_config_group(ctx, da->global, &ad_lavc_conf);
AVCodecContext *lavc_context;
AVCodec *lavc_codec;
const AVCodec *lavc_codec;
ctx->codec_timebase = mp_get_codec_timebase(codec);
+1 -1
View File
@@ -116,7 +116,7 @@ static void determine_codec_params(struct mp_filter *da, AVPacket *pkt,
if (profile != FF_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS)
return;
AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
const AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
if (!codec)
goto done;
+1 -1
View File
@@ -68,7 +68,7 @@ struct priv {
struct mp_aframe *in_frame;
struct mp_aframe_pool *out_pool;
struct AVCodec *lavc_acodec;
const struct AVCodec *lavc_acodec;
struct AVCodecContext *lavc_actx;
int bit_rate;
int out_samples; // upper bound on encoded output per AC3 frame
+85 -12
View File
@@ -4,6 +4,8 @@
#include "audio/chmap.h"
#include "audio/filter/af_scaletempo2_internals.h"
#include "config.h"
// Algorithm overview (from chromium):
// Waveform Similarity Overlap-and-add (WSOLA).
//
@@ -104,6 +106,10 @@ static float multi_channel_similarity_measure(
return similarity_measure;
}
#if HAVE_VECTOR
typedef float v8sf __attribute__ ((vector_size (32), aligned (1)));
// Dot-product of channels of two AudioBus. For each AudioBus an offset is
// given. |dot_product[k]| is the dot-product of channel |k|. The caller should
// allocate sufficient space for |dot_product|.
@@ -116,16 +122,79 @@ static void multi_channel_dot_product(
assert(frame_offset_a >= 0);
assert(frame_offset_b >= 0);
memset(dot_product, 0, sizeof(*dot_product) * channels);
for (int k = 0; k < channels; ++k) {
const float* ch_a = a[k] + frame_offset_a;
const float* ch_b = b[k] + frame_offset_b;
for (int n = 0; n < num_frames; ++n) {
dot_product[k] += *ch_a++ * *ch_b++;
float sum = 0.0;
if (num_frames < 32)
goto rest;
const v8sf *va = (const v8sf *) ch_a;
const v8sf *vb = (const v8sf *) ch_b;
v8sf vsum[4] = {
// Initialize to product of first 32 floats
va[0] * vb[0],
va[1] * vb[1],
va[2] * vb[2],
va[3] * vb[3],
};
va += 4;
vb += 4;
// Process `va` and `vb` across four vertical stripes
for (int n = 1; n < num_frames / 32; n++) {
vsum[0] += va[0] * vb[0];
vsum[1] += va[1] * vb[1];
vsum[2] += va[2] * vb[2];
vsum[3] += va[3] * vb[3];
va += 4;
vb += 4;
}
// Vertical sum across `vsum` entries
vsum[0] += vsum[1];
vsum[2] += vsum[3];
vsum[0] += vsum[2];
// Horizontal sum across `vsum[0]`, could probably be done better but
// this section is not super performance critical
float *vf = (float *) &vsum[0];
sum = vf[0] + vf[1] + vf[2] + vf[3] + vf[4] + vf[5] + vf[6] + vf[7];
ch_a = (const float *) va;
ch_b = (const float *) vb;
rest:
// Process the remainder
for (int n = 0; n < num_frames % 32; n++)
sum += *ch_a++ * *ch_b++;
dot_product[k] = sum;
}
}
#else // !HAVE_VECTOR
static void multi_channel_dot_product(
float **a, int frame_offset_a,
float **b, int frame_offset_b,
int channels,
int num_frames, float *dot_product)
{
assert(frame_offset_a >= 0);
assert(frame_offset_b >= 0);
for (int k = 0; k < channels; ++k) {
const float* ch_a = a[k] + frame_offset_a;
const float* ch_b = b[k] + frame_offset_b;
float sum = 0.0;
for (int n = 0; n < num_frames; n++)
sum += *ch_a++ * *ch_b++;
dot_product[k] = sum;
}
}
#endif // HAVE_VECTOR
// Fit the curve f(x) = a * x^2 + b * x + c such that
// f(-1) = y[0]
// f(0) = y[1]
@@ -389,10 +458,8 @@ static int write_completed_frames_to(struct mp_scaletempo2 *p,
static bool can_perform_wsola(struct mp_scaletempo2 *p)
{
const int search_block_size = p->num_candidate_blocks
+ (p->ola_window_size - 1);
return p->target_block_index + p->ola_window_size <= p->input_buffer_frames
&& p->search_block_index + search_block_size <= p->input_buffer_frames;
&& p->search_block_index + p->search_block_size <= p->input_buffer_frames;
}
// number of frames needed until a wsola iteration can be performed
@@ -403,6 +470,14 @@ static int frames_needed(struct mp_scaletempo2 *p)
p->search_block_index + p->search_block_size - p->input_buffer_frames));
}
static void resize_input_buffer(struct mp_scaletempo2 *p, int size)
{
if (size > p->input_buffer_size) {
p->input_buffer_size = size;
p->input_buffer = realloc_2d(p->input_buffer, p->channels, size);
}
}
int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
uint8_t **planes, int frame_size, bool final)
{
@@ -411,7 +486,8 @@ int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
int total_fill = final ? needed : read;
if (total_fill == 0) return 0;
assert(total_fill + p->input_buffer_frames <= p->input_buffer_size);
int required_size = total_fill + p->input_buffer_frames;
resize_input_buffer(p, required_size);
for (int i = 0; i < p->channels; ++i) {
memcpy(p->input_buffer[i] + p->input_buffer_frames,
@@ -427,11 +503,9 @@ int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
static bool target_is_within_search_region(struct mp_scaletempo2 *p)
{
const int search_block_size = p->num_candidate_blocks + (p->ola_window_size - 1);
return p->target_block_index >= p->search_block_index
&& p->target_block_index + p->ola_window_size
<= p->search_block_index + search_block_size;
<= p->search_block_index + p->search_block_size;
}
@@ -715,8 +789,7 @@ void mp_scaletempo2_init(struct mp_scaletempo2 *p, int channels, int rate)
p->search_block = realloc_2d(p->search_block, p->channels, p->search_block_size);
p->target_block = realloc_2d(p->target_block, p->channels, p->ola_window_size);
p->input_buffer_size = 4 * MPMAX(p->ola_window_size, p->search_block_size);
p->input_buffer = realloc_2d(p->input_buffer, p->channels, p->input_buffer_size);
resize_input_buffer(p, 4 * MPMAX(p->ola_window_size, p->search_block_size));
p->input_buffer_frames = 0;
p->energy_candidate_blocks = realloc(p->energy_candidate_blocks,
+4
View File
@@ -35,6 +35,7 @@
#include "common/common.h"
#include "common/global.h"
extern const struct ao_driver audio_out_oss;
extern const struct ao_driver audio_out_audiotrack;
extern const struct ao_driver audio_out_audiounit;
extern const struct ao_driver audio_out_coreaudio;
@@ -70,6 +71,9 @@ static const struct ao_driver * const audio_out_drivers[] = {
#endif
#if HAVE_WASAPI
&audio_out_wasapi,
#endif
#if HAVE_OSS_AUDIO
&audio_out_oss,
#endif
// wrappers:
#if HAVE_JACK
+131 -17
View File
@@ -82,6 +82,7 @@ struct JNIByteBuffer {
struct JNIAudioTrack {
jclass clazz;
jmethodID ctor;
jmethodID ctorV21;
jmethodID release;
jmethodID getState;
jmethodID getPlayState;
@@ -94,6 +95,7 @@ struct JNIAudioTrack {
jmethodID writeV23;
jmethodID writeShortV23;
jmethodID writeBufferV21;
jmethodID getBufferSizeInFramesV23;
jmethodID getPlaybackHeadPosition;
jmethodID getTimestamp;
jmethodID getLatency;
@@ -114,6 +116,7 @@ struct JNIAudioTrack {
#define OFFSET(member) offsetof(struct JNIAudioTrack, member)
{"android/media/AudioTrack", NULL, NULL, MP_JNI_CLASS, OFFSET(clazz), 1},
{"android/media/AudioTrack", "<init>", "(IIIIIII)V", MP_JNI_METHOD, OFFSET(ctor), 1},
{"android/media/AudioTrack", "<init>", "(Landroid/media/AudioAttributes;Landroid/media/AudioFormat;III)V", MP_JNI_METHOD, OFFSET(ctorV21), 0},
{"android/media/AudioTrack", "release", "()V", MP_JNI_METHOD, OFFSET(release), 1},
{"android/media/AudioTrack", "getState", "()I", MP_JNI_METHOD, OFFSET(getState), 1},
{"android/media/AudioTrack", "getPlayState", "()I", MP_JNI_METHOD, OFFSET(getPlayState), 1},
@@ -126,6 +129,7 @@ struct JNIAudioTrack {
{"android/media/AudioTrack", "write", "([BIII)I", MP_JNI_METHOD, OFFSET(writeV23), 0},
{"android/media/AudioTrack", "write", "([SIII)I", MP_JNI_METHOD, OFFSET(writeShortV23), 0},
{"android/media/AudioTrack", "write", "(Ljava/nio/ByteBuffer;II)I", MP_JNI_METHOD, OFFSET(writeBufferV21), 1},
{"android/media/AudioTrack", "getBufferSizeInFrames", "()I", MP_JNI_METHOD, OFFSET(getBufferSizeInFramesV23), 0},
{"android/media/AudioTrack", "getTimestamp", "(Landroid/media/AudioTimestamp;)Z", MP_JNI_METHOD, OFFSET(getTimestamp), 1},
{"android/media/AudioTrack", "getPlaybackHeadPosition", "()I", MP_JNI_METHOD, OFFSET(getPlaybackHeadPosition), 1},
{"android/media/AudioTrack", "getLatency", "()I", MP_JNI_METHOD, OFFSET(getLatency), 1},
@@ -145,6 +149,38 @@ struct JNIAudioTrack {
#undef OFFSET
}};
struct JNIAudioAttributes {
jclass clazz;
jint CONTENT_TYPE_MOVIE;
jint USAGE_MEDIA;
struct MPJniField mapping[];
} AudioAttributes = {.mapping = {
#define OFFSET(member) offsetof(struct JNIAudioAttributes, member)
{"android/media/AudioAttributes", NULL, NULL, MP_JNI_CLASS, OFFSET(clazz), 0},
{"android/media/AudioAttributes", "CONTENT_TYPE_MOVIE", "I", MP_JNI_STATIC_FIELD_AS_INT, OFFSET(CONTENT_TYPE_MOVIE), 0},
{"android/media/AudioAttributes", "USAGE_MEDIA", "I", MP_JNI_STATIC_FIELD_AS_INT, OFFSET(USAGE_MEDIA), 0},
{0}
#undef OFFSET
}};
struct JNIAudioAttributesBuilder {
jclass clazz;
jmethodID ctor;
jmethodID setUsage;
jmethodID setContentType;
jmethodID build;
struct MPJniField mapping[];
} AudioAttributesBuilder = {.mapping = {
#define OFFSET(member) offsetof(struct JNIAudioAttributesBuilder, member)
{"android/media/AudioAttributes$Builder", NULL, NULL, MP_JNI_CLASS, OFFSET(clazz), 0},
{"android/media/AudioAttributes$Builder", "<init>", "()V", MP_JNI_METHOD, OFFSET(ctor), 0},
{"android/media/AudioAttributes$Builder", "setUsage", "(I)Landroid/media/AudioAttributes$Builder;", MP_JNI_METHOD, OFFSET(setUsage), 0},
{"android/media/AudioAttributes$Builder", "setContentType", "(I)Landroid/media/AudioAttributes$Builder;", MP_JNI_METHOD, OFFSET(setContentType), 0},
{"android/media/AudioAttributes$Builder", "build", "()Landroid/media/AudioAttributes;", MP_JNI_METHOD, OFFSET(build), 0},
{0}
#undef OFFSET
}};
struct JNIAudioFormat {
jclass clazz;
jint ENCODING_PCM_8BIT;
@@ -189,6 +225,27 @@ struct JNIAudioFormat {
#undef OFFSET
}};
struct JNIAudioFormatBuilder {
jclass clazz;
jmethodID ctor;
jmethodID setEncoding;
jmethodID setSampleRate;
jmethodID setChannelMask;
jmethodID build;
struct MPJniField mapping[];
} AudioFormatBuilder = {.mapping = {
#define OFFSET(member) offsetof(struct JNIAudioFormatBuilder, member)
{"android/media/AudioFormat$Builder", NULL, NULL, MP_JNI_CLASS, OFFSET(clazz), 0},
{"android/media/AudioFormat$Builder", "<init>", "()V", MP_JNI_METHOD, OFFSET(ctor), 0},
{"android/media/AudioFormat$Builder", "setEncoding", "(I)Landroid/media/AudioFormat$Builder;", MP_JNI_METHOD, OFFSET(setEncoding), 0},
{"android/media/AudioFormat$Builder", "setSampleRate", "(I)Landroid/media/AudioFormat$Builder;", MP_JNI_METHOD, OFFSET(setSampleRate), 0},
{"android/media/AudioFormat$Builder", "setChannelMask", "(I)Landroid/media/AudioFormat$Builder;", MP_JNI_METHOD, OFFSET(setChannelMask), 0},
{"android/media/AudioFormat$Builder", "build", "()Landroid/media/AudioFormat;", MP_JNI_METHOD, OFFSET(build), 0},
{0}
#undef OFFSET
}};
struct JNIAudioManager {
jclass clazz;
jint ERROR_DEAD_OBJECT;
@@ -219,22 +276,64 @@ struct JNIAudioTimestamp {
#undef OFFSET
}};
#define MP_JNI_DELETELOCAL(o) (*env)->DeleteLocalRef(env, o)
static int AudioTrack_New(struct ao *ao)
{
struct priv *p = ao->priv;
JNIEnv *env = MP_JNI_GET_ENV(ao);
jobject audiotrack = NULL;
jobject audiotrack = MP_JNI_NEW(
AudioTrack.clazz,
AudioTrack.ctor,
AudioManager.STREAM_MUSIC,
p->samplerate,
p->channel_config,
p->format,
p->size,
AudioTrack.MODE_STREAM,
p->cfg_session_id
);
if (AudioTrack.ctorV21) {
MP_VERBOSE(ao, "Using API21 initializer\n");
jobject tmp = NULL;
jobject format_builder = MP_JNI_NEW(AudioFormatBuilder.clazz, AudioFormatBuilder.ctor);
MP_JNI_EXCEPTION_LOG(ao);
tmp = MP_JNI_CALL_OBJECT(format_builder, AudioFormatBuilder.setEncoding, p->format);
MP_JNI_DELETELOCAL(tmp);
tmp = MP_JNI_CALL_OBJECT(format_builder, AudioFormatBuilder.setSampleRate, p->samplerate);
MP_JNI_DELETELOCAL(tmp);
tmp = MP_JNI_CALL_OBJECT(format_builder, AudioFormatBuilder.setChannelMask, p->channel_config);
MP_JNI_DELETELOCAL(tmp);
jobject format = MP_JNI_CALL_OBJECT(format_builder, AudioFormatBuilder.build);
MP_JNI_DELETELOCAL(format_builder);
jobject attr_builder = MP_JNI_NEW(AudioAttributesBuilder.clazz, AudioAttributesBuilder.ctor);
MP_JNI_EXCEPTION_LOG(ao);
tmp = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.setUsage, AudioAttributes.USAGE_MEDIA);
MP_JNI_DELETELOCAL(tmp);
tmp = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.setContentType, AudioAttributes.CONTENT_TYPE_MOVIE);
MP_JNI_DELETELOCAL(tmp);
jobject attr = MP_JNI_CALL_OBJECT(attr_builder, AudioAttributesBuilder.build);
MP_JNI_DELETELOCAL(attr_builder);
audiotrack = MP_JNI_NEW(
AudioTrack.clazz,
AudioTrack.ctorV21,
attr,
format,
p->size,
AudioTrack.MODE_STREAM,
p->cfg_session_id
);
MP_JNI_DELETELOCAL(format);
MP_JNI_DELETELOCAL(attr);
} else {
MP_VERBOSE(ao, "Using legacy initializer\n");
audiotrack = MP_JNI_NEW(
AudioTrack.clazz,
AudioTrack.ctor,
AudioManager.STREAM_MUSIC,
p->samplerate,
p->channel_config,
p->format,
p->size,
AudioTrack.MODE_STREAM,
p->cfg_session_id
);
}
if (!audiotrack || MP_JNI_EXCEPTION_LOG(ao) < 0) {
MP_FATAL(ao, "AudioTrack Init failed\n");
return -1;
@@ -248,6 +347,14 @@ static int AudioTrack_New(struct ao *ao)
return -1;
}
if (AudioTrack.getBufferSizeInFramesV23) {
int bufferSize = MP_JNI_CALL_INT(audiotrack, AudioTrack.getBufferSizeInFramesV23);
if (bufferSize > 0) {
MP_VERBOSE(ao, "AudioTrack.getBufferSizeInFrames = %d\n", bufferSize);
ao->device_buffer = bufferSize;
}
}
p->audiotrack = (*env)->NewGlobalRef(env, audiotrack);
(*env)->DeleteLocalRef(env, audiotrack);
if (!p->audiotrack)
@@ -372,12 +479,12 @@ static double AudioTrack_getLatency(struct ao *ao)
if (!p->timestamp_set &&
p->format != AudioFormat.ENCODING_IEC61937)
delay += (double)MP_JNI_CALL_INT(p->audiotrack, AudioTrack.getLatency)/1000.0;
if (delay > 1.0) {
if (delay > 2.0) {
//MP_WARN(ao, "getLatency: written=%u playhead=%u diff=%u delay=%f\n", p->written_frames, playhead, diff, delay);
p->timestamp_fetched = 0;
return 0;
}
return MPCLAMP(delay, 0.0, 1.0);
return MPCLAMP(delay, 0.0, 2.0);
}
static int AudioTrack_write(struct ao *ao, int len)
@@ -427,6 +534,9 @@ static void uninit_jni(struct ao *ao)
mp_jni_reset_jfields(env, &AudioTimestamp, AudioTimestamp.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &AudioManager, AudioManager.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &AudioFormat, AudioFormat.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &AudioFormatBuilder, AudioFormatBuilder.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &AudioAttributes, AudioAttributes.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &AudioAttributesBuilder, AudioAttributesBuilder.mapping, 1, ao->log);
mp_jni_reset_jfields(env, &ByteBuffer, ByteBuffer.mapping, 1, ao->log);
}
@@ -437,6 +547,9 @@ static int init_jni(struct ao *ao)
mp_jni_init_jfields(env, &ByteBuffer, ByteBuffer.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioTimestamp, AudioTimestamp.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioManager, AudioManager.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioAttributes, AudioAttributes.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioAttributesBuilder, AudioAttributesBuilder.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioFormatBuilder, AudioFormatBuilder.mapping, 1, ao->log) < 0 ||
mp_jni_init_jfields(env, &AudioFormat, AudioFormat.mapping, 1, ao->log) < 0) {
uninit_jni(ao);
return -1;
@@ -607,15 +720,16 @@ static int init(struct ao *ao)
MP_FATAL(ao, "AudioTrack.getMinBufferSize returned an invalid size: %d", buffer_size);
return -1;
}
p->chunksize = buffer_size;
p->chunk = malloc(buffer_size);
int min = 0.200 * p->samplerate * af_fmt_to_bytes(ao->format);
int max = min * 3 / 2;
int min = 0.075 * p->samplerate * af_fmt_to_bytes(ao->format) * ao->channels.num;
int max = min * 2;
p->size = MPCLAMP(buffer_size * 2, min, max);
MP_VERBOSE(ao, "Setting bufferSize = %d (driver=%d, min=%d, max=%d)\n", p->size, buffer_size, min, max);
ao->device_buffer = p->size / af_fmt_to_bytes(ao->format);
p->chunksize = p->size;
p->chunk = malloc(p->size);
jobject timestamp = MP_JNI_NEW(AudioTimestamp.clazz, AudioTimestamp.ctor);
if (!timestamp || MP_JNI_EXCEPTION_LOG(ao) < 0) {
MP_FATAL(ao, "AudioTimestamp could not be created\n");
+410
View File
@@ -0,0 +1,410 @@
/*
* OSS audio output driver
*
* Original author: A'rpi
* Support for >2 output channels added 2001-11-25
* - Steve Davies <steve@daviesfam.org>
* Rozhuk Ivan <rozhuk.im@gmail.com> 2020
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <sys/stat.h>
#if defined(__DragonFly__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
#endif
#include <sys/types.h>
#include "config.h"
#include "audio/format.h"
#include "common/msg.h"
#include "options/options.h"
#include "osdep/endian.h"
#include "osdep/io.h"
#include "ao.h"
#include "internal.h"
#ifndef AFMT_AC3
#define AFMT_AC3 -1
#endif
#define PATH_DEV_DSP "/dev/dsp"
struct priv {
int dsp_fd;
bool playing;
double bps; /* Bytes per second. */
};
/* like alsa except for 6.1 and 7.1, from pcm/matrix_map.h */
static const struct mp_chmap oss_layouts[MP_NUM_CHANNELS + 1] = {
{0}, /* empty */
MP_CHMAP_INIT_MONO, /* mono */
MP_CHMAP2(FL, FR), /* stereo */
MP_CHMAP3(FL, FR, LFE), /* 2.1 */
MP_CHMAP4(FL, FR, BL, BR), /* 4.0 */
MP_CHMAP5(FL, FR, BL, BR, FC), /* 5.0 */
MP_CHMAP6(FL, FR, BL, BR, FC, LFE), /* 5.1 */
MP_CHMAP7(FL, FR, BL, BR, FC, LFE, BC), /* 6.1 */
MP_CHMAP8(FL, FR, BL, BR, FC, LFE, SL, SR), /* 7.1 */
};
#if !defined(AFMT_S32_NE) && defined(AFMT_S32_LE) && defined(AFMT_S32_BE)
#define AFMT_S32_NE AFMT_S32MP_SELECT_LE_BE(AFMT_S32_LE, AFMT_S32_BE)
#endif
static const int format_table[][2] = {
{AFMT_U8, AF_FORMAT_U8},
{AFMT_S16_NE, AF_FORMAT_S16},
#ifdef AFMT_S32_NE
{AFMT_S32_NE, AF_FORMAT_S32},
#endif
#ifdef AFMT_FLOAT
{AFMT_FLOAT, AF_FORMAT_FLOAT},
#endif
#ifdef AFMT_MPEG
{AFMT_MPEG, AF_FORMAT_S_MP3},
#endif
{-1, -1}
};
#define MP_WARN_IOCTL_ERR(__ao) \
MP_WARN((__ao), "%s: ioctl() fail, err = %i: %s\n", \
__FUNCTION__, errno, strerror(errno))
static void uninit(struct ao *ao);
static void device_descr_get(size_t dev_idx, char *buf, size_t buf_size)
{
#if defined(__DragonFly__) || defined(__FreeBSD__)
char dev_path[32];
size_t tmp = (buf_size - 1);
snprintf(dev_path, sizeof(dev_path), "dev.pcm.%zu.%%desc", dev_idx);
if (sysctlbyname(dev_path, buf, &tmp, NULL, 0) != 0) {
tmp = 0;
}
buf[tmp] = 0x00;
#elif defined(SOUND_MIXER_INFO)
size_t tmp = 0;
char dev_path[32];
mixer_info mi;
snprintf(dev_path, sizeof(dev_path), PATH_DEV_MIXER"%zu", dev_idx);
int fd = open(dev_path, O_RDONLY);
if (ioctl(fd, SOUND_MIXER_INFO, &mi) == 0) {
strncpy(buf, mi.name, buf_size);
tmp = (buf_size - 1);
}
close(fd);
buf[tmp] = 0x00;
#else
buf[0] = 0x00;
#endif
}
static int format2oss(int format)
{
for (size_t i = 0; format_table[i][0] != -1; i++) {
if (format_table[i][1] == format)
return format_table[i][0];
}
return -1;
}
static bool try_format(struct ao *ao, int *format)
{
struct priv *p = ao->priv;
int oss_format = format2oss(*format);
if (oss_format == -1 && af_fmt_is_spdif(*format))
oss_format = AFMT_AC3;
if (oss_format == -1) {
MP_VERBOSE(ao, "Unknown/not supported internal format: %s\n",
af_fmt_to_str(*format));
*format = 0;
return false;
}
return (ioctl(p->dsp_fd, SNDCTL_DSP_SETFMT, &oss_format) != -1);
}
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
struct mp_chmap channels = ao->channels;
audio_buf_info info;
size_t i;
int format, samplerate, nchannels, reqchannels, trig = 0;
int best_sample_formats[AF_FORMAT_COUNT + 1];
const char *device = ((ao->device) ? ao->device : PATH_DEV_DSP);
/* Opening device. */
MP_VERBOSE(ao, "Using '%s' audio device.\n", device);
p->dsp_fd = open(device, (O_WRONLY | O_CLOEXEC));
if (p->dsp_fd < 0) {
MP_ERR(ao, "Can't open audio device %s: %s.\n",
device, mp_strerror(errno));
goto err_out;
}
/* Selecting sound format. */
format = af_fmt_from_planar(ao->format);
af_get_best_sample_formats(format, best_sample_formats);
for (i = 0; best_sample_formats[i]; i++) {
format = best_sample_formats[i];
if (try_format(ao, &format))
break;
}
if (!format) {
MP_ERR(ao, "Can't set sample format.\n");
goto err_out;
}
MP_VERBOSE(ao, "Sample format: %s\n", af_fmt_to_str(format));
/* Channels count. */
if (af_fmt_is_spdif(format)) {
/* Probably could be fixed by setting number of channels;
* needs testing. */
if (channels.num != 2) {
MP_ERR(ao, "Format %s not implemented.\n", af_fmt_to_str(format));
goto err_out;
}
} else {
struct mp_chmap_sel sel = {0};
for (i = 0; i < MP_ARRAY_SIZE(oss_layouts); i++) {
mp_chmap_sel_add_map(&sel, &oss_layouts[i]);
}
if (!ao_chmap_sel_adjust(ao, &sel, &channels))
goto err_out;
nchannels = reqchannels = channels.num;
if (ioctl(p->dsp_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
MP_ERR(ao, "Failed to set audio device to %d channels.\n",
reqchannels);
goto err_out_ioctl;
}
if (nchannels != reqchannels) {
/* Update number of channels to OSS suggested value. */
if (!ao_chmap_sel_get_def(ao, &sel, &channels, nchannels))
goto err_out;
}
MP_VERBOSE(ao, "Using %d channels (requested: %d).\n",
channels.num, reqchannels);
}
/* Sample rate. */
samplerate = ao->samplerate;
if (ioctl(p->dsp_fd, SNDCTL_DSP_SPEED, &samplerate) == -1)
goto err_out_ioctl;
MP_VERBOSE(ao, "Using %d Hz samplerate.\n", samplerate);
/* Get buffer size. */
if (ioctl(p->dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
goto err_out_ioctl;
/* See ao.c ao->sstride initializations and get_state(). */
ao->device_buffer = ((info.fragstotal * info.fragsize) /
af_fmt_to_bytes(format));
if (!af_fmt_is_planar(format)) {
ao->device_buffer /= channels.num;
}
/* Do not start playback after data written. */
if (ioctl(p->dsp_fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1)
goto err_out_ioctl;
/* Update sound params. */
ao->format = format;
ao->samplerate = samplerate;
ao->channels = channels;
p->bps = (channels.num * samplerate * af_fmt_to_bytes(format));
p->playing = false;
return 0;
err_out_ioctl:
MP_WARN_IOCTL_ERR(ao);
err_out:
uninit(ao);
return -1;
}
static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->dsp_fd == -1)
return;
ioctl(p->dsp_fd, SNDCTL_DSP_HALT, NULL);
close(p->dsp_fd);
p->dsp_fd = -1;
p->playing = false;
}
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
struct priv *p = ao->priv;
ao_control_vol_t *vol = (ao_control_vol_t *)arg;
int v;
if (p->dsp_fd < 0)
return CONTROL_ERROR;
switch (cmd) {
case AOCONTROL_GET_VOLUME:
if (ioctl(p->dsp_fd, SNDCTL_DSP_GETPLAYVOL, &v) == -1) {
MP_WARN_IOCTL_ERR(ao);
return CONTROL_ERROR;
}
vol->right = ((v & 0xff00) >> 8);
vol->left = (v & 0x00ff);
return CONTROL_OK;
case AOCONTROL_SET_VOLUME:
v = ((int)vol->right << 8) | (int)vol->left;
if (ioctl(p->dsp_fd, SNDCTL_DSP_SETPLAYVOL, &v) == -1) {
MP_WARN_IOCTL_ERR(ao);
return CONTROL_ERROR;
}
return CONTROL_OK;
}
return CONTROL_UNKNOWN;
}
static void reset(struct ao *ao)
{
struct priv *p = ao->priv;
int trig = 0;
/* Clear buf and do not start playback after data written. */
p->playing = false;
if (ioctl(p->dsp_fd, SNDCTL_DSP_HALT, NULL) == -1 ||
ioctl(p->dsp_fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1)
{
MP_WARN_IOCTL_ERR(ao);
MP_WARN(ao, "Force reinitialize audio device.\n");
uninit(ao);
init(ao);
}
}
static void start(struct ao *ao)
{
struct priv *p = ao->priv;
int trig = PCM_ENABLE_OUTPUT;
if (ioctl(p->dsp_fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1) {
MP_WARN_IOCTL_ERR(ao);
return;
}
p->playing = true;
}
static bool audio_write(struct ao *ao, void **data, int samples)
{
struct priv *p = ao->priv;
ssize_t rc;
const size_t size = (samples * ao->sstride);
if (size == 0)
return true;
while ((rc = write(p->dsp_fd, data[0], size)) == -1) {
if (errno == EINTR)
continue;
MP_WARN(ao, "audio_write: write() fail, err = %i: %s.\n",
errno, strerror(errno));
p->playing = false;
return false;
}
if ((size_t)rc != size) {
MP_WARN(ao, "audio_write: unexpected partial write: required: %zu, written: %zu.\n",
size, (size_t)rc);
p->playing = false;
return false;
}
return true;
}
static void get_state(struct ao *ao, struct mp_pcm_state *state)
{
struct priv *p = ao->priv;
audio_buf_info info;
int odelay;
if (ioctl(p->dsp_fd, SNDCTL_DSP_GETOSPACE, &info) == -1 ||
ioctl(p->dsp_fd, SNDCTL_DSP_GETODELAY, &odelay) == -1)
{
MP_WARN_IOCTL_ERR(ao);
p->playing = false;
memset(state, 0x00, sizeof(struct mp_pcm_state));
state->delay = 0.0;
return;
}
state->free_samples = (info.bytes / ao->sstride);
state->queued_samples = (ao->device_buffer - state->free_samples);
state->delay = (odelay / p->bps);
state->playing = p->playing;
}
static void list_devs(struct ao *ao, struct ao_device_list *list)
{
struct stat st;
char dev_path[32] = PATH_DEV_DSP, dev_descr[256] = "Default";
struct ao_device_desc dev = {.name = dev_path, .desc = dev_descr};
if (stat(PATH_DEV_DSP, &st) == 0) {
ao_device_list_add(list, ao, &dev);
}
/* Auto detect. */
for (size_t i = 0, fail_cnt = 0; fail_cnt < 8; i ++, fail_cnt ++) {
snprintf(dev_path, sizeof(dev_path), PATH_DEV_DSP"%zu", i);
if (stat(dev_path, &st) != 0)
continue;
device_descr_get(i, dev_descr, sizeof(dev_descr));
ao_device_list_add(list, ao, &dev);
fail_cnt = 0; /* Reset fail counter. */
}
}
const struct ao_driver audio_out_oss = {
.name = "oss",
.description = "OSS/ioctl audio output",
.init = init,
.uninit = uninit,
.control = control,
.reset = reset,
.start = start,
.write = audio_write,
.get_state = get_state,
.list_devs = list_devs,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.dsp_fd = -1,
.playing = false,
},
};
+12 -13
View File
@@ -535,6 +535,7 @@ static void reset(struct ao *ao)
cork(ao, true);
struct priv *priv = ao->priv;
pa_threaded_mainloop_lock(priv->mainloop);
priv->playing = false;
priv->retval = 0;
if (!waitop(priv, pa_stream_flush(priv->stream, success_cb, ao)) ||
!priv->retval)
@@ -696,9 +697,8 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
case AOCONTROL_SET_MUTE:
case AOCONTROL_SET_VOLUME: {
pa_operation *o;
pa_threaded_mainloop_lock(priv->mainloop);
priv->retval = 0;
uint32_t stream_index = pa_stream_get_index(priv->stream);
if (cmd == AOCONTROL_SET_VOLUME) {
const ao_control_vol_t *vol = arg;
@@ -711,27 +711,26 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
volume.values[0] = VOL_MP2PA(vol->left);
volume.values[1] = VOL_MP2PA(vol->right);
}
o = pa_context_set_sink_input_volume(priv->context, stream_index,
&volume, NULL, NULL);
if (!o) {
pa_threaded_mainloop_unlock(priv->mainloop);
if (!waitop(priv, pa_context_set_sink_input_volume(priv->context,
stream_index,
&volume,
context_success_cb, ao)) ||
!priv->retval) {
GENERIC_ERR_MSG("pa_context_set_sink_input_volume() failed");
return CONTROL_ERROR;
}
} else if (cmd == AOCONTROL_SET_MUTE) {
const bool *mute = arg;
o = pa_context_set_sink_input_mute(priv->context, stream_index,
*mute, NULL, NULL);
if (!o) {
pa_threaded_mainloop_unlock(priv->mainloop);
if (!waitop(priv, pa_context_set_sink_input_mute(priv->context,
stream_index,
*mute,
context_success_cb, ao)) ||
!priv->retval) {
GENERIC_ERR_MSG("pa_context_set_sink_input_mute() failed");
return CONTROL_ERROR;
}
} else
abort();
/* We don't wait for completion here */
pa_operation_unref(o);
pa_threaded_mainloop_unlock(priv->mainloop);
return CONTROL_OK;
}
+3 -8
View File
@@ -2,8 +2,8 @@
# This script simply downloads waf to the current directory
from __future__ import print_function
import os, sys, stat, hashlib, subprocess
from urllib.request import urlopen, URLError
WAFRELEASE = "waf-2.0.20"
WAFURLS = ["https://waf.io/" + WAFRELEASE,
@@ -20,11 +20,6 @@ if "--no-download" in sys.argv[1:]:
print("Did not find {} and no download was requested.".format(WAFRELEASE))
sys.exit(1)
try:
from urllib.request import urlopen, URLError
except:
from urllib2 import urlopen, URLError
waf = None
for WAFURL in WAFURLS:
@@ -32,8 +27,8 @@ for WAFURL in WAFURLS:
print("Downloading {}...".format(WAFURL))
waf = urlopen(WAFURL).read()
break
except URLError:
print("Download failed.")
except URLError as err:
print("Download failed! ({})".format(err))
if not waf:
print("Could not download {}.".format(WAFRELEASE))
+3 -3
View File
@@ -99,7 +99,7 @@ fi
## freetype2
if [ ! -e "$prefix_dir/lib/libfreetype.dll.a" ]; then
ver=2.10.2
ver=2.11.0
gettar "https://download.savannah.gnu.org/releases/freetype/freetype-${ver}.tar.gz"
builddir freetype-${ver}
ZLIB_LIBS="-L'$prefix_dir/lib' -lz" \
@@ -111,7 +111,7 @@ fi
## fribidi
if [ ! -e "$prefix_dir/lib/libfribidi.dll.a" ]; then
ver=1.0.9
ver=1.0.11
gettar "https://github.com/fribidi/fribidi/releases/download/v${ver}/fribidi-${ver}.tar.xz"
builddir fribidi-${ver}
../configure --host=$TARGET $commonflags
@@ -121,7 +121,7 @@ fi
## harfbuzz
if [ ! -e "$prefix_dir/lib/libharfbuzz.dll.a" ]; then
ver=2.7.2
ver=3.0.0
gettar "https://github.com/harfbuzz/harfbuzz/releases/download/${ver}/harfbuzz-${ver}.tar.xz"
builddir harfbuzz-${ver}
../configure --host=$TARGET $commonflags --with-icu=no
+17 -6
View File
@@ -80,12 +80,23 @@ AVCodecParameters *mp_codec_params_to_av(struct mp_codec_params *c)
avp->codec_id = mp_codec_to_av_codec_id(c->codec);
avp->codec_tag = c->codec_tag;
if (c->extradata_size) {
avp->extradata =
av_mallocz(c->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
uint8_t *extradata = c->extradata;
int size = c->extradata_size;
if (avp->codec_id == AV_CODEC_ID_FLAC) {
// ffmpeg expects FLAC extradata to be just the STREAMINFO,
// so grab only that (and assume it'll be the first block)
if (size >= 8 && !memcmp(c->extradata, "fLaC", 4)) {
extradata += 8;
size = MPMIN(34, size - 8); // FLAC_STREAMINFO_SIZE
}
}
avp->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!avp->extradata)
goto error;
avp->extradata_size = c->extradata_size;
memcpy(avp->extradata, c->extradata, avp->extradata_size);
avp->extradata_size = size;
memcpy(avp->extradata, extradata, size);
}
avp->bits_per_coded_sample = c->bits_per_coded_sample;
@@ -270,7 +281,7 @@ int mp_codec_to_av_codec_id(const char *codec)
if (desc)
id = desc->id;
if (id == AV_CODEC_ID_NONE) {
AVCodec *avcodec = avcodec_find_decoder_by_name(codec);
const AVCodec *avcodec = avcodec_find_decoder_by_name(codec);
if (avcodec)
id = avcodec->id;
}
@@ -285,7 +296,7 @@ const char *mp_codec_from_av_codec_id(int codec_id)
if (desc)
name = desc->name;
if (!name) {
AVCodec *avcodec = avcodec_find_decoder(codec_id);
const AVCodec *avcodec = avcodec_find_decoder(codec_id);
if (avcodec)
name = avcodec->name;
}
+3 -3
View File
@@ -735,7 +735,7 @@ static void encoder_destroy(void *ptr)
free_stream(p->twopass_bytebuffer);
}
static AVCodec *find_codec_for(struct encode_lavc_context *ctx,
static const AVCodec *find_codec_for(struct encode_lavc_context *ctx,
enum stream_type type, bool *used_auto)
{
char *codec_name = type == STREAM_VIDEO
@@ -746,7 +746,7 @@ static AVCodec *find_codec_for(struct encode_lavc_context *ctx,
*used_auto = !(codec_name && codec_name[0]);
AVCodec *codec;
const AVCodec *codec;
if (*used_auto) {
codec = avcodec_find_encoder(av_guess_codec(ctx->oformat, NULL,
ctx->options->file, NULL,
@@ -797,7 +797,7 @@ struct encoder_context *encoder_context_alloc(struct encode_lavc_context *ctx,
};
bool auto_codec;
AVCodec *codec = find_codec_for(ctx, type, &auto_codec);
const AVCodec *codec = find_codec_for(ctx, type, &auto_codec);
const char *tname = stream_type_name(type);
if (!codec) {
+2 -2
View File
@@ -41,7 +41,7 @@ struct encode_lavc_context {
struct encode_opts *options;
struct mp_log *log;
struct encode_priv *priv;
AVOutputFormat *oformat;
const AVOutputFormat *oformat;
const char *filename;
// All entry points must be guarded with the lock. Functions called by
@@ -71,7 +71,7 @@ struct encoder_context {
struct mpv_global *global;
struct encode_opts *options;
struct mp_log *log;
AVOutputFormat *oformat;
const AVOutputFormat *oformat;
// (avoid using this)
struct encode_lavc_context *encode_lavc_ctx;
+2 -2
View File
@@ -126,6 +126,8 @@ static void update_loglevel(struct mp_log *log)
struct mp_log_root *root = log->root;
pthread_mutex_lock(&root->lock);
log->level = MSGL_STATUS + root->verbose; // default log level
if (root->really_quiet)
log->level = -1;
for (int n = 0; root->msg_levels && root->msg_levels[n * 2 + 0]; n++) {
if (match_mod(log->verbose_prefix, root->msg_levels[n * 2 + 0]))
log->level = mp_msg_find_level(root->msg_levels[n * 2 + 1]);
@@ -143,8 +145,6 @@ static void update_loglevel(struct mp_log *log)
if (log->root->stats_file)
log->level = MPMAX(log->level, MSGL_STATS);
log->level = MPMIN(log->level, log->max_level);
if (root->really_quiet)
log->level = -1;
atomic_store(&log->reload_counter, atomic_load(&log->root->reload_counter));
pthread_mutex_unlock(&root->lock);
}
+48 -21
View File
@@ -23,6 +23,7 @@
#include "common/common.h"
#include "common/global.h"
#include "common/msg.h"
#include "demux/demux.h"
#include "demux/packet.h"
#include "demux/stheader.h"
@@ -91,6 +92,12 @@ static int add_stream(struct mp_recorder *priv, struct sh_stream *sh)
if (!avp)
return -1;
// Check if we get the same codec_id for the output format;
// otherwise clear it to have a chance at muxing
if (av_codec_get_id(priv->mux->oformat->codec_tag,
avp->codec_tag) != avp->codec_id)
avp->codec_tag = 0;
// We don't know the delay, so make something up. If the format requires
// DTS, the result will probably be broken. FFmpeg provides nothing better
// yet (unless you demux with libavformat, which contains tons of hacks
@@ -113,7 +120,9 @@ static int add_stream(struct mp_recorder *priv, struct sh_stream *sh)
struct mp_recorder *mp_recorder_create(struct mpv_global *global,
const char *target_file,
struct sh_stream **streams,
int num_streams)
int num_streams,
struct demux_attachment **attachments,
int num_attachments)
{
struct mp_recorder *priv = talloc_zero(NULL, struct mp_recorder);
@@ -147,6 +156,35 @@ struct mp_recorder *mp_recorder_create(struct mpv_global *global,
}
}
if (!strcmp(priv->mux->oformat->name, "matroska")) {
// Only attach attachments (fonts) to matroska - mp4, nut, mpegts don't
// like them, and we find that out too late in the muxing process.
AVStream *a_stream = NULL;
for (int i = 0; i < num_attachments; ++i) {
a_stream = avformat_new_stream(priv->mux, NULL);
if (!a_stream) {
MP_ERR(priv, "Can't mux one of the attachments.\n");
goto error;
}
struct demux_attachment *attachment = attachments[i];
a_stream->codecpar->codec_type = AVMEDIA_TYPE_ATTACHMENT;
a_stream->codecpar->extradata = av_mallocz(
attachment->data_size + AV_INPUT_BUFFER_PADDING_SIZE
);
if (!a_stream->codecpar->extradata) {
goto error;
}
memcpy(a_stream->codecpar->extradata,
attachment->data, attachment->data_size);
a_stream->codecpar->extradata_size = attachment->data_size;
av_dict_set(&a_stream->metadata, "filename", attachment->name, 0);
av_dict_set(&a_stream->metadata, "mimetype", attachment->type, 0);
}
}
// Not sure how to write this in a "standard" way. It appears only mkv
// and mp4 support this directly.
char version[200];
@@ -217,30 +255,19 @@ static void mux_packet(struct mp_recorder_sink *rst,
MP_ERR(priv, "Failed writing packet.\n");
}
// Write all packets that currently can be written.
static void mux_packets(struct mp_recorder_sink *rst, bool force)
// Write all packets available in the stream queue
static void mux_packets(struct mp_recorder_sink *rst)
{
struct mp_recorder *priv = rst->owner;
if (!priv->muxing || !rst->num_packets)
return;
int safe_count = 0;
for (int n = 0; n < rst->num_packets; n++) {
if (rst->packets[n]->keyframe)
safe_count = n;
}
if (force)
safe_count = rst->num_packets;
for (int n = 0; n < safe_count; n++) {
mux_packet(rst, rst->packets[n]);
talloc_free(rst->packets[n]);
}
// Remove packets[0..safe_count]
memmove(&rst->packets[0], &rst->packets[safe_count],
(rst->num_packets - safe_count) * sizeof(rst->packets[0]));
rst->num_packets -= safe_count;
rst->num_packets = 0;
}
// If there was a discontinuity, check whether we can resume muxing (and from
@@ -291,7 +318,7 @@ void mp_recorder_destroy(struct mp_recorder *priv)
if (priv->opened) {
for (int n = 0; n < priv->num_streams; n++) {
struct mp_recorder_sink *rst = priv->streams[n];
mux_packets(rst, true);
mux_packets(rst);
}
if (av_write_trailer(priv->mux) < 0)
@@ -312,15 +339,15 @@ void mp_recorder_destroy(struct mp_recorder *priv)
// This is called on a seek, or when recording was started mid-stream.
void mp_recorder_mark_discontinuity(struct mp_recorder *priv)
{
flush_packets(priv);
for (int n = 0; n < priv->num_streams; n++) {
struct mp_recorder_sink *rst = priv->streams[n];
mux_packets(rst, true);
mux_packets(rst);
rst->discont = true;
rst->proper_eof = false;
}
flush_packets(priv);
priv->muxing = false;
priv->muxing_from_start = false;
}
@@ -350,7 +377,7 @@ void mp_recorder_feed_packet(struct mp_recorder_sink *rst,
if (!pkt) {
rst->proper_eof = true;
check_restart(priv);
mux_packets(rst, false);
mux_packets(rst);
return;
}
@@ -359,7 +386,7 @@ void mp_recorder_feed_packet(struct mp_recorder_sink *rst,
// No, FFmpeg doesn't tell us which formats need DTS at all.
// No, we can not shut up the FFmpeg warning, which will follow.
MP_WARN(priv, "Source stream misses DTS on at least some packets!\n"
"If the target file format requires DTS, the written\n"
"If the target file format requires DTS, the written "
"file will be invalid.\n");
priv->dts_warning = true;
}
@@ -380,5 +407,5 @@ void mp_recorder_feed_packet(struct mp_recorder_sink *rst,
MP_TARRAY_APPEND(rst, rst->packets, rst->num_packets, pkt);
check_restart(priv);
mux_packets(rst, false);
mux_packets(rst);
}
+4 -1
View File
@@ -5,12 +5,15 @@ struct mp_recorder;
struct mpv_global;
struct demux_packet;
struct sh_stream;
struct demux_attachment;
struct mp_recorder_sink;
struct mp_recorder *mp_recorder_create(struct mpv_global *global,
const char *target_file,
struct sh_stream **streams,
int num_streams);
int num_streams,
struct demux_attachment **demux_attachments,
int num_attachments);
void mp_recorder_destroy(struct mp_recorder *r);
void mp_recorder_mark_discontinuity(struct mp_recorder *r);
+39 -8
View File
@@ -121,8 +121,7 @@ const struct m_sub_options demux_conf = {
M_RANGE(0, M_MAX_MEM_BYTES)},
{"demuxer-donate-buffer", OPT_FLAG(donate_fw)},
{"force-seekable", OPT_FLAG(force_seekable)},
{"cache-secs", OPT_DOUBLE(min_secs_cache), M_RANGE(0, DBL_MAX),
.deprecation_message = "will use unlimited time"},
{"cache-secs", OPT_DOUBLE(min_secs_cache), M_RANGE(0, DBL_MAX)},
{"access-references", OPT_FLAG(access_references)},
{"demuxer-seekable-cache", OPT_CHOICE(seekable_cache,
{"auto", -1}, {"no", 0}, {"yes", 1})},
@@ -1945,9 +1944,18 @@ static struct mp_recorder *recorder_create(struct demux_internal *in,
if (stream->ds->selected)
MP_TARRAY_APPEND(NULL, streams, num_streams, stream);
}
struct demuxer *demuxer = in->d_thread;
struct demux_attachment **attachments = talloc_array(NULL, struct demux_attachment*, demuxer->num_attachments);
for (int n = 0; n < demuxer->num_attachments; n++) {
attachments[n] = &demuxer->attachments[n];
}
struct mp_recorder *res = mp_recorder_create(in->d_thread->global, dst,
streams, num_streams);
streams, num_streams,
attachments, demuxer->num_attachments);
talloc_free(streams);
talloc_free(attachments);
return res;
}
@@ -2827,7 +2835,7 @@ done:
return out_pkt;
}
void demuxer_help(struct mp_log *log)
int demuxer_help(struct mp_log *log, const m_option_t *opt, struct bstr name)
{
int i;
@@ -2837,6 +2845,9 @@ void demuxer_help(struct mp_log *log)
mp_info(log, "%10s %s\n",
demuxer_list[i]->name, demuxer_list[i]->desc);
}
mp_info(log, "\n");
return M_OPT_EXIT;
}
static const char *d_level(enum demux_check level)
@@ -3970,6 +3981,26 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
pthread_mutex_unlock(&in->lock);
}
// Execute a refresh seek on the given stream.
// ref_pts has the same meaning as with demuxer_select_track()
void demuxer_refresh_track(struct demuxer *demuxer, struct sh_stream *stream,
double ref_pts)
{
struct demux_internal *in = demuxer->in;
struct demux_stream *ds = stream->ds;
pthread_mutex_lock(&in->lock);
ref_pts = MP_ADD_PTS(ref_pts, -in->ts_offset);
if (ds->selected) {
MP_VERBOSE(in, "refresh track %d\n", stream->index);
update_stream_selection_state(in, ds);
if (in->back_demuxing)
ds->back_seek_pos = ref_pts;
if (!in->after_seek)
initiate_refresh_seek(in, ds, ref_pts);
}
pthread_mutex_unlock(&in->lock);
}
// This is for demuxer implementations only. demuxer_select_track() sets the
// logical state, while this function returns the actual state (in case the
// demuxer attempts to cache even unselected packets for track switching - this
@@ -4106,10 +4137,10 @@ static void update_cache(struct demux_internal *in)
stream_control(stream, STREAM_CTRL_GET_METADATA, &stream_metadata);
}
update_bytes_read(in);
pthread_mutex_lock(&in->lock);
update_bytes_read(in);
if (do_update)
in->stream_size = stream_size;
if (stream_metadata) {
@@ -4144,8 +4175,8 @@ static void dumper_close(struct demux_internal *in)
static int range_time_compare(const void *p1, const void *p2)
{
struct demux_cached_range *r1 = (void *)p1;
struct demux_cached_range *r2 = (void *)p2;
struct demux_cached_range *r1 = *((struct demux_cached_range **)p1);
struct demux_cached_range *r2 = *((struct demux_cached_range **)p2);
if (r1->seek_start == r2->seek_start)
return 0;
+3 -1
View File
@@ -290,8 +290,10 @@ void demux_block_reading(struct demuxer *demuxer, bool block);
void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
double ref_pts, bool selected);
void demuxer_refresh_track(struct demuxer *demuxer, struct sh_stream *stream,
double ref_pts);
void demuxer_help(struct mp_log *log);
int demuxer_help(struct mp_log *log, const m_option_t *opt, struct bstr name);
int demuxer_add_attachment(struct demuxer *demuxer, char *name,
char *type, void *data, size_t data_size);
+16 -1
View File
@@ -32,6 +32,7 @@
#include "options/path.h"
#include "misc/bstr.h"
#include "common/common.h"
#include "common/tags.h"
#include "stream/stream.h"
#define HEADER "# mpv EDL v0\n"
@@ -60,6 +61,7 @@ struct tl_parts {
struct tl_root {
struct tl_parts **pars;
int num_pars;
struct mp_tags *tags;
};
struct priv {
@@ -171,6 +173,7 @@ static struct sh_stream *get_meta(struct tl_parts *tl, int index)
static struct tl_root *parse_edl(bstr str, struct mp_log *log)
{
struct tl_root *root = talloc_zero(NULL, struct tl_root);
root->tags = talloc_zero(root, struct mp_tags);
struct tl_parts *tl = add_part(root);
while (str.len) {
if (bstr_eatstart0(&str, "#")) {
@@ -273,6 +276,12 @@ static struct tl_root *parse_edl(bstr str, struct mp_log *log)
sh->codec->fps = get_param_int(&ctx, "fps", 0);
sh->codec->samplerate = get_param_int(&ctx, "samplerate", 0);
tl->delay_open = true;
} else if (bstr_equals0(f_type, "global_tags")) {
for (int n = 0; n < ctx.num_params; n++) {
mp_tags_set_bstr(root->tags, ctx.param_names[n],
ctx.param_vals[n]);
}
ctx.num_params = 0;
} else {
mp_err(log, "Unknown header: '%.*s'\n", BSTR_P(f_type));
goto error;
@@ -389,6 +398,7 @@ static void resolve_timestamps(struct tl_part *part, struct demuxer *demuxer)
}
static struct timeline_par *build_timeline(struct timeline *root,
struct tl_root *edl_root,
struct tl_parts *parts)
{
struct timeline_par *tl = talloc_zero(root, struct timeline_par);
@@ -542,6 +552,11 @@ static struct timeline_par *build_timeline(struct timeline *root,
if (!root->meta)
root->meta = tl->track_layout;
// Not very sane, since demuxer fields are supposed to be treated read-only
// from outside, but happens to work in this case, so who cares.
if (root->meta)
mp_tags_merge(root->meta->metadata, edl_root->tags);
assert(tl->num_parts == parts->num_parts);
return tl;
@@ -581,7 +596,7 @@ static void build_mpv_edl_timeline(struct timeline *tl)
for (int n = 0; n < root->num_pars; n++) {
struct tl_parts *parts = root->pars[n];
fix_filenames(parts, tl->demuxer->filename);
struct timeline_par *par = build_timeline(tl, parts);
struct timeline_par *par = build_timeline(tl, root, parts);
if (!par)
break;
all_dash &= par->dash;
+18 -17
View File
@@ -138,7 +138,6 @@ struct format_hack {
bool use_stream_ids : 1; // has a meaningful native stream IDs (export it)
bool fully_read : 1; // set demuxer.fully_read flag
bool detect_charset : 1; // format is a small text file, possibly not UTF8
bool image_format : 1; // expected to contain exactly 1 frame
// Do not confuse player's position estimation (position is into external
// segment, with e.g. HLS, player knows about the playlist main file only).
bool clear_filepos : 1;
@@ -205,8 +204,6 @@ static const struct format_hack format_hacks[] = {
BLACKLIST("bin"),
// Useless, does not work with custom streams.
BLACKLIST("image2"),
// Image demuxers ("<name>_pipe" is detected explicitly)
{"image2pipe", .image_format = true},
{0}
};
@@ -227,7 +224,7 @@ typedef struct lavf_priv {
bool own_stream;
char *filename;
struct format_hack format_hack;
AVInputFormat *avif;
const AVInputFormat *avif;
int avif_flags;
AVFormatContext *avfc;
AVIOContext *pb;
@@ -260,22 +257,20 @@ typedef struct lavf_priv {
static void update_read_stats(struct demuxer *demuxer)
{
#if !HAVE_FFMPEG_AVIOCONTEXT_BYTES_READ
return;
#else
lavf_priv_t *priv = demuxer->priv;
for (int n = 0; n < priv->num_nested; n++) {
struct nested_stream *nest = &priv->nested[n];
#if !HAVE_FFMPEG_STRICT_ABI
// Note: accessing the bytes_read field is not allowed by FFmpeg's API.
// This is fully intentional - there is no other way to get this
// information (not even by custom I/O, because the connection reuse
// mechanism by the HLS demuxer would get disabled).
int64_t cur = nest->id->bytes_read;
int64_t new = cur - nest->last_bytes;
nest->last_bytes = cur;
demux_report_unbuffered_read_bytes(demuxer, new);
#endif
}
#endif
}
// At least mp4 has name="mov,mp4,m4a,3gp,3g2,mj2", so we split the name
@@ -443,7 +438,7 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
if (!lavfdopts->allow_mimetype || !mime_type)
mime_type = "";
AVInputFormat *forced_format = NULL;
const AVInputFormat *forced_format = NULL;
const char *format = lavfdopts->format;
if (!format)
format = s->lavf_type;
@@ -528,11 +523,6 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
return -1;
}
if (bstr_endswith0(bstr0(priv->avif->name), "_pipe")) {
MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
priv->format_hack.image_format = true;
}
if (lavfdopts->hacks)
priv->avif_flags = priv->avif->flags | priv->format_hack.if_flags;
@@ -714,8 +704,17 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->codec->disp_h = codec->height;
if (st->avg_frame_rate.num)
sh->codec->fps = av_q2d(st->avg_frame_rate);
if (priv->format_hack.image_format)
if (st->nb_frames <= 1 && (
sh->attached_picture ||
bstr_endswith0(bstr0(priv->avif->name), "_pipe") ||
strcmp(priv->avif->name, "alias_pix") == 0 ||
strcmp(priv->avif->name, "gif") == 0 ||
strcmp(priv->avif->name, "image2pipe") == 0
)) {
MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
sh->image = true;
sh->codec->fps = priv->mf_fps;
}
sh->codec->par_w = st->sample_aspect_ratio.num;
sh->codec->par_h = st->sample_aspect_ratio.den;
@@ -1354,6 +1353,8 @@ static void demux_close_lavf(demuxer_t *demuxer)
}
if (priv->own_stream)
free_stream(priv->stream);
if (priv->av_opts)
av_dict_free(&priv->av_opts);
talloc_free(priv);
demuxer->priv = NULL;
}
+44 -3
View File
@@ -121,7 +121,8 @@ static mf_t *open_mf_pattern(void *talloc_ctx, struct demuxer *d, char *filename
goto exit_mf;
}
char *fname = talloc_size(mf, strlen(filename) + 32);
size_t fname_avail = strlen(filename) + 32;
char *fname = talloc_size(mf, fname_avail);
#if HAVE_GLOB
if (!strchr(filename, '%')) {
@@ -148,10 +149,44 @@ static mf_t *open_mf_pattern(void *talloc_ctx, struct demuxer *d, char *filename
}
#endif
// We're using arbitrary user input as printf format with 1 int argument.
// Any format which uses exactly 1 int argument would be valid, but for
// simplicity we reject all conversion specifiers except %% and simple
// integer specifier: %[.][NUM]d where NUM is 1-3 digits (%.d is valid)
const char *f = filename;
int MAXDIGS = 3, nspec = 0, bad_spec = 0, c;
while (nspec < 2 && (c = *f++)) {
if (c != '%')
continue;
if (*f != '%') {
nspec++; // conversion specifier which isn't %%
if (*f == '.')
f++;
for (int ndig = 0; mp_isdigit(*f) && ndig < MAXDIGS; ndig++, f++)
/* no-op */;
if (*f != 'd') {
bad_spec++; // not int, or beyond our validation capacity
break;
}
}
// *f is '%' or 'd'
f++;
}
// nspec==0 (zero specifiers) is rejected because fname wouldn't advance.
if (bad_spec || nspec != 1) {
mp_err(log, "unsupported expr format: '%s'\n", filename);
goto exit_mf;
}
mp_info(log, "search expr: %s\n", filename);
while (error_count < 5) {
sprintf(fname, filename, count++);
if (snprintf(fname, fname_avail, filename, count++) >= fname_avail) {
mp_err(log, "format result too long: '%s'\n", filename);
goto exit_mf;
}
if (!mp_path_exists(fname)) {
error_count++;
mp_verbose(log, "file not found: '%s'\n", fname);
@@ -254,6 +289,8 @@ static const struct {
{ "jls", "ljpeg" },
{ "thm", "mjpeg" },
{ "db", "mjpeg" },
{ "pcd", "photocd" },
{ "pfm", "pfm" },
{ "pcx", "pcx" },
{ "png", "png" },
{ "pns", "png" },
@@ -344,8 +381,12 @@ static int demux_open_mf(demuxer_t *demuxer, enum demux_check check)
// create a new video stream header
struct sh_stream *sh = demux_alloc_sh_stream(STREAM_VIDEO);
struct mp_codec_params *c = sh->codec;
if (mf->nr_of_files == 1) {
MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
sh->image = true;
}
struct mp_codec_params *c = sh->codec;
c->codec = codec;
c->disp_w = 0;
c->disp_h = 0;
+5
View File
@@ -1300,6 +1300,7 @@ static void add_coverart(struct demuxer *demuxer)
sh->attached_picture->pts = 0;
talloc_steal(sh, sh->attached_picture);
sh->attached_picture->keyframe = true;
sh->image = true;
}
sh->title = att->name;
demux_add_sh_stream(demuxer, sh);
@@ -1741,7 +1742,11 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
if (!strcmp(codec, "mp2") || !strcmp(codec, "mp3") ||
!strcmp(codec, "truehd") || !strcmp(codec, "eac3"))
{
mkv_demuxer_t *mkv_d = demuxer->priv;
int64_t segment_timebase = (1e9 / mkv_d->tc_scale);
track->parse = true;
track->parse_timebase = MPMAX(sh_a->samplerate, segment_timebase);
} else if (!strcmp(codec, "flac")) {
unsigned char *ptr = extradata;
unsigned int size = extradata_len;
+1 -1
View File
@@ -50,7 +50,7 @@ static bool check_mimetype(struct stream *s, const char *const *list)
struct pl_parser {
struct mp_log *log;
struct stream *s;
char buffer[512 * 1024];
char buffer[2 * 1024 * 1024];
int utf16;
struct playlist *pl;
bool error;
+1
View File
@@ -525,6 +525,7 @@ static void apply_meta(struct sh_stream *dst, struct sh_stream *src)
dst->missing_timestamps = src->missing_timestamps;
if (src->attached_picture)
dst->attached_picture = src->attached_picture;
dst->image = src->image;
}
// This is mostly for EDL user-defined metadata.
+1
View File
@@ -48,6 +48,7 @@ struct sh_stream {
bool dependent_track; // container dependent track flag
bool visual_impaired_track; // container flag
bool hearing_impaired_track;// container flag
bool image; // video stream is an image
bool still_image; // video stream contains still images
int hls_bitrate;
+4 -4
View File
@@ -42,7 +42,7 @@ function _mpv_generate_arguments {
local -a option_aliases=()
local list_options_line
for list_options_line in "${(@f)$($words[1] --list-options)}"; do
for list_options_line in "${(@f)$($~words[1] --list-options)}"; do
[[ $list_options_line =~ $'^[ \t]+--([^ \t]+)[ \t]*(.*)' ]] || continue
@@ -146,7 +146,7 @@ function _mpv_generate_arguments {
function _mpv_generate_protocols {
_mpv_completion_protocols=()
local list_protos_line
for list_protos_line in "${(@f)$($words[1] --list-protocols)}"; do
for list_protos_line in "${(@f)$($~words[1] --list-protocols)}"; do
if [[ $list_protos_line =~ $'^[ \t]+(.*)' ]]; then
_mpv_completion_protocols+="$match[1]"
fi
@@ -158,7 +158,7 @@ function _mpv_generate_if_changed {
# on the first run and re-generates it if the executable being completed for
# is different than the one we used to generate the cached list.
typeset -gA _mpv_completion_binary
local current_binary=${words[1]:c}
local current_binary=${~words[1]:c}
zmodload -F zsh/stat b:zstat
current_binary+=T$(zstat +mtime $current_binary)
if [[ $_mpv_completion_binary[$1] != $current_binary ]]; then
@@ -207,7 +207,7 @@ case $state in
esac
local -a values
local current
for current in "${(@f)$($words[1] --${option_name}=help)}"; do
for current in "${(@f)$($~words[1] --${option_name}=help)}"; do
[[ $current =~ $pattern ]] || continue;
local name=${match[name_group]//:/\\:} desc=${match[desc_group]}
if [[ -n $desc ]]; then
+97 -108
View File
@@ -29,87 +29,82 @@
#default-bindings start
#MBTN_LEFT ignore # don't do anything
#MBTN_LEFT_DBL cycle fullscreen # toggle fullscreen on/off
#MBTN_RIGHT cycle pause # toggle pause on/off
#MBTN_BACK playlist-prev
#MBTN_FORWARD playlist-next
#MBTN_LEFT_DBL cycle fullscreen # toggle fullscreen
#MBTN_RIGHT cycle pause # toggle pause/playback mode
#MBTN_BACK playlist-prev # skip to the previous file
#MBTN_FORWARD playlist-next # skip to the next file
# Mouse wheels, touchpad or other input devices that have axes
# if the input devices supports precise scrolling it will also scale the
# numeric value accordingly
#WHEEL_UP seek 10
#WHEEL_DOWN seek -10
#WHEEL_UP seek 10 # seek 10 seconds forward
#WHEEL_DOWN seek -10 # seek 10 seconds backward
#WHEEL_LEFT add volume -2
#WHEEL_RIGHT add volume 2
## Seek units are in seconds, but note that these are limited by keyframes
#RIGHT seek 5
#LEFT seek -5
#UP seek 60
#DOWN seek -60
#RIGHT seek 5 # seek 5 seconds forward
#LEFT seek -5 # seek 5 seconds backward
#UP seek 60 # seek 1 minute forward
#DOWN seek -60 # seek 1 minute backward
# Do smaller, always exact (non-keyframe-limited), seeks with shift.
# Don't show them on the OSD (no-osd).
#Shift+RIGHT no-osd seek 1 exact
#Shift+LEFT no-osd seek -1 exact
#Shift+UP no-osd seek 5 exact
#Shift+DOWN no-osd seek -5 exact
# Skip to previous/next subtitle (subject to some restrictions; see manpage)
#Ctrl+LEFT no-osd sub-seek -1
#Ctrl+RIGHT no-osd sub-seek 1
# Adjust timing to previous/next subtitle
#Ctrl+Shift+LEFT sub-step -1
#Ctrl+Shift+RIGHT sub-step 1
# Move video rectangle
#Alt+left add video-pan-x 0.1
#Alt+right add video-pan-x -0.1
#Alt+up add video-pan-y 0.1
#Alt+down add video-pan-y -0.1
# Zoom/unzoom video
#Alt++ add video-zoom 0.1
#Alt+- add video-zoom -0.1
# Reset video zoom/pan settings
#Alt+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0
#PGUP add chapter 1 # skip to next chapter
#PGDWN add chapter -1 # skip to previous chapter
#Shift+PGUP seek 600
#Shift+PGDWN seek -600
#[ multiply speed 1/1.1 # scale playback speed
#] multiply speed 1.1
#{ multiply speed 0.5
#} multiply speed 2.0
#BS set speed 1.0 # reset speed to normal
#Shift+BS revert-seek # undo previous (or marked) seek
#Shift+Ctrl+BS revert-seek mark # mark position for revert-seek
#Shift+RIGHT no-osd seek 1 exact # seek exactly 1 second forward
#Shift+LEFT no-osd seek -1 exact # seek exactly 1 second backward
#Shift+UP no-osd seek 5 exact # seek exactly 5 seconds forward
#Shift+DOWN no-osd seek -5 exact # seek exactly 5 seconds backward
#Ctrl+LEFT no-osd sub-seek -1 # seek to the previous subtitle
#Ctrl+RIGHT no-osd sub-seek 1 # seek to the next subtitle
#Ctrl+Shift+LEFT sub-step -1 # change subtitle timing such that the previous subtitle is displayed
#Ctrl+Shift+RIGHT sub-step 1 # change subtitle timing such that the next subtitle is displayed
#Alt+left add video-pan-x 0.1 # move the video right
#Alt+right add video-pan-x -0.1 # move the video left
#Alt+up add video-pan-y 0.1 # move the video down
#Alt+down add video-pan-y -0.1 # move the video up
#Alt++ add video-zoom 0.1 # zoom in
#Alt+- add video-zoom -0.1 # zoom out
#Alt+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0 # reset zoom and pan settings
#PGUP add chapter 1 # seek to the next chapter
#PGDWN add chapter -1 # seek to the previous chapter
#Shift+PGUP seek 600 # seek 10 minutes forward
#Shift+PGDWN seek -600 # seek 10 minutes backward
#[ multiply speed 1/1.1 # decrease the playback speed
#] multiply speed 1.1 # increase the playback speed
#{ multiply speed 0.5 # halve the playback speed
#} multiply speed 2.0 # double the playback speed
#BS set speed 1.0 # reset the speed to normal
#Shift+BS revert-seek # undo the previous (or marked) seek
#Shift+Ctrl+BS revert-seek mark # mark the position for revert-seek
#q quit
#Q quit-watch-later
#Q quit-watch-later # exit and remember the playback position
#q {encode} quit 4
#ESC set fullscreen no
#ESC set fullscreen no # leave fullscreen
#ESC {encode} quit 4
#p cycle pause # toggle pause/playback mode
#. frame-step # advance one frame and pause
#, frame-back-step # go back by one frame and pause
#SPACE cycle pause
#> playlist-next # skip to next file
#ENTER playlist-next # skip to next file
#< playlist-prev # skip to previous file
#O no-osd cycle-values osd-level 3 1 # cycle through OSD mode
#o show-progress
#P show-progress
#i script-binding stats/display-stats
#I script-binding stats/display-stats-toggle
#` script-binding console/enable
#z add sub-delay -0.1 # subtract 100 ms delay from subs
#Z add sub-delay +0.1 # add
#x add sub-delay +0.1 # same as previous binding (discouraged)
#ctrl++ add audio-delay 0.100 # this changes audio/video sync
#ctrl+- add audio-delay -0.100
#Shift+g add sub-scale +0.1 # increase subtitle font size
#Shift+f add sub-scale -0.1 # decrease subtitle font size
#SPACE cycle pause # toggle pause/playback mode
#> playlist-next # skip to the next file
#ENTER playlist-next # skip to the next file
#< playlist-prev # skip to the previous file
#O no-osd cycle-values osd-level 3 1 # toggle displaying the OSD on user interaction or always
#o show-progress # show playback progress
#P show-progress # show playback progress
#i script-binding stats/display-stats # display information and statistics
#I script-binding stats/display-stats-toggle # toggle displaying information and statistics
#` script-binding console/enable # open the console
#z add sub-delay -0.1 # shift subtitles 100 ms earlier
#Z add sub-delay +0.1 # delay subtitles by 100 ms
#x add sub-delay +0.1 # delay subtitles by 100 ms
#ctrl++ add audio-delay 0.100 # change audio/video sync by delaying the audio
#ctrl+- add audio-delay -0.100 # change audio/video sync by shifting the audio earlier
#Shift+g add sub-scale +0.1 # increase the subtitle font size
#Shift+f add sub-scale -0.1 # decrease the subtitle font size
#9 add volume -2
#/ add volume -2
#0 add volume 2
#* add volume 2
#m cycle mute
#m cycle mute # toggle mute
#1 add contrast -1
#2 add contrast 1
#3 add brightness -1
@@ -118,73 +113,67 @@
#6 add gamma 1
#7 add saturation -1
#8 add saturation 1
#Alt+0 set window-scale 0.5
#Alt+1 set window-scale 1.0
#Alt+2 set window-scale 2.0
# toggle deinterlacer (automatically inserts or removes required filter)
#d cycle deinterlace
#Alt+0 set current-window-scale 0.5 # halve the window size
#Alt+1 set current-window-scale 1.0 # reset the window size
#Alt+2 set current-window-scale 2.0 # double the window size
#d cycle deinterlace # toggle the deinterlacing filter
#r add sub-pos -1 # move subtitles up
#R add sub-pos +1 # down
#t add sub-pos +1 # same as previous binding (discouraged)
#v cycle sub-visibility
# stretch SSA/ASS subtitles with anamorphic videos to match historical
#V cycle sub-ass-vsfilter-aspect-compat
# switch between applying no style overrides to SSA/ASS subtitles, and
# overriding them almost completely with the normal subtitle style
#u cycle-values sub-ass-override "force" "no"
#j cycle sub # cycle through subtitles
#J cycle sub down # ...backwards
#SHARP cycle audio # switch audio streams
#_ cycle video
#T cycle ontop # toggle video window ontop of other windows
#R add sub-pos +1 # move subtitles down
#t add sub-pos +1 # move subtitles down
#v cycle sub-visibility # hide or show the subtitles
#Alt+v cycle secondary-sub-visibility # hide or show the secondary subtitles
#V cycle sub-ass-vsfilter-aspect-compat # toggle stretching SSA/ASS subtitles with anamorphic videos to match the historical renderer
#u cycle-values sub-ass-override "force" "no" # toggle overriding SSA/ASS subtitle styles with the normal styles
#j cycle sub # switch subtitle track
#J cycle sub down # switch subtitle track backwards
#SHARP cycle audio # switch audio track
#_ cycle video # switch video track
#T cycle ontop # toggle placing the video on top of other windows
#f cycle fullscreen # toggle fullscreen
#s screenshot # take a screenshot
#S screenshot video # ...without subtitles
#Ctrl+s screenshot window # ...with subtitles and OSD, and scaled
#Alt+s screenshot each-frame # automatically screenshot every frame
#w add panscan -0.1 # zoom out with -panscan 0 -fs
#W add panscan +0.1 # in
#e add panscan +0.1 # same as previous binding (discouraged)
# cycle video aspect ratios; "-1" is the container aspect
#A cycle-values video-aspect-override "16:9" "4:3" "2.35:1" "-1"
#s screenshot # take a screenshot of the video in its original resolution with subtitles
#S screenshot video # take a screenshot of the video in its original resolution without subtitles
#Ctrl+s screenshot window # take a screenshot of the window with OSD and subtitles
#Alt+s screenshot each-frame # automatically screenshot every frame; issue this command again to stop taking screenshots
#w add panscan -0.1 # decrease panscan
#W add panscan +0.1 # shrink black bars by cropping the video
#e add panscan +0.1 # shrink black bars by cropping the video
#A cycle-values video-aspect-override "16:9" "4:3" "2.35:1" "-1" # cycle the video aspect ratio ("-1" is the container aspect)
#POWER quit
#PLAY cycle pause
#PAUSE cycle pause
#PLAYPAUSE cycle pause
#PLAYONLY set pause no
#PAUSEONLY set pause yes
#PLAY cycle pause # toggle pause/playback mode
#PAUSE cycle pause # toggle pause/playback mode
#PLAYPAUSE cycle pause # toggle pause/playback mode
#PLAYONLY set pause no # unpause
#PAUSEONLY set pause yes # pause
#STOP quit
#FORWARD seek 60
#REWIND seek -60
#NEXT playlist-next
#PREV playlist-prev
#FORWARD seek 60 # seek 1 minute forward
#REWIND seek -60 # seek 1 minute backward
#NEXT playlist-next # skip to the next file
#PREV playlist-prev # skip to the previous file
#VOLUME_UP add volume 2
#VOLUME_DOWN add volume -2
#MUTE cycle mute
#MUTE cycle mute # toggle mute
#CLOSE_WIN quit
#CLOSE_WIN {encode} quit 4
#ctrl+w quit
#E cycle edition # next edition
#l ab-loop # Set/clear A-B loop points
#E cycle edition # switch edition
#l ab-loop # set/clear A-B loop points
#L cycle-values loop-file "inf" "no" # toggle infinite looping
#ctrl+c quit 4
#DEL script-binding osc/visibility # cycle OSC display
#ctrl+h cycle-values hwdec "auto" "no" # cycle hardware decoding
#F8 show_text ${playlist} # show playlist
#F9 show_text ${track-list} # show list of audio/sub streams
#DEL script-binding osc/visibility # cycle OSC visibility between never, auto (mouse-move) and always
#ctrl+h cycle-values hwdec "auto" "no" # toggle hardware decoding
#F8 show-text ${playlist} # show the playlist
#F9 show-text ${track-list} # show the list of video, audio and sub tracks
#
# Legacy bindings (may or may not be removed in the future)
#
#! add chapter -1 # skip to previous chapter
#@ add chapter 1 # next
#! add chapter -1 # seek to the previous chapter
#@ add chapter 1 # seek to the next chapter
#
# Not assigned by default
# (not an exhaustive list of unbound commands)
#
# ? cycle angle # switch DVD/Bluray angle
# ? cycle sub-forced-only # toggle DVD forced subs
# ? cycle program # cycle transport stream programs
# ? stop # stop playback (quit or enter idle mode)
+3 -4
View File
@@ -34,13 +34,12 @@ _mpv_get_args()
declare -a candidates
case $type in
String)
echo "$doc" | grep -q '\[file\]'
if [ $? -eq 0 ]; then
if echo "$doc" | grep -q '\[file\]' ; then
if [ "$cur" = '=' ]; then
# Without this, _filedir will try and complete files starting with '='
cur=""
fi
_filedir
_filedir 2>/dev/null || COMPREPLY=($(compgen -f))
return 0
else
candidates=($(mpv $1=help | grep -v ':' | awk '{print $1;}'))
@@ -106,7 +105,7 @@ _mpv()
fi
;;
*)
_filedir
_filedir 2>/dev/null || COMPREPLY=($(compgen -f))
;;
esac
fi
+1
View File
@@ -34,3 +34,4 @@ Terminal=false
Categories=AudioVideo;Audio;Video;Player;TV;
MimeType=application/ogg;application/x-ogg;application/mxf;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/aiff;audio/x-aiff;audio/m4a;audio/x-m4a;application/x-extension-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/mpeg2;audio/mpeg3;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/musepack;audio/x-musepack;audio/ogg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg2;video/x-mpeg3;video/mp4v-es;video/x-m4v;video/mp4;application/x-extension-mp4;video/divx;video/vnd.divx;video/msvideo;video/x-msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;audio/x-ms-asf;application/vnd.ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/avi;video/x-flic;video/fli;video/x-flc;video/flv;video/x-flv;video/x-theora;video/x-theora+ogg;video/x-matroska;video/mkv;audio/x-matroska;application/x-matroska;video/webm;audio/webm;audio/vorbis;audio/x-vorbis;audio/x-vorbis+ogg;video/x-ogm;video/x-ogm+ogg;application/x-ogm;application/x-ogm-audio;application/x-ogm-video;application/x-shorten;audio/x-shorten;audio/x-ape;audio/x-wavpack;audio/x-tta;audio/AMR;audio/ac3;audio/eac3;audio/amr-wb;video/mp2t;audio/flac;audio/mp4;application/x-mpegurl;video/vnd.mpegurl;application/vnd.apple.mpegurl;audio/x-pn-au;video/3gp;video/3gpp;video/3gpp2;audio/3gpp;audio/3gpp2;video/dv;audio/dv;audio/opus;audio/vnd.dts;audio/vnd.dts.hd;audio/x-adpcm;application/x-cue;audio/m3u;
X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb,srt
StartupWMClass=mpv
+2 -2
View File
@@ -329,9 +329,9 @@ static void aspeed_process(struct mp_filter *f)
if (req_filter) {
if (req_filter == 1) {
MP_VERBOSE(f, "adding scaletempo\n");
MP_VERBOSE(f, "adding scaletempo2\n");
p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
"scaletempo", NULL);
"scaletempo2", NULL);
} else if (req_filter == 2) {
MP_VERBOSE(f, "adding drop\n");
p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
+1 -1
View File
@@ -9,5 +9,5 @@ struct mp_filter *mp_deint_create(struct mp_filter *parent);
// Rotate according to mp_image.rotate and VO capabilities.
struct mp_filter *mp_autorotate_create(struct mp_filter *parent);
// Insert a filter that inserts scaletempo depending on speed settings.
// Insert a filter that inserts scaletempo2 depending on speed settings.
struct mp_filter *mp_autoaspeed_create(struct mp_filter *parent);
+10 -9
View File
@@ -110,16 +110,19 @@ struct dec_wrapper_opts {
int64_t audio_reverse_size;
};
static int decoder_list_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param);
static int decoder_list_help(struct mp_log *log, const m_option_t *opt,
struct bstr name);
const struct m_sub_options dec_wrapper_conf = {
.opts = (const struct m_option[]){
{"correct-pts", OPT_FLAG(correct_pts)},
{"fps", OPT_DOUBLE(force_fps), M_RANGE(0, DBL_MAX)},
{"ad", OPT_STRING_VALIDATE(audio_decoders, decoder_list_opt)},
{"vd", OPT_STRING_VALIDATE(video_decoders, decoder_list_opt)},
{"audio-spdif", OPT_STRING_VALIDATE(audio_spdif, decoder_list_opt)},
{"ad", OPT_STRING(audio_decoders),
.help = decoder_list_help},
{"vd", OPT_STRING(video_decoders),
.help = decoder_list_help},
{"audio-spdif", OPT_STRING(audio_spdif),
.help = decoder_list_help},
{"video-rotate", OPT_CHOICE(video_rotate, {"no", -1}),
.flags = UPDATE_IMGPAR, M_RANGE(0, 359)},
{"video-aspect-override", OPT_ASPECT(movie_aspect),
@@ -232,11 +235,9 @@ struct priv {
int dropped_frames; // total frames _probably_ dropped
};
static int decoder_list_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param)
static int decoder_list_help(struct mp_log *log, const m_option_t *opt,
struct bstr name)
{
if (!bstr_equals0(param, "help"))
return 1;
if (strcmp(opt->name, "ad") == 0) {
struct mp_decoder_list *list = audio_decoder_list();
mp_print_decoders(log, MSGL_INFO, "Audio decoders:", list);
+28 -3
View File
@@ -336,11 +336,34 @@ static int pctx_read_token(struct parse_ctx *ctx, bstr *out)
return -1;
}
if (!bstr_eatstart0(&ctx->str, "\"")) {
MP_ERR(ctx, "Unterminated quotes: ...>%.*s<.\n", BSTR_P(start));
MP_ERR(ctx, "Unterminated double quote: ...>%.*s<.\n", BSTR_P(start));
return -1;
}
return 1;
}
if (bstr_eatstart0(&ctx->str, "'")) {
int next = bstrchr(ctx->str, '\'');
if (next < 0) {
MP_ERR(ctx, "Unterminated single quote: ...>%.*s<.\n", BSTR_P(start));
return -1;
}
*out = bstr_splice(ctx->str, 0, next);
ctx->str = bstr_cut(ctx->str, next+1);
return 1;
}
if (ctx->start.len > 1 && bstr_eatstart0(&ctx->str, "`")) {
char endquote[2] = {ctx->str.start[0], '`'};
ctx->str = bstr_cut(ctx->str, 1);
int next = bstr_find(ctx->str, (bstr){endquote, 2});
if (next < 0) {
MP_ERR(ctx, "Unterminated custom quote: ...>%.*s<.\n", BSTR_P(start));
return -1;
}
*out = bstr_splice(ctx->str, 0, next);
ctx->str = bstr_cut(ctx->str, next+2);
return 1;
}
return read_token(ctx->str, &ctx->str, out) ? 1 : 0;
}
@@ -585,8 +608,10 @@ void mp_cmd_dump(struct mp_log *log, int msgl, char *header, struct mp_cmd *cmd)
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd)
{
return (cmd->def->allow_auto_repeat) || cmd->def == &mp_cmd_list ||
(cmd->flags & MP_ALLOW_REPEAT);
if (cmd->def == &mp_cmd_list && cmd->args[0].v.p)
cmd = cmd->args[0].v.p; // list - only 1st cmd is considered
return (cmd->def->allow_auto_repeat) || (cmd->flags & MP_ALLOW_REPEAT);
}
bool mp_input_is_scalable_cmd(struct mp_cmd *cmd)
+4 -1
View File
@@ -176,6 +176,7 @@ struct input_opts {
int use_gamepad;
int use_media_keys;
int default_bindings;
int builtin_bindings;
int enable_mouse_movements;
int vo_key_input;
int test;
@@ -190,6 +191,7 @@ const struct m_sub_options input_config = {
{"input-keylist", OPT_PRINT(mp_print_key_list)},
{"input-cmdlist", OPT_PRINT(mp_print_cmd_list)},
{"input-default-bindings", OPT_FLAG(default_bindings)},
{"input-builtin-bindings", OPT_FLAG(builtin_bindings)},
{"input-test", OPT_FLAG(test)},
{"input-doubleclick-time", OPT_INT(doubleclick_time),
M_RANGE(0, 1000)},
@@ -218,6 +220,7 @@ const struct m_sub_options input_config = {
.enable_mouse_movements = 1,
.use_media_keys = 1,
.default_bindings = 1,
.builtin_bindings = 1,
.vo_key_input = 1,
.allow_win_drag = 1,
},
@@ -1367,7 +1370,7 @@ void mp_input_load_config(struct input_ctx *ictx)
// "Uncomment" the default key bindings in etc/input.conf and add them.
// All lines that do not start with '# ' are parsed.
bstr builtin = bstr0(builtin_input_conf);
while (builtin.len) {
while (ictx->opts->builtin_bindings && builtin.len) {
bstr line = bstr_getline(builtin, &builtin);
bstr_eatstart0(&line, "#");
if (!bstr_startswith0(line, " "))
+32
View File
@@ -244,6 +244,26 @@ void m_config_restore_backups(struct m_config *config)
restore_backups(&config->backup_opts, config);
}
bool m_config_watch_later_backup_opt_changed(struct m_config *config,
char *opt_name)
{
struct m_config_option *co = m_config_get_co(config, bstr0(opt_name));
if (!co) {
MP_ERR(config, "Option %s not found.\n", opt_name);
return false;
}
for (struct m_opt_backup *bc = config->watch_later_backup_opts; bc;
bc = bc->next) {
if (strcmp(bc->co->name, co->name) == 0) {
struct m_config_option *bc_co = (struct m_config_option *)bc->backup;
return !m_option_equal(co->opt, co->data, bc_co);
}
}
return false;
}
void m_config_backup_opt(struct m_config *config, const char *opt)
{
struct m_config_option *co = m_config_get_co(config, bstr0(opt));
@@ -260,6 +280,11 @@ void m_config_backup_all_opts(struct m_config *config)
ensure_backup(&config->backup_opts, BACKUP_LOCAL, &config->opts[n]);
}
void m_config_backup_watch_later_opts(struct m_config *config)
{
for (int n = 0; n < config->num_opts; n++)
ensure_backup(&config->watch_later_backup_opts, 0, &config->opts[n]);
}
struct m_config_option *m_config_get_co_raw(const struct m_config *config,
struct bstr name)
@@ -509,6 +534,13 @@ static void config_destroy(void *p)
config->option_change_callback = NULL;
m_config_restore_backups(config);
struct m_opt_backup **list = &config->watch_later_backup_opts;
while (*list) {
struct m_opt_backup *bc = *list;
*list = bc->next;
talloc_free(bc);
}
talloc_free(config->cache);
talloc_free(config->shadow);
}
+9
View File
@@ -75,6 +75,7 @@ typedef struct m_config {
int profile_backup_flags;
struct m_opt_backup *backup_opts;
struct m_opt_backup *watch_later_backup_opts;
bool use_profiles;
bool is_toplevel;
@@ -134,10 +135,18 @@ void m_config_backup_opt(struct m_config *config, const char *opt);
// Call m_config_backup_opt() on all options.
void m_config_backup_all_opts(struct m_config *config);
// Backup options on startup so that quit-watch-later can compare the current
// values to their backups, and save them only if they have been changed.
void m_config_backup_watch_later_opts(struct m_config *config);
// Restore all options backed up with m_config_backup_opt(), and delete the
// backups afterwards.
void m_config_restore_backups(struct m_config *config);
// Whether opt_name is different from its initial value.
bool m_config_watch_later_backup_opt_changed(struct m_config *config,
char *opt_name);
enum {
M_SETOPT_PRE_PARSE_ONLY = 1, // Silently ignore non-M_OPT_PRE_PARSE opt.
M_SETOPT_CHECK_ONLY = 2, // Don't set, just check name/value
+27 -9
View File
@@ -61,6 +61,31 @@ const char m_option_path_separator = OPTION_PATH_SEPARATOR;
#define OPT_INT_MAX(opt, T, Tm) ((opt)->min < (opt)->max \
? ((opt)->max >= (double)(Tm) ? (Tm) : (T)((opt)->max)) : (Tm))
int m_option_parse(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
int r = M_OPT_INVALID;
if (bstr_equals0(param, "help") && opt->help) {
r = opt->help(log, opt, name);
if (r < 0)
return r;
}
r = opt->type->parse(log, opt, name, param, dst);
if (r < 0)
return r;
if (opt->validate) {
r = opt->validate(log, opt, name, dst);
if (r < 0) {
if (opt->type->free)
opt->type->free(dst);
return r;
}
}
return 1;
}
char *m_option_strerror(int code)
{
switch (code) {
@@ -1192,13 +1217,6 @@ const m_option_type_t m_option_type_aspect = {
static int parse_str(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
m_opt_string_validate_fn validate = opt->priv;
if (validate) {
int r = validate(log, opt, name, param);
if (r < 0)
return r;
}
if (dst) {
talloc_free(VAL(dst));
VAL(dst) = bstrdup0(NULL, param);
@@ -1846,7 +1864,7 @@ static int parse_msglevels(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
if (bstr_equals0(param, "help")) {
mp_info(log, "Syntax:\n\n --msglevel=module1=level,module2=level,...\n\n"
mp_info(log, "Syntax:\n\n --msg-level=module1=level,module2=level,...\n\n"
"'module' is output prefix as shown with -v, or a prefix\n"
"of it. level is one of:\n\n"
" fatal error warn info status v debug trace\n\n"
@@ -3650,7 +3668,7 @@ static bool obj_settings_list_equal(const m_option_t *opt, void *pa, void *pb)
struct m_obj_settings *b = VAL(pb);
if (a == b || !a || !b)
return a == b;
return a == b || (!a && !b[0].name) || (!b && !a[0].name);
for (int n = 0; a[n].name || b[n].name; n++) {
if (!a[n].name || !b[n].name)
+31 -9
View File
@@ -189,9 +189,15 @@ struct m_opt_choice_alternatives {
const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices,
int value);
// For OPT_STRING_VALIDATE(). Behaves like m_option_type.parse().
// Validator function signatures. Required to properly type the param value.
typedef int (*m_opt_generic_validate_fn)(struct mp_log *log, const m_option_t *opt,
struct bstr name, void *value);
typedef int (*m_opt_string_validate_fn)(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param);
struct bstr name, const char **value);
typedef int (*m_opt_int_validate_fn)(struct mp_log *log, const m_option_t *opt,
struct bstr name, const int *value);
// m_option.priv points to this if OPT_SUBSTRUCT is used
struct m_sub_options {
@@ -270,6 +276,9 @@ struct m_option_type {
// Parse the data from a string.
/** It is the only required function, all others can be NULL.
* Generally should not be called directly outside of the options module,
* but instead through \ref m_option_parse which calls additional option
* specific callbacks during the process.
*
* \param log for outputting parser error or help messages
* \param opt The option that is parsed.
@@ -384,6 +393,12 @@ struct m_option {
// Print a warning when this option is used (for options with no direct
// replacement.)
const char *deprecation_message;
// Optional function that validates a param value for this option.
m_opt_generic_validate_fn validate;
// Optional function that displays help. Will replace type-specific help.
int (*help)(struct mp_log *log, const m_option_t *opt, struct bstr name);
};
char *format_file_size(int64_t size);
@@ -490,12 +505,13 @@ char *format_file_size(int64_t size);
char *m_option_strerror(int code);
// Helper to parse options, see \ref m_option_type::parse.
static inline int m_option_parse(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
return opt->type->parse(log, opt, name, param, dst);
}
// Base function to parse options. Includes calling help and validation
// callbacks. Only when this functionality is for some reason required to not
// happen should the parse function pointer be utilized by itself.
//
// See \ref m_option_type::parse.
int m_option_parse(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst);
// Helper to print options, see \ref m_option_type::print.
static inline char *m_option_print(const m_option_t *opt, const void *val_ptr)
@@ -661,9 +677,15 @@ extern const char m_option_path_separator;
#define OPT_CHANNELS(field) \
OPT_TYPED_FIELD(m_option_type_channels, struct m_channels, field)
#define OPT_INT_VALIDATE(field, validate_fn) \
OPT_TYPED_FIELD(m_option_type_int, int, field), \
.validate = (m_opt_generic_validate_fn) \
MP_EXPECT_TYPE(m_opt_int_validate_fn, validate_fn)
#define OPT_STRING_VALIDATE(field, validate_fn) \
OPT_TYPED_FIELD(m_option_type_string, char*, field), \
.priv = MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn)
.validate = (m_opt_generic_validate_fn) \
MP_EXPECT_TYPE(m_opt_string_validate_fn, validate_fn)
#define M_CHOICES(...) \
.priv = (void *)&(const struct m_opt_choice_alternatives[]){ __VA_ARGS__, {0}}
+60 -7
View File
@@ -46,6 +46,7 @@
#include "player/core.h"
#include "player/command.h"
#include "stream/stream.h"
#include "demux/demux.h"
#if HAVE_DRM
#include "video/out/drm_common.h"
@@ -86,6 +87,7 @@ extern const struct m_sub_options ao_conf;
extern const struct m_sub_options opengl_conf;
extern const struct m_sub_options vulkan_conf;
extern const struct m_sub_options vulkan_display_conf;
extern const struct m_sub_options spirv_conf;
extern const struct m_sub_options d3d11_conf;
extern const struct m_sub_options d3d11va_conf;
@@ -112,7 +114,8 @@ static const m_option_t mp_vo_opt_list[] = {
{"ontop-level", OPT_CHOICE(ontop_level, {"window", -1}, {"system", -2},
{"desktop", -3}), M_RANGE(0, INT_MAX)},
{"border", OPT_FLAG(border)},
{"fit-border", OPT_FLAG(fit_border)},
{"fit-border", OPT_FLAG(fit_border),
.deprecation_message = "the option is ignored and no longer needed"},
{"on-all-workspaces", OPT_FLAG(all_workspaces)},
{"geometry", OPT_GEOMETRY(geometry)},
{"autofit", OPT_SIZE_BOX(autofit)},
@@ -147,8 +150,10 @@ static const m_option_t mp_vo_opt_list[] = {
{"no", 0}, {"yes", 1}, {"downscale-big", 2})},
{"wid", OPT_INT64(WinID)},
{"screen", OPT_CHOICE(screen_id, {"default", -1}), M_RANGE(0, 32)},
{"screen-name", OPT_STRING(screen_name)},
{"fs-screen", OPT_CHOICE(fsscreen_id, {"all", -2}, {"current", -1}),
M_RANGE(0, 32)},
{"fs-screen-name", OPT_STRING(fsscreen_name)},
{"keepaspect", OPT_FLAG(keepaspect)},
{"keepaspect-window", OPT_FLAG(keepaspect_window)},
{"hidpi-window-scale", OPT_FLAG(hidpi_window_scale)},
@@ -193,6 +198,7 @@ const struct m_sub_options vo_sub_opts = {
.snap_window = 0,
.border = 1,
.fit_border = 1,
.appid = "mpv",
.WinID = -1,
.window_scale = 1.0,
.x11_bypass_compositor = 2,
@@ -212,7 +218,9 @@ const struct m_sub_options mp_sub_filter_opts = {
{"sub-filter-sdh", OPT_FLAG(sub_filter_SDH)},
{"sub-filter-sdh-harder", OPT_FLAG(sub_filter_SDH_harder)},
{"sub-filter-regex-enable", OPT_FLAG(rf_enable)},
{"sub-filter-regex-plain", OPT_FLAG(rf_plain)},
{"sub-filter-regex", OPT_STRINGLIST(rf_items)},
{"sub-filter-jsre", OPT_STRINGLIST(jsre_items)},
{"sub-filter-regex-warn", OPT_FLAG(rf_warn)},
{0}
},
@@ -232,6 +240,7 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"sub-fps", OPT_FLOAT(sub_fps)},
{"sub-speed", OPT_FLOAT(sub_speed)},
{"sub-visibility", OPT_FLAG(sub_visibility)},
{"secondary-sub-visibility", OPT_FLAG(sec_sub_visibility)},
{"sub-forced-only", OPT_CHOICE(forced_subs_only,
{"auto", -1}, {"no", 0}, {"yes", 1})},
{"stretch-dvd-subs", OPT_FLAG(stretch_dvd_subs)},
@@ -269,11 +278,13 @@ const struct m_sub_options mp_subtitle_sub_opts = {
{"sub", OPT_SUBSTRUCT(sub_style, sub_style_conf)},
{"sub-clear-on-seek", OPT_FLAG(sub_clear_on_seek)},
{"teletext-page", OPT_INT(teletext_page), M_RANGE(1, 999)},
{"sub-past-video-end", OPT_FLAG(sub_past_video_end)},
{0}
},
.size = sizeof(OPT_BASE_STRUCT),
.defaults = &(OPT_BASE_STRUCT){
.sub_visibility = 1,
.sec_sub_visibility = 1,
.forced_subs_only = -1,
.sub_pos = 100,
.sub_speed = 1.0,
@@ -499,7 +510,8 @@ static const m_option_t mp_opts[] = {
{"lavfi-complex", OPT_STRING(lavfi_complex), .flags = UPDATE_LAVFI_COMPLEX},
{"audio-display", OPT_CHOICE(audio_display, {"no", 0}, {"attachment", 1})},
{"audio-display", OPT_CHOICE(audio_display, {"no", 0},
{"embedded-first", 1}, {"external-first", 2})},
{"hls-bitrate", OPT_CHOICE(hls_bitrate,
{"no", -1}, {"min", 0}, {"max", INT_MAX}), M_RANGE(0, INT_MAX)},
@@ -512,9 +524,9 @@ static const m_option_t mp_opts[] = {
#endif
// demuxer.c - select audio/sub file/demuxer
{"demuxer", OPT_STRING(demuxer_name)},
{"audio-demuxer", OPT_STRING(audio_demuxer_name)},
{"sub-demuxer", OPT_STRING(sub_demuxer_name)},
{"demuxer", OPT_STRING(demuxer_name), .help = demuxer_help},
{"audio-demuxer", OPT_STRING(audio_demuxer_name), .help = demuxer_help},
{"sub-demuxer", OPT_STRING(sub_demuxer_name), .help = demuxer_help},
{"demuxer-thread", OPT_FLAG(demuxer_thread)},
{"demuxer-termination-timeout", OPT_DOUBLE(demux_termination_timeout)},
{"demuxer-cache-wait", OPT_FLAG(demuxer_cache_wait)},
@@ -588,7 +600,7 @@ static const m_option_t mp_opts[] = {
{"audio-file-auto", OPT_CHOICE(audiofile_auto,
{"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})},
{"cover-art-auto", OPT_CHOICE(coverart_auto,
{"no", -1}, {"fuzzy", 1})},
{"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})},
{"", OPT_SUBSTRUCT(subs_rend, mp_subtitle_sub_opts)},
{"", OPT_SUBSTRUCT(subs_filt, mp_sub_filter_opts)},
@@ -620,7 +632,7 @@ static const m_option_t mp_opts[] = {
{"album", 2}),
.flags = UPDATE_VOL},
{"replaygain-preamp", OPT_FLOAT(rgain_preamp), .flags = UPDATE_VOL,
M_RANGE(-15, 15)},
M_RANGE(-150, 150)},
{"replaygain-clip", OPT_FLAG(rgain_clip), .flags = UPDATE_VOL},
{"replaygain-fallback", OPT_FLOAT(rgain_fallback), .flags = UPDATE_VOL,
M_RANGE(-200, 60)},
@@ -686,6 +698,7 @@ static const m_option_t mp_opts[] = {
OPT_FLAG(ignore_path_in_watch_later_config)},
{"watch-later-directory", OPT_STRING(watch_later_directory),
.flags = M_OPT_FILE},
{"watch-later-options", OPT_STRINGLIST(watch_later_options)},
{"ordered-chapters", OPT_FLAG(ordered_chapters)},
{"ordered-chapters-files", OPT_STRING(ordered_chapters_files),
@@ -775,6 +788,7 @@ static const m_option_t mp_opts[] = {
#if HAVE_VULKAN
{"", OPT_SUBSTRUCT(vulkan_opts, vulkan_conf)},
{"", OPT_SUBSTRUCT(vulkan_display_opts, vulkan_display_conf)},
#endif
#if HAVE_D3D11
@@ -1028,10 +1042,49 @@ static const struct MPOpts mp_default_opts = {
"Artist", "Album", "Album_Artist", "Comment", "Composer",
"Date", "Description", "Genre", "Performer", "Rating",
"Series", "Title", "Track", "icy-title", "service_name",
"Uploader", "Channel_URL",
NULL
},
.cuda_device = -1,
.watch_later_options = (char **)(const char*[]){
"osd-level",
"speed",
"edition",
"pause",
"volume",
"mute",
"audio-delay",
"fullscreen",
"ontop",
"border",
"gamma",
"brightness",
"contrast",
"saturation",
"hue",
"deinterlace",
"vf",
"af",
"panscan",
"aid",
"vid",
"sid",
"sub-delay",
"sub-speed",
"sub-pos",
"sub-visibility",
"sub-scale",
"sub-use-margins",
"sub-ass-force-margins",
"sub-ass-vsfilter-aspect-compat",
"sub-ass-override",
"ab-loop-a",
"ab-loop-b",
"video-aspect-override",
NULL
},
};
const struct m_sub_options mp_opt_root = {
+8
View File
@@ -22,7 +22,9 @@ typedef struct mp_vo_opts {
bool focus_on_open;
int screen_id;
char *screen_name;
int fsscreen_id;
char *fsscreen_name;
char *winname;
char *appid;
int x11_netwm;
@@ -71,6 +73,7 @@ typedef struct mp_vo_opts {
// Subtitle options needed by the subtitle decoders/renderers.
struct mp_subtitle_opts {
int sub_visibility;
int sec_sub_visibility;
int sub_pos;
float sub_delay;
float sub_fps;
@@ -104,13 +107,16 @@ struct mp_subtitle_opts {
int ass_justify;
int sub_clear_on_seek;
int teletext_page;
int sub_past_video_end;
};
struct mp_sub_filter_opts {
int sub_filter_SDH;
int sub_filter_SDH_harder;
int rf_enable;
int rf_plain;
char **rf_items;
char **jsre_items;
int rf_warn;
};
@@ -248,6 +254,7 @@ typedef struct MPOpts {
int write_filename_in_watch_later_config;
int ignore_path_in_watch_later_config;
char *watch_later_directory;
char **watch_later_options;
int pause;
int keep_open;
int keep_open_pause;
@@ -341,6 +348,7 @@ typedef struct MPOpts {
struct angle_opts *angle_opts;
struct opengl_opts *opengl_opts;
struct vulkan_opts *vulkan_opts;
struct vulkan_display_opts *vulkan_display_opts;
struct spirv_opts *spirv_opts;
struct d3d11_opts *d3d11_opts;
struct d3d11va_opts *d3d11va_opts;
+38 -28
View File
@@ -47,23 +47,26 @@ class LibmpvHelper {
}
func initRender() {
var advanced: CInt = 1
let advanced: CInt = 1
let api = UnsafeMutableRawPointer(mutating: (MPV_RENDER_API_TYPE_OPENGL as NSString).utf8String)
var pAddress = mpv_opengl_init_params(get_proc_address: getProcAddress,
let pAddress = mpv_opengl_init_params(get_proc_address: getProcAddress,
get_proc_address_ctx: nil,
extra_exts: nil)
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_API_TYPE, data: api),
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, data: &pAddress),
mpv_render_param(type: MPV_RENDER_PARAM_ADVANCED_CONTROL, data: &advanced),
mpv_render_param()
]
if (mpv_render_context_create(&mpvRenderContext, mpvHandle, &params) < 0)
{
log.sendError("Render context init has failed.")
exit(1)
MPVHelper.withUnsafeMutableRawPointers([pAddress, advanced]) { (pointers: [UnsafeMutableRawPointer?]) in
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_API_TYPE, data: api),
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, data: pointers[0]),
mpv_render_param(type: MPV_RENDER_PARAM_ADVANCED_CONTROL, data: pointers[1]),
mpv_render_param()
]
if (mpv_render_context_create(&mpvRenderContext, mpvHandle, &params) < 0) {
log.sendError("Render context init has failed.")
exit(1)
}
}
}
let getProcAddress: (@convention(c) (UnsafeMutableRawPointer?, UnsafePointer<Int8>?)
@@ -119,26 +122,29 @@ class LibmpvHelper {
deinitLock.lock()
if mpvRenderContext != nil {
var i: GLint = 0
var flip: CInt = 1
var skip: CInt = skip ? 1 : 0
var ditherDepth = depth
let flip: CInt = 1
let skip: CInt = skip ? 1 : 0
let ditherDepth = depth
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
// CAOpenGLLayer has ownership of FBO zero yet can return it to us,
// so only utilize a newly received FBO ID if it is nonzero.
fbo = i != 0 ? i : fbo
var data = mpv_opengl_fbo(fbo: Int32(fbo),
let data = mpv_opengl_fbo(fbo: Int32(fbo),
w: Int32(surface.width),
h: Int32(surface.height),
internal_format: 0)
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: &data),
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: &flip),
mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: &ditherDepth),
mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: &skip),
mpv_render_param()
]
mpv_render_context_render(mpvRenderContext, &params);
MPVHelper.withUnsafeMutableRawPointers([data, flip, ditherDepth, skip]) { (pointers: [UnsafeMutableRawPointer?]) in
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: pointers[0]),
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: pointers[1]),
mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: pointers[2]),
mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: pointers[3]),
mpv_render_param()
]
mpv_render_context_render(mpvRenderContext, &params);
}
} else {
glClearColor(0, 0, 0, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
@@ -161,16 +167,20 @@ class LibmpvHelper {
let u8Ptr = baseAddress.assumingMemoryBound(to: UInt8.self)
let iccBstr = bstrdup(nil, bstr(start: u8Ptr, len: ptr.count))
var icc = mpv_byte_array(data: iccBstr.start, size: iccBstr.len)
let params = mpv_render_param(type: MPV_RENDER_PARAM_ICC_PROFILE, data: &icc)
mpv_render_context_set_parameter(mpvRenderContext, params)
withUnsafeMutableBytes(of: &icc) { (ptr: UnsafeMutableRawBufferPointer) in
let params = mpv_render_param(type: MPV_RENDER_PARAM_ICC_PROFILE, data: ptr.baseAddress)
mpv_render_context_set_parameter(mpvRenderContext, params)
}
}
}
func setRenderLux(_ lux: Int) {
if mpvRenderContext == nil { return }
var light = lux
let params = mpv_render_param(type: MPV_RENDER_PARAM_AMBIENT_LIGHT, data: &light)
mpv_render_context_set_parameter(mpvRenderContext, params)
withUnsafeMutableBytes(of: &light) { (ptr: UnsafeMutableRawBufferPointer) in
let params = mpv_render_param(type: MPV_RENDER_PARAM_AMBIENT_LIGHT, data: ptr.baseAddress)
mpv_render_context_set_parameter(mpvRenderContext, params)
}
}
func commandAsync(_ cmd: [String?], id: UInt64 = 1) {
+33 -3
View File
@@ -86,17 +86,23 @@ class MPVHelper {
func setOption(fullscreen: Bool) {
optsPtr.pointee.fullscreen = fullscreen
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.fullscreen))
_ = withUnsafeMutableBytes(of: &optsPtr.pointee.fullscreen) { (ptr: UnsafeMutableRawBufferPointer) in
m_config_cache_write_opt(optsCachePtr, ptr.baseAddress)
}
}
func setOption(minimized: Bool) {
optsPtr.pointee.window_minimized = Int32(minimized)
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.window_minimized))
_ = withUnsafeMutableBytes(of: &optsPtr.pointee.window_minimized) { (ptr: UnsafeMutableRawBufferPointer) in
m_config_cache_write_opt(optsCachePtr, ptr.baseAddress)
}
}
func setOption(maximized: Bool) {
optsPtr.pointee.window_maximized = Int32(maximized)
m_config_cache_write_opt(optsCachePtr, UnsafeMutableRawPointer(&optsPtr.pointee.window_maximized))
_ = withUnsafeMutableBytes(of: &optsPtr.pointee.window_maximized) { (ptr: UnsafeMutableRawBufferPointer) in
m_config_cache_write_opt(optsCachePtr, ptr.baseAddress)
}
}
func setMacOptionCallback(_ callback: swift_wakeup_cb_fn, context object: AnyObject) {
@@ -123,4 +129,28 @@ class MPVHelper {
class func bridge<T: AnyObject>(ptr: UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
class func withUnsafeMutableRawPointers(_ arguments: [Any],
pointers: [UnsafeMutableRawPointer?] = [],
closure: (_ pointers: [UnsafeMutableRawPointer?]) -> Void) {
if arguments.count > 0 {
let args = Array(arguments.dropFirst(1))
var newPtrs = pointers
var firstArg = arguments.first
withUnsafeMutableBytes(of: &firstArg) { (ptr: UnsafeMutableRawBufferPointer) in
newPtrs.append(ptr.baseAddress)
withUnsafeMutableRawPointers(args, pointers: newPtrs, closure: closure)
}
return
}
closure(pointers)
}
class func getPointer<T>(_ value: inout T) -> UnsafeMutableRawPointer? {
return withUnsafeMutableBytes(of: &value) { (ptr: UnsafeMutableRawBufferPointer) in
ptr.baseAddress
}
}
}
-27
View File
@@ -33,7 +33,6 @@ extension String {
#endif
extension NSPasteboard.PasteboardType {
static let fileURLCompat: NSPasteboard.PasteboardType = {
if #available(OSX 10.13, *) {
return .fileURL
@@ -53,7 +52,6 @@ extension NSPasteboard.PasteboardType {
#if !swift(>=5.0)
extension Data {
mutating func withUnsafeMutableBytes<Type>(_ body: (UnsafeMutableRawBufferPointer) throws -> Type) rethrows -> Type {
let dataCount = count
return try withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) throws -> Type in
@@ -65,33 +63,8 @@ extension Data {
#if !swift(>=4.2)
extension NSDraggingInfo {
var draggingPasteboard: NSPasteboard {
get { return draggingPasteboard() }
}
}
#endif
#if !swift(>=4.1)
extension Array {
func compactMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return try self.flatMap(transform)
}
}
extension Array where Element == [CGLPixelFormatAttribute] {
func contains(_ obj: [CGLPixelFormatAttribute]) -> Bool {
return self.contains(where:{ $0 == obj })
}
}
extension NSWindow.Level {
static func +(left: NSWindow.Level, right: Int) -> NSWindow.Level {
return NSWindow.Level(left.rawValue + right)
}
}
#endif
+6
View File
@@ -21,6 +21,11 @@
#include "osdep/macosx_menubar.h"
#include "options/m_option.h"
enum {
FRAME_VISIBLE = 0,
FRAME_WHOLE,
};
struct macos_opts {
int macos_title_bar_style;
int macos_title_bar_appearance;
@@ -29,6 +34,7 @@ struct macos_opts {
int macos_fs_animation_duration;
int macos_force_dedicated_gpu;
int macos_app_activation_policy;
int macos_geometry_calculation;
int cocoa_cb_sw_renderer;
int cocoa_cb_10bit_context;
};
+2
View File
@@ -65,6 +65,8 @@ const struct m_sub_options macos_conf = {
{"macos-force-dedicated-gpu", OPT_FLAG(macos_force_dedicated_gpu)},
{"macos-app-activation-policy", OPT_CHOICE(macos_app_activation_policy,
{"regular", 0}, {"accessory", 1}, {"prohibited", 2})},
{"macos-geometry-calculation", OPT_CHOICE(macos_geometry_calculation,
{"visible", FRAME_VISIBLE}, {"whole", FRAME_WHOLE})},
{"cocoa-cb-sw-renderer", OPT_CHOICE(cocoa_cb_sw_renderer,
{"auto", -1}, {"no", 0}, {"yes", 1})},
{"cocoa-cb-10bit-context", OPT_FLAG(cocoa_cb_10bit_context)},
+7
View File
@@ -218,6 +218,13 @@
@"target" : self,
@"cmd" : @"cycle ontop"
}],
[NSMutableDictionary dictionaryWithDictionary:@{
@"name" : @"Toggle Visibility on All Workspaces",
@"action" : @"cmd:",
@"key" : @"",
@"target" : self,
@"cmd" : @"cycle on-all-workspaces"
}],
#if HAVE_MACOS_TOUCHBAR
@{ @"name": @"separator" },
[NSMutableDictionary dictionaryWithDictionary:@{
+1
View File
@@ -41,5 +41,6 @@ struct mpv_event;
@property(nonatomic, retain) NSDictionary *touchbarItems;
@property(nonatomic, assign) double duration;
@property(nonatomic, assign) double position;
@property(nonatomic, assign) int pause;
@end
+155 -93
View File
@@ -24,6 +24,7 @@
@synthesize touchbarItems = _touchbar_items;
@synthesize duration = _duration;
@synthesize position = _position;
@synthesize pause = _pause;
- (id)init
{
@@ -86,58 +87,25 @@
@"name": @"Time Left"
}]
};
[self addObserver:self forKeyPath:@"visible" options:0 context:nil];
}
return self;
}
-(void)processEvent:(struct mpv_event *)event
{
switch (event->event_id) {
case MPV_EVENT_END_FILE: {
self.position = 0;
self.duration = 0;
break;
}
case MPV_EVENT_PROPERTY_CHANGE: {
[self handlePropertyChange:(mpv_event_property *)event->data];
break;
}
}
}
-(void)handlePropertyChange:(struct mpv_event_property *)property
{
NSString *name = [NSString stringWithUTF8String:property->name];
mpv_format format = property->format;
if ([name isEqualToString:@"time-pos"] && format == MPV_FORMAT_DOUBLE) {
self.position = *(double *)property->data;
self.position = self.position < 0 ? 0 : self.position;
[self updateTouchBarTimeItems];
} else if ([name isEqualToString:@"duration"] && format == MPV_FORMAT_DOUBLE) {
self.duration = *(double *)property->data;
[self updateTouchBarTimeItems];
} else if ([name isEqualToString:@"pause"] && format == MPV_FORMAT_FLAG) {
NSButton *playButton = self.touchbarItems[play][@"view"];
if (*(int *)property->data) {
playButton.image = self.touchbarItems[play][@"imageAlt"];
} else {
playButton.image = self.touchbarItems[play][@"image"];
}
}
}
- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar
makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier
{
if ([self.touchbarItems[identifier][@"type"] isEqualToString:@"slider"]) {
NSSliderTouchBarItem *tbItem = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier];
tbItem.slider.minValue = 0.0f;
tbItem.slider.maxValue = 100.0f;
tbItem.target = self;
tbItem.action = @selector(seekbarChanged:);
NSCustomTouchBarItem *tbItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSSlider *slider = [NSSlider sliderWithTarget:self action:@selector(seekbarChanged:)];
slider.minValue = 0.0f;
slider.maxValue = 100.0f;
tbItem.view = slider;
tbItem.customizationLabel = self.touchbarItems[identifier][@"name"];
[self.touchbarItems[identifier] setObject:tbItem.slider forKey:@"view"];
[self.touchbarItems[identifier] setObject:slider forKey:@"view"];
[self.touchbarItems[identifier] setObject:tbItem forKey:@"tbItem"];
[tbItem addObserver:self forKeyPath:@"visible" options:0 context:nil];
return tbItem;
} else if ([self.touchbarItems[identifier][@"type"] isEqualToString:@"button"]) {
NSCustomTouchBarItem *tbItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
@@ -146,6 +114,8 @@
tbItem.view = tbButton;
tbItem.customizationLabel = self.touchbarItems[identifier][@"name"];
[self.touchbarItems[identifier] setObject:tbButton forKey:@"view"];
[self.touchbarItems[identifier] setObject:tbItem forKey:@"tbItem"];
[tbItem addObserver:self forKeyPath:@"visible" options:0 context:nil];
return tbItem;
} else if ([self.touchbarItems[identifier][@"type"] isEqualToString:@"text"]) {
NSCustomTouchBarItem *tbItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
@@ -154,12 +124,124 @@
tbItem.view = tbText;
tbItem.customizationLabel = self.touchbarItems[identifier][@"name"];
[self.touchbarItems[identifier] setObject:tbText forKey:@"view"];
[self.touchbarItems[identifier] setObject:tbItem forKey:@"tbItem"];
[tbItem addObserver:self forKeyPath:@"visible" options:0 context:nil];
return tbItem;
}
return nil;
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"visible"]) {
NSNumber *visible = [object valueForKey:@"visible"];
if (visible.boolValue) {
[self updateTouchBarTimeItems];
[self updatePlayButton];
}
}
}
- (void)updateTouchBarTimeItems
{
if (!self.isVisible)
return;
[self updateSlider];
[self updateTimeLeft];
[self updateCurrentPosition];
}
- (void)updateSlider
{
NSCustomTouchBarItem *tbItem = self.touchbarItems[seekBar][@"tbItem"];
if (!tbItem.visible)
return;
NSSlider *seekSlider = self.touchbarItems[seekBar][@"view"];
if (self.duration <= 0) {
seekSlider.enabled = NO;
seekSlider.doubleValue = 0;
} else {
seekSlider.enabled = YES;
if (!seekSlider.highlighted)
seekSlider.doubleValue = (self.position/self.duration)*100;
}
}
- (void)updateTimeLeft
{
NSCustomTouchBarItem *tbItem = self.touchbarItems[timeLeft][@"tbItem"];
if (!tbItem.visible)
return;
NSTextField *timeLeftItem = self.touchbarItems[timeLeft][@"view"];
[self removeConstraintForIdentifier:timeLeft];
if (self.duration <= 0) {
timeLeftItem.stringValue = @"";
} else {
int left = (int)(floor(self.duration)-floor(self.position));
NSString *leftFormat = [self formatTime:left];
NSString *durFormat = [self formatTime:self.duration];
timeLeftItem.stringValue = [NSString stringWithFormat:@"-%@", leftFormat];
[self applyConstraintFromString:[NSString stringWithFormat:@"-%@", durFormat]
forIdentifier:timeLeft];
}
}
- (void)updateCurrentPosition
{
NSCustomTouchBarItem *tbItem = self.touchbarItems[currentPosition][@"tbItem"];
if (!tbItem.visible)
return;
NSTextField *curPosItem = self.touchbarItems[currentPosition][@"view"];
NSString *posFormat = [self formatTime:(int)floor(self.position)];
curPosItem.stringValue = posFormat;
[self removeConstraintForIdentifier:currentPosition];
if (self.duration <= 0) {
[self applyConstraintFromString:[self formatTime:self.position]
forIdentifier:currentPosition];
} else {
NSString *durFormat = [self formatTime:self.duration];
[self applyConstraintFromString:durFormat forIdentifier:currentPosition];
}
}
- (void)updatePlayButton
{
NSCustomTouchBarItem *tbItem = self.touchbarItems[play][@"tbItem"];
if (!self.isVisible || !tbItem.visible)
return;
NSButton *playButton = self.touchbarItems[play][@"view"];
if (self.pause) {
playButton.image = self.touchbarItems[play][@"imageAlt"];
} else {
playButton.image = self.touchbarItems[play][@"image"];
}
}
- (void)buttonAction:(NSButton *)sender
{
NSString *identifier = [self getIdentifierFromView:sender];
[self.app queueCommand:(char *)[self.touchbarItems[identifier][@"cmd"] UTF8String]];
}
- (void)seekbarChanged:(NSSlider *)slider
{
NSString *identifier = [self getIdentifierFromView:slider];
NSString *seek = [NSString stringWithFormat:
self.touchbarItems[identifier][@"cmd"], slider.doubleValue];
[self.app queueCommand:(char *)[seek UTF8String]];
}
- (NSString *)formatTime:(int)time
{
int seconds = time % 60;
@@ -204,48 +286,6 @@
}
}
- (void)updateTouchBarTimeItemConstrains
{
[self removeConstraintForIdentifier:currentPosition];
[self removeConstraintForIdentifier:timeLeft];
if (self.duration <= 0) {
[self applyConstraintFromString:[self formatTime:self.position]
forIdentifier:currentPosition];
} else {
NSString *durFormat = [self formatTime:self.duration];
[self applyConstraintFromString:durFormat forIdentifier:currentPosition];
[self applyConstraintFromString:[NSString stringWithFormat:@"-%@", durFormat]
forIdentifier:timeLeft];
}
}
- (void)updateTouchBarTimeItems
{
NSSlider *seekSlider = self.touchbarItems[seekBar][@"view"];
NSTextField *curPosItem = self.touchbarItems[currentPosition][@"view"];
NSTextField *timeLeftItem = self.touchbarItems[timeLeft][@"view"];
if (self.duration <= 0) {
seekSlider.enabled = NO;
seekSlider.doubleValue = 0;
timeLeftItem.stringValue = @"";
}
else {
seekSlider.enabled = YES;
if (!seekSlider.highlighted)
seekSlider.doubleValue = (self.position/self.duration)*100;
int left = (int)(floor(self.duration)-floor(self.position));
NSString *leftFormat = [self formatTime:left];
timeLeftItem.stringValue = [NSString stringWithFormat:@"-%@", leftFormat];
}
NSString *posFormat = [self formatTime:(int)floor(self.position)];
curPosItem.stringValue = posFormat;
[self updateTouchBarTimeItemConstrains];
}
- (NSString *)getIdentifierFromView:(id)view
{
NSString *identifier;
@@ -255,18 +295,40 @@
return identifier;
}
- (void)buttonAction:(NSButton *)sender
- (void)processEvent:(struct mpv_event *)event
{
NSString *identifier = [self getIdentifierFromView:sender];
[self.app queueCommand:(char *)[self.touchbarItems[identifier][@"cmd"] UTF8String]];
switch (event->event_id) {
case MPV_EVENT_END_FILE: {
self.position = 0;
self.duration = 0;
break;
}
case MPV_EVENT_PROPERTY_CHANGE: {
[self handlePropertyChange:(mpv_event_property *)event->data];
break;
}
}
}
- (void)seekbarChanged:(NSSliderTouchBarItem *)sender
- (void)handlePropertyChange:(struct mpv_event_property *)property
{
NSString *identifier = [self getIdentifierFromView:sender.slider];
NSString *seek = [NSString stringWithFormat:
self.touchbarItems[identifier][@"cmd"], sender.slider.doubleValue];
[self.app queueCommand:(char *)[seek UTF8String]];
NSString *name = [NSString stringWithUTF8String:property->name];
mpv_format format = property->format;
if ([name isEqualToString:@"time-pos"] && format == MPV_FORMAT_DOUBLE) {
double newPosition = *(double *)property->data;
newPosition = newPosition < 0 ? 0 : newPosition;
if ((int)(floor(newPosition) - floor(self.position)) != 0) {
self.position = newPosition;
[self updateTouchBarTimeItems];
}
} else if ([name isEqualToString:@"duration"] && format == MPV_FORMAT_DOUBLE) {
self.duration = *(double *)property->data;
[self updateTouchBarTimeItems];
} else if ([name isEqualToString:@"pause"] && format == MPV_FORMAT_FLAG) {
self.pause = *(int *)property->data;
[self updatePlayButton];
}
}
@end
+22 -2
View File
@@ -45,6 +45,14 @@
// Timeout in ms after which the (normally ambiguous) ESC key is detected.
#define ESC_TIMEOUT 100
// Timeout in ms after which the poll for input is aborted. The FG/BG state is
// tested before every wait, and a positive value allows reactivating input
// processing when mpv is brought to the foreground while it was running in the
// background. In such a situation, an infinite timeout (-1) will keep mpv
// waiting for input without realizing the terminal state changed - and thus
// buffer all keypresses until ENTER is pressed.
#define INPUT_TIMEOUT 1000
static volatile struct termios tio_orig;
static volatile int tio_orig_set;
@@ -213,6 +221,17 @@ static void process_input(struct input_ctx *input_ctx, bool timeout)
if (!match) { // normal or unknown key
int mods = 0;
if (buf.b[0] == '\033') {
if (buf.len > 1 && buf.b[1] == '[') {
// unknown CSI sequence. wait till it completes
for (int i = 2; i < buf.len; i++) {
if (buf.b[i] >= 0x40 && buf.b[i] <= 0x7E) {
skip_buf(&buf, i+1);
continue; // complete - throw it away
}
}
goto read_more; // not yet complete
}
// non-CSI esc sequence
skip_buf(&buf, 1);
if (buf.len > 0 && buf.b[0] > 0 && buf.b[0] < 127) {
// meta+normal key
@@ -227,7 +246,8 @@ static void process_input(struct input_ctx *input_ctx, bool timeout)
unsigned char c = buf.b[0];
skip_buf(&buf, 1);
if (c < 32) {
c = c <= 25 ? (c + 'a' - 1) : (c - 25 + '2' - 1);
// 1..26 is ^A..^Z, and 27..31 is ^3..^7
c = c <= 26 ? (c + 'a' - 1) : (c + '3' - 27);
mods |= MP_KEY_MODIFIER_CTRL;
}
mp_input_put_key(input_ctx, c | mods);
@@ -397,7 +417,7 @@ static void *terminal_thread(void *ptr)
{ .events = POLLIN, .fd = death_pipe[0] },
{ .events = POLLIN, .fd = tty_in }
};
int r = polldev(fds, stdin_ok ? 2 : 1, buf.len ? ESC_TIMEOUT : -1);
int r = polldev(fds, stdin_ok ? 2 : 1, buf.len ? ESC_TIMEOUT : INPUT_TIMEOUT);
if (fds[0].revents)
break;
if (fds[1].revents) {
+60 -1
View File
@@ -19,12 +19,39 @@
#include <sys/time.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <versionhelpers.h>
#include "timer.h"
#include "config.h"
static LARGE_INTEGER perf_freq;
// ms values
static int hires_max = 50;
static int hires_res = 1;
int mp_start_hires_timers(int wait_ms)
{
#if !HAVE_UWP
// policy: request hires_res ms resolution if wait < hires_max ms
if (wait_ms > 0 && wait_ms <= hires_max &&
timeBeginPeriod(hires_res) == TIMERR_NOERROR)
{
return hires_res;
}
#endif
return 0;
}
void mp_end_hires_timers(int res_ms)
{
#if !HAVE_UWP
if (res_ms > 0)
timeEndPeriod(res_ms);
#endif
}
void mp_sleep_us(int64_t us)
{
if (us < 0)
@@ -34,7 +61,9 @@ void mp_sleep_us(int64_t us)
// it may take some time until it actually starts to run again
if (us < 1000)
us = 1000;
int hrt = mp_start_hires_timers(us / 1000);
Sleep(us / 1000);
mp_end_hires_timers(hrt);
}
uint64_t mp_raw_time_us(void)
@@ -52,7 +81,37 @@ uint64_t mp_raw_time_us(void)
void mp_raw_time_init(void)
{
QueryPerformanceFrequency(&perf_freq);
#if !HAVE_UWP
timeBeginPeriod(1); // request 1ms timer resolution
// allow (undocumented) control of all the High Res Timers parameters,
// for easier experimentation and diagnostic of bug reports.
const char *v;
// 1..1000 ms max timetout for hires (used in "perwait" mode)
if ((v = getenv("MPV_HRT_MAX"))) {
int hmax = atoi(v);
if (hmax >= 1 && hmax <= 1000)
hires_max = hmax;
}
// 1..15 ms hires resolution (not used in "never" mode)
if ((v = getenv("MPV_HRT_RES"))) {
int res = atoi(v);
if (res >= 1 && res <= 15)
hires_res = res;
}
// "always"/"never"/"perwait" (or "auto" - same as unset)
if (!(v = getenv("MPV_HRT")) || !strcmp(v, "auto"))
v = IsWindows10OrGreater() ? "perwait" : "always";
if (!strcmp(v, "perwait")) {
// no-op, already per-wait
} else if (!strcmp(v, "never")) {
hires_max = 0;
} else { // "always" or unknown value
hires_max = 0;
timeBeginPeriod(hires_res);
}
#endif
}
+8
View File
@@ -37,6 +37,14 @@ uint64_t mp_raw_time_us(void);
// Sleep in microseconds.
void mp_sleep_us(int64_t us);
#ifdef _WIN32
// returns: timer resolution in ms if needed and started successfully, else 0
int mp_start_hires_timers(int wait_ms);
// call unconditionally with the return value of mp_start_hires_timers
void mp_end_hires_timers(int resolution_ms);
#endif /* _WIN32 */
#define MP_START_TIME 10000000
// Duration of a second in mpv time.
+4
View File
@@ -22,6 +22,8 @@
#include <sys/time.h>
#include <assert.h>
#include "osdep/timer.h" // mp_{start,end}_hires_timers
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
{
BOOL pending;
@@ -78,11 +80,13 @@ static int cond_wait(pthread_cond_t *restrict cond,
DWORD ms)
{
BOOL res;
int hrt = mp_start_hires_timers(ms);
if (mutex->use_cs) {
res = SleepConditionVariableCS(cond, &mutex->lock.cs, ms);
} else {
res = SleepConditionVariableSRW(cond, &mutex->lock.srw, ms, 0);
}
mp_end_hires_timers(hrt);
return res ? 0 : ETIMEDOUT;
}
+21 -12
View File
@@ -314,6 +314,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao)
mp_async_queue_set_notifier(ao_c->queue_filter, ao_c->ao_filter);
// Make sure filtering never stops with frames stuck in access filter.
mp_filter_set_high_priority(ao_c->queue_filter, true);
audio_update_volume(ao_c->mpctx);
}
if (ao_c->filter->ao_needs_update)
@@ -322,7 +323,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao)
mp_filter_wakeup(ao_c->ao_filter);
}
static void reinit_audio_filters_and_output(struct MPContext *mpctx)
static int reinit_audio_filters_and_output(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
struct ao_chain *ao_c = mpctx->ao_chain;
@@ -359,13 +360,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
{
ao_chain_set_ao(ao_c, mpctx->ao);
talloc_free(out_fmt);
return;
return 0;
}
// Wait until all played.
if (mpctx->ao && ao_is_playing(mpctx->ao)) {
talloc_free(out_fmt);
return;
return 0;
}
// Format change during syncing. Force playback start early, then wait.
if (ao_c->ao_queue && mp_async_queue_get_frames(ao_c->ao_queue) &&
@@ -374,11 +375,11 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
mpctx->audio_status = STATUS_READY;
mp_wakeup_core(mpctx);
talloc_free(out_fmt);
return;
return 0;
}
if (mpctx->audio_status == STATUS_READY) {
talloc_free(out_fmt);
return;
return 0;
}
uninit_audio_out(mpctx);
@@ -446,7 +447,7 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
reset_audio_state(mpctx);
mp_output_chain_reset_harder(ao_c->filter);
mp_wakeup_core(mpctx); // reinit with new format next time
return;
return 0;
}
MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n");
@@ -477,12 +478,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
mp_wakeup_core(mpctx);
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
return;
return 0;
init_error:
uninit_audio_chain(mpctx);
uninit_audio_out(mpctx);
error_on_track(mpctx, track);
return -1;
}
int init_audio_decoder(struct MPContext *mpctx, struct track *track)
@@ -516,7 +518,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
struct track *track = NULL;
track = mpctx->current_track[0][STREAM_AUDIO];
if (!track || !track->stream) {
uninit_audio_out(mpctx);
if (!mpctx->encode_lavc_ctx)
uninit_audio_out(mpctx);
error_on_track(mpctx, track);
return;
}
@@ -820,8 +823,10 @@ void audio_start_ao(struct MPContext *mpctx)
MP_VERBOSE(mpctx, "starting audio playback\n");
ao_start(ao_c->ao);
mpctx->audio_status = STATUS_PLAYING;
if (ao_c->out_eof)
if (ao_c->out_eof) {
mpctx->audio_status = STATUS_DRAINING;
MP_VERBOSE(mpctx, "audio draining\n");
}
ao_c->underrun = false;
mpctx->logged_async_diff = -1;
mp_wakeup_core(mpctx);
@@ -849,8 +854,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx)
return;
}
if (ao_c->filter->ao_needs_update)
reinit_audio_filters_and_output(mpctx);
if (ao_c->filter->ao_needs_update) {
if (reinit_audio_filters_and_output(mpctx) < 0)
return;
}
if (mpctx->vo_chain && ao_c->track && ao_c->track->dec &&
mp_decoder_wrapper_get_pts_reset(ao_c->track->dec))
@@ -870,8 +877,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx)
// until the old audio is fully played.
// (Buggy if AO underruns.)
if (mpctx->ao && ao_is_playing(mpctx->ao) &&
mpctx->video_status != STATUS_EOF)
mpctx->video_status != STATUS_EOF) {
MP_VERBOSE(mpctx, "blocked, waiting for old audio to play\n");
ok = false;
}
if (ao_c->start_pts_known != ok || ao_c->start_pts != pts) {
ao_c->start_pts_known = ok;
+178 -49
View File
@@ -54,6 +54,7 @@
#include "options/m_option.h"
#include "options/m_property.h"
#include "options/m_config_frontend.h"
#include "osdep/getpid.h"
#include "video/out/vo.h"
#include "video/csputils.h"
#include "video/hwdec.h"
@@ -426,6 +427,13 @@ static int mp_property_display_sync_active(void *ctx, struct m_property *prop,
return m_property_flag_ro(action, arg, mpctx->display_sync_active);
}
static int mp_property_pid(void *ctx, struct m_property *prop,
int action, void *arg)
{
// 32 bit on linux/windows - which C99 `int' is not guaranteed to hold
return m_property_int64_ro(action, arg, mp_getpid());
}
/// filename with path (RO)
static int mp_property_path(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -1941,6 +1949,7 @@ static int get_track_entry(int item, int action, void *arg, void *ctx)
.unavailable = !track->lang},
{"audio-channels", SUB_PROP_INT(track_channels(track)),
.unavailable = track_channels(track) <= 0},
{"image", SUB_PROP_FLAG(track->image)},
{"albumart", SUB_PROP_FLAG(track->attached_picture)},
{"default", SUB_PROP_FLAG(track->default_track)},
{"forced", SUB_PROP_FLAG(track->forced_track)},
@@ -2067,6 +2076,16 @@ static int property_current_tracks(void *ctx, struct m_property *prop,
return M_PROPERTY_UNKNOWN;
struct track *t = mpctx->current_track[order][type];
if (!t && mpctx->lavfi) {
for (int n = 0; n < mpctx->num_tracks; n++) {
if (mpctx->tracks[n]->type == type && mpctx->tracks[n]->selected) {
t = mpctx->tracks[n];
break;
}
}
}
if (!t)
return M_PROPERTY_UNAVAILABLE;
@@ -2322,6 +2341,25 @@ static int mp_property_current_window_scale(void *ctx, struct m_property *prop,
if (vid_w < 1 || vid_h < 1)
return M_PROPERTY_UNAVAILABLE;
if (params.rotate % 180 == 90 && (vo->driver->caps & VO_CAP_ROTATE90))
MPSWAP(int, vid_w, vid_h);
if (vo->monitor_par < 1) {
vid_h = MPCLAMP(vid_h / vo->monitor_par, 1, 16000);
} else {
vid_w = MPCLAMP(vid_w * vo->monitor_par, 1, 16000);
}
if (action == M_PROPERTY_SET) {
// Also called by update_window_scale as a NULL property.
double scale = *(double *)arg;
int s[2] = {vid_w * scale, vid_h * scale};
if (s[0] <= 0 || s[1] <= 0)
return M_PROPERTY_INVALID_FORMAT;
vo_control(vo, VOCTRL_SET_UNFS_WINDOW_SIZE, s);
return M_PROPERTY_OK;
}
int s[2];
if (vo_control(vo, VOCTRL_GET_UNFS_WINDOW_SIZE, s) <= 0 ||
s[0] < 1 || s[1] < 1)
@@ -2334,20 +2372,9 @@ static int mp_property_current_window_scale(void *ctx, struct m_property *prop,
static void update_window_scale(struct MPContext *mpctx)
{
struct vo *vo = mpctx->video_out;
if (!vo)
return;
struct mp_image_params params = get_video_out_params(mpctx);
int vid_w, vid_h;
mp_image_params_get_dsize(&params, &vid_w, &vid_h);
if (vid_w < 1 || vid_h < 1)
return;
double scale = mpctx->opts->vo->window_scale;
int s[2] = {vid_w * scale, vid_h * scale};
if (s[0] > 0 && s[1] > 0)
vo_control(vo, VOCTRL_SET_UNFS_WINDOW_SIZE, s);
mp_property_current_window_scale(mpctx, (struct m_property *)NULL,
M_PROPERTY_SET, (void*)&scale);
}
static int mp_property_display_fps(void *ctx, struct m_property *prop,
@@ -2404,6 +2431,23 @@ static int mp_property_vsync_jitter(void *ctx, struct m_property *prop,
return m_property_double_ro(action, arg, stddev);
}
static int mp_property_display_resolution(void *ctx, struct m_property *prop,
int action, void *arg)
{
MPContext *mpctx = ctx;
struct vo *vo = mpctx->video_out;
if (!vo)
return M_PROPERTY_UNAVAILABLE;
int res[2];
if (vo_control(vo, VOCTRL_GET_DISPLAY_RES, &res) <= 0)
return M_PROPERTY_UNAVAILABLE;
if (strcmp(prop->name, "display-width") == 0) {
return m_property_int_ro(action, arg, res[0]);
} else {
return m_property_int_ro(action, arg, res[1]);
}
}
static int mp_property_hidpi_scale(void *ctx, struct m_property *prop,
int action, void *arg)
{
@@ -2587,14 +2631,14 @@ static int mp_property_osd_dim(void *ctx, struct m_property *prop,
(vo_res.display_par ? vo_res.display_par : 1);
struct m_sub_property props[] = {
{"w", SUB_PROP_DOUBLE(vo_res.w)},
{"h", SUB_PROP_DOUBLE(vo_res.h)},
{"w", SUB_PROP_INT(vo_res.w)},
{"h", SUB_PROP_INT(vo_res.h)},
{"par", SUB_PROP_DOUBLE(vo_res.display_par)},
{"aspect", SUB_PROP_DOUBLE(aspect)},
{"mt", SUB_PROP_DOUBLE(vo_res.mt)},
{"mb", SUB_PROP_DOUBLE(vo_res.mb)},
{"ml", SUB_PROP_DOUBLE(vo_res.ml)},
{"mr", SUB_PROP_DOUBLE(vo_res.mr)},
{"mt", SUB_PROP_INT(vo_res.mt)},
{"mb", SUB_PROP_INT(vo_res.mb)},
{"ml", SUB_PROP_INT(vo_res.ml)},
{"mr", SUB_PROP_INT(vo_res.mr)},
{0}
};
@@ -2805,12 +2849,12 @@ static int mp_property_sub_pos(void *ctx, struct m_property *prop,
return mp_property_generic_option(mpctx, prop, action, arg);
}
static int mp_property_sub_text(void *ctx, struct m_property *prop,
int action, void *arg)
static int get_sub_text(void *ctx, struct m_property *prop,
int action, void *arg, int sub_index)
{
int type = *(int *)prop->priv;
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_SUB];
struct track *track = mpctx->current_track[sub_index][STREAM_SUB];
struct dec_sub *sub = track ? track->d_sub : NULL;
double pts = mpctx->playback_pts;
if (!sub || pts == MP_NOPTS_VALUE)
@@ -2831,12 +2875,25 @@ static int mp_property_sub_text(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
static int mp_property_sub_text(void *ctx, struct m_property *prop,
int action, void *arg)
{
return get_sub_text(ctx, prop, action, arg, 0);
}
static int mp_property_secondary_sub_text(void *ctx, struct m_property *prop,
int action, void *arg)
{
return get_sub_text(ctx, prop, action, arg, 1);
}
static struct sd_times get_times(void *ctx, struct m_property *prop,
int action, void *arg)
{
struct sd_times res = { .start = MP_NOPTS_VALUE, .end = MP_NOPTS_VALUE };
MPContext *mpctx = ctx;
struct track *track = mpctx->current_track[0][STREAM_SUB];
int track_ind = *(int *)prop->priv;
struct track *track = mpctx->current_track[track_ind][STREAM_SUB];
struct dec_sub *sub = track ? track->d_sub : NULL;
double pts = mpctx->playback_pts;
if (!sub || pts == MP_NOPTS_VALUE)
@@ -3500,6 +3557,7 @@ static int mp_property_script_props(void *ctx, struct m_property *prop,
// Base list of properties. This does not include option-mapped properties.
static const struct m_property mp_properties_base[] = {
// General
{"pid", mp_property_pid},
{"speed", mp_property_playback_speed},
{"audio-speed-correction", mp_property_av_speed_correction, .priv = "a"},
{"video-speed-correction", mp_property_av_speed_correction, .priv = "v"},
@@ -3519,6 +3577,8 @@ static const struct m_property mp_properties_base[] = {
{"total-avsync-change", mp_property_total_avsync_change},
{"mistimed-frame-count", mp_property_mistimed_frame_count},
{"vsync-ratio", mp_property_vsync_ratio},
{"display-width", mp_property_display_resolution},
{"display-height", mp_property_display_resolution},
{"decoder-frame-drop-count", mp_property_frame_drop_dec},
{"frame-drop-count", mp_property_frame_drop_vo},
{"vo-delayed-frame-count", mp_property_vo_delayed_frame_count},
@@ -3630,10 +3690,18 @@ static const struct m_property mp_properties_base[] = {
{"sub-pos", mp_property_sub_pos},
{"sub-text", mp_property_sub_text,
.priv = (void *)&(const int){SD_TEXT_TYPE_PLAIN}},
{"secondary-sub-text", mp_property_secondary_sub_text,
.priv = (void *)&(const int){SD_TEXT_TYPE_PLAIN}},
{"sub-text-ass", mp_property_sub_text,
.priv = (void *)&(const int){SD_TEXT_TYPE_ASS}},
{"sub-start", mp_property_sub_start},
{"sub-end", mp_property_sub_end},
{"sub-start", mp_property_sub_start,
.priv = (void *)&(const int){0}},
{"secondary-sub-start", mp_property_sub_start,
.priv = (void *)&(const int){1}},
{"sub-end", mp_property_sub_end,
.priv = (void *)&(const int){0}},
{"secondary-sub-end", mp_property_sub_end,
.priv = (void *)&(const int){1}},
{"vf", mp_property_vf},
{"af", mp_property_af},
@@ -3710,10 +3778,10 @@ static const char *const *const mp_event_property_change[] = {
"estimated-vf-fps", "drop-frame-count", "vo-drop-frame-count",
"total-avsync-change", "audio-speed-correction", "video-speed-correction",
"vo-delayed-frame-count", "mistimed-frame-count", "vsync-ratio",
"estimated-display-fps", "vsync-jitter", "sub-text", "audio-bitrate",
"video-bitrate", "sub-bitrate", "decoder-frame-drop-count",
"estimated-display-fps", "vsync-jitter", "sub-text", "secondary-sub-text",
"audio-bitrate", "video-bitrate", "sub-bitrate", "decoder-frame-drop-count",
"frame-drop-count", "video-frame-info", "vf-metadata", "af-metadata",
"sub-start", "sub-end"),
"sub-start", "sub-end", "secondary-sub-start", "secondary-sub-end"),
E(MP_EVENT_DURATION_UPDATE, "duration"),
E(MPV_EVENT_VIDEO_RECONFIG, "video-out-params", "video-params",
"video-format", "video-codec", "video-bitrate", "dwidth", "dheight",
@@ -3734,7 +3802,8 @@ static const char *const *const mp_event_property_change[] = {
"demuxer-cache-state"),
E(MP_EVENT_WIN_RESIZE, "current-window-scale", "osd-width", "osd-height",
"osd-par", "osd-dimensions"),
E(MP_EVENT_WIN_STATE, "display-names", "display-fps"),
E(MP_EVENT_WIN_STATE, "display-names", "display-fps", "display-width",
"display-height"),
E(MP_EVENT_WIN_STATE2, "display-hidpi-scale"),
E(MP_EVENT_FOCUS, "focused"),
E(MP_EVENT_CHANGE_PLAYLIST, "playlist", "playlist-pos", "playlist-pos-1",
@@ -3917,6 +3986,7 @@ static const struct property_osd_display {
{"taskbar-progress", "Progress in taskbar"},
{"snap-window", "Snap to screen edges"},
{"ontop", "Stay on top"},
{"on-all-workspaces", "Visibility on all workspaces"},
{"border", "Border"},
{"framedrop", "Framedrop"},
{"deinterlace", "Deinterlace"},
@@ -3935,6 +4005,9 @@ static const struct property_osd_display {
{"sub-visibility",
.msg = "Subtitles ${!sub-visibility==yes:hidden}"
"${?sub-visibility==yes:visible${?sub==no: (but no subtitles selected)}}"},
{"secondary-sub-visibility",
.msg = "Secondary Subtitles ${!secondary-sub-visibility==yes:hidden}"
"${?secondary-sub-visibility==yes:visible${?secondary-sid==no: (but no secondary subtitles selected)}}"},
{"sub-forced-only", "Forced sub only"},
{"sub-scale", "Sub Scale"},
{"sub-ass-vsfilter-aspect-compat", "Subtitle VSFilter aspect compat"},
@@ -4859,7 +4932,9 @@ static void cmd_add_cycle(void *p)
bool is_cycle = !!cmd->priv;
char *property = cmd->args[0].v.s;
if (cmd->cmd->repeated && !check_property_autorepeat(property, mpctx)) {
if (cmd->cmd->repeated && !check_property_autorepeat(property, mpctx) &&
!(cmd->cmd->flags & MP_ALLOW_REPEAT) /* "repeatable" prefix */ )
{
MP_VERBOSE(mpctx, "Dropping command '%s' from auto-repeated key.\n",
cmd->cmd->original);
return;
@@ -4981,13 +5056,14 @@ static void cmd_sub_step_seek(void *p)
struct mp_cmd_ctx *cmd = p;
struct MPContext *mpctx = cmd->mpctx;
bool step = *(bool *)cmd->priv;
int track_ind = cmd->args[1].v.i;
if (!mpctx->playback_initialized) {
cmd->success = false;
return;
}
struct track *track = mpctx->current_track[0][STREAM_SUB];
struct track *track = mpctx->current_track[track_ind][STREAM_SUB];
struct dec_sub *sub = track ? track->d_sub : NULL;
double refpts = get_current_time(mpctx);
if (sub && refpts != MP_NOPTS_VALUE) {
@@ -5097,7 +5173,7 @@ static void cmd_loadlist(void *p)
struct mp_cmd_ctx *cmd = p;
struct MPContext *mpctx = cmd->mpctx;
char *filename = cmd->args[0].v.s;
bool append = cmd->args[1].v.i;
int append = cmd->args[1].v.i;
struct playlist *pl = playlist_parse_file(filename, cmd->abort->cancel,
mpctx->global);
@@ -5114,7 +5190,7 @@ static void cmd_loadlist(void *p)
if (!new)
new = playlist_get_first(mpctx->playlist);
if (!append && new)
if ((!append || (append == 2 && !mpctx->playlist->current)) && new)
mp_set_playlist_entry(mpctx, new);
struct mpv_node *res = &cmd->result;
@@ -5240,6 +5316,8 @@ static void cmd_track_add(void *p)
struct mp_cmd_ctx *cmd = p;
struct MPContext *mpctx = cmd->mpctx;
int type = *(int *)cmd->priv;
bool is_albumart = type == STREAM_VIDEO &&
cmd->args[4].v.i;
if (mpctx->stop_play) {
cmd->success = false;
@@ -5259,7 +5337,7 @@ static void cmd_track_add(void *p)
}
}
int first = mp_add_external_file(mpctx, cmd->args[0].v.s, type,
cmd->abort->cancel);
cmd->abort->cancel, is_albumart);
if (first < 0) {
cmd->success = false;
return;
@@ -5322,8 +5400,10 @@ static void cmd_track_reload(void *p)
if (t && t->is_external && t->external_filename) {
char *filename = talloc_strdup(NULL, t->external_filename);
bool is_albumart = t->attached_picture;
mp_remove_track(mpctx, t);
nt_num = mp_add_external_file(mpctx, filename, type, cmd->abort->cancel);
nt_num = mp_add_external_file(mpctx, filename, type, cmd->abort->cancel,
is_albumart);
talloc_free(filename);
}
@@ -6015,10 +6095,28 @@ const struct mp_cmd_def mp_cmds[] = {
},
{ "playlist-shuffle", cmd_playlist_shuffle, },
{ "playlist-unshuffle", cmd_playlist_unshuffle, },
{ "sub-step", cmd_sub_step_seek, { {"skip", OPT_INT(v.i)} },
.allow_auto_repeat = true, .priv = &(const bool){true} },
{ "sub-seek", cmd_sub_step_seek, { {"skip", OPT_INT(v.i)} },
.allow_auto_repeat = true, .priv = &(const bool){false} },
{ "sub-step", cmd_sub_step_seek,
{
{"skip", OPT_INT(v.i)},
{"flags", OPT_CHOICE(v.i,
{"primary", 0},
{"secondary", 1}),
OPTDEF_INT(0)},
},
.allow_auto_repeat = true,
.priv = &(const bool){true}
},
{ "sub-seek", cmd_sub_step_seek,
{
{"skip", OPT_INT(v.i)},
{"flags", OPT_CHOICE(v.i,
{"primary", 0},
{"secondary", 1}),
OPTDEF_INT(0)},
},
.allow_auto_repeat = true,
.priv = &(const bool){false}
},
{ "print-text", cmd_print_text, { {"text", OPT_STRING(v.s)} },
.is_noisy = true, .allow_auto_repeat = true },
{ "show-text", cmd_show_text,
@@ -6070,6 +6168,7 @@ const struct mp_cmd_def mp_cmds[] = {
.flags = MP_CMD_OPT_ARG},
{"title", OPT_STRING(v.s), .flags = MP_CMD_OPT_ARG},
{"lang", OPT_STRING(v.s), .flags = MP_CMD_OPT_ARG},
{"albumart", OPT_FLAG(v.i), .flags = MP_CMD_OPT_ARG},
},
.priv = &(const int){STREAM_VIDEO},
.spawn_thread = true,
@@ -6165,7 +6264,10 @@ const struct mp_cmd_def mp_cmds[] = {
{ "loadlist", cmd_loadlist,
{
{"url", OPT_STRING(v.s)},
{"flags", OPT_CHOICE(v.i, {"replace", 0}, {"append", 1}),
{"flags", OPT_CHOICE(v.i,
{"replace", 0},
{"append", 1},
{"append-play", 2}),
.flags = MP_CMD_OPT_ARG},
},
.spawn_thread = true,
@@ -6471,6 +6573,25 @@ static void update_priority(struct MPContext *mpctx)
#endif
}
static void update_track_switch(struct MPContext *mpctx, int order, int type)
{
if (!mpctx->playback_initialized)
return;
int tid = mpctx->opts->stream_id[order][type];
struct track *track;
if (tid == -1) {
// If "auto" reset to default track selection
track = select_default_track(mpctx, order, type);
mark_track_selection(mpctx, order, type, -1);
} else {
track = mp_track_by_tid(mpctx, type, tid);
}
mp_switch_track_n(mpctx, order, type, track, (tid == -1) ? 0 : FLAG_MARK_SELECTION);
print_track_list(mpctx, "Track switched:");
mp_wakeup_core(mpctx);
}
void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
bool self_update)
{
@@ -6525,6 +6646,16 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global);
}
if (opt_ptr == &opts->vo->video_driver_list) {
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
uninit_video_out(mpctx);
reinit_video_chain(mpctx);
if (track)
reselect_demux_stream(mpctx, track, true);
mp_wakeup_core(mpctx);
}
if (flags & UPDATE_AUDIO)
reload_audio_output(mpctx);
@@ -6619,15 +6750,8 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
for (int type = 0; type < STREAM_TYPE_COUNT; type++) {
for (int order = 0; order < num_ptracks[type]; order++) {
if (opt_ptr == &opts->stream_id[order][type] &&
mpctx->playback_initialized)
{
struct track *track =
mp_track_by_tid(mpctx, type, opts->stream_id[order][type]);
mp_switch_track_n(mpctx, order, type, track, FLAG_MARK_SELECTION);
print_track_list(mpctx, "Track switched:");
mp_wakeup_core(mpctx);
}
if (opt_ptr == &opts->stream_id[order][type])
update_track_switch(mpctx, order, type);
}
}
@@ -6636,6 +6760,11 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
if (opt_ptr == &opts->vo->taskbar_progress)
update_vo_playback_state(mpctx);
if (opt_ptr == &opts->image_display_duration && mpctx->vo_chain
&& mpctx->vo_chain->is_sparse && !mpctx->ao_chain
&& mpctx->video_status == STATUS_DRAINING)
mpctx->time_frame = opts->image_display_duration;
}
void mp_notify_property(struct MPContext *mpctx, const char *property)
+14 -74
View File
@@ -37,6 +37,7 @@
#include "misc/ctype.h"
#include "options/path.h"
#include "options/m_config.h"
#include "options/m_config_frontend.h"
#include "options/parse_configfile.h"
#include "common/playlist.h"
#include "options/options.h"
@@ -237,63 +238,6 @@ exit:
return res;
}
static const char *const backup_properties[] = {
"osd-level",
//"loop",
"speed",
"options/edition",
"pause",
"volume",
"mute",
"audio-delay",
//"balance",
"fullscreen",
"ontop",
"border",
"gamma",
"brightness",
"contrast",
"saturation",
"hue",
"options/deinterlace",
"vf",
"af",
"panscan",
"options/aid",
"options/vid",
"options/sid",
"sub-delay",
"sub-speed",
"sub-pos",
"sub-visibility",
"sub-scale",
"sub-use-margins",
"sub-ass-force-margins",
"sub-ass-vsfilter-aspect-compat",
"sub-style-override",
"ab-loop-a",
"ab-loop-b",
"options/video-aspect-override",
0
};
// Used to retrieve default settings, which should not be stored in the
// resume config. Uses backup_properties[] meaning/order of values.
// This explicitly includes values set by config files and command line.
void mp_get_resume_defaults(struct MPContext *mpctx)
{
char **list =
talloc_zero_array(mpctx, char*, MP_ARRAY_SIZE(backup_properties));
for (int i = 0; backup_properties[i]; i++) {
const char *pname = backup_properties[i];
char *val = NULL;
int r = mp_property_do(pname, M_PROPERTY_GET_STRING, &val, mpctx);
if (r == M_PROPERTY_OK)
list[i] = talloc_steal(list, val);
}
mpctx->resume_defaults = list;
}
// Should follow what parser-cfg.c does/needs
static bool needs_config_quoting(const char *s)
{
@@ -368,25 +312,21 @@ void mp_write_watch_later_conf(struct MPContext *mpctx)
} else {
fprintf(file, "start=%f\n", pos);
}
for (int i = 0; backup_properties[i]; i++) {
const char *pname = backup_properties[i];
char *val = NULL;
int r = mp_property_do(pname, M_PROPERTY_GET_STRING, &val, mpctx);
if (r == M_PROPERTY_OK) {
if (strncmp(pname, "options/", 8) == 0)
pname += 8;
// Only store it if it's different from the initial value.
char *prev = mpctx->resume_defaults[i];
if (!prev || strcmp(prev, val) != 0) {
if (needs_config_quoting(val)) {
// e.g. '%6%STRING'
fprintf(file, "%s=%%%d%%%s\n", pname, (int)strlen(val), val);
} else {
fprintf(file, "%s=%s\n", pname, val);
}
char **watch_later_options = mpctx->opts->watch_later_options;
for (int i = 0; watch_later_options && watch_later_options[i]; i++) {
char *pname = watch_later_options[i];
// Only store it if it's different from the initial value.
if (m_config_watch_later_backup_opt_changed(mpctx->mconfig, pname)) {
char *val = NULL;
mp_property_do(pname, M_PROPERTY_GET_STRING, &val, mpctx);
if (needs_config_quoting(val)) {
// e.g. '%6%STRING'
fprintf(file, "%s=%%%d%%%s\n", pname, (int)strlen(val), val);
} else {
fprintf(file, "%s=%s\n", pname, val);
}
talloc_free(val);
}
talloc_free(val);
}
fclose(file);
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more