Compare commits

...
584 Commits
Author SHA1 Message Date
sfan5 75d938912d Release 0.35.0 2022-11-12 14:52:40 +01:00
Dudemanguy c56d981cc6 meson: fix macos-touchbar check
Apparently, it is possible for touchbar.m to compile on non-macos
machines. Also, the disable switch didn't actually work either. Fix this
by using the require() function and making sure that Cocoa (should be
apple-only) is found in addition to the compile check passing which is
what waf does. Fixes #10847.
2022-11-11 19:47:43 +00:00
Jan Ekström 8758d96a33 github/workflows: force deletion of existing upstream python symlinks on macOS
This way each time a new Python version is installed via Homebrew
, we don't get CI failures due to the upstream Python distribution
also being installed.

Ref: actions/runner-images#6459
Ref: actions/runner-images#6507
Ref: actions/runner-images#2322
2022-11-11 21:25:03 +02:00
Niklas Haas 33136c276c vo_gpu_next: add tunable shader parameters
This is a very simple but easy way of doing it. Ideally, it would be
nice if we could also add some sort of introspection about shader
parameters at runtime, ideally exposing the entire list of parameters as
a custom property dict. But that is a lot of effort for dubious gain.

It's worth noting that, as currently implemented, re-setting
`glsl-shader-opts` to a new value doesn't reset back previously mutated
values to their defaults.
2022-11-11 13:58:35 +01:00
sfan5 ac3966184b vo_gpu: mark --gamma-factor and --gamma-auto with deprecation warnings
This was forgotten in commit 2207236aaa.
2022-11-10 16:19:37 +01:00
sfan5 175e250038 wayland, x11: fix possibly unsafe bstr usage
In practice this never led to any issues due to implementation
details of bstr_sanitize_utf8_latin1, but there's no guarantee that
a bstr is correctly null-terminated.
2022-11-10 16:19:37 +01:00
Thomas Weißschuh 2e5d0d6e07 ao_pipewire: reload ao on stream disconnect
This allows the core of mpv to know about issues in the AO.
Otherwise playback will just freeze as no more data callbacks are sent
by PipeWire.
Also it allows mpv to try to reconnect the AO or find another, working
AO.
2022-11-07 10:36:40 -08:00
Thomas Weißschuh b7cf35c9a4 ao_pipewire: explicitly remove stream hook
We want to add more logic to the stream event handler.
This logic should not be triggered during normal stream shutdown, so we
remove the listener beforehand.
2022-11-07 10:36:40 -08:00
Thomas Weißschuh bf7ade420d ao_pipewire: log generic stream errors 2022-11-07 10:36:40 -08:00
Aman Karmani 9f0381c51b Revert "ao/audiounit: include AVAudioSession buffer in latency calc"
This reverts commit 8b114e574a.
2022-11-07 18:45:55 +02:00
Aaron Boxer 00e3c90fb1 vo_dmabuf_wayland: improve error handling exporting VA surface
1. check for all error conditions when calling vaExportSurfaceHandle
2. only clean up valid descriptors
2022-11-07 16:42:01 +00:00
Aaron Boxer 259eda4e2f hwdec_vaapi: only set VADisplay resource if entire init process has succeeded
This resource is used by dmabuf_waland to decide if it should manage
vaapi buffers, so it should not be set if vaapi init has failed
2022-11-07 16:42:01 +00:00
Jan Ekström 25906514c3 github/workflows: remove seccomp disablement
Workflow virtual machines have now been updated so that moby package
contains rule for the newly added syscalls, such as 'clone3'.

Effectively reverts 64fa440c69 .
2022-11-05 23:54:27 +02:00
Jan Ekström 9087213916 github/workflows: bump linux jobs to Ubuntu 22.04 base VM
These utilize a custom docker container in any case, but this brings
us to consistency with the mingw-w64 jobs.
2022-11-05 23:54:27 +02:00
Jan Ekström f50cafd2cb github/workflows: move all build jobs to checkout V3
mingw-w64 has utilized this for a while so might as well make it
consistent.
2022-11-05 23:54:27 +02:00
Jan Ekström d525c3c6c2 github/workflows: remove xcode 13.0 to xcode 13.1 override
Thankfully, this version is no longer the default on any of the
macOS runners.

Effectively reverts a76527772e .
2022-11-05 23:54:27 +02:00
Jan Ekström 0076b51dd2 github/workflows: remove macOS 10.15 image usage
This older image has been deprecated and will be removed in December.
The images have also already had planned outages during which the CI
flow has been affected. Thus it feels like a good idea to clean
this up at this point.

Ref: actions/runner-images#5583
2022-11-05 23:54:27 +02:00
Oneric c416a38ef2 sd_ass: never mangle colours on RGB video
It turns out, even xy-VSFilter and XySubFilter do not
mangle colours if the video is native RGB regardless of
the sub's YCbCr header. libass' docs were also updated
to reflect this.
2022-11-05 09:32:05 -04:00
Dudemanguy c5b258b490 meson: move dmabuf-wayland specific files under the right check
This doesn't need to be under the generic wayland check, but the
dmabuf-wayland one. Matches the waf build.
2022-11-03 17:29:48 -05:00
Dudemanguy 2c53fb6a2b gpu/context: properly guard wldmabuf context
This should only be added if the build has dmabuf-wayland enabled. This
fixes #10828.
2022-11-03 17:24:09 -05:00
Christoph Heinrich 445a3561d3 console: add history deduplication
Deduplicate history like the fish shell. So for example
entering "cmd 1" then "cmd 2" then "cmd 3" then "cmd 1"
would result in a history of
[cmd 2][cmd 3][cmd 1]
instead of
[cmd 1][cmd 2][cmd 3][cmd 1]

Adds a function `history_add` to replace directly adding to history.
Adds an option `history_dedup` to activate the deduplication.
Defaults to on.
2022-11-03 13:30:58 +01:00
Dudemanguy 806dddc7d9 github/workflows: remove pip usage in mingw CI
This was only needed because the mingw CI used to run on Ubuntu 20.04
which had a version of meson too old for mpv. This hasn't been the case
since we switched to 22.04 in f7164fcfac
and can now just use the package manager version.
2022-11-02 21:03:29 +02:00
Niklas Haas 6acb7db9fa vo_gpu_next: set background transparency
Fixes: https://github.com/mpv-player/mpv/issues/10815
2022-11-01 19:09:40 +01:00
sfan5 7f5bcd7244 ci: upload resulting binary of mingw64 build 2022-11-01 16:30:59 +01:00
sfan5 f67a56b830 ci/mingw64: refresh build scripts
- newer library versions
- use libplacebo submodules
- prefer meson where possible
- fix minor details
2022-11-01 16:30:59 +01:00
Christoph Heinrich 1a633a6cbc ytdl_hook: reverse order of tracks
Only matters when configuring ytdl_hook with `all_formats=yes`.

So far the tracks were ordered from worst to best quality.

Web players with quality selection always show the highest quality
option at the top. Since tracks are usually listed with the first
track at the top, that should also be the highest quality one.

yt-dlp/youtube-dl sorts it's formats from worst to best.
Iterate in reverse to get best track first.
2022-11-01 09:54:33 -04:00
Leo Izen 3875312e41 demux/codec_tags: support more WAVEFORMATEXTENSIBLE tags
This patch adds support for two extra WAVEFORMATEXTENSIBLE GUID tags
that can appear inside RIFF headers. It also adds support for extra
codec IDs that may appear as their own unique wSubFormats inside RIFF
headers, such as ATRAC9 inside matroska, as one example.

Fixes #10757.
2022-11-01 09:52:27 -04:00
Lynne d555ae9571 wayland_common: always zero out presentation context when destroying it
A desync between the feedback and the feedback in the context
still happens when closing a hidden surface.
2022-10-31 20:46:29 -05:00
Dudemanguy 5fa3bca863 wayland: correct braindead comment (no-op)
I was confused in d3a28f12c9 why it
actually even worked, but after not being stupid, it's quite obviously
just a dangling pointer. The reason it only happens with
wp_presentation_feedback is because the object and listener actually
created in frame_callback not the presentation events itself (for vsync
timing reasons). So it is possible to free the object, but not
immediately recreate it again before quitting (unlike with the frame
callback). The actual comment is moved into feedback_presented (which is
first) but as of this commit it doesn't have the NULL setting logic
(that's the next one).
2022-10-31 20:45:56 -05:00
Dudemanguy d3a28f12c9 wayland: hack around presentation_feedback weirdness
964692ad4c added some code to destroy
presentation_feedback we get in the presentation_discarded event. This
is the correct thing to do since the compositor could send us this
instead of feedback_presented. Without that change, mutter could
potentially leak memory on every frame.

Unfortunately, life is not so simple and wlroots and weston act
differently. These compositors only send one presentation_discarded
event if the mpv window is hidden. Not on every single missed frame like
mutter. Now in theory this shouldn't matter, but it also turns out that
mpv attempts to free the presentation feedback twice if you quit it
while it is hidden away (on weston and wlroots compositors only). The
inital wp_presentation_feedback_destroy in feedback_discarded fires, but
then the function goes off again in vo_wayland_uninit because
wl->feedback is apparently not NULL for some reason. Possibly, this is
some race condition but we can't just get rid of what's in
feedback_discarded since mutter needs this line. Instead, just hack it
by explicitly setting wl->feedback to NULL in feedback_discarded after we
destroy the presentation feedback. Some valgrind testing in mutter,
sway, and weston shows that this works correctly on all of those
compositors with various combinations of mpv being visible or not while
quitting. feedback_presented doesn't appear to exhibit this behavior so
we just leave that as-is.
2022-10-30 14:23:55 +00:00
Dudemanguy 667222dffa wayland: free dmabuf_feedback object
666cb91cf1 added dmabuf_feedback, but it
was never actually free'd on uninit. Because this function requires
wayland protocols 1.24, we have to wrap it in an #if. Also throw in some
minor cosmetic changes in here.
2022-10-30 14:23:55 +00:00
Philip Langdale 8ba4ace1f6 test: update to reflect that Vulkan is a generic format again
In the previous change, I removed the explicit mapping for Vulkan, so
it now shows up as [GENERIC].
2022-10-29 19:18:43 -07:00
Philip Langdale 48bb17549c filters/f_hwtransfer: remove VAAPI <-> Vulkan mapping for now
This mapping isn't actually relevant until we have the Vulkan interop
merged, and it requires a newer version of libavutil than our minimum
requirement. So I'm going to remove it from master and put it in the
interop PR.

Fixes #10813
2022-10-29 18:49:46 -07:00
Dudemanguy f594482451 build: add an additional check for wayland-protocols 1.24
666cb91cf1 added support for v4 of the
dmabuf protocol. This was meant to be optional and the fallback support
for the old v2 (dates back to 2017[0] well before the 1.15
wayland-protocol version we depend on) was maintained. However, v4 added
several new functions and structs that of course aren't defined in old
protocol versions so naturally this breaks the build on those systems.
Since this is just a niche feature and not really critical to overall
wayland support in mpv, just give in and add another check in the build
system and #if out the newer stuff in wayland_common. v4 of linux-dmabuf
depends on wayland protocols 1-24[1], so go ahead and make that our new
check. Fixes #10807.

[0]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/commit/a840b3634ad637b237f238d2efb9ab8f4712d5f4
[1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/commit/8a5cd28a0e84911a5339855cb32ed63fb57ea40a
2022-10-29 20:41:20 +00:00
Dudemanguy a9e1905a4a meson: add more hardcoded values to configuration
mpv has a CONFIGURATION define which is defined at configure time in
both build systems and printed out when you use verbose flags. In waf,
this is line is exactly what the user passes on cli at configure time.
In meson, there's currently no way to do that (someone did recently open
up a PR that would make this possible), so we just hardcode the prefix
and call it a day. This is a bit of a tangent, but the build also
copies waf and sets an optimize variable (true or false) that is also
printed out on verbose output. For waf, this makes some sense because
the build has a specific --optimize option (internally all it does is
pass -O2). In meson, optimizing is a built-in option and we just set
anything that's not -O0 as "optimize". Furthermore, there is a new
optimization option added in meson 0.64 called "plain" which passes no
flags at all* so this logic would need to be updated to account for
this.

In retrospect, this is all just stupid though. optimization is not a
boolean value and there's no real use for treating it like one just
because that's what waf does. Let's remove it from the features array.
Instead, we can expose this information in the CONFIGURATION variable
along with the prefix option so we know exactly what optimization was
used in the compiled executable. For good measure, let's also throw in
buildtype since it's related.

*: https://github.com/mesonbuild/meson/commit/a590cfde0cf719c637b75e4784be0c0ae60e3b1f
2022-10-29 17:55:33 +00:00
Dudemanguy 0fa5bfae24 meson: use 'dl' instead of 'libdl' in find_library
Meson's master branch helpfully prints out a warning here now saying
that "find_library('libdl') starting in "lib" only works by accident
and is not portable". We'll go ahead and trust them and instead change
this to dl which works with no issues.
2022-10-29 17:55:33 +00:00
Dudemanguy 6ebc4928c5 ci: use meson setup build instead of meson build
The old "meson build" build command was actually deprecated a few months
ago*. It turns out that you're supposed to use "meson setup build"
instead which has been around for years. Go ahead and be a good citizen
and update this in the CI. Also replace any mention of "meson build"
with "meson setup build" in the documentation as well and change the one
random hardcoded string we have in meson.build to "meson configure
build" (might as well).

*: https://github.com/mesonbuild/meson/commit/3c7ab542c0c4770241eae149b0d4cd8de329aee0
2022-10-29 17:55:33 +00:00
rcombs 89bd6ead6c ao_coreaudio: specify UTF-8 as text encoding for CFString conversions
This matches our internal expectations, as well as fixes handling
of non-ASCII device descriptions.
2022-10-29 00:00:09 +03:00
Natural-Harmonia-Gropius e5e918954f options: log profile name if there is no restore data 2022-10-28 15:48:24 +00:00
Christoph Heinrich fd91776207 console: respect the top margin shared script property
Console already respected the bottom margin to not overlap with the
bottom bar from the OSC, but it would still overlap with the window
decorations from the OSC.

Now everything is clipped above the top margin and no superfluous lines
are drawn.
2022-10-28 13:04:32 +02:00
Dudemanguy adb556bf15 vo_dmabuf_wayland: use special ra_ctx_create_by_name
vo_dmabuf_wayland has its own ra and context so it can handle all the
different hwdec correctly. Unfortunately, this API was pretty clearly
designed with vo_gpu/vo_gpu_next in mind and has a lot of concepts that
don't make sense for vo_dmabuf_wayland. We still want to bolt on a
ra_ctx, but instead let's rework the ra_ctx logic a little bit. First,
this introduces a hidden bool within the ra_ctx_fns that is used to hide
the wldmabuf context from users as an option (unlike the other usual
contexts). We also want to make sure that hidden contexts wouldn't be
autoprobed in the usual ra_ctx_create, so we be sure to skip those in
that function. Additionally, let's create a new ra_ctx_create_by_name
function which does exactly what says. It specifically selects a context
based on a passed string. This function has no probing or option logic
is simplified just for what vo_dmabuf_wayland needs. The api/context
validations functions are modified just a little bit to make sure hidden
contexts are skipped and the documentation is updated to remove this
entries. Fixes #10793.
2022-10-28 02:36:46 +00:00
Dudemanguy 31af37f877 vo_dmabuf_wayland: load all hwdecs in preinit
vo_gpu and vo_gpu_next typically load hwdec interops on demand and
vo_dmabuf_wayland naively copied this logic. This is actually wrong
however since draw_frame in the VO always inherently relies on hwdec
being fully loaded. This can lead to a race condition during startup
which happens with --force-window=immediate. Avoid this by simply always
loading all the interops. In the case of vo_dmabuf_wayland, this is not
really a big deal since there's only vaapi and drmprime to load. Also
fixes #10791 (the other half).
2022-10-28 02:36:46 +00:00
Dudemanguy 99699cd7ba wayland: always do a display_roundtrip at the end of init
We really need two roundtrips in the init function. The first one is for
running the registry and then second one is for ensuring the xdg_surface
and other potential wayland objects are configured at least once before
mpv does anything. We've been getting away with only doing the first for
a while via luck, but really we should do at least one more wait on the
compositor. Fixes #10791 (half of it).
2022-10-28 02:36:46 +00:00
Dudemanguy 0f1ae8896e github/workflows: print error logs on freebsd
Despite being run in a VM, the workflow actually copies the files back
to the host. We can then explictly print the error logs on failure in
their own separate section for visibility instead of it being hidden
within all the vm output.
2022-10-27 18:42:12 +00:00
Dudemanguy c3c1978330 ci/build-freebsd.sh: remove nonexistent option
Mistakenly added in aeb4792cb6.
2022-10-27 18:42:12 +00:00
Dave Craig 6e274dc8d8 vo_dmabuf_wayland: fix DRM builds with no VAAPI
Building on DRM platform without VAAPI broke because of misuse of
HAVE_VAAPI with #ifdef in place of #if. Also, the hwcontext_drm.h
header is not required for VAAPI builds, only DRM builds.
2022-10-27 18:41:37 +00:00
Jan Ekström bc3e96098d video/out/wayland_common: adjust decoration disagreement log level
Originally, I considered warning once to be useful for figuring
out whether the change in logic regarding resetting requested
mode actually fixed the reported issue or not, but alas not everyone
was happy with that decision. Thus the log level will always be
debug. This enables us to lose one level of indent as well as a
variable, which is always positive.

Additionally, make the message more explicit regarding what could
possibly be implied by the mismatch, as it seems like this was
not always clear.
2022-10-27 19:07:05 +03:00
Jan Ekström e0c4193ee5 video/out/wayland_common: clear decoration request even if compositor disagrees
Otherwise mpv and the compositor can end up in an eternal loop where
mpv requests one mode, and compositor tells that the mode is not
that (and will most likely not change).

Additionally, log these mismatches - first time as a warning, and
later as debug logging.
2022-10-26 22:20:31 +03:00
Jan Ekström f39e56bf5e video/out/wayland_common: don't pass a negative of border flag into ternary
Make it clear that we are passing the original requested border mode
on.
2022-10-26 22:20:31 +03:00
Jan Ekström 2c58ab481b video/out/wayland_common: make decoration state usage explicit
It is verbose, but makes it more explicit that requested_decoration
takes in three values:

* 0: no specific mode requested by mpv
* ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE: (!border)
* ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE: (border)
2022-10-26 22:20:31 +03:00
Thomas Weißschuh c9af75e888 ao_pipewire: compatibility for libpipewire 0.3.19 2022-10-26 21:56:33 +03:00
Jan Ekström 8b81f45e1b ci: require pipewire to be enabled for Tumbleweed Linux builds 2022-10-26 21:56:33 +03:00
Emmanuel Gil Peyrot 666cb91cf1 wayland: bump dmabuf protocol to version 4
Pulled from https://github.com/mpv-player/mpv/pull/10382

The zwp_linux_dmabuf_v1 protocol version 4 provides a file descriptor
containing both formats and modifiers, which makes it possible for the
compositor to import the buffers onto planes using explicit modifiers.

This is an extremely important efficiency improvement, as the 3D
hardware can be left powered off altogether, the vaapi buffer being sent
directly from the video hardware to the display controller.

It could be possible to support zwp_linux_dmabuf_v1 version 3 as well,
but there is no reason beyond compatibility with old stacks.  I would
recommend to ditch version 2 as well, as modifier-less formats aren’t
very useful nowadays.
2022-10-26 18:41:47 +00:00
Aaron Boxer aeb4792cb6 vo_vaapi_wayland: remove, as it is superceded by vo_dmabuf_wayland 2022-10-26 18:41:47 +00:00
Aaron Boxer 7358b9d371 vo_dmabuf_wayland: wayland VO displaying dmabuf buffers
Wayland VO that can display images from either vaapi or drm hwdec

The PR adds the following changes:

1. a context_wldmabuf context with no gl dependencies
2. no-op ra_wldmabuf and dmabuf_interop_wldmabuf objects
   no-op because there is no need to map/unmap the drmprime buffer,
    and there is no need to manage any textures.

Tested on both x86_64 and rk3399 AArch64
2022-10-26 18:41:47 +00:00
Aaron Boxer 964692ad4c wayland: clean wp_presentation_feedback in discard callback to avoid leak 2022-10-26 18:41:47 +00:00
Aaron Boxer 8314c907ab build_image_converter - use full image format list to create hw_upload
currently we only try for the first format in the list
2022-10-26 18:41:47 +00:00
Aaron Boxer fbcd9c140f mp_imgfmt: move DRMPRIME format to end of enum
dmabuf-wayland vo supports both DRMPRIME and VAAPI formats.
If upload filter is needed, we want to try VAAPI hwdec first
since most users will be using VAAPI, and there is a several second
delay when DRMPRIME hwdec is tried and fails.
2022-10-26 18:41:47 +00:00
Leo Izen 050f5e7915 DOCS: document E to cycle through Editions
Pushing E (aka Shift+e) cycles through Editions for containers
that support editions, such as Matroska, although this feature was not
documented before this commit.
2022-10-24 15:23:41 -04:00
Thomas Weißschuh c3be7e2585 ao: promote ao_pipewire
The AO is feature-complete now.
As PipeWire also provides compatibility with PulseAudio, ALSA and Jack
we should put it before those for the autodetection to work.
2022-10-24 11:09:34 -07:00
Thomas Weißschuh b9a9e0a6f1 ao_pipewire: test for session to contain audio sinks
The pure presence of PipeWire does not mean that it is actually driving
the audio session. For example it could only be meant for video.

Currently there is no proper API to detect this (see [0]), so we check
for the presence of audio sinks.

As soon as a proper API exists, we should use that.

[0] https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1835
2022-10-24 11:09:34 -07:00
Thomas Weißschuh e4505ce744 ao_pipewire: init_boilerplate(): simplify errorhandling 2022-10-24 11:09:34 -07:00
dyphire 4bc6686b6a TOOLS/lua/autoload: fix incorrect duplicate file loading behavior
This will correctly avoid the duplicate file loading when the playlist
changes due to shuffle playback or append new files.

Fixes https://github.com/mpv-player/mpv/issues/8575
2022-10-24 01:34:39 -04:00
Cœur 67260f8aac audio/format: fix Type 'struct entry' has incompatible definitions in different translation units
`struct entry` already exists from <search.h>, so the one we declare in audio/format.c needs to be named differently
2022-10-23 14:57:24 +02:00
Philip Langdale 395b37b005 vo_gpu/hwdec: add NULL check for legacy_name 2022-10-22 12:56:18 -07:00
sfan5 42cfed002f hwdec_aimagereader: fix incorrect return values 2022-10-22 15:34:37 +02:00
Nicolas F 375076578f demux_mkv: add AVS2 and AVS3 to tag list
Add support for playing back AVS2 and AVS3 video streams inside
mkv containers if ffmpeg was compiled with avs2/avs3 support.

Fixes: #10695
2022-10-21 18:12:08 +03:00
Dudemanguy 48ad2278c7 wscript: remove some bogus configure options
It turns out that wayland-scanner and wayland-protocols are both exposed
as configure options in waf meaning you can --enable/--disable them at
configure time. This is pretty nonsensical. If you want to control
wayland in the build, you should just use --enable-/--disable-wayland.
wayland-scanner and wayland-protocols should just be typical checks like
in the meson build.
2022-10-17 14:57:42 +00:00
Paul B Mahol cdcbd7372d demux_mf: add support for QOI, PHM and HDR images 2022-10-15 21:31:43 +03:00
Philip Langdale 2852691587 f_hwtransfer: allow hw uploads to implicitly convert formats
vaapi allows for implicit conversion on upload, which has some
relevance as the set of supported source formats is larger than the
set of displayable formats. In theory, this allows for offloading the
conversion to the GPU - if you have any confidence in the hardware
and/or driver's ability to do the conversion.

Today, we actually track the 'input' and 'output' upload formats
separately all the way up until the point we do a check as to whether
the original source format is an accepted 'output' format and then
reject it if it is not.

This means that we're essentially ignoring all the work we did to track
those 'input' formats in the first place. But it also means that it's a
simple change to compare against the 'input' format instead. The logic
is already in place to do best format selection on both sides.

I imagine that if I read through the history here, wm4 tried to
implement all of this properly and then gave up in disgust after seeing
vaapi mangle various conversions.

This is particularly interesting for vo-dmabuf-wayland where it is only
possible to display the subset of valid vaapi formats that are
supported by the compositor, yet all playback has to go through vaapi.
Users will then be able to take advantage of all possible vaapi formats
to avoid having to do software format conversion.
2022-10-15 09:57:09 -07:00
Philip Langdale 1bca62e58b f_hwtransfer: accept non-power-of-2 hw uploads
This works fine for me on vaapi, cuda and vulkan. Why did we have this
restriction in there? Worst case, the hwdec_interop will reject it.
2022-10-15 09:57:09 -07:00
Philip Langdale 345342f50a hwdec/dmabuf_interop_gl: work-around implicit rgba swizzling
This has been a long standing problem that I think was the root cause
for wm4's vaapi shitlist. As DRM explicit supports all possible rgba
orderings, but OpenGL only guarantees support for 'rgba8', something
has to happen to support import of dmabufs with non-native ordering.

Although undocumented, it appears that somewhere in the import on the
GL side, the ordering is swizzled to rgba - which makes sense as that's
the only way to be able to support importing all the different formats.

But we didn't know this, and we do our own swizzling based on the
original imgfmt - which matches the drm format. So we get double
swizzling and messed up colours.

As there is no way for us to express that the GL swizzle happened to
the rest of mpv, the easiest thing to do is fudge the format to the
natural ordering so the GL doesn't change anything, then our swizzling
will do the right thing in the end.

Note that this change doesn't handle 0rgb and 0bgr because they seem to
be affected by some additional feature/bug that is mangling the
ordering somewhere that equally affects Vulkan interop. That could be a
vaapi driver bug or something going on in ffmpeg.
2022-10-15 09:30:46 -07:00
Philip Langdale 6f7506b660 f_hwtransfer: get rid of the shit list
A few years ago, wm4 got sufficiently annoyed with how vaapi image
format support was being discovered that he flipped the table and
introduced the shit list (which just included vaapi) to hard-code the
set of supported formats.

While that might have been necessary at the time, I haven't been able
to find a situation where the true list of supported formats was unsafe
to use. We filter down the list based on what the vo reports - and the
vo is already doing a thorough testing of formats, and if a format
makes it through that gauntlet, it does actually work.

Interestingly, as far as I can tell, the hwdec_vaapi probing code was
already good enough at the time (also written by wm4), so perhaps the
key difference here is that the driver side of things has improved.

I dug into this because of the support for the 422/444 high bit depth
vaapi formats I added to ffmpeg. These are obviously not in the hard
coded list today, but they work fine.

Finally, although it's positioned as a vaapi thing, it's really just
Intel specific, as the AMD vaapi driver has never exposed support for
anything except the formats used by the decoder/encoder profiles.
2022-10-15 09:30:46 -07:00
Philip Langdale 66e30e7f2f hwdec/vaapi: improve probing of supported sw formats
The logic around trying to establish what formats are supported by
vaapi is confusing, and it turns out that we've been doing it wrong.

Up until now, we've been going through the list of decoding profile
endpoints and checking the formats declared in those profiles to build
our list.

However, the set of formats that the vaapi driver can actually support
is potentially a superset of those supported by any given profile
endpoint. This master list is exposed by libavutil via the
av_hwframe_transfer_get_formats() function, and so we should use that
list as our starting point.

Perhaps surprisingly, this change actually removes no code, because we
still want the logic that enumerates endpoints and finds supported
formats for endpoints. We need this because we must have at least one
known sw format to initialise the hwframe_ctx with.

Additionally, while in the general case,
av_hwframe_transfer_get_formats can return different formats depending
on what format you initialise the hwframe_ctx with, I happen to have
read the libavutil code, and it doesn't care, so we just need to call
it once, we know we'll get back all known formats.

In practice, with an Intel vaapi driver, this will result in us
supporting a handful of extra formats for hwuploads - particularly
yuv420p (so no need to convert to nv12 first) and various orderings
of rgb(a).
2022-10-15 09:30:46 -07:00
rcombs dfb5b0c55f vo_gpu_next: fix crash on uninit after startup failure 2022-10-14 15:37:49 +02:00
VincentVerdynanta 59fc8eecbc sd_ass: improve handling of subtitles with unknown duration
Commit 740b701 introduced handling for subtitles with unknown duration,
but it came with a minor flaw where a track event that shares identical
start time with following track event will has its Duration value set
to 0, we don't want this to happen since it will prevent simultaneous
rendering of multiple track events.
This commit aims to address this issue.
2022-10-12 19:57:44 -04:00
Leo Izen b3d77397eb DOCS: fix minor typo with keep-open description
Fix a minor typo in the description of --keep-open
in DOCS/man/options.rst
2022-10-12 10:19:09 -04:00
Shreesh Adiga e97819f88e draw_bmp: fix out of bounds access in mark_rect
When the width is exactly a multiple of SLICE_W (currently 256),
heap buffer overflow is reported by Address Sanitizer. So adjust
the maximum index for the line array accordingly.
2022-10-11 17:11:07 +00:00
Philip Langdale 064059e6c3 vo_gpu/hwdec: rename and introduce legacy names for some interops
We've had some annoying names for interops, which we can't simply
rename because that would break config files and command lines. So we
need to put a little more effort in and add a concept of legacy names
that allow us to continue loading them, but with a warning.

The two I'm renaming here are:
* vaapi-egl -> vaapi (vaapi works with Vulkan too)
* drmprime-drm -> drmprime-overlay (actually describes what it does)
* cuda-nvdec -> cuda (cuda interop is not nvdec specific)
2022-10-11 10:07:48 -07:00
odnar-dev d050e350fe x11: fix --on-all-workspaces option
mpv set _NET_WM_DESKTOP to 0xFFFFFFFF, which behaves differently with each window manager.
Instead, set the window property to STICKY, and let the window managers deal with it.
2022-10-11 09:25:26 +02:00
Niklas Haas c96cee2940 vo_gpu_next: vulkan: libplacebo: unify log prefix
The new status quo is simple: all messages coming from libplacebo are
marked "vo/gpu{-next}/libplacebo", regardless of the backend API (vulkan
vs opengl/d3d11).

Messages coming from mpv's internal vulkan code will continue to come
from "vo/gpu{-next}/vulkan", and messages coming from the vo module
itself will be marked "vo/gpu{-next}".

This is significantly better than the old status quo of vulkan messages
coming from "vo/gpu{-next}/vulkan/libplacebo" whereas opengl/d3d11
messages simply came from "vo/gpu{-next}", even when those messages
originated from libplacebo.

(It's worth noting that the the destructor for the log is redundant
because it's attached to the ctx which is freed on uninit anyway)
2022-10-09 21:47:35 +02:00
Jan Ekström 3f32dfe981 github/workflows: explicitly install Xinerama on FreeBSD
Apparently an implicit dependency on it through one of the
otherwise installed packages is no longer there.
2022-10-09 17:09:06 +03:00
Dudemanguy bb56554a62 x11: fix a couple of memory leaks
Managed to go completely unnoticed for months (who was the bad person
that introduced these*). Fairly self-explanatory. After getting
ProviderInfo from randr, we need to free it. The other one is pretty bad
because it leaked every frame (ouch). It turns out that you're supposed
to free any event data after you cast a generic event to an
XGenericEventCookie. Free that as well.

*: It was me.
2022-10-08 23:50:55 -05:00
Thomas Weißschuh 161bdd9359 ao_pipewire: allow specification of remote name 2022-10-06 13:16:35 -07:00
Thomas Weißschuh a1e29f1555 ao_pipewire: small cleanups and restructring
* Remove unneeded braces.
* Don't use non-standard %m in printf.
* Organize struct priv a bit.
2022-10-06 13:16:35 -07:00
Christoph Heinrich cc65b3892d osc: scale rendered aspect ratio with window aspect ratio
The logo stays centered better and it doesn't distort anymore due to a
recent change in libass https://github.com/libass/libass/pull/645
2022-10-06 14:34:56 -04:00
Dudemanguy d2a0791fe8 wayland: correctly handle non-CLOCK_MONOTONIC clocks
The wayland presentation time code currently always assumes that only
CLOCK_MONOTONIC can be used. There is a naive attempt to ignore clocks
other than CLOCK_MONOTONIC, but the logic is actually totally wrong and
the timestamps would be used anyway. Fix this by checking a use_present
bool (similar to use_present in xorg) which is set to true if we receive
a valid clock in the clockid event. Additionally, allow
CLOCK_MONOTONIC_RAW as a valid clockid. In practice, it should be the
same as CLOCK_MONOTONIC for us (ntp/adjustime difference wouldn't
matter). Since this is a linux-specific clock, add a define for it if it
is not found.
2022-10-06 18:08:51 +00:00
Niklas Haas 7f5541fc3c vulkan: remove --vulkan-disable-events
This has had no effect since libplacebo v4.192.0, and was deprecated
upstream a year ago. No deprecation period in mpv is justified by this
being a debug / work-around option.
2022-10-05 16:35:14 +02:00
sfan5 a2de6524ff vo: hwdec_aimagereader: add missing image format specifier
This is required since e50db42927, but was missed during the merge.
2022-10-03 20:34:25 +02:00
sfan5 5463d3eeff vo_gpu: hwdec: add Android hwdec utilizing AImageReader 2022-10-02 14:12:26 +02:00
Leo Izen 2207236aaa DOCS: deprecate --gamma-factor and --gamma-auto
Removed the outdated information about environmental brightness
with respect to --gamma-factor, and mention that the option is
deprecated and subject to future removal. Also deprecated the
--gamma-auto option as it relies on the same outdated way of doing
things.
2022-10-01 10:01:09 -04:00
Niklas Haas 98e6fb26a3 vo_gpu_next: respect --blend-subtitles=<yes/no>
This brings vo_gpu_next's behavior more in line with vo_gpu. Currently,
the status quo was that `vo_gpu_next` generated subtitles with the full
resolution of the dst crop, even though practical limitations of
libplacebo meant that such subtitles inevitably got cut off at the video
boundaries. This was actually a worse status quo than `vo_gpu`, which
simply constrained subtitles to the video dimensions to prevent these
issues.

With this change, the behavior is the same as `vo_gpu`, which has the
exact same problem w.r.t interpolation. Users are back to choosing
between --blend-subtitles=yes and not having subtitles in margins,
and using --blend-subtitles=no and not having subtitle interpolation.

There are different pros and cons to each approach, and I still
ultimately plan on allowing libplacebo to interpolate subtitles even in
the black bars, to solve this issue once and for all. But for now, let's
not let perfect be the enemy of good.

No attempt is made to implement `--blend-subs=video`, which I consider
deprecated.

Fixes: https://github.com/mpv-player/mpv/issues/10272
2022-09-29 22:02:00 +02:00
Thomas Weißschuh b2aaf7250f ao_pipewire: don't try to lock nonexistent loop 2022-09-28 15:53:33 -07:00
Thomas Weißschuh 5e49c09f2e ao_pipewire: use target.object
Specifying the id of the target node during stream connect is
deprecated.  Instead the property target.object should be used to link
by target serial or name.  Using the name allows us to drop a bunch of
custom code.
2022-09-28 15:53:05 -07:00
Niklas Haas eba4ce5c2d mp_image: strip DoVi metadata that requires an EL
We can't support this. Better strip it than partially apply.

Fixes: #9831
2022-09-28 02:28:37 +02:00
Niklas Haas 00813c7629 manpage: document bt.2390 parameter
Closes #9788
2022-09-28 01:55:39 +02:00
Niklas Haas 3376f775e3 vo_gpu_next: fix screenshots of rotated sources
I actually don't quite understand why this is needed, since in theory we
should already be doing the rotation as part of applying the crop. But I
guess that code doesn't quite work. This is the only way it works, so
it's probably correct. (And note that `vo_gpu` does the same internally)
2022-09-27 21:32:46 +02:00
hooke007 1c05a30e95 DOCS/man/vf.rst : replace the outdated syntax
`get_core()` had been deprecated for several years and totally
removed since vapoursynth R55 API4.
2022-09-27 08:24:54 -04:00
Niklas Haas 1c8fdf6992 vo_gpu_next: use static assert for array size
This is used in other places in the code, so it should be fine.
2022-09-27 01:35:53 +02:00
Niklas Haas 6b9b032d51 vo_gpu_next: update render_info for upstream API change
This fixes an issue where blend stages with multiple passes got
overwritten by later passes, with only the final pass (typically the
overlayp pass) actually being shown.
2022-09-26 21:14:34 +02:00
Niklas Haas 2b0736ed83 vo_gpu_next: implement --video-output-levels
This was ignored as an oversight.
2022-09-25 20:31:22 +02:00
Leo Izen 56e24d535e TOOLS/lua/autoload: add various extra file extensions
Add to autoload.lua several extra file extensions that are
unambiguously for media files.
2022-09-23 15:50:57 -04:00
Leo Izen a6d544d6a6 TOOLS/lua/autoload: alphebatize auto-loaded file extensions
Alphabetizing the extensions cleans up the code and makes it less
ambiguous where newer extensions should be added. The video line
also was wrapped to 72 characters for cleanliness.
2022-09-23 15:50:57 -04:00
Christoph Heinrich ac7f3913d3 ytdl_hook: use subtitle name as title if available
So far the `ext` was always used as the title,
but `name` is more appropriate when it's available.
2022-09-23 19:18:49 +00:00
Peter DeLong f46bbde5e6 af_scaletempo2: fix crash when the number of channels increases
When af_scaletempo2.c:process() detects a format change, it goes back
through mp_scaletempo2_init() to reinitialize everything.  However,
mp_scaletempo2.input_buffer is not necessarily reallocated due to a
check in af_scaletempo2_internals.c:resize_input_buffer().  This is a
problem if the number of audio channels increases, since without
reallocating, the buffer for the new channel(s) will at best point to
NULL, and at worst uninitialized memory.

Since resize_input_buffer() is only called from two places, pull size
check out into mp_scaletempo2_fill_input_buffer().  This allows each
caller to decide whether they want to resize or not.  We could be
smarter about when to reallocate, but that would add a lot of machinery
for a case I don't expect to be hit often in practice.
2022-09-23 18:15:00 +02:00
sfan5 e6c5d58d1e build: update waf to 2.0.24 2022-09-21 22:51:25 +02:00
Philip Langdale f221666ade f_hwtransfer: mp_image_pool: support HW -> HW mapping
Certain combinations of hardware formats require the use of hwmap to
transfer frames between the formats, rather than hwupload, which will
fail if attempted.

To keep the usage of vf_format for HW -> HW transfers as intuitive as
possible, we should detect these cases and do the map operation instead
of uploading.

For now, the relevant cases are moving between VAAPI and Vulkan, and
VAAPI and DRM Prime, in both directions. I have introduced the IMGFMT
entry for Vulkan here so that I can put in the complete mapping table.
It's actually not useless, as you can map to Vulkan, use a Vulkan
filter and then map back to VAAPI for display output.
2022-09-21 09:39:34 -07:00
Philip Langdale 7b84e6fa89 f_autoconvert: f_hwtransfer: support HW -> HW uploads
Historically, HW -> HW uploads did not exist, so the current code
assumes they will never happen. But as part of introducing Vulkan
support into ffmpeg, we added HW -> HW support to enable transfers
between Vulkan and CUDA.

Today, that means you can use the lavfi hwupload filter with the
correct configuration (and previous changes in this series) but it
would be more convenient to enable HW -> HW in the format filter so
that the transfers can be done more intuitively:

```
--vf=format=fmt=cuda
```

and

```
--vf=format=fmt=vulkan
```

Most of the work here is skipping logic that is specific to SW -> HW
uploads doing format conversion. There is no ability to do inline
conversion when moving between HW formats, so the format must be
mutually understood to begin with.

Additional work needs to be done to enable transfers between VAAPI
and Vulkan which uses mapping, rather than uploads. I'll tackle that
in the next change.
2022-09-21 09:39:34 -07:00
Philip Langdale 989d873d6e filters: lavfi: allow hwdec_interop selection for filters
Today, lavfi filters are provided a hw_device from the first
hwdec_interop that was loaded, regardless of whether it's the right one
or not. In most situations where a hardware based filter is used, we
need more control over the device.

In this change, a `hwdec_interop` option is added to the lavfi wrapper
filter configuration and this is used to pick the correct hw_device to
inject into the filter or graph (in the case of a graph, all filters
get the same device).

Note that this requires the use of the explicit lavfi syntax to allow
for the extra configuration.

eg:

```
mpv --vf=hwupload
```

becomes

```
mpv --vf=lavfi=[hwupload]:hwdec_interop=cuda-nvdec
```

or

```
mpv --vf=lavfi-bridge=[hwupload]:hwdec_interop=cuda-nvdec
```
2022-09-21 09:39:34 -07:00
Philip Langdale 5629ed81ee filters: support loading new hwdec_interops from filters
If we want to be able to handle conversion between hw formats in filter
chains, then we need to be able to load hwdec_interops from filters, as
the VO is only ever going to initialise one interop, based on its
configuration. That means that in almost all situations, only one of
the required interops will be loaded at the time the filter is
initialised.

The existing code has some assumptions that new hwdec_interops will not
be loaded after the vo has picked one to use. This change fixes two
instances:

* Refusing to load a new hwdec_interop if there is at least one
  loaded already.
* Not recalculating the set of formats known to the autoconvert
  filter when a new output format shows up. This leads to autoconvert
  not knowing that a new format is supported when the hwdec interop is
  lazily loaded.
2022-09-21 09:39:34 -07:00
Philip Langdale e50db42927 vo: hwdec: do hwdec interop lookup by image format
It turns out that it's generally more useful to look up hwdecs by image
format, rather than device type. In the situations where we need to
find one, we generally know the image format we're dealing with. Doing
this avoids us having to create mappings from image format to device
type.

The most significant part of this change is filling in the image format
for the various hw interops. There is a hw_imgfmt field today today, but
only a couple of the interops fill it in, and that seems to be because
we've never actually used this piece of metadata before. Well, now we
have a good use for it.
2022-09-21 09:39:34 -07:00
Guido Cella 7f2bc43a68 demux_lavf: extract is_image function 2022-09-20 19:35:25 +02:00
Guido Cella 565e7d906c demux_lavf: detect avif images
Detect avif files with 1 frame as images. This works because AV1 videos
and AVIF animations have nb_frames 0 or > 1.
2022-09-20 19:35:25 +02:00
Leo Izen 4856a7bd59 DOCS/man/options.rst: replace some legacy single-hyphen syntax
Replace some occurrences of ``-option`` with ``--option`` to
coincide with the current option sytnax.
2022-09-20 10:08:28 -04:00
Niklas Haas 1fb5f06c66 vo_gpu_next: support error diffusion dithering
One step closer to vo_gpu_next feature parity with vo_gpu!
2022-09-20 14:59:00 +02:00
Oneric 9e3ec04d56 sub: use Unicode linebreaking for non-ASS subs and OSD
ASS must only automatically break at ASCII spaces (\x20), but other
subtitle formats might expect more breaking oppurtinities.
Especially non-ASS subs in scripts, which typically do not use (ASCII)
spaces to seperate words, like e.g. CJK, might overflow the screen
if the conversion didn't insert additional linebreaks (ffmpeg does not).

Thus try to enable Unicode linebreaking for converted subs and the OSD
if libass is new enough. The feature may still be unavailable at runtime
if libass wasn't build with Unicode linebreaking support.
2022-09-19 15:56:38 +02:00
rcombs ba81e4ed88 ao_audiounit: get the channel layout from the AU itself
Fixes 5.1/7.1 output mapping on tvOS 16,
and also makes the AC3-layout hack unnecessary.

Also adds some diagnostic log messages.
2022-09-15 11:52:50 -05:00
rcombs 588cb9a977 mac: avoid unnecessary unsafe conversions; fixes crash in debug builds
Previously, running a debug build of mpv would crash with this output
when preinit() at vo_libmpv.c:732 calls control(vo, VOCTRL_PREINIT, NULL):

Swift/Optional.swift:247: Fatal error: unsafelyUnwrapped of nil optional

This comes from this line of code:

var data = UnsafeMutableRawPointer.init(bitPattern: 0).unsafelyUnwrapped

Unsafely unwrapping a UnsafeMutableRawPointer.init has always been UB,
but the Swift runtime began asserting on it in debug builds a couple macOS
versions ago.
2022-09-14 16:28:12 -05:00
DeadNews 750b58a5a3 TOOLS/lua/autoload: add m2ts extension
* `.m2ts` used for the Blu-ray disc container file format
2022-09-14 14:49:00 -04:00
Christoph Heinrich e302c9b7dd ytdl_hook: simplify exclude option parsing
The parsing used to be unnecessarily complicated,
now it's easier to read and understand.
2022-09-14 13:29:11 +02:00
Niklas Haas b9c7e5b5ff vo_gpu_next: only require full pixel byte alignment
The current code also rejects e.g. rgb30, even though this format is
perfectly valid, because it only checks for alignment of the used bits.
2022-09-12 16:01:07 +02:00
Niklas Haas 30ca46259e vo_gpu_next: implement ICC 3DLUT caching
Relies on a new upstream API for adding save/load callbacks to the ICC
3DLUT generation parameters.

Closes: https://github.com/mpv-player/mpv/issues/10252
2022-09-12 15:35:17 +02:00
Niklas Haas 7a6dc79e29 vo_gpu_next: use correct pixel size when mapping formats
`total_bits` may be less than the true pixel stride (`bpp`) for formats
which contain extra ignored components (e.g. rgb0).
2022-09-12 15:25:56 +02:00
Thomas Weißschuh 38a7562ebe ao_pipewire: listen to hotplug events 2022-09-11 20:24:42 -07:00
Thomas Weißschuh f36eeaf4e8 ao_pipewire: use proper hotplug init APIs 2022-09-11 20:24:42 -07:00
Thomas Weißschuh aa7223cd8c ao_pipewire: create is_sink_node helper 2022-09-11 20:24:42 -07:00
Thomas Weißschuh 235a66bfc8 audio: list devices for all AOs with hotplug_init
Previously we would only call list_devs() on available AOs if an AO
*did not* have a hotplug_init() callback or for the first one that *did*
have it.

This is problematic when multiple fully functional hotplug-capable AOs
are available.

The second one would not be able to contribute discovered devices.

This problem prevents ao_pipewire from introducing full hotplug support
with hotplug_init().
2022-09-11 20:24:42 -07:00
Thomas Weißschuh 013ec877f6 audio: try to use playback AO as hotplug AO first
When a platform has multiple valid AOs that can provide hotplug events
we should try to use the one that also provides playback.

Concretely this will help when introducing hotplug support for
ao_pipewire.

Currently ao_pulse is probed by ao_hotplug_get_device_list() before
ao_pipewire and on the common setups where both AOs could work pulse
will be selected for hotplug handling.
This means that hotplug_init() of ao_pipewire will never be called and
list_devs() has to do its own initialization.
But if ao_pulse is non-functional or not compiled-in suddenly
ao_pipewire *must* implement hotplug_init() for hotplugging events to
work for all.

Also if the hotplug ao_pulse connects to a PulseAudio instance that is
not emulated by the same PipeWire instance as the playback ao_pipewire
the hotplug events are useless.
2022-09-11 20:24:42 -07:00
Thomas Weißschuh a9155c6f97 ta: increase size of names printed
30 characters are not a lot.
Also when the name is calculated from the allocation site the line
number will be the at the end of the name, so truncating it is
especially inconvenient.
2022-09-11 20:24:42 -07:00
Thomas Weißschuh 535cd6f313 ao_pipewire: handle AOCONTROL_UPDATE_MEDIA_ROLE 2022-09-10 12:32:52 -07:00
Thomas Weißschuh 3167a77aa3 audio: add AOCONTROL_UPDATE_MEDIA_ROLE
This is used to notify an AO about the type of media that is being
played.
Either a movie or music.
2022-09-10 12:32:52 -07:00
Thomas Weißschuh 221bf540a1 ao_pipewire: fix indent 2022-09-10 12:32:52 -07:00
Philip Langdale 98f02e33ef repack: add repacker for ccc16x16 formats
I'm adding support in ffmpeg for the XV36 format which will be used
by VAAPI for 12bit 4:4:4 content. It's an undefined-alpha channel
variant of Y412 which is itself a 12bit+4bits padding variant of Y416.

We currently have a repacker for full four channel cccc16, and for
three channel ccc16, but nothing for ccc16x16 with the undefined alpha
channel.

It's simple enough to add one using the existing macros.
2022-09-10 12:31:44 -07:00
Vitaly Zaitsev ca9b00145c mpv.metainfo.xml: add XDG appstream metadata manifest 2022-09-09 19:28:26 +02:00
Cairn a7098a4336 DOCS: Mention "mono" audio channels option 2022-09-09 13:00:58 -04:00
25792431 d433c5d655 DOCS/libmpv: fix typo in linkage section 2022-09-03 12:54:48 -04:00
Thomas Weißschuh 7a7042a4d1 w32: fix typo in F23 mapping 2022-09-03 08:46:42 -04:00
Tillmann Karras 1800891a1d vo_gpu_next: fix typo affecting --target-trc option 2022-09-02 22:03:33 -04:00
Thomas Weißschuh c4db110c8e macos: add support for F13-F20 keys 2022-09-02 14:05:46 +02:00
Thomas Weißschuh c5e5fba632 w32: add support for F13-F24 keys
Fixes #10595
2022-09-02 14:05:46 +02:00
Thomas Weißschuh 103efdd614 x11: add support for F13-F24 keys 2022-09-02 14:05:46 +02:00
Thomas Weißschuh 03e8ed450d wayland: add support for F13-F24 keys 2022-09-02 14:05:46 +02:00
Thomas Weißschuh 5d3680c314 input: add function keys F13-F24 2022-09-02 14:05:46 +02:00
Niklas Haas 9be52e5dd8 ad_lavc: strip non-normalized floats
`opus` codec likes returning denormalized floats in some cases, causing
wacky issues.

Fixes #10290
2022-09-02 01:27:31 +02:00
Niklas Haas 04062b6f89 vo_gpu_next: display subtitles without video stream
Fixes https://github.com/mpv-player/mpv/issues/10594
2022-08-31 13:33:05 +02:00
sfan5 0421e81965 DOCS/options: update vd-lavc-skiploopfilter, skipidct and related descriptions
Cross-checked the current functionality of these with the FFmpeg source.
2022-08-31 11:29:39 +02:00
Avi Halachmi (:avih) 0f30b0757f DOCS/mpv: remove spaces at EOL, ensure 80 cols
These are fixes for the previous commit.
2022-08-29 16:33:38 +03:00
enly1 92c03a191b DOCS/mpv: added COMMAND INTERFACE refs to INTERACTIVE CONTROL
Added COMMAND INTERFACE references to make it easier for new users.
2022-08-29 16:26:15 +03:00
Thomas Weißschuh 211ce69f74 ao_pipewire: for_each_sink(): report errors 2022-08-28 10:46:54 -07:00
Owen Rafferty 1a32bd37e0 meson: fix condition for enabling vaapi-egl 2022-08-27 10:53:05 -07:00
Niklas Haas 89cab5c32f meson: fix libplacebo check
Missing waf quivalent, and doesn't necessarily output a good error
message. But I might as well submit this rather than sitting on it
unnecessarily.
2022-08-26 02:24:20 +02:00
Philip Langdale ed7717298b audio: fix lack of reinitialization on format change with pull AOs
uau did some investigation and noticed that we do not send a wakeup
event when we encounter end-of-stream in ao_read_data(), in contrast to
the equivalent logic for push AOs in ao_play_data().

Inserting that wakeup fixes the original problem of lack of
reinitialization on a format change without the problems we saw with
the previous attempted fix.

Fixes #10566
2022-08-23 11:01:52 -07:00
Philip Langdale e2e8c21be4 player/audio: remove explicit drain on EOF
We have previously had a problem where pull AOs (such as pipewire)
would not reinitialize on a format change when going between two
audio-only files. In such a situation, playback would stop after the
first file.

We initially attempted to fix this by explicitly draining on EOF, which
solves that problem but introduces a blocking step where we don't
actually want one, breaking gapless audio, and causing dropped frames
at the end of playback for files with video in them too.

So, let's undo these changes and do something better in the next
commit.
2022-08-23 11:01:52 -07:00
Thomas Weißschuh 6c1f01d284 ao_pipewire: make sure not to exceed the available buffer
The error description in #10545 could indicate that we are overflowing
we are corrupting the buffer metadata ourselves through out-of-bound
writes.
This check is also present in pw-cat so it seems to be expected for
b->requested to exceed the actual available buffer space.

Potential fix for #10545
2022-08-21 18:38:53 +02:00
Thomas Weißschuh bf5c19e05b audio: don't try to drain non-existent AO
52aed495cb ("audio: drain ao on EOF") introduced logic to drain an AO
when EOF of the input has been reached.
When no AO however is present this leads to a NULL-dereference.

Fixes #10556
2022-08-21 08:05:13 -07:00
Niklas Haas 37aea112c1 vo_gpu_next: pass GL get_proc_addr pointer to libplacebo
Facing down the multitude of ways to somehow wrangle the get_fn pointer
out of the GL environment and into libplacebo, I decided the easiest is
to just store it inside the GL struct itself.

The lifetime of this get_fn function is a bit murky, since it's not
clear on whether or not it survives the VO init call (especially in the
case of the GL render API, which explicitly states that parameters do
not need to survive the call they're passed to), so just add a
disclaimer.

(It's fine for us to use like this because `gpu_ctx_create` is still
part of VO init)

Closes https://code.videolan.org/videolan/libplacebo/-/issues/216
2022-08-19 13:54:50 +02:00
Thomas Weißschuh 891c9c869f ao_pipewire: test on FreeBSD 2022-08-18 09:16:52 -07:00
The-head-obamid d5b0f5648d mpv.desktop: add RIST protocol to desktop entry 2022-08-18 11:33:50 +02:00
The-head-obamid 4c431c8ad6 osxbundle: add RIST protocol support to app metadata 2022-08-18 11:33:50 +02:00
The-head-obamid f344d481a5 stream_lavf: enable RIST protocol support via ffmpeg 2022-08-18 11:33:50 +02:00
Thomas Weißschuh e735f7f61a ao_pipewire: restructure logic a bit 2022-08-17 15:48:12 -07:00
Thomas Weißschuh dbfee1be3d ao_pipewire: only try to read requested data 2022-08-17 15:48:12 -07:00
Thomas Weißschuh 0638a91ff4 ao_pipewire: report all available info about chunk
This allows the audio server better to make sense of the data instead of
having to use heuristics.
2022-08-17 15:48:12 -07:00
Christoph Heinrich 08dd30fde8 ytdl_hook: improve track detection
Every format that was not detected as a video format was added to the
audio tracks. This resulted in e.g. YouTube storyboards from ending up
in the list of audio tracks.

Now formats that are already known to be neither video formats nor audio
formats, will also not end up in any track list.

Formats where it is unknown if they are video or audio get added to
tracks if `force_all_formats` is used, otherwise only
formats that are known to contain video or audio become video or audio
tracks respectively.

https://github.com/yt-dlp/yt-dlp/issues/4373#issuecomment-1186637357
2022-08-17 20:04:00 +00:00
Leo Izen 52e7269ea6 misc/random: add xoshiro random number implementation
Add xoshiro as a PRNG implementation instead of relying
on srand() and rand() from the C standard library. This,
in particular, lets us avoid platform-defined behavior with
respect to threading.
2022-08-17 10:21:55 -04:00
Dudemanguy 813164cc07 meson: fix the build-date option
Rewrites are hard.
2022-08-16 11:41:52 -05:00
Dudemanguy 8e9c5b7b66 meson: fix building without gl
This needs to be unconditionally added.
2022-08-15 11:30:11 -05:00
Dudemanguy 1835dfc05c meson: consistently use feature['foo']
Since the previous commit introduced the notion of a features dictionary
that conveniently tells us whether or not to use a feature in a simple
yes/no, we can make use of this everywhere in the build. Instead of
doing something like 'if foo.()', change it to 'if feature['foo']
instead. This enforces a consistent standard instead of having a lot of
different possible combinations of booleans that may or may not do
something.
2022-08-15 14:14:44 +00:00
Dudemanguy f295d39f5c meson: refactor generating config.h
mpv has a ton of defines that are generated during building. Previously,
the meson build just had this as a big giant wall of text that manually
set each one but we can do this smarter. Instead, change the "features"
object to a dictionary and have it hold the name of the feature and its
value (true/false on whether it is enabled). Then at the end, just loop
through it and reformat the name of the feature so it becomes
HAVE_FEATURE. A side effect of this is that a lot of extra defines are
generated that aren't actually used in the code, but the waf build
worked like this for years anyway. A nice result of this is that the use
of foo['use'] internally can be completely eliminated and replaced with
feature['foo'] instead when needed.
2022-08-15 14:14:44 +00:00
Dudemanguy 7c4f03e82a meson: disable dvdnav by default
It turns out that this is disabled in waf. Go ahead and copy this in
meson for consistency.
2022-08-15 14:14:44 +00:00
Dudemanguy 686027f9b2 meson: reduce dictionary usage
The build was a bit overzealous with using dictionaries. These are fine
for when the feature checking is more complicated, but there's no point
in having them for the simplier things. This also eliminates the usage
of the 'name' key completely.
2022-08-15 14:14:44 +00:00
Dudemanguy 484f1d7adc meson: add comment clarifying windows-internal-pthreads 2022-08-15 14:14:44 +00:00
Christoph Heinrich 1ef53f094b ytdl_hook: consistant behavior for single format
One would expect that e.g.
`--script-opts=ytdl_hook-all_formats=no --ytdl-format=bestaudio` and
`--script-opts=ytdl_hook-all_formats=yes --ytdl-format=bestaudio`
to play the exact same tracks without manual intervention.
This already worked when two formats were requested.
For a single format with `all_formats=yes` it would also play a track
that was not requested when available. This was inconsistant with the
behavior of `all_formats=no` (default), which would not play a second
track when only a single one was requested.
This combined with #10395 now plays the exact same tracks with
`all_formats=yes` as without, even when only one format is requested.
2022-08-14 23:31:51 +00:00
Dudemanguy f0011552e7 wayland: add support for configure bounds
In wayland-protocols 1.25, xdg-shell got a version bump which added the
configure_bounds event. The compositor can send this to clients to
indicate that they should not resize past a certain size. For mpv, we'll
choose to only listen to this on reconfig events (i.e. when the window
first appears and if the video resolution changes later in the
playlist). However, this behavior is still exposed as a user option
(default on) because it will neccesarily conflict with a user setting a
specific geometry size and/or window scale. Presumably, if someone is
setting a really large size that goes beyond the bounds of their
monitor, they actually want it like that. The wayland-protocols version
is newer-ish, but we can get around having to poke the build system by
just using a define that exists in the generated xdg-shell header.
2022-08-14 16:04:49 +00:00
Dudemanguy f781dddabc x11: fix display-{width,height} calculation
Unexpectedly, x11->screenrc actually doesn't update with randr events.
In a multimonitor configuration it could easily be wrong depending on
the user's layout. While it's tempting to modify the logic so screenrc
changes with randr events, this rectangle is currently used everywhere
and as far as we know, this pretty much works fine. Instead, just loop
over the randr displays that we have and select it if it overlaps with
the winrc. This follows the same logic as the fps selection in the case
of the mpv window overlapping multiple monitors (the last one is
selected).
2022-08-14 16:04:23 +00:00
Dudemanguy b669a20bb5 DOCS/options: correct wayland-disable-vsync option
This is actually dated. It works on all wayland outputs/VOs and has for
some time now.
2022-08-12 23:14:09 -05:00
Christoph Heinrich 813dfe1924 ytdl_hook: fix default track for single format
Tracks are marked as default tracks based on what yt-dlp/youtube-dl
returns in the field `requested_formats`. The problem is that this field
only exists when there is more then one requested format.
So `ytdl-format=bestvideo+bestaudio` would have that field,
but `ytdl-format=bestaudio` would not,
leading to no tracks being marked as default tracks.

The requested formats can also be found under `requested_downloads`,
which exists regardless of the number of requested formats.
However when there is more then one requested format,
`requested_downloads` doesn't contain those formats directly and instead
has a field `requested_formats` that is identical to the other
`requested_formats`. Therefore use `requested_downloads` as a fallback
for when `requested_formats` doesn't exist.
2022-08-12 14:31:59 +00:00
Jan Beich a3b2d3f930 github/workflows: auto-update freebsd-vm within major version
Reduce the churn by transparently picking up bustage fixes.
2022-08-12 09:18:45 +02:00
sfan5 f2ef942ef5 drm_common: remove hard dependency on drmIsKMS()
ae768a1e14 forgot to bump the required
libdrm version however Debian 11 just barely misses the requirement,
which is a good reason not to require it unconditionally anyway.
2022-08-11 18:31:04 +02:00
Ho Ming Shun 5f6e8f856c context_drm_egl: skip page flip wait on error
Any error in page flipping caused mpv to wait indefinitely for a page
flip callback.
2022-08-11 09:05:44 +02:00
Philip Langdale 4081f45501 gpu/hwdec: reorder drmprime below drmprime_drm
The older overlay based drmprime hwdec should be preferred to the new
texture mapping one. This is for a few reasons:

1. In any situation where both hwdecs work, it's probably right to use
   the more mature one by default, for now.
2. It seems like the overlay path primarily works on older SoCs
   where the texture path is less performant, and in at least one
   tested case is visually buggy, so you definitely want it to be
   tried first.
3. In situations where the old hwdec doesn't work, it will fall through
   to the new one.
2022-08-09 22:19:45 -07:00
Philip Langdale 6265cbb62a video/drmprime: fix use-after-free
Same thing as in hwdec/drmprime.
2022-08-09 22:19:45 -07:00
Philip Langdale f87ab4d441 hwdec/drmprime: fix build
I accidentally included an adjustment for a pending change.
2022-08-09 21:21:47 -07:00
Philip Langdale 093db2f565 hwdec/dmabuf_interop: Properly prefix priv struct
Obviously, this should be dmabuf_interop_priv as it's declared in a
header file that could get included anywhere.
2022-08-09 21:02:50 -07:00
Philip Langdale dbc2d37401 hwdec/drmprime: Fix small issues
sfan5 found a few things after I pushed the change, so this fixes them.

* Use-after-free on drm_device_Path
* Not comparing render_fd against -1
* Not handling dup() errors
2022-08-09 21:01:04 -07:00
Thomas Weißschuh 52aed495cb audio: drain ao on EOF
This gives pull-based AOs the chance to play all queued audio.
Also it will make sure that the audio has finished playing so we can
reinitialize the AO if format changes are necessary.

Fixes #10018
Fixes #9835
Fixes #8904
2022-08-09 10:30:58 -07:00
Philip Langdale 25fa1b0b45 hwdec/drmprime: add drmprime hwdec-interop
In the confusing landscape of hardware video decoding APIs, we have had
a long standing support gap for the v4l2 based APIs implemented for the
various SoCs from Rockship, Amlogic, Allwinner, etc. While VAAPI is the
defacto default for desktop GPUs, the developers who work on these SoCs
(who are not the vendors!) have preferred to implement kernel APIs
rather than maintain a userspace driver as VAAPI would require.

While there are two v4l2 APIs (m2m and requests), and multiple forks of
ffmpeg where support for those APIs languishes without reaching
upstream, we can at least say that these APIs export frames as DRMPrime
dmabufs, and that they use the ffmpeg drm hwcontext.

With those two constants, it is possible for us to write a
hwdec-interop without worrying about the mess underneath - for the most
part.

Accordingly, this change implements a hwdec-interop for any decoder
that produces frames as DRMPrime dmabufs. The bulk of the heavy
lifting is done by the dmabuf interop code we already had from
supporting vaapi, and which I refactored for reusability in a previous
set of changes.

When we combine that with the fact that we can't probe for supported
formats, the new code in this change is pretty simple.

This change also includes the hwcontext_fns that are required for us to
be able to configure the hwcontext used by `hwdec=drm-copy`. This is
technically unrelated, but it seemed a good time to fill this gap.

From a testing perspective, I have directly tested on a RockPRO64,
while others have tested with different flavours of Rockchip and on
Amlogic, providing m2m coverage.

I have some other SoCs that I need to spin up to test with, but I don't
expect big surprises, and when we inevitably need to account for new
special cases down the line, we can do so - we won't be able to support
every possible configuration blindly.
2022-08-09 10:19:18 -07:00
Thomas Weißschuh c9ecaedc44 ao_pipewire: tell audio server about number of queued samples 2022-08-09 09:24:55 -07:00
Mia Herkt 2c46ae8ea3 man: remove unhelpful language
Whether or not the GNOME project has a tendency to make life
difficult for anyone outside their ecosystem, the user manual is
no place for childish rants such as this.

Keep it to what is relevant for users.
2022-08-07 20:58:56 +02:00
Thomas Weißschuh 9add44b11a ao_pipewire: use mpv logging 2022-08-04 09:25:19 -07:00
Philip Langdale 2b34949a7c hwdec/dmabuf_interop_gl: support basic multi-plane formats
I already added the equivalent logic for dmabuf_interop_pl previously
but I skipped the GL support because importing dmabufs into GL requires
explicitly providing the DRM format, and if you are taking a
multi-plane format and trying to treat each plane as a separate layer,
you need to come up with a DRM format for each synthetic layer.

But my initial testing has shown that the RockPRO64 board I've got to
work on drmprime hwdec will only produce NV12 in a single layer multi
plane format, and it doesn't have Vulkan support, so I have had to
tackle the GL multi-plane problem.

To that end, this change introduces the infrastructure to provide new
formats for synthetic layers. We only have lookup code for NV12 and
P010 as these were the only ones I could test.
2022-08-03 16:56:17 -07:00
Philip Langdale 64f4249604 hwdec/dmabuf_interop: use AVDRMFrameDescriptor to describe dmabufs
Annoyingly, libva and libdrm use different structs to describe dmabufs
and if we are going to support drmprime, we must pick one format and do
some shuffling in the other case.

I've decided to use AVDRMFrameDescriptor as our internal format as this
removes the libva dependency from dmabuf_interop. That means that the
future drmprime hwdec will be able to populate it directly and the
existing hwdec_vaapi needs to copy the struct members around, but
that's cheap and not a concern.
2022-08-03 16:56:17 -07:00
Philip Langdale e9e5059589 hwdec/dmabuf_interop: refactor out hwdec_vaapi dependencies
With the files renamed, we can now disentangle the shared private
struct between the interops and hwdec_vaapi. We need this separation
to allow the future drmprime hwdec to use the interops.
2022-08-03 16:56:17 -07:00
Philip Langdale 06900eef63 hwdec/vaapi: rename interops to reflect more general use
This is the first in a series of changes that will introduce a drmprime
hwdec. As our vaapi hwdec is based around exporting surfaces as
drmprime dmabufs, we've actually got a lot of useful code already in
place in the GL/PL interops. I'm going to reorganise and adjust this
code to make the interops usable with the new hwdec as well.

The first step is to rename the files and functions. There are no
functional or other changes here. They will come next.
2022-08-03 16:56:17 -07:00
Christoph Heinrich 490e263529 af_rubberband: add new engine option in rubberband 3.0.0 2022-08-03 15:29:02 +00:00
sfan5 ae768a1e14 drm_common: skip cards that don't support KMS for autodetection
Avoids another pitfall on systems where the first card has a primary
node but is not capable of KMS. With this change --drm-context=drm
should work correctly out-of-the-box in all cases.
2022-08-03 16:43:08 +02:00
Ho Ming Shun 8b1f978712 drm: avoid drmModeAtomicCommit races by blocking
On S905X (meson) boards drmModeAtomicCommit called from
disable_video_plane in hwdec_drmprime_drm.c might still be running when
another call is made from queue_flip in context_drm_egl.c.

This causes EBUSY error in queue_flip, and causes mpv to hang.
2022-08-03 16:42:49 +02:00
Aaron Boxer 24d10fc998 video: remove unnecessary code
plane_clear[p] is never NULL
2022-08-01 23:11:42 +02:00
Christoph Heinrich 284fecc0bd ytdl_hook: fix playlist index extraction
The example given in #3024 would not play the correct video when
combined with `--ytdl-raw-options=yes-playlist=`.
Allowing `youtube:tab` as extractor and correcting the id check fixes
that.
2022-07-26 21:16:23 +00:00
SukkaW cb98d8d71c ci: bump macos runner version 2022-07-26 14:20:00 -04:00
Emmanuel Gil Peyrot d2467f61be wayland: add missing newline in wayland_common 2022-07-23 19:56:48 +00:00
Philip Langdale 89dfcf8286 hwdec_vaapi_pl: support simple multi-plane image formats
This is somewhat academic for now, as we explicitly ask for separate
layers and the scenarios where multi-plane images are required also use
complex formats that cannot be decomposed after the fact, but
nevertheless it is possible for us to consume simple multi-plane
images where there is one layer with n planes instead of n layers with
one plane each.

In these cases, we just treat the planes the same as we would if they
were each in a separate layer and everything works out.

It ought to be possible to make this work for OpenGL but I couldn't
wrap my head around how to provide the right DRM fourcc when
pretending a plane is a layer by itself. So I've left that
unimplemented.
2022-07-23 12:23:30 -07:00
Niklas Haas 6e4dd334fe vo_gpu_next: fix screenshots on single-frame files
This check was wrong/outdated. PL_QUEUE_MORE does not imply an empty
frame mix, it can still contain partial frames.
2022-07-23 14:54:39 +02:00
Graham Booker 99315383f8 vo_gpu/d3d11: fix VRAM leak
A VRAM memory leak was present in d3d11 when `idle=yes` and playback
stops for an item. This patch re-enables some of the code which is
only used during diagnostic which fixes the issue.
2022-07-21 16:13:45 +02:00
Ryan Hendrickson ad5a1ac873 osc.lua: add osc-tcspace script option
Generally, the hard-coded sizes used for the OSC elements are
comfortable regardless of the font used, but the timecode fields have
relatively many characters, and so are affected to a greater degree by
fonts with a wider or narrower average character width than expected.

This allow users to adjust the space reserved for the timecode fields to
compensate.
2022-07-19 23:19:45 +03:00
Ryan Hendrickson ff25a8c65a osc.lua: add osc-unicodeminus script option
This option enables the use of the Unicode U+2212 Minus Sign character
when displaying the time remaining, instead of "-" (U+002D
Hyphen-Minus).
2022-07-19 23:19:45 +03:00
Niklas Haas 8ef744d1b7 vo_gpu_next: don't crash on !frame->current
This path incorrectly assumes there is a current frame.
2022-07-18 22:03:06 +02:00
Christoph Heinrich 431473310f ytdl_hook: always set HTTP headers
In some cases HTTP headers were not set, leading to some sites not
working despite being supported by yt-dlp/youtube-dl.
2022-07-18 01:17:00 +00:00
Coelacanthus 70fa9502f3 libplacebo: fix compatibility with libplacebo >= 5
libplacebo 4.157 [1] rename context.h to log.h, and left a compatibility
header. In 5.x, this header has been removed.

Since we require libplacebo 4.157 to build mpv, we can just use log.h to
fix compatibility with 5.x.

[1]: https://github.com/haasn/libplacebo/commit/2459200a133d1a0f36f092a32a2d5d443cfbee55

Signed-off-by: Coelacanthus <coelacanthus@outlook.com>
2022-07-16 13:06:21 +03:00
Jan Beich 59ee10e3c7 github/workflows: upgrade FreeBSD to 13.1
FreeBSD doesn't support /latest and /quarterly package repos on EOL
versions. 13.0 reaches EOL on 2022-08-31, so avoid CI breakage.
2022-07-15 22:02:44 +00:00
Niklas Haas 81c5ed5b13 vo_gpu: fix 3DLUT precision
Using cmsFLAGS_HIGHRESPRECALC results in Little-CMS generating an
internal 49x49x49 3DLUT, from which it then samples our own 3DLUT. This
is completely pointless and not only destroys the accuracy of the 3DLUT,
but also results in no additional gain from increasing the 3DLUT
precision further.

The correct flag for us to be using is cmsFLAGS_NOOPTIMIZE, which
suppresses this internal 3DLUT generation and gives us the full
precision. We can also specify cmsFLAGS_NOCACHE, which is negligible but
in theory prevents Little-CMS from unnecessary pixel equality tests.
2022-07-15 16:34:11 +02:00
Thomas Weißschuh 0044c19f0d ao_pipewire: prevent deprecation warning for pw_stream_get_time() 2022-07-08 17:19:23 -07:00
Wim Taymans c7b17beaf1 ao_pipewire: pipewire uses linear volume
Don't use cube root volumes, pipewire uses linear volumes.
2022-07-08 07:45:09 -07:00
Wim Taymans c01bb44e36 ao_pipewire: don't access core after disconnect
pw_core_disconnect frees the core, so accessing it afterward to
destroy the context is not allowed.

Instead, just destroy the context, the first thing it does is disconnect
all cores for us.
2022-07-08 07:45:09 -07:00
Wim Taymans 60ed51008d ao_pipewire: zero listeners
The listeners need to be cleared because removing them might invoke the
removed handler, which could otherwise point to invalid memory.
2022-07-08 07:45:09 -07:00
Alex B d38ff1c958 ao_pipewire: support ao-volume on non-stereo channel layouts
mpv only remembers volume for two channels.
Always apply the same volume to all channels in case of
non-stereo layout similarly to ao_pulse.
Don't try to do anything smart when averaging volumes,
normally they are equal anyway.
2022-07-08 06:39:23 -07:00
hooke007 6858fc7d80 DOCS/encoding: remove the legacy option syntax 2022-07-07 21:12:57 -04:00
Ho Ming Shun 80e29d1851 drm_prime: fix newline in error message 2022-07-05 13:55:47 -04:00
J. Dekker 659ab2f946 meson: fix rst2html command 2022-07-05 13:19:42 +00:00
Dudemanguy 369168b9be context_x11egl: remove supposed transparency fix
This was introduced in 7fb972fd39 and
later revised in f5a094db04. Transparency
in EGL/X11 has been broken upstream for years in Mesa unfortunately.
However, the first commit claimed to have found a way to preserve
transparency by doing a trick with picking EGLConfigs (the second commit
revises this but keeps the logic in place). However, it doesn't appear
that the first commit actually fixes anything (transparency doesn't work
on my machine) and no one else seems to have reported it working. On the
other hand, if Mesa does ever actually fix this, transparency would
immediately be broken since mpv would always set the EGL_ALPHA_SIZE to
0. Go ahead and remove this since it doesn't seem to have any actual
utility and is technically a bit of a timebomb (not that deleting two
lines is a lot of work but still) if upstream ever does fix this.
2022-07-01 14:13:19 +00:00
25792431 beac0d729b DOCS: fix typo 2022-07-01 14:11:01 +00:00
dyphire 572850774d DOCS/osc: fix option "showidlescreen" -> "idlescreen"
This option was added in mpv-player@ec236f7, but its name in the document description is incorrect
2022-07-01 14:06:31 +00:00
Dudemanguy 8557ba76e2 meson: add a summary at the end of configuration
The meson build does a lot of checks and if you aren't familiar with the
internals of the meson.build, it may not be clear what is actually
enabled and what isn't. It turns out that meson has a handy function,
summary, exactly for this. This just prints a pretty summary of some
notable features in the build. It's not meant to be a comprehensive
list, but rather just what users are likely to care the most about (i.e.
x11, vulkan, etc.)
2022-06-27 19:09:33 +00:00
Niklas Haas 3a2838c88d vo_gpu_next: implement --cscale
Fixes #9451
2022-06-24 16:11:17 +02:00
Niklas Haas 8da6b355f8 swresample: don't forcibly clip on every conversion
This was introduced in 04257417 without a clear explanation of the bug
it was solving, so I have no idea if it's still needed (or why it ever
was). And it definitely creates unexpected behavior, e.g. forced
clipping when converting between float and floatp.

I therefore think we should simply remove this logic and see if it
regresses anything else, then fix those other bugs *properly* (if
they're still around).

Fixes #9979
2022-06-23 23:52:35 +02:00
Avi Halachmi (:avih) 3694af6076 js: key bindings: ensure priorities for same-key - again
Commit 7f4841ff sorted the bindings so that if the same key was bound
more than once, then the newest binding takes priority (sorted last).

However, it got the comparison function wrong, which means the result
of the sort depended on the algorithm and not on the actual data, so
the priority for keys with more than one binding was still arbitraty.

Fix the sort function, and finally ensure that later binding acutally
override earlier bindings of the same key.
2022-06-23 17:16:33 +03:00
Dudemanguy 652f09a7a6 x11: avoid XPresent API calls when it's not needed
This commit kind of mixes several related things together. The main
thing is to avoid calling any XPresent functions or internal functions
related to presentation when the feature is not auto-whitelisted or
enabled by the user. Internally rework this so it all works off of a
use_present bool (have_present is eliminated because having a non-zero
present_code covers exactly the same thing) and make sure it updates on
runtime. Finally, put some actual logging in here whenever XPresent is
enabled/disabled. Fixes #10326.
2022-06-22 18:09:11 +00:00
CogentRedTester 1ffdb9128d lua: command_native_async: make the callback optional
The documentation states that the callback is optional, but it actually
was not.

Now it's optional, as docuented.
2022-06-22 14:44:52 +03:00
CogentRedTester 099ae86717 lua: command_native_async: always callback a-sync
Previously if the raw command_native_async returned an error then the
callback function was run directly. This meant that script writers
potentially had to account for both synchronous and asynchronous logic
in the callback, which can happen even with seemingly 'safe' commands
if the mpv event queue is full.

This was at odds with the Javascript implementation of
the function, which always runs the callback asynchronously.

Now the mp.add_timeout function is used to run the callback
asynchronously on error, replicating the Javascript implementation.

This provides consistency for developers in how the callback is handled
in Lua, and increases consistency between the Lua and Javascript APIs.
2022-06-22 14:44:12 +03:00
Dudemanguy 24f4582b6f x11: add --x11-present option
With the recent addition of the libxpresent, it should improve frame
timings for most users. However, there were known cases of bad behavior
(Nvidia) which lead to a construction of a whitelist instead of just
enabling this all the time. Since there's no way to predict whatever
combination of hardware/drivers/etc. may work correctly, just give users
an option to switch the usage of xorg's presentation statistics on/off.
The default value, auto, works like before (basically, Mesa drivers and
no Nvidia are allowed), but now one can force it on/off if needed.
2022-06-22 03:55:49 +00:00
Dudemanguy d9f7dd7212 x11: add nouveau to the xpresent whitelist
A user noted that this worked correctly (i.e. vsync jitter of 0) so go
ahead and add it here as a safe driver for xpresent to use.
2022-06-22 03:55:49 +00:00
Dudemanguy 230d490eca x11: correct provider detection logic
The old logic always reset the x11->has_mesa/has_nvidia values on every
loop through the provider. This meant that it would always just match
whatever the last provider happened to be. So in the case of a dual GPU
system, if nvidia was the very first provider and the integrated
intel/amd card was the second (in practice, this is probably mostly the
other way around), then mpv would set has_mesa to true and has_nvidia to
false and thus try to use presentation. This is not the intended
behavior. Just rework this by also checking x11->has_mesa/has_nvidia in
the loop so a true value from the previous iteration is preserved.
2022-06-21 18:05:35 +00:00
Aaron Boxer b29878e3a1 vo_vaapi_wayland: remove vaapi format query as formats are never used
This code was taken from the older vo_vaapi driver, which does
use the vaapi format list, but the new driver has no use for
these formats, as it is only interested in va surfaces that
can be mapped to wl buffers. The format doesn't enter into
it at all.
2022-06-21 14:05:19 +00:00
Dudemanguy 45ff20986d meson: remove pointless d3d11 dictionary
Immediately after this, d3d11 is defined again and the rest of the
meson.build uses that. Probably, this dictionary was from the original
meson PR and removing it was forgotten at some point while stuff was
being rewritten.
2022-06-20 15:01:41 +00:00
Dudemanguy 2606d4cc51 x11: replace strcasestr usage with bstr
strcasestr is a GNU extension, but we can just use bstr instead to do
the same thing.
2022-06-19 16:21:07 -05:00
Dudemanguy 7e921e9939 github/workflows: install libxpresent on freebsd
This is needed for x11 which is in turn needed for vdpau.
2022-06-19 18:13:55 +00:00
Dudemanguy 3d459832a8 x11: support xorg present extension
This builds off of present_sync which was introduced in a previous
commit to support xorg's present extension in all of the X11 backends
(sans vdpau) in mpv. It turns out there is an Xpresent library that
integrates the xorg present extention with Xlib (which barely anyone
seems to use), so this can be added without too much trouble. The
workflow is to first setup the event by telling Xorg we would like to
receive PresentCompleteNotify (there are others in the extension but
this is the only one we really care about). After that, just call
XPresentNotifyMSC after every buffer swap with a target_msc of 0. Xorg
then returns the last presentation through its usual event loop and we
go ahead and use that information to update mpv's values for vsync
timing purposes. One theoretical weakness of this approach is that the
present event is put on the same queue as the rest of the XEvents. It
would be nicer for it be placed somewhere else so we could just wait
on that queue without having to deal with other possible events in
there. In theory, xcb could do that with special events, but it doesn't
really matter in practice.

Unsurprisingly, this doesn't work on NVIDIA. Well NVIDIA does actually
receive presentation events, but for whatever the calculations used make
timings worse which defeats the purpose. This works perfectly fine on
Mesa however. Utilizing the previous commit that detects Xrandr
providers, we can enable this mechanism for users that have both Mesa
and not NVIDIA (to avoid messing up anyone that has a switchable
graphics system or such). Patches welcome if anyone figures out how to
fix this on NVIDIA.

Unlike the EGL/GLX sync extensions, the present extension works with any
graphics API (good for vulkan since its timing extension has been in
development hell). NVIDIA also happens to have zero support for the
EGL/GLX sync extensions, so we can just remove it with no loss. Only
Xorg ever used it and other backends already have their own present
methods. vo_vdpau VO is a special case that has its own fancying timing
code in its flip_page. This presumably works well, and I have no way of
testing it so just leave it as it is.
2022-06-19 18:13:55 +00:00
Dudemanguy ceade34930 x11: use xrandr providers for driver detection
Unfortunately there's a certain company that makes graphics drivers that
are harder to deal with. The next commit aims to implement presentation,
but some empirical testing from users show that it's actually broken.
Give up and just tap into Xrandr so we can figure what drivers (or well,
providers by the extension terminology) are driving the screen.
Basically if we find intel, amd, or radeon, assume it's a Mesa driver.
If we find nvidia, then it must be nvidia. This detection requires randr
1.4 (which means using presentation in mpv secretly depends on randr
1.4), but this protocol version is nearly a decade old anyway so
probably 99.9% of users are fine. Do the version query check and all
that anyway just to be on the safe side.
2022-06-19 18:13:55 +00:00
Dudemanguy 7ce26dd324 vo: move wayland presentation to separate files
Wayland had some specific code that it used for implementing the
presentation time protocol. It turns out that xorg's present extension
is extremely similar, so it would be silly to duplicate this whole mess
again. Factor this out to separate, independent code and introduce the
mp_present struct which is used for handling the ust/msc values and some
other associated values. Also, add in some helper functions so all the
dirty details live specifically in present_sync. The only
wayland-specific part is actually obtaining ust/msc values. Since only
wayland or xorg are expected to use this, add a conditional to the build
that only adds this file when either one of those are present.

You may observe that sbc is completely omitted. This field existed in
wayland, but was completely unused (presentation time doesn't return
this). Xorg's present extension also doesn't use this so just get rid of
it all together. The actual calculation is slightly altered so it is
correct for our purposes. We want to get the presentation event of the
last frame that was just occured (this function executes right after the
buffer swap). The adjustment is to just remove the vsync_duration
subtraction. Also, The overly-complicated queue approach is removed.
This has no actual use in practice (on wayland or xorg). Presentation
statistics are only ever used after the immediate preceding swap to
update vsync timings or thrown away.
2022-06-19 18:13:55 +00:00
Dudemanguy 44ecf83a1b meson: use require when checking for vdpau
Technically this was wrong. If you passed -Dvdpau=enabled but did not
have x11 (a requirement for this), the build would silently just not
build the vdpau VO. The correct behavior is for it to be a hard error.
Accomplish this by using the require function and making sure that x11
is indeed being used before attempting to find the library.
2022-06-19 02:24:31 +00:00
Mia Herkt 07d78f8c8b ci/build: Do not manually install Meson in openSUSE container
Newer image builds already include Meson.
2022-06-19 02:56:28 +02:00
Crend King c1a46ecfaf meson: rearrange library dependency order to avoid crash with fontconfig
In win32 build, if libass and libfontconfig appear after libmingwex
during linking, crash happens whenever fontconfig calls to opendir().

Moving them before ffmpeg makes sure they always appear first.

More info on https://github.com/shinchiro/mpv-winbuild-cmake/issues/217.
2022-06-18 15:17:46 +00:00
Aaron Boxer c961f4d0db vo_vaapi_wayland: only attach solid buffer once to main surface, on creation
There's no need to attach it with each frame.
2022-06-15 20:54:34 +00:00
Aaron Boxer ccce813a92 vo_vaapi_wayland: remove unnecessary subsurface sync/desync in resize
resize only changes subsurface position, which is always synchronized
with the parent surface.

For reference, see :
https://wayland-book.com/surfaces-in-depth/subsurfaces.html
2022-06-15 20:54:34 +00:00
Jan Ekström 1e1956e15b ci/build-mingw64: enable test building
Not currently run, but adds coverage for compiled code.
2022-06-15 21:19:10 +03:00
Jan Ekström 5d9af3a9dd ci/build-mingw64: bump dependencies 2022-06-15 21:19:10 +03:00
Jan Ekström 05a3affc58 ci/build-mingw64: switch to fossils directory for zlib
This contains current as well as previous versions, while the root
directory only contains the latest version.
2022-06-15 21:19:10 +03:00
Jan Ekström 312a555053 ci/build-tumbleweed: attempt to enable unit tests in CI 2022-06-15 21:19:10 +03:00
Jan Ekström 8f274da066 test/chmap: start adding AVChannelLayout unit tests
The first set iterates through all standard FFmpeg layouts and
checks that those which fit MP_NUM_CHANNELS succeed.

The second set iterates through built-in named channel layouts,
and attempts to convert them to AVChannelLayouts.
2022-06-15 21:19:10 +03:00
Jan Ekström 8123adadbd audio/chmap: add mp_iterate_builtin_layouts
Mostly useful for unit tests in order to access the channel
layouts from chmap which have mapped channels.
2022-06-15 21:19:10 +03:00
Jan Ekström 0411acf5f6 f_lavfi: switch to AVChannelLayout when available 2022-06-15 21:19:10 +03:00
Jan Ekström edfd17ab18 ad_lavc: switch to AVChannelLayout when available 2022-06-15 21:19:10 +03:00
Jan Ekström e7483ced5d af_lavcac3enc: switch to AVChannelLayout when available 2022-06-14 22:41:20 +03:00
Jan Ekström 42b58c5698 af_lavcac3enc: refactor chmap adding into its own function
This simplifies ifdeffery with AVChannelLayouts.
2022-06-14 22:19:45 +03:00
Jan Ekström 7a3f9af67f ao_lavc: switch to AVChannelLayout when available 2022-06-12 21:05:59 +03:00
Jan Ekström cfc39bec00 demux_lavf: switch to AVChannelLayout when available 2022-06-12 21:05:59 +03:00
Jan Ekström 46b19aedc6 common/av_common: switch to AVChannelLayout when available 2022-06-12 21:05:59 +03:00
Jan Ekström 302acb27c8 audio/aframe: switch to AVChannelLayout when available 2022-06-12 21:05:59 +03:00
Jan Ekström 1d15a5a059 audio: add AVChannelLayout helpers to convert from/to mp_chmap
This is the new FFmpeg channel layout structure, which now
combines channel count and layout into a single location.

Only unspecified (channel count only) and native (channel layout
mask based) layouts are currently supported for the initial move
towards non-deprecated APIs.
2022-06-12 21:05:59 +03:00
Dudemanguy 602995fd40 wayland: set appid before initial surface commit
This shouldn't have mattered but apparently qtile is unable to get the
app id if you set it after the initial surface commit. Wayland is a mess
anyway so just shuffle this around so that the frame callback and
surface commit are the last things registered in vo_wayland_init. This
works around qtile and, in theory, doesn't appear to break anything
else. Fixes #10280.
2022-06-11 10:20:06 -05:00
Dudemanguy b3ef506932 wayland_gl: fix a typo
Somehow in commit 661b5542de, my editor
snuck in a ¥ sign in here. Oops.
2022-06-11 10:07:11 -05:00
Dudemanguy 661b5542de wayland_gl: wait until resize to create egl_window
Some wayland compositors (i.e. weston) get extremely picky about
committed buffer sizes not matching the configured state. In particular,
weston throws an error on you if you attempt to launch with
--window-maximized and use opengl (vo_vaapi_wayland actually errors as
well in this case, but that's a different issue). The culprit here is
actually wl_egl_window_create. This creates an initial buffer at the
sizes passed in the arguments which is what weston doesn't like.
Instead, move the egl_window creation call to the resize function. This
ensures that mpv is using the size obtained via the toplevel event, and
it should always be the buffer size we want.
2022-06-10 13:55:22 +00:00
Sagnac aab9ab97f0 DOCS/options: fix incorrect labelling of hr-seek default
The `absolute` value was incorrectly labelled as the default instead of
the value named `default`, which was somewhat confusing. When the newer
default option was added in 679e410 it seems like wm4 forgot to remove
the label in the manual on the previous default.
2022-06-10 13:42:10 +00:00
Avi Halachmi (:avih) 7ff4a27eb6 sub: jsre filter: abort init early on empty filter list
TL;DR: previously a JavaScript VM was created + destroyed whenever
       a sub track was initialized, even if no jsre filter was set.
       Now a JS VM is created only if jsre filters were set.

Sub filters are initialized once when a subtitle track is chosen, and
then whenever the sub track changes or when some sub options change.

Sub filters init is synchronous - playback is suspended till it ends.

A filter can abort init early (get disabled) depending on conditions
specific to each filter. The regex and jsre filters aborted early
if the filter is disabled (default is enabled) or if the track is not
ass (relativey rare, e.g. bitmap subs).

The init then iterates over the filter strings, and if the result is
empty (common - no filter was added, but also if all strings failed
regex init) then it's also aborted during init.

While this iteration step is cheap with filter regex, with jsre it
requires instanciating the JS VM (mujs) in advance in order to parse
the filter strings at the list, and the VM is then destroyed if the
list ends up empty.

This VM create+destroy is fast but measurable (0.2 - 0.7 ms, slowest
measured on 2010 MacBook Air), but can be avoided altogether if we
check that the filter list is not empty before we create the VM.

So now we do just that.
2022-06-09 14:38:24 +03:00
Jan Ekström 3a52159286 ci/mingw64: add git libplacebo for gpu-next
This way mingw-w64 becomes the first CI workflow to build gpu-next.

Unfortunately, currently neither wscript or meson has gpu-next or
libplacebo-next as an option that one can require.
2022-06-07 21:04:00 +03:00
Jan Ekström f7164fcfac github/workflows: move mingw CI to ubuntu 22.04
Updates mingw-w64 to 8.0 as well as generally bumps the toolchain
to gcc 10.x.
2022-06-07 21:02:37 +03:00
Jan Ekström a10e3ab230 ci/mingw64: make meson crossfile global
This enables it to be utilized for dependencies such as libplacebo.
2022-06-07 21:02:22 +03:00
Dudemanguy 7684ebc68b wayland_gl: use wl->scaling when creating egl_window
This was actually always bugged, but we just got lucky that compositors
ignored it. The egl window was created only using wl->geometry's
coordinates but those do not include the scale factor. So technically,
the initial window creation always had the wrong size (off by whatever
the scaling factor is). The resize call later fixes it because that
correctly uses wl->scaling so in practice nothing bad was seen.
wlroots's master branch has started sending an error in this case
however and this is what trips it. Fix it correctly by using the scale
factor. This is what cd3b4edea0 tried to
fix (but was incorrect).
2022-06-07 17:13:45 +00:00
Dudemanguy a18b614a4a wayland: rearrange initialization logic
cd3b4edea0 is not correct and had some
unexpected breakage with geometry/resizing. Rather than completely
revert it, this commit restores the set_surface_scaling call as well as
rearranges some other things in the wayland init/reconfig process to
make it simplier. The next commit properly fixes what
cd3b4edea0 tried to fix.
2022-06-07 17:13:45 +00:00
AtticFinder65536 a4f0db051a player: add tiff/tif (TIFF) to list of image extensions 2022-06-07 06:28:34 -04:00
AtticFinder65536 bd46f050fe player: add jxl (JPEG XL) to list of image extensions 2022-06-07 06:28:34 -04:00
Dudemanguy cd3b4edea0 wayland: remove some unneeded lines from reconfig
Just a couple of small changes. First, the obvious one is to remove the
bogus wl->window_size = wl->vdparams; line in the configure conditional.
The reconfig always unconditionally sets the window_size here so there's
no need to duplicate it. The more important change is to remove the
usage of set_surface_scaling. This function is just to handle when
scaling changes and for setting the initial scale, it was called in the
reconfig. This, however, causes some weird issues in the latest
sway/wlroots where it can try to divide a buffer by an inappropriate
scale factor. This is possibly due to some weird ordering of events and
only occured in opengl for some reason.

Luckily, it turns it out it's not neccessary to set the scaling here at
all. The surface enter event is already setup to handle scale changes.
On an HIDPI display, mpv will initially assume a scale of 1 but the
surface actually enters the wl_output, it will automatically readjust
and resize itself to the appropriate scale value. This works on the
initial launch of the mpv window as well, so there's no need to special
case this in the reconfig event. This has the nice bonus of avoiding
that sway/wlroots issue as well since the buffer_scale is set much
later. Fixes #10263.
2022-06-06 15:13:07 -05:00
Niklas Haas 969bdf5f41 vo_gpu_next: fix OSD rendering of screenshots
One downside of this approach is that it bypasses the mixer cache, but
while this is not ideal for performance reasons, the status quo is also
simply broken so I'd rather have a slower implementation that works than
a faster implementation that does not.

And as it turns out, updating the OSD state and invalidating the mixer
cache correctly is sufficiently nontrivial to do in a clean way, so I'd
rather have this code that I can be reasonably certain does the right
thing.

Fixes #9923 as discussed. Also fixes #9928.
2022-06-06 17:04:08 +02:00
Simon Ser c4c7b07acf meson: add internal arg to wayland-protocols' get_variable()
This allows developers to build mpv with a wayland-protocols
subproject.
2022-06-05 13:46:29 -05:00
Dudemanguy ec236f7a99 osc.lua: add idlescreen and osc-idlescreen
This is mainly for other user scripts that may conflict with the osc
logo in some way. Although it is possible to listen for
shared-script-properties, this has many edge cases that could easily pop
up. A user could want other OSC things to happen at the same time (say
osc-message). They just don't want the logo. The idlescreen option
disables all idlescreen related things (including the santa hat) if it
is set to "no". A new script message (osc-idlescreen) is also added so
users can easily toggle the value (passing "cycle" or just explictly
setting "yes" or "no"). Some more discussion on this is found in the
below github issues.
https://github.com/mpv-player/mpv/issues/10201
https://github.com/CogentRedTester/mpv-file-browser/issues/55
2022-06-04 14:48:32 +00:00
Wessel Dankers 5c4b0c2afd video/out/dither: remove custom index_t typedef
Apparently _t names are reserved, and in this case it wasn't very
useful anymore (it was useful while developing it, but this code is
almost 10 years old now).

Fixes a compilation error on Solaris.
2022-06-04 01:23:03 +02:00
Dudemanguy f235bfbf36 wayland: force vo_vaapi_wayland scaling to 1
The wayland stuff is designed to update/rescale itself whenever the
wl_output scale changes. This is great, but vo_vaapi_wayland should not
actually attempt to handle any hidpi stuff. The point of this VO is to
hand off as much to the compositor as possible, so we do want the
compositor to do the scaling here (enjoy your bilinear). This fixes some
incorrect rendering that could occur with scaling values not equal 1 due
to mismatches between buffer coordinates and the surface local
coordinates. It also eliminates the need to specify
--no-hidpi-window-scale on hidpi displays (has the same practical
effect).
2022-05-30 20:28:16 -05:00
Dudemanguy 1ff2153245 DOCS/interface-changes: mention vaapi-wayland vo 2022-05-30 19:51:46 +00:00
Aaron Boxer 3536b53ed1 vo: move allocate_memfd method to wayland_common 2022-05-30 19:51:46 +00:00
Dudemanguy 38eda3804f vo_vaapi_wayland/wayland_common: code style fixes
A bad person (AKA me) merged this stuff without paying close enough
attention to the code style. Reformat this to be in-line with the rest
of the wayland code and general mpv style (braces for functions on the
next line, horizontally aligning arguments, some cosmetic cleanups for
wayland_common.h, etc.).
2022-05-30 19:51:46 +00:00
Dudemanguy 0ec3bd6ba9 wayland: use mp_tag_str not drm_format_string
So it turns out that mpv already has an mp_tag_str which makes a
readable string out of fourccs (drm formats are these).
drm_format_string, on the other hand, has a ton of baggage with having
to check different libdrm versions for certain headers, adding
compile-time defines (because there are no version defines in the libdrm
headers), etc. It's a lot simpler to just use what mpv already has and
it returns what you actually care about: i.e. is this format supported
or not. Fixes https://github.com/mpv-player/mpv-build/issues/184
2022-05-30 19:51:46 +00:00
Aaron Boxer b1639ee561 vo: allow vaapi_wayland and vaapi_x11 to coexist 2022-05-30 19:51:46 +00:00
Julian Orth afe29026ed wayland: don't depend on the order of global announcements
E.g. wl_subcompositor could be announced before wl_compositor.
2022-05-28 21:26:04 +00:00
Aaron Boxer defb02daa4 vo: add new vaapi-wayland driver
This driver makes use of dmabuffer and viewporter interfaces
to enable efficient display of vaapi surfaces, avoiding
any unnecessary colour space conversion, and avoiding scaling
or colour conversion using GPU shader resources.
2022-05-24 21:39:34 +00:00
Emanuele Torre 9022b1b51d demux: stop iterating over demuxers as soon as a match is found 2022-05-21 23:32:40 +03:00
CogentRedTester b4c73ed105 osc.lua: fix crash when calling osc-tracklist while idle
If the player is started with --idle  and the osc-tracklist script-message
is called then the tracks_osc table will be nil,
which caused the OSC to crash due to attempting to index a nil value.

This appears to be because the osc_tracklist variable is both
initialised and updated by (ultimately) the render() function, which
is not run when the player is idling.

Rather than mess with the existing OSC logic it's easier to either
add this single check, or alternatively to initialise the the tracks_osc
table somewhere before this.
2022-05-19 13:54:31 +00:00
Dudemanguy f20dbcd620 player: check for argv before printing help text
Both mpv's main function and the client API use mp_initialize to start
up. In general, these work the same however the client API had one
slight, unnecessary limitation: you can't start it up with idle=no. In
practice, the libmpv profile (used with the client API) sets idle to
yes, so it's rarely encountered, but there's no particular reason why
this policy needs to be enforced. It turns out that mp_initialize does a
quick check to see if there are any entries in the playlist and if idle
mode is set. If not, it prints the help message and exits. Basically,
it's just the part that handles the terminal message when you type "mpv"
with no arguments. Unfortunately with idle=no, the client API also hits
this code path, exits prematurely with 1 and thus returns an API error.

Fortunately, the fix is very simple. If the client API is used instead
of the "normal" mpv executable, then the mp_initialize function gets a
NULL for the options argument. When starting mpv from the terminal (when
you would want to see the before mentioned help text), there will always
be at least an argv[0] (the mpv executable name itself) so we can
reliably distinguish between the two. The other case where there could
be no argv is if the pseudo-gui profile is used, but this always
enforces idle so we don't have to worry about it either. In other words,
with this combination of conditions (options, no idle, and no playlist
entries), we can be sure this is from a user calling mpv in the terminal
with no arguments. Therefore, other cases can be allowed which means
client API users can initialize with idle=no. Fixes #10162.
2022-05-16 21:10:09 +00:00
Dudemanguy 9467772362 player: set EOF when seeking to end with keep-open
Normally with the keep-open option, mpv is supposed to set the
eof-reached property to true so clients can possibly do interesting
things at this step. However, there was actually an edge case where this
property notification did not occur. If you use keep-open and then seek
in the file past the end (so mpv stops), property notification is not
actually sent in this case. Internally, mpv does a very exact seek at
this step which also ends playback, but it does not set STATUS_EOF to
the ao and vo before the core idle state is updated. To fix this edge
case, it's simply just a matter of explictly setting STATUS_EOF after
seek_to_last_frame in handle_keep_open. This logic will only ever
trigger if keep-open is being used and the seek goes past the end of the
file, so we know that there will always be an EOF here.
2022-05-14 14:51:42 +00:00
Guido Cella fe9e074752 various: remove trailing whitespace 2022-05-14 14:51:34 +00:00
Dudemanguy d27c85b0a1 wayland: use wl_output v4 for display-names
5774ce759a added the new output name event
and used them for the --fs-screen-name option. It turns out that the
display-names property could also make use of these names, so go ahead
and use output->name in this case if we have them. If not, fallback to
output->model like before.
2022-05-13 14:12:49 -05:00
Guido Cella e686297ecf lua: avoid rare memory leak in mp.join_path
If lua_pushstring is OOM, then our joined path allocation is leaked. Use
autofree to ensure it's not leaked in case of Lua OOM.
2022-05-12 17:15:37 +03:00
Dudemanguy 88120d4759 client API: always export symbols on windows
Windows is weird and symbols weren't actually being exported. This is
because __GNUC__ is defined and picked up in the conditional, but
__attribute__((visibility("default"))) doesn't actually export anything
to the dll. Instead, just check if we have win32 defined first and then
always set __declspec(dllexport). Fixes #10171.
2022-05-11 14:46:41 +00:00
Mark Gaiser 3458651010 stream_lavf: add support for ipfs and ipns
ffmpeg 5.1 adds support for IPFS (the ipns:// and ipfs:// protocols).
This patch enables those protocols to be fist-class citizens in mpv.
Thus allowing for playing IPFS resources on mpv like:
"mpv ipfs://QmbGtJg23skhvFmu9mJiePVByhfzu5rwo74MEkVDYAmF5T"
2022-05-05 16:20:31 +00:00
Dudemanguy 3a4537d40b meson: compile mpv.exe as a win32 gui application
Some compiler flags were passed to mpv in order to get it to build as a
gui application on windows. However on the meson build, this always
resulted in mpv being built as a console application. This is because
the function for making executables in meson specifically has a kwarg
called win_subsystem* which defaults to 'console'. That always added
link arguments at the end which compiled mpv.exe as a console
application. The correct thing to do is to remove all of the
subsystem-related flags in the meson build and use the win_subsystem
kwarg as intended by setting it to 'windows,6.0'. For mpv.com, we can
remove the -Wl,--subsystem,console flag since meson will set this by
default in that executable. This makes mpv.exe function correctly and
open with the pseudo-gui while mpv.com acts as a console wrapper.

https://github.com/mesonbuild/meson/commit/1a0603835e3c9f1047d9b7694efc996219a422e4
2022-05-05 13:04:15 +00:00
Dudemanguy 76f888f555 context_drm_egl: support monitor par
These values and options were simply never looked at in the drm egl
context. This pretty much is just a copy and paste of what is in vo_drm.
Fixes #10157.
2022-05-05 13:03:43 +00:00
Jan Ekström 6f7a0675b0 github/workflows: add macOS 12 build
Apparently it is now in public beta.

ref actions/virtual-environments#5446
2022-05-05 00:02:30 +03:00
Leo Izen db882ed650 video/image_writer: tag colorspace in AVCodecContext
If screenshot-tag-colorspace=yes, then set the corresponding
fields in AVCodecContext, not just in AVFrame.
2022-05-04 14:42:06 -04:00
Emanuele Torre 90d291dce7 DOCS/input: fix typo "NANME" -> "NAME" 2022-05-02 13:24:07 +00:00
Guido Cella ebaf6a6cfa console.lua: don't render a 2nd cursor on the OSC
09ea3a424f moved the console above the OSC when it is visible so they
don't overlap, but only changed the first ass:pos() call and forgot to
update the second one, which redraws the cursor on top of the text, so
when both the OSC and the console are visible, a second cursor is drawn
on the OSC. You have to type past where the buttons are to notice it.

This commit synchronizes the position of the 2 ASS events.
2022-05-01 21:48:20 +10:00
Leo Izen 9ffaa6b81b video/image_writer: fix high-depth JPEG XL screenshots
Allow screenshot-high-bit-depth=yes to work with JPEG XL
screenshots when screenshot-sw=no is set. They already work
as expected when screenshot-sw=yes is set, but this allows
the hardware screenshots to work this way too.
2022-04-29 01:05:52 -04:00
Leo Izen aa1158569c build: add avcodec jpegxl dependency versions
Add the libavcodec version check for AV_CODEC_ID_JPEGXL to the
build system rather than to any file that references it.
2022-04-28 23:56:50 -04:00
datasone ee62a1a56e demux: add support for r128 replaygain tags 2022-04-28 20:13:36 +00:00
Jakub Wilk 05f0ff304e DOCS/ao: remove only usage of git.io link shortening service
This link was originally shortened in bf0cb27489
to improve manpage formatting, but unfortunately Github is now
taking down this service on the 29th. Thus, the full link is
being reinstated.

ref: https://github.blog/changelog/2022-04-25-git-io-deprecation/
2022-04-28 01:07:11 +03:00
Dudemanguy 8a8580e05c wayland: use wl_surface_damage_buffer
Since 2018, wl_surface_damage_buffer has been explicitly preferred and
recommended over wl_surface_damage*. mpv was still using the old
function in a couple of spots. The only difference is that we need to
pass buffer coordinates instead of surface coordinates. In vo_wlshm,
this is done by using vo->dwidth/vo->dheight since that is always used
whenever wl_buffers are created. In the case of the cursor surfaace, we
actually already passed buffer coordinates to it (img->width/height)
which was probablly technically wrong with wl_surface_damage, but it
doesn't really matter in practice. This requires bumping wl_compositor
to version 4 which is no problem since this dates back to 2015*.

https://gitlab.freedesktop.org/wayland/wayland/-/commit/921d0548035673a1bf6aeb9396b9bc728133411e
https://gitlab.freedesktop.org/wayland/wayland/-/commit/3384f69ecf043d62a4e036c0353c2daa01d7c4d0
2022-04-27 20:31:07 +00:00
Leo Izen 6605b6d619 DOCS/options: properly capitalize JPEG XL
The appropriate style for jxl images is JPEG XL,
not Jpeg XL. Update the docs to reflect this.
2022-04-26 12:47:07 -04:00
Leo Izen 1345977f99 video/image_writer: add Jpeg XL screenshots
Add Jpeg XL as a possible output format for screenshots, which
should make it possible to take fast screenshots with much better
quality than JPEG, or take lossless high-bit-depth screenshots
with lower file sizes than PNG.
2022-04-26 16:48:00 +03:00
Cœur bb5b4b1ba6 various: fix typos 2022-04-25 09:07:18 -04:00
Dudemanguy 6407095871 vo_gpu_next: avoid 0x0 resizes
It is possible for vo_gpu_next to attempt a resize before the windowing
backend is fully initialized. In practice, this can happen on wayland
which means libplacebo attempts a 0x0 resize. Depending on the API, a
0x0 resize may be allowed (vulkan or d3d11), but libplacebo just returns
a 0 in this case which mpv doesn't do anything with anyway. In the case
of opengl, this usage is explictly forbidden and will result in a
warning which may confuse users. Solve this by just not trying a resize
if dwidth and dheight in the vo are not available. Fixes #10083.
2022-04-24 22:35:54 +00:00
Dudemanguy 9d133eb00b github/workflows: workaround git permissions error
Recently, git patched a CVE which makes it much more strict about
different users operating on directories they don't own. For us, this
causes breakage with version.sh and version.py since they both run a git
describe command to fetch the commit hash. Currently, this only affects
the tumbleweed container (likely because it was recently changed) and
thus the git describe command always errors out. Workaround this by just
explictly adding the mpv directory as a safe directory for git.
2022-04-21 22:14:27 +03:00
Guido Cella f75701b219 DOCS/options: update the --load-osd-console documentation
- Say built-in which is more common than builtin
- Move "By default" because only the key to open the console is
  customizable, and fix the punctuation and case of the sentence
- ` opens the console, not ´
- Remove the sentences that explains which user script console.lua is
  based on since it's no longer relevant now that the console has been
  part of mpv for over 2 years.
2022-04-21 17:07:47 +00:00
Guido Cella c8125119fa DOCS/input: update the ASS tags documentation URL
The current one hasn't worked in years.
2022-04-21 16:53:46 +00:00
Guido Cella ccff82e610 options: make --cover-art-auto=exact the default
Now that a separate --cover-art-whitelist option exists, files like
cover.jpg are loaded even without setting --cover-art-auto to fuzzy, so
only load files that have exactly the media filename by default, since
fuzzy loading is probably more likely to load unwanted images than to
load cover art that the user intended to display, especially if you play
audio files with a short filename like a.mp3.
2022-04-21 16:42:27 +00:00
Guido Cella 9d2a6dc302 player: add cover-art-whitelist option
This allows more fine grained control over which cover art to load. With
--cover-art-auto=exact and --cover-art-whitelist=yes, you can now load
cover art with the exact media filename and the whitelisted filenames,
but not cover art that contains the media filename
(--cover-art-auto=fuzzy).
2022-04-21 16:42:27 +00:00
hooke007 c317abbb63 DOCS: fix the typo of --sub-justify 2022-04-21 16:04:50 +00:00
hooke007 7b5c6dfd57 DOCS: correct --sub-shadow-color 2022-04-21 16:04:50 +00:00
Guido Cella 120989f56a DOCS/{mpv,options}: document the watch later functionality
This adds a section to the documentation to explain how resuming
playback works, and in particular it explains how it affects which
playlist entry mpv starts playing from, since this feature was only
implied in the --playlist-start documentation.

It also groups the documentation of the watch later options together to
make them easier to find.
2022-04-21 15:07:56 +00:00
Dudemanguy cd1b04411f vo_wlshm: use draw_frame instead of draw_image
draw_image is an old API that was deprecated long ago. However when
wlshm was originally added, it used draw_image. There's no particular
reason for this and it can trivially be switched to draw_frame instead.
This has some real advantages (notably --vo=wlshm --idle --force-window
actually works).
2022-04-21 14:47:43 +00:00
Dudemanguy 8d0c1c8be0 mpv.desktop: add japanese translation 2022-04-21 14:47:24 +00:00
Mia Herkt a2d86333f4 ci: switch Tumbleweed build to openSUSE container registry 2022-04-19 05:19:31 +02:00
Jan Ekström 305332f8a0 vd_lavc: fixup unchecked usage of AV_CODEC_EXPORT_DATA_FILM_GRAIN
This fixes build failures with avcodec 58.113.100 or before,
matching FFmpeg release versions 4.0 to 4.3.

This flag was added in between avcodec 58.113.100 and 58.114.100
during the FFmpeg 4.4 development cycle. It lacks its own version bump,
so instead a check for the define is utilized instead.

Additionally, warn the user if they request GPU film grain with
too old of an FFmpeg.

Fixes #10088
2022-04-13 00:52:08 +03:00
Jan Ekström 1a597ea987 vd_lavc: fix decoder initialization when no VO is available
The VO is available during decoder initialization mostly for direct
rendering purposes, so if f.ex. a complex filter chain is utilized,
there is no video renderer information available via
mp_filter_find_stream_info during creation of the decoder filter.

Thus, check for whether the VO is available before attempting to
check the capabilities flag from it.

Additionally - to simplify logic - makes explicitly requesting GPU
film grain to always disable decoder film grain functionality. The
warning is still shown if the VO is available and no support for
film grain application is available.

Fixes #10079
2022-04-11 23:54:22 +03:00
Jan Ekström eddc0bfe25 vd_lavc: remove duplicate vd_ffmpeg_ctx pointer from init_avctx
Seems like in some functions this was called p and in others ctx,
and thus it was added as the `p` pointer was not available.
2022-04-11 23:54:22 +03:00
Dudemanguy 5774ce759a wayland: use wl_output v4 for --fs-screen-name
In wayland 1.20.0, a couple of new events, name and description, were
added to the interface. Description is not particularly useful, but name
returns back nice names for the output like "DP-1" and so on. It makes
sense to use these for fs-screen-name and prefer them over the model
name (old way of doing it) if they are available. The only problem is
that 1.20.0 is pretty new so old distros aren't going to have it anytime
soon. Deal with this by adding some defines.
2022-04-11 18:21:14 +00:00
Dudemanguy 6158bb5be2 x11: avoid wasteful rendering when possible
Because wayland is a special snowflake, mpv wound up incorporating a lot
of logic into its render loop where visibilty checks are performed
before rendering anything (in the name of efficiency of course). Only
wayland actually uses this, but there's no reason why other backends
(x11 in this commit) can't be smarter. It's far easier on xorg since we
can just query _NET_WM_STATE_HIDDEN directly and not have to do silly
callback dances.

The function, vo_x11_check_net_wm_state_change, already tracks net wm
changes, including _NET_WM_STATE_HIDDEN. There is an already existing
window_hidden variable but that is actually just for checking if the
window was mapped and has nothing to do with this particular atom. mpv
also currently assumes that a _NET_WM_STATE_HIDDEN is exactly the same
as being minimized but according to the spec, that's not neccesarily
true (in practice, it's likely that these are the same though). Anyways,
just keep track of this state in a new variable (hidden) and use that
for determing if mpv should render or not.

There is one catch though: this cannot work if a display sync mode is
used. This is why the previous commit is needed. The display sync modes
in mpv require a blocking vsync implementation since its render loop is
directly driven by vsync. In xorg, if nothing is actually rendered, then
there's nothing for eglSwapBuffers (or FIFO for vulkan) to block on so
it returns immediately. This, of course, results in completely broken
video. We just need to check to make sure that we aren't in a display
sync mode before trying to be smart about rendering. Display sync is
power inefficient anyways, so no one is really being hurt here. As an
aside, this happens to work in wayland because there's basically a
custom (and ugly) vsync blocking function + timeout but that's off
topic.
2022-04-11 18:14:22 +00:00
Dudemanguy fe6d9b6962 player: rearrange video sync opts/enums/defines
The video sync logic for mpv lies completely within its core at
essentially the highest layer of abstraction. The problem with this is
that it is impossible for VOs to know what video sync mode mpv is
currently using since it has no access to the opts. Because different
video sync modes completely changes how mpv's render loop operates, it's
reasonable that a VO may want to change how it renders based on the
current mode (see the next commit for an example).

Let's just move the video sync option to mp_vo_opts. MPContext, of
course, can still access the value of the option so it only requires
minor changes in player/video.c. Additionally, move the VS_IS_DISP
define from to player/core.h to common/common.h. All VOs already have
access to common/common.h, and there's no need for them to gain access
to everything that's in player/core.h.
2022-04-11 18:14:22 +00:00
Dudemanguy 2c2a856f25 wayland: unify visibility checking code
A bit of a personal pet peeve. vulkan, opengl, and wlshm all had
different methods for doing wayland's "check for visibility before
drawing" thing. The specific backend doesn't matter in this case and the
logic should all be shared. Additionally, the external swapchain that
the opengl code on wayland uses is done away with and it instead copies
vulkan by using a param. This keeps things looking more uniform across
backends and also makes it easier to extend to other platforms (see the
next couple of commits).
2022-04-11 18:14:22 +00:00
Jan Ekström 5edc49adc9 vo_gpu/d3d11: add message ID based log level mapping
This lets us remap various messages which might now be happening at
each frame onto the trace level, thus unaffecting the initial debug
log level.

Additionally - thanks to this ability - the previously globally denied
message queue abandonment messages can now be handled and mapped to
trace log level, as on that log level they may be of use.

Recommended by rossy and based on his libplacebo commit
6d72f6445566eddb0493447d0bda72d98a99d40c .
2022-04-11 17:56:02 +03:00
Jan Ekström 4b8e3f20bc vo_gpu/d3d11: mimic libplacebo backbuffer usage
Instead of always having the reference outside of calling resize,
request a backbuffer at start and relieve the backbuffer at
submission for presentation.
2022-04-11 17:56:02 +03:00
Jan Ekström 6102d2bd78 vo_gpu/d3d11: enable receival of color depth without active backbuffer
Query the description of the swap chain, which should in all theory
contain the format of the backbuffer. Then utilize a newly added
ra_d3d11 function to map the format to an ra_format. After that,
utilize the depth of the first plane of the format, as previously.
2022-04-11 17:56:02 +03:00
Jan Ekström b5b5098d48 vo_gpu/d3d11: add helper function to get ra_format from DXGI_FORMAT 2022-04-11 17:56:02 +03:00
Niklas Haas 26a3a06861 vo_gpu_next: switch to unpooled hwdec mapping
This makes use of the new frame acquire/release callbacks to hold on to
hwdec images only as long as necessary. This should greatly improve the
smoothness/efficiency of hwdec interop, by not holding on to them for
longer than needed.

This also avoids the need to pool hwdec mappers altogether.

Should fix #10067 as well, since frames are now only mapped when we
actually use them.
2022-04-11 15:43:51 +02:00
Dudemanguy 2cafe5137f x11: fix screen-name option
9a7b2015e1 added the --screen-name option
for x11, but it was unfortunately broken. The commit does correctly
handle vo_x11_update_screeninfo and select the correct screen. However,
vo_x11_sizehint was missed. Specifically, the force_pos bool was always
false because it only took into account --screen being set and not
--screen-name. To fix this, just add an extra condition to the force_pos
bool so it becomes true if there's a string in --screen_name. Fixes
issue #9877.
2022-04-08 19:34:53 +00:00
Oğuz Ersen 3a934da1c7 mpv.desktop: add turkish translation 2022-04-08 19:34:30 +00:00
Guido Cella 4d12dfb75a options.lua: remove unused function
val2str isn't used anywhere. Its only use was removed in dd3e52fe68,
when it was still part of osc.lua.
2022-04-08 19:20:49 +03:00
Guido Cella d6affda0a7 options: add osd-playing-msg-duration 2022-04-07 22:13:50 +00:00
Olivier Perret 86dfdf083b egl_helpers: request at least 8 alpha bits if necessary
Previously on wayland, it would result in an egl config with only 2 alpha
bits, which technically matches what was requested, but is not very useful.
Fixes #9862
2022-04-07 16:56:36 +00:00
Guido Cella 4930667784 DOCS/input: mark chapter-list as writable 2022-04-07 16:21:22 +00:00
Philip Langdale 73a06ffae6 drm: context_drm_egl: add support for enabling VRR
Variable Refresh Rate (VRR), aka Freesync or Adaptive Sync can be used
with DRM by setting the VRR_ENABLED property on a crtc if the
connector reports that it is VRR_CAPABLE. This is a useful feature
for us as it is common to play 24/25/50 fps content on displays that
are nominally locked to 60Hz. VRR can allow this content to play at
native framerates.

This is a simple change as we just need to check the capability
and set the enabled property if requested by the user. I've defaulted
it to disabled for now, but it might make sense to default to auto
in the long term.
2022-04-05 20:56:36 -07:00
Lynne f61eda0f5e vd_lavc: add vo caps and option to set GPU film grain application 2022-04-05 15:02:18 +02:00
Lynne 4149cc2ce3 vo_gpu_next: apply film grain if such metadata is present 2022-04-05 15:02:18 +02:00
Lynne 7230550191 vf_format: support forwarding/stripping film grain metadata 2022-04-05 15:02:18 +02:00
Lynne 3194ed4b58 mp_image: support film grain parameters 2022-04-05 15:02:18 +02:00
Jan Ekström 083ae8e736 vd_lavc: hide a deprecation warning in already handled compatible code
The field has been deprecated, yet the upcoming new default is not yet
the default. Thus, until lavc major hits 60 and the default behavior
finally gets changed, we have to explicitly set the field's value.

The deprecation had already been handled by adding the required
version limitation for this code in bbbf3571ed ,
this change merely just removes the warning which would otherwise
appear until lavc major version gets bumped to 60.
2022-04-03 00:23:58 +03:00
Aman Karmani fb7b66ecf1 sub/osd: use atomic for osd_state.force_video_pts
this field is used only in a special vo draining edge case.

switching to an atomic reduces osd->lock contention
between the mpv core (in write_video) and vo threads
which are managing osd rendering manually (such as vo_rpi).

Signed-off-by: Aman Karmani <aman@tmm1.net>
2022-04-02 21:41:58 +03:00
Aman Karmani 76b9254b8b osdep/atomic: add mp_atomic_double
Signed-off-by: Aman Karmani <aman@tmm1.net>
2022-04-02 21:41:58 +03:00
Niklas Haas a76b1f4abd Revert "vo_gpu_next: remove unnecessary dependency"
This reverts commit 1c2dde91d3.

Fixes #10037
2022-04-01 23:43:47 +02:00
Thomas Weißschuh deedc3d418 ao_pipewire: Do not hold thread lock during loop stop
Stopping the thread is done using pw_thread_loop_stop(),
*which must be called without the lock held.*

Fixes #10033
2022-03-31 14:40:21 -07:00
Thomas Weißschuh 84dc9b1a02 ao_pipewire: fix resource lifetimes
We have to destroy the core before destroying the loop.
Also we have to lock the mainloop for operations on its objects.

Fixes #10003
2022-03-30 13:06:33 -07:00
Niklas Haas 1c2dde91d3 vo_gpu_next: remove unnecessary dependency
Pulling in <libplacebo/utils/libav.h> in particular triggers the
notorious _av_vkfmt_from_pixfmt linking issue when FFmpeg is built
without Vulkan support.
2022-03-29 15:42:09 +02:00
sfan5 84821dbcb6 lua: use correct chunkname when loading script files
This was brought up in #10007 and it turned out mpv did not follow Lua conventions.
2022-03-23 21:09:53 +01:00
Philip Langdale fcc81cd940 vo_gpu[_next]: hwdec: fix logging regression when probing
When I introduced the concept of lazy loading of hwdecs by img format,
I did not propagate the probing flag correctly, leading to the new
normal loading path not runnng with probing set, meaning that any
errors would show up, creating unnecessary noise.

This change fixes this regression.
2022-03-21 09:53:37 -07:00
Leo Izen f871294204 common/av_log: explicitly include version.h for required libraries
FFmpeg recently split version.h into version.h and
version_major.h, and no longer automatically includes
version.h in avcodec.h (and the other libraries). This
should allow mpv to build against ffmpeg git master. See
FFmpeg/ffmpeg@f2da2e1458

These headers are not new, so their inclusion should not affect
backwards compatibility.
2022-03-17 20:07:55 +02:00
Niklas Haas 5ef7bf7a20 vo_gpu_next: also include stride alignment in DR size
Fixes #9976
2022-03-14 15:45:36 +01:00
Niklas Haas 23e3be80dc vulkan: correctly inherit proc_addr pointer
As found out by @philipl, failing to pass this from the VkInstance to
the VkDevice is bad style. We might want to override the get_proc_addr
pointer in the future.
2022-03-13 23:39:31 +01:00
LaserEyess 7ac4b7dfe7 ao_sndio: fix parentheses warning
No change in logic, but wrap the LT operator and the && in parentheses
to silence the compiler warning.
2022-03-11 16:43:31 +01:00
Dudemanguy 199a7ebcd9 client API: also export mpv_stream_cb_add_ro
20c4036daa switched to hiding all symbols
by default and exporting the ones we want with MPV_EXPORT.
However, the mpv_stream_cb_add_ro function was missed and it is part of
the client API. Export it too. Fixes #9971.
2022-03-11 08:07:13 -06:00
Philip Langdale 919de742a4 vo_gpu: hwdec_vaapi: Improve logging when probing surface formats
Our logging here today is very poor. We don't make it clear what
formats we are probing, or even that a certain format failed in most
cases. In the case where we do log the error, we don't make it clear
which format it was that failed.

The end result is that we have no idea what the possible and final
format spaces are, which makes it very hard to debug whether things are
working correctly, or to work on supporting additional formats.
2022-03-10 15:12:12 -08:00
Philip Langdale d598ab2b24 DOCS/options.rst DOCS/vo.rst: Update discussion of hwdec usage
The documentation's current discussion of hwdec usage is out of date,
and unnecessarily pessemistic when applied to modern hardware. The
reality is that modern APIs on modern hardware produce reasonable
results and there's no need to pretend otherwise. The current language
that tries to drive people away from using hwdecs at all leads to them
making bad choices when they do try to use it.

Let's also make it clearer that users should use vo=gpu with hwdecs
rather than vo=vaapi or vo=vdpau. Even the existing admonitions have
proven insufficient, so let's strengthen that language.
2022-03-09 10:51:35 -08:00
Niklas Haas d936293c41 vo_gpu_next: fix crash when disabling DR at runtime
This code fails if we have DR buffers, but none of them correspond to
the current frame. Normally only happens if e.g. changing the decoder at
runtime, since DR buffers are not properly reinit in that case.
(Arguably a separate bug)
2022-03-08 13:49:03 +01:00
Niklas Haas 803bcaa12b vo_gpu_next: don't leak mpi on failed upload
The current map_frame() code fails to clean up after itself on the
failure paths. But if map_frame returns false, no cleanup code is ever
attempted. Add the relevant calls to clean up state manually,
throughout.
2022-03-08 13:42:13 +01:00
Niklas Haas 124dd4270d vo_gpu_next: properly keep track of DR allocations
So, turns out the approach in 7f67a553f doesn't work for all codecs. In
particular, sometimes lavc will internally allocate a new AVBuffer that
just points at the old AVBuffer but has a different opaque field for
some reason. In these cases, the DR metadata doesn't survive the
round-trip through libavcodec.

I explored several alternative ways of solving this problem, including
adding new mp_image fields, but in the end none of them survived the
round-trip through AVFrame and back. The `priv` and `opaque` fields
in respectively `mp_image` and `AVFrame` are also too heavily overloaded
to be of much help.

In the end, bite the bullet and use the same approach as done in
`vo_gpu`, which is to just keep track of a list of all allocations. This
is a really ugly way of doing things IMO, but ultimately, completely
safe.
2022-03-07 11:52:00 +01:00
Avi Halachmi (:avih) 836e87e6d4 hwdec: warn on unsupported hwdec option value
Previously, when mpv was invoked with unsupported hwdec value, such
as --hwdec=foobar, there was no indication that it doesn't exist.

The reason it's not validated during options parsing is that the name
is only evaluated when selecting hwdec for actual decoding, by
matching it against runtime list of names from ffmpeg.

Additionally, when selecting hwdec for decoding, matching the name
came after filtering by codec, hence overall never-matched-name did
not necessarily indicate it's unsupported (doesn't exist at all).

Now we check the name before filtering by codec, and when done,
warn if no hwdec with that name exists at all.

This means that an unsupported name will now generate such warning
whenever we try to choose a hwdec, i.e. possibly more than once.

It's much better than no notification at all, and arguably adequate
for a sort of configuration error (linked ffmpeg has no such hwdec
name) which we don't validate during option parsing.
2022-03-07 01:05:20 +02:00
Niklas Haas 7f67a553f6 vo_gpu_next: don't allocate dr_buf as part of the AVBufferRef
Some decoders, notably hevcdec, will unconditionally memset() the entire
AVBufferRef based on the AVBufferRef size. This is bad news for us,
since it also overwrites our `struct dr_buf`.

Rewrite this code to make it more robust - keep track of the DR buf
metadata in a separate allocation instead. Has the unfortunate downside
of technically being undefined behavior if `opaque` is not at least 64
bits in size, though, but avoids this issue.

Maybe there's a better way for us to unconditionally keep track of DR
allocation metadata. I could try adding it into the `mp_image` itself.
Maybe on a rainy day. For now, this works.

Fixes #9949
Might fix #9526
2022-03-06 15:53:47 +01:00
Niklas Haas 1c49d5735d hwdec: fix out-of-date preprocessor variable name
This was renamed to HAVE_VAAPI_LIBPLACEBO.
2022-03-04 14:33:26 +01:00
Avi Halachmi (:avih) b15b3f6711 ytdl_hook.lua: consider any subprocess status != 0 as error
Previously only status<0 was considered as error, but status>0 is
also an error (the process exit code). Change to status != 0.

This likely makes little to no difference in practice, because if
stdout is empty or can't be parsed as JSON then it's considered
an error anyway, but still, this is more correct.

Also, on error, add the complete subprocess result to the verbose log.
2022-03-03 15:01:40 +02:00
James Ross-Gowan 11f0947d46 vo_gpu_next: add D3D11 RA texture wrapping/unwrapping for hwdec
This mostly copies the API used in the GL backend.
2022-03-03 13:06:05 +01:00
Niklas Haas dfe846f9de vo_gpu_next: add support for hardware decoding
There are two major ways of going about this:

1. Expose the native ra_gl/ra_pl/ra_d3d11 objects to the pre-existing
   hwdec mappers, and then add code in vo_gpu_next to rewrap those
   ra_tex objects into pl_tex.

2. Wrap the underlying pl_opengl/pl_d3d11 into a ra_pl object and expose
   it to the hwdec mappers, then directly use the resulting pl_tex.

I ultimately opted for approach 1 because it enables compatibility with
more hardware decoders, specifically including ones that use native
OpenGL calls currently. The second approach only really works with
cuda_vk and vaapi_pl.
2022-03-03 13:06:05 +01:00
Niklas Haas c13f5f24cd manpage: add vo_gpu_next wiki link to manpage
I was initially hesitant to link to an external article from the manpage
but a lot of other places in the man page already do something like
this, and it really makes more sense to have this as a wiki article
rather than trying to keep the manpage up-to-date by hand, since this
evolves quickly and the two are expected to converge over time.
2022-03-03 13:06:05 +01:00
Niklas Haas a71baf7c63 vo_gpu_next: configure the VO queue size dynamically
This avoids decoding/caching more frames in advance than necessary. In
particular, this is very important for hwdec, which generally can't have
too many decoded frames in a pool at the same time.
2022-03-03 13:06:05 +01:00
Niklas Haas 4b7671cf36 vo_gpu_next: expose EGLDisplay to pl_gpu
Straightforward and enables the import/export of dmabufs.
2022-03-03 13:06:05 +01:00
Niklas Haas d4fc44e711 vo_gpu: move hwdec loading code to common helper
So I can reuse it in vo_gpu_next without having to reinvent the wheel.
In theory, a lot of the stuff could be made more private inside the
hwdec code itself, but for the time being I don't care about refactoring
this code, merely sharing it.
2022-03-03 13:06:05 +01:00
Niklas Haas bb434a60ed hwdec: release images as soon as possible after mapping
We don't need to hold on to buffers longer than necessary. Doesn't
matter for vo_gpu but greatly matters for vo_gpu_next, since it persists
hwdec mapped textures for longer periods.

Unfortunately, only provides benefits for hwdecs which do explicit
copies in their decode path, which currently just means cuda and
d3d11va.
2022-03-03 13:06:05 +01:00
Niklas Haas e2c02a4ce3 hwdec_vaapi_vk: rename to vaapi_pl
There's really nothing vulkan-specific about this hwdec wrapper, and it
actually works perfectly fine with an OpenGL-based ra_pl. This is not
hugely important at the time, but I still think it makes sense in case
we ever decide to make vo_gpu_next wrap OpenGL contexts to ra_pl instead
of exposing the underlying ra_gl.
2022-03-03 13:06:05 +01:00
Niklas Haas 4387f3bcd0 hwdec_vaapi_gl: properly zero initialize priv struct
Easiest way is by just using a designated struct initializer. If we
don't, `p->images` ends up inheriting random data, which leaks into e.g.
eglDestroyImageKHR.

It's a small miracle this never blew up before. Or maybe it did. Who
knows.
2022-03-03 13:06:05 +01:00
Philip Langdale 7d08201a8f filters: Re-add vavpp deinterlacing auto-filter
A few years ago, in 25e70f4743, we
disabled the vavpp deinterlacing auto-filter on the basis that it
caused crashes on _some_ hardware with _some_ driver version(s). But
since then, the situation has improved. There is still a limitation
where you can't turn deinterlacing on on the fly with AMD, but it
doesn't crash anymore (That is #7388).

So, given that AMD users have to set up the deinterlacing filter
manually either way, let's re-add the auto-filter for Intel users.
2022-03-02 16:21:04 -08:00
George Brooke 1a3e85ec33 ytdl_hook: fix url_is_safe to match URL protocols properly
Some youtube_dl extractors retrieve URLs which contain other URLs
inside of them, for example Funimation, like this:
https://example.com/video?parameter=https://example.net/something

The url_is_safe function uses a pattern to match the protocol at the
start of the URL. Before this commit, this pattern was not compliant
with the URL spec (see the definition of "A URL-scheme string"):
https://url.spec.whatwg.org/#url-writing
Therefore it would match any characters, including "://", until the
last occurence of "://" in the string. Thus the above URL would match
https://example.com/video?parameter=https
which is not in safe_protos so the video will not play.

Now the protocol can only start with a letter and only contain
alphanumerics, "." "+" or "-" as the spec says, so it will only match
the first protocol in the URL ("https" in the above example.)
Previously the URL also had to contain "//" after the ":". Data URLs
do not contain "//": https://datatracker.ietf.org/doc/html/rfc2397
so now the pattern does not look for "//", only ":".
2022-03-02 20:59:33 +02:00
Niklas Haas b1fb4b783b vo_gpu_next: remove/simplify plane flipping hacks
libplacebo v198 fixed this properly by adding the ability to flip planes
directly, which is done automatically by the swapchain helpers.

As such, we no longer need to concern ourselves with hacky logic to flip
planes using the crop. This also removes the need for the OSD coordinate
hack on OpenGL.
2022-02-25 22:13:20 +01:00
Niklas Haas 626fa506d5 vo_gpu_next: avoid rendering subtitles as HDR/wide gamut
Fixes #9911
2022-02-25 14:22:03 +01:00
Niklas Haas e6c18641bd mp_image: fix mp_image_plane_w/h
These helpers, for some reason, decided to round the returned values up
to multiples of the nearest plane alignment. This logic makes no sense
to me, and completely breaks any sort of oddly-sized mp_image.

This logic was introduced, presumably in error and without real
justification, as part of a major refactor commit (caee8748), As far as
I can tell, removing it again doesn't regress anything.

Fixes several serious bugs including buffer underflows and GPU crashes
in vo_gpu and vo_gpu_next.
2022-02-24 18:36:28 +01:00
Avi Halachmi (:avih) 57f42cee84 stats.lua: page 2 - frame timing: use fixed display order
Page 2 displays the frame timing info for each type (currently "Fresh"
and "Redraw"), but since they're unordered keys of a map, their
iteration order and hence their order on screen could (and did) change
depending on $things, which was annoying.

haasn thinks none of them should be considered more important (and
therefore maybe worthy of being displayed on top), so we go with
lexicographic order, which currently means that "Fresh" is first.

Fixes #9901
2022-02-23 02:20:49 +02:00
Avi Halachmi (:avih) 37927b65f7 stats.lua: graphs: fix bad rendering due to division by 0
This fixes two potential divisions by 0 at generate_graph(...):
- If v_avg is (given and) 0.
- if v_max is 0.

The former doesn't seem to happen in practice because v_avg is only
used at one generate_gpah call, where it's apparently not 0.

The latter triggers if all the graph values are 0 (hence v_max is
also 0).

The implication of these divisions by 0 is an invalid y-value which
ends up at the ASS coordinates string for the graph inner content.

On linux the value ends as "nan" (luajit) or "-nan" (lua 5.1/5.2), and
on Windows it's "nan" (luajit) or "-1.#IND00" (lua 5.1/5.2), maybe due
to msvcrt's snprintf.

All these strings are wrong as ASS numbers, but due to luck in how
libass parses the coordinates, "nan" and "-nan" result in empty graph
(which looks OK for "all values are 0"), while "-1.#IND00" is parsed
as -1, which breaks the graph rendering (affects other graphs too).

One example of "all values are 0" is at page 0 (internal performance
graphs) on Windows - because the cpu metrics don't work.
So this fixes at least page 0 on Windows with lua 5.1/5.2.

While at it, move the scale calculations to one place, which now
avoids division by 0, instead of duplicating this calculation.

In the future, we can consider improving the generate_graph API:
- It needs one peak value, but takes 3 (v_max, v_avg, scale) which
  are meshed into one final value.
- v_avg is only used in 1 of 6 call sites, but at the middle of the
  arguments, so all other call sites need to pass explicit "nil".
- "scale" is arbitrary and used to leave some space at the top of the
  graph. 5 places use 0.8, one uses 0.9. Could probably be unified.
2022-02-21 16:05:02 +02:00
Niklas Haas fbe154831a vo_gpu_next: refactor subtitle rendering
Render subs at the output resolution, rather than the video resolution.
Uses the new APIs found in libplacebo 197+, to allow controlling the OSD
resolution even for image-attached overlays.

Also fixes an issue where the overlay state did not get correctly
updated while paused. To avoid regenerating the OSD / flushing the cache
constantly, we keep track of OSD changes and only regenerate the OSD
when the OSD state is expected to change in some way (e.g. resolution
change). This requires introducing a new VOCTRL to inform the VO when
the UPDATE_OSD-tagged options have changed.

Fixes #9744, #9524, #9399 and #9398.
2022-02-21 12:01:44 +01:00
Dudemanguy 27c38eac10 options: add always to stop-screensaver
The stop-screensaver option is currently limited to a simple yes/no
option. While the no option does always disable mpv trying to stop the
screensaver, yes does not mean the screensaver is always stopped. The
screensaver will be enabled again depending on certain conditions (like
if the player is paused). Simply introduce a new value for this option,
always, which does exactly what the name implies: the screensaver will
always be disabled.
2022-02-18 22:04:08 +00:00
Guido Cella beac97ba07 DOCS/input: document subprocess more clearly
- Make it clearer that playback_only affects subprocess' behavior when
  the playback of the current playlist entry terminates, rather than
  when mpv quits.
- Explain when status is positive and when it is negative.
- Replace "exited gracefully" in status' and error_string's
  documentation with "terminated normally" so it can't be misinterpreted
  as exiting successfully.
- Reword the playback_only warning
2022-02-18 19:39:10 +02:00
Guido Cella b89ca0c552 DOCS/input: fix typo 2022-02-18 19:39:10 +02:00
Philip Langdale 5186651f30 vo_gpu: hwdec: load hwdec interops on-demand by default
Historically, we have treated hwdec interop loading as a completely
separate step from loading the hwdecs themselves. Some hwdecs need an
interop, and some don't, and users generally configure the exact
hwdec they want, so interops that aren't relevant for that hwdec
shouldn't be loaded to save time and avoid warning/error spam.

The basic approach here is to recognise that interops are tied to
hwdecs by imgfmt. The hwdec outputs some format, and an interop is
needed to get that format to the vo without read back.

So, when we try to load an hwdec, instead of just blindly loading all
interops as we do today, let's pass the imgfmt in and only load
interops that work for that format. If more than one interop is
available for the format, the existing logic (whatever it is) will
continue to be used to pick one.

We also have one callsite in filters where we seem to pre-emptively
load all the interops. It's probably possible to trace down a specific
format but for now I'm just letting it keep loading all of them; it's
no worse than before.

You may notice there is no documentation update - and that's because
the current docs say that when the interop mode is `auto`, the interop
is loaded on demand. So reality now reflects the docs. How nice.
2022-02-17 20:02:32 -08:00
Alex B bc9805c71a ao_pipewire: fix ao-volume handling
Pass channel volumes to `pw_stream_set_control` as array.
This is correct calling conventions and prevents
right channel muting every time ao-volume property is changed.

Terminate `pw_stream_set_control` calls with 0.
2022-02-11 11:27:57 -08:00
Niklas Haas ef83498aef vo_gpu_next: don't crash on negative plane strides
This is an annoying special case only really needed because of the
`vflip` filter. mpv handles this by directly adjusting the plane
transform. The libplacebo API, unfortunately, does not allow passing the
required information for this to work smoothly.

Long-term I plan on adding support for plane flipping in libplacebo
directly, but for the meantime, we will have to work-around it by moving
the flipping to the whole-image `crop` instead. Not an ideal solution
but better than crashing.

Fixes #9855
2022-02-11 05:12:09 +01:00
James Ross-Gowan 4629fe577f vo_gpu: d3d11_helpers: don't create UNORDERED_ACCESS backbuffers in Win7
We're getting bug reports that the recent change to add extra usage
flags to swapchain buffers (for gpu-next) breaks mpv on some Windows 7
systems, and it seems like this is only happening with flip-model
swapchains.

Creating swapchains with DXGI_USAGE_UNORDERED_ACCESS should be valid. At
least, it's not specifically disallowed, unlike some other flags[1]. So,
just disable it for flip-model swapchains in Windows 7, rather than
disabling it everywhere.

[1]: https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-usage
2022-02-09 17:20:07 +02:00
Dudemanguy f9bf6a601c meson: remove horrifying macos luajit hack
See the previous commit for the full explanation. Basically, luajit 2.0
has a bad pc file on macos that causes libmpv to fail during build. The
workaround was, if the os was darwin and luajit was found, to save a
full luajit dep and a partial luajit dep with the link args removed. The
partial dep was used for compiling libmpv, and the full dep was used for
the actual mpv executable. This worked and was needed for the CI to pass
but it sucked. Since the previous commit now makes the CI grab lua 5.1,
we don't need all this crap anymore. Just delete it and treat the
dependency normally.

This does effectively mean that building libmpv with luajit 2.0 on macOS
will no longer work with the meson build. However libraries not being
built correctly is not a mpv-specific issue. The waf build will succeed
for some reason, but it has known issues and it would be better if it
just failed honestly. An upstream developer said years ago that that
macOS users should use the 2.1 branch (and there's no release of
course). In any case, no macOS user should be building mpv with luajit
2.0, so we shouldn't be going out of our way to support this.

https://github.com/mpv-player/mpv/issues/7512
https://github.com/LuaJIT/LuaJIT/issues/521#issuecomment-562999247
2022-02-07 21:17:12 +00:00
Dudemanguy 649556b2b6 github/workflows: use lua 5.1 on macos
LuaJIT is still actively developed, but upstream is allergic to making
new releases for whatever reason. The last tagged release was in May of
2017, so we probably shouldn't expect a new release anytime soon. Now
for mpv, this doesn't really matter except in the case of macOS where
2.0.5 is actually a bit broken (and of course the CI uses luajit). More
specifically, the 2.0.5 pc is broken and has a "-pagezero_size 10000"
flag which causes libmpv to fail (only executables are allowed to use
this). This magically works on waf. It's possible that it just happens
to ignore the link arguments. However on the meson build, this is broken
and led to a really ugly hack using a partial dependency so both mpv and
libmpv succeed. Fortunately, the 2.1 luajit branch fixes this.
Unfortunately, there's no actual release.

Instead, just use Lua 5.1. Note that lua 5.1 is technically deprecated
in homebrew, but the chances of this going away is pretty slim since
everyone knows that new lua versions are not backwards compatible.
Anyways, using 5.1 works fine and lets us get rid of a terrible hack in
the meson build. People really shouldn't be using 2.0 LuaJIT anyway.
2022-02-07 21:17:12 +00:00
Guido Cella 25bd428393 DOCS/mpv: improve vf=rotate examples
We have a few examples with vf=rotate=90, but libavfilter's rotate
accepts radians - not degrees, so a value of 90 is valid but misleading
because it's not 90 degrees.

Change the value of 90 at those examples.

Also replace "vf-add=hflip" with "vf add hflip", since that example
lists commands, not options, to run.
2022-02-07 22:14:51 +02:00
Dudemanguy 34e0a212cd wayland: partially fix drag and drop handling
Drag and drop in wayland is weird and it seems everyone does this
slightly differently (fun). In the past, there was a crash that
occured (fixed by 700f4ef5fa) which
involved using the wl_data_offer_finish in an incorrect way that
triggered a protocol error (always fatal). The fix involved moving the
function call to data_device_handle_drop which seemingly works, but it
has an unfortunate side effect. It appears like GTK applications (or at
least firefox) close the pipe after this function is called which makes
it impossible for mpv to read data from the fd (well you could force it
open again in theory but let's not do that). Who knows if that was the
case when that commit was made (probably not because I'd think I would
have noticed; could just be a dummy though), but obviously having broken
dnd for a major application isn't so fun (this works with QT and
chromium anyway).

Ideally one would just simply check the pipe in data_device_handle_drop,
but this doesn't work because it doesn't seem the compositor actually
sends mpv the data by then. There's not actually a defined event when
you're supposed to be able to read data from this pipe, so we wait for
the usual event checking loop later for this. In that case,
wl_data_offer_finish needs to go back into check_dnd_fd, but we have to
be careful when calling it otherwise we'd just commit protocol errors
like before. We check to make sure we even have a valid wl->dnd_offer
before trying to indicate that it is finished and additionally make sure
there is a valid dnd_action (after checking the fd, it's always set back
to -1).

This doesn't fix everything though. Specifically, sway with
focus_follows_mouse (the default) and GTK as the data source still
doesn't work. The reason is that when you do a drag and drop in sway
with that option on, a new wl_data_device.data_offer event is sent out
instantly after the drop event. This happens before any data is sent
across the fd and before mpv even has a chance to check it. What GTK
does, when getting this new data_offer event, is close the pipe
(POLLHUP). This means mpv can't read it when we reach the event loop and
thus no data is ever read and broken drag and drop. From the client
side, this isn't really fixable since the wayland protocol doesn't have
a clear indication of when clients are supposed to read from the fd and
both the compositor and data source are doing things totally out of our
control. So we'll consider this weird case, "not our bug" at least. The
rest should work.
2022-02-07 17:54:03 +00:00
Thomas Weißschuh 09343bc86e ao_pipewire: validate pod creation
Our allocated buffers should be big enough, but add some errorhandling
just in case.
2022-02-06 22:44:40 -08:00
Thomas Weißschuh b7a71ea706 ao_pipewire: add support for device selection 2022-02-06 22:44:40 -08:00
Jan Ekström c72b897e9c vo_gpu_next/context: get graphics API-specific contexts from pl_gpu
By receiving the graphics API-specific contexts from the generic
pl_gpu instance, it is not necessary to store them separately.
As the current priv struct stores nothing else, this allows its
removal. This removal cleans up related compiler warnings regarding
unused variables in case of opengl and d3d11 being disabled in
mpv/libplacebo.

Functions to receive the underlying vulkan,gl,d3d11 structure were
added in libplacebo version 4.182. Our current requirement for
gpu-next is 4.190, and thus we can freely utilize these helper
functions.
2022-02-06 22:59:14 +02:00
Jan Ekström 8c4cb84f9e vf_format: simplify frame type checking after addition of DoVi option
We only wish to touch actual video frames, which should have an
allocated image attached to them, so just check the frame type
early, and exit by passing through such non-video frames to further
filters in the chain without attempting to process them.

Fixes a crash in case of non-video (EOF/NONE) frames being passed
onto the filter when the dovi option was set to false since
05ccc51d53 .
2022-02-06 14:45:50 +02:00
Philip Langdale 240340d60a vo_gpu: hwdec_vaapi: Don't probe formats for irrelevant endpoints
While testing support for the exotic formats used by Intel vaapi for
4:2:2 and 4:4:4 surfaces, I realised that we were enumerating all
endpoints and checking formats for them. The problem with this is
that decoding (VLD) endpoints are only a subset of what vaapi exposes.

All the encoding endpoints are there too, and there is also the
None profile that we don't care about, but which generates ffmpeg
warnings if you try and examine it.

So, let's only look at VLD endpoints. This will speed things up a
little bit and make the logging less noisy.
2022-02-06 14:40:18 +02:00
sfan5 83f1c87676 ci/appveyor: fix package install line
It appears MinGW switched their pkg config implementation from pkg-config to pkgconf,
causing all builds to fail because we requested the former.
2022-02-06 12:00:21 +01:00
Avi Halachmi (:avih) 0197729949 osc.lua: seekbar hover: speed-up chapter access
This speeds up chapter name access while hovering the seekbar:

- Fetch the chapter-list property using observation rather than on
  every render while hovering the bar. Property access, especially
  with potentially lots of values (chapters), can be expensive-ish,
  and can involve locking, so the less per-render the better.

- Sort the list once (on change) to simplify the iteration logic when
  searching the chapter which matches the mouse position. It's still
  O(N) (no binary search currently), but with less work.

The cached sorted list is stored at the state. While there are other
places which access this property and could use this cache, for now we
don't touch them, because they're not performance-critical (on init
for the chapter markers, on ch_{prev,next} button click for OSD).

Caching properties using observation instead of using mp.get_property
can indeed speedup other places too, but it should be part of a system
rather than implemented per-property. Maybe some day.
2022-02-06 11:02:39 +02:00
Avi Halachmi (:avih) 7849a36beb js: utils.get_user_path: make wrapper of expand-path
When utils.get_user_path was added, the expand-path command didn't
exist. Now it does, so remove the C code, make it a trivial wrapper.

Keep this function for backward compat to not break scripts, but
technically it's not required anymore.
2022-02-04 12:53:16 +02:00
Niklas Haas 5d31c7310c libplacebo: switch to new target format API
`target_dummy` got deprecated in version v4.169. We unfortunately have
to hide this behind an #if for the time being.
2022-02-03 18:22:14 +01:00
Niklas Haas d59eb58007 libplacebo: switch to new GPU limits APIs
`caps` is deprecated, and replaced by individual fields in
`pl_glsl_version` / `pl_gpu_limits`.
2022-02-03 18:22:14 +01:00
Niklas Haas b2958670a3 libplacebo: switch to v4 naming convention
All of these const struct pointers got typedefs, clean up the code
accordingly.
2022-02-03 18:22:14 +01:00
Niklas Haas 88c6c84b64 libplacebo: update log helpers
Use the pl_log APIs introduced in libplacebo v4, replacing the
deprecated pl_context concept.
2022-02-03 18:22:14 +01:00
Niklas Haas e8e89fae38 libplacebo: bump minimum dependency to 4.157
This has been the latest stable release for about half a year now. This
version in particular lets us get rid of all the deprecation warnings in
the older code. (See the following commits)
2022-02-03 18:22:14 +01:00
Niklas Haas 9d1f48bda2 vo_gpu_next: create shader cache dir if missing
Failing to do this results in the shader cache not actually ever being
written, ergo no shader caching being done. Oops.
2022-02-03 18:22:14 +01:00
Niklas Haas a2b147abc6 build: rename libplacebo version check
Rename from "libplacebo-v4" to "libplacebo-next" to more closely capture
the intent, since this will become libplacebo v5 eventually (tm).
2022-02-03 18:22:14 +01:00
Julian Orth c25129339d wayland: always start rendering after a resize
The wayland backend contains logic to detect if the window is hidden. If
so, we skip rendering as an optimization. However, if we receive
multiple resize events in rapid succession, we will send the compositor
new buffers faster than the refresh rate of the monitor.  Therefore the
compositor will not send us frame events which we incorrectly interpret
as the window being hidden.

Once the last buffer has actually been rendered, the compositor sends us
a frame event. However, if at that point playback is paused, there is no
logic to restart rendering of frames that we skipped due to the above
optimization.  Therefore we never send the compositor new buffers
corresponding to the new size of the window and the surface will either
be too small or too large.

The simplest solution is to always render a few frames after we receive
a resize event.
2022-02-03 16:15:59 +00:00
Avi Halachmi (:avih) ddef9eb52d DOCS/options.rst: fix typo (double "aspect") 2022-02-03 12:48:17 +02:00
garamond13 67a2b2852c filter kernels: add cosine window
filter kernels: add cosine window
2022-02-03 01:25:50 +01:00
Jan Ekström 899850bedc wscript: bump libplacebo version requirement to 4.190
Was done in meson.build as part of
a9cb2e2821 , but the waf wscript
was missed.

This brings the two files in sync again.
2022-02-02 22:53:32 +02:00
Jan Ekström 053f10003c vo_gpu_next: initial attempt at adding d3d11 support 2022-02-02 22:53:32 +02:00
Jan Ekström 723a2ba762 vo_gpu_next/context: common'ize things that would be common for non-vulkan
This prepares us to not duplicate all of this code for d3d11.
2022-02-02 21:48:01 +02:00
Jan Ekström 13d0df7c21 vo_gpu/d3d11: enable access to the underlying ra_ctx swap chain
This enables us to utilize it from gpu-next.
2022-02-02 21:48:01 +02:00
James Ross-Gowan 3c4b8433dc vo_gpu/d3d11: add more usage flags to the swapchain images
vo_gpu_next and libplacebo expect swapchain images to be able to be
blitted to, which for libplacebo on FL11_0 and up means they have to
have DXGI_USAGE_UNORDERED_ACCESS, since libplacebo uses a compute shader
to emulate certain kinds of blits. For libplacebo's benefit, set all
applicable usage flags on swapchain images.
2022-02-02 21:48:01 +02:00
Jan Ekström 65f9a688a4 vo_gpu/d3d11: early exit in start_frame if output fbo is nullptr 2022-02-02 21:48:01 +02:00
Avi Halachmi (:avih) 555c15efba win32: apply geometry position to content instead of window
The docs specify that the +-X+-Y geometry values position the content.
This used to work correctly but got broken at 8fb4fd9a .
Geometry size is unaffected - this only concerns position.

Commit 8fb4fd9a made it center the window rather than the content by
taking the borders into account during positioning, but forgot to make
an exception when a position is specified explicitly.

This commit adds this exception, and now if a specific position is
requested then the borders are ignored, and the content is positioned
correctly.
2022-02-02 13:05:55 +02:00
Andrew Krasavin 8172c501ac meson: fix libdl existence check for *bsd systems 2022-02-02 02:34:49 +00:00
CogentRedTester 712ef65e2a auto_profiles.lua: don't warn if profile-restore=default
The code assumed that the value of the profile-restore field is
"default" for such profiles, but the C implementation is such
that the field is intentionally omitted in such case.

This resulted in incorrectly trying to restore such profiles. However,
there are no stored values with profile-restore=default, so it only
resulted in a harmless warning, but otherwise behaved correctly (i.e.
nothing is restored).

Fix the condition by taking into account that missing field means
"default", so that it doesn't try to restore in such case, and
avoid the warning.
2022-01-30 15:13:10 +02:00
Avi Halachmi (:avih) 9fd9239990 DOCS/input.rst: profile-list: profile-restore could be missing
Currently the profile-restore field is intentionally omitted if it
holds the default value (i.e. no values are stored for the profile,
and trying to restore would only warn).

See m_config_get_profiles at command.c .
2022-01-30 15:13:10 +02:00
Dudemanguy 4d3ebb9d83 meson: add version check to wayland-protocols
This was mistakenly left out. mpv requires at least 1.15 for the
xdg-decoration protocol. This just matches the waf build.
2022-01-29 12:12:45 -06:00
Dudemanguy 19dd61fa19 wayland: always resize when scale changes on surface enter
a02901cae7 changed how mpv was handling
wl_surface_set_buffer_scale. It's correct in that constantly setting the
surface scale on every resize (which mpv was previously doing) is
unneccessary and not right. However, it introduced a slight regression
if someone moved a surface to a new monitor with the same resolution but
a different scale. It did not trigger a resize and thus the video would
have incorrect dimensions. A later refactor changed how things looked
inside here, but this regression wasn't fixed. A resize should always be
triggered if the scale changes in this surface event. Fixes #9426.
2022-01-27 18:34:17 -06:00
Ryan Hendrickson 9098ae5a16 wayland: support extra mouse buttons
Mouse button event codes above `BTN_EXTRA` (the ones currently defined
in `input-event-codes.h` are `BTN_FORWARD`, `BTN_BACK`, and `BTN_TASK`)
are mapped to `MP_MBTN9` and up. (Reminder that due to historical
reasons, the names `BTN_FORWARD` and `BTN_BACK` are completely
misleading; the real forward and back buttons are `BTN_SIDE` and
`BTN_EXTRA` and are already mapped correctly by mpv.)

This functionality is analogous to what the X11 backend supports in
`video/out/x11_common.c` and what the Cocoa backend supports in
`video/out/cocoa/events_view.m`.
2022-01-28 00:14:56 +00:00
Dudemanguy 073fbd98ee wayland: actually handle 0x0 resizes correctly
According to the xdg-shell protocol spec, a 0x0 size from the compositor
means that "the client should decide its own window dimension". We were
not doing this correctly. What should happen is that mpv should simply
reuse the old window size if it is not maximized or fullscreened. This
should work on all (reasonably recent) versions of mutter and an
compositor that follows the spec.

https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/xdg-shell/xdg-shell.xml#L1050
2022-01-27 15:15:43 +00:00
Dudemanguy 5bcf061744 Revert "wayland: ignore 0x0 resizes"
So actually according to the xdg-shell spec, a 0x0 resize is meant to
indicate that "the client should decide its own window dimension".
Previously, this just accidentally worked. In mutter 41.3, they changed
how 0x0 resizes were sent and what actually happened was that mpv tried
to resize itself to 0x0. This was obviously broken, so the reverted
commit naively just ignored 0x0. It actually seemed to work, but it
ended up breaking older versions of mutter. It's also not exactly the
correct fix so it deserves a revert.

This reverts commit d16defac27.

https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/xdg-shell/xdg-shell.xml#L1050
2022-01-27 15:15:43 +00:00
Dudemanguy 8087e3371f build: remove aviocontext bytes_read check
This define was always just a stopgap for that two month period (August
2021 - October 2021) where the bytes_read field in ffmpeg was completely
missing. Before that time, it was a private member in a struct (which
mpv used). Afterwards, it officially became public. Fortunately, the
lack of this field never actually made it into a release, so it could
have only possibly affected people building from the master branch.
Since ffmpeg 5.0 came out recently, and it's been plenty of months since
that two month window, we can go ahead and drop this check. This
finishes up the work done in 78cfeee2b9.

Sidenote: the cached ffmpeg version in the mingw ci were from that time
period when the bytes_read field was missing. The N in the workflow is
bumped to force a full rebuild and fresh clone of ffmpeg.
2022-01-25 00:17:01 +02:00
Dudemanguy e809ef0441 x11: sanitize window title to UTF-8 for EWMH
Both _NET_WM_NAME and _NET_WM_ICON_NAME (part of Extended Window Manager
Hints) require that the string is UTF-8*. mpv was not doing this and
thus violating the spec. Just sanitize the title for these two atoms.
Note that XA_WM_NAME and XA_WM_ICON_NAME have no such requirement so
those atoms are left the same. Fixes #8812.

*: https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html
2022-01-24 15:07:00 +00:00
Dudemanguy 5b16fe4134 wayland: sanitize toplevel title to UTF-8
The xdg-shell protocol requires that the toplevel title is UTF-8*. Go
ahead and leverage existing mpv tools to sanitize the title. Fixes #9694

*: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/0aaf12157ede8fdf6eda49963da313bd1a7d930f/stable/xdg-shell/xdg-shell.xml#L638
2022-01-24 15:07:00 +00:00
Dudemanguy d16defac27 wayland: ignore 0x0 resizes
Apparently mutter can send us 0x0 resizes* for whatever reason. Probably
there's some interal reason why this occurs, but for us trying to resize
to 0x0 is obviously terrible and results in all kinds of brokenness.
Just ignore any 0 values. Fixes #9748.

*: https://gitlab.gnome.org/GNOME/mutter/-/issues/2091
2022-01-23 13:58:15 -06:00
Dudemanguy 93d77b781d version.py/version.sh: bump copyright year 2022-01-22 13:22:23 -06:00
Dudemanguy 95257eaa88 ci/build-freebsd: enable sndio ao during build
We have this ao again since #9298 so let's run it through the CI.
2022-01-22 19:06:31 +00:00
Andrew Krasavin b01598510f ao_sndio: bugfix and small refactoring for #8314
Changes:
  * fixed hangups in the loop function and in some other cases
  * refactoring according to @michaelforney's recommendations in #8314
  * a few minor and/or cosmetic changes
  * ability to build ao_sndio using meson
2022-01-22 18:44:34 +00:00
rim adc32e25e0 ao_sndio: add this audio output again
Changes:
- rewrite to use new internal MPV API;
- code refactoring;
- fix buffers size calculations;
- buffer set to auto;
- reset() - clean/reinit device only after errors;
2022-01-22 18:44:34 +00:00
Dudemanguy 024e0cd4c1 options: only apply sub-visibility to primary subs
Previously, the sub-visibility option changed the visibility of all
subtitles including secondary ones. This meant that it was not possible
to only display secondary subtitles while hiding the primary ones. This
modifies the sub-visibility option so that it only affects primary
subtitles which allows only secondary subtitles to be displayed.
2022-01-22 16:22:25 +00:00
Avi Halachmi (:avih) 9cddd73f67 Revert "options: add --sub-visibility=<primary-only|secondary-only>"
This reverts commit 04f0b0abe4.

It's not a good idea to unify the names only for visibility, while
keeping secondary-* for everything else.

This needs a bit more thought before we allow secondary sub to be
visible on its own.
2022-01-19 21:56:28 +02:00
Ripose 04f0b0abe4 options: add --sub-visibility=<primary-only|secondary-only>
Adds --sub-visibility choices 'primary-only' for only displaying the
primary subtitle track, and 'secondary-only' for only displaying
secondary subtitle track.

Removes --secondary-sub-visibility and displays a message telling the
user to use --sub-visibility=yes/primary-only instead.

These changes make it so that the default 'sub-visibility' bind 'v'
cycles through all the 'sub-visibility' choices, 'no', 'yes',
'primary-only', and 'secondary-only'.
2022-01-19 14:27:04 +00:00
chelobaka 1ab3f56df0 player: add thd (TrueHD) to whitelist of audio extensions 2022-01-19 14:00:05 +00:00
LaserEyess 471b3c2b59 player: fix parentheses warning with &&
Was tripping -Wparantheses as the && after the || was not explicitly
wrapped. However, due to operator precedence the intended effect was
still correct.
2022-01-18 13:49:19 +00:00
LaserEyess 4cb4660c7c meson: add check kwarg to run_command() calls
Warning from meson:

WARNING: You should add the boolean check kwarg to the run_command call.
         It currently defaults to false,
         but it will default to true in future releases of meson.
         See also: https://github.com/mesonbuild/meson/issues/9300

All of the run_command() calls currently use need to succeed for the
build to work properly.
2022-01-18 13:49:19 +00:00
Philip Langdale 22b0bac28e ao/pipewire: Add copyright header
Sometimes the most obvious things can be missed.

Reflects authorship described in the original commit.

* https://github.com/mpv-player/mpv/pull/7902
* https://github.com/Oschowa/mpv/commit/fddb143282fa74425a8a6f29c9566e51777759d0
* https://github.com/mpv-player/mpv/pull/9587
2022-01-17 13:48:44 -08:00
Thomas Weißschuh 87aba146ed ao_pipewire: Add PipeWire audio backend
The AO provides a way for mpv to directly submit audio to the PipeWire
audio server.
Doing this directly instead of going through the various compatibility
layers provided by PipeWire has the following advantages:

* It reduces complexity of going through the compatibility layers
* It allows a richer integration between mpv and PipeWire
  (for example for metadata)
* Some users report issues with the compatibility layers that to not
  occur with the native AO

For now the AO is ordered after all the other relevant AOs, so it will
most probably not be picked up by default.
This is for the following reasons:

* Currently it is not possible to detect if the PipeWire daemon that mpv
  connects to is actually driving the system audio.
  (https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1835)
* It gives the AO time to stabilize before it is used by everyone.

Based-on-patch-by: Oschowa <oschowa@web.de>
Based-on-patch-by: Andreas Kempf <aakempf@gmail.com>
Helped-by: Ivan <etircopyhdot@gmail.com>
2022-01-17 11:43:02 -08:00
Niklas Haas 1ba0547bfb vo_gpu: add HOOKED_gather
Can be used conditionally (via #ifdef HOOKED_gather) to use
textureGather in custom shaders.
2022-01-15 10:27:21 +01:00
Niklas Haas eca78ee925 vo_gpu_next: fix SUBBITMAP_BGRA
The only way to fix the channel order here is to create the texture with
bgra format. Incidentally, there used to be a way to set the component
map for overlays directly, but no more. Shouldn't matter since
everything supports bgra8 anyways, though.

Fixes #9699
2022-01-11 23:45:08 +02:00
Niklas Haas 9e2c0b8baa sub: rename SUBBITMAP_RGBA to SUBBITMAP_BGRA
This was a misnomer, the actual channel order is IMGFMT_BGRA (as the
comment explicitly point out). Rename the enum for consistency.
2022-01-11 23:45:08 +02:00
sfan5 429402cb08 af_lavcac3enc: fix some minor things
mark an array as static, a typo and a missing free
2022-01-10 22:56:52 +01:00
sfan5 d28a792c00 af_lavcac3enc: replace deprecated av_init_packet() 2022-01-10 22:56:52 +01:00
sfan5 39bed5c7fc encode_lavc: replace deprecated av_init_packet() 2022-01-10 22:56:52 +01:00
sfan5 b1bf4393a8 demux/packet: replace deprecated av_init_packet() 2022-01-10 22:56:52 +01:00
sfan5 8b4a613c54 image_writer: replace deprecated av_init_packet() 2022-01-10 22:56:52 +01:00
Niklas Haas 79783f4ac5 vo_gpu: placebo: add missing gamma functions
These got added upstream a while ago. Need to be added to the mapping
helpers.

It might be time to think about bumping the minimum dependency here.

Reported-by: Uoti Urpala <uau@glyph.nonexistent.invalid>
2022-01-10 15:43:57 +01:00
Dudemanguy d77b30abce meson: remove iconv hacks and bump req. version
There was some breakage with regards to the iconv detection in some
older meson versions. This was all settled in 0.60.3 and now it simply
just works. Remove the workarounds and bump the needed meson version to
0.60.3.
2022-01-09 16:34:50 +00:00
Dudemanguy 5ac8f85d3d github/workflows: remove some pip3 usages
When this was originally added, some OS package managers were slow and
behind the required meson version needed for mpv to build. Both opensuse
tumbleweed and freebsd now appear to carry meson 0.60.3 in their repos
so we no longer need to do the two-step process of installing pip3 and
then installing meson via pip. Instead, just use the OS package manager
version.
2022-01-09 16:34:50 +00:00
Niklas Haas e3b835de7c vo_gpu_next: forward dovi metadata to libplacebo 2022-01-09 13:06:27 +01:00
Niklas Haas 05ccc51d53 vf_format: add dolbyvision sub-option
Useful to strip dolbyvision from the output, in cases where the user
does not want it applied. Doing this as a video filter gives users the
abiilty to easily toggle this stripping at runtime in a way that
properly propagates to any (potentially stateful) VO.

It also thematically fits the rest of the options in vf_format, which
are similarly concerned with modifying the video image parameters.
2022-01-09 13:06:27 +01:00
Niklas Haas 88047f7654 demux_lavf: properly forward dovi config record
This needs to be forwarded from the AVStream to the AVPacket itself, so
that it reaches the decoder. There exists an FFmpeg function for this,
we just need to call it. (Also add some logging)
2022-01-09 13:06:27 +01:00
LynneandNiklas Haas 0e5f7b48d2 mp_image: add dolbyvision metadata
Co-authored-by: Niklas Haas <git@haasn.dev>
2022-01-09 13:06:27 +01:00
Julian Orth 777628e761 wayland: use xkb_keymap_new_from_buffer
Instead of `xkb_keymap_new_from_string`. The protocol does not require
the keymap to be null terminated and if the size of the keymap is a
multiple of the page size, using `_from_string` could lead to problems.

Some compositors include a null byte and even include the null byte in
`size`. Therefore we have to use `strnlen` to find the real length of
the string. Note that `_from_string` internally uses `strlen` and then
calls `_from_buffer`.
2022-01-08 15:20:02 +00:00
Julian Orth 3978669ece wayland: map keymaps with MAP_PRIVATE
While mpv uses version 1 of the `wl_seat` protocol and `MAP_PRIVATE` is
only required from version 7 on, using `MAP_PRIVATE` allows us to be
compatible with compositors that have only been tested with newer
applications.

Since the keymap is not modified after `mmap`, using `MAP_SHARED` has no
advantage over `MAP_PRIVATE`.
2022-01-08 15:20:02 +00:00
Niklas Haas d09c73c7b2 vo_gpu: add --tone-mapping-mode
This merges the old desaturation control options into a single
enumeration, with the goal of both simplifying how these options work
and also making this list more extensible (including, notably, new
options only supported by vo_gpu_next).

For the hybrid option, I decided to port the (slightly tweaked) values
from libplacebo's pre-refactor defaults, rather than the old values we
had in mpv, to more visually match the look of the vo_gpu_next hybrid.
2022-01-07 06:28:14 +01:00
Niklas Haas f3fccfc395 vo_gpu: add --gamut-mapping-mode
Merge --gamut-clipping and --gamut-warning into a single option,
--gamut-mapping-mode, better corresponding to the new vo_gpu_next APIs
and allowing us to easily extend this option as new modes are added in
the future.
2022-01-07 06:28:14 +01:00
Niklas Haas 2332445d8d vo_gpu_next: use new HDR metadata options
Properly forward the HDR metadata from the mpi to the equivalent (new)
fields in pl_color_space. Used by the new tone mapping code.
2022-01-07 06:28:14 +01:00
Niklas Haas a9cb2e2821 vo_gpu_next: update for new tone mapping options
This was significantly refactored upstream. Switch to new APIs and add
new tone mapping curves and options.

cf. https://code.videolan.org/videolan/libplacebo/-/merge_requests/212
2022-01-07 06:28:14 +01:00
sfan5 57bc5ba6d6 vo_gpu: move image2D precision qualifier to point of use
image2D is only defined from GLSL ES 3.1 onwards, so those statements
broke GLES 2.0. Move the qualifier to a place that is only reached with
the right version requirements.
fixes commit 584ab29c88
2022-01-02 14:01:33 +01:00
rcombs f40d66f624 vd_lavc: enable hwdec for prores by default 2021-12-29 01:04:09 +02:00
Niklas Haas 4b43800079 vo_gpu_next: fix --target-peak scaling
This is in nits, so it needs to be converted.
2021-12-29 00:02:54 +01:00
Avi Halachmi (:avih) 2157bb1995 js: events registration: clarify breakage/fix
This commit is mainly for correcting the previous commit message.

The previous commit fixed an issue where [un]registering events above
the first event ID "hole" is not requested from libmpv, and that's
indeed true.

However, this had nearly zero impact in practice, because libmpv
enables all events by default anyway (except TICK).

Therefore, above the first ID "hole" [un]register requests are not
sent to libmpv, and the events just keep arriving.

But the callback functions are still added/removed correctly (at
defaults.js), and so the script is not called back even if unregister
did not actually happen with libmpv.

The only event which was affected is TICK - which is not enabled by
default as it's deprecated, and before the previous commit could not
be enabled.

So the fix is more a general correctness fix now that the IDs array
can have "holes", but with effctively no impact in practice.
2021-12-26 21:00:21 +02:00
Avi Halachmi (:avih) 5c5e35c1bc js: fix event registration (keys, script-message, more)
Commit 63205981 removed some events but left all other event IDs at
their original values, which created "holes" at the events IDs array.

The JS backend for mp.register_event maps a name to an ID by scanning
all IDs and stopping when the name was found or a NULL name was
returned. Lua does the same except that it doesn't stop on NULL name.

Previously it was not possible to have a NULL name before the end of
the array, but now it is possible due to the enumeration holes.

Fix by skipping missing names, like lua does.
2021-12-26 20:02:45 +02:00
Dudemanguy d92cf77be5 meson: fix incorrect egl_drm operator in build
Back when the meson build was still in the PR state, this particular
variable was a dictionary. Later, it was refactored to simply be a
feature object instead. All uses of egl_drm['use'] should have been
replaced with egl_drm.allowed() but this particular line was missed
(that's what I get for not just doing find/replace). The conditional in
this line is usually satisified before egl_drm ever needs to be checked
which was why no one noticed until now. Fixes #9631.
2021-12-21 15:30:12 -06:00
Dudemanguy 87286fe820 wayland: avoid doing unneccesary window resizes
Commits 04018c3061
cd7a7a1de8 introduced behavior that
updated window geometry during wayland events (specifically surface and
output). This is good but they also are too aggressive with
automatically resizing. For example, if a window is manually resized by
the user and then dragged to a different monitor with different geometry
than the initial monitor, mpv will automatically resize itself to the
window's resolution. The initial thought behind this logic was for
autofit to automatically readjust itself on a new monitor, but doing
that breaks other common use cases. An attempt could be made to
distinguish between autofit and a manual resize but that introduces a
lot of complexity for an edge case. It's better to simply not change the
window geometry here. Internal values are recalculated and scaled of
course, but wl->window_size and wl->geometry should not change.
2021-12-20 22:51:03 +00:00
Dudemanguy 2db7a148d3 meson: remove unneccesary shaderc_static check
shaderc is a special case dependency in meson. According to the
documentation*, it first checks for shaderc_shared and will fallback to
shaderc_combined (the order is reversed if the static keyword is true).
However, shaderc also has a third .pc file (shaderc_static) which should
be checked. The meson documentation doesn't indicate this, but it also
actually checks shaderc_static*. shaderc_combined is first checked if
meson looks for static libs and if that is not found it tries
shaderc_static. So this extra fallback check is not needed.

*: https://mesonbuild.com/Dependencies.html#shaderc
*: https://github.com/mesonbuild/meson/blob/a2934ca9d13ede4eb97b320bc768319ecad7b525/mesonbuild/dependencies/misc.py#L539
2021-12-19 19:11:56 +00:00
sfan5 2858073fd0 wscript: switch shaderc checks to pkgconfig
Shaderc has been shipping .pc files for almost three years and we all
know of the advantages. If this turns out to be problematic the old checks
can be re-added but I'd like to avoid doing this preemptively.
2021-12-19 19:08:01 +01:00
sfan5 24dcb5d167 subprocess: unblock/reset signals before running child process
During execve() ignored and blocked signals carry over to the child
process, though apparently for SIGCHLD (which the bug report was about)
this is implementation-defined.
fixes #9613
2021-12-19 15:02:18 +01:00
Philip Langdale fd63bf398a vo_gpu: stop hard-coding max compute group threads
We've been assuming that maximum number of compute group threads is
never less than the 1024 defined by the desktop GL spec. Given that we
haven't had working compute shaders for GLES and I guess the Vulkan
spec defines at least as high a value, we've gotten away with it so
far.

But we should really look the value up and respect it.
2021-12-19 01:51:54 +01:00
sfan5 c8b6dc489b vo_gpu_next: implement VOCTRL_EXTERNAL_RESIZE
This is only needed on Android and supposed to handle a context
resize without reconfiguring the image parameters. reconfig()
already does exactly this so plug it in there.
2021-12-19 01:44:52 +01:00
Philip Langdale e79cd6227b meson: look for rst2man.py as well as rst2man
If you install docutils with pip in the default way, you will get a
script called `rst2man.py` rather than `rst2man`, so look for both
names.
2021-12-17 11:10:50 -08:00
Alex Xu (Hello71) 3ec2012cec mp_image, f_decoder_wrapper: implement AV_FRAME_DATA_DISPLAYMATRIX
fixes #9249 (JPEG orientation support) with ffmpeg commit [0].

[0] https://github.com/FFmpeg/FFmpeg/commit/e93c9986027d17917c3b4f533b28ee4a2ce7cd4c
2021-12-15 16:39:45 +01:00
sfan5 f9fd50c654 player: make deprecated track/chapter/metadata events internal
We still need these to track or notify of modifications to certain properties,
but they're now gone from the libmpv ABI.
2021-12-15 12:29:10 +01:00
sfan5 dfcd561ba9 lua: remove mp.suspend, resume and resume_all
These functions were deprecated in v0.21.0 and no-ops
since v0.23.0. The matching client API functions were
removed in the previous commit.
2021-12-15 12:29:10 +01:00
sfan5 632059816a libmpv: remove opengl_cb API and other deprecated symbols
Not all deprecated symbols were removed. Only three events were removed for now
since these are not used internally.
This bumps the library version to 2.0.
2021-12-15 12:29:10 +01:00
sfan5 72915e8b76 {player,video}: remove references to obsolete opengl-cb API 2021-12-15 12:29:10 +01:00
Niklas Haas 0bb15c7a13 af_lavcac3enc: fix memory leak on no-op
Simply returning out of this function leaks avpkt, need to always "goto
done".

Rewrite the logic a bit to make it more clear what's going on (IMO).

Fixes #9593
2021-12-14 21:25:02 +01:00
Philip Langdale 584ab29c88 vo_gpu: opengl: some fixes to make compute shaders work with GLES
It's supposed to work with GLES >= 3.1 but we had all sorts of bad
assumptions in our version handling, and then our compute shaders
turn out not to be GLSL-ES compliant.

This change contains some necessary, but insufficient, tweaks to the
shaders. Perhaps we'll make it actually work some day.
2021-12-12 20:23:31 -08:00
Philip Langdale 2fc327f2fd vo_gpu: opengl: fix OpenGL ES version and extension handling
Some of the extension declarations did not include the ES version where
they became core functionality, and in some of these cases, there was
never actually an ES extension - it first appeared in core. We also had
a number of buggy version checks where ES versions were compared
against required desktop GL versions.
2021-12-12 20:23:31 -08:00
Philip Langdale 0e76372e86 vo_gpu: opengl: try and create context at version 440 again
nvidia follow the OpenGL spec very strictly, with two particular
consequences:

* They will give you the exact context version that you ask for,
  rather than the highest possible version that meets your request.
* They will hide extensions that the specs say require a higher
  version than you request, even if it's technically possible to
  provide the extension at lower versions.

In our case, we really want a variety of extensions, particularly
compute shaders that are only available in 4.2 or higher. That means
that we must explicitly include a high enough version in our list of
versions to check for us to be able to get a 'good' enough context.

As for which version? We restore the 4.4 version that we had in the
old version selection logic. This is the highest version we ever asked
for, and we have separate logic that clamps the GLSL version to 4.4,
so anything newer wouldn't make a difference.
2021-12-07 15:37:29 -08:00
Niklas Haas 9b06a71a5d vo_gpu: opengl: fix wrong glMemoryBarrier
This call was completely wrong.
2021-12-06 23:59:14 +01:00
Jan Ekström 77142ed9b8 sub/lavc_conv: only set subtitle text format when required
Since libavcodec major version 59, the requested "ass" format became
the default as the old timing-included format was disabled starting
with that version. Additionally, this option by itself has since
been deprecated as it no longer serves any purpose.

References:
FFmpeg/FFmpeg@1f63665ca5
FFmpeg/FFmpeg@176b8d785b

Fixes #9413
2021-12-05 22:31:32 +02:00
Niklas Haas 036bda9166 vo_gpu_next: fix UB in query_format()
`plane_data_from_imgfmt` doesn't zero-initialize the struct, so this
contained invalid values for e.g. `row_stride`, causing formats to
*randomly* fail. (Especially any formats with specific alignment
requirements)

Might fix #9424 and #9425.
2021-12-05 21:24:57 +01:00
Kurt Kartaltepe fc94c8c365 wayland: ensure read and draw buffers are assigned
This is a workaround for nvidia proprietary drivers. The authors of
those drivers interpret the spec such that eglMakeCurrent will not
reconfigure the read and draw buffers. Thus windows wont display
anything drawn by opengl. nvidia authors refer to
https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_no_config_context.txt
specifically Issues 2/3 which reference eglMakeCurrent.

On mesa this is a non-issue and the read/draw targets are assigned with
eglMakeCurrent.

The context must be made current in order to query OpenGL strings. An
earlier proposal to create the wayland window surface similarly to X11
during init was deemed inappropriate so instead we manually set the
targets once we have created a window surface.
2021-12-04 03:04:17 +00:00
Aman Karmani 181656955b audio: fix typo 2021-12-03 14:04:58 -08:00
Kurt Kartaltepe d86bfebe6d opengl: support DebugMessageCallback on ES
This function is provided by a different extension on OpenGL ES so we
add a separate gl_functions.
2021-12-02 12:20:16 +01:00
Ivan 87ce3b31a9 ao_openal: enable AL_SOFT_direct_channels_remix extension by default
Prevent audio distortions caused by OpenAL's 3D effects.
2021-11-29 11:27:39 +01:00
Leo Izen ac39af461d player: make --keep-open=always work with --loop-playlist
Allow --keep-open=always to work with --loop-playlist, where
before this patch it would work only on the last playthrough of the
playlist. This patch allows it to work on all playthroughs.

Fixes #9470.
2021-11-28 19:45:52 -05:00
Niklas Haas 4991ffa859 vo_gpu_next: implement VOCTRL_SCREENSHOT
Somewhat annoying but still relatively straightforward. There are
several ways to approach this, but I settled on reusing the pl_queue as
a cheap way to get access to the currently mapped frame. This saves us
from having to process `vo_frame` at all, and also avoids any overhead
from re-uploading the same frame twice.

(However maybe there's some circumstance in which `vo_frame` needs to be
queried/updated first, to get a screenshot of the correct frame? I'm not
sure.)

I also had the option of going with either pl_render_image() on the
extract pl_frame, or just calling pl_render_image_mix directly on it. I
went for the latter, because in the optimal case, this allows the
rendered frame to be directly retrieved from the cache, actually
entirely avoiding any sort of recompute overhead. This makes e.g. ctrl+s
during playback essentially free. (Except for the download cost,
obviously)

It would be even neater if we could make this VOCTRL asynchronous and
thereby leverage libplacebo's asynchronous download capabilities. But oh
well. That will have to wait for a sufficiently rainy day.

Closes #9388
2021-11-28 11:58:53 +01:00
Niklas Haas c66f3b0123 vo_gpu_next: factor out some common helpers
In preparation of VOCTRL_SCREENSHOT support
2021-11-28 11:58:53 +01:00
Dudemanguy f08db00d26 client API: also export mpv_client_api_version
20c4036daa switched to using symbol
visibility attributes for mpv client api functions (for the meson build
at least). Unfortunately mpv_client_api_version was mistakenly missed.
We need to export this function as well. Fixes #9531.
2021-11-27 22:46:54 -06:00
Funami580 448fe0226b osc: fix cache displaying 60s in some cases
It was caused by string.format rounding e.g. 59.9 to 60.
2021-11-27 21:37:24 +02:00
Niklas Haas cc4ac14d51 vo_gpu_next: guard sentinel in free_dr_buf
As noticed in #9526, apparently there's some case in which DR buffers
get corrupted. Add an explicit sentinel check to try and figure out
which cases these are.
2021-11-26 19:59:26 +01:00
Solomon Choina 059bd3dcaa meson: correct champ.c to chmap.c
meson: correct champ.c to chmap.c
2021-11-26 15:13:01 +00:00
Dudemanguy ec97b3f279 meson: add a temporary workaround for iconv crap
The initial iconv dependency worked everywhere but was broken on
freebsd. This was fixed in 0.60.2 but the fix accidentally broke mingw
(ouch; kind of my fault for not double checking). There's another PR to
fix this but that won't land until 0.60.3 so for the meantime just
if/else this (both freebsd and windows work with the system method)
until we want to bump the meson version (probably not for a while since
opensuse tumbleweed is weirdly slow).
2021-11-26 04:43:43 +00:00
Dudemanguy 51da9d257e ci: fix the path for logs on failure in mingw
The old directory was wrong. The actual build directory has the matrix
prefix in its name.
2021-11-25 21:33:29 -06:00
Dave Airlie 8ed1368501 vo_gpu: hwdec_vaapi: avoid drm_fourcc.h dependency
Suggested by haasn
2021-11-25 23:11:37 +01:00
Avi Halachmi (:avih) b8926dd484 osc: add options: chapters/playlist OSD, hover chapter format
Previously OSD was always displayed on {ch,pl}_{next,prev} left-click,
and seekbar-hover-chapter was always enabled and with fixed format.

Now it can be controlled with:
- chapters_osd, playlist_osd: yes/no (only affects left-click).
- chapter_fmt: lua string.format template, or "no" to disable.

Fixes #4675
2021-11-25 21:20:48 +02:00
Dudemanguy 1ab9119817 wayland: increase the vblank waiting time
This commit sucks bad, but everything else is worse is other ways.
Basically, the current vblank waiting time in the vo_wayland_wait_frame
function (calculated very carefully using presentation statistics) is
randomly too short. Some compositors are quite variable when they
actually return callback so our timeout expires too quickly and throws
everything off. The fix? Add an arbitrary 5% to the vblank value and
pray that nothing gets off that much. Why did they have to make
swapinterval 1/fifo mode indefinitely block? Fixes #9504.
2021-11-25 17:20:26 +00:00
Dudemanguy 55b085707a wayland: initialize presentation time values as 0
Better to avoid any wonky calculations on startup with garbage values.
The others end up being derived from last_ust/last_msc. refresh_interval
is referenced exactly once and could, in theory, result in some terribly
erroneous vblank time.
2021-11-24 23:28:53 -06:00
Kurt Kartaltepe 79bfcc6723 wayland: cancel prepared reads when no events
A read can be prepared on the wayland display FD that is never actually
read. This occurs when events are triggered on other FDs in the fd set.
This change cancels a prepared read if poll reported no events for it.

This fixes some hangs due to how nvidia's EGL implementation polls on
the wayland fd unlike mesa implementations. It is based on nvidia's
proposed fix for qt's similar message pump in
https://codereview.qt-project.org/c/qt/qtwayland/+/373473

Signed-off-by: Kurt Kartaltepe <kkartaltepe@gmail.com>
2021-11-25 04:09:31 +00:00
Dave Airlie a6e5eba6ab vo_gpu: hwdec_vaapi: add dma-buf modifiers support.
If the EGL extension is present, pass the modifiers for each plane
to the EGL driver.
2021-11-23 23:18:54 +01:00
sfan5 dc73f1ad4b vo_gpu_next: implement OpenGL context support
Wrapping the context is pretty straightforward. This is only complicated
by needing to account for the upside-down framebuffer in a few places.
2021-11-22 18:08:56 +01:00
sfan5 d5d62c6a64 vo_gpu_next: factor out context-specific code to gpu_next/context.c
This is done to avoid cluttering vo_gpu_next.c with more ifdeffery and context-specific code
when additional backends are added in the near future.
Eventually gpu_ctx is intended to take the place of ra_ctx to further separate gpu and gpu_next.
2021-11-22 18:08:56 +01:00
sfan5 f32ea013dd video: opengl: teach start_frame() about out_fbo == NULL
This case was added in 662c793a55
for use in vo_gpu_next as a visibility test before rendering a frame.
The OpenGL context doesn't have this so it just returns true.
2021-11-22 18:08:56 +01:00
Niklas Haas 4ca6c2ff34 vo_gpu_next: respect tagged YUV colorspace
Fixes 2b2442ee67
2021-11-22 14:40:11 +01:00
Niklas Haas 2b2442ee67 vo_gpu_next: apply csp overrides for RGB/XYZ/YUV formats
This is needed when the color system is not explicitly tagged, but
instead needs to be inferred by the VO.

Note that there exists the function mp_image_params_guess_csp for this
sort of stuff, but it contains a lot of baggage that I don't want to
replicate, in order to move as much of this logic into pl_renderer as
possible, and therefore also give it the best chance of knowing what
shortcuts it can and can't take.

Fixes the other half of https://github.com/mpv-player/mpv/issues/9499
2021-11-22 12:38:43 +01:00
Dudemanguy 67c1ff8dad vo_gpu_next: fix timings without interpolation
Adding vsync_offset to the pts in pl_queue_update actually messes up
frame timings if one isn't using interpolation. The easiest way to see
this is to have the monitor's refresh rate at an integer multiple of a
video during a panning shot (classic case). There will be very visible
judder/stutter in this case that does not happen in vo_gpu. The cause of
this is the addition of the extra vsync_offset. Just match the semantics
of vo_gpu where this is only used when interpolating.
2021-11-21 22:56:30 +01:00
Aman Karmani ac3d567bd3 audio: stop corrupting audio on underreads
regression introduced in b74c09efbf

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-11-20 12:08:32 -08:00
Niklas Haas 970061efdc vo_gpu_next: fix OOM on wayland
Similar to ff0864d5f0

Fixes #9484
2021-11-20 19:21:50 +01:00
Dudemanguy d2c2bf5a13 wayland: fix a potential segfault on surface enter
This possibility actually existed for years. The wayland protocol is
asynchronous and there's no restriction on when a compositor can send a
surface enter event. In mpv's case, the surface enter event is used to
set some vital things regarded geometry/scaling etc. However, this
implictly assumes that wl->current_output is actually initialized. The
vast majority of the time, vo_wayland_reconfig will happen first which
is where wl->current_output is, and should, be created. There's no
rule/law that the ordering of events will always occur in this order.
Plasma with certain auto-profile conditions can send the surface enter
event before mpv does its initial reconfig. That segfaults of course.
Just add a check to make sure we have wl->current_output here and return
if we don't. This assumes that the compositor will send us another
surface enterance event when mpv actually does the initial surface
commit and roundtrip request later. Wayland logs indicate this does
happen. Fixes #9492.
2021-11-20 10:48:09 -06:00
Dudemanguy 21cdc713bc wayland: support modifiers during axis events
It was never implemented before but it's trivial. As an aside, touch
events currently don't support modifiers either (is this a thing?). Well
if someone complains that can be done later. Fixes #9490.
2021-11-20 09:17:41 -06:00
Dudemanguy 59898331dd DOCS/ao: remove incorrect note about openal
The audio rewrite in d27ad96542 originally
broke this ao. However, 0ac724f002 fixed
and the documentation was never updated to reflect that. OpenAL has
worked fine for a while not. Just remove this sentence.
2021-11-19 16:57:37 -06:00
Niklas Haas 170259c7c3 vo_gpu_next: always cache still frames
Even when not display synced. Prevents redraw overhead for refreshes
while paused.

Also make the logic slightly clearer to follow (since it's inverted).
2021-11-19 22:42:21 +01:00
Leo Izen 763e0d259f vo_gpu_next: fix lancozs typo to lanczos
Fix typo in the warning to avoid ewa_lanczossharp because
it might be removed in the future.
2021-11-19 23:35:27 +02:00
Niklas Haas 7acbecf7b8 vo_gpu: libplacebo: make version logging slightly clearer
Matches what `pl_log_create` does as well.
2021-11-19 21:50:59 +01:00
Dudemanguy e095bdb5f5 meson: use gnu_symbol_visibility for libmpv
Following the previous commit, we can just set gnu_symbol_visibility to
'hidden' to hide everything except for the symbols we explictly want to
export. This should work on gcc, clang, and msvc.
2021-11-19 14:16:41 +00:00
Dudemanguy 20c4036daa client API: use symbol visibility attributes
In mpv, the only symbols we want to export are the functions from the
client API. This is accomplised using a specific .def whitelist, but the
main compilers people use (gcc or clang) like these attributes since it
allows for further optimizations. MSVC also allegedly supports this as
well (untested of course), so use __declspec for tht case.
2021-11-19 14:16:41 +00:00
Niklas Haas 75ee35cec9 vo_gpu_next: simplify and improve frame redrawing logic
This almost perfectly recreates the semantics of --vo=gpu, i.e.:

- still frames are never interpolated
- non-repeated frames bypass single frame cache

The only difference is that libplacebo doesn't do a cache/blit on the
full output image, but rather it re-runs the last rendering step. This
has some advantages and some drawbacks. The most notable advantage is
that it also allows re-using the image contents when the only thing that
changes is the OSD (whereas `--vo=gpu` would force a full re-render for
that). The most notable drawback is that it also implies going through
the dithering and output LUT logic on redraws. All in all, I think this
is a pretty good trade-off in favor of `--vo=gpu-next`.

Fully fixes the last remaining performance difference in #9430.
2021-11-19 14:51:48 +01:00
Tom Yan d1e9f4a159 ao_opensles: add guards for sample rate to use
Upstream "Wilhelm" (the Android OpenSLES implementation) supports
only 8000 <= rate <= 192000. Make sure mpv resamples the audio
when necessary.
2021-11-19 14:27:52 +01:00
Niklas Haas 17df53519f vo_gpu_next: fix panning on rotated videos
Closes #9454
2021-11-19 12:10:25 +01:00
Dudemanguy b89d3f205b meson: fix typo in header check
This should be EGL not GL. Fixes #9469.
2021-11-18 07:43:51 -06:00
sfan5 69f21d5e74 context_glx: fix check for wrong GLX extension
GLX_CONTEXT_PROFILE_MASK_ARB and related constants are provided by
GLX_ARB_create_context_profile but the check was for _create_context.
The former implies the latter (which we also need) so just replace
the checked extension.
2021-11-17 22:38:34 +01:00
sfan5 9afa41945f context_{wayland,x11egl}: use mpegl_create_window_surface() too
Again no functional difference, just uses better APIs when they're available.
2021-11-17 22:38:34 +01:00
sfan5 da3b85b613 context_drm_egl: make use of mpegl_create_window_surface()
This does what 3a10210c56 was supposed to, but better.
2021-11-17 22:38:34 +01:00
sfan5 b69af0abef egl_helpers: introduce wrapper around eglCreatePlatformWindowSurface
It abstracts EGL 1.5, extension checks and other inconsistencies away.
This can be used in context code as the (preferred) alternative to
eglCreateWindowSurface().
2021-11-17 22:38:34 +01:00
sfan5 c3d78b0017 video: opengl: use gl_check_extension() instead of strstr()
Using a simple substring match for extension checks is considered bad practice
because it's incorrect when one extension is a prefix of another's name.
This will almost surely not make a difference in practice but do it for correctness anyway.
2021-11-17 22:38:34 +01:00
sfan5 f5cc28a627 context_drm_egl: use mpegl_get_display() helper over own code
Although there are no known problems with this, using the helper should
be more portable. It will also prefer EGL 1.5's eglGetPlatformDisplay
over eglGetPlatformDisplayEXT if available.
2021-11-17 22:38:34 +01:00
Oliver Freyermuth 3d9c0eae9e stream_dvb: add missing mutex unlock
This deadlock was not triggered in real use since configuration
validity does not change at runtime.

closes #9459
2021-11-16 22:24:14 +01:00
Dudemanguy e24a87efaa meson: fix build on android
The original implementation had some errors with regards to android. Add
a couple of missing files, add the android library, fix the aviocontext
bytes_read check, fix egl-android, and rearrange/tidy up the vulkan
handling.
2021-11-16 18:56:34 +00:00
Philip Langdale b030cfe05f vo_gpu: vulkan: open DRM render fd when using VK_KHR_display
While the basic Vulkan Display context can theoretically drive the
display without the involvement of any non-Vulkan code, that prevents
us from using VAAPI acceleration. When initialising VAAPI without a
window system, we need to provide it with an opened DRM render fd
corresponding to the device to use.

In the context of using VK_KHR_display, that means we need to identify
which DRM device matches the selected Vulkan device, and then open its
render fd and set the necessary state that VAAPI expects to find.

With that done, the normal VAAPI<->Vulkan interop can kick in and we
get working acceleration
2021-11-15 21:07:21 -08:00
Dudemanguy 3bfc37dcb4 meson: check for x11 when building the xv option
Obvious oversight in the original PR for the meson build. The xv option
requires x11 to function. Check for this by using the require method.
2021-11-15 16:58:23 +00:00
Dudemanguy 257bc95255 meson: minor QOL and logic tweaks
A few custom targets had some less than optimal names which created some
misleading "Generating custom-target-name with a custom command"
messages. Change those to be more descriptive/correct. In a few other
places, some checks were being done that could easily be
skipped/ignored in certain cases (like checking for windows-related
headers when gl-win32 isn't true). Also rearrange that to be smarter.
Finally, print some extra libplacebo messages for enabling/disabling
vo_gpu_next.
2021-11-15 16:58:23 +00:00
Dudemanguy e6ce03f3ef meson: also check for generic lua.pc
Some systems have only a "lua.pc" file which contains version
information inside it. Check those as well.
2021-11-15 16:58:23 +00:00
Dudemanguy dfbaf4dd81 meson: fix -Werror=format-security flag
This test fails because the compiler object does not have -Wformat when
it tries this flag. To fix this this, we have to pass both -Wformat and
-Werror=format-security at the same time during the test. This requires
us to use has_multi_arguments so this flag needs to be pulled out of
this array and tested separately.
2021-11-15 16:58:23 +00:00
Umar Javed 923c0f0370 ytdl_hook.lua: improve check for sub language before inserting all-subs
youtube-dl and yt-dlp both support --sub-langs and --srt-lang in
addition to --sub-lang for defining languages of subtitles. This hook
only checked for sub-lang in --ytdl-raw-options and inserted --all-subs
in its absence.
2021-11-15 15:08:22 +01:00
Emil Velikov b44f522dba options: const annotate all m_opt_choice_alternatives accessors
Constant data, most accessors are good but some were missing the
explicit notation.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2021-11-15 14:02:08 +00:00
Emil Velikov f09396ab7d options: const annotate m_obj_list accessors
Nearly all the code base correctly references the data as constant. But
a couple of instances - fix those.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2021-11-15 14:02:08 +00:00
Emil Velikov 37619c4cf5 options: remove always true m_obj_list::allow_unknown_entries
Ever instance of m_obj_list is a constant and for all of them, the field
is true. Just remove the field all together.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2021-11-15 14:02:08 +00:00
Mehul Mittal b66120a75d DOCS/options: fix target-colorspace-hint typo 2021-11-14 21:48:34 +01:00
Dudemanguy 31780a6db5 ci: add meson builds
Update the github workflows to also do meson builds for every OS.
Additionally, make every workflow execute the built mpv executable
(except for windows and FreeBSD's waf executable) to make sure that it
runs. As an aside, FreeBSD unfortunately is a bit less elegant since it
is in a VM.
2021-11-14 19:13:10 +00:00
Dudemanguy ff322864f2 build: add meson build support
Adds support for the meson build system as well as a bit of
documentation. Compatibility with the existing waf build is
maintained.
2021-11-14 19:13:10 +00:00
Dudemanguy f610fe16c0 demux_edl: rename ebml_defs.c to ebml_defs.inc
The extension is completely arbitrary since ebml_defs.c isn't a real c
file that actually is compiled at any point in time. It's just used as
an include. The reason for changing the extension is because meson needs
to add this to its list of sources for dependency/ordering purposes.
Understandably, meson will try to compile any .c file added to a c
project executable object. Obviously, this compilation will never
succeed, and this shouldn't be compiled anyways. Just make it .inc
instead.
2021-11-14 19:13:10 +00:00
Dudemanguy 94950b1b22 TOOLS/matroska.py: support outputting to file
Like the previous commit, it's better to just output it to a file for
meson.
2021-11-14 19:13:10 +00:00
Dudemanguy f7fab994eb TOOLS/file2string.py: support outputting to file
Another modification for the upcoming meson build. Meson can capture the
stdout and redirect it to a file. However, this is considered a hack.
It's better to just add a few lines to this script and write a file
directly.
2021-11-14 19:13:10 +00:00
Dudemanguy c698575c57 TOOLS: add macos-swift-lib-directory.py script
Apple is great and forces us to do a lot of weird checks because they
randomly move the location of the swift libraries around. Make a
specific python script for checking various locations and write the
output to stdout for meson.
2021-11-14 19:13:10 +00:00
Dudemanguy be536dd45a TOOLS: add macos-sdk-version.py script
Building for macos requires us to check the macos sdk path as well as
the sdk version that is on the system. To do this, let's steal the logic
that's in the compiler_swift.py check from the waf build. This returns a
comma-delinated string. The first entry is the absolute path to the sdk.
The second entry is the detected macos sdk version.
2021-11-14 19:13:10 +00:00
Dudemanguy 37549b6faa build: add version.py for generating version.h
version.h is essential for building, and its generation was done by a
shell script. Strictly speaking, python should in general be more
portable (windows), and would be better for the upcoming meson build to
simply just execute a python script. version.py has some small
differences with version.sh which shouldn't matter but they are noted
below.

- version.sh accepted several arguments that seemed useless (like
  --cwd). These were removed from version.py.
- version.py takes either no arguments (prints the version) or it takes
  exactly one argument specifying the complete path of where the header
  should be generated.
- version.sh attempted to read a file named "snapshot_version". The
  comments noted that this was for "daily tarball snapshots". Such a
  file does not exist in the source tree, and it's not really clear that
  anyone actually uses this. This logic was removed from version.py.
- version.py reads the SOURCE_DATE_EPOCH environment variable. Some
  distros use this for reproducible builds. Technically you could also
  just disable the build date but this is only a couple of extra lines
  and maybe it's prettier than UNKNOWN.
- version.py also doesn't attempt to display timezone information in the
  build date. It only shows UTC time.
2021-11-14 19:13:10 +00:00
Dudemanguy c478a1efba egl_helpers: remove EGL_OPENGL_ES3_BIT
d2e8bc4499 was the the commit that
originally introduced the usage of this bit. As the message states, the
purpose was to force creating GLES 3 contexts on drivers that do not
return a higher version context than what was requested. With the recent
opengl refactors, mpv's gl selection has already moved away from such
complicated queries. Perhaps when that commit was added things were
different, but nowadays it seems like Mesa simply returns the highest
driver version available that is compatibile with the request (i.e.
requesting GLES 2 returns a GLES 3 context on my machine). In that case,
let's just simply drop EGL_OPENGL_ES3_BIT altogether as it does break
GLES 2 only machines. Fixes #9431.
2021-11-11 16:51:51 +00:00
sfan5 3a10210c56 context_drm_egl: use eglCreatePlatformWindowSurfaceEXT if available
This is identical to eglCreateWindowSurface but should be
preferred as part of EGL's platform extension.
2021-11-11 17:41:42 +01:00
Philip Langdale 2b9d8ae8b1 context_drm_egl: add support for BGR surface formats
The new GBM supporting nvidia drivers declare support for 10bit
surfaces using BGR ordering, rather than RGB, so add support for them.

We've also seen examples of hardware supporting BGR8888 but not
RGB8888 so let's support those too.

Of course, the nvidia EGL driver doesn't publish support for any 10bit
formats so you can't actually do 10bit display. Perhaps they'll
eventually fix that.
2021-11-10 09:57:58 -08:00
Philip Langdale 10d677575a context_drm_egl: use gbm_surface_create_with_modifiers
The GBM supporting nvidia driver doesn't support creating surfaces
without modifiers and using modifiers is more and more recommended as
the right way to do this.

Enumerating modifiers is painfully verbose, but necessary if we are to
allow the driver to pick the best possible one.
2021-11-10 09:57:58 -08:00
Jan Ekström e6a75075b2 ao_oss: define PATH_DEV_MIXER as it is an internal define
This fixes a mismatch between configure working and build time
failing with Linux + OSSv4, enabling compilation on Debian based
Linux systems with the oss4-dev package.

Fixes #9378
2021-11-10 17:08:16 +01:00
Jan Ekström dd6fce5138 ci/build-freebsd: require OSSv4 AO to be enabled 2021-11-10 17:08:16 +01:00
Niklas Haas c413720801 vo_gpu_next: fix slight performance regression
This logic, which was working around a libplacebo bug, ended up always
alpha blending - even for sources without an alpha channel. This caused
a minor slowdown to be constantly enabled.

Due to the recent bump to libplacebo v170, this is no longer needed.
2021-11-10 10:38:58 +01:00
Starsam80 69527077c1 vo_gpu_next: Initialize pl_frame_mix
Without initializing, the random data causes the `pl_render_image_mix`
function to abort with a SIGSEGV.
2021-11-09 02:14:30 +01:00
Niklas Haas 4470eaf5e5 vo_gpu_next: implement HDR passthrough
Completely untested, since Linux still can't into HDR in 2021. Somebody
please make sure it works.

Technically covers #8219, since gpu-context=drm can be combined with
vo=gpu-next.
2021-11-08 20:57:54 +01:00
Niklas Haas 3cf6147368 vo_gpu_next: drop PL_API_VER checks
These are no longer needed with the minimum version bump.
2021-11-08 18:24:11 +01:00
Niklas Haas ff0864d5f0 vo_gpu_next: fix resource exhaustion on minimized windows
This required an upstream API change to implement in a way that doesn't
unnecessarily re-push or upload frames that won't be used. I consider
this a big enough bug to justify bumping the minimum version for it.

Closes #9401
2021-11-08 18:24:11 +01:00
Dudemanguy f5d545c917 wayland: remove bogus scale_change variable
This was originally added in f2afae55e9
for unclear reasons (way to go me). This concept is clearly incorrect.
It doesn't matter what state the window is in. As soon as mpv detects a
scale change, it needs to reset the buffer scale of the window. Just
remove all this junk and put wl_surface_set_buffer_scale in
set_surface_scaling like it should be. Related issue: #9426.
2021-11-08 09:49:49 -06:00
Niklas Haas 73563cebf9 vo_gpu_next: add automatic translation for ewa_lanczossharp
This one hits a lot of people. Probably because the man page explicitly
recommends it.

Fixes #9408
2021-11-07 22:32:00 +01:00
Niklas Haas eca1b8dc29 vo_gpu_next: implement --dither-depth
I somehow completely forgot about this option existing.

Closes #9416
2021-11-07 18:12:42 +01:00
Niklas Haas 459f7d4a8d vo_gpu_next: remove --builtin-scalers option
Looking at this again I'm not sure it does anything useful at all. The
man page entry is also wrong: `bicubic` is not affected, only
`bicubic_fast`, and those filters are not configurable anyways.

So this would only ever be a debugging option, and I don't see a
pressing need for it.

No interface-change.rst update because it only just got added anyways.
2021-11-07 11:32:57 +01:00
sfan5 ec16769c2d f_lavfi: replace deprecated avfilter_pad_count 2021-11-05 23:34:20 +01:00
sfan5 6996588254 audio: replace deprecated av_mallocz_array 2021-11-05 23:34:20 +01:00
Dudemanguy 662c793a55 vo_gpu_next: call start_frame in vulkan/context.c
In practice, this is for wayland. vo_gpu_next doesn't check the
check_visible parameter since it didn't descend into the
vulkan/context.c file when starting a frame. To make this happen, just
call the start_frame function pointer but pass NULL as the ra_fbo. In
there, we can do the visibility checks and after that bail out of the
start_frame function if ra_fbo is NULL.
2021-11-04 15:59:56 +00:00
Dudemanguy acde63f05a wayland_vk: rename start_frame to check_visible
This vulkan-specific parameter was poorly named and probably causes
confusion. Just rename it to check_visible instead to make clear what is
going on here. Only wayland uses it for now but in theory anyone else
can. As an aside, wayland egl accomplishes this by using an external
swapchain instead (an opengl-only concept in the mpv code). This may or
may not need to be changed in the future when gpu-next gets opengl
support.
2021-11-04 15:59:56 +00:00
Niklas Haas a73e5cdbed manpage: document --sharpen not affecting vo_gpu_next
Fixes https://github.com/mpv-player/mpv/issues/9387
2021-11-03 15:37:19 +01:00
Niklas Haas 8bd0dee531 osdep: rename MP_UNREACHABLE
It was pointed out on IRC that the name is misleading, since the actual
semantics of the macro is to assert first.
2021-11-03 15:15:20 +01:00
Niklas Haas 701bd783ca vo_gpu_next: fix --tone-mapping-param mapping
vo_gpu defaults this to NAN, libplacebo uses 0.0 as the default.

Fixes https://github.com/mpv-player/mpv/issues/9386
2021-11-03 14:43:17 +01:00
Niklas Haas 9d5d9b2424 vo_gpu_next: add new libplacebo-based renderer
As discussed in #8799, this will eventually replace vo_gpu. However, it
is not yet complete. Currently missing:

- OpenGL contexts
- hardware decoding
- blend-subtitles=video
- VOCTRL_SCREENSHOT

However, it's usable enough to cover most use cases, and as such is
enough to start getting in some crucial testing.
2021-11-03 14:09:27 +01:00
Niklas Haas 872015813c sub: assert potential pitfall
This one got me debugging for quite a while. Assert it for the future.
2021-11-03 14:09:27 +01:00
Niklas Haas c704824b45 osdep: add MP_UNREACHABLE
This seems to work on gcc, clang and mingw as-is, but I made it
conditional on __GNUC__ just in case, even though I can't figure out
which compilers we care about that don't export this define.

Also replace all instances of assert(0) in the code by MP_UNREACHABLE(),
which is a strict improvement.
2021-11-03 14:09:27 +01:00
Niklas Haas 2107671691 build: add check_preprocessor
This can be used to do things like query the values of preprocessor
defines like version macros, among other potential uses.
2021-11-03 14:09:27 +01:00
Niklas Haas edb0caa441 vo_gpu: allow using bare windows as --(t)scale
A lot of people seem to do something like --tscale=box
--tscale-window=<function>. Just let them use --tscale=<function>
directly, by also accepting raw windows.

Kinda hacky but needed for feature parity with vo_gpu_next, which no
longer has `--tscale=box`. Note that because the option struct is still
shared, vo_gpu_next inherits the same option handling code, so we have
to export this feature for vo_gpu as well.
2021-11-03 14:09:27 +01:00
Niklas Haas 242cd76ee7 vo_gpu: vulkan: expose swapchain to mpvk_ctx
So I can reuse it in vo_gpu_next.
2021-11-03 14:09:27 +01:00
Niklas Haas 432581b604 vo_gpu: lift ra_ctx_* opts to a global struct
So I can re-use them for vo_gpu_next.
2021-11-03 14:09:27 +01:00
Dudemanguy 5512f53722 player: fix autofit/geometry related segfault
Back when runtime updating of autofit/geometry was added for wayland and
x11 (commits: 4445ac828dca0298543103094357e64f8828ef56 and
ced92ba607ebd98687b26ef3d8c09d5f6e22cf4b respectively), the naive
assumption was that window-related geometry would always be available.
While this is true 99% of the time, this isn't a guarentee. It is
possible for certain things such as loading shaders to delay starting up
the player. This causes autofit/geometry options to be registered as a
runtime update and triggers VOCTRL_VO_OPTS_CHANGED. This ends up calling
some geometry-related functions but this happens before the actual
values are available. Hence, a nullptr was accessed which segfaults. At
least one user experienced this with a combination of options in wayland
but in theory the same thing could happen under x11.

The fix is simple. Just be sure to check that the required geometry is
available before doing any calculations. In wayland, this would be
wl->current_output. Additionally add an assert to set_geometry (we
should never use this function without wl->current_output) to be extra
sure. In x11, the check is on x11->window. Later when the reconfig for
each backend actually happens, the autofit/geometry set by the user
happens anyway so ignoring it in this case does no harm. Fixes #9381.
2021-11-03 00:32:27 +00:00
sfan5 171627b267 Update VERSION 2021-11-01 15:46:09 +01:00
296 changed files with 13293 additions and 3325 deletions

No files matched your search

+86 -34
View File
@@ -11,36 +11,58 @@ on:
jobs:
mingw:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
target: [i686-w64-mingw32, x86_64-w64-mingw32]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
# Increase -N suffix here to force full rebuild after changes
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: mingw_prefix/
key: "${{ matrix.target }}-1"
key: "${{ matrix.target }}-6"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y autoconf automake pkg-config g++-mingw-w64 gcc-multilib nasm yasm
sudo apt-get install -y autoconf automake pkg-config g++-mingw-w64 gcc-multilib meson nasm
./bootstrap.py
- name: Build
- name: Build libraries
run: |
./ci/build-mingw64.sh
env:
TARGET: ${{ matrix.target }}
- name: Print configure log
- name: Build with meson
run: |
./ci/build-mingw64.sh meson
env:
TARGET: ${{ matrix.target }}
- name: Print meson log
if: ${{ failure() }}
run: |
cat ./build/meson-logs/meson-log.txt
- name: Build with waf
run: |
./ci/build-mingw64.sh waf pack
env:
TARGET: ${{ matrix.target }}
- name: Print waf log
if: ${{ failure() }}
run: |
cat ./build/config.log
- uses: actions/upload-artifact@v3
with:
name: mpv-${{ matrix.target }}
path: mpv-git-*.zip
macos:
runs-on: ${{ matrix.os }}
strategy:
@@ -48,46 +70,49 @@ jobs:
cc:
- "clang"
os:
- "macos-10.15"
- "macos-11"
- "macos-12"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Override Xcode 13.0 if it's the default toolchain
- name: Remove stray upstream python binary symlinks under /usr/local
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
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete -print
brew unlink python && brew link --overwrite python
- name: Install dependencies
run: |
brew update
brew install autoconf automake pkg-config libtool python freetype fribidi little-cms2 luajit libass ffmpeg
brew install autoconf automake pkg-config libtool python freetype fribidi little-cms2 lua@5.1 libass ffmpeg meson
- name: Build
- name: Build with meson
run: |
./ci/build-macos.sh
./ci/build-macos.sh meson
env:
CC: "${{ matrix.cc }}"
TRAVIS_OS_NAME: "${{ matrix.os }}"
- name: Print configure log
- name: Print meson log
if: ${{ failure() }}
run: |
cat ./build/meson-logs/meson-log.txt
- name: Build with waf
run: |
./ci/build-macos.sh waf
env:
CC: "${{ matrix.cc }}"
TRAVIS_OS_NAME: "${{ matrix.os }}"
- name: Print waf log
if: ${{ failure() }}
run: |
cat ./build/config.log
linux:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-22.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
image: "registry.opensuse.org/home/mia/images/images/mpv-ci:stable-deps"
env:
CC: "${{ matrix.cc }}"
strategy:
@@ -96,41 +121,57 @@ jobs:
- "gcc"
- "clang"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install dependencies
run: |
./bootstrap.py
# workaround to avoid "fatal: unsafe repository" error
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Build
- name: Build with meson
run: |
./ci/build-tumbleweed.sh
./ci/build-tumbleweed.sh meson
- name: Print configure log
- name: Print meson log
if: ${{ failure() }}
run: |
cat ./build/meson-logs/meson-log.txt
- name: Build with waf
run: |
./ci/build-tumbleweed.sh waf
- name: Print waf log
if: ${{ failure() }}
run: |
cat ./build/config.log
freebsd:
runs-on: macos-10.15 # until https://github.com/actions/runner/issues/385
runs-on: macos-12 # until https://github.com/actions/runner/issues/385
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Test in FreeBSD VM
uses: vmactions/freebsd-vm@v0.1.5 # aka FreeBSD 13.0
uses: vmactions/freebsd-vm@v0
with:
usesh: true
prepare: |
# Requested in ci/build-freebsd.sh
pkg install -y \
cmake \
evdev-proto \
ffmpeg \
libplacebo \
libxkbcommon \
libXinerama \
libxpresent \
luajit \
meson \
openal-soft \
pkgconf \
python3 \
sdl2 \
sndio \
vulkan-headers \
wayland-protocols \
#
@@ -145,6 +186,7 @@ jobs:
libcdio-paranoia \
libdvdnav \
mujs \
pipewire \
pulseaudio \
rubberband \
sekrit-twc-zimg \
@@ -153,3 +195,13 @@ jobs:
#
run: |
./ci/build-freebsd.sh
- name: Print meson log
if: ${{ failure() }}
run: |
cat ./build/meson-logs/meson-log.txt
- name: Print waf log
if: ${{ failure() }}
run: |
cat ./build/config.log
+2
View File
@@ -36,3 +36,5 @@
/old_build
/Makefile
/subprojects
+70
View File
@@ -0,0 +1,70 @@
# Differences Between Meson and Waf
mpv currently supports two different build systems: waf and meson. In general,
option names between both build systems are mostly the same. In most cases,
``--enable-foo`` in waf becomes ``-Dfoo=enabled`` in meson. Likewise,
``--disable-foo`` becomes ``-Dfoo=disabled``. For the rest of this document,
Waf options will be noted as ``--foo`` while meson options are noted as
``foo``.
## Universal Options
Meson has several [universal options](https://mesonbuild.com/Builtin-options.html#universal-options)
that you get for free. In some cases, these overlapped with custom waf options.
* ``--libmpv-static`` and ``--libmpv-shared`` were combined into one option:
``libmpv``. Use ``default_library`` to control if you want to build static or
shared libraries.
* Waf had a boolean ``--optimize`` option. In meson, this is a universal option,
``optimization``, which can take several different values. In mpv's meson
build, the default is ``2``.
* Instead of ``--debug-build``, meson simply calls it ``debug``. It is enabled
by default.
## Changed Options
* The legacy lua names (``52``, ``52deb``, etc.) for ``--lua`` are not
supported in the meson build. Instead, pass the generic pkg-config values
such as ``lua52``, ``lua5.2``, etc.
* ``--lgpl`` was changed to ``gpl``. If ``gpl`` is false, the build is LGPL2.1+.
### Boolean Options
The following options are all booleans that accept ``true`` or ``false``
instead of ``enabled`` or ``disabled``.
* ``build-date``
* ``cplayer``
* ``gpl``
* ``libmpv``
* ``ta-leak-report``
* ``tests``
## Removed Options
There are options removed with no equivalent in the meson build.
* ``--asm`` was removed since it doesn't do anything.
* ``--android`` was removed since meson knows if the machine is android.
* ``--clang-compilation-database`` was removed. Meson can do this on its own
by invoking ninja (``ninja -t compdb``).
* ``--tvos`` was removed since it doesn't do anything.
* ``--static-build`` was removed. Use ``default_library``.
* ``--swift-static`` was removed. The swift library always dynamically links.
## Renamed Options
These are some other options that were renamed.
* ``--gl-wayland`` was renamed to ``egl-wayland``.
* ``--swift`` was renamed to ``swift-build``.
## Other
* The meson build supports passing the ``SOURCE_DATE_EPOCH`` environment variable
during the compilation step for those who want reproducibility without having to
disable the build date.
* The ``Configuration`` line shown by ``mpv -v`` does not show everything passed on
cli since meson does not have any easy way to access a user's argv. Instead, it
simply shows whatever the value of ``prefix`` is regardless if it was specified
or not.
+7 -2
View File
@@ -32,6 +32,13 @@ API changes
::
--- mpv 0.35.0 ---
2.0 - remove headers/functions of the obsolete opengl_cb API
- remove mpv_opengl_init_params.extra_exts field
- remove deprecated mpv_detach_destroy. Use mpv_destroy instead.
- remove obsolete mpv_suspend and mpv_resume
- remove deprecated SCRIPT_INPUT_DISPATCH, PAUSE and UNPAUSE, TRACKS_CHANGED
TRACK_SWITCHED, METADATA_UPDATE, CHAPTER_CHANGE events
--- mpv 0.33.0 ---
1.109 - add MPV_RENDER_API_TYPE_SW and related (software rendering API)
- inactivate the opengl_cb API (always fails to initialize now)
@@ -54,7 +61,6 @@ API changes
It is a good idea to write better wrappers for your use, though.
--- mpv 0.31.0 ---
1.107 - Deprecate MPV_EVENT_TICK
--- mpv 0.30.0 ---
1.106 - Add cancel_fn to mpv_stream_cb_info
1.105 - Fix deadlock problems with MPV_RENDER_PARAM_ADVANCED_CONTROL and if
@@ -72,7 +78,6 @@ API changes
- add mpv_abort_async_command()
1.102 - rename struct mpv_opengl_drm_osd_size to mpv_opengl_drm_draw_surface_size
- rename MPV_RENDER_PARAM_DRM_OSD_SIZE to MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE
--- mpv 0.29.0 ---
1.101 - add MPV_RENDER_PARAM_ADVANCED_CONTROL and related API
- add MPV_RENDER_PARAM_NEXT_FRAME_INFO and related symbols
+37 -37
View File
@@ -3,26 +3,26 @@ General usage
::
mpv infile -o outfile [-of outfileformat] [-ofopts formatoptions] [-orawts] \
mpv infile --o=outfile [--of=outfileformat] [--ofopts=formatoptions] [--orawts] \
[(any other mpv options)] \
-ovc outvideocodec [-ovcopts outvideocodecoptions] \
-oac outaudiocodec [-oacopts outaudiocodecoptions]
--ovc=outvideocodec [--ovcopts=outvideocodecoptions] \
--oac=outaudiocodec [--oacopts=outaudiocodecoptions]
Help for these options is provided if giving help as parameter, as in::
mpv -ovc help
mpv --ovc=help
The suboptions of these generally are identical to ffmpeg's (as option parsing
is simply delegated to ffmpeg). The option -ocopyts enables copying timestamps
is simply delegated to ffmpeg). The option --ocopyts enables copying timestamps
from the source as-is, instead of fixing them to match audio playback time
(note: this doesn't work with all output container formats); -orawts even turns
(note: this doesn't work with all output container formats); --orawts even turns
off discontinuity fixing.
Note that if neither -ofps nor -oautofps is specified, VFR encoding is assumed
and the time base is 24000fps. -oautofps sets -ofps to a guessed fps number
Note that if neither --ofps nor --oautofps is specified, VFR encoding is assumed
and the time base is 24000fps. --oautofps sets --ofps to a guessed fps number
from the input video. Note that not all codecs and not all formats support VFR
encoding, and some which do have bugs when a target bitrate is specified - use
-ofps or -oautofps to force CFR encoding in these cases.
--ofps or --oautofps to force CFR encoding in these cases.
Of course, the options can be stored in a profile, like this .config/mpv/mpv.conf
section::
@@ -48,7 +48,7 @@ to encoding. This is not the case anymore.)
One can then encode using this profile using the command::
mpv infile -o outfile.mp4 -profile myencprofile
mpv infile --o=outfile.mp4 --profile=myencprofile
Some example profiles are provided in a file
etc/encoding-profiles.conf; as for this, see below.
@@ -62,10 +62,10 @@ for.
Typical MPEG-4 Part 2 ("ASP", "DivX") encoding, AVI container::
mpv infile -o outfile.avi \
mpv infile --o=outfile.avi \
--vf=fps=25 \
-ovc mpeg4 -ovcopts qscale=4 \
-oac libmp3lame -oacopts ab=128k
--ovc=mpeg4 --ovcopts=qscale=4 \
--oac=libmp3lame --oacopts=b=128k
Note: AVI does not support variable frame rate, so the fps filter must be used.
The frame rate should ideally match the input (25 for PAL, 24000/1001 or
@@ -73,22 +73,22 @@ The frame rate should ideally match the input (25 for PAL, 24000/1001 or
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, Matroska (MKV) container::
mpv infile -o outfile.mkv \
-ovc libx264 -ovcopts preset=medium,crf=23,profile=baseline \
-oac libvorbis -oacopts qscale=3
mpv infile --o=outfile.mkv \
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
--oac=libopus --oacopts=qscale=3
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, MPEG-4 (MP4) container::
mpv infile -o outfile.mp4 \
-ovc libx264 -ovcopts preset=medium,crf=23,profile=baseline \
-oac aac -oacopts ab=128k
mpv infile --o=outfile.mp4 \
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
--oac=aac --oacopts=b=128k
Typical VP8 encoding, WebM (restricted Matroska) container::
mpv infile -o outfile.mkv \
-of webm \
-ovc libvpx -ovcopts qmin=6,b=1000000k \
-oac libvorbis -oacopts qscale=3
--of=webm \
--ovc=libvpx --ovcopts=qmin=6,b=1000000k \
--oac=libopus --oacopts=qscale=3
Device targets
@@ -111,18 +111,18 @@ section.
Refer to the top of that file for more comments - in a nutshell, the following
options are added by it::
-profile enc-to-dvdpal DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en
-profile enc-to-dvdntsc DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en
-profile enc-to-bb-9000 MP4 for Blackberry Bold 9000
-profile enc-to-nok-6300 3GP for Nokia 6300
-profile enc-to-psp MP4 for PlayStation Portable
-profile enc-to-iphone MP4 for iPhone
-profile enc-to-iphone-4 MP4 for iPhone 4 (double res)
-profile enc-to-iphone-5 MP4 for iPhone 5 (even larger res)
--profile=enc-to-dvdpal # DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en
--profile=enc-to-dvdntsc # DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en
--profile=enc-to-bb-9000 # MP4 for Blackberry Bold 9000
--profile=enc-to-nok-6300 # 3GP for Nokia 6300
--profile=enc-to-psp # MP4 for PlayStation Portable
--profile=enc-to-iphone # MP4 for iPhone
--profile=enc-to-iphone-4 # MP4 for iPhone 4 (double res)
--profile=enc-to-iphone-5 # MP4 for iPhone 5 (even larger res)
You can encode using these with a command line like::
mpv infile -o outfile.mp4 -profile enc-to-bb-9000
mpv infile --o=outfile.mp4 --profile=enc-to-bb-9000
Of course, you are free to override options set by these profiles by specifying
them after the -profile option.
@@ -133,19 +133,19 @@ What works
* Encoding at variable frame rate (default)
* Encoding at constant frame rate using --vf=fps=RATE
* 2-pass encoding (specify flags=+pass1 in the first pass's -ovcopts, specify
* 2-pass encoding (specify flags=+pass1 in the first pass's --ovcopts, specify
flags=+pass2 in the second pass)
* Hardcoding subtitles using vobsub, ass or srt subtitle rendering (just
configure mpv for the subtitles as usual)
* Hardcoding any other mpv OSD (e.g. time codes, using -osdlevel 3 and -vf
expand=::::1)
* Hardcoding any other mpv OSD (e.g. time codes, using --osdlevel=3 and
--vf=expand=::::1)
* Encoding directly from a DVD, network stream, webcam, or any other source
mpv supports
* Using x264 presets/tunings/profiles (by using profile=, tune=, preset= in the
-ovcopts)
--ovcopts)
* Deinterlacing/Inverse Telecine with any of mpv's filters for that
* Audio file converting: mpv -o outfile.mp3 infile.flac -no-video -oac
libmp3lame -oacopts ab=320k
* Audio file converting: mpv --o=outfile.m4a infile.flac --no-video
--oac=aac --oacopts=b=320k
What does not work yet
======================
+24
View File
@@ -26,6 +26,30 @@ Interface changes
::
--- mpv 0.35.0 ---
- add the `--vo=gpu-next` video output driver, as well as the options
`--allow-delayed-peak-detect`, `--builtin-scalers`,
`--interpolation-preserve` `--lut`, `--lut-type`, `--image-lut`,
`--image-lut-type` and `--target-lut` along with it.
- add `--target-colorspace-hint`
- add `--tone-mapping-crosstalk`
- add `--tone-mapping` options `auto`, `spline` and `bt.2446a`
- add `--inverse-tone-mapping`
- add `--gamut-mapping-mode`, replacing `--gamut-clipping` and `--gamut-warning`
- add `--tone-mapping-mode`, replacing `--tone-mapping-desaturate` and
`--tone-mapping-desaturate-exponent`.
- add `dolbyvision` sub-parameter to `format` video filter
- `--sub-visibility` no longer has any effect on secondary subtitles
- add `film-grain` sub-parameter to `format` video filter
- add experimental `--vo=dmabuf-wayland` video output driver
- add `--x11-present` for controlling whether to use xorg's present extension
- add `engine` option to the `rubberband` audio filter to support the new
engine introduced in rubberband 3.0.0. Defaults to `finer` (new engine).
- add `--wayland-configure-bounds` option
- deprecate `--gamma-factor`
- deprecate `--gamma-auto`
- remove `--vulkan-disable-events`
- add `--glsl-shader-opts`
--- mpv 0.34.0 ---
- deprecate selecting by card number with `--drm-connector`, add
`--drm-device` which can be used instead
+4 -4
View File
@@ -161,14 +161,14 @@ Available filters are:
Would play media at 1.2x normal speed, with audio at normal pitch.
Changing playback speed would change pitch, leaving audio tempo at
1.2x.
``scaletempo2[=option1:option2:...]``
Scales audio tempo without altering pitch.
The algorithm is ported from chromium and uses the
The algorithm is ported from chromium and uses the
Waveform Similarity Overlap-and-add (WSOLA) method.
It seems to achieve a higher audio quality than scaletempo and rubberband.
By default, the ``search-interval`` and ``window-size`` parameters
By default, the ``search-interval`` and ``window-size`` parameters
have the same values as in chromium.
``min-speed=<speed>``
@@ -180,7 +180,7 @@ Available filters are:
``search-interval=<amount>``
Length in milliseconds to search for best overlap position. (default: 30)
``window-size=<amount>``
Length in milliseconds of the overlap-and-add window. (default: 20)
+26 -5
View File
@@ -30,7 +30,8 @@ Available audio output drivers are:
explicitly reject multichannel output, as there is no way to detect
whether a certain channel layout is actually supported.
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
You can also try `using the upmix plugin
<https://github.com/mpv-player/mpv/wiki/ALSA-Surround-Sound-and-Upmixing>`_.
This setup enables multichannel audio on the ``default`` device
with automatic upmixing with shared access, so playing stereo
and multichannel audio at the same time will work as expected.
@@ -100,7 +101,7 @@ Available audio output drivers are:
exclusive mode (bypasses the sound server).
``openal``
OpenAL audio output driver. This is broken and does not work.
OpenAL audio output driver.
``--openal-num-buffers=<2-128>``
Specify the number of audio buffers to use. Lower values are better for
@@ -112,9 +113,7 @@ Available audio output drivers are:
``--openal-direct-channels=<yes|no>``
Enable OpenAL Soft's direct channel extension when available to avoid
tinting the sound with ambisonics or HRTF.
Channels are dropped when when they are not available as downmixing
will be disabled. Default: no.
tinting the sound with ambisonics or HRTF. Default: yes.
``pulse``
PulseAudio audio output driver
@@ -146,6 +145,22 @@ Available audio output drivers are:
Allow mpv to use PulseAudio even if the sink is suspended (default: no).
Can be useful if PulseAudio is running as a bridge to jack and mpv has its sink-input set to the one jack is using.
``pipewire``
PipeWire audio output driver
The following global options are supported by this audio output:
``--pipewire-buffer=<1-2000|native>``
Set the audio buffer size in milliseconds. A higher value buffers
more data, and has a lower probability of buffer underruns. A smaller
value makes the audio stream react faster, e.g. to playback speed
changes.
``--pipewire-remote=<remote>``
Specify the PipeWire remote daemon name to connect to via local UNIX
sockets.
An empty <remote> string uses the default remote named ``pipewire-0``.
``sdl``
SDL 1.2+ audio output driver. Should work on any platform supported by SDL
1.2, but may require the ``SDL_AUDIODRIVER`` environment variable to be set
@@ -219,5 +234,11 @@ Available audio output drivers are:
``no-waveheader`` option - with ``waveheader`` it's broken, because
it will write a WAVE header every time the file is opened.
``sndio``
Audio output to the OpenBSD sndio sound system
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
layouts.)
``wasapi``
Audio output to the Windows Audio Session API.
+6 -1
View File
@@ -142,4 +142,9 @@ Configurable Options
Default: 16
Set the font size used for the REPL and the console. This will be
multiplied by "scale."
multiplied by "scale".
``history_dedup``
Default: true
Remove duplicate entries in history as to only keep the latest one.
+35 -28
View File
@@ -431,7 +431,7 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
Playback is stopped. If idle mode (``--idle``) is enabled, the player
will enter idle mode, otherwise it will exit.
This comm and is similar to ``loadfile`` in that it only manipulates the
This command is similar to ``loadfile`` in that it only manipulates the
state of what to play next, without waiting until the current file is
unloaded, and the next one is loaded.
@@ -551,9 +551,9 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
``playback_only`` (``MPV_FORMAT_FLAG``)
Boolean indicating whether the process should be killed when playback
terminates (optional, default: true). If enabled, stopping playback
will automatically kill the process, and you can't start it outside of
playback.
of the current playlist entry terminates (optional, default: true). If
enabled, stopping playback will automatically kill the process, and you
can't start it outside of playback.
``capture_size`` (``MPV_FORMAT_INT64``)
Integer setting the maximum number of stdout plus stderr bytes that can
@@ -581,7 +581,7 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
instead. (Unlike the underlying OS mechanisms, the mpv command cannot
start a process with empty environment. Fortunately, that is completely
useless.) The format of the list is as in the ``execle()`` syscall. Each
string item defines an environment variable as in ``NANME=VALUE``.
string item defines an environment variable as in ``NAME=VALUE``.
On Lua, you may use ``utils.get_env_list()`` to retrieve the current
environment if you e.g. simply want to add a new variable.
@@ -600,12 +600,14 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
The command returns the following result (as ``MPV_FORMAT_NODE_MAP``):
``status`` (``MPV_FORMAT_INT64``)
The raw exit status of the process. It will be negative on error. The
meaning of negative values is undefined, other than meaning error (and
does not correspond to OS low level exit status values).
Typically this is the process exit code (0 or positive) if the process
terminates normally, or negative for other errors (failed to start,
terminated by mpv, and others). The meaning of negative values is
undefined, other than meaning error (and does not correspond to OS low
level exit status values).
On Windows, it can happen that a negative return value is returned
even if the process exits gracefully, because the win32 ``UINT`` exit
On Windows, it can happen that a negative return value is returned even
if the process terminates normally, because the win32 ``UINT`` exit
code is assigned to an ``int`` variable before being set as ``int64_t``
field in the result map. This might be fixed later.
@@ -616,9 +618,9 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
Same as ``stdout``, but for stderr.
``error_string`` (``MPV_FORMAT_STRING``)
Empty string if the process exited gracefully. The string ``killed`` if
the process was terminated in an unusual way. The string ``init`` if the
process could not be started.
Empty string if the process terminated normally. The string ``killed``
if the process was terminated in an unusual way. The string ``init`` if
the process could not be started.
On Windows, ``killed`` is only returned when the process has been
killed by mpv as a result of ``playback_only`` being set to true.
@@ -633,17 +635,19 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
it was somehow killed or returned an error status has to be queried from
the result value.
This command can be asynchronously aborted via API.
This command can be asynchronously aborted via API. Also see `Asynchronous
command details`_. Only the ``run`` command can start processes in a truly
detached way.
In all cases, the subprocess will be terminated on player exit. Also see
`Asynchronous command details`_. Only the ``run`` command can start
processes in a truly detached way.
.. note:: The subprocess will always be terminated on player exit if it
wasn't started in detached mode, even if ``playback_only`` is
false.
.. admonition:: Warning
Don't forget to set the ``playback_only`` field if you want the command
run while the player is in idle mode, or if you don't want that end of
playback kills the command.
Don't forget to set the ``playback_only`` field to false if you want
the command to run while the player is in idle mode, or if you don't
want the end of playback to kill the command.
.. admonition:: Example
@@ -668,7 +672,7 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_).
``quit-watch-later [<code>]``
Exit player, and store current playback position. Playing that file later
will seek to the previous position on start. The (optional) argument is
exactly as in the ``quit`` command.
exactly as in the ``quit`` command. See `RESUMING PLAYBACK`_.
``sub-add <url> [<flags> [<title> [<lang>]]]``
Load the given subtitle file or stream. By default, it is selected as
@@ -1600,10 +1604,8 @@ This list uses the event name field value, and the C API symbol in brackets:
``data``
The new value of the property.
The following events also happen, but are deprecated: ``tracks-changed``,
``track-switched``, ``pause``, ``unpause``, ``metadata-update``, ``idle``,
``tick``, ``chapter-change``. Use ``mpv_observe_property()``
(Lua: ``mp.observe_property()``) instead.
The following events also happen, but are deprecated: ``idle``, ``tick``
Use ``mpv_observe_property()`` (Lua: ``mp.observe_property()``) instead.
Hooks
~~~~~
@@ -1817,7 +1819,7 @@ Property list
.. note::
Most options can be set as runtime via properties as well. Just remove the
Most options can be set at runtime via properties as well. Just remove the
leading ``--`` from the option name. These are not documented below, see
`OPTIONS`_ instead. Only properties which do not exist as option with the
same name, or which have very different behavior from the options are
@@ -2979,7 +2981,7 @@ Property list
If tracks of the requested type are selected via ``--lavfi-complex``, the
first one is returned.
``chapter-list``
``chapter-list`` (RW)
List of chapters, current entry marked. Currently, the raw property value
is useless.
@@ -3070,7 +3072,8 @@ Property list
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/
A list of tags can be found here:
https://aeg-dev.github.io/AegiSite/docs/3.2/ass_tags/
``vo-configured``
Whether the VO is configured right now. Usually this corresponds to whether
@@ -3387,6 +3390,10 @@ Property list
not a map, as order matters and duplicate entries are possible. Recursive
profiles are not expanded, and show up as special ``profile`` options.
The ``profile-restore`` field is currently missing if it holds the default
value (either because it was not set, or set explicitly to ``default``),
but in the future it might hold the value ``default``.
``command-list``
The list of input commands. This returns an array of maps, where each map
node represents a command. This map currently only has a single entry:
+4 -10
View File
@@ -73,12 +73,6 @@ Unsupported Lua APIs and their JS alternatives
``utils.to_string(v)`` see ``dump`` below.
``mp.suspend()`` JS: none (deprecated).
``mp.resume()`` JS: none (deprecated).
``mp.resume_all()`` JS: none (deprecated).
``mp.get_next_timeout()`` see event loop below.
``mp.dispatch_events([allow_wait])`` see event loop below.
@@ -97,7 +91,7 @@ Where the Lua APIs use ``nil`` to indicate error, JS APIs use ``undefined``.
``mp.command_native(table [,def])`` (LE)
``id = mp.command_native_async(table [,fn])`` (LE) Notes: ``id`` is true-thy on
success, ``fn`` is called always a-sync, ``error`` is empty string on success.
success, ``error`` is empty string on success.
``mp.abort_async_command(id)``
@@ -221,9 +215,9 @@ Additional utilities
``undefined`` if the variable is not defined.
``mp.utils.get_user_path(path)``
Expands (mpv) meta paths like ``~/x``, ``~~/y``, ``~~desktop/z`` etc.
``read_file``, ``write_file``, ``append_file`` and ``require`` already use
this internally.
Trivial wrapper of the ``expand-path`` mpv command, returns a string.
``read_file``, ``write_file``, ``append_file`` and ``require`` already
expand the path internally and accept mpv meta-paths like ``~~desktop/foo``.
``mp.utils.read_file(fname [,max])``
Returns the content of file ``fname`` as string. If ``max`` is provided and
+1 -1
View File
@@ -64,7 +64,7 @@ Linkage to libmpv
-----------------
The current implementation requires that your plugins are **not** linked against
libmpv. What your plugins uses are not symbols from a libmpv binary, but
libmpv. What your plugins use are not symbols from a libmpv binary, but
symbols from the mpv host binary.
Examples
+2 -12
View File
@@ -191,6 +191,8 @@ The ``mp`` module is preloaded, although it can be loaded manually with
If starting the command failed for some reason, ``nil, error`` is returned,
and ``fn`` is called indicating failure, using the same error value.
``fn`` is always called asynchronously, even if the command failed to start.
``mp.abort_async_command(t)``
Abort a ``mp.command_native_async`` call. The argument is the return value
of that command (which starts asynchronous execution of the command).
@@ -527,18 +529,6 @@ Advanced mp functions
These also live in the ``mp`` module, but are documented separately as they
are useful only in special situations.
``mp.suspend()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.resume()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.resume_all()``
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.get_wakeup_pipe()``
Calls ``mpv_get_wakeup_pipe()`` and returns the read end of the wakeup
pipe. This is deprecated, but still works. (See ``client.h`` for details.)
+50 -36
View File
@@ -39,9 +39,12 @@ LIRC support - configure remotes as input devices instead).
See the ``--input-`` options for ways to customize it.
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.
The following listings are not necessarily complete. See ``etc/input.conf``
in the mpv source files for a list of default bindings. User ``input.conf``
files and Lua scripts can define additional key bindings.
See `COMMAND INTERFACE`_ and `Key names`_ sections for more details on
configuring keybindings.
See also ``--input-test`` for interactive binding details by key, and the
`stats`_ built-in script for key bindings list (including print to terminal).
@@ -107,7 +110,8 @@ q
Q
Like ``q``, but store the current playback position. Playing the same file
later will resume at the old playback position if possible.
later will resume at the old playback position if possible. See
`RESUMING PLAYBACK`_.
/ and *
Decrease/increase volume.
@@ -124,6 +128,9 @@ m
\#
Cycle through the available audio tracks.
E
Cycle through the available Editions.
f
Toggle fullscreen (see also ``--fs``).
@@ -767,7 +774,7 @@ the following options:
[something]
profile-restore=copy-equal
vf-add=rotate=90
vf-add=rotate=PI/2 # rotate by 90 degrees
Then running these commands will result in behavior as commented:
@@ -775,9 +782,9 @@ the following options:
set vf vflip
apply-profile something
vf-add=hflip
vf add hflip
apply-profile something
# vf == vflip,rotate=90,hflip,rotate=90
# vf == vflip,rotate=PI/2,hflip,rotate=PI/2
apply-profile something restore
# vf == vflip
@@ -841,7 +848,7 @@ and unintuitive behavior.
profile-desc=Mess up video when entering fullscreen
profile-cond=fullscreen
profile-restore=copy
vf-add=rotate=90
vf-add=rotate=PI/2 # rotate by 90 degrees
This appends the ``rotate`` filter to the video filter chain when entering
fullscreen. When leaving fullscreen, the ``vf`` option is set to the value
@@ -854,7 +861,7 @@ and unintuitive behavior.
[something]
profile-cond=fullscreen
vf-add=@rot:rotate=90
vf-add=@rot:rotate=PI/2
[something-inv]
profile-cond=not fullscreen
@@ -1088,6 +1095,33 @@ Additional options that can be tried:
- without audio ``--framedrop=no --speed=1.01`` may help for live sources
(results can be mixed)
RESUMING PLAYBACK
=================
mpv is capable of storing the playback position of the currently playing file
and resume from there the next time that file is played. This is done with the
commands ``quit-watch-later`` (bound to Shift+Q by default) and
``write-watch-later-config``, and with the ``--save-position-on-quit`` option.
The difference between always quitting with a key bound to ``quit-watch-later``
and using ``--save-position-on-quit`` is that the latter will save the playback
position even when mpv is closed with a method other than a keybinding, for
example if you shutdown your system without closing mpv beforehand, unless of
course mpv is terminated abruptly and doesn't have the time to save (e.g. with
the KILL Unix signal).
mpv also stores options other than the playback position when they have been
modified after playback began, for example the volume and the fullscreen state,
and restores their values the next time the file is played. Which options are
saved can be configured with the ``--watch-later-options`` option.
When playing multiple playlist entries, mpv checks if one them has a resume
config file associated, and if it finds one it restarts playback from it. For
example, if you use ``quit-watch-later`` on the 5th episode of a show, and
later play all the episodes, mpv will automatically resume playback from
episode 5.
More options to configure this functionality are listed in `Watch Later`_.
PROTOCOLS
=========
@@ -1321,36 +1355,16 @@ a VO using the OS GUI API is active). ``--stop-screensaver=no`` disables this.
A common problem is that Linux desktop environments ignore the standard
screensaver APIs on which mpv relies. In particular, mpv uses the Screen Saver
extension (XSS) on X11, and the idle-inhibit on Wayland.
extension (XSS) on X11, and the idle-inhibit protocol on Wayland.
GNOME is one of the worst offenders, and ignores even the now widely supported
idle-inhibit protocol. (This is either due to a combination of malice and
incompetence, but since implementing this protocol would only take a few lines
of code, it is most likely the former. You will also notice how GNOME advocates
react offended whenever their sabotage is pointed out, which indicates either
hypocrisy, or even worse ignorance.)
Such incompatible desktop environments (i.e. which ignore standards) typically
require using a DBus API. This is ridiculous in several ways. The immediate
practical problem is that it would require adding a quite unwieldy dependency
for a DBus library, somehow integrating its mainloop into mpv, and other
generally unacceptable things.
However, since mpv does not officially support GNOME, this is not much of a
problem. If you are one of those miserable users who want to use mpv on GNOME,
report a bug on the GNOME issue tracker:
https://gitlab.gnome.org/groups/GNOME/-/issues
Alternatively, you may be able to write a Lua script that calls the
``xdg-screensaver`` command line program. (By the way, this a command line
program is an utterly horrible kludge that tries to identify your DE, and then
tries to send the correct DBus command via a DBus CLI tool.) If you find the
idea of having to write a script just so your screensaver doesn't kick in
ridiculous, do not use GNOME, or use GNOME video software instead of mpv (good
luck).
GNOME in particular still ignores the idle-inhibit protocol, and has its own
D-Bus interfaces for display power management, which mpv does not support.
Before mpv 0.33.0, the X11 backend ran ``xdg-screensaver reset`` in 10 second
intervals when not paused. This hack was removed in 0.33.0.
intervals when not paused in order to support screensaver inhibition in these
environments. This functionality was removed in 0.33.0, but it is possible to
call the ``xdg-screensaver`` command line program from a user script instead.
.. include:: options.rst
+382 -221
View File
@@ -298,10 +298,10 @@ Playback Control
:no: Never use precise seeks.
:absolute: Use precise seeks if the seek is to an absolute position in the
file, such as a chapter seek, but not for relative seeks like
the default behavior of arrow keys (default).
the default behavior of arrow keys.
:default: Like ``absolute``, but enable hr-seeks in audio-only cases. The
exact behavior is implementation specific and may change with
new releases.
new releases (default).
:yes: Use precise seeks whenever possible.
:always: Same as ``yes`` (for compatibility).
@@ -746,23 +746,6 @@ Program Behavior
Note that the ``--no-config`` option takes precedence over this option.
``--save-position-on-quit``
Always save the current playback position on quit. When this file is
played again later, the player will seek to the old playback position on
start. This does not happen if playback of a file is stopped in any other
way than quitting. For example, going to the next file in the playlist
will not save the position, and start playback at beginning the next time
the file is played.
This behavior is disabled by default, but is always available when quitting
the player with Shift+Q.
``--watch-later-directory=<path>``
The directory in which to store the "watch later" temporary files.
The default is a subdirectory named "watch_later" underneath the
config directory (usually ``~/.config/mpv/``).
``--dump-stats=<filename>``
Write certain statistics to the given file. The file is truncated on
opening. The file will contain raw samples, each with a timestamp. To
@@ -804,18 +787,6 @@ Program Behavior
Pretend that all files passed to mpv are concatenated into a single, big
file. This uses timeline/EDL support internally.
``--no-resume-playback``
Do not restore playback position from the ``watch_later`` configuration
subdirectory (usually ``~/.config/mpv/watch_later/``).
See ``quit-watch-later`` input command.
``--resume-playback-check-mtime``
Only restore the playback position from the ``watch_later`` configuration
subdirectory (usually ``~/.config/mpv/watch_later/``) if the file's
modification time is the same as at the time of saving. This may prevent
skipping forward in files with the same name which have different content.
(Default: ``no``)
``--profile=<profile1,profile2,...>``
Use the given profile(s), ``--profile=help`` displays a list of the
defined profiles.
@@ -851,42 +822,6 @@ 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.
.. warning::
This option may expose privacy-sensitive information and is thus
disabled by default.
``--ignore-path-in-watch-later-config``
Ignore path (i.e. use filename only) when using watch later feature.
(Default: disabled)
``--show-profile=<profile>``
Show the description and content of a profile. Lists all profiles if no
parameter is provided.
@@ -1046,10 +981,9 @@ Program Behavior
the overlay permanent).
``--load-osd-console=<yes|no>``
Enable the builtin script that shows a console on a key binding and lets
you enter commands (default: yes). By default,. The ``´`` key is used to
show the console, and ``ESC`` to hide it again. (This is based on a user
script called ``repl.lua``.)
Enable the built-in script that shows a console on a key binding and lets
you enter commands (default: yes). The ````` key is used to show the
console by default, and ``ESC`` to hide it again.
``--load-auto-profiles=<yes|no|auto>``
Enable the builtin script that does auto profiles (default: auto). See
@@ -1062,6 +996,75 @@ Program Behavior
only by mpv internally, or mpv-provided scripts, config files, or .desktop
files. See `PSEUDO GUI MODE`_ for details.
Watch Later
-----------
``--save-position-on-quit``
Always save the current playback position on quit. When this file is
played again later, the player will seek to the old playback position on
start. This does not happen if playback of a file is stopped in any other
way than quitting. For example, going to the next file in the playlist
will not save the position, and start playback at beginning the next time
the file is played.
This behavior is disabled by default, but is always available when quitting
the player with Shift+Q.
See `RESUMING PLAYBACK`_.
``--watch-later-directory=<path>``
The directory in which to store the "watch later" temporary files.
The default is a subdirectory named "watch_later" underneath the
config directory (usually ``~/.config/mpv/``).
``--no-resume-playback``
Do not restore playback position from the ``watch_later`` configuration
subdirectory (usually ``~/.config/mpv/watch_later/``).
``--resume-playback-check-mtime``
Only restore the playback position from the ``watch_later`` configuration
subdirectory (usually ``~/.config/mpv/watch_later/``) if the file's
modification time is the same as at the time of saving. This may prevent
skipping forward in files with the same name which have different content.
(Default: ``no``)
``--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.
.. warning::
This option may expose privacy-sensitive information and is thus
disabled by default.
``--ignore-path-in-watch-later-config``
Ignore path (i.e. use filename only) when using watch later feature.
(Default: disabled)
Video
-----
@@ -1176,26 +1179,40 @@ Video
Whether hardware decoding is actually done depends on the video codec. If
hardware decoding is not possible, mpv will fall back on software decoding.
Hardware decoding is not enabled by default, because it is typically an
additional source of errors. It is worth using only if your CPU is too
slow to decode a specific video.
Hardware decoding is not enabled by default, to keep the out-of-the-box
configuration as reliable as possible. However, when using modern hardware,
hardware video decoding should work correctly, offering reduced CPU usage,
and possibly lower power consumption. On older systems, it may be necessary
to use hardware decoding due to insufficient CPU resources; and even on
modern systems, sufficiently complex content (eg: 4K60 AV1) may require it.
.. note::
Use the ``Ctrl+h`` shortcut to toggle hardware decoding at runtime. It
toggles this option between ``auto`` and ``no``.
Always enabling HW decoding by putting it into the config file is
discouraged. If you use the Ubuntu package, delete ``/etc/mpv/mpv.conf``,
as the package tries to enable HW decoding by default by setting
``hwdec=vaapi`` (which is less than ideal, and may even cause
sub-optimal wrappers to be used). Or at least change it to
``hwdec=auto-safe``.
If you decide you want to use hardware decoding by default, the general
recommendation is to try out decoding with the command line option, and
prove to yourself that it works as desired for the content you care
about. After that, you can add it to your config file.
Use one of the auto modes if you want to enable hardware decoding.
Explicitly selecting the mode is mostly meant for testing and debugging.
It's a bad idea to put explicit selection into the config file if you
want thing to just keep working after updates and so on.
When testing, you should start by using ``hwdec=auto-safe`` as it will
limit itself to choosing from hwdecs that are actively supported by the
development team. If that doesn't result in working hardware decoding,
you can try ``hwdec=auto`` to have it attempt to load every possible
hwdec, but if ``auto-safe`` didn't work, you will probably need to know
exactly which hwdec matches your hardware and read up on that entry
below.
If ``auto-safe`` or ``auto`` produced the desired results, we recommend
just sticking with that and only setting a specific hwdec in your config
file if it is really necessary.
If you use the Ubuntu package, keep in mind that their
``/etc/mpv/mpv.conf`` contains ``hwdec=vaapi``, which is less than
ideal as it may not be the right choice for your system, and it may end
up using an inefficient wrapper library under the covers. We recommend
removing this line or deleting the file altogether.
.. note::
@@ -1210,8 +1227,7 @@ Video
``Ctrl+h`` default binding to enable it at runtime.
- If you're not sure, but want hardware decoding always enabled by
default, put ``hwdec=auto-safe`` into your ``mpv.conf``, and
acknowledge that this use case is not "really" supported and may cause
problems.
acknowledge that this may cause problems.
- If you want to test available hardware decoding methods, pass
``--hwdec=auto --hwdec-codecs=all`` and look at the terminal output.
- If you're a developer, or want to perform elaborate tests, you may
@@ -1224,26 +1240,35 @@ Video
:yes: exactly the same as ``auto``
:auto-safe: enable any whitelisted hw decoder (see below)
:auto-copy: enable best hw decoder with copy-back (see below)
:vdpau: requires ``--vo=gpu`` with X11, or ``--vo=vdpau`` (Linux only)
: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)
Actively supported hwdecs:
:d3d11va: requires ``--vo=gpu`` with ``--gpu-context=d3d11`` or
``--gpu-context=angle`` (Windows 8+ only)
:d3d11va-copy: copies video back to system RAM (Windows 8+ only)
: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 (macOS 10.8 or iOS 9.0 and up)
:vaapi: requires ``--vo=gpu``, ``--vo=vaapi`` or ``--vo=dmabuf-wayland`` (Linux only)
:vaapi-copy: copies video back into system RAM (Linux with some GPUs only)
:nvdec: requires ``--vo=gpu`` (Any platform CUDA is available)
:nvdec-copy: copies video back to system RAM (Any platform CUDA is available)
:drm: requires ``--vo=gpu`` (Linux only)
:drm-copy: copies video back to system RAM (Linux ony)
Other hwdecs (only use if you know you have to):
:dxva2: requires ``--vo=gpu`` with ``--gpu-context=d3d11``,
``--gpu-context=angle`` or ``--gpu-context=dxinterop``
(Windows only)
:dxva2-copy: copies video back to system RAM (Windows only)
:d3d11va: requires ``--vo=gpu`` with ``--gpu-context=d3d11`` or
``--gpu-context=angle`` (Windows 8+ only)
:d3d11va-copy: copies video back to system RAM (Windows 8+ only)
:mediacodec: requires ``--vo=mediacodec_embed`` (Android only)
:vdpau: requires ``--vo=gpu`` with X11, or ``--vo=vdpau`` (Linux only)
:vdpau-copy: copies video back into system RAM (Linux with some GPUs only)
:mediacodec: requires ``--vo=gpu --gpu-context=android``
or ``--vo=mediacodec_embed`` (Android only)
:mediacodec-copy: copies video back to system RAM (Android only)
:mmal: requires ``--vo=gpu`` (Raspberry Pi only - default if available)
:mmal-copy: copies video back to system RAM (Raspberry Pi only)
:nvdec: requires ``--vo=gpu`` (Any platform CUDA is available)
:nvdec-copy: copies video back to system RAM (Any platform CUDA is available)
:cuda: requires ``--vo=gpu`` (Any platform CUDA is available)
:cuda-copy: copies video back to system RAM (Any platform CUDA is available)
:crystalhd: copies video back to system RAM (Any platform supported by hardware)
@@ -1280,7 +1305,7 @@ Video
Because these copy the decoded video back to system RAM, they're often less
efficient than the direct modes, and may not help too much over software
decoding.
decoding if you are short on CPU resources.
.. note::
@@ -1309,7 +1334,12 @@ Video
In theory, hardware decoding does not reduce video quality (at least
for the codecs h264 and HEVC). However, due to restrictions in video
output APIs, as well as bugs in the actual hardware decoders, there can
be some loss, or even blatantly incorrect results.
be some loss, or even blatantly incorrect results. This has largely
ceased to be a problem with modern hardware, but there is a lot of
hardware out there, so caveat emptor. Known problems are discussed
below, but the list cannot be considered exhaustive, as even hwdecs that
work well on certain hardware generations may be problematic on other
ones.
In some cases, RGB conversion is forced, which means the RGB conversion
is performed by the hardware decoding API, instead of the shaders
@@ -1325,10 +1355,6 @@ Video
doesn't support 10 bit or HDR encodings, so these limitations are
unlikely to be relevant.
``vaapi`` and ``d3d11va`` are safe. Enabling deinterlacing (or simply
their respective post-processing filters) will possibly at least reduce
color quality by converting the output to a 8 bit format.
``dxva2`` is not safe. It appears to always use BT.601 for forced RGB
conversion, but actual behavior depends on the GPU drivers. Some drivers
appear to convert to limited range RGB, which gives a faded appearance.
@@ -1339,6 +1365,11 @@ Video
``rpi`` always uses the hardware overlay renderer, even with
``--vo=gpu``.
``mediacodec`` is not safe. It forces RGB conversion (not with ``-copy``)
and how well it handles non-standard colorspaces is not known.
In the rare cases where 10-bit is supported the bit depth of the output
will be reduced to 8.
``cuda`` should usually be safe, but depending on how a file/stream
has been mixed, it has been reported to corrupt the timestamps causing
glitched, flashing frames. It can also sometimes cause massive
@@ -1350,20 +1381,9 @@ Video
conversion. It also discards the top left pixel of each frame for
some reason.
All other methods, in particular the copy-back methods (like
``dxva2-copy`` etc.) should hopefully be safe, although they can still
cause random decoding issues. At the very least, they shouldn't affect
the colors of the image.
In particular, ``auto-copy`` will only select "safe" modes
(although potentially slower than other methods), but there's still no
guarantee the chosen hardware decoder will actually work correctly.
In general, it's very strongly advised to avoid hardware decoding
unless **absolutely** necessary, i.e. if your CPU is insufficient to
decode the file in questions. If you run into any weird decoding issues,
frame glitches or discoloration, and you have ``--hwdec`` turned on,
the first thing you should try is disabling it.
If you run into any weird decoding issues, frame glitches or
discoloration, and you have ``--hwdec`` turned on, the first thing you
should try is disabling it.
``--gpu-hwdec-interop=<auto|all|no|name>``
This option is for troubleshooting hwdec interop issues. Since it's a
@@ -1532,7 +1552,7 @@ Video
video will be either cut off, or black bars are added.
This value is multiplied with the value derived from ``--video-zoom`` and
the normal video aspect aspect ratio. This option is disabled if the
the normal video aspect ratio. This option is disabled if the
``--no-keepaspect`` option is used.
``--video-align-x=<-1-1>``, ``--video-align-y=<-1-1>``
@@ -1670,6 +1690,17 @@ Video
the number of packets that could not be decoded. Values below an unspecified
count will not have this problem, because mpv retains the packets.
``--vd-lavc-film-grain=<auto|cpu|gpu>``
Enables film grain application on the GPU. If video decoding is done on
the CPU, doing film grain application on the GPU can speed up decoding.
This option can also help hardware decoding, as it can reduce the number
of frame copies done.
By default, it's set to ``auto``, so if the VO supports film grain
application, then it will be treated as ``gpu``. If the VO does not
support this, then it will be treated as ``cpu``, regardless of the setting.
Currently, only ``gpu-next`` supports film grain application.
``--vd-lavc-dr=<yes|no>``
Enable direct rendering (default: yes). If this is set to ``yes``, the
video will be decoded directly to GPU video memory (or staging buffers).
@@ -1677,9 +1708,7 @@ Video
slow hardware. This works only with the following VOs:
- ``gpu``: requires at least OpenGL 4.4 or Vulkan.
(In particular, this can't be made work with ``opengl-cb``, but the libmpv
render API has optional support.)
- ``libmpv``: The libmpv render API has optional support.
Using video filters of any kind that write to the image data (or output
newly allocated frames) will silently disable the DR code path.
@@ -1687,7 +1716,7 @@ Video
``--vd-lavc-bitexact``
Only use bit-exact algorithms in all decoding steps (for codec testing).
``--vd-lavc-fast`` (MPEG-2, MPEG-4, and H.264 only)
``--vd-lavc-fast`` (MPEG-1/2 and H.264 only)
Enable optimizations which do not comply with the format specification and
potentially cause problems, like simpler dequantization, simpler motion
compensation, assuming use of the default quantization matrix, assuming YUV
@@ -1713,12 +1742,14 @@ Video
no, libavcodec won't output frames that were either decoded before an
initial keyframe was decoded, or frames that are recognized as corrupted.
``--vd-lavc-skiploopfilter=<skipvalue> (H.264 only)``
Skips the loop filter (AKA deblocking) during H.264 decoding. Since
``--vd-lavc-skiploopfilter=<skipvalue>`` (H.264, HEVC only)
Skips the loop filter (AKA deblocking) during decoding. Since
the filtered frame is supposed to be used as reference for decoding
dependent frames, this has a worse effect on quality than not doing
deblocking on e.g. MPEG-2 video. But at least for high bitrate HDTV,
this provides a big speedup with little visible quality loss.
Codecs other than H.264 or HEVC may have partial support for this option
(often only ``all`` and ``none``).
``<skipvalue>`` can be one of the following:
@@ -1730,7 +1761,7 @@ Video
:nonkey: Skip all frames except keyframes.
:all: Skip all frames.
``--vd-lavc-skipidct=<skipvalue> (MPEG-1/2 only)``
``--vd-lavc-skipidct=<skipvalue>`` (MPEG-1/2/4 only)
Skips the IDCT step. This degrades quality a lot in almost all cases
(see skiploopfilter for available skip values).
@@ -1753,7 +1784,7 @@ Video
Normally, this is autodetected by libavcodec. But if the bitstream contains
no x264 version info (or it was somehow skipped), and the stream was in fact
encoded by an old x264 version (build 150 or earlier), and if the stream
uses ``4:4:4`` chroma, then libavcodec will by default show corrupted video.
uses 4:4:4 chroma, then libavcodec will by default show corrupted video.
This option sets the libavcodec ``x264_build`` option to ``150``, which
means that if the stream contains no version info, or was not encoded by
x264 at all, it assumes it was encoded by the old version. Enabling this
@@ -1997,9 +2028,9 @@ Audio
Using this mode is recommended for direct hardware output, especially
over HDMI (see HDMI warning below).
- ``--audio-channels=stereo``
Force a plain stereo downmix. This is a special-case of the previous
item. (See paragraphs below for implications.)
- ``--audio-channels=<stereo|mono>``
Force a downmix to stereo or mono. These are special-cases of the
previous item. (See paragraphs below for implications.)
If a list of layouts is given, each item can be either an explicit channel
layout name (like ``5.1``), or a channel number. Channel numbers refer to
@@ -2617,11 +2648,6 @@ Subtitles
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
@@ -2683,12 +2709,6 @@ Subtitles
``--sub-border-color=<color>``
See ``--sub-color``. Color used for the sub font border.
.. note::
ignored when ``--sub-back-color`` is
specified (or more exactly: when that option is not set to completely
transparent).
``--sub-border-size=<size>``
Size of the sub font border in scaled pixels (see ``--sub-font-size``
for details). A value of 0 disables borders.
@@ -2755,7 +2775,7 @@ Subtitles
``--sub-justify=<auto|left|center|right>``
Control how multi line subs are justified irrespective of where they
are aligned (default: ``auto`` which justifies as defined by
``--sub-align-y``).
``--sub-align-x``).
Left justification is recommended to make the subs easier to read
as it is easier for the eyes.
@@ -2767,6 +2787,12 @@ Subtitles
``--sub-shadow-color=<color>``
See ``--sub-color``. Color used for sub text shadow.
.. note::
ignored when ``--sub-back-color`` is
specified (or more exactly: when that option is not set to completely
transparent).
``--sub-shadow-offset=<size>``
Displacement of the sub text shadow in scaled pixels (see
``--sub-font-size`` for details). A value of 0 disables shadows.
@@ -2938,7 +2964,7 @@ Window
``--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).
there is no next file to be played (and ``--loop`` is not used).
Instead, pause the player. When trying to seek beyond end of the file, the
player will attempt to seek to the last frame.
@@ -3262,10 +3288,12 @@ Window
1). A value of 1 means square pixels (correct for (almost?) all LCDs). See
also ``--monitoraspect`` and ``--video-aspect-override``.
``--stop-screensaver``, ``--no-stop-screensaver``
``--stop-screensaver=<yes|no|always>``
Turns off the screensaver (or screen blanker and similar mechanisms) at
startup and turns it on again on exit (default: yes). The screensaver is
always re-enabled when the player is paused.
startup and turns it on again on exit (default: yes). When using ``yes``,
the screensaver will re-enable when playback is not active. ``always`` will
always disable the screensaver. Note that stopping the screensaver is only
possible if a video output is available (i.e. there is an open mpv window).
This is not supported on all video outputs or platforms. Sometimes it is
implemented, but does not work (especially with Linux "desktops"). Read the
@@ -3295,7 +3323,7 @@ Window
On Android, the ID is interpreted as ``android.view.Surface``. Pass it as a
value cast to ``intptr_t``. Use with ``--vo=mediacodec_embed`` and
``--hwdec=mediacodec`` for direct rendering using MediaCodec, or with
``--vo=gpu --gpu-context=android`` (with or without ``--hwdec=mediacodec-copy``).
``--vo=gpu --gpu-context=android`` (with or without ``--hwdec=mediacodec``).
``--no-window-dragging``
Don't move the window when clicking on it and moving the mouse pointer.
@@ -3336,6 +3364,23 @@ Window
``never`` asks the window manager to never disable the compositor.
``--x11-present=<no|auto|yes>``
Whether or not to use presentation statistics from X11's presentation
extension (default: ``auto``).
mpv asks X11 for present events which it then may use for more accurate
frame presentation. This only has an effect if ``--video-sync=display-...``
is being used.
The auto option enumerates XRandr providers for autodetection. If amd, radeon,
intel, or nouveau (the standard x86 Mesa drivers) is found and nvidia is NOT
found, presentation feedback is enabled. Other drivers are not assumed to
work, so they are not enabled automatically.
``yes`` or ``no`` can still be passed regardless to enable/disable this
mechanism in case there is good/bad behavior with whatever your combination
of hardware/drivers/etc. happens to be.
Disc Devices
------------
@@ -4047,6 +4092,10 @@ OSD
See `Property Expansion`_.
``--osd-playing-msg-duration=<time>``
Set the duration of ``osd-playing-msg`` in ms. If this is unset,
``osd-playing-msg`` stays on screen for the duration of ``osd-duration``.
``--osd-bar-align-x=<-1-1>``
Position of the OSD bar. -1 is far left, 0 is centered, 1 is far right.
Fractional values (like 0.5) are allowed.
@@ -4182,6 +4231,7 @@ Screenshot
:jpg: JPEG (default)
:jpeg: JPEG (alias for jpg)
:webp: WebP
:jxl: JPEG XL
``--screenshot-tag-colorspace=<yes|no>``
Tag screenshots with the appropriate colorspace.
@@ -4327,6 +4377,16 @@ Screenshot
more CPU time. Note that this also affects the screenshot quality when used
with lossy WebP files. The default is 4.
``--screenshot-jxl-distance=<0-15>``
Set the JPEG XL Butteraugli distance. Lower means better quality. Lossless
is 0.0, and 1.0 is approximately equivalent to JPEG quality 90 for
photographic content. Use 0.1 for "visually lossless" screenshots. The
default is 1.0.
``--screenshot-jxl-effort=<1-9>``
Set the JPEG XL compression effort. Higher effort (usually) means better
compression, but takes more CPU time. The default is 3.
``--screenshot-sw=<yes|no>``
Whether to use software rendering for screenshots (default: no).
@@ -5013,8 +5073,9 @@ ALSA audio output options
GPU renderer options
-----------------------
The following video options are currently all specific to ``--vo=gpu`` and
``--vo=libmpv`` only, which are the only VOs that implement them.
The following video options are currently all specific to ``--vo=gpu``,
``--vo=libmpv`` and ``--vo=gpu-next``, which are the only VOs that implement
them.
``--scale=<filter>``
The filter function to use when upscaling video.
@@ -5267,6 +5328,15 @@ The following video options are currently all specific to ``--vo=gpu`` and
Set this to ``-1`` to disable this logic.
``--interpolation-preserve``
Preserve the previous frames' interpolated results even when renderer
parameters are changed - with the exception of options related to
cropping and video placement, which always invalidate the cache. Enabling
this option makes dynamic updates of renderer settings slightly smoother at
the cost of slightly higher latency in response to such changes. Defaults
to on. (Only affects ``--vo=gpu-next``, note that ``--vo=gpu`` always
invalidates interpolated frames)
``--opengl-pbo``
Enable use of PBOs. On some drivers this can be faster, especially if the
source video size is huge (e.g. so called "4K" video). On other drivers it
@@ -5401,11 +5471,6 @@ The following video options are currently all specific to ``--vo=gpu`` and
use of compute shaders over fragment shaders wherever possible. Enabled by
default, although Nvidia users may want to disable it.
``--vulkan-disable-events``
Disable the use of VkEvents, for debugging purposes or for compatibility
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``
@@ -5508,11 +5573,18 @@ The following video options are currently all specific to ``--vo=gpu`` and
``--wayland-app-id=<string>``
Set the client app id for Wayland-based video output methods (default: ``mpv``).
``--wayland-configure-bounds=<yes|no>``
Controls whether or not mpv opts into the configure bounds event if sent by the
compositor (default: yes). This restricts the initial size of the mpv window to
a certain maximum size intended by the compositor. In most cases, this simply
just prevents the mpv window from being larger than the size of the monitor when
it first renders. This option will take precedence over any ``autofit`` or
``geometry`` type settings if the configure bounds are used.
``--wayland-disable-vsync=<yes|no>``
Disable vsync for the wayland contexts (default: no). Useful for benchmarking
the wayland context when combined with ``video-sync=display-desync``,
``--no-audio``, and ``--untimed=yes``. Only works with ``--gpu-context=wayland``
and ``--gpu-context=waylandvk``.
Disable mpv's internal vsync for Wayland-based video output (default: no).
This is mainly useful for benchmarking wayland VOs when combined with
``video-sync=display-desync``, ``--no-audio``, and ``--untimed=yes``.
``--wayland-edge-pixels-pointer=<value>``
Defines the size of an edge border (default: 10) to initiate client side
@@ -5785,6 +5857,13 @@ The following video options are currently all specific to ``--vo=gpu`` and
``--glsl-shader=<file>``
CLI/config file only alias for ``--glsl-shaders-append``.
``--glsl-shader-opts=param1=value1,param2=value2,...``
Specifies the options to use for tunable shader parameters. You can target
specific named shaders by prefixing the shader name with a ``/``, e.g.
``shader/param=value``. Without a prefix, parameters affect all shaders.
The shader name is the base part of the shader filename, without the
extension. (``--vo=gpu-next`` only)
``--deband``
Enable the debanding algorithm. This greatly reduces the amount of visible
banding, blocking and other quantization artifacts, at the expense of
@@ -5821,7 +5900,7 @@ The following video options are currently all specific to ``--vo=gpu`` and
values will sharpen the image (but add more ringing and aliasing). Negative
values will blur the image. If your GPU is powerful enough, consider
alternatives like the ``ewa_lanczossharp`` scale filter, or the
``--scale-blur`` option.
``--scale-blur`` option. (Only for ``--vo=gpu``)
``--opengl-glfinish``
Call ``glFinish()`` before swapping buffers (default: disabled). Slower,
@@ -6117,28 +6196,44 @@ The following video options are currently all specific to ``--vo=gpu`` and
other ways (like with the ``--gamma`` option or key bindings and the
``gamma`` property), the value is multiplied with the other gamma value.
Recommended values based on the environmental brightness:
1.0
Pitch black or dimly lit room (default)
1.1
Moderately lit room, home
1.2
Brightly illuminated room, office
NOTE: This is based around the assumptions of typical movie content, which
contains an implicit end-to-end of about 0.8 from scene to display. For
bright environments it can be useful to cancel that out.
This option is deprecated and may be removed in the future.
``--gamma-auto``
Automatically corrects the gamma value depending on ambient lighting
conditions (adding a gamma boost for bright rooms).
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.
This option is deprecated and may be removed in the future.
NOTE: Only implemented on macOS.
``--image-lut=<file>``
Specifies a custom LUT file (in Adobe .cube format) to apply to the colors
during image decoding. The exact interpretation of the LUT depends on
the value of ``--image-lut-type``. (Only for ``--vo=gpu-next``)
``--image-lut-type=<value>``
Controls the interpretation of color values fed to and from the LUT
specified as ``--image-lut``. Valid values are:
auto
Chooses the interpretation of the LUT automatically from tagged
metadata, and otherwise falls back to ``native``. (Default)
native
Applied to the raw image contents in its native colorspace, before
decoding to RGB. For example, for a HDR10 image, this would be fed
PQ-encoded YCbCr values in the range 0.0 - 1.0.
normalized
Applied to the normalized RGB image contents, after decoding from
its native color encoding, but before linearization.
conversion
Fully replaces the color decoding. A LUT of this type should ingest the
image's native colorspace and output normalized non-linear RGB.
``--target-colorspace-hint``
Automatically configure the output colorspace of the display to pass
through the input values of the stream (e.g. for HDR passthrough), if
possible. Requires a supporting driver and ``--vo=gpu-next``.
``--target-prim=<value>``
Specifies the primaries of the display. Video colors will be adapted to
this colorspace when ICC color management is not being used. Valid values
@@ -6254,12 +6349,20 @@ The following video options are currently all specific to ``--vo=gpu`` and
In such a configuration, we highly recommend setting ``--tone-mapping``
to ``mobius`` or even ``clip``.
``--target-lut=<file>``
Specifies a custom LUT file (in Adobe .cube format) to apply to the colors
before display on-screen. This LUT is fed values in normalized RGB, after
encoding into the target colorspace, so after the application of
``--target-trc``. (Only for ``--vo=gpu-next``)
``--tone-mapping=<value>``
Specifies the algorithm used for tone-mapping images onto the target
display. This is relevant for both HDR->SDR conversion as well as gamut
reduction (e.g. playing back BT.2020 content on a standard gamut display).
Valid values are:
auto
Choose the best curve according to internal heuristics. (Default)
clip
Hard-clip any out-of-range values. Use this when you care about
perfect color accuracy for in-range values at the cost of completely
@@ -6285,13 +6388,17 @@ The following video options are currently all specific to ``--vo=gpu`` and
you should also enable ``--hdr-compute-peak`` for the best results.
bt.2390
Perceptual tone mapping curve (EETF) specified in ITU-R Report BT.2390.
This is the recommended curve to use for typical HDR-mastered content.
(Default)
gamma
Fits a logarithmic transfer between the tone curves.
linear
Linearly stretches the entire reference gamut to (a linear multiple of)
the display.
spline
Perceptually linear single-pivot polynomial. (``--vo=gpu-next`` only)
bt.2446a
HDR<->SDR mapping specified in ITU-R Report BT.2446, method A. This is
the recommended curve for well-mastered content. (``--vo=gpu-next``
only)
``--tone-mapping-param=<value>``
Set tone mapping parameters. By default, this is set to the special string
@@ -6312,10 +6419,25 @@ The following video options are currently all specific to ``--vo=gpu`` and
Specifies the local contrast coefficient at the display peak. Defaults
to 0.5, which means that in-gamut values will be about half as bright
as when clipping.
bt.2390
Specifies the offset for the knee point. Defaults to 1.0, which is
higher than the value from the original ITU-R specification (0.5).
(``--vo=gpu-next`` only)
gamma
Specifies the exponent of the function. Defaults to 1.8.
linear
Specifies the scale factor to use while stretching. Defaults to 1.0.
spline
Specifies the knee point (in PQ space). Defaults to 0.30.
``--inverse-tone-mapping``
If set, allows inverse tone mapping (expanding SDR to HDR). Not supported
by all tone mapping curves. Use with caution. (``--vo=gpu-next`` only)
``--tone-mapping-crosstalk=<0.0..0.30>``
If nonzero, apply an extra crosstalk matrix before tone mapping. Can help
improve the appearance of strongly saturated monochromatic highlights.
(Default: 0.04, only affects ``--vo=gpu-next``)
``--tone-mapping-max-boost=<1.0..10.0>``
Upper limit for how much the tone mapping algorithm is allowed to boost
@@ -6323,7 +6445,48 @@ The following video options are currently all specific to ``--vo=gpu`` and
allows no additional brightness boost. A value of 2.0 would allow
over-exposing by a factor of 2, and so on. Raising this setting can help
reveal details that would otherwise be hidden in dark scenes, but raising
it too high will make dark scenes appear unnaturally bright.
it too high will make dark scenes appear unnaturally bright. (``--vo=gpu``
only)
``--tone-mapping-mode``
Controls how the tone mapping function is applied to colors.
auto
Choose the best mode automatically. (Default)
rgb
Tone-map per-channel (RGB). Has a tendency to severely distort colors,
desaturate highlights, and is generally not very recommended. However,
this is the mode used in many displays and TVs (especially early ones),
and so sometimes it's needed to reproduce the artistic intent a film
was mastered with.
max
Tone-map on the brightest component in the video. Has a tendency to
lead to weirdly oversaturated colors, and loss of dark details.
hybrid
A hybrid approach that uses linear tone-mapping for midtones and
per-channel tone mapping for highlights.
luma
Luminance-based method from ITU-R BT.2446a, including fixed gamut
reductions to account for brightness-related perceptual nonuniformity.
(``--vo=gpu-next`` only)
``--gamut-mapping-mode``
Specifies the algorithm used for reducing the gamut of images for the
target display, after any tone mapping is done.
auto
Choose the best mode automatically. (Default)
clip
Hard-clip to the gamut (per-channel).
warn
Simply highlight out-of-gamut pixels.
desaturate
Chromatically desaturate out-of-gamut colors towards white.
darken
Linearly darken the entire image, then clip to the color volume. Unlike
``clip``, this does not destroy detail in saturated regions, but comes
at the cost of sometimes significantly lowering output brightness.
(``--vo=gpu-next`` only)
``--hdr-compute-peak=<auto|yes|no>``
Compute the HDR peak and frame average brightness per-frame instead of
@@ -6335,6 +6498,14 @@ The following video options are currently all specific to ``--vo=gpu`` and
The special value ``auto`` (default) will enable HDR peak computation
automatically if compute shaders and SSBOs are supported.
``--allow-delayed-peak-detect``
When using ``--hdr-compute-peak``, allow delaying the detected peak by a
frame when beneficial for performance. In particular, this is required to
avoid an unnecessary FBO indirection when no advanced rendering is required
otherwise. Has no effect if there already is an indirect pass, such as when
advanced scaling is enabled. Defaults to on. (Only affects
``--vo=gpu-next``, note that ``--vo=gpu`` always delays the peak.)
``--hdr-peak-decay-rate=<1.0..1000.0>``
The decay rate used for the HDR peak detection algorithm (default: 100.0).
This is only relevant when ``--hdr-compute-peak`` is enabled. Higher values
@@ -6359,46 +6530,6 @@ The following video options are currently all specific to ``--vo=gpu`` and
aggressive, up to the limit of the high threshold (at which point the
filter becomes instant).
``--tone-mapping-desaturate=<0.0..1.0>``
Apply desaturation for highlights (default: 0.75). The parameter controls
the strength of the desaturation curve. A value of 0.0 completely disables
it, while a value of 1.0 means that overly bright colors will tend towards
white. (This is not always the case, especially not for highlights that are
near primary colors)
Values in between apply progressively more/less aggressive desaturation.
This setting helps prevent unnaturally oversaturated colors for
super-highlights, by (smoothly) turning them into less saturated (per
channel tone mapped) colors instead. This makes images feel more natural,
at the cost of chromatic distortions for out-of-range colors. The default
value of 0.75 provides a good balance. Setting this to 0.0 preserves the
chromatic accuracy of the tone mapping process.
``--tone-mapping-desaturate-exponent=<0.0..20.0>``
This setting controls the exponent of the desaturation curve, which
controls how bright a color needs to be in order to start being
desaturated. The default of 1.5 provides a reasonable balance. Decreasing
this exponent makes the curve more aggressive.
``--gamut-warning``
If enabled, mpv will mark all clipped/out-of-gamut pixels that exceed a
given threshold (currently hard-coded to 101%). The affected pixels will be
inverted to make them stand out. Note: This option applies after the
effects of all of mpv's color space transformation / tone mapping options,
so it's a good idea to combine this with ``--tone-mapping=clip`` and use
``--target-prim`` to set the gamut to simulate. For example,
``--target-prim=bt.709`` would make mpv highlight all pixels that exceed the
gamut of a standard gamut (sRGB) display. This option also does not work
well with ICC profiles, since the 3DLUTs are always generated against the
source color space and have chromatically-accurate clipping built in.
``--gamut-clipping``
If enabled (default: yes), mpv will colorimetrically clip out-of-gamut
colors by desaturating them (preserving luma), rather than hard-clipping
each component individually. This should make playback of wide gamut
content on typical (standard gamut) monitors look much more aesthetically
pleasing and less blown-out.
``--use-embedded-icc-profile``
Load the embedded ICC profile contained in media files such as PNG images.
(Default: yes). Note that this option only works when also using a display
@@ -6456,6 +6587,30 @@ The following video options are currently all specific to ``--vo=gpu`` and
value ``inf`` causes the BT.1886 curve to be treated as a pure power gamma
2.4 function.
``--lut=<file>``
Specifies a custom LUT (in Adobe .cube format) to apply to the colors
as part of color conversion. The exact interpretation depends on the value
of ``--lut-type``. (Only for ``--vo=gpu-next``)
``--lut-type=<value>``
Controls the interpretation of color values fed to and from the LUT
specified as ``--lut``. Valid values are:
auto
Chooses the interpretation of the LUT automatically from tagged
metadata, and otherwise falls back to ``native``. (Default)
native
Applied to raw image contents in its native RGB colorspace (non-linear
light), before conversion to the output color space.
normalized
Applied to the normalized RGB image contents, in linear light, before
conversion to the output color space.
conversion
Fully replaces the conversion from the image color space to the output
color space. If such a LUT is present, it has the highest priority, and
overrides any ICC profiles, as well as options related to tone mapping
and output colorimetry (``--target-prim``, ``--target-trc`` etc.).
``--blend-subtitles=<yes|video|no>``
Blend subtitles directly onto upscaled video frames, before interpolation
and/or color management (default: no). Enabling this causes subtitles to be
@@ -6590,9 +6745,9 @@ Miscellaneous
other hand, setting a too high value can reduce responsiveness with low
FPS value.
For client API users using the render API (or the deprecated ``opengl-cb``
API), this option is interesting, because you can stop the render API
from limiting your FPS (see ``mpv_render_context_render()`` documentation).
This option is interesting for client API users using the render API
because you can stop it from limiting your FPS
(see ``mpv_render_context_render()`` documentation).
This applies only to audio timing modes (e.g. ``--video-sync=audio``). In
other modes (``--video-sync=display-...``), video timing relies on vsync
@@ -6787,9 +6942,8 @@ Miscellaneous
(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).
:exact: Load the media filename with an image file extension (default).
:fuzzy: Load all cover art containing the media filename.
:all: Load all images in the current directory.
See ``--cover-art-files`` for details about what constitutes cover art.
@@ -6797,6 +6951,13 @@ Miscellaneous
See ``--audio-display`` how to control display of cover art (this can be
used to disable cover art that is part of the file).
``--cover-art-whitelist=<no|yes>``
Whether to load filenames in an internal whitelist, such as ``cover.jpg``,
as cover art. If ``cover-art-auto`` is set to ``no``, the whitelisted
filenames are never loaded even if this option is set to ``yes``.
Default: ``yes``.
``--autoload-files=<yes|no>``
Automatically load/select external files (default: yes).
@@ -6849,7 +7010,7 @@ Miscellaneous
that are unavailable to outside users.
This replaces ``--record-file``. It is similar to the ancient/removed
``--stream-capture``/``-capture`` options, and provides better behavior in
``--stream-capture``/``--capture`` options, and provides better behavior in
most cases (i.e. actually works).
``--lavfi-complex=<string>``
+37
View File
@@ -236,6 +236,11 @@ Configurable Options
Enable the OSC when fullscreen
``idlescreen``
Default: yes
Show the mpv logo and message when idle
``scalewindowed``
Default: 1.0
@@ -310,6 +315,14 @@ Configurable Options
Display timecodes with milliseconds
``tcspace``
Default: 100 (allowed: 50-200)
Adjust space reserved for timecodes (current time and time remaining) in
the ``bottombar`` and ``topbar`` layouts. The timecode width depends on the
font, and with some fonts the spacing near the timecodes becomes too small.
Use values above 100 to increase that spacing, or below 100 to decrease it.
``visibility``
Default: auto (auto hide/show on mouse move)
@@ -382,6 +395,26 @@ Configurable Options
Update chapter markers positions on duration changes, e.g. live streams.
The updates are unoptimized - consider disabling it on very low-end systems.
``chapters_osd``, ``playlist_osd``
Default: yes
Whether to display the chapters/playlist at the OSD when left-clicking the
next/previous OSC buttons, respectively.
``chapter_fmt``
Default: ``Chapter: %s``
Template for the chapter-name display when hovering the seekbar.
Use ``no`` to disable chapter display on hover. Otherwise it's a lua
``string.format`` template and ``%s`` is replaced with the actual name.
``unicodeminus``
Default: no
Use a Unicode minus sign instead of an ASCII hyphen when displaying
the remaining playback time.
Script Commands
~~~~~~~~~~~~~~~
@@ -404,6 +437,10 @@ to set auto mode (the default) with ``b``::
a script-message osc-visibility never
b script-message osc-visibility auto
``osc-idlescreen``
Controls the visibility of the mpv logo on idle. Valid arguments are ``yes``,
``no``, and ``cycle`` to toggle between yes and no.
``osc-playlist``, ``osc-chapterlist``, ``osc-tracklist``
Shows a limited view of the respective type of list using the OSC. First
argument is duration in seconds.
+9 -1
View File
@@ -308,6 +308,14 @@ Available mpv-only filters are:
:709-1886: Scene-referred using the BT709+BT1886 interaction
:gamma1.2: Scene-referred using a pure power OOTF (gamma=1.2)
``<dolbyvision=yes|no>``
Whether or not to include Dolby Vision metadata (default: yes). If
disabled, any Dolby Vision metadata will be stripped from frames.
``<film-grain=yes|no>``
Whether or not to include film grain metadata (default: yes). If
disabled, any film grain metadata will be stripped from frames.
``<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
@@ -457,7 +465,7 @@ Available mpv-only filters are:
::
import vapoursynth as vs
core = vs.get_core()
from vapoursynth import core
core.std.AddBorders(video_in, 10, 10, 20, 20).set_output()
.. warning::
+76 -44
View File
@@ -21,6 +21,46 @@ in the list.
Available video output drivers are:
``gpu``
General purpose, customizable, GPU-accelerated video output driver. It
supports extended scaling methods, dithering, color management, custom
shaders, HDR, and more.
See `GPU renderer options`_ for options specific to this VO.
By default, it tries to use fast and fail-safe settings. Use the
``gpu-hq`` profile to use this driver with defaults set to high quality
rendering. The profile can be applied with ``--profile=gpu-hq`` and its
contents can be viewed with ``--show-profile=gpu-hq``.
This VO abstracts over several possible graphics APIs and windowing
contexts, which can be influenced using the ``--gpu-api`` and
``--gpu-context`` options.
Hardware decoding over OpenGL-interop is supported to some degree. Note
that in this mode, some corner case might not be gracefully handled, and
color space conversion and chroma upsampling is generally in the hand of
the hardware decoder APIs.
``gpu`` makes use of FBOs by default. Sometimes you can achieve better
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 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.
``gpu-next``
Experimental video renderer based on ``libplacebo``. This supports almost
the same set of features as ``--vo=gpu``. See `GPU renderer options`_ for a
list.
Should generally be faster and higher quality, but some features may still
be missing or misbehave. Expect (and report!) bugs. See here for a list of
known differences and bugs:
https://github.com/mpv-player/mpv/wiki/GPU-Next-vs-GPU
``xv`` (X11 only)
Uses the XVideo extension to enable hardware-accelerated display. This is
the most compatible VO on X, but may be low-quality, and has issues with
@@ -78,7 +118,9 @@ Available video output drivers are:
``vdpau`` (X11 only)
Uses the VDPAU interface to display and optionally also decode video.
Hardware decoding is used with ``--hwdec=vdpau``.
Hardware decoding is used with ``--hwdec=vdpau``. Note that there is
absolutely no reason to use this, other than compatibility. We strongly
recommend that you use ``--vo=gpu`` with ``--hwdec=nvdec`` instead.
.. note::
@@ -228,35 +270,6 @@ Available video output drivers are:
``--vo-direct3d-exact-backbuffer``
Always resize the backbuffer to window size.
``gpu``
General purpose, customizable, GPU-accelerated video output driver. It
supports extended scaling methods, dithering, color management, custom
shaders, HDR, and more.
See `GPU renderer options`_ for options specific to this VO.
By default, it tries to use fast and fail-safe settings. Use the
``gpu-hq`` profile to use this driver with defaults set to high quality
rendering. The profile can be applied with ``--profile=gpu-hq`` and its
contents can be viewed with ``--show-profile=gpu-hq``.
This VO abstracts over several possible graphics APIs and windowing
contexts, which can be influenced using the ``--gpu-api`` and
``--gpu-context`` options.
Hardware decoding over OpenGL-interop is supported to some degree. Note
that in this mode, some corner case might not be gracefully handled, and
color space conversion and chroma upsampling is generally in the hand of
the hardware decoder APIs.
``gpu`` makes use of FBOs by default. Sometimes you can achieve better
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 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.
``sdl``
SDL 2.0+ Render video output driver, depending on system with or without
hardware acceleration. Should work on all platforms supported by SDL 2.0.
@@ -273,13 +286,20 @@ Available video output drivers are:
``--sdl-switch-mode``
Instruct SDL to switch the monitor video mode when going fullscreen.
``dmabuf-wayland``
Experimental Wayland output driver designed for use with either drm stateless
or VA API hardware decoding. The driver is designed to avoid any GPU to CPU copies,
and to perform scaling and color space conversion using fixed-function hardware,
if available, rather than GPU shaders. This frees up GPU resources for other tasks.
Currently this driver is experimental and only works with the ``--hwdec=vaapi``
or ``hwdec=drm`` drivers;
OSD is also not supported. Supported compositors : Weston and Sway.
``vaapi``
Intel VA API video output driver with support for hardware decoding. Note
that there is absolutely no reason to use this, other than compatibility.
This is low quality, and has issues with OSD.
.. note:: This driver is for compatibility with crappy systems. You can
use vaapi hardware decoding with ``--vo=gpu`` too.
This is low quality, and has issues with OSD. We strongly recommend that
you use ``--vo=gpu`` with ``--hwdec=vaapi`` instead.
The following global options are supported by this video output:
@@ -595,11 +615,11 @@ Available video output drivers are:
based, and related to the CRTC.
(default: primary)
When using this option with the drmprime-drm hwdec interop, only the OSD
is rendered to this plane.
When using this option with the drmprime-overlay hwdec interop, only the
OSD is rendered to this plane.
``--drm-drmprime-video-plane=<primary|overlay|N>``
Select the DRM plane to use for video with the drmprime-drm hwdec
Select the DRM plane to use for video with the drmprime-overlay hwdec
interop (used by e.g. the rkmpp hwdec on RockChip SoCs, and v4l2 hwdec:s
on various other SoC:s). The plane is unused otherwise. This option
accepts the same values as ``--drm-draw-plane``. (default: overlay)
@@ -625,17 +645,29 @@ Available video output drivers are:
``--drm-draw-surface-size=<[WxH]>``
Sets the size of the surface used on the draw plane. The surface will
then be upscaled to the current screen resolution. This option can be
useful when used together with the drmprime-drm hwdec interop at high
resolutions, as it allows scaling the draw plane (which in this case
only handles the OSD) down to a size the GPU can handle.
useful when used together with the drmprime-overlay hwdec interop at
high resolutions, as it allows scaling the draw plane (which in this
case only handles the OSD) down to a size the GPU can handle.
When used without the drmprime-drm hwdec interop this option will just
cause the video to get rendered at a different resolution and then
When used without the drmprime-overlay hwdec interop this option will
just cause the video to get rendered at a different resolution and then
scaled to screen size.
Note: this option is only available with DRM atomic support.
(default: display resolution)
``--drm-vrr-enabled=<no|yes|auto>``
Toggle use of Variable Refresh Rate (VRR), aka Freesync or Adaptive Sync
on compatible systems. VRR allows for the display to be refreshed at any
rate within a range (usually ~40Hz-60Hz for 60Hz displays). This can help
with playback of 24/25/50fps content. Support depends on the use of a
compatible monitor, GPU, and a sufficiently new kernel with drivers
that support the feature.
:no: Do not attempt to enable VRR. (default)
:yes: Attempt to enable VRR, whether the capability is reported or not.
:auto: Attempt to enable VRR if support is reported.
``mediacodec_embed`` (Android)
Renders ``IMGFMT_MEDIACODEC`` frames directly to an ``android.view.Surface``.
Requires ``--hwdec=mediacodec`` for hardware decoding, along with
@@ -645,8 +677,8 @@ Available video output drivers are:
many of mpv's features (subtitle rendering, OSD/OSC, video filters, etc)
are not available with this driver.
To use hardware decoding with ``--vo=gpu`` instead, use
``--hwdec=mediacodec-copy`` along with ``--gpu-context=android``.
To use hardware decoding with ``--vo=gpu`` instead, use ``--hwdec=mediacodec``
or ``mediacodec-copy`` along with ``--gpu-context=android``.
``wlshm`` (Wayland only)
Shared memory video output driver without hardware acceleration that works
+2 -2
View File
@@ -377,7 +377,7 @@ without causing conflicts with other library users in the same process. To any
piece of code, a "safe" library's API can simply be used, without having to
worry about other API users that may be around somewhere.
Libraries are often not library safe, because they they use global mutable state
Libraries are often not library safe, because they use global mutable state
or other "global" resources. Typical examples include use of signals, simple
global variables (like hsearch() in libc), or internal caches not protected by
locks.
@@ -481,7 +481,7 @@ VOs, AOs, demuxers, and more. The frontend usually calls "down" the usage
hierarchy: mpctx almost on top, then things like vo/ao, and utility code on the
very bottom.
"Callback hell" is when when components call both up and down the hierarchy,
"Callback hell" is when components call both up and down the hierarchy,
which for example leads to accidentally recursion, reentrancy problems, or
locking nightmares. This is avoided by (mostly) calling only down the hierarchy.
Basically the call graph forms a DAG. The other direction is handled by event
+21 -4
View File
@@ -73,11 +73,27 @@ Changes to the default key bindings are indicated in
Compiling with full features requires development files for several
external libraries. Below is a list of some important requirements.
external libraries. One of the two build systems supported by mpv is required:
[meson](https://mesonbuild.com/index.html) or [waf](https://waf.io/). Meson
can be obtained from your distro or PyPI. Waf can be downloaded by using the
`./bootstrap.py` script. It will get the latest version of waf that was tested
with mpv. Some documentation about the differences between the build systems are
located in [build-system-differences][build-system-differences].
The mpv build system uses [waf](https://waf.io/), but we don't store it in the
repository. The `./bootstrap.py` script will download the latest version
of waf that was tested with the build system.
### Meson
After creating your build directory (e.g. `meson setup build`), you can view a list
of all the build options via `meson configure build`. You could also just simply
look at the `meson_options.txt` file. Logs are stored in `meson-logs` within
your build directory.
Example:
meson setup build
meson compile -C build
meson install -C build
### Waf
For a list of the available build options use `./waf configure --help`. If
you think you have support for some feature installed but configure fails to
@@ -214,3 +230,4 @@ Most activity happens on the IRC channel and the github issue tracker.
[api-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/client-api-changes.rst
[restore-old-bindings]: https://github.com/mpv-player/mpv/blob/master/etc/restore-old-bindings.conf
[contribute.md]: https://github.com/mpv-player/mpv/blob/master/DOCS/contribute.md
[build-system-differences]: https://github.com/mpv-player/mpv/blob/master/DOCS/build-system-differences.md
+95 -86
View File
@@ -1,4 +1,4 @@
Release 0.34.0
Release 0.35.0
==============
This release requires FFmpeg 4.0 or newer.
@@ -7,6 +7,9 @@ For packagers: Note that mpv's build system is only supported on Python 3.
If you use the `bootstrap.py` script it will take care of this, otherwise you
need to explicitly invoke the build system using `python3 waf`.
This release adds the Meson build system as an alternative to waf.
It is supposed to be feature-complete but please report any issues you encounter.
Features
--------
@@ -14,34 +17,39 @@ Features
Added
~~~~~
- 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)
- vo_gpu_next: add new libplacebo-based renderer
- build: add meson build support
- vo_gpu_next: forward Dolby Vision metadata to libplacebo
- ao_pipewire: add PipeWire audio backend
- ao_sndio: readd this audio output again
- vo_gpu_next: apply film grain if such metadata is present
- drm: context_drm_egl: add support for enabling VRR
- demux: add support for R128 replaygain tags
- x11: support X Present extension
- af_rubberband: add support for new engine in rubberband 3.0.0
- hwdec/drmprime: add drmprime hwdec-interop (commonly found on SoCs)
- various: support binding functions keys beyond F12
- audio: support hotplug events for multiple AOs
- sub: use Unicode linebreaking for non-ASS subs and OSD
- vo_gpu: hwdec: add Android hwdec utilizing AImageReader
- vo_dmabuf_wayland: add wayland VO displaying dmabuf buffers (vaapi or drm hwdec only)
- lua/console: add history deduplication
Changed
~~~~~~~
- 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
- filters: re-add vavpp hardware deinterlacing auto-filter (for --deinterlace)
- swresample: don't forcibly clip audio on every conversion
- ytdl_hook: always set HTTP headers to fix yt-dlp on certain sites
Removed
~~~~~~~
- mac: drop build support for swift versions earlier than 4.1
- vo_gpu: drop support for libplacebo older than v3.104.0
- libmpv: remove opengl_cb API and other deprecated symbols
- lua: remove deprecated mp.suspend(), resume() and resume_all()
- build: raise minimum libplacebo version requirement to v4.157.0
Options and Commands
@@ -50,97 +58,98 @@ Options and Commands
Added
~~~~~
- 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
- vo_gpu_next: add --target-colorspace-hint to facilitate HDR passthrough
- vo_gpu_next: new tone mapping options 'auto', 'spline', 'bt.2446a'
and add --tone-mapping-crosstalk, --inverse-tone-mapping
- vo_gpu: add --gamut-mapping-mode and --tone-mapping-mode
- options: add 'always' choice to --stop-screensaver
- options: add --osd-playing-msg-duration
- player: add --cover-art-whitelist option
- x11: add --x11-present option
Changed
~~~~~~~
- 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
- ao_openal: enable --openal-direct-channels by default
- options: only apply --sub-visibility to primary subtitles
- options: make --cover-art-auto=exact the default
- vo_gpu/hwdec: rename and introduce legacy names for some interops
Deprecated
~~~~~~~~~~
- win32: ignore and deprecate --fit-border
- drm_common: deprecate selecting by card number in --drm-connector
- vo_gpu: deprecate --gamma-factor and --gamma-auto
Removed
~~~~~~~
- vo_gpu: remove --icc-contrast
- stats.lua: remove script-opts for the main keys (i/I)
- vo_gpu: opengl: remove --opengl-restrict
- vo_gpu: remove --gamut-clipping, --gamut-warning, --tone-mapping-desaturate and
--tone-mapping-desaturate-exponent (replacements available)
- vulkan: remove --vulkan-disable-events
Fixes and Minor Enhancements
----------------------------
- 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)
- context_drm_egl: use gbm_surface_create_with_modifiers
- context_drm_egl: add support for BGR surface formats
- vo_gpu: vulkan: open DRM render fd when using VK_KHR_display
- client API: use symbol visibility attributes
- vo_gpu: hwdec_vaapi: add dma-buf modifiers support
- wayland: fix various issues that could lead to jitter
- osc: fix cache displaying 60s in some cases
- player: make --keep-open=always work with --loop-playlist
- opengl: support driver debug message under OpenGL ES
- vo_gpu: opengl: fixes for OpenGL ES version and extension handling
- f_decoder_wrapper: support frame rotation metadata (used by JPEG)
- wscript: switch shaderc checks to pkgconfig
- vd_lavc: enable hwdec for prores by default
- vo_gpu: add HOOKED_gather for custom shaders
- wayland, x11: sanitize window title for valid UTF-8
- win32: apply geometry position to content instead of window
- filter_kernels: add cosine window
- vo_gpu: hwdec_vaapi: don't probe formats for irrelevant endpoints
- vo_gpu: hwdec: load hwdec interops on-demand by default
- stats.lua: graphs: fix bad rendering due to division by 0
- hwdec: warn on unsupported --hwdec option value
- x11: fix --screen-name option
- x11: avoid wasteful rendering when possible
- video/image_writer: add JPEG XL support
- stream_lavf: enable ipfs, ipns and rist protocol support
- osc.lua: fix crash when calling osc-tracklist while idle
- player: add jxl, tiff, tif to list of image extensions
- various: switch to new AVChannelLayout structure
- lua: command_native_async: always run callback asynchronously (edge case)
- context_x11egl: remove supposed transparency workaround
- vo_gpu: fix 3DLUT precision
- drm: avoid drmModeAtomicCommit races by blocking
- drm_common: skip cards that don't support KMS for autodetection
- hwdec/dmabuf_interop_gl: support basic multi-plane formats
- misc/random: switch to internal xoshiro rng implementation
- ytdl_hook: improve track detection
- ad_lavc: strip non-normalized floats
- mpv.metainfo.xml: add XDG appstream metadata manifest
- mac: avoid unnecessary unsafe conversions; fixes crash in debug builds
- af_scaletempo2: fix crash when the number of channels increases
- wayland: correctly handle non-CLOCK_MONOTONIC clocks
- x11: fix --on-all-workspaces option
- sd_ass: improve handling of subtitles with unknown duration
- hwdec/vaapi: improve probing of supported sw formats
- demux_mf: enable support for QOI, PHM and HDR images
- demux_mkv: add AVS2 and AVS3 to tag list
- TOOLS/lua/autoload: fix incorrect duplicate file loading behavior
- demux/codec_tags: support more WAVEFORMATEXTENSIBLE tags
- sd_ass: never mangle colours on RGB video
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.33.0..v0.34.0`
A complete changelog can be seen by running `git log v0.34.0..v0.35.0`
in the git repository or by visiting either
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
https://github.com/mpv-player/mpv/compare/v0.34.0...v0.35.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.34.0..v0.35.0
+1 -1
View File
@@ -69,7 +69,7 @@ def lib_name(lib):
def process_libraries(libs_dict, binary):
libs_set = set(libs_dict)
# Remove binary from libs_set to prevent a duplicate of the binary being
# Remove binary from libs_set to prevent a duplicate of the binary being
# added to the libs directory.
libs_set.remove(binary)
+6 -1
View File
@@ -39,5 +39,10 @@ def file2string(infilename, infile, outfile):
outfile.write('"' + ''.join(conv[c] for c in line) + '"\n')
if __name__ == "__main__":
if len(sys.argv) < 2:
outfile = sys.stdout
else:
outfile = open(sys.argv[2], "w")
with open(sys.argv[1], 'rb') as infile:
file2string(sys.argv[1], infile, sys.stdout)
file2string(sys.argv[1], infile, outfile)
+1 -1
View File
@@ -2,7 +2,7 @@
-- filter including key bindings for adjusting parameters.
--
-- See https://ffmpeg.org/ffmpeg-filters.html#acompressor for explanation
-- of the parameteres.
-- of the parameters.
local mp = require 'mp'
local options = require 'mp.options'
+20 -12
View File
@@ -49,15 +49,18 @@ function SetUnion (a,b)
end
EXTENSIONS_VIDEO = Set {
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp'
'3g2', '3gp', 'avi', 'flv', 'm2ts', 'm4v', 'mj2', 'mkv', 'mov',
'mp4', 'mpeg', 'mpg', 'ogv', 'rmvb', 'webm', 'wmv', 'y4m'
}
EXTENSIONS_AUDIO = Set {
'mp3', 'wav', 'ogm', 'flac', 'm4a', 'wma', 'ogg', 'opus'
'aiff', 'ape', 'au', 'flac', 'm4a', 'mka', 'mp3', 'oga', 'ogg',
'ogm', 'opus', 'wav', 'wma'
}
EXTENSIONS_IMAGES = Set {
'jpg', 'jpeg', 'png', 'tif', 'tiff', 'gif', 'webp', 'svg', 'bmp'
'avif', 'bmp', 'gif', 'j2k', 'jp2', 'jpeg', 'jpg', 'jxl', 'png',
'svg', 'tga', 'tif', 'tiff', 'webp'
}
EXTENSIONS = Set {}
@@ -124,6 +127,16 @@ end
local autoloaded = nil
function get_playlist_filenames()
local filenames = {}
for n = 0, pl_count - 1, 1 do
local filename = mp.get_property('playlist/'..n..'/filename')
local _, file = utils.split_path(filename)
filenames[file] = true
end
return filenames
end
function find_and_add_entries()
local path = mp.get_property("path", "")
local dir, filename = utils.split_path(path)
@@ -136,7 +149,7 @@ function find_and_add_entries()
return
end
local pl_count = mp.get_property_number("playlist-count", 1)
pl_count = mp.get_property_number("playlist-count", 1)
-- check if this is a manually made playlist
if (pl_count > 1 and autoloaded == nil) or
(pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil) then
@@ -188,22 +201,17 @@ function find_and_add_entries()
msg.trace("current file position in files: "..current)
local append = {[-1] = {}, [1] = {}}
local filenames = get_playlist_filenames()
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
for i = 1, MAXENTRIES do
local file = files[current + i * direction]
local pl_e = pl[pl_current + i * direction]
if file == nil or file[1] == "." then
break
end
local filepath = dir .. file
if pl_e then
-- If there's a playlist entry, and it's the same file, stop.
msg.trace(pl_e.filename.." == "..filepath.." ?")
if pl_e.filename == filepath then
break
end
end
-- skip files already in playlist
if filenames[file] then break end
if direction == -1 then
if pl_current == 1 then -- never add additional entries in the middle
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env python3
# Logic copied from compiler_swift.py in the waf build. This checks for the sdk
# path, the sdk version, and the sdk build version. The sdk path is returned
# along with what is selected as the sdk version.
import re
import os
import string
import sys
from distutils.version import StrictVersion
from shutil import which
from subprocess import check_output
def find_macos_sdk():
sdk = os.environ.get('MACOS_SDK', '')
sdk_version = os.environ.get('MACOS_SDK_VERSION', '0.0')
xcrun = which('xcrun')
if not xcrun:
return sdk,sdk_version
if not sdk:
sdk = check_output([xcrun, '--sdk', 'macosx', '--show-sdk-path'],
encoding="UTF-8")
# find macOS SDK paths and version
if sdk_version == '0.0':
# show-sdk-build-version: is not available on older command line tools, but returns a build version (eg 17A360)
# show-sdk-version: is always available, but on older dev tools it's only the major version
sdk_build_version = check_output([xcrun, '--sdk', 'macosx',
'--show-sdk-build-version'], encoding="UTF-8")
sdk_version = check_output([xcrun, '--sdk', 'macosx', '--show-sdk-version'],
encoding="UTF-8")
if sdk:
build_version = '10.10.0'
# convert build version to a version string
# first 2 two digits are the major version, starting with 15 which is 10.11 (offset of 4)
# 1 char is the minor version, A => 0, B => 1 and ongoing
# last digits are bugfix version, which are not relevant for us
# eg 16E185 => 10.12.4, 17A360 => 10.13, 18B71 => 10.14.1
if sdk_build_version and isinstance(sdk_build_version, str):
verRe = re.compile("(\d+)(\D+)(\d+)")
version_parts = verRe.search(sdk_build_version)
major = int(version_parts.group(1)) - 4
minor = string.ascii_lowercase.index(version_parts.group(2).lower())
build_version = '10.' + str(major) + '.' + str(minor)
# from 20 onwards macOS 11.0 starts
if int(version_parts.group(1)) >= 20:
build_version = '11.' + str(minor)
if not isinstance(sdk_version, str):
sdk_version = '10.10.0'
# pick the higher version, always pick sdk over build if newer
if StrictVersion(build_version) > StrictVersion(sdk_version):
return sdk,build_version
else:
return sdk,sdk_version
return sdk,sdk_version
if __name__ == "__main__":
sdk_info = find_macos_sdk()
sys.stdout.write(','.join(sdk_info))
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
# Finds the macos swift library directory and prints the full path to stdout.
# First argument is the path to the swift executable.
import os
import sys
from shutil import which
from subprocess import check_output
def find_swift_lib():
swift_lib_dir = os.environ.get('SWIFT_LIB_DYNAMIC', '')
if swift_lib_dir:
return swift_lib_dir
# first check for lib dir relative to swift executable
xcode_dir = os.path.dirname(os.path.dirname(sys.argv[1]))
swift_lib_dir = os.path.join(xcode_dir, "lib", "swift", "macosx")
if os.path.isdir(swift_lib_dir):
return swift_lib_dir
# fallback to xcode-select path
xcode_select = which("xcode-select")
if not xcode_select:
sys.exit(1)
xcode_path = check_output([xcode_select, "-p"], encoding="UTF-8")
swift_lib_dir = os.path.join(xcode_path, "Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx")
if os.path.isdir(swift_lib_dir):
return swift_lib_dir
# last resort if we still haven't found a path
swift_lib_dir = os.path.join(xcode_path, "usr/lib/swift/macosx")
if not os.path.isdir(swift_lib_dir):
sys.exit(1)
return swift_lib_dir
if __name__ == "__main__":
swift_lib_dir = find_swift_lib()
sys.stdout.write(swift_lib_dir)
+7 -2
View File
@@ -459,10 +459,15 @@ if __name__ == "__main__":
def parse_toplevel(s):
parse_one(s, 0, None, 1 << 63)
if len(sys.argv) < 3:
outfile = sys.stdout
else:
outfile = open(sys.argv[2], "w")
if sys.argv[1] == '--generate-header':
generate_C_header(sys.stdout)
generate_C_header(outfile)
elif sys.argv[1] == '--generate-definitions':
generate_C_definitions(sys.stdout)
generate_C_definitions(outfile)
else:
s = open(sys.argv[1], "rb")
while 1:
@@ -223,6 +223,7 @@
<string>udp</string>
<string>smb</string>
<string>srt</string>
<string>rist</string>
</array>
</dict>
<dict>
+1 -1
View File
@@ -1 +1 @@
0.34.0
0.35.0
+1 -1
View File
@@ -26,7 +26,7 @@ install:
# Update non-core packages
- C:\msys64\usr\bin\pacman -Suu --noconfirm --noprogressbar --ask=20
# Install required MSYS2 packages
- C:\msys64\usr\bin\pacman -S --noconfirm --noprogressbar --needed base-devel perl python pkg-config
- C:\msys64\usr\bin\pacman -S --noconfirm --noprogressbar --needed base-devel perl python pkgconf
# Now MSYS2 is up to date, do the rest of the install from a bash script
- C:\msys64\usr\bin\bash -lc "cd && exec \"$APPVEYOR_BUILD_FOLDER\"/TOOLS/appveyor-install.sh"
build_script:
+64 -1
View File
@@ -18,9 +18,12 @@
#include <libavutil/frame.h>
#include <libavutil/mem.h>
#include "config.h"
#include "common/common.h"
#include "chmap.h"
#include "chmap_avchannel.h"
#include "fmt-conversion.h"
#include "format.h"
#include "aframe.h"
@@ -121,6 +124,16 @@ struct mp_aframe *mp_aframe_from_avframe(struct AVFrame *av_frame)
if (!av_frame || av_frame->width > 0 || av_frame->height > 0)
return NULL;
#if HAVE_AV_CHANNEL_LAYOUT
if (!av_channel_layout_check(&av_frame->ch_layout))
return NULL;
struct mp_chmap converted_map = { 0 };
if (!mp_chmap_from_av_layout(&converted_map, &av_frame->ch_layout)) {
return NULL;
}
#endif
int format = af_from_avformat(av_frame->format);
if (!format && av_frame->format != AV_SAMPLE_FMT_NONE)
return NULL;
@@ -132,11 +145,15 @@ struct mp_aframe *mp_aframe_from_avframe(struct AVFrame *av_frame)
abort();
frame->format = format;
#if !HAVE_AV_CHANNEL_LAYOUT
mp_chmap_from_lavc(&frame->chmap, frame->av_frame->channel_layout);
// FFmpeg being a stupid POS again
if (frame->chmap.num != frame->av_frame->channels)
mp_chmap_from_channels(&frame->chmap, av_frame->channels);
#else
frame->chmap = converted_map;
#endif
if (av_frame->opaque_ref) {
struct avframe_opaque *op = (void *)av_frame->opaque_ref->data;
@@ -204,9 +221,16 @@ void mp_aframe_config_copy(struct mp_aframe *dst, struct mp_aframe *src)
dst->av_frame->sample_rate = src->av_frame->sample_rate;
dst->av_frame->format = src->av_frame->format;
#if !HAVE_AV_CHANNEL_LAYOUT
dst->av_frame->channel_layout = src->av_frame->channel_layout;
// FFmpeg being a stupid POS again
dst->av_frame->channels = src->av_frame->channels;
#else
if (av_channel_layout_copy(&dst->av_frame->ch_layout,
&src->av_frame->ch_layout) < 0)
abort();
#endif
}
// Copy "soft" attributes from src to dst, excluding things which affect
@@ -315,13 +339,21 @@ bool mp_aframe_set_chmap(struct mp_aframe *frame, struct mp_chmap *in)
return false;
if (mp_aframe_is_allocated(frame) && in->num != frame->chmap.num)
return false;
#if !HAVE_AV_CHANNEL_LAYOUT
uint64_t lavc_layout = mp_chmap_to_lavc_unchecked(in);
if (!lavc_layout && in->num)
return false;
#endif
frame->chmap = *in;
#if !HAVE_AV_CHANNEL_LAYOUT
frame->av_frame->channel_layout = lavc_layout;
// FFmpeg being a stupid POS again
frame->av_frame->channels = frame->chmap.num;
#else
mp_chmap_to_av_layout(&frame->av_frame->ch_layout, in);
#endif
return true;
}
@@ -434,6 +466,37 @@ void mp_aframe_skip_samples(struct mp_aframe *f, int samples)
f->pts += samples / mp_aframe_get_effective_rate(f);
}
// sanitize a floating point sample value
#define sanitizef(f) do { \
if (!isnormal(f)) \
(f) = 0; \
} while (0)
void mp_aframe_sanitize_float(struct mp_aframe *mpa)
{
int format = af_fmt_from_planar(mp_aframe_get_format(mpa));
if (format != AF_FORMAT_FLOAT && format != AF_FORMAT_DOUBLE)
return;
int num_planes = mp_aframe_get_planes(mpa);
uint8_t **planes = mp_aframe_get_data_rw(mpa);
if (!planes)
return;
for (int p = 0; p < num_planes; p++) {
void *ptr = planes[p];
int total = mp_aframe_get_total_plane_samples(mpa);
switch (format) {
case AF_FORMAT_FLOAT:
for (int s = 0; s < total; s++)
sanitizef(((float *)ptr)[s]);
break;
case AF_FORMAT_DOUBLE:
for (int s = 0; s < total; s++)
sanitizef(((double *)ptr)[s]);
break;
}
}
}
// Return the timestamp of the sample just after the end of this frame.
double mp_aframe_end_pts(struct mp_aframe *f)
{
@@ -637,7 +700,7 @@ int mp_aframe_pool_allocate(struct mp_aframe_pool *pool, struct mp_aframe *frame
av_freep(&av_frame->extended_data); // sigh
if (planes > AV_NUM_DATA_POINTERS) {
av_frame->extended_data =
av_mallocz_array(planes, sizeof(av_frame->extended_data[0]));
av_calloc(planes, sizeof(av_frame->extended_data[0]));
if (!av_frame->extended_data)
abort();
} else {
+1
View File
@@ -60,6 +60,7 @@ char *mp_aframe_format_str_buf(char *buf, size_t buf_size, struct mp_aframe *fmt
#define mp_aframe_format_str(fmt) mp_aframe_format_str_buf((char[32]){0}, 32, (fmt))
void mp_aframe_skip_samples(struct mp_aframe *f, int samples);
void mp_aframe_sanitize_float(struct mp_aframe *f);
double mp_aframe_end_pts(struct mp_aframe *f);
double mp_aframe_duration(struct mp_aframe *f);
void mp_aframe_clip_timestamps(struct mp_aframe *f, double start, double end);
+17
View File
@@ -470,6 +470,23 @@ char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *
return mp_chmap_to_str_buf(buf, buf_size, &map);
}
mp_ch_layout_tuple *mp_iterate_builtin_layouts(void **opaque)
{
uintptr_t i = (uintptr_t)*opaque;
if (i >= MP_ARRAY_SIZE(std_layout_names) ||
!std_layout_names[i][0])
return NULL;
*opaque = (void *)(i + 1);
if (std_layout_names[i][1][0] == '\0') {
return mp_iterate_builtin_layouts(opaque);
}
return &std_layout_names[i];
}
void mp_chmap_print_help(struct mp_log *log)
{
mp_info(log, "Speakers:\n");
+15
View File
@@ -75,6 +75,8 @@ struct mp_chmap {
uint8_t speaker[MP_NUM_CHANNELS];
};
typedef const char * const (mp_ch_layout_tuple)[2];
#define MP_SP(speaker) MP_SPEAKER_ID_ ## speaker
#define MP_CHMAP2(a, b) \
@@ -129,6 +131,19 @@ char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *
bool mp_chmap_from_str(struct mp_chmap *dst, bstr src);
/**
* Iterate over all built-in channel layouts which have mapped channels.
*
* @param opaque a pointer where the iteration state is stored. Must point
* to nullptr to start the iteration.
*
* @return nullptr when the iteration is finished.
* Otherwise a pointer to an array of two char pointers.
* - [0] being the human-readable layout name.
* - [1] being the string representation of the layout.
*/
mp_ch_layout_tuple *mp_iterate_builtin_layouts(void **opaque);
struct mp_log;
void mp_chmap_print_help(struct mp_log *log);
+51
View File
@@ -0,0 +1,51 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libavutil/channel_layout.h>
#include "chmap.h"
#include "chmap_avchannel.h"
bool mp_chmap_from_av_layout(struct mp_chmap *dst, const AVChannelLayout *src)
{
*dst = (struct mp_chmap) {0};
switch (src->order) {
case AV_CHANNEL_ORDER_UNSPEC:
mp_chmap_from_channels(dst, src->nb_channels);
return dst->num == src->nb_channels;
case AV_CHANNEL_ORDER_NATIVE:
mp_chmap_from_lavc(dst, src->u.mask);
return dst->num == src->nb_channels;
default:
// TODO: handle custom layouts
return false;
}
}
void mp_chmap_to_av_layout(AVChannelLayout *dst, const struct mp_chmap *src)
{
*dst = (AVChannelLayout){
.order = AV_CHANNEL_ORDER_UNSPEC,
.nb_channels = src->num,
};
// TODO: handle custom layouts
if (!mp_chmap_is_unknown(src)) {
av_channel_layout_from_mask(dst, mp_chmap_to_lavc(src));
}
}
+32
View File
@@ -0,0 +1,32 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <libavutil/channel_layout.h>
#include "config.h"
#include "chmap.h"
#if HAVE_AV_CHANNEL_LAYOUT
bool mp_chmap_from_av_layout(struct mp_chmap *dst, const AVChannelLayout *src);
void mp_chmap_to_av_layout(AVChannelLayout *dst, const struct mp_chmap *src);
#endif
+21 -1
View File
@@ -26,8 +26,11 @@
#include <libavutil/common.h>
#include <libavutil/intreadwrite.h>
#include "config.h"
#include "mpv_talloc.h"
#include "audio/aframe.h"
#include "audio/chmap_avchannel.h"
#include "audio/fmt-conversion.h"
#include "common/av_common.h"
#include "common/codecs.h"
@@ -106,8 +109,22 @@ static bool init(struct mp_filter *da, struct mp_codec_params *codec,
lavc_context->pkt_timebase = ctx->codec_timebase;
if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) {
const struct mp_chmap *requested_layout =
&mpopts->audio_output_channels.chmaps[0];
#if !HAVE_AV_CHANNEL_LAYOUT
lavc_context->request_channel_layout =
mp_chmap_to_lavc(&mpopts->audio_output_channels.chmaps[0]);
mp_chmap_to_lavc(requested_layout);
#else
AVChannelLayout av_layout = { 0 };
mp_chmap_to_av_layout(&av_layout, requested_layout);
// Always try to set requested output layout - currently only something
// supported by AC3, MLP/TrueHD, DTS and the fdk-aac wrapper.
av_opt_set_chlayout(lavc_context, "downmix", &av_layout,
AV_OPT_SEARCH_CHILDREN);
av_channel_layout_uninit(&av_layout);
#endif
}
// Always try to set - option only exists for AC3 at the moment
@@ -243,6 +260,9 @@ static int receive_frame(struct mp_filter *da, struct mp_frame *out)
priv->trim_samples -= trim;
}
// Strip possibly bogus float values like Infinity, NaN, denormalized
mp_aframe_sanitize_float(mpframe);
if (mp_aframe_get_size(mpframe) > 0) {
*out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
} else {
+86 -37
View File
@@ -31,7 +31,10 @@
#include <libavutil/bswap.h>
#include <libavutil/mem.h>
#include "config.h"
#include "audio/aframe.h"
#include "audio/chmap_avchannel.h"
#include "audio/chmap_sel.h"
#include "audio/fmt-conversion.h"
#include "audio/format.h"
@@ -47,7 +50,7 @@
#define AC3_MAX_CHANNELS 6
#define AC3_MAX_CODED_FRAME_SIZE 3840
#define AC3_FRAME_SIZE (6 * 256)
const uint16_t ac3_bitrate_tab[19] = {
const static uint16_t ac3_bitrate_tab[19] = {
32, 40, 48, 56, 64, 80, 96, 112, 128,
160, 192, 224, 256, 320, 384, 448, 512, 576, 640
};
@@ -70,6 +73,7 @@ struct priv {
const struct AVCodec *lavc_acodec;
struct AVCodecContext *lavc_actx;
AVPacket *lavc_pkt;
int bit_rate;
int out_samples; // upper bound on encoded output per AC3 frame
};
@@ -103,8 +107,13 @@ static bool reinit(struct mp_filter *f)
// Put sample parameters
s->lavc_actx->sample_fmt = af_to_avformat(format);
#if !HAVE_AV_CHANNEL_LAYOUT
s->lavc_actx->channels = chmap.num;
s->lavc_actx->channel_layout = mp_chmap_to_lavc(&chmap);
#else
mp_chmap_to_av_layout(&s->lavc_actx->ch_layout, &chmap);
#endif
s->lavc_actx->sample_rate = rate;
s->lavc_actx->bit_rate = bit_rate;
@@ -134,6 +143,7 @@ static void destroy(struct mp_filter *f)
struct priv *s = f->priv;
reset(f);
av_packet_free(&s->lavc_pkt);
avcodec_free_context(&s->lavc_actx);
}
@@ -152,57 +162,57 @@ static void process(struct mp_filter *f)
bool err = true;
struct mp_aframe *out = NULL;
AVPacket pkt = {0};
av_init_packet(&pkt);
AVPacket *pkt = s->lavc_pkt;
// Send input as long as it wants.
while (1) {
if (avcodec_is_open(s->lavc_actx)) {
int lavc_ret = avcodec_receive_packet(s->lavc_actx, &pkt);
int lavc_ret = avcodec_receive_packet(s->lavc_actx, pkt);
if (lavc_ret >= 0)
break;
if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) {
MP_FATAL(f, "Encode failed (receive).\n");
goto done;
goto error;
}
}
AVFrame *frame = NULL;
struct mp_frame input = mp_pin_out_read(s->in_pin);
// The following code assumes no sample data buffering in the encoder.
if (input.type == MP_FRAME_EOF) {
switch (input.type) {
case MP_FRAME_NONE:
goto done; // no data yet
case MP_FRAME_EOF:
mp_pin_in_write(f->ppins[1], input);
return;
} else if (input.type == MP_FRAME_AUDIO) {
goto done;
case MP_FRAME_AUDIO:
TA_FREEP(&s->in_frame);
s->in_frame = input.data;
frame = mp_frame_to_av(input, NULL);
if (!frame)
goto done;
goto error;
if (mp_aframe_get_channels(s->in_frame) < s->opts->min_channel_num) {
// Just pass it through.
s->in_frame = NULL;
mp_pin_in_write(f->ppins[1], input);
return;
goto done;
}
if (!mp_aframe_config_equals(s->in_frame, s->cur_format)) {
if (!reinit(f))
goto done;
goto error;
}
} else if (input.type) {
goto done;
} else {
return; // no data yet
break;
default: goto error; // unexpected packet type
}
int lavc_ret = avcodec_send_frame(s->lavc_actx, frame);
av_frame_free(&frame);
if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) {
MP_FATAL(f, "Encode failed (send).\n");
goto done;
goto error;
}
}
if (!s->in_frame)
goto done;
goto error;
out = mp_aframe_create();
mp_aframe_set_format(out, AF_FORMAT_S_AC3);
@@ -210,18 +220,18 @@ static void process(struct mp_filter *f)
mp_aframe_set_rate(out, 48000);
if (mp_aframe_pool_allocate(s->out_pool, out, s->out_samples) < 0)
goto done;
goto error;
int sstride = mp_aframe_get_sstride(out);
mp_aframe_copy_attributes(out, s->in_frame);
int frame_size = pkt.size;
int frame_size = pkt->size;
int header_len = 0;
char hdr[8];
if (s->opts->add_iec61937_header && pkt.size > 5) {
int bsmod = pkt.data[5] & 0x7;
if (s->opts->add_iec61937_header && pkt->size > 5) {
int bsmod = pkt->data[5] & 0x7;
int len = frame_size;
frame_size = AC3_FRAME_SIZE * 2 * 2;
@@ -239,20 +249,22 @@ static void process(struct mp_filter *f)
uint8_t **planes = mp_aframe_get_data_rw(out);
if (!planes)
goto done;
goto error;
char *buf = planes[0];
memcpy(buf, hdr, header_len);
memcpy(buf + header_len, pkt.data, pkt.size);
memset(buf + header_len + pkt.size, 0,
frame_size - (header_len + pkt.size));
swap_16((uint16_t *)(buf + header_len), pkt.size / 2);
memcpy(buf + header_len, pkt->data, pkt->size);
memset(buf + header_len + pkt->size, 0,
frame_size - (header_len + pkt->size));
swap_16((uint16_t *)(buf + header_len), pkt->size / 2);
mp_aframe_set_size(out, frame_size / sstride);
mp_pin_in_write(f->ppins[1], MAKE_FRAME(MP_FRAME_AUDIO, out));
out = NULL;
err = 0;
done:
av_packet_unref(&pkt);
err = false;
// fall through
error:
av_packet_unref(pkt);
talloc_free(out);
if (err)
mp_filter_internal_mark_failed(f);
@@ -266,6 +278,38 @@ static const struct mp_filter_info af_lavcac3enc_filter = {
.destroy = destroy,
};
static void add_chmaps_to_autoconv(struct mp_filter *f,
struct mp_autoconvert *conv,
const struct AVCodec *codec)
{
#if !HAVE_AV_CHANNEL_LAYOUT
const uint64_t *lch = codec->channel_layouts;
for (int n = 0; lch && lch[n]; n++) {
struct mp_chmap chmap = {0};
mp_chmap_from_lavc(&chmap, lch[n]);
if (mp_chmap_is_valid(&chmap))
mp_autoconvert_add_chmap(conv, &chmap);
}
#else
const AVChannelLayout *lch = codec->ch_layouts;
for (int n = 0; lch && lch[n].nb_channels; n++) {
struct mp_chmap chmap = {0};
if (!mp_chmap_from_av_layout(&chmap, &lch[n])) {
char layout[128] = {0};
MP_VERBOSE(f, "Skipping unsupported channel layout: %s\n",
av_channel_layout_describe(&lch[n],
layout, 128) < 0 ?
"undefined" : layout);
continue;
}
if (mp_chmap_is_valid(&chmap))
mp_autoconvert_add_chmap(conv, &chmap);
}
#endif
}
static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent,
void *options)
{
@@ -295,14 +339,23 @@ static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent,
goto error;
}
s->lavc_pkt = av_packet_alloc();
if (!s->lavc_pkt)
goto error;
if (mp_set_avopts(f->log, s->lavc_actx, s->opts->avopts) < 0)
goto error;
// For this one, we require the decoder to expert lists of all supported
// For this one, we require the decoder to export lists of all supported
// parameters. (Not all decoders do that, but the ones we're interested
// in do.)
if (!s->lavc_acodec->sample_fmts ||
!s->lavc_acodec->channel_layouts)
#if !HAVE_AV_CHANNEL_LAYOUT
!s->lavc_acodec->channel_layouts
#else
!s->lavc_acodec->ch_layouts
#endif
)
{
MP_ERR(f, "Audio encoder doesn't list supported parameters.\n");
goto error;
@@ -334,13 +387,7 @@ static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent,
mp_autoconvert_add_afmt(conv, mpfmt);
}
const uint64_t *lch = s->lavc_acodec->channel_layouts;
for (int n = 0; lch && lch[n]; n++) {
struct mp_chmap chmap = {0};
mp_chmap_from_lavc(&chmap, lch[n]);
if (mp_chmap_is_valid(&chmap))
mp_autoconvert_add_chmap(conv, &chmap);
}
add_chmaps_to_autoconv(f, conv, s->lavc_acodec);
// At least currently, the AC3 encoder doesn't export sample rates.
mp_autoconvert_add_srate(conv, 48000);
@@ -357,6 +404,8 @@ static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent,
return f;
error:
av_packet_free(&s->lavc_pkt);
avcodec_free_context(&s->lavc_actx);
talloc_free(f);
return NULL;
}
+15 -2
View File
@@ -20,6 +20,8 @@
#include <rubberband/rubberband-c.h>
#include "config.h"
#include "audio/aframe.h"
#include "audio/format.h"
#include "common/common.h"
@@ -31,7 +33,7 @@
// command line options
struct f_opts {
int transients, detector, phase, window,
smoothing, formant, pitch, channels;
smoothing, formant, pitch, channels, engine;
double scale;
};
@@ -78,7 +80,10 @@ static bool init_rubberband(struct mp_filter *f)
int opts = p->opts->transients | p->opts->detector | p->opts->phase |
p->opts->window | p->opts->smoothing | p->opts->formant |
p->opts->pitch | p-> opts->channels |
p->opts->pitch | p->opts->channels |
#if HAVE_RUBBERBAND_3
p->opts->engine |
#endif
RubberBandOptionProcessRealTime;
int rate = mp_aframe_get_rate(p->pending);
@@ -331,6 +336,9 @@ const struct mp_user_filter_entry af_rubberband = {
.transients = RubberBandOptionTransientsMixed,
.formant = RubberBandOptionFormantPreserved,
.channels = RubberBandOptionChannelsTogether,
#if HAVE_RUBBERBAND_3
.engine = RubberBandOptionEngineFiner,
#endif
},
.options = (const struct m_option[]) {
{"transients", OPT_CHOICE(transients,
@@ -361,6 +369,11 @@ const struct mp_user_filter_entry af_rubberband = {
{"channels", OPT_CHOICE(channels,
{"apart", RubberBandOptionChannelsApart},
{"together", RubberBandOptionChannelsTogether})},
#if HAVE_RUBBERBAND_3
{"engine", OPT_CHOICE(engine,
{"finer", RubberBandOptionEngineFiner},
{"faster", RubberBandOptionEngineFaster})},
#endif
{"pitch-scale", OPT_DOUBLE(scale), M_RANGE(0.01, 100)},
{0}
},
+1 -1
View File
@@ -230,7 +230,7 @@ const struct mp_user_filter_entry af_scaletempo2 = {
.wsola_search_interval_ms = 30,
},
.options = (const struct m_option[]) {
{"search-interval",
{"search-interval",
OPT_FLOAT(wsola_search_interval_ms), M_RANGE(1, 1000)},
{"window-size",
OPT_FLOAT(ola_window_size_ms), M_RANGE(1, 1000)},
+6 -7
View File
@@ -472,10 +472,8 @@ static int frames_needed(struct mp_scaletempo2 *p)
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);
}
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,
@@ -487,7 +485,8 @@ int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
if (total_fill == 0) return 0;
int required_size = total_fill + p->input_buffer_frames;
resize_input_buffer(p, required_size);
if (required_size > p->input_buffer_size)
resize_input_buffer(p, required_size);
for (int i = 0; i < p->channels; ++i) {
memcpy(p->input_buffer[i] + p->input_buffer_frames,
@@ -743,9 +742,9 @@ void mp_scaletempo2_init(struct mp_scaletempo2 *p, int channels, int rate)
p->channels = channels;
p->samples_per_second = rate;
p->num_candidate_blocks = (int)(p->opts->wsola_search_interval_ms
p->num_candidate_blocks = (int)(p->opts->wsola_search_interval_ms
* p->samples_per_second / 1000);
p->ola_window_size = (int)(p->opts->ola_window_size_ms
p->ola_window_size = (int)(p->opts->ola_window_size_ms
* p->samples_per_second / 1000);
// Make sure window size in an even number.
p->ola_window_size += p->ola_window_size & 1;
+2 -2
View File
@@ -1,4 +1,4 @@
// This filter was ported from Chromium
// This filter was ported from Chromium
// (https://chromium.googlesource.com/chromium/chromium/+/51ed77e3f37a9a9b80d6d0a8259e84a8ca635259/media/filters/audio_renderer_algorithm.cc)
//
// Copyright 2015 The Chromium Authors. All rights reserved.
@@ -118,4 +118,4 @@ int mp_scaletempo2_fill_input_buffer(struct mp_scaletempo2 *p,
uint8_t **planes, int frame_size, bool final);
int mp_scaletempo2_fill_buffer(struct mp_scaletempo2 *p,
float **dest, int dest_size, float playback_rate);
bool mp_scaletempo2_frames_available(struct mp_scaletempo2 *p);
bool mp_scaletempo2_frames_available(struct mp_scaletempo2 *p);
+4 -4
View File
@@ -187,7 +187,7 @@ int af_format_conversion_score(int dst_format, int src_format)
return score;
}
struct entry {
struct mp_entry {
int fmt;
int score;
};
@@ -195,7 +195,7 @@ struct entry {
static int cmp_entry(const void *a, const void *b)
{
#define CMP_INT(a, b) (a > b ? 1 : (a < b ? -1 : 0))
return -CMP_INT(((struct entry *)a)->score, ((struct entry *)b)->score);
return -CMP_INT(((struct mp_entry *)a)->score, ((struct mp_entry *)b)->score);
}
// Return a list of sample format compatible to src_format, sorted by order
@@ -207,11 +207,11 @@ static int cmp_entry(const void *a, const void *b)
void af_get_best_sample_formats(int src_format, int *out_formats)
{
int num = 0;
struct entry e[AF_FORMAT_COUNT + 1];
struct mp_entry e[AF_FORMAT_COUNT + 1];
for (int fmt = 1; fmt < AF_FORMAT_COUNT; fmt++) {
int score = af_format_conversion_score(fmt, src_format);
if (score > INT_MIN)
e[num++] = (struct entry){fmt, score};
e[num++] = (struct mp_entry){fmt, score};
}
qsort(e, num, sizeof(e[0]), cmp_entry);
for (int n = 0; n < num; n++)
+36 -10
View File
@@ -41,6 +41,8 @@ extern const struct ao_driver audio_out_audiounit;
extern const struct ao_driver audio_out_coreaudio;
extern const struct ao_driver audio_out_coreaudio_exclusive;
extern const struct ao_driver audio_out_rsound;
extern const struct ao_driver audio_out_pipewire;
extern const struct ao_driver audio_out_sndio;
extern const struct ao_driver audio_out_pulse;
extern const struct ao_driver audio_out_jack;
extern const struct ao_driver audio_out_openal;
@@ -63,6 +65,9 @@ static const struct ao_driver * const audio_out_drivers[] = {
#if HAVE_COREAUDIO
&audio_out_coreaudio,
#endif
#if HAVE_PIPEWIRE
&audio_out_pipewire,
#endif
#if HAVE_PULSE
&audio_out_pulse,
#endif
@@ -87,6 +92,9 @@ static const struct ao_driver * const audio_out_drivers[] = {
#endif
#if HAVE_SDL2_AUDIO
&audio_out_sdl,
#endif
#if HAVE_SNDIO
&audio_out_sndio,
#endif
&audio_out_null,
#if HAVE_COREAUDIO
@@ -120,7 +128,6 @@ static bool get_desc(struct m_obj_desc *dst, int index)
static const struct m_obj_list ao_obj_list = {
.get_desc = get_desc,
.description = "audio outputs",
.allow_unknown_entries = true,
.allow_trailer = true,
.disallow_positional_parameters = true,
.use_global_options = true,
@@ -446,8 +453,9 @@ struct ao_hotplug {
void *wakeup_ctx;
// A single AO instance is used to listen to hotplug events. It wouldn't
// make much sense to allow multiple AO drivers; all sane platforms have
// a single such audio API.
// This is _not_ the same AO instance as used for playing audio.
// a single audio API providing all events.
// This is _not_ necessarily the same AO instance as used for playing
// audio.
struct ao *ao;
// cached
struct ao_device_list *list;
@@ -487,7 +495,8 @@ bool ao_hotplug_check_update(struct ao_hotplug *hp)
}
// The return value is valid until the next call to this API.
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp,
struct ao *playback_ao)
{
if (hp->list && !hp->needs_update)
return hp->list;
@@ -499,6 +508,19 @@ struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
MP_TARRAY_APPEND(list, list->devices, list->num_devices,
(struct ao_device_desc){"auto", "Autoselect device"});
// Try to use the same AO for hotplug handling as for playback.
// Different AOs may not agree and the playback one is the only one the
// user knows about and may even have configured explicitly.
if (!hp->ao && playback_ao && playback_ao->driver->hotplug_init) {
struct ao *ao = ao_alloc(true, hp->global, hp->wakeup_cb, hp->wakeup_ctx,
(char *)playback_ao->driver->name);
if (playback_ao->driver->hotplug_init(ao) >= 0) {
hp->ao = ao;
} else {
talloc_free(ao);
}
}
for (int n = 0; audio_out_drivers[n]; n++) {
const struct ao_driver *d = audio_out_drivers[n];
if (d == &audio_out_null)
@@ -510,10 +532,13 @@ struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
continue;
if (ao->driver->hotplug_init) {
if (!hp->ao && ao->driver->hotplug_init(ao) >= 0)
hp->ao = ao; // keep this one
if (hp->ao && hp->ao->driver == d)
get_devices(hp->ao, list);
if (ao->driver->hotplug_init(ao) >= 0) {
get_devices(ao, list);
if (hp->ao)
ao->driver->hotplug_uninit(ao);
else
hp->ao = ao; // keep this one
}
} else {
get_devices(ao, list);
}
@@ -562,10 +587,11 @@ static void dummy_wakeup(void *ctx)
{
}
void ao_print_devices(struct mpv_global *global, struct mp_log *log)
void ao_print_devices(struct mpv_global *global, struct mp_log *log,
struct ao *playback_ao)
{
struct ao_hotplug *hp = ao_hotplug_create(global, dummy_wakeup, NULL);
struct ao_device_list *list = ao_hotplug_get_device_list(hp);
struct ao_device_list *list = ao_hotplug_get_device_list(hp, playback_ao);
mp_info(log, "List of detected audio devices:\n");
for (int n = 0; n < list->num_devices; n++) {
struct ao_device_desc *desc = &list->devices[n];
+9 -2
View File
@@ -35,6 +35,8 @@ enum aocontrol {
AOCONTROL_SET_MUTE,
// Has char* as argument, which contains the desired stream title.
AOCONTROL_UPDATE_STREAM_TITLE,
// Has enum aocontrol_media_role* argument, which contains the current media role
AOCONTROL_UPDATE_MEDIA_ROLE,
};
// If set, then the queued audio data is the last. Note that after a while, new
@@ -64,6 +66,11 @@ typedef struct ao_control_vol {
float right;
} ao_control_vol_t;
enum aocontrol_media_role {
AOCONTROL_MEDIA_ROLE_MUSIC,
AOCONTROL_MEDIA_ROLE_MOVIE,
};
struct ao_device_desc {
const char *name; // symbolic name; will be set on ao->device
const char *desc; // verbose human readable name
@@ -119,8 +126,8 @@ struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
void *wakeup_ctx);
void ao_hotplug_destroy(struct ao_hotplug *hp);
bool ao_hotplug_check_update(struct ao_hotplug *hp);
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp);
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp, struct ao *playback_ao);
void ao_print_devices(struct mpv_global *global, struct mp_log *log);
void ao_print_devices(struct mpv_global *global, struct mp_log *log, struct ao *playback_ao);
#endif /* MPLAYER_AUDIO_OUT_H */
+78 -14
View File
@@ -36,6 +36,54 @@ struct priv {
double device_latency;
};
static OSStatus au_get_ary(AudioUnit unit, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void **data, UInt32 *outDataSize)
{
OSStatus err;
err = AudioUnitGetPropertyInfo(unit, inID, inScope, inElement, outDataSize, NULL);
CHECK_CA_ERROR_SILENT_L(coreaudio_error);
*data = talloc_zero_size(NULL, *outDataSize);
err = AudioUnitGetProperty(unit, inID, inScope, inElement, *data, outDataSize);
CHECK_CA_ERROR_SILENT_L(coreaudio_error_free);
return err;
coreaudio_error_free:
talloc_free(*data);
coreaudio_error:
return err;
}
static AudioChannelLayout *convert_layout(AudioChannelLayout *layout, UInt32* size)
{
AudioChannelLayoutTag tag = layout->mChannelLayoutTag;
AudioChannelLayout *new_layout;
if (tag == kAudioChannelLayoutTag_UseChannelDescriptions)
return layout;
else if (tag == kAudioChannelLayoutTag_UseChannelBitmap)
AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(UInt32), &layout->mChannelBitmap, size);
else
AudioFormatGetPropertyInfo(kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &tag, size);
new_layout = talloc_zero_size(NULL, *size);
if (!new_layout) {
talloc_free(layout);
return NULL;
}
if (tag == kAudioChannelLayoutTag_UseChannelBitmap)
AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(UInt32), &layout->mChannelBitmap, size, new_layout);
else
AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &tag, size, new_layout);
new_layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
talloc_free(layout);
return new_layout;
}
static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
const AudioTimeStamp *ts, UInt32 bus,
UInt32 frames, AudioBufferList *buffer_list)
@@ -59,12 +107,15 @@ static bool init_audiounit(struct ao *ao)
AudioStreamBasicDescription asbd;
OSStatus err;
uint32_t size;
AudioChannelLayout *layout = NULL;
struct priv *p = ao->priv;
AVAudioSession *instance = AVAudioSession.sharedInstance;
AVAudioSessionPortDescription *port = nil;
NSInteger maxChannels = instance.maximumOutputNumberOfChannels;
NSInteger prefChannels = MIN(maxChannels, ao->channels.num);
MP_VERBOSE(ao, "max channels: %ld, requested: %d\n", maxChannels, (int)ao->channels.num);
[instance setCategory:AVAudioSessionCategoryPlayback error:nil];
[instance setMode:AVAudioSessionModeMoviePlayback error:nil];
[instance setActive:YES error:nil];
@@ -91,23 +142,33 @@ static bool init_audiounit(struct ao *ao)
CHECK_CA_ERROR_L(coreaudio_error_component,
"unable to initialize audio unit");
err = au_get_ary(p->audio_unit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Output,
0, (void**)&layout, &size);
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"unable to retrieve audio unit channel layout");
MP_VERBOSE(ao, "AU channel layout tag: %x (%x)\n", layout->mChannelLayoutTag, layout->mChannelBitmap);
layout = convert_layout(layout, &size);
if (!layout) {
MP_ERR(ao, "unable to convert channel layout to list format\n");
goto coreaudio_error_audiounit;
}
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; i++) {
MP_VERBOSE(ao, "channel map: %i: %u\n", i, layout->mChannelDescriptions[i].mChannelLabel);
}
if (af_fmt_is_spdif(ao->format) || instance.outputNumberOfChannels <= 2) {
ao->channels = (struct mp_chmap)MP_CHMAP_INIT_STEREO;
MP_VERBOSE(ao, "using stereo output\n");
} else {
port = instance.currentRoute.outputs.firstObject;
if (port.channels.count == 2 &&
port.channels[0].channelLabel == kAudioChannelLabel_Unknown) {
// Special case when using an HDMI adapter. The iOS device will
// perform SPDIF conversion for us, so send all available channels
// using the AC3 mapping.
ao->channels = (struct mp_chmap)MP_CHMAP6(FL, FC, FR, SL, SR, LFE);
} else {
ao->channels.num = (uint8_t)port.channels.count;
for (AVAudioSessionChannelDescription *ch in port.channels) {
ao->channels.speaker[ch.channelNumber - 1] =
ca_label_to_mp_speaker_id(ch.channelLabel);
}
ao->channels.num = (uint8_t)layout->mNumberChannelDescriptions;
for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; i++) {
ao->channels.speaker[i] =
ca_label_to_mp_speaker_id(layout->mChannelDescriptions[i].mChannelLabel);
}
MP_VERBOSE(ao, "using standard channel mapping\n");
}
ca_fill_asbd(ao, &asbd);
@@ -132,6 +193,8 @@ static bool init_audiounit(struct ao *ao)
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"unable to set render callback on audio unit");
talloc_free(layout);
return true;
coreaudio_error_audiounit:
@@ -139,6 +202,7 @@ coreaudio_error_audiounit:
coreaudio_error_component:
AudioComponentInstanceDispose(p->audio_unit);
coreaudio_error:
talloc_free(layout);
return false;
}
@@ -154,7 +218,7 @@ static void start(struct ao *ao)
struct priv *p = ao->priv;
AVAudioSession *instance = AVAudioSession.sharedInstance;
p->device_latency = [instance outputLatency] + [instance IOBufferDuration];
p->device_latency = [instance outputLatency];
OSStatus err = AudioOutputUnitStart(p->audio_unit);
CHECK_CA_WARN("can't start audio unit");
+1 -1
View File
@@ -16,7 +16,7 @@
*/
/*
* Abstractions on the CoreAudio API to make property setting/getting suck les
* Abstractions on the CoreAudio API to make property setting/getting suck less
*/
#include "audio/out/ao_coreaudio_properties.h"
+1 -1
View File
@@ -26,7 +26,7 @@
#include "audio/out/ao.h"
#include "internal.h"
#define CA_CFSTR_ENCODING kCFStringEncodingASCII
#define CA_CFSTR_ENCODING kCFStringEncodingUTF8
CFStringRef cfstr_from_cstr(char *str);
char *cfstr_get_cstr(CFStringRef cfstr);
+6
View File
@@ -31,6 +31,7 @@
#include "options/options.h"
#include "common/common.h"
#include "audio/aframe.h"
#include "audio/chmap_avchannel.h"
#include "audio/format.h"
#include "audio/fmt-conversion.h"
#include "filters/filter_internal.h"
@@ -124,8 +125,13 @@ static int init(struct ao *ao)
if (!ao_chmap_sel_adjust2(ao, &sel, &ao->channels, false))
goto fail;
mp_chmap_reorder_to_lavc(&ao->channels);
#if !HAVE_AV_CHANNEL_LAYOUT
encoder->channels = ao->channels.num;
encoder->channel_layout = mp_chmap_to_lavc(&ao->channels);
#else
mp_chmap_to_av_layout(&encoder->ch_layout, &ao->channels);
#endif
encoder->sample_fmt = AV_SAMPLE_FMT_NONE;
+9 -3
View File
@@ -199,8 +199,14 @@ static int init(struct ao *ao)
alListenerfv(AL_ORIENTATION, direction);
alGenSources(1, &source);
if (p->direct_channels && alGetEnumValue((ALchar*)"AL_DIRECT_CHANNELS_SOFT")) {
alSourcei(source, alGetEnumValue((ALchar*)"AL_DIRECT_CHANNELS_SOFT"), AL_TRUE);
if (p->direct_channels) {
if (alIsExtensionPresent("AL_SOFT_direct_channels_remix")) {
alSourcei(source,
alGetEnumValue((ALchar*)"AL_DIRECT_CHANNELS_SOFT"),
alcGetEnumValue(dev, "AL_REMIX_UNMATCHED_SOFT"));
} else {
MP_WARN(ao, "Direct channels aren't supported by this version of OpenAL\n");
}
}
cur_buf = 0;
@@ -385,7 +391,7 @@ const struct ao_driver audio_out_openal = {
.priv_defaults = &(const struct priv) {
.num_buffers = 4,
.num_samples = 8192,
.direct_channels = 0,
.direct_channels = 1,
},
.options = (const struct m_option[]) {
{"num-buffers", OPT_INT(num_buffers), M_RANGE(2, MAX_BUF)},
+2
View File
@@ -111,6 +111,8 @@ static int init(struct ao *ao)
// This AO only supports two channels at the moment
mp_chmap_from_channels(&ao->channels, 2);
// Upstream "Wilhelm" supports only 8000 <= rate <= 192000
ao->samplerate = MPCLAMP(ao->samplerate, 8000, 192000);
CHK(slCreateEngine(&p->sl, 0, NULL, 0, NULL, NULL));
CHK((*p->sl)->Realize(p->sl, SL_BOOLEAN_FALSE));
+1
View File
@@ -49,6 +49,7 @@
#endif
#define PATH_DEV_DSP "/dev/dsp"
#define PATH_DEV_MIXER "/dev/mixer"
struct priv {
int dsp_fd;
+817
View File
@@ -0,0 +1,817 @@
/*
* PipeWire audio output driver.
* Copyright (C) 2021 Thomas Weißschuh <thomas@t-8ch.de>
* Copyright (C) 2021 Oschowa <oschowa@web.de>
* Copyright (C) 2020 Andreas Kempf <aakempf@gmail.com>
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pipewire/pipewire.h>
#include <pipewire/global.h>
#include <spa/param/audio/format-utils.h>
#include <spa/param/props.h>
#include <spa/utils/result.h>
#include <math.h>
#include "common/msg.h"
#include "options/m_config.h"
#include "options/m_option.h"
#include "ao.h"
#include "audio/format.h"
#include "config.h"
#include "generated/version.h"
#include "internal.h"
#include "osdep/timer.h"
// Added in Pipewire 0.3.33
// remove the fallback when we require a newer version
#ifndef PW_KEY_NODE_RATE
#define PW_KEY_NODE_RATE "node.rate"
#endif
// Added in Pipewire 0.3.44
// remove the fallback when we require a newer version
#ifndef PW_KEY_TARGET_OBJECT
#define PW_KEY_TARGET_OBJECT "target.object"
#endif
#if !PW_CHECK_VERSION(0, 3, 50)
static inline int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time *time, size_t size) {
return pw_stream_get_time(stream, time);
}
#endif
struct priv {
struct pw_thread_loop *loop;
struct pw_stream *stream;
struct pw_core *core;
struct spa_hook stream_listener;
struct spa_hook core_listener;
bool muted;
float volume[2];
struct {
int buffer_msec;
char *remote;
} options;
struct {
struct pw_registry *registry;
struct spa_hook registry_listener;
struct spa_list sinks;
} hotplug;
};
struct id_list {
uint32_t id;
struct spa_list node;
};
static enum spa_audio_format af_fmt_to_pw(struct ao *ao, enum af_format format)
{
switch (format) {
case AF_FORMAT_U8: return SPA_AUDIO_FORMAT_U8;
case AF_FORMAT_S16: return SPA_AUDIO_FORMAT_S16;
case AF_FORMAT_S32: return SPA_AUDIO_FORMAT_S32;
case AF_FORMAT_FLOAT: return SPA_AUDIO_FORMAT_F32;
case AF_FORMAT_DOUBLE: return SPA_AUDIO_FORMAT_F64;
case AF_FORMAT_U8P: return SPA_AUDIO_FORMAT_U8P;
case AF_FORMAT_S16P: return SPA_AUDIO_FORMAT_S16P;
case AF_FORMAT_S32P: return SPA_AUDIO_FORMAT_S32P;
case AF_FORMAT_FLOATP: return SPA_AUDIO_FORMAT_F32P;
case AF_FORMAT_DOUBLEP: return SPA_AUDIO_FORMAT_F64P;
default:
MP_WARN(ao, "Unhandled format %d\n", format);
return SPA_AUDIO_FORMAT_UNKNOWN;
}
}
static enum spa_audio_channel mp_speaker_id_to_spa(struct ao *ao, enum mp_speaker_id mp_speaker_id)
{
switch (mp_speaker_id) {
case MP_SPEAKER_ID_FL: return SPA_AUDIO_CHANNEL_FL;
case MP_SPEAKER_ID_FR: return SPA_AUDIO_CHANNEL_FR;
case MP_SPEAKER_ID_FC: return SPA_AUDIO_CHANNEL_FC;
case MP_SPEAKER_ID_LFE: return SPA_AUDIO_CHANNEL_LFE;
case MP_SPEAKER_ID_BL: return SPA_AUDIO_CHANNEL_RL;
case MP_SPEAKER_ID_BR: return SPA_AUDIO_CHANNEL_RR;
case MP_SPEAKER_ID_FLC: return SPA_AUDIO_CHANNEL_FLC;
case MP_SPEAKER_ID_FRC: return SPA_AUDIO_CHANNEL_FRC;
case MP_SPEAKER_ID_BC: return SPA_AUDIO_CHANNEL_RC;
case MP_SPEAKER_ID_SL: return SPA_AUDIO_CHANNEL_SL;
case MP_SPEAKER_ID_SR: return SPA_AUDIO_CHANNEL_SR;
case MP_SPEAKER_ID_TC: return SPA_AUDIO_CHANNEL_TC;
case MP_SPEAKER_ID_TFL: return SPA_AUDIO_CHANNEL_TFL;
case MP_SPEAKER_ID_TFC: return SPA_AUDIO_CHANNEL_TFC;
case MP_SPEAKER_ID_TFR: return SPA_AUDIO_CHANNEL_TFR;
case MP_SPEAKER_ID_TBL: return SPA_AUDIO_CHANNEL_TRL;
case MP_SPEAKER_ID_TBC: return SPA_AUDIO_CHANNEL_TRC;
case MP_SPEAKER_ID_TBR: return SPA_AUDIO_CHANNEL_TRR;
case MP_SPEAKER_ID_DL: return SPA_AUDIO_CHANNEL_FL;
case MP_SPEAKER_ID_DR: return SPA_AUDIO_CHANNEL_FR;
case MP_SPEAKER_ID_WL: return SPA_AUDIO_CHANNEL_FL;
case MP_SPEAKER_ID_WR: return SPA_AUDIO_CHANNEL_FR;
case MP_SPEAKER_ID_SDL: return SPA_AUDIO_CHANNEL_SL;
case MP_SPEAKER_ID_SDR: return SPA_AUDIO_CHANNEL_SL;
case MP_SPEAKER_ID_LFE2: return SPA_AUDIO_CHANNEL_LFE2;
case MP_SPEAKER_ID_NA: return SPA_AUDIO_CHANNEL_NA;
default:
MP_WARN(ao, "Unhandled channel %d\n", mp_speaker_id);
return SPA_AUDIO_CHANNEL_UNKNOWN;
};
}
static void on_process(void *userdata)
{
struct ao *ao = userdata;
struct priv *p = ao->priv;
struct pw_time time;
struct pw_buffer *b;
void *data[MP_NUM_CHANNELS];
if ((b = pw_stream_dequeue_buffer(p->stream)) == NULL) {
MP_WARN(ao, "out of buffers: %s\n", strerror(errno));
return;
}
struct spa_buffer *buf = b->buffer;
int bytes_per_channel = buf->datas[0].maxsize / ao->channels.num;
int nframes = bytes_per_channel / ao->sstride;
#if PW_CHECK_VERSION(0, 3, 49)
if (b->requested != 0)
nframes = MPMIN(b->requested, nframes);
#endif
for (int i = 0; i < buf->n_datas; i++)
data[i] = buf->datas[i].data;
pw_stream_get_time_n(p->stream, &time, sizeof(time));
if (time.rate.denom == 0)
time.rate.denom = ao->samplerate;
if (time.rate.num == 0)
time.rate.num = 1;
int64_t end_time = mp_time_us();
/* time.queued is always going to be 0, so we don't need to care */
end_time += (nframes * 1e6 / ao->samplerate) +
((float) time.delay * SPA_USEC_PER_SEC * time.rate.num / time.rate.denom);
int samples = ao_read_data(ao, data, nframes, end_time);
b->size = samples;
for (int i = 0; i < buf->n_datas; i++) {
buf->datas[i].chunk->size = samples * ao->sstride;
buf->datas[i].chunk->offset = 0;
buf->datas[i].chunk->stride = ao->sstride;
}
pw_stream_queue_buffer(p->stream, b);
}
static void on_param_changed(void *userdata, uint32_t id, const struct spa_pod *param)
{
struct ao *ao = userdata;
struct priv *p = ao->priv;
const struct spa_pod *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
if (param == NULL || id != SPA_PARAM_Format)
return;
int buffer_size = ao->device_buffer * af_fmt_to_bytes(ao->format) * ao->channels.num;
params[0] = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(ao->num_planes),
SPA_PARAM_BUFFERS_size, SPA_POD_Int(buffer_size),
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(ao->sstride));
if (!params[0]) {
MP_ERR(ao, "Could not build parameter pod\n");
return;
}
if (pw_stream_update_params(p->stream, params, 1) < 0) {
MP_ERR(ao, "Could not update stream parameters\n");
return;
}
}
static void on_state_changed(void *userdata, enum pw_stream_state old, enum pw_stream_state state, const char *error)
{
struct ao *ao = userdata;
MP_DBG(ao, "Stream state changed: old_state=%d state=%d error=%s\n", old, state, error);
if (state == PW_STREAM_STATE_ERROR) {
MP_WARN(ao, "Stream in error state, trying to reload...\n");
ao_request_reload(ao);
}
if (state == PW_STREAM_STATE_UNCONNECTED && old != PW_STREAM_STATE_UNCONNECTED) {
MP_WARN(ao, "Stream disconnected, trying to reload...\n");
ao_request_reload(ao);
}
}
static float spa_volume_to_mp_volume(float vol)
{
return vol * 100;
}
static float mp_volume_to_spa_volume(float vol)
{
return vol / 100;
}
static float volume_avg(float* vols, uint32_t n)
{
float sum = 0.0;
for (int i = 0; i < n; i++)
sum += vols[i];
return sum / n;
}
static void on_control_info(void *userdata, uint32_t id,
const struct pw_stream_control *control)
{
struct ao *ao = userdata;
struct priv *p = ao->priv;
switch (id) {
case SPA_PROP_mute:
if (control->n_values == 1)
p->muted = control->values[0] >= 0.5;
break;
case SPA_PROP_channelVolumes:
if (control->n_values == 2) {
p->volume[0] = control->values[0];
p->volume[1] = control->values[1];
} else if (control->n_values > 0) {
float volume = volume_avg(control->values, control->n_values);
p->volume[0] = volume;
p->volume[1] = volume;
}
break;
}
}
static const struct pw_stream_events stream_events = {
.version = PW_VERSION_STREAM_EVENTS,
.param_changed = on_param_changed,
.process = on_process,
.state_changed = on_state_changed,
.control_info = on_control_info,
};
static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->loop)
pw_thread_loop_stop(p->loop);
spa_hook_remove(&p->stream_listener);
spa_zero(p->stream_listener);
if (p->stream)
pw_stream_destroy(p->stream);
p->stream = NULL;
if (p->core) {
pw_context_destroy(pw_core_get_context(p->core));
}
p->core = NULL;
if (p->loop)
pw_thread_loop_destroy(p->loop);
p->loop = NULL;
pw_deinit();
}
struct registry_event_global_ctx {
struct ao *ao;
void (*sink_cb) (struct ao *ao, uint32_t id, const struct spa_dict *props, void *sink_cb_ctx);
void *sink_cb_ctx;
};
static bool is_sink_node(const char *type, const struct spa_dict *props)
{
if (strcmp(type, PW_TYPE_INTERFACE_Node) != 0)
return false;
if (!props)
return false;
const char *class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS);
if (!class || strcmp(class, "Audio/Sink") != 0)
return false;
return true;
}
static void for_each_sink_registry_event_global(void *data, uint32_t id,
uint32_t permissions, const
char *type, uint32_t version,
const struct spa_dict *props)
{
struct registry_event_global_ctx *ctx = data;
if (!is_sink_node(type, props))
return;
ctx->sink_cb(ctx->ao, id, props, ctx->sink_cb_ctx);
}
static const struct pw_registry_events for_each_sink_registry_events = {
.version = PW_VERSION_REGISTRY_EVENTS,
.global = for_each_sink_registry_event_global,
};
static void for_each_sink_done(void *data, uint32_t it, int seq)
{
struct pw_thread_loop *loop = data;
pw_thread_loop_signal(loop, false);
}
static const struct pw_core_events for_each_sink_core_events = {
.version = PW_VERSION_CORE_EVENTS,
.done = for_each_sink_done,
};
static int for_each_sink(struct ao *ao, void (cb) (struct ao *ao, uint32_t id,
const struct spa_dict *props, void *ctx), void *cb_ctx)
{
struct priv *priv = ao->priv;
struct pw_registry *registry;
struct spa_hook core_listener;
int ret = -1;
pw_thread_loop_lock(priv->loop);
spa_zero(core_listener);
if (pw_core_add_listener(priv->core, &core_listener, &for_each_sink_core_events, priv->loop) < 0)
goto unlock_loop;
registry = pw_core_get_registry(priv->core, PW_VERSION_REGISTRY, 0);
if (!registry)
goto remove_core_listener;
pw_core_sync(priv->core, 0, 0);
struct spa_hook registry_listener;
struct registry_event_global_ctx revents_ctx = {
.ao = ao,
.sink_cb = cb,
.sink_cb_ctx = cb_ctx,
};
spa_zero(registry_listener);
if (pw_registry_add_listener(registry, &registry_listener, &for_each_sink_registry_events, &revents_ctx) < 0)
goto destroy_registry;
pw_thread_loop_wait(priv->loop);
spa_hook_remove(&registry_listener);
ret = 0;
destroy_registry:
pw_proxy_destroy((struct pw_proxy *)registry);
remove_core_listener:
spa_hook_remove(&core_listener);
unlock_loop:
pw_thread_loop_unlock(priv->loop);
return ret;
}
static void have_sink(struct ao *ao, uint32_t id, const struct spa_dict *props, void *ctx)
{
bool *b = ctx;
*b = true;
}
static bool session_has_sinks(struct ao *ao)
{
bool b = false;
if (for_each_sink(ao, have_sink, &b) < 0)
MP_WARN(ao, "Could not list devices, sink detection may be wrong\n");
return b;
}
static void on_error(void *data, uint32_t id, int seq, int res, const char *message)
{
struct ao *ao = data;
MP_WARN(ao, "Error during playback: %s, %s\n", spa_strerror(res), message);
}
static const struct pw_core_events core_events = {
.version = PW_VERSION_CORE_EVENTS,
.error = on_error,
};
static int pipewire_init_boilerplate(struct ao *ao)
{
struct priv *p = ao->priv;
struct pw_context *context;
pw_init(NULL, NULL);
p->loop = pw_thread_loop_new("ao-pipewire", NULL);
if (p->loop == NULL)
return -1;
pw_thread_loop_lock(p->loop);
if (pw_thread_loop_start(p->loop) < 0)
goto error;
context = pw_context_new(pw_thread_loop_get_loop(p->loop), NULL, 0);
if (!context)
goto error;
p->core = pw_context_connect(
context,
pw_properties_new(PW_KEY_REMOTE_NAME, p->options.remote, NULL),
0);
if (!p->core) {
MP_WARN(ao, "Could not connect to context '%s': %s\n",
p->options.remote, strerror(errno));
goto error;
}
if (pw_core_add_listener(p->core, &p->core_listener, &core_events, ao) < 0)
goto error;
pw_thread_loop_unlock(p->loop);
if (!session_has_sinks(ao)) {
MP_VERBOSE(ao, "PipeWire does not have any audio sinks, skipping\n");
return -1;
}
return 0;
error:
pw_thread_loop_unlock(p->loop);
return -1;
}
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
const struct spa_pod *params[1];
struct pw_properties *props = pw_properties_new(
PW_KEY_MEDIA_TYPE, "Audio",
PW_KEY_MEDIA_CATEGORY, "Playback",
PW_KEY_NODE_NAME, ao->client_name,
PW_KEY_NODE_DESCRIPTION, ao->client_name,
PW_KEY_APP_NAME, ao->client_name,
PW_KEY_APP_ID, ao->client_name,
PW_KEY_APP_ICON_NAME, ao->client_name,
PW_KEY_NODE_ALWAYS_PROCESS, "true",
PW_KEY_TARGET_OBJECT, ao->device,
NULL
);
if (pipewire_init_boilerplate(ao) < 0)
goto error;
ao->device_buffer = p->options.buffer_msec * ao->samplerate / 1000;
pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%d/%d", ao->device_buffer, ao->samplerate);
pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%d", ao->samplerate);
enum spa_audio_format spa_format = af_fmt_to_pw(ao, ao->format);
if (spa_format == SPA_AUDIO_FORMAT_UNKNOWN) {
ao->format = AF_FORMAT_FLOATP;
spa_format = SPA_AUDIO_FORMAT_F32P;
}
struct spa_audio_info_raw audio_info = {
.format = spa_format,
.rate = ao->samplerate,
.channels = ao->channels.num,
};
for (int i = 0; i < ao->channels.num; i++)
audio_info.position[i] = mp_speaker_id_to_spa(ao, ao->channels.speaker[i]);
params[0] = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &audio_info);
if (!params[0])
goto error;
if (af_fmt_is_planar(ao->format)) {
ao->num_planes = ao->channels.num;
ao->sstride = af_fmt_to_bytes(ao->format);
} else {
ao->num_planes = 1;
ao->sstride = ao->channels.num * af_fmt_to_bytes(ao->format);
}
pw_thread_loop_lock(p->loop);
p->stream = pw_stream_new(
p->core,
"audio-src",
props);
if (p->stream == NULL) {
pw_thread_loop_unlock(p->loop);
goto error;
}
pw_stream_add_listener(p->stream,
&p->stream_listener,
&stream_events, ao);
if (pw_stream_connect(p->stream,
PW_DIRECTION_OUTPUT, PW_ID_ANY,
PW_STREAM_FLAG_AUTOCONNECT |
PW_STREAM_FLAG_INACTIVE |
PW_STREAM_FLAG_MAP_BUFFERS |
PW_STREAM_FLAG_RT_PROCESS,
params, 1) < 0) {
pw_thread_loop_unlock(p->loop);
goto error;
}
pw_thread_loop_unlock(p->loop);
return 0;
error:
uninit(ao);
return -1;
}
static void reset(struct ao *ao)
{
struct priv *p = ao->priv;
pw_thread_loop_lock(p->loop);
pw_stream_set_active(p->stream, false);
pw_stream_flush(p->stream, false);
pw_thread_loop_unlock(p->loop);
}
static void start(struct ao *ao)
{
struct priv *p = ao->priv;
pw_thread_loop_lock(p->loop);
pw_stream_set_active(p->stream, true);
pw_thread_loop_unlock(p->loop);
}
#define CONTROL_RET(r) (!r ? CONTROL_OK : CONTROL_ERROR)
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
struct priv *p = ao->priv;
switch (cmd) {
case AOCONTROL_GET_VOLUME: {
struct ao_control_vol *vol = arg;
vol->left = spa_volume_to_mp_volume(p->volume[0]);
vol->right = spa_volume_to_mp_volume(p->volume[1]);
return CONTROL_OK;
}
case AOCONTROL_GET_MUTE: {
bool *muted = arg;
*muted = p->muted;
return CONTROL_OK;
}
case AOCONTROL_SET_VOLUME:
case AOCONTROL_SET_MUTE:
case AOCONTROL_UPDATE_STREAM_TITLE:
case AOCONTROL_UPDATE_MEDIA_ROLE: {
int ret;
pw_thread_loop_lock(p->loop);
switch (cmd) {
case AOCONTROL_SET_VOLUME: {
struct ao_control_vol *vol = arg;
uint8_t n = ao->channels.num;
float values[MP_NUM_CHANNELS] = {0};
if (n == 2) {
values[0] = mp_volume_to_spa_volume(vol->left);
values[1] = mp_volume_to_spa_volume(vol->right);
} else {
for (int i = 0; i < n; i++)
values[i] = mp_volume_to_spa_volume(vol->left);
}
ret = CONTROL_RET(pw_stream_set_control(p->stream, SPA_PROP_channelVolumes, n, values, 0));
break;
}
case AOCONTROL_SET_MUTE: {
bool *muted = arg;
float value = *muted ? 1.f : 0.f;
ret = CONTROL_RET(pw_stream_set_control(p->stream, SPA_PROP_mute, 1, &value, 0));
break;
}
case AOCONTROL_UPDATE_STREAM_TITLE: {
char *title = arg;
struct spa_dict_item items[1];
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_NAME, title);
ret = CONTROL_RET(pw_stream_update_properties(p->stream, &SPA_DICT_INIT(items, MP_ARRAY_SIZE(items))));
break;
}
case AOCONTROL_UPDATE_MEDIA_ROLE: {
enum aocontrol_media_role *role = arg;
struct spa_dict_item items[1];
const char *role_str;
switch (*role) {
case AOCONTROL_MEDIA_ROLE_MOVIE:
role_str = "Movie";
break;
case AOCONTROL_MEDIA_ROLE_MUSIC:
role_str = "Music";
break;
default:
MP_WARN(ao, "Unknown media role %d\n", *role);
role_str = "";
break;
}
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_MEDIA_ROLE, role_str);
ret = CONTROL_RET(pw_stream_update_properties(p->stream, &SPA_DICT_INIT(items, MP_ARRAY_SIZE(items))));
break;
}
default:
ret = CONTROL_NA;
}
pw_thread_loop_unlock(p->loop);
return ret;
}
default:
return CONTROL_UNKNOWN;
}
}
static void add_device_to_list(struct ao *ao, uint32_t id, const struct spa_dict *props, void *ctx)
{
struct ao_device_list *list = ctx;
const char *name = spa_dict_lookup(props, PW_KEY_NODE_NAME);
if (!name)
return;
const char *description = spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION);
ao_device_list_add(list, ao, &(struct ao_device_desc){name, description});
}
static void hotplug_registry_global_cb(void *data, uint32_t id,
uint32_t permissions, const char *type,
uint32_t version, const struct spa_dict *props)
{
struct ao *ao = data;
struct priv *priv = ao->priv;
if (!is_sink_node(type, props))
return;
pw_thread_loop_lock(priv->loop);
struct id_list *item = talloc_size(ao, sizeof(*item));
item->id = id;
spa_list_init(&item->node);
spa_list_append(&priv->hotplug.sinks, &item->node);
pw_thread_loop_unlock(priv->loop);
ao_hotplug_event(ao);
}
static void hotplug_registry_global_remove_cb(void *data, uint32_t id)
{
struct ao *ao = data;
struct priv *priv = ao->priv;
bool removed_sink = false;
struct id_list *e;
pw_thread_loop_lock(priv->loop);
spa_list_for_each(e, &priv->hotplug.sinks, node) {
if (e->id == id) {
removed_sink = true;
spa_list_remove(&e->node);
talloc_free(e);
goto done;
}
}
done:
pw_thread_loop_unlock(priv->loop);
if (removed_sink)
ao_hotplug_event(ao);
}
static const struct pw_registry_events hotplug_registry_events = {
.version = PW_VERSION_REGISTRY_EVENTS,
.global = hotplug_registry_global_cb,
.global_remove = hotplug_registry_global_remove_cb,
};
static int hotplug_init(struct ao *ao)
{
struct priv *priv = ao->priv;
int res = pipewire_init_boilerplate(ao);
if (res)
return res;
pw_thread_loop_lock(priv->loop);
spa_memzero(&priv->hotplug, sizeof(priv->hotplug));
spa_list_init(&priv->hotplug.sinks);
priv->hotplug.registry = pw_core_get_registry(priv->core, PW_VERSION_REGISTRY, 0);
if (!priv->hotplug.registry) {
goto error;
}
if (pw_registry_add_listener(priv->hotplug.registry, &priv->hotplug.registry_listener, &hotplug_registry_events, ao) < 0) {
pw_proxy_destroy((struct pw_proxy *)priv->hotplug.registry);
goto error;
}
pw_thread_loop_unlock(priv->loop);
return res;
error:
pw_thread_loop_unlock(priv->loop);
uninit(ao);
return -1;
}
static void hotplug_uninit(struct ao *ao)
{
struct priv *priv = ao->priv;
pw_thread_loop_lock(priv->loop);
spa_hook_remove(&priv->hotplug.registry_listener);
pw_proxy_destroy((struct pw_proxy *)priv->hotplug.registry);
pw_thread_loop_unlock(priv->loop);
uninit(ao);
}
static void list_devs(struct ao *ao, struct ao_device_list *list)
{
ao_device_list_add(list, ao, &(struct ao_device_desc){});
if (for_each_sink(ao, add_device_to_list, list) < 0)
MP_WARN(ao, "Could not list devices, list may be incomplete\n");
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_pipewire = {
.description = "PipeWire audio output",
.name = "pipewire",
.init = init,
.uninit = uninit,
.reset = reset,
.start = start,
.control = control,
.hotplug_init = hotplug_init,
.hotplug_uninit = hotplug_uninit,
.list_devs = list_devs,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv)
{
.loop = NULL,
.stream = NULL,
.options.buffer_msec = 20,
},
.options_prefix = "pipewire",
.options = (const struct m_option[]) {
{"buffer", OPT_INT(options.buffer_msec), M_RANGE(1, 2000)},
{"remote", OPT_STRING(options.remote) },
{0}
},
};
+318
View File
@@ -0,0 +1,318 @@
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
* Copyright (c) 2013 Christian Neukirchen <chneukirchen@gmail.com>
* Copyright (c) 2020 Rozhuk Ivan <rozhuk.im@gmail.com>
* Copyright (c) 2021 Andrew Krasavin <noiseless-ak@yandex.ru>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <sys/types.h>
#include <poll.h>
#include <errno.h>
#include <sndio.h>
#include "options/m_option.h"
#include "common/msg.h"
#include "audio/format.h"
#include "ao.h"
#include "internal.h"
struct priv {
struct sio_hdl *hdl;
struct sio_par par;
int delay;
bool playing;
int vol;
int havevol;
struct pollfd *pfd;
};
static const struct mp_chmap sndio_layouts[] = {
{0}, /* empty */
{1, {MP_SPEAKER_ID_FL}}, /* mono */
MP_CHMAP2(FL, FR), /* stereo */
{0}, /* 2.1 */
MP_CHMAP4(FL, FR, BL, BR), /* 4.0 */
{0}, /* 5.0 */
MP_CHMAP6(FL, FR, BL, BR, FC, LFE), /* 5.1 */
{0}, /* 6.1 */
MP_CHMAP8(FL, FR, BL, BR, FC, LFE, SL, SR), /* 7.1 */
/* Above is the fixed channel assignment for sndio, since we need to
* fill all channels and cannot insert silence, not all layouts are
* supported.
* NOTE: MP_SPEAKER_ID_NA could be used to add padding channels. */
};
static void uninit(struct ao *ao);
/* Make libsndio call movecb(). */
static void process_events(struct ao *ao)
{
struct priv *p = ao->priv;
int n = sio_pollfd(p->hdl, p->pfd, POLLOUT);
while (poll(p->pfd, n, 0) < 0 && errno == EINTR);
sio_revents(p->hdl, p->pfd);
}
/* Call-back invoked to notify of the hardware position. */
static void movecb(void *addr, int delta)
{
struct ao *ao = addr;
struct priv *p = ao->priv;
p->delay -= delta;
}
/* Call-back invoked to notify about volume changes. */
static void volcb(void *addr, unsigned newvol)
{
struct ao *ao = addr;
struct priv *p = ao->priv;
p->vol = newvol;
}
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
struct mp_chmap_sel sel = {0};
size_t i;
struct af_to_par {
int format, bits, sig;
};
static const struct af_to_par af_to_par[] = {
{AF_FORMAT_U8, 8, 0},
{AF_FORMAT_S16, 16, 1},
{AF_FORMAT_S32, 32, 1},
};
const struct af_to_par *ap;
const char *device = ((ao->device) ? ao->device : SIO_DEVANY);
/* Opening device. */
MP_VERBOSE(ao, "Using '%s' audio device.\n", device);
p->hdl = sio_open(device, SIO_PLAY, 0);
if (p->hdl == NULL) {
MP_ERR(ao, "Can't open audio device %s.\n", device);
goto err_out;
}
sio_initpar(&p->par);
/* Selecting sound format. */
ao->format = af_fmt_from_planar(ao->format);
p->par.bits = 16;
p->par.sig = 1;
p->par.le = SIO_LE_NATIVE;
for (i = 0; i < MP_ARRAY_SIZE(af_to_par); i++) {
ap = &af_to_par[i];
if (ap->format == ao->format) {
p->par.bits = ap->bits;
p->par.sig = ap->sig;
break;
}
}
p->par.rate = ao->samplerate;
/* Channels count. */
for (i = 0; i < MP_ARRAY_SIZE(sndio_layouts); i++) {
mp_chmap_sel_add_map(&sel, &sndio_layouts[i]);
}
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
goto err_out;
p->par.pchan = ao->channels.num;
p->par.appbufsz = p->par.rate * 250 / 1000; /* 250ms buffer */
p->par.round = p->par.rate * 10 / 1000; /* 10ms block size */
if (!sio_setpar(p->hdl, &p->par)) {
MP_ERR(ao, "couldn't set params\n");
goto err_out;
}
/* Get current sound params. */
if (!sio_getpar(p->hdl, &p->par)) {
MP_ERR(ao, "couldn't get params\n");
goto err_out;
}
if (p->par.bps > 1 && p->par.le != SIO_LE_NATIVE) {
MP_ERR(ao, "swapped endian output not supported\n");
goto err_out;
}
/* Update sound params. */
if (p->par.bits == 8 && p->par.bps == 1 && !p->par.sig) {
ao->format = AF_FORMAT_U8;
} else if (p->par.bits == 16 && p->par.bps == 2 && p->par.sig) {
ao->format = AF_FORMAT_S16;
} else if ((p->par.bits == 32 || p->par.msb) && p->par.bps == 4 && p->par.sig) {
ao->format = AF_FORMAT_S32;
} else {
MP_ERR(ao, "couldn't set format\n");
goto err_out;
}
p->havevol = sio_onvol(p->hdl, volcb, ao);
sio_onmove(p->hdl, movecb, ao);
p->pfd = talloc_array_ptrtype(p, p->pfd, sio_nfds(p->hdl));
if (!p->pfd)
goto err_out;
ao->device_buffer = p->par.bufsz;
MP_VERBOSE(ao, "bufsz = %i, appbufsz = %i, round = %i\n",
p->par.bufsz, p->par.appbufsz, p->par.round);
p->delay = 0;
p->playing = false;
if (!sio_start(p->hdl)) {
MP_ERR(ao, "start: sio_start() fail.\n");
goto err_out;
}
return 0;
err_out:
uninit(ao);
return -1;
}
static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->hdl) {
sio_close(p->hdl);
p->hdl = NULL;
}
p->pfd = NULL;
p->playing = false;
}
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
struct priv *p = ao->priv;
ao_control_vol_t *vol = arg;
switch (cmd) {
case AOCONTROL_GET_VOLUME:
if (!p->havevol)
return CONTROL_FALSE;
vol->left = vol->right = p->vol * 100 / SIO_MAXVOL;
break;
case AOCONTROL_SET_VOLUME:
if (!p->havevol)
return CONTROL_FALSE;
sio_setvol(p->hdl, vol->left * SIO_MAXVOL / 100);
break;
default:
return CONTROL_UNKNOWN;
}
return CONTROL_OK;
}
static void reset(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->playing) {
p->playing = false;
if (!sio_stop(p->hdl)) {
MP_ERR(ao, "reset: couldn't sio_stop()\n");
}
p->delay = 0;
if (!sio_start(p->hdl)) {
MP_ERR(ao, "reset: sio_start() fail.\n");
}
}
}
static void start(struct ao *ao)
{
struct priv *p = ao->priv;
p->playing = true;
process_events(ao);
}
static bool audio_write(struct ao *ao, void **data, int samples)
{
struct priv *p = ao->priv;
const size_t size = (samples * ao->sstride);
size_t rc;
rc = sio_write(p->hdl, data[0], size);
if (rc != size) {
MP_WARN(ao, "audio_write: unexpected partial write: required: %zu, written: %zu.\n",
size, rc);
reset(ao);
p->playing = false;
return false;
}
p->delay += samples;
return true;
}
static void get_state(struct ao *ao, struct mp_pcm_state *state)
{
struct priv *p = ao->priv;
process_events(ao);
/* how many samples we can play without blocking */
state->free_samples = ao->device_buffer - p->delay;
state->free_samples = state->free_samples / p->par.round * p->par.round;
/* how many samples are already in the buffer to be played */
state->queued_samples = p->delay;
/* delay in seconds between first and last sample in buffer */
state->delay = p->delay / (double)p->par.rate;
/* report unexpected EOF / underrun */
if ((state->queued_samples && state->queued_samples &&
(state->queued_samples < state->free_samples) &&
p->playing) || sio_eof(p->hdl))
{
MP_VERBOSE(ao, "get_state: EOF/underrun detected.\n");
MP_VERBOSE(ao, "get_state: free: %d, queued: %d, delay: %lf\n", \
state->free_samples, state->queued_samples, state->delay);
p->playing = false;
state->playing = p->playing;
ao_wakeup_playthread(ao);
} else {
state->playing = p->playing;
}
}
const struct ao_driver audio_out_sndio = {
.name = "sndio",
.description = "sndio audio output",
.init = init,
.uninit = uninit,
.control = control,
.reset = reset,
.start = start,
.write = audio_write,
.get_state = get_state,
.priv_size = sizeof(struct priv),
};
+3 -1
View File
@@ -162,7 +162,8 @@ static int read_buffer(struct ao *ao, void **data, int samples, bool *eof)
// pad with silence (underflow/paused/eof)
for (int n = 0; n < ao->num_planes; n++) {
af_fill_silence((char *)data[n] + pos, (samples - pos) * ao->sstride,
af_fill_silence((char *)data[n] + pos * ao->sstride,
(samples - pos) * ao->sstride,
ao->format);
}
@@ -192,6 +193,7 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us)
if (pos < samples && p->playing && !p->paused) {
p->playing = false;
ao->wakeup_cb(ao->wakeup_ctx);
// For ao_drain().
pthread_cond_broadcast(&p->wakeup);
}
+3 -3
View File
@@ -5,10 +5,10 @@
import os, sys, stat, hashlib, subprocess
from urllib.request import urlopen, URLError
WAFRELEASE = "waf-2.0.20"
WAFRELEASE = "waf-2.0.24"
WAFURLS = ["https://waf.io/" + WAFRELEASE,
"http://www.freehackers.org/~tnagy/release/" + WAFRELEASE]
SHA256HASH = "bf971e98edc2414968a262c6aa6b88541a26c3cd248689c89f4c57370955ee7f"
"https://www.freehackers.org/~tnagy/release/" + WAFRELEASE]
SHA256HASH = "93909bca823a675f9f40af7c65b24887c3a3c0efdf411ff1978ba827194bdeb0"
if os.path.exists("waf"):
wafver = subprocess.check_output([sys.executable, './waf', '--version']).decode()
+22 -1
View File
@@ -5,6 +5,25 @@ export CFLAGS="$CFLAGS -isystem/usr/local/include"
export CXXFLAGS="$CXXFLAGS -isystem/usr/local/include"
export LDFLAGS="$LDFLAGS -L/usr/local/lib"
meson setup build \
-Dlibmpv=true \
-Dlua=enabled \
-Degl-drm=enabled \
-Dopenal=enabled \
-Dsdl2=enabled \
-Dsndio=enabled \
-Dvdpau=enabled \
-Dvulkan=enabled \
-Doss-audio=enabled \
$(pkg info -q v4l_compat && echo -Ddvbin=enabled) \
$(pkg info -q libdvdnav && echo -Ddvdnav=enabled) \
$(pkg info -q libcdio-paranoia && echo -Dcdda=enabled) \
$(pkg info -q pipewire && echo -Dpipewire=enabled) \
$NULL
meson compile -C build
./build/mpv
if [ ! -e "./waf" ] ; then
python3 ./bootstrap.py
fi
@@ -15,12 +34,14 @@ python3 ./waf configure \
--enable-egl-drm \
--enable-openal \
--enable-sdl2 \
--enable-vaapi-wayland \
--enable-sndio \
--enable-vdpau \
--enable-vulkan \
--enable-oss-audio \
$(pkg info -q v4l_compat && echo --enable-dvbin) \
$(pkg info -q libdvdnav && echo --enable-dvdnav) \
$(pkg info -q libcdio-paranoia && echo --enable-cdda) \
$(pkg info -q pipewire && echo --enable-pipewire) \
$NULL
python3 ./waf build
+28 -11
View File
@@ -10,18 +10,35 @@ if [[ -d "./build/${MPV_VARIANT}" ]] ; then
rm -rf "./build/${MPV_VARIANT}"
fi
if [[ ! -e "./waf" ]] ; then
python3 ./bootstrap.py
if [[ $1 = "meson" ]]; then
PKG_CONFIG_PATH="${FFMPEG_SYSROOT}/lib/pkgconfig/" CC="${CC}" CXX="${CXX}" \
meson setup build \
-Dprefix="${MPV_INSTALL_PREFIX}" \
-Dlibmpv=true \
-D{gl,iconv,lcms2,lua,jpeg,plain-gl,zlib}=enabled \
-D{cocoa,coreaudio,gl-cocoa,macos-cocoa-cb,macos-touchbar,videotoolbox-gl}=enabled
meson compile -C build -j4
meson install -C build
./build/mpv
fi
PKG_CONFIG_PATH="${FFMPEG_SYSROOT}/lib/pkgconfig/" CC="${CC}" CXX="${CXX}" python3 \
./waf configure \
--variant="${MPV_VARIANT}" \
--prefix="${MPV_INSTALL_PREFIX}" \
--enable-{gl,iconv,lcms2,libmpv-shared,lua,jpeg,plain-gl,zlib} \
--enable-{cocoa,coreaudio,gl-cocoa,macos-cocoa-cb,macos-touchbar,videotoolbox-gl} \
--swift-flags="${CI_SWIFT_FLAGS}"
if [[ $1 = "waf" ]]; then
if [[ ! -e "./waf" ]] ; then
python3 ./bootstrap.py
fi
python3 ./waf build --variant="${MPV_VARIANT}" -j4
PKG_CONFIG_PATH="${FFMPEG_SYSROOT}/lib/pkgconfig/" CC="${CC}" CXX="${CXX}" python3 \
./waf configure \
--variant="${MPV_VARIANT}" \
--prefix="${MPV_INSTALL_PREFIX}" \
--enable-{gl,iconv,lcms2,libmpv-shared,lua,jpeg,plain-gl,zlib} \
--enable-{cocoa,coreaudio,gl-cocoa,macos-cocoa-cb,macos-touchbar,videotoolbox-gl} \
--swift-flags="${CI_SWIFT_FLAGS}"
python3 ./waf install --variant="${MPV_VARIANT}"
python3 ./waf build --variant="${MPV_VARIANT}" -j4
python3 ./waf install --variant="${MPV_VARIANT}"
./build/mpv
fi
+91 -25
View File
@@ -6,7 +6,7 @@ ln -snf . "$prefix_dir/usr"
ln -snf . "$prefix_dir/local"
wget="wget -nc --progress=bar:force"
gitclone="git clone --depth=10"
gitclone="git clone --depth=10 --recursive"
commonflags="--disable-static --enable-shared"
export PKG_CONFIG_SYSROOT_DIR="$prefix_dir"
@@ -22,6 +22,26 @@ export RANLIB=$TARGET-ranlib
export CFLAGS="-O2 -pipe -Wall -D_FORTIFY_SOURCE=2"
export LDFLAGS="-fstack-protector-strong"
fam=x86_64
[[ "$TARGET" == "i686-"* ]] && fam=x86
cat >"$prefix_dir/crossfile" <<EOF
[built-in options]
buildtype = 'release'
wrap_mode = 'nodownload'
[binaries]
c = '${CC}'
cpp = '${CXX}'
ar = '${AR}'
strip = '${TARGET}-strip'
pkgconfig = 'pkg-config'
windres = '${TARGET}-windres'
[host_machine]
system = 'windows'
cpu_family = '${fam}'
cpu = '${TARGET%%-*}'
endian = 'little'
EOF
function builddir () {
[ -d "$1/builddir" ] && rm -rf "$1/builddir"
mkdir -p "$1/builddir"
@@ -29,8 +49,13 @@ function builddir () {
}
function makeplusinstall () {
make -j$(nproc)
make DESTDIR="$prefix_dir" install
if [ -f build.ninja ]; then
ninja
DESTDIR="$prefix_dir" ninja install
else
make -j$(nproc)
make DESTDIR="$prefix_dir" install
fi
}
function gettar () {
@@ -42,7 +67,7 @@ function gettar () {
## iconv
if [ ! -e "$prefix_dir/lib/libiconv.dll.a" ]; then
ver=1.16
ver=1.17
gettar "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ver}.tar.gz"
builddir libiconv-${ver}
../configure --host=$TARGET $commonflags
@@ -52,9 +77,10 @@ fi
## zlib
if [ ! -e "$prefix_dir/lib/libz.dll.a" ]; then
ver=1.2.11
gettar "https://zlib.net/zlib-${ver}.tar.gz"
ver=1.2.12
gettar "https://zlib.net/fossils/zlib-${ver}.tar.gz"
pushd zlib-${ver}
make -fwin32/Makefile.gcc clean
make -fwin32/Makefile.gcc PREFIX=$TARGET- SHARED_MODE=1 \
DESTDIR="$prefix_dir" install \
BINARY_PATH=/bin INCLUDE_PATH=/include LIBRARY_PATH=/lib
@@ -68,7 +94,7 @@ if [ ! -e "$prefix_dir/lib/libavcodec.dll.a" ]; then
../configure --pkg-config=pkg-config --target-os=mingw32 \
--enable-cross-compile --cross-prefix=$TARGET- --arch=${TARGET%%-*} \
$commonflags \
--disable-{stripping,doc,programs,muxers,encoders,devices}
--disable-{doc,programs,muxers,encoders,devices}
makeplusinstall
popd
fi
@@ -97,37 +123,45 @@ if [ ! -e "$prefix_dir/lib/libspirv-cross-c-shared.dll.a" ]; then
popd
fi
## libplacebo
if [ ! -e "$prefix_dir/lib/libplacebo.dll.a" ]; then
[ -d libplacebo ] || $gitclone https://code.videolan.org/videolan/libplacebo.git
builddir libplacebo
meson .. --cross-file "$prefix_dir/crossfile"
makeplusinstall
popd
fi
## freetype2
if [ ! -e "$prefix_dir/lib/libfreetype.dll.a" ]; then
ver=2.11.0
gettar "https://download.savannah.gnu.org/releases/freetype/freetype-${ver}.tar.gz"
ver=2.12.1
gettar "https://download.savannah.gnu.org/releases/freetype/freetype-${ver}.tar.xz"
builddir freetype-${ver}
ZLIB_LIBS="-L'$prefix_dir/lib' -lz" \
../configure --host=$TARGET $commonflags --with-png=no
meson .. --cross-file "$prefix_dir/crossfile"
makeplusinstall
popd
fi
[ -f "$prefix_dir/lib/libfreetype.dll.a" ] || { echo "libtool fuckup"; exit 1; }
## fribidi
if [ ! -e "$prefix_dir/lib/libfribidi.dll.a" ]; then
ver=1.0.11
ver=1.0.12
gettar "https://github.com/fribidi/fribidi/releases/download/v${ver}/fribidi-${ver}.tar.xz"
builddir fribidi-${ver}
../configure --host=$TARGET $commonflags
meson .. --cross-file "$prefix_dir/crossfile" \
-D{tests,docs}=false
makeplusinstall
popd
fi
## harfbuzz
if [ ! -e "$prefix_dir/lib/libharfbuzz.dll.a" ]; then
ver=3.0.0
ver=5.3.0
gettar "https://github.com/harfbuzz/harfbuzz/releases/download/${ver}/harfbuzz-${ver}.tar.xz"
builddir harfbuzz-${ver}
../configure --host=$TARGET $commonflags --with-icu=no
meson .. --cross-file "$prefix_dir/crossfile" \
-Dtests=disabled
makeplusinstall
popd
rm "$prefix_dir"/lib/*.la # fuck off
fi
## libass
@@ -142,21 +176,53 @@ fi
## luajit
if [ ! -e "$prefix_dir/lib/libluajit-5.1.a" ]; then
ver=2.0.5
ver=2.1.0-beta3
gettar "http://luajit.org/download/LuaJIT-${ver}.tar.gz"
pushd LuaJIT-${ver}
hostcc=gcc
hostcc=cc
[[ "$TARGET" == "i686-"* ]] && hostcc="$hostcc -m32"
make HOST_CC="$hostcc" CROSS=$TARGET- TARGET_SYS=Windows \
make TARGET_SYS=Windows clean
make TARGET_SYS=Windows HOST_CC="$hostcc" CROSS=$TARGET- \
BUILDMODE=static amalg
make DESTDIR="$prefix_dir" INSTALL_DEP= FILE_T=luajit.exe install
popd
fi
## mpv
PKG_CONFIG=pkg-config CFLAGS="-I'$prefix_dir/include'" LDFLAGS="-L'$prefix_dir/lib'" \
python3 ./waf configure \
--enable-libmpv-shared --lua=luajit \
--enable-{shaderc,spirv-cross,d3d11}
python3 ./waf build --verbose
[ -z "$1" ] && exit 0
CFLAGS+=" -I'$prefix_dir/include'"
LDFLAGS+=" -L'$prefix_dir/lib'"
export CFLAGS LDFLAGS
rm -rf build
if [ "$1" = "meson" ]; then
meson setup build --cross-file "$prefix_dir/crossfile" \
--buildtype debugoptimized \
-D{libmpv,tests}=true -Dlua=luajit \
-D{shaderc,spirv-cross,d3d11,libplacebo}=enabled
ninja -C build --verbose
elif [ "$1" = "waf" ]; then
PKG_CONFIG=pkg-config ./waf configure \
--enable-libmpv-shared --lua=luajit \
--enable-{shaderc,spirv-cross,d3d11,libplacebo,tests}
./waf build --verbose
fi
if [ "$2" = pack ]; then
mkdir -p artifact
echo "Copying:"
cp -pv build/mpv.{com,exe} "$prefix_dir/bin/"*.dll artifact/
# ship everything and the kitchen sink
shopt -s nullglob
for file in /usr/lib/gcc/$TARGET/*-posix/*.dll /usr/$TARGET/lib/*.dll; do
cp -pv "$file" artifact/
done
echo "Archiving:"
pushd artifact
zip -9r "../mpv-git-$(date +%F)-$(git rev-parse --short HEAD)-${TARGET%%-*}.zip" -- *
popd
fi
+31 -10
View File
@@ -1,13 +1,34 @@
#!/bin/sh
set -e
python3 ./waf configure \
--enable-cdda \
--enable-dvbin \
--enable-dvdnav \
--enable-libarchive \
--enable-libmpv-shared \
--enable-manpage-build \
--enable-shaderc \
--enable-vulkan
python3 ./waf build --verbose
if [ "$1" = "meson" ]; then
meson setup build \
-Dcdda=enabled \
-Ddvbin=enabled \
-Ddvdnav=enabled \
-Dlibarchive=enabled \
-Dlibmpv=true \
-Dmanpage-build=enabled \
-Dpipewire=enabled \
-Dshaderc=enabled \
-Dtests=true \
-Dvulkan=enabled
meson compile -C build --verbose
./build/mpv --no-config -v --unittest=all-simple
fi
if [ "$1" = "waf" ]; then
python3 ./waf configure \
--enable-cdda \
--enable-dvbin \
--enable-dvdnav \
--enable-libarchive \
--enable-libmpv-shared \
--enable-manpage-build \
--enable-pipewire \
--enable-shaderc \
--enable-tests \
--enable-vulkan
python3 ./waf build --verbose
./build/mpv -v --no-config -v --unittest=all-simple
fi
+6
View File
@@ -30,6 +30,7 @@
#include "config.h"
#include "audio/chmap_avchannel.h"
#include "common/common.h"
#include "common/msg.h"
#include "demux/packet.h"
@@ -108,9 +109,14 @@ AVCodecParameters *mp_codec_params_to_av(struct mp_codec_params *c)
avp->sample_rate = c->samplerate;
avp->bit_rate = c->bitrate;
avp->block_align = c->block_align;
#if !HAVE_AV_CHANNEL_LAYOUT
avp->channels = c->channels.num;
if (!mp_chmap_is_unknown(&c->channels))
avp->channel_layout = mp_chmap_to_lavc(&c->channels);
#else
mp_chmap_to_av_layout(&avp->ch_layout, &c->channels);
#endif
return avp;
error:
+6
View File
@@ -32,12 +32,18 @@
#include <libavutil/avutil.h>
#include <libavutil/log.h>
#include <libavutil/version.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/version.h>
#include <libavformat/avformat.h>
#include <libavformat/version.h>
#include <libswresample/swresample.h>
#include <libswresample/version.h>
#include <libswscale/swscale.h>
#include <libswscale/version.h>
#include <libavfilter/avfilter.h>
#include <libavfilter/version.h>
#if HAVE_LIBAVDEVICE
#include <libavdevice/avdevice.h>
+18
View File
@@ -68,6 +68,24 @@ enum stream_type {
STREAM_TYPE_COUNT,
};
enum video_sync {
VS_DEFAULT = 0,
VS_DISP_RESAMPLE,
VS_DISP_RESAMPLE_VDROP,
VS_DISP_RESAMPLE_NONE,
VS_DISP_ADROP,
VS_DISP_VDROP,
VS_DISP_NONE,
VS_NONE,
};
#define VS_IS_DISP(x) ((x) == VS_DISP_RESAMPLE || \
(x) == VS_DISP_RESAMPLE_VDROP || \
(x) == VS_DISP_RESAMPLE_NONE || \
(x) == VS_DISP_ADROP || \
(x) == VS_DISP_VDROP || \
(x) == VS_DISP_NONE)
extern const char mpv_version[];
extern const char mpv_builddate[];
extern const char mpv_copyright[];
+7 -5
View File
@@ -731,6 +731,7 @@ static void encoder_destroy(void *ptr)
{
struct encoder_context *p = ptr;
av_packet_free(&p->pkt);
avcodec_free_context(&p->encoder);
free_stream(p->twopass_bytebuffer);
}
@@ -910,6 +911,9 @@ bool encoder_init_codec_and_muxer(struct encoder_context *p,
if (avcodec_parameters_from_context(p->info.codecpar, p->encoder) < 0)
goto fail;
p->pkt = av_packet_alloc();
MP_HANDLE_OOM(p->pkt);
encode_lavc_add_stream(p, p->encode_lavc_ctx, &p->info, on_ready, ctx);
if (!p->mux_stream)
goto fail;
@@ -930,11 +934,9 @@ bool encoder_encode(struct encoder_context *p, AVFrame *frame)
goto fail;
}
AVPacket *packet = p->pkt;
for (;;) {
AVPacket packet = {0};
av_init_packet(&packet);
status = avcodec_receive_packet(p->encoder, &packet);
status = avcodec_receive_packet(p->encoder, packet);
if (status == AVERROR(EAGAIN))
break;
if (status < 0 && status != AVERROR_EOF)
@@ -948,7 +950,7 @@ bool encoder_encode(struct encoder_context *p, AVFrame *frame)
if (status == AVERROR_EOF)
break;
encode_lavc_add_packet(p->mux_stream, &packet);
encode_lavc_add_packet(p->mux_stream, packet);
}
return true;
+2
View File
@@ -83,7 +83,9 @@ struct encoder_context {
AVCodecContext *encoder;
struct mux_stream *mux_stream;
// (essentially private)
struct stream *twopass_bytebuffer;
AVPacket *pkt;
};
// Free with talloc_free(). (Keep in mind actual deinitialization requires
+2 -1
View File
@@ -21,6 +21,7 @@
#include "common/common.h"
#include "common/global.h"
#include "common/msg.h"
#include "misc/random.h"
#include "mpv_talloc.h"
#include "options/path.h"
@@ -147,7 +148,7 @@ void playlist_shuffle(struct playlist *pl)
for (int n = 0; n < pl->num_entries; n++)
pl->entries[n]->original_index = n;
for (int n = 0; n < pl->num_entries - 1; n++) {
int j = (int)((double)(pl->num_entries - n) * rand() / (RAND_MAX + 1.0));
size_t j = (size_t)((pl->num_entries - n) * mp_rand_next_double());
MPSWAP(struct playlist_entry *, pl->entries[n], pl->entries[n + j]);
}
playlist_update_indexes(pl, 0, -1);
+2 -1
View File
@@ -69,7 +69,8 @@ struct stat_entry {
// Overflows only after I'm dead.
static int64_t get_thread_cpu_time_ns(pthread_t thread)
{
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME)
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) && \
!HAVE_WIN32_INTERNAL_PTHREADS
clockid_t id;
struct timespec tv;
if (pthread_getcpuclockid(thread, &id) == 0 &&
+78 -8
View File
@@ -44,15 +44,69 @@ static const char *lookup_tag(int type, uint32_t tag)
return id == AV_CODEC_ID_NONE ? NULL : mp_codec_from_av_codec_id(id);
}
// Corresponds to WMMEDIASUBTYPE_Base.
static const unsigned char guid_ext_base[16] =
/*
* As seen in the following page:
*
* https://web.archive.org/web/20220406060153/
* http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
*
* Note that the GUID struct in the above citation has its
* integers encoded in little-endian format, which means that
* the unsigned short and unsigned long entries need to be
* byte-flipped for this encoding.
*
* In theory only the first element of this array should be used,
* however some encoders incorrectly encoded the GUID byte-for-byte
* and thus the second one exists as a fallback.
*/
static const unsigned char guid_ext_base[][16] = {
// MEDIASUBTYPE_BASE_GUID
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71};
0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71},
// SUBTYPE_AMBISONIC_B_FORMAT_PCM
{0x01, 0x00, 0x00, 0x00, 0x21, 0x07, 0xD3, 0x11,
0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00}
};
struct mp_waveformatex_guid {
const char *codec;
const unsigned char guid[16];
};
static const struct mp_waveformatex_guid guid_ext_other[] = {
{"ac3",
{0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11,
0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA}},
{"adpcm_agm",
{0x82, 0xEC, 0x1F, 0x6A, 0xCA, 0xDB, 0x19, 0x45,
0xBD, 0xE7, 0x56, 0xD3, 0xB3, 0xEF, 0x98, 0x1D}},
{"atrac3p",
{0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44,
0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62}},
{"atrac9",
{0xD2, 0x42, 0xE1, 0x47, 0xBA, 0x36, 0x8D, 0x4D,
0x88, 0xFC, 0x61, 0x65, 0x4F, 0x8C, 0x83, 0x6C}},
{"dfpwm",
{0x3A, 0xC1, 0xFA, 0x38, 0x81, 0x1D, 0x43, 0x61,
0xA4, 0x0D, 0xCE, 0x53, 0xCA, 0x60, 0x7C, 0xD1}},
{"eac3",
{0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42,
0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD}},
{"mp2",
{0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11,
0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA}}
};
static void map_audio_pcm_tag(struct mp_codec_params *c)
{
// MS PCM, Extended
if (c->codec_tag == 0xfffe && c->extradata_size >= 22) {
// WAVEFORMATEXTENSIBLE.wBitsPerSample
int bits_per_sample = AV_RL16(c->extradata);
if (bits_per_sample)
c->bits_per_coded_sample = bits_per_sample;
// WAVEFORMATEXTENSIBLE.dwChannelMask
uint64_t chmask = AV_RL32(c->extradata + 2);
struct mp_chmap chmap;
@@ -62,9 +116,23 @@ static void map_audio_pcm_tag(struct mp_codec_params *c)
// WAVEFORMATEXTENSIBLE.SubFormat
unsigned char *subformat = c->extradata + 6;
if (memcmp(subformat + 4, guid_ext_base + 4, 12) == 0) {
c->codec_tag = AV_RL32(subformat);
c->codec = lookup_tag(c->type, c->codec_tag);
for (int i = 0; i < MP_ARRAY_SIZE(guid_ext_base); i++) {
if (memcmp(subformat + 4, guid_ext_base[i] + 4, 12) == 0) {
c->codec_tag = AV_RL32(subformat);
c->codec = lookup_tag(c->type, c->codec_tag);
break;
}
}
// extra subformat, not a base one
if (c->codec_tag == 0xfffe) {
for (int i = 0; i < MP_ARRAY_SIZE(guid_ext_other); i++) {
if (memcmp(subformat, &guid_ext_other[i].guid, 16) == 0) {
c->codec = guid_ext_other[i].codec;
c->codec_tag = mp_codec_to_av_codec_id(c->codec);
break;
}
}
}
// Compressed formats might use this.
@@ -73,6 +141,9 @@ static void map_audio_pcm_tag(struct mp_codec_params *c)
}
int bits = c->bits_per_coded_sample;
if (!bits)
return;
int bytes = (bits + 7) / 8;
switch (c->codec_tag) {
case 0x0: // Microsoft PCM
@@ -89,8 +160,7 @@ static void map_audio_pcm_tag(struct mp_codec_params *c)
void mp_set_codec_from_tag(struct mp_codec_params *c)
{
c->codec = lookup_tag(c->type, c->codec_tag);
if (c->type == STREAM_AUDIO && c->bits_per_coded_sample)
if (c->type == STREAM_AUDIO)
map_audio_pcm_tag(c);
}
+18 -3
View File
@@ -1506,7 +1506,7 @@ static void find_backward_restart_pos(struct demux_stream *ds)
// Or if preroll is involved, the first preroll packet.
while (ds->reader_head != target) {
if (!advance_reader_head(ds))
assert(0); // target must be in list
MP_ASSERT_UNREACHABLE(); // target must be in list
}
double seek_pts;
@@ -1685,7 +1685,7 @@ static void attempt_range_joining(struct demux_internal *in)
// Try to find a join point, where packets obviously overlap. (It would be
// better and faster to do this incrementally, but probably too complex.)
// The current range can overlap arbitrarily with the next one, not only by
// by the seek overlap, but for arbitrary packet readahead as well.
// the seek overlap, but for arbitrary packet readahead as well.
// We also drop the overlapping packets (if joining fails, we discard the
// entire next range anyway, so this does no harm).
for (int n = 0; n < in->num_streams; n++) {
@@ -2942,6 +2942,19 @@ static struct replaygain_data *decode_rgain(struct mp_log *log,
return talloc_dup(NULL, &rg);
}
// The r128 replaygain tags declared in RFC 7845 for opus files. The tags
// are generated with EBU-R128, which does not use peak meters. And the
// values are stored as a Q7.8 fixed point number in dB.
if (decode_gain(log, tags, "R128_TRACK_GAIN", &rg.track_gain) >= 0) {
if (decode_gain(log, tags, "R128_ALBUM_GAIN", &rg.album_gain) < 0) {
// Album gain is undefined; fall back to track gain.
rg.album_gain = rg.track_gain;
}
rg.track_gain /= 256.;
rg.album_gain /= 256.;
return talloc_dup(NULL, &rg);
}
return NULL;
}
@@ -3392,8 +3405,10 @@ static struct demuxer *demux_open(struct stream *stream,
check_levels = d_force;
}
for (int n = 0; demuxer_list[n]; n++) {
if (strcmp(demuxer_list[n]->name, force_format) == 0)
if (strcmp(demuxer_list[n]->name, force_format) == 0) {
check_desc = demuxer_list[n];
break;
}
}
if (!check_desc) {
mp_err(log, "Demuxer %s does not exist.\n", force_format);
+40 -11
View File
@@ -36,6 +36,12 @@
#include <libavutil/display.h>
#include <libavutil/opt.h>
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 43, 100)
#include <libavutil/dovi_meta.h>
#endif
#include "audio/chmap_avchannel.h"
#include "common/msg.h"
#include "common/tags.h"
#include "common/av_common.h"
@@ -257,9 +263,6 @@ 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++) {
@@ -270,7 +273,6 @@ static void update_read_stats(struct demuxer *demuxer)
nest->last_bytes = cur;
demux_report_unbuffered_read_bytes(demuxer, new);
}
#endif
}
// At least mp4 has name="mov,mp4,m4a,3gp,3g2,mj2", so we split the name
@@ -645,6 +647,18 @@ static int dict_get_decimal(AVDictionary *dict, const char *entry, int def)
return def;
}
static bool is_image(AVStream *st, bool attached_picture, const AVInputFormat *avif)
{
return st->nb_frames <= 1 && (
attached_picture ||
bstr_endswith0(bstr0(avif->name), "_pipe") ||
strcmp(avif->name, "alias_pix") == 0 ||
strcmp(avif->name, "gif") == 0 ||
strcmp(avif->name, "image2pipe") == 0 ||
(st->codecpar->codec_id == AV_CODEC_ID_AV1 && st->nb_frames == 1)
);
}
static void handle_new_stream(demuxer_t *demuxer, int i)
{
lavf_priv_t *priv = demuxer->priv;
@@ -658,10 +672,22 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
case AVMEDIA_TYPE_AUDIO: {
sh = demux_alloc_sh_stream(STREAM_AUDIO);
#if !HAVE_AV_CHANNEL_LAYOUT
// probably unneeded
mp_chmap_set_unknown(&sh->codec->channels, codec->channels);
if (codec->channel_layout)
mp_chmap_from_lavc(&sh->codec->channels, codec->channel_layout);
#else
if (!mp_chmap_from_av_layout(&sh->codec->channels, &codec->ch_layout)) {
char layout[128] = {0};
MP_WARN(demuxer,
"Failed to convert channel layout %s to mpv one!\n",
av_channel_layout_describe(&codec->ch_layout,
layout, 128) < 0 ?
"undefined" : layout);
}
#endif
sh->codec->samplerate = codec->sample_rate;
sh->codec->bitrate = codec->bit_rate;
@@ -704,13 +730,7 @@ 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 (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
)) {
if (is_image(st, sh->attached_picture, priv->avif)) {
MP_VERBOSE(demuxer, "Assuming this is an image format.\n");
sh->image = true;
sh->codec->fps = priv->mf_fps;
@@ -725,6 +745,15 @@ static void handle_new_stream(demuxer_t *demuxer, int i)
sh->codec->rotate = (((int)(-r) % 360) + 360) % 360;
}
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 43, 100)
if ((sd = av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL))) {
const AVDOVIDecoderConfigurationRecord *cfg = (void *) sd;
MP_VERBOSE(demuxer, "Found Dolby Vision config record: profile "
"%d level %d\n", cfg->dv_profile, cfg->dv_level);
av_format_inject_global_side_data(avfc);
}
#endif
// This also applies to vfw-muxed mkv, but we can't detect these easily.
sh->codec->avi_dts = matches_avinputformat_name(priv, "avi");
+3
View File
@@ -291,6 +291,8 @@ static const struct {
{ "db", "mjpeg" },
{ "pcd", "photocd" },
{ "pfm", "pfm" },
{ "phm", "phm" },
{ "hdr", "hdr" },
{ "pcx", "pcx" },
{ "png", "png" },
{ "pns", "png" },
@@ -319,6 +321,7 @@ static const struct {
{ "pix", "brender_pix" },
{ "exr", "exr" },
{ "pic", "pictor" },
{ "qoi", "qoi" },
{ "xface", "xface" },
{ "xwd", "xwd" },
{0}
+3 -1
View File
@@ -1362,6 +1362,8 @@ static const char *const mkv_video_tags[][2] = {
{"V_SNOW", "snow"},
{"V_AV1", "av1"},
{"V_PNG", "png"},
{"V_AVS2", "avs2"},
{"V_AVS3", "avs3"},
{0}
};
@@ -2872,7 +2874,7 @@ static int read_next_block_into_queue(demuxer_t *demuxer)
if (mkv_d->cluster_end != EBML_UINT_INVALID)
mkv_d->cluster_end += stream_tell(s);
}
assert(0); // unreachable
MP_ASSERT_UNREACHABLE();
add_block:
index_block(demuxer, &block);
+1 -1
View File
@@ -224,7 +224,7 @@ int ebml_resync_cluster(struct mp_log *log, stream_t *s)
#define E_S(str, count) EVALARGS(E_SN, str, count, N)
#define FN(id, name, multiple, N) { id, multiple, offsetof(struct ebml_ ## N, name), offsetof(struct ebml_ ## N, n_ ## name), &ebml_##name##_desc},
#define F(id, name, multiple) EVALARGS(FN, id, name, multiple, N)
#include "generated/ebml_defs.c"
#include "generated/ebml_defs.inc"
#undef EVALARGS
#undef SN
#undef S
+5 -7
View File
@@ -39,9 +39,7 @@ void demux_packet_unref_contents(struct demux_packet *dp)
{
if (dp->avpacket) {
assert(!dp->is_cached);
av_packet_unref(dp->avpacket);
talloc_free(dp->avpacket);
dp->avpacket = NULL;
av_packet_free(&dp->avpacket);
dp->buffer = NULL;
dp->len = 0;
}
@@ -70,11 +68,12 @@ struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
.start = MP_NOPTS_VALUE,
.end = MP_NOPTS_VALUE,
.stream = -1,
.avpacket = talloc_zero(dp, AVPacket),
.avpacket = av_packet_alloc(),
};
av_init_packet(dp->avpacket);
int r = -1;
if (avpkt->data) {
if (!dp->avpacket) {
// error
} else if (avpkt->data) {
// We hope that this function won't need/access AVPacket input padding,
// because otherwise new_demux_packet_from() wouldn't work.
r = av_packet_ref(dp->avpacket, avpkt);
@@ -82,7 +81,6 @@ struct demux_packet *new_demux_packet_from_avpacket(struct AVPacket *avpkt)
r = av_new_packet(dp->avpacket, avpkt->size);
}
if (r < 0) {
*dp->avpacket = (AVPacket){0};
talloc_free(dp);
return NULL;
}
+7 -1
View File
@@ -5,14 +5,18 @@ Name[ca]=Reproductor multimèdia mpv
Name[cs]=mpv přehrávač
Name[da]=mpv-medieafspiller
Name[fr]=Lecteur multimédia mpv
Name[ja]=mpv メディアプレイヤー
Name[pl]=Odtwarzacz mpv
Name[ru]=Проигрыватель mpv
Name[tr]=mpv Ortam Oynatıcı
Name[zh_CN]=mpv 媒体播放器
Name[zh_TW]=mpv 媒體播放器
GenericName=Multimedia player
GenericName[cs]=Multimediální přehrávač
GenericName[da]=Multimedieafspiller
GenericName[fr]=Lecteur multimédia
GenericName[ja]=マルチメディアプレイヤー
GenericName[tr]=Çoklu ortam oynatıcı
GenericName[zh_CN]=多媒体播放器
GenericName[zh_TW]=多媒體播放器
Comment=Play movies and songs
@@ -22,9 +26,11 @@ Comment[da]=Afspil film og sange
Comment[de]=Filme und Musik abspielen
Comment[es]=Reproduzca vídeos y canciones
Comment[fr]=Lire des vidéos et des musiques
Comment[ja]=映画や音楽を再生する
Comment[it]=Lettore multimediale
Comment[pl]=Odtwarzaj filmy i muzykę
Comment[ru]=Воспроизвести фильмы и музыку
Comment[tr]=Filmleri ve şarkıları oynatın
Comment[zh_CN]=播放电影和歌曲
Comment[zh_TW]=播放電影和歌曲
Icon=mpv
@@ -33,5 +39,5 @@ Exec=mpv --player-operation-mode=pseudo-gui -- %U
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
X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb,srt,rist
StartupWMClass=mpv
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>io.mpv.mpv</id>
<name>mpv</name>
<summary>A free, open source, and cross-platform media player</summary>
<description>
<p>mpv is a free (as in freedom) media player for the command line. It supports a wide variety of media file formats, audio and video codecs, and subtitle types.</p>
<p>mpv has an OpenGL, Vulkan, and D3D11 based video output that is capable of many features loved by videophiles, such as video scaling with popular high quality algorithms, color management, frame timing, interpolation, HDR, and more.</p>
<p>While mpv strives for minimalism and provides no real GUI, it has a small controller on top of the video for basic control.</p>
<p>mpv can leverage most hardware decoding APIs on all platforms. Hardware decoding can be enabled at runtime on demand.</p>
<p>Powerful scripting capabilities can make the player do almost anything. There is a large selection of user scripts on the wiki.</p>
<p>A straightforward C API was designed from the ground up to make mpv usable as a library and facilitate easy integration into other applications.</p>
</description>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0-or-later AND LGPL-2.0-or-later</project_license>
<developer_name>mpv.io</developer_name>
<launchable type="desktop-id">mpv.desktop</launchable>
<content_rating type="oars-1.1" />
<screenshots>
<screenshot type="default">
<image>https://mpv.io/images/mpv-screenshot-34cd36ae.jpg</image>
<caption>Main window</caption>
</screenshot>
</screenshots>
<url type="homepage">https://mpv.io/</url>
<url type="bugtracker">https://github.com/mpv-player/mpv/issues</url>
<url type="faq">https://github.com/mpv-player/mpv/wiki/FAQ</url>
<url type="help">https://mpv.io/manual/stable</url>
</component>
+5
View File
@@ -82,6 +82,11 @@ static void deint_process(struct mp_filter *f)
char *args[] = {"mode", "send_field", NULL};
p->sub.filter =
mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "yadif_cuda", args);
} else if (img->imgfmt == IMGFMT_VAAPI) {
char *args[] = {"deint", "motion-adaptive",
"interlaced-only", "yes", NULL};
p->sub.filter =
mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vavpp", args);
} else {
has_filter = false;
}
+36 -12
View File
@@ -191,21 +191,40 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
dst_have_sw |= !is_hw;
}
// Source is sw, all targets are hw -> try to upload.
bool sw_to_hw = imgfmt_is_sw && dst_all_hw;
// Source is hw, some targets are sw -> try to download.
bool hw_to_sw = !imgfmt_is_sw && dst_have_sw;
if (sw_to_hw && num_fmts > 0) {
// We can probably use this! Very lazy and very approximate.
struct mp_hwupload *upload = mp_hwupload_create(conv, fmts[0]);
if (upload) {
mp_info(log, "HW-uploading to %s\n", mp_imgfmt_to_name(fmts[0]));
filters[2] = upload->f;
hwupload_fmt = mp_hwupload_find_upload_format(upload, img->imgfmt);
fmts = &hwupload_fmt;
num_fmts = hwupload_fmt ? 1 : 0;
hw_to_sw = false;
if (dst_all_hw && num_fmts > 0) {
bool upload_created = false;
int sw_fmt = imgfmt_is_sw ? img->imgfmt : img->params.hw_subfmt;
for (int i = 0; i < num_fmts; i++) {
// We can probably use this! Very lazy and very approximate.
struct mp_hwupload *upload = mp_hwupload_create(conv, fmts[i]);
if (upload) {
mp_info(log, "HW-uploading to %s\n", mp_imgfmt_to_name(fmts[i]));
filters[2] = upload->f;
hwupload_fmt = mp_hwupload_find_upload_format(upload, sw_fmt);
fmts = &hwupload_fmt;
num_fmts = hwupload_fmt ? 1 : 0;
hw_to_sw = false;
// We cannot do format conversions when transferring between
// two hardware devices, so reject this format if that would be
// required.
if (!imgfmt_is_sw && hwupload_fmt != sw_fmt) {
mp_err(log, "Format %s is not supported by %s\n",
mp_imgfmt_to_name(sw_fmt),
mp_imgfmt_to_name(p->imgfmts[i]));
continue;
}
upload_created = true;
break;
}
}
if (!upload_created) {
mp_err(log, "Failed to create HW uploader for format %s\n",
mp_imgfmt_to_name(sw_fmt));
}
}
@@ -235,6 +254,11 @@ static bool build_image_converter(struct mp_autoconvert *c, struct mp_log *log,
force_sws_params |= !mp_image_params_equal(&imgpar, &p->imgparams);
need_sws |= force_sws_params;
}
if (!imgfmt_is_sw && dst_all_hw) {
// This is a hw -> hw upload, so the sw format must already be
// mutually understood. No conversion can be done.
need_sws = false;
}
if (need_sws) {
// Create a new conversion filter.
+3 -1
View File
@@ -594,12 +594,14 @@ static void fix_image_params(struct priv *p,
if (m.p_w <= 0 || m.p_h <= 0)
m.p_w = m.p_h = 1;
m.rotate = p->codec->rotate;
m.stereo3d = p->codec->stereo_mode;
if (opts->video_rotate < 0) {
m.rotate = 0;
} else {
// ffmpeg commit 535a835e51 says that frame rotate takes priority
if (!m.rotate)
m.rotate = p->codec->rotate;
m.rotate = (m.rotate + opts->video_rotate) % 360;
}
+127 -81
View File
@@ -15,9 +15,9 @@ struct priv {
AVBufferRef *hw_pool;
int last_input_fmt;
int last_upload_fmt;
int last_sw_fmt;
int last_source_fmt;
int last_hw_output_fmt;
int last_hw_input_fmt;
// Hardware wrapper format, e.g. IMGFMT_VAAPI.
int hw_imgfmt;
@@ -35,66 +35,84 @@ struct priv {
int *fmt_upload_index;
int *fmt_upload_num;
// List of source formats that require hwmap instead of hwupload.
int *map_fmts;
int num_map_fmts;
struct mp_hwupload public;
};
struct ffmpeg_and_other_bugs {
int imgfmt; // hw format
const int *const whitelist_formats; // if non-NULL, allow only these
// sw formats
bool force_same_upload_fmt; // force upload fmt == sw fmt
struct hwmap_pairs {
int first_fmt;
int second_fmt;
};
// This garbage is so complex and buggy. Hardcoding knowledge makes it work,
// trying to use the dynamic information returned by the API does not. So fuck
// this shit, I'll just whitelist the cases that work, what the fuck.
static const struct ffmpeg_and_other_bugs shitlist[] = {
// We cannot discover which pairs of hardware formats need to use hwmap to
// convert between the formats, so we need a lookup table.
static const struct hwmap_pairs hwmap_pairs[] = {
{
.imgfmt = IMGFMT_VAAPI,
.whitelist_formats = (const int[]){IMGFMT_NV12, IMGFMT_P010, IMGFMT_BGRA,
IMGFMT_ABGR, IMGFMT_RGB0, 0},
.force_same_upload_fmt = true,
.first_fmt = IMGFMT_DRMPRIME,
.second_fmt = IMGFMT_VAAPI,
},
{0}
};
static bool select_format(struct priv *p, int input_fmt, int *out_sw_fmt,
int *out_upload_fmt)
/**
* @brief Find the closest supported format when hw uploading
*
* Some hardware types support implicit format conversion on upload. For these
* types, it is possible for the set of formats that are accepts as inputs to
* the upload process to differ from the set of formats that can be outputs of
* the upload.
*
* hw_input_format -> hwupload -> hw_output_format
*
* Awareness of this is important because we can avoid doing software conversion
* if our input_fmt is accepted as a hw_input_format even if it cannot be the
* hw_output_format.
*/
static bool select_format(struct priv *p, int input_fmt,
int *out_hw_input_fmt, int *out_hw_output_fmt)
{
if (!input_fmt)
return false;
// First find the closest sw fmt. Some hwdec APIs return crazy lists of
// If the input format is a hw format, then we shouldn't be doing this
// format selection here at all.
if (IMGFMT_IS_HWACCEL(input_fmt)) {
return false;
}
// First find the closest hw input fmt. Some hwdec APIs return crazy lists of
// "supported" formats, which then are not supported or crash (???), so
// the this is a good way to avoid problems.
// (Actually we should just have hardcoded everything instead of relying on
// this fragile bullshit FFmpeg API and the fragile bullshit hwdec drivers.)
int sw_fmt = mp_imgfmt_select_best_list(p->fmts, p->num_fmts, input_fmt);
if (!sw_fmt)
int hw_input_fmt = mp_imgfmt_select_best_list(p->fmts, p->num_fmts, input_fmt);
if (!hw_input_fmt)
return false;
// Dumb, but find index for p->fmts[index]==sw_fmt.
// Dumb, but find index for p->fmts[index]==hw_input_fmt.
int index = -1;
for (int n = 0; n < p->num_fmts; n++) {
if (p->fmts[n] == sw_fmt)
if (p->fmts[n] == hw_input_fmt)
index = n;
}
if (index < 0)
return false;
// Now check the available upload formats. This is the format our sw frame
// has to be in, and which the upload API will take (probably).
// Now check the available output formats. This is the format our sw frame
// will be in after the upload (probably).
int *upload_fmts = &p->upload_fmts[p->fmt_upload_index[index]];
int num_upload_fmts = p->fmt_upload_num[index];
int up_fmt = mp_imgfmt_select_best_list(upload_fmts, num_upload_fmts,
int hw_output_fmt = mp_imgfmt_select_best_list(upload_fmts, num_upload_fmts,
input_fmt);
if (!up_fmt)
if (!hw_output_fmt)
return false;
*out_sw_fmt = sw_fmt;
*out_upload_fmt = up_fmt;
*out_hw_input_fmt = hw_input_fmt;
*out_hw_output_fmt = hw_output_fmt;
return true;
}
@@ -104,7 +122,15 @@ int mp_hwupload_find_upload_format(struct mp_hwupload *u, int imgfmt)
int sw = 0, up = 0;
select_format(p, imgfmt, &sw, &up);
return up;
// In th case where the imgfmt is not natively supported, it must be
// converted, either before or during upload. If the imgfmt is supported as
// an hw input format, then prefer that, and if the upload has to do implict
// conversion, that's fine. On the other hand, if the imgfmt is not a
// supported input format, then pick the output format as the conversion
// target to avoid doing two conversions (one before upload, and one during
// upload). Note that for most hardware types, there is no ability to convert
// during upload, and the two formats will always be the same.
return imgfmt == sw ? sw : up;
}
static void process(struct mp_filter *f)
@@ -125,44 +151,66 @@ static void process(struct mp_filter *f)
}
struct mp_image *src = frame.data;
// As documented, just pass though HW frames.
if (IMGFMT_IS_HWACCEL(src->imgfmt)) {
/*
* Just pass though HW frames in the same format. This shouldn't normally
* occur as the upload filter will not be inserted when the formats already
* match.
*
* Technically, we could have frames from different device contexts,
* which would require an explicit transfer, but mpv doesn't let you
* create that configuration.
*/
if (src->imgfmt == p->hw_imgfmt) {
mp_pin_in_write(f->ppins[1], frame);
return;
}
if (src->w % 2 || src->h % 2) {
MP_ERR(f, "non-mod 2 input frames unsupported\n");
goto error;
}
if (src->imgfmt != p->last_input_fmt) {
if (!select_format(p, src->imgfmt, &p->last_sw_fmt, &p->last_upload_fmt))
{
MP_ERR(f, "no hw upload format found\n");
goto error;
if (src->imgfmt != p->last_source_fmt) {
if (IMGFMT_IS_HWACCEL(src->imgfmt)) {
// Because there cannot be any conversion of the sw format when the
// input is a hw format, just pick the source sw format.
p->last_hw_input_fmt = p->last_hw_output_fmt = src->params.hw_subfmt;
} else {
if (!select_format(p, src->imgfmt,
&p->last_hw_input_fmt, &p->last_hw_output_fmt))
{
MP_ERR(f, "no hw upload format found\n");
goto error;
}
if (src->imgfmt != p->last_hw_input_fmt) {
// Should not fail; if it does, mp_hwupload_find_upload_format()
// does not return the src->imgfmt format.
MP_ERR(f, "input format is not an upload format\n");
goto error;
}
}
if (src->imgfmt != p->last_upload_fmt) {
// Should not fail; if it does, mp_hwupload_find_upload_format()
// does not return the src->imgfmt format.
MP_ERR(f, "input format not an upload format\n");
goto error;
}
p->last_input_fmt = src->imgfmt;
p->last_source_fmt = src->imgfmt;
MP_INFO(f, "upload %s -> %s[%s]\n",
mp_imgfmt_to_name(p->last_input_fmt),
mp_imgfmt_to_name(p->last_source_fmt),
mp_imgfmt_to_name(p->hw_imgfmt),
mp_imgfmt_to_name(p->last_sw_fmt));
mp_imgfmt_to_name(p->last_hw_output_fmt));
}
if (!mp_update_av_hw_frames_pool(&p->hw_pool, p->av_device_ctx, p->hw_imgfmt,
p->last_sw_fmt, src->w, src->h))
p->last_hw_output_fmt, src->w, src->h))
{
MP_ERR(f, "failed to create frame pool\n");
goto error;
}
struct mp_image *dst = mp_av_pool_image_hw_upload(p->hw_pool, src);
struct mp_image *dst;
bool map_images = false;
for (int n = 0; n < p->num_map_fmts; n++) {
if (src->imgfmt == p->map_fmts[n]) {
map_images = true;
break;
}
}
if (map_images)
dst = mp_av_pool_image_hw_map(p->hw_pool, src);
else
dst = mp_av_pool_image_hw_upload(p->hw_pool, src);
if (!dst)
goto error;
@@ -198,10 +246,10 @@ static const struct mp_filter_info hwupload_filter = {
// So filter out all not explicitly supported formats.
static bool vo_supports(struct mp_hwdec_ctx *ctx, int hw_fmt, int sw_fmt)
{
if (!ctx->hw_imgfmt)
return true; // if unset, all formats are allowed
if (ctx->hw_imgfmt != hw_fmt)
return false;
if (!ctx->supported_formats)
return true; // if unset, all formats are allowed
for (int i = 0; ctx->supported_formats && ctx->supported_formats[i]; i++) {
if (ctx->supported_formats[i] == sw_fmt)
@@ -228,6 +276,12 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
struct mp_hwdec_ctx *ctx = NULL;
AVHWFramesConstraints *cstr = NULL;
struct hwdec_imgfmt_request params = {
.imgfmt = hw_imgfmt,
.probing = true,
};
hwdec_devices_request_for_img_fmt(info->hwdec_devs, &params);
for (int n = 0; ; n++) {
struct mp_hwdec_ctx *cur = hwdec_devices_get_n(info->hwdec_devs, n);
if (!cur)
@@ -251,7 +305,7 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
}
if (!ctx) {
MP_ERR(u->f, "no support for this hw format\n");
MP_INFO(u->f, "no support for this hw format\n");
return false;
}
@@ -261,11 +315,13 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
// supported formats. This should be relatively cheap as we don't create
// any real frames (although some backends do for probing info).
const struct ffmpeg_and_other_bugs *bugs = NULL;
for (int n = 0; shitlist[n].imgfmt; n++) {
if (shitlist[n].imgfmt == hw_imgfmt) {
bugs = &shitlist[n];
break;
for (int n = 0; hwmap_pairs[n].first_fmt; n++) {
if (hwmap_pairs[n].first_fmt == hw_imgfmt) {
MP_TARRAY_APPEND(p, p->map_fmts, p->num_map_fmts,
hwmap_pairs[n].second_fmt);
} else if (hwmap_pairs[n].second_fmt == hw_imgfmt) {
MP_TARRAY_APPEND(p, p->map_fmts, p->num_map_fmts,
hwmap_pairs[n].first_fmt);
}
}
@@ -280,18 +336,12 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
mp_imgfmt_to_name(hw_imgfmt),
mp_imgfmt_to_name(imgfmt));
if (bugs && bugs->whitelist_formats) {
bool found = false;
for (int i = 0; bugs->whitelist_formats[i]; i++) {
if (bugs->whitelist_formats[i] == imgfmt) {
found = true;
break;
}
}
if (!found) {
MP_VERBOSE(u->f, "... skipping blacklisted format\n");
continue;
}
if (IMGFMT_IS_HWACCEL(imgfmt)) {
// If the enumerated format is a hardware format, we don't need to
// do any further probing. It will be supported.
MP_VERBOSE(u->f, " supports %s (a hardware format)\n",
mp_imgfmt_to_name(imgfmt));
continue;
}
// Creates an AVHWFramesContexts with the given parameters.
@@ -319,10 +369,6 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
if (!fmt)
continue;
MP_VERBOSE(u->f, " supports %s\n", mp_imgfmt_to_name(fmt));
if (bugs && bugs->force_same_upload_fmt && imgfmt != fmt) {
MP_VERBOSE(u->f, " ... skipping blacklisted format\n");
continue;
}
if (!vo_supports(ctx, hw_imgfmt, fmt)) {
MP_VERBOSE(u->f, " ... not supported by VO\n");
continue;
@@ -360,12 +406,12 @@ struct mp_hwupload *mp_hwupload_create(struct mp_filter *parent, int hw_imgfmt)
mp_filter_add_pin(f, MP_PIN_OUT, "out");
if (!probe_formats(u, hw_imgfmt)) {
MP_ERR(f, "hardware format not supported\n");
goto error;
MP_INFO(f, "hardware format not supported\n");
goto fail;
}
return u;
error:
fail:
talloc_free(f);
return NULL;
}
+61 -19
View File
@@ -33,6 +33,8 @@
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include "config.h"
#include "common/common.h"
#include "common/av_common.h"
#include "common/tags.h"
@@ -40,10 +42,12 @@
#include "audio/format.h"
#include "audio/aframe.h"
#include "audio/chmap_avchannel.h"
#include "video/mp_image.h"
#include "audio/fmt-conversion.h"
#include "video/fmt-conversion.h"
#include "video/hwdec.h"
#include "video/out/gpu/hwdec.h"
#include "f_lavfi.h"
#include "filter.h"
@@ -95,6 +99,9 @@ struct lavfi {
double delay; // seconds of audio apparently buffered by filter
struct mp_lavfi public;
// Identify a specific hwdec_interop to use
char *hwdec_interop;
};
struct lavfi_pad {
@@ -394,7 +401,7 @@ static bool init_pads(struct lavfi *c)
} else if (pad->type == MP_FRAME_VIDEO) {
dst_filter = avfilter_get_by_name("buffersink");
} else {
assert(0);
MP_ASSERT_UNREACHABLE();
}
if (!dst_filter)
@@ -470,7 +477,11 @@ static bool init_pads(struct lavfi *c)
params->sample_rate = mp_aframe_get_rate(fmt);
struct mp_chmap chmap = {0};
mp_aframe_get_chmap(fmt, &chmap);
#if !HAVE_AV_CHANNEL_LAYOUT
params->channel_layout = mp_chmap_to_lavc(&chmap);
#else
mp_chmap_to_av_layout(&params->ch_layout, &chmap);
#endif
pad->timebase = (AVRational){1, mp_aframe_get_rate(fmt)};
filter_name = "abuffer";
} else if (pad->type == MP_FRAME_VIDEO) {
@@ -484,7 +495,7 @@ static bool init_pads(struct lavfi *c)
params->frame_rate = av_d2q(fmt->nominal_fps, 1000000);
filter_name = "buffer";
} else {
assert(0);
MP_ASSERT_UNREACHABLE();
}
params->time_base = pad->timebase;
@@ -541,11 +552,22 @@ static void init_graph(struct lavfi *c)
if (init_pads(c)) {
struct mp_stream_info *info = mp_filter_find_stream_info(c->f);
if (info && info->hwdec_devs) {
struct mp_hwdec_ctx *hwdec = hwdec_devices_get_first(info->hwdec_devs);
for (int n = 0; n < c->graph->nb_filters; n++) {
AVFilterContext *filter = c->graph->filters[n];
if (hwdec && hwdec->av_device_ref)
filter->hw_device_ctx = av_buffer_ref(hwdec->av_device_ref);
struct mp_hwdec_ctx *hwdec_ctx = NULL;
if (c->hwdec_interop) {
int imgfmt =
ra_hwdec_driver_get_imgfmt_for_name(c->hwdec_interop);
hwdec_ctx = mp_filter_load_hwdec_device(c->f, imgfmt);
} else {
hwdec_ctx = hwdec_devices_get_first(info->hwdec_devs);
}
if (hwdec_ctx && hwdec_ctx->av_device_ref) {
MP_VERBOSE(c, "Configuring hwdec_interop=%s for filter graph: %s\n",
hwdec_ctx->driver_name, c->graph_string);
for (int n = 0; n < c->graph->nb_filters; n++) {
AVFilterContext *filter = c->graph->filters[n];
filter->hw_device_ctx =
av_buffer_ref(hwdec_ctx->av_device_ref);
}
}
}
@@ -879,6 +901,7 @@ error:
struct mp_lavfi *mp_lavfi_create_graph(struct mp_filter *parent,
enum mp_frame_type type, bool bidir,
char *hwdec_interop,
char **graph_opts, const char *graph)
{
struct lavfi *c = lavfi_alloc(parent);
@@ -889,12 +912,14 @@ struct mp_lavfi *mp_lavfi_create_graph(struct mp_filter *parent,
c->force_bidir = bidir;
c->graph_opts = mp_dup_str_array(c, graph_opts);
c->graph_string = talloc_strdup(c, graph);
c->hwdec_interop = talloc_strdup(c, hwdec_interop);
return do_init(c);
}
struct mp_lavfi *mp_lavfi_create_filter(struct mp_filter *parent,
enum mp_frame_type type, bool bidir,
char *hwdec_interop,
char **graph_opts,
const char *filter, char **filter_opts)
{
@@ -904,6 +929,7 @@ struct mp_lavfi *mp_lavfi_create_filter(struct mp_filter *parent,
c->force_type = type;
c->force_bidir = bidir;
c->hwdec_interop = talloc_strdup(c, hwdec_interop);
c->graph_opts = mp_dup_str_array(c, graph_opts);
c->graph_string = talloc_strdup(c, filter);
c->direct_filter_opts = mp_dup_str_array(c, filter_opts);
@@ -923,6 +949,8 @@ struct lavfi_user_opts {
char **filter_opts;
int fix_pts;
char *hwdec_interop;
};
static struct mp_filter *lavfi_create(struct mp_filter *parent, void *options)
@@ -930,10 +958,11 @@ static struct mp_filter *lavfi_create(struct mp_filter *parent, void *options)
struct lavfi_user_opts *opts = options;
struct mp_lavfi *l;
if (opts->is_bridge) {
l = mp_lavfi_create_filter(parent, opts->type, true, opts->avopts,
l = mp_lavfi_create_filter(parent, opts->type, true,
opts->hwdec_interop, opts->avopts,
opts->filter_name, opts->filter_opts);
} else {
l = mp_lavfi_create_graph(parent, opts->type, true,
l = mp_lavfi_create_graph(parent, opts->type, true, opts->hwdec_interop,
opts->avopts, opts->graph);
}
if (l) {
@@ -944,19 +973,19 @@ static struct mp_filter *lavfi_create(struct mp_filter *parent, void *options)
return l ? l->f : NULL;
}
static bool is_single_media_only(const AVFilterPad *pads, int media_type)
{
int count = avfilter_pad_count(pads);
if (count != 1)
return false;
return avfilter_pad_get_type(pads, 0) == media_type;
}
// Does it have exactly one video input and one video output?
static bool is_usable(const AVFilter *filter, int media_type)
{
return is_single_media_only(filter->inputs, media_type) &&
is_single_media_only(filter->outputs, media_type);
#if LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(8, 3, 0)
int nb_inputs = avfilter_filter_pad_count(filter, 0),
nb_outputs = avfilter_filter_pad_count(filter, 1);
#else
int nb_inputs = avfilter_pad_count(filter->inputs),
nb_outputs = avfilter_pad_count(filter->outputs);
#endif
return nb_inputs == 1 && nb_outputs == 1 &&
avfilter_pad_get_type(filter->inputs, 0) == media_type &&
avfilter_pad_get_type(filter->outputs, 0) == media_type;
}
bool mp_lavfi_is_usable(const char *name, int media_type)
@@ -1094,6 +1123,9 @@ const struct mp_user_filter_entry af_lavfi = {
{"graph", OPT_STRING(graph)},
{"fix-pts", OPT_FLAG(fix_pts)},
{"o", OPT_KEYVALUELIST(avopts)},
{"hwdec_interop",
OPT_STRING_VALIDATE(hwdec_interop,
ra_hwdec_validate_drivers_only_opt)},
{0}
},
.priv_defaults = &(const OPT_BASE_STRUCT){
@@ -1113,6 +1145,9 @@ const struct mp_user_filter_entry af_lavfi_bridge = {
{"name", OPT_STRING(filter_name)},
{"opts", OPT_KEYVALUELIST(filter_opts)},
{"o", OPT_KEYVALUELIST(avopts)},
{"hwdec_interop",
OPT_STRING_VALIDATE(hwdec_interop,
ra_hwdec_validate_drivers_only_opt)},
{0}
},
.priv_defaults = &(const OPT_BASE_STRUCT){
@@ -1132,6 +1167,9 @@ const struct mp_user_filter_entry vf_lavfi = {
.options = (const m_option_t[]){
{"graph", OPT_STRING(graph)},
{"o", OPT_KEYVALUELIST(avopts)},
{"hwdec_interop",
OPT_STRING_VALIDATE(hwdec_interop,
ra_hwdec_validate_drivers_only_opt)},
{0}
},
.priv_defaults = &(const OPT_BASE_STRUCT){
@@ -1151,6 +1189,10 @@ const struct mp_user_filter_entry vf_lavfi_bridge = {
{"name", OPT_STRING(filter_name)},
{"opts", OPT_KEYVALUELIST(filter_opts)},
{"o", OPT_KEYVALUELIST(avopts)},
{"hwdec_interop",
OPT_STRING_VALIDATE(hwdec_interop,
ra_hwdec_validate_drivers_only_opt)},
{0}
},
.priv_defaults = &(const OPT_BASE_STRUCT){
+2
View File
@@ -18,6 +18,7 @@ struct mp_lavfi {
// graph: a libavfilter graph specification
struct mp_lavfi *mp_lavfi_create_graph(struct mp_filter *parent,
enum mp_frame_type type, bool bidir,
char *hwdec_interop,
char **graph_opts, const char *graph);
// Unlike mp_lavfi_create_graph(), this creates a single filter, using explicit
@@ -26,6 +27,7 @@ struct mp_lavfi *mp_lavfi_create_graph(struct mp_filter *parent,
// (which are applied with mp_set_avopts()).
struct mp_lavfi *mp_lavfi_create_filter(struct mp_filter *parent,
enum mp_frame_type type, bool bidir,
char *hwdec_interop,
char **graph_opts,
const char *filter, char **filter_opts);
+6 -6
View File
@@ -106,16 +106,16 @@ static void check_in_format_change(struct mp_user_filter *u,
if (u == p->input) {
p->public.input_params = img->params;
// Unfortunately there's no good place to update these.
// But a common case is enabling HW decoding, which
// might init some support of them in the VO, and update
// the VO's format list.
update_output_caps(p);
} else if (u == p->output) {
p->public.output_params = img->params;
}
// Unfortunately there's no good place to update these.
// But a common case is enabling HW decoding, which
// might init some support of them in the VO, and update
// the VO's format list.
update_output_caps(p);
p->public.reconfig_happened = true;
}
}
-22
View File
@@ -327,26 +327,6 @@ static void reset(struct mp_filter *f)
close_lavrr(p);
}
static void extra_output_conversion(struct mp_aframe *mpa)
{
int format = af_fmt_from_planar(mp_aframe_get_format(mpa));
int num_planes = mp_aframe_get_planes(mpa);
uint8_t **planes = mp_aframe_get_data_rw(mpa);
if (!planes)
return;
for (int p = 0; p < num_planes; p++) {
void *ptr = planes[p];
int total = mp_aframe_get_total_plane_samples(mpa);
if (format == AF_FORMAT_FLOAT) {
for (int s = 0; s < total; s++)
((float *)ptr)[s] = av_clipf(((float *)ptr)[s], -1.0f, 1.0f);
} else if (format == AF_FORMAT_DOUBLE) {
for (int s = 0; s < total; s++)
((double *)ptr)[s] = MPCLAMP(((double *)ptr)[s], -1.0, 1.0);
}
}
}
// This relies on the tricky way mpa was allocated.
static bool reorder_planes(struct mp_aframe *mpa, int *reorder,
struct mp_chmap *newmap)
@@ -451,8 +431,6 @@ static struct mp_frame filter_resample_output(struct priv *p,
goto error;
}
extra_output_conversion(out);
if (in) {
mp_aframe_copy_attributes(out, in);
p->current_pts = mp_aframe_end_pts(in);
+1 -1
View File
@@ -250,7 +250,7 @@ static void fixed_aframe_size_process(struct mp_filter *f)
int in_samples = mp_aframe_get_size(p->in);
int copy = MPMIN(in_samples, p->samples - p->out_written);
if (!mp_aframe_copy_samples(p->out, p->out_written, p->in, 0, copy))
assert(0);
MP_ASSERT_UNREACHABLE();
mp_aframe_skip_samples(p->in, copy);
p->out_written += copy;
}
+3 -3
View File
@@ -10,7 +10,7 @@ struct mp_filter *mp_compute_frame_duration_create(struct mp_filter *parent);
// Given the filters[0..num_filters] array, connect in with the input of the
// first filter, connect the output of the first filter to the input to the
// second filter, etc., until out. All filters are assumed to be bidrectional,
// second filter, etc., until out. All filters are assumed to be bidirectional,
// with input on pin 0 and output on pin 1. NULL entries are skipped.
void mp_chain_filters(struct mp_pin *in, struct mp_pin *out,
struct mp_filter **filters, int num_filters);
@@ -68,10 +68,10 @@ void mp_subfilter_destroy(struct mp_subfilter *sub);
// The filter is destroyed with talloc_free(sub->filter).
bool mp_subfilter_drain_destroy(struct mp_subfilter *sub);
// A bidrectional filter which passes through all data.
// A bidirectional filter which passes through all data.
struct mp_filter *mp_bidir_nop_filter_create(struct mp_filter *parent);
// A bidrectional filter which does not connect its pins. Instead, the user is,
// A bidirectional filter which does not connect its pins. Instead, the user is,
// by convention, allowed to access the filter's private pins, and use them
// freely. (This is sometimes convenient, such as when you need to pass a single
// filter instance to other code, and you don't need a full "proper" filter.)
+12 -5
View File
@@ -1,12 +1,15 @@
#include <math.h>
#include <pthread.h>
#include <libavutil/hwcontext.h>
#include "common/common.h"
#include "common/global.h"
#include "common/msg.h"
#include "osdep/atomic.h"
#include "osdep/timer.h"
#include "video/hwdec.h"
#include "video/img_format.h"
#include "filter.h"
#include "filter_internal.h"
@@ -372,7 +375,7 @@ static struct mp_pin *find_connected_end(struct mp_pin *p)
return other;
p = other->user_conn;
}
assert(0);
MP_ASSERT_UNREACHABLE();
}
// With p being part of a connection, create the pin_connection and set all
@@ -397,7 +400,7 @@ static void init_connection(struct mp_pin *p)
if (out->manual_connection)
assert(out->manual_connection->in->runner == runner);
// Logicaly, the ends are always manual connections. A pin chain without
// Logically, the ends are always manual connections. A pin chain without
// manual connections at the ends is still disconnected (or if this
// attempted to extend an existing connection, becomes dangling and gets
// disconnected).
@@ -682,15 +685,19 @@ struct mp_stream_info *mp_filter_find_stream_info(struct mp_filter *f)
return NULL;
}
struct AVBufferRef *mp_filter_load_hwdec_device(struct mp_filter *f, int avtype)
struct mp_hwdec_ctx *mp_filter_load_hwdec_device(struct mp_filter *f, int imgfmt)
{
struct mp_stream_info *info = mp_filter_find_stream_info(f);
if (!info || !info->hwdec_devs)
return NULL;
hwdec_devices_request_all(info->hwdec_devs);
struct hwdec_imgfmt_request params = {
.imgfmt = imgfmt,
.probing = false,
};
hwdec_devices_request_for_img_fmt(info->hwdec_devs, &params);
return hwdec_devices_get_lavc(info->hwdec_devs, avtype);
return hwdec_devices_get_by_imgfmt(info->hwdec_devs, imgfmt);
}
static void filter_wakeup(struct mp_filter *f, bool mark_only)
+1 -2
View File
@@ -408,8 +408,7 @@ struct mp_stream_info {
// Search for a parent filter (including f) that has this set, and return it.
struct mp_stream_info *mp_filter_find_stream_info(struct mp_filter *f);
struct AVBufferRef;
struct AVBufferRef *mp_filter_load_hwdec_device(struct mp_filter *f, int avtype);
struct mp_hwdec_ctx *mp_filter_load_hwdec_device(struct mp_filter *f, int imgfmt);
// Perform filtering. This runs until the filter graph is blocked (due to
// missing external input or unread output). It returns whether any outside
+1 -3
View File
@@ -67,7 +67,6 @@ const struct m_obj_list af_obj_list = {
.get_desc = get_af_desc,
.description = "audio filters",
.allow_disable_entries = true,
.allow_unknown_entries = true,
.check_unknown_entry = check_af_lavfi,
.print_help_list = print_af_help_list,
.print_unknown_entry_help = print_af_lavfi_help,
@@ -124,7 +123,6 @@ const struct m_obj_list vf_obj_list = {
.get_desc = get_vf_desc,
.description = "video filters",
.allow_disable_entries = true,
.allow_unknown_entries = true,
.check_unknown_entry = check_vf_lavfi,
.print_help_list = print_vf_help_list,
.print_unknown_entry_help = print_vf_lavfi_help,
@@ -157,7 +155,7 @@ struct mp_filter *mp_create_user_filter(struct mp_filter *parent,
if (strncmp(name, "lavfi-", 6) == 0)
name += 6;
struct mp_lavfi *l =
mp_lavfi_create_filter(parent, frame_type, true, NULL, name, args);
mp_lavfi_create_filter(parent, frame_type, true, NULL, NULL, name, args);
if (l)
f = l->f;
goto done;
@@ -0,0 +1,8 @@
input = join_paths(source_root, 'TOOLS', 'osxbundle',
'mpv.app', 'Contents', 'Resources', 'icon.icns')
osxbundle = custom_target('osxbundle',
input: input,
output: 'icon.icns.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += osxbundle
+20
View File
@@ -0,0 +1,20 @@
icons = ['16', '32', '64', '128']
foreach size: icons
name = 'mpv-icon-8bit-'+size+'x'+size+'.png'
icon = custom_target(name,
input: join_paths(source_root, 'etc', name),
output: name + '.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += icon
endforeach
etc_files = ['input.conf', 'builtin.conf']
foreach file: etc_files
etc_file = custom_target(file,
input: join_paths(source_root, 'etc', file),
output: file + '.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += etc_file
endforeach
+25
View File
@@ -0,0 +1,25 @@
ebml_defs = custom_target('ebml_defs.inc',
output: 'ebml_defs.inc',
command: [matroska, '--generate-definitions', '@OUTPUT@'],
)
ebml_types = custom_target('ebml_types.h',
output: 'ebml_types.h',
command: [matroska, '--generate-header', '@OUTPUT@'],
)
version_h = custom_target('version.h',
output: 'version.h',
command: [version_py, '@OUTPUT@'],
build_always_stale: true,
)
sources += [ebml_defs, ebml_types, version_h]
# Meson doesn't allow having multiple build targets with the same name in the same file.
# Just generate the com in here for windows builds.
if win32 and get_option('cplayer')
wrapper_sources= '../osdep/win32-console-wrapper.c'
executable('mpv', wrapper_sources, c_args: '-municode', link_args: '-municode',
name_suffix: 'com', install: true)
endif
+57
View File
@@ -0,0 +1,57 @@
# custom swift targets
bridge = join_paths(source_root, 'osdep/macOS_swift_bridge.h')
header = join_paths(build_root, 'osdep/macOS_swift.h')
module = join_paths(build_root, 'osdep/macOS_swift.swiftmodule')
target = join_paths(build_root, 'osdep/macOS_swift.o')
swift_flags = ['-frontend', '-c', '-sdk', macos_sdk_path,
'-enable-objc-interop', '-emit-objc-header', '-parse-as-library']
if swift_ver.version_compare('>=6.0')
swift_flags += ['-swift-version', '5']
endif
if get_option('debug')
swift_flags += '-g'
endif
if get_option('optimization') != '0'
swift_flags += '-O'
endif
if macos_10_11_features.allowed()
swift_flags += ['-D', 'HAVE_MACOS_10_11_FEATURES']
endif
if macos_10_14_features.allowed()
swift_flags += ['-D', 'HAVE_MACOS_10_14_FEATURES']
endif
extra_flags = get_option('swift-flags').split()
swift_flags += extra_flags
swift_compile = [swift_prog, swift_flags, '-module-name', 'macOS_swift',
'-emit-module-path', '@OUTPUT0@', '-import-objc-header', bridge,
'-emit-objc-header-path', '@OUTPUT1@', '-o', '@OUTPUT2@',
'@INPUT@', '-I.', '-I' + source_root]
swift_targets = custom_target('swift_targets',
input: swift_sources,
output: ['macOS_swift.swiftmodule', 'macOS_swift.h', 'macOS_swift.o'],
command: swift_compile,
)
sources += swift_targets
swift_lib_dir_py = find_program(join_paths(tools_directory, 'macos-swift-lib-directory.py'))
swift_lib_dir = run_command(swift_lib_dir_py, swift_prog.full_path(), check: true).stdout()
message('Detected Swift library directory: ' + swift_lib_dir)
# linker flags
swift_link_flags = ['-L' + swift_lib_dir, '-Xlinker', '-rpath',
'-Xlinker', swift_lib_dir, '-rdynamic', '-Xlinker',
'-add_ast_path', '-Xlinker', module]
if swift_ver.version_compare('>=5.0')
swift_link_flags += ['-Xlinker', '-rpath', '-Xlinker',
'/usr/lib/swift', '-L/usr/lib/swift']
endif
add_project_link_arguments(swift_link_flags, language: ['c', 'objc'])
+6
View File
@@ -0,0 +1,6 @@
defaults_js = custom_target('defaults.js',
input: join_paths(source_root, 'player', 'javascript', 'defaults.js'),
output: 'defaults.js.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += defaults_js
+10
View File
@@ -0,0 +1,10 @@
lua_files = ['defaults.lua', 'assdraw.lua', 'options.lua', 'osc.lua',
'ytdl_hook.lua', 'stats.lua', 'console.lua', 'auto_profiles.lua']
foreach file: lua_files
lua_file = custom_target(file,
input: join_paths(source_root, 'player', 'lua', file),
output: file + '.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += lua_file
endforeach
+6
View File
@@ -0,0 +1,6 @@
osd_font = custom_target('osd_font.otf',
input: join_paths(source_root, 'sub', 'osd_font.otf'),
output: 'osd_font.otf.inc',
command: [file2string, '@INPUT@', '@OUTPUT@'],
)
sources += osd_font
+36
View File
@@ -0,0 +1,36 @@
wl_protocol_dir = wayland['deps'][2].get_variable(pkgconfig: 'pkgdatadir', internal: 'pkgdatadir')
protocols = [[wl_protocol_dir, 'stable/presentation-time/presentation-time.xml'],
[wl_protocol_dir, 'stable/viewporter/viewporter.xml'],
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
[wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
[wl_protocol_dir, 'unstable/xdg-decoration/xdg-decoration-unstable-v1.xml']]
wl_protocols_source = []
wl_protocols_headers = []
features += {'wayland_protocols_1_24': wayland['deps'][2].version().version_compare('>=1.24')}
foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
input: xml,
output: '@BASENAME@.c',
command: [wayland['scanner'], 'private-code', '@INPUT@', '@OUTPUT@'],
)
wl_protocols_headers += custom_target(xml.underscorify() + '_h',
input: xml,
output: '@BASENAME@.h',
command: [wayland['scanner'], 'client-header', '@INPUT@', '@OUTPUT@'],
)
endforeach
lib_client_protocols = static_library('protocols',
wl_protocols_source + wl_protocols_headers,
dependencies: wayland['deps'][0])
client_protocols = declare_dependency(link_with: lib_client_protocols,
sources: wl_protocols_headers)
dependencies += [client_protocols, wayland['deps']]
sources += ['video/out/wayland_common.c']
+12
View File
@@ -64,6 +64,18 @@ static const struct key_name key_names[] = {
{ MP_KEY_F+10, "F10" },
{ MP_KEY_F+11, "F11" },
{ MP_KEY_F+12, "F12" },
{ MP_KEY_F+13, "F13" },
{ MP_KEY_F+14, "F14" },
{ MP_KEY_F+15, "F15" },
{ MP_KEY_F+16, "F16" },
{ MP_KEY_F+17, "F17" },
{ MP_KEY_F+18, "F18" },
{ MP_KEY_F+19, "F19" },
{ MP_KEY_F+20, "F20" },
{ MP_KEY_F+21, "F21" },
{ MP_KEY_F+22, "F22" },
{ MP_KEY_F+23, "F23" },
{ MP_KEY_F+24, "F24" },
{ MP_KEY_KP0, "KP0" },
{ MP_KEY_KP1, "KP1" },
{ MP_KEY_KP2, "KP2" },
+67 -248
View File
@@ -26,6 +26,15 @@
#include <stddef.h>
#include <stdint.h>
/* New symbols must still be added to libmpv/mpv.def. */
#ifdef _WIN32
#define MPV_EXPORT __declspec(dllexport)
#elif defined(__GNUC__) || defined(__clang__)
#define MPV_EXPORT __attribute__((visibility("default")))
#else
#define MPV_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -143,8 +152,6 @@ extern "C" {
* - Using UNIX IPC (off by default) will override the SIGPIPE signal handler,
* and set it to SIG_IGN. Some invocations of the "subprocess" command will
* also do that.
* - mpv will reseed the legacy C random number generator by calling srand() at
* some random point once.
* - mpv may start sub processes, so overriding SIGCHLD, or waiting on all PIDs
* (such as calling wait()) by the parent process or any other library within
* the process must be avoided. libmpv itself only waits for its own PIDs.
@@ -215,10 +222,8 @@ extern "C" {
* This are the planned changes that will most likely be done on the next major
* bump of the library:
*
* - remove all symbols and include files that are marked as deprecated
* - remove all symbols that are marked as deprecated
* - reassign enum numerical values to remove gaps
* - remove the mpv_opengl_init_params.extra_exts field
* - change the type of mpv_event_end_file.reason
* - disabling all events by default
*/
@@ -235,7 +240,7 @@ extern "C" {
* relational operators (<, >, <=, >=).
*/
#define MPV_MAKE_VERSION(major, minor) (((major) << 16) | (minor) | 0UL)
#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 109)
#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(2, 0)
/**
* The API user is allowed to "#define MPV_ENABLE_DEPRECATED 0" before
@@ -250,7 +255,7 @@ extern "C" {
/**
* Return the MPV_CLIENT_API_VERSION the mpv source has been compiled with.
*/
unsigned long mpv_client_api_version(void);
MPV_EXPORT unsigned long mpv_client_api_version(void);
/**
* Client context used by the client API. Every client has its own private
@@ -374,7 +379,7 @@ typedef enum mpv_error {
* @return A static string describing the error. The string is completely
* static, i.e. doesn't need to be deallocated, and is valid forever.
*/
const char *mpv_error_string(int error);
MPV_EXPORT const char *mpv_error_string(int error);
/**
* General function to deallocate memory returned by some of the API functions.
@@ -383,7 +388,7 @@ const char *mpv_error_string(int error);
*
* @param data A valid pointer returned by the API, or NULL.
*/
void mpv_free(void *data);
MPV_EXPORT void mpv_free(void *data);
/**
* Return the name of this client handle. Every client has its own unique
@@ -392,7 +397,7 @@ void mpv_free(void *data);
* @return The client name. The string is read-only and is valid until the
* mpv_handle is destroyed.
*/
const char *mpv_client_name(mpv_handle *ctx);
MPV_EXPORT const char *mpv_client_name(mpv_handle *ctx);
/**
* Return the ID of this client handle. Every client has its own unique ID. This
@@ -409,7 +414,7 @@ const char *mpv_client_name(mpv_handle *ctx);
*
* @return The client ID.
*/
int64_t mpv_client_id(mpv_handle *ctx);
MPV_EXPORT int64_t mpv_client_id(mpv_handle *ctx);
/**
* Create a new mpv instance and an associated client API handle to control
@@ -465,7 +470,7 @@ int64_t mpv_client_id(mpv_handle *ctx);
* - out of memory
* - LC_NUMERIC is not set to "C" (see general remarks)
*/
mpv_handle *mpv_create(void);
MPV_EXPORT mpv_handle *mpv_create(void);
/**
* Initialize an uninitialized mpv instance. If the mpv instance is already
@@ -487,7 +492,7 @@ mpv_handle *mpv_create(void);
*
* @return error code
*/
int mpv_initialize(mpv_handle *ctx);
MPV_EXPORT int mpv_initialize(mpv_handle *ctx);
/**
* Disconnect and destroy the mpv_handle. ctx will be deallocated with this
@@ -499,27 +504,7 @@ int mpv_initialize(mpv_handle *ctx);
* be sent MPV_EVENT_SHUTDOWN. This function may block until these clients
* have responded to the shutdown event, and the core is finally destroyed.
*/
void mpv_destroy(mpv_handle *ctx);
#if MPV_ENABLE_DEPRECATED
/**
* @deprecated use mpv_destroy(), which has exactly the same semantics (the
* deprecation is a mere rename)
*
* Since mpv client API version 1.29:
* If the last mpv_handle is detached, the core player is destroyed. In
* addition, if there are only weak mpv_handles (such as created by
* mpv_create_weak_client() or internal scripts), these mpv_handles will
* be sent MPV_EVENT_SHUTDOWN. This function may block until these clients
* have responded to the shutdown event, and the core is finally destroyed.
*
* Before mpv client API version 1.29:
* This left the player running. If you want to be sure that the
* player is terminated, send a "quit" command, and wait until the
* MPV_EVENT_SHUTDOWN event is received, or use mpv_terminate_destroy().
*/
void mpv_detach_destroy(mpv_handle *ctx);
#endif
MPV_EXPORT void mpv_destroy(mpv_handle *ctx);
/**
* Similar to mpv_destroy(), but brings the player and all clients down
@@ -546,7 +531,7 @@ void mpv_detach_destroy(mpv_handle *ctx);
* this function will merely send a quit command and then call
* mpv_destroy(), without waiting for the actual shutdown.
*/
void mpv_terminate_destroy(mpv_handle *ctx);
MPV_EXPORT void mpv_terminate_destroy(mpv_handle *ctx);
/**
* Create a new client handle connected to the same player core as ctx. This
@@ -572,7 +557,7 @@ void mpv_terminate_destroy(mpv_handle *ctx);
* If NULL, an arbitrary name is automatically chosen.
* @return a new handle, or NULL on error
*/
mpv_handle *mpv_create_client(mpv_handle *ctx, const char *name);
MPV_EXPORT mpv_handle *mpv_create_client(mpv_handle *ctx, const char *name);
/**
* This is the same as mpv_create_client(), but the created mpv_handle is
@@ -586,7 +571,7 @@ mpv_handle *mpv_create_client(mpv_handle *ctx, const char *name);
* mpv_terminate_destroy() _and_ mpv_destroy() for the last non-weak
* mpv_handle will block until all weak mpv_handles are destroyed.
*/
mpv_handle *mpv_create_weak_client(mpv_handle *ctx, const char *name);
MPV_EXPORT mpv_handle *mpv_create_weak_client(mpv_handle *ctx, const char *name);
/**
* Load a config file. This loads and parses the file, and sets every entry in
@@ -606,44 +591,7 @@ mpv_handle *mpv_create_weak_client(mpv_handle *ctx, const char *name);
* @param filename absolute path to the config file on the local filesystem
* @return error code
*/
int mpv_load_config_file(mpv_handle *ctx, const char *filename);
#if MPV_ENABLE_DEPRECATED
/**
* This does nothing since mpv 0.23.0 (API version 1.24). Below is the
* description of the old behavior.
*
* Stop the playback thread. This means the core will stop doing anything, and
* only run and answer to client API requests. This is sometimes useful; for
* example, no new frame will be queued to the video output, so doing requests
* which have to wait on the video output can run instantly.
*
* Suspension is reentrant and recursive for convenience. Any thread can call
* the suspend function multiple times, and the playback thread will remain
* suspended until the last thread resumes it. Note that during suspension, all
* clients still have concurrent access to the core, which is serialized through
* a single mutex.
*
* Call mpv_resume() to resume the playback thread. You must call mpv_resume()
* for each mpv_suspend() call. Calling mpv_resume() more often than
* mpv_suspend() is not allowed.
*
* Calling this on an uninitialized player (see mpv_create()) will deadlock.
*
* @deprecated This function, as well as mpv_resume(), are deprecated, and
* will stop doing anything soon. Their semantics were never
* well-defined, and their usefulness is extremely limited. The
* calls will remain stubs in order to keep ABI compatibility.
*/
void mpv_suspend(mpv_handle *ctx);
/**
* See mpv_suspend().
*/
void mpv_resume(mpv_handle *ctx);
#endif
MPV_EXPORT int mpv_load_config_file(mpv_handle *ctx, const char *filename);
/**
* Return the internal time in microseconds. This has an arbitrary start offset,
@@ -659,7 +607,7 @@ void mpv_resume(mpv_handle *ctx);
*
* Safe to be called from mpv render API threads.
*/
int64_t mpv_get_time_us(mpv_handle *ctx);
MPV_EXPORT int64_t mpv_get_time_us(mpv_handle *ctx);
/**
* Data format for options and properties. The API functions to get/set
@@ -893,7 +841,7 @@ typedef struct mpv_byte_array {
* be called. (This is just a clarification that there's no danger of anything
* strange happening in these cases.)
*/
void mpv_free_node_contents(mpv_node *node);
MPV_EXPORT void mpv_free_node_contents(mpv_node *node);
/**
* Set an option. Note that you can't normally set options during runtime. It
@@ -908,36 +856,19 @@ void mpv_free_node_contents(mpv_node *node);
* Starting with mpv version 0.21.0 (version 1.23) most options can be set
* with mpv_set_property() (and related functions), and even before
* mpv_initialize(). In some obscure corner cases, using this function
* to set options might still be required (see below, and also section
* "Inconsistencies between options and properties" on the manpage). Once
* to set options might still be required (see
* "Inconsistencies between options and properties" in the manpage). Once
* these are resolved, the option setting functions might be fully
* deprecated.
*
* The following options still need to be set either _before_
* mpv_initialize() with mpv_set_property() (or related functions), or
* with mpv_set_option() (or related functions) at any time:
* - options shadowed by deprecated properties:
* - demuxer (property deprecated in 0.21.0)
* - idle (property deprecated in 0.21.0)
* - fps (property deprecated in 0.21.0)
* - cache (property deprecated in 0.21.0)
* - length (property deprecated in 0.10.0)
* - audio-samplerate (property deprecated in 0.10.0)
* - audio-channels (property deprecated in 0.10.0)
* - audio-format (property deprecated in 0.10.0)
* - deprecated options shadowed by properties:
* - chapter (option deprecated in 0.21.0)
* - playlist-pos (option deprecated in 0.21.0)
* The deprecated properties were removed in mpv 0.23.0.
*
* @param name Option name. This is the same as on the mpv command line, but
* without the leading "--".
* @param format see enum mpv_format.
* @param[in] data Option value (according to the format).
* @return error code
*/
int mpv_set_option(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
MPV_EXPORT int mpv_set_option(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
/**
* Convenience function to set an option to a string value. This is like
@@ -945,7 +876,7 @@ int mpv_set_option(mpv_handle *ctx, const char *name, mpv_format format,
*
* @return error code
*/
int mpv_set_option_string(mpv_handle *ctx, const char *name, const char *data);
MPV_EXPORT int mpv_set_option_string(mpv_handle *ctx, const char *name, const char *data);
/**
* Send a command to the player. Commands are the same as those used in
@@ -961,7 +892,7 @@ int mpv_set_option_string(mpv_handle *ctx, const char *name, const char *data);
* is the command, and the following items are arguments.
* @return error code
*/
int mpv_command(mpv_handle *ctx, const char **args);
MPV_EXPORT int mpv_command(mpv_handle *ctx, const char **args);
/**
* Same as mpv_command(), but allows passing structured data in any format.
@@ -997,7 +928,7 @@ int mpv_command(mpv_handle *ctx, const char **args);
* Not many commands actually use this at all.
* @return error code (the result parameter is not set on error)
*/
int mpv_command_node(mpv_handle *ctx, mpv_node *args, mpv_node *result);
MPV_EXPORT int mpv_command_node(mpv_handle *ctx, mpv_node *args, mpv_node *result);
/**
* This is essentially identical to mpv_command() but it also returns a result.
@@ -1013,7 +944,7 @@ int mpv_command_node(mpv_handle *ctx, mpv_node *args, mpv_node *result);
* Not many commands actually use this at all.
* @return error code (the result parameter is not set on error)
*/
int mpv_command_ret(mpv_handle *ctx, const char **args, mpv_node *result);
MPV_EXPORT int mpv_command_ret(mpv_handle *ctx, const char **args, mpv_node *result);
/**
* Same as mpv_command, but use input.conf parsing for splitting arguments.
@@ -1022,7 +953,7 @@ int mpv_command_ret(mpv_handle *ctx, const char **args, mpv_node *result);
*
* This also has OSD and string expansion enabled by default.
*/
int mpv_command_string(mpv_handle *ctx, const char *args);
MPV_EXPORT int mpv_command_string(mpv_handle *ctx, const char *args);
/**
* Same as mpv_command, but run the command asynchronously.
@@ -1044,8 +975,8 @@ int mpv_command_string(mpv_handle *ctx, const char *args);
* @param args NULL-terminated list of strings (see mpv_command())
* @return error code (if parsing or queuing the command fails)
*/
int mpv_command_async(mpv_handle *ctx, uint64_t reply_userdata,
const char **args);
MPV_EXPORT int mpv_command_async(mpv_handle *ctx, uint64_t reply_userdata,
const char **args);
/**
* Same as mpv_command_node(), but run it asynchronously. Basically, this
@@ -1061,8 +992,8 @@ int mpv_command_async(mpv_handle *ctx, uint64_t reply_userdata,
* @param args as in mpv_command_node()
* @return error code (if parsing or queuing the command fails)
*/
int mpv_command_node_async(mpv_handle *ctx, uint64_t reply_userdata,
mpv_node *args);
MPV_EXPORT int mpv_command_node_async(mpv_handle *ctx, uint64_t reply_userdata,
mpv_node *args);
/**
* Signal to all async requests with the matching ID to abort. This affects
@@ -1094,7 +1025,7 @@ int mpv_command_node_async(mpv_handle *ctx, uint64_t reply_userdata,
*
* @param reply_userdata ID of the request to be aborted (see above)
*/
void mpv_abort_async_command(mpv_handle *ctx, uint64_t reply_userdata);
MPV_EXPORT void mpv_abort_async_command(mpv_handle *ctx, uint64_t reply_userdata);
/**
* Set a property to a given value. Properties are essentially variables which
@@ -1127,15 +1058,15 @@ void mpv_abort_async_command(mpv_handle *ctx, uint64_t reply_userdata);
* @param[in] data Option value.
* @return error code
*/
int mpv_set_property(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
MPV_EXPORT int mpv_set_property(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
/**
* Convenience function to set a property to a string value.
*
* This is like calling mpv_set_property() with MPV_FORMAT_STRING.
*/
int mpv_set_property_string(mpv_handle *ctx, const char *name, const char *data);
MPV_EXPORT int mpv_set_property_string(mpv_handle *ctx, const char *name, const char *data);
/**
* Set a property asynchronously. You will receive the result of the operation
@@ -1152,8 +1083,8 @@ int mpv_set_property_string(mpv_handle *ctx, const char *name, const char *data)
* will never be modified by the client API.
* @return error code if sending the request failed
*/
int mpv_set_property_async(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, mpv_format format, void *data);
MPV_EXPORT int mpv_set_property_async(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, mpv_format format, void *data);
/**
* Read the value of the given property.
@@ -1173,8 +1104,8 @@ int mpv_set_property_async(mpv_handle *ctx, uint64_t reply_userdata,
* mpv_free_node_contents() (MPV_FORMAT_NODE).
* @return error code
*/
int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
MPV_EXPORT int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format,
void *data);
/**
* Return the value of the property with the given name as string. This is
@@ -1189,7 +1120,7 @@ int mpv_get_property(mpv_handle *ctx, const char *name, mpv_format format,
* @return Property value, or NULL if the property can't be retrieved. Free
* the string with mpv_free().
*/
char *mpv_get_property_string(mpv_handle *ctx, const char *name);
MPV_EXPORT char *mpv_get_property_string(mpv_handle *ctx, const char *name);
/**
* Return the property as "OSD" formatted string. This is the same as
@@ -1198,7 +1129,7 @@ char *mpv_get_property_string(mpv_handle *ctx, const char *name);
* @return Property value, or NULL if the property can't be retrieved. Free
* the string with mpv_free().
*/
char *mpv_get_property_osd_string(mpv_handle *ctx, const char *name);
MPV_EXPORT char *mpv_get_property_osd_string(mpv_handle *ctx, const char *name);
/**
* Get a property asynchronously. You will receive the result of the operation
@@ -1212,8 +1143,8 @@ char *mpv_get_property_osd_string(mpv_handle *ctx, const char *name);
* @param format see enum mpv_format.
* @return error code if sending the request failed
*/
int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, mpv_format format);
MPV_EXPORT int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, mpv_format format);
/**
* Get a notification whenever the given property changes. You will receive
@@ -1270,8 +1201,8 @@ int mpv_get_property_async(mpv_handle *ctx, uint64_t reply_userdata,
* from the change events.
* @return error code (usually fails only on OOM or unsupported format)
*/
int mpv_observe_property(mpv_handle *mpv, uint64_t reply_userdata,
const char *name, mpv_format format);
MPV_EXPORT int mpv_observe_property(mpv_handle *mpv, uint64_t reply_userdata,
const char *name, mpv_format format);
/**
* Undo mpv_observe_property(). This will remove all observed properties for
@@ -1283,7 +1214,7 @@ int mpv_observe_property(mpv_handle *mpv, uint64_t reply_userdata,
* @return negative value is an error code, >=0 is number of removed properties
* on success (includes the case when 0 were removed)
*/
int mpv_unobserve_property(mpv_handle *mpv, uint64_t registered_reply_userdata);
MPV_EXPORT int mpv_unobserve_property(mpv_handle *mpv, uint64_t registered_reply_userdata);
typedef enum mpv_event_id {
/**
@@ -1332,24 +1263,6 @@ typedef enum mpv_event_id {
*/
MPV_EVENT_FILE_LOADED = 8,
#if MPV_ENABLE_DEPRECATED
/**
* The list of video/audio/subtitle tracks was changed. (E.g. a new track
* was found. This doesn't necessarily indicate a track switch; for this,
* MPV_EVENT_TRACK_SWITCHED is used.)
*
* @deprecated This is equivalent to using mpv_observe_property() on the
* "track-list" property. The event is redundant, and might
* be removed in the far future.
*/
MPV_EVENT_TRACKS_CHANGED = 9,
/**
* A video/audio/subtitle track was switched on or off.
*
* @deprecated This is equivalent to using mpv_observe_property() on the
* "vid", "aid", and "sid" properties. The event is redundant,
* and might be removed in the far future.
*/
MPV_EVENT_TRACK_SWITCHED = 10,
/**
* Idle mode was entered. In this mode, no file is played, and the playback
* core waits for new commands. (The command line player normally quits
@@ -1363,35 +1276,6 @@ typedef enum mpv_event_id {
* start of the program), while the property behaves correctly.
*/
MPV_EVENT_IDLE = 11,
/**
* Playback was paused. This indicates the user pause state.
*
* The user pause state is the state the user requested (changed with the
* "pause" property). There is an internal pause state too, which is entered
* if e.g. the network is too slow (the "core-idle" property generally
* indicates whether the core is playing or waiting).
*
* This event is sent whenever any pause states change, not only the user
* state. You might get multiple events in a row while these states change
* independently. But the event ID sent always indicates the user pause
* state.
*
* If you don't want to deal with this, use mpv_observe_property() on the
* "pause" property and ignore MPV_EVENT_PAUSE/UNPAUSE. Likewise, the
* "core-idle" property tells you whether video is actually playing or not.
*
* @deprecated The event is redundant with mpv_observe_property() as
* mentioned above, and might be removed in the far future.
*/
MPV_EVENT_PAUSE = 12,
/**
* Playback was unpaused. See MPV_EVENT_PAUSE for not so obvious details.
*
* @deprecated The event is redundant with mpv_observe_property() as
* explained in the MPV_EVENT_PAUSE comments, and might be
* removed in the far future.
*/
MPV_EVENT_UNPAUSE = 13,
/**
* Sent every time after a video frame is displayed. Note that currently,
* this will be sent in lower frequency if there is no video, or playback
@@ -1402,15 +1286,6 @@ typedef enum mpv_event_id {
* (such as "playback-time").
*/
MPV_EVENT_TICK = 14,
/**
* @deprecated This was used internally with the internal "script_dispatch"
* command to dispatch keyboard and mouse input for the OSC.
* It was never useful in general and has been completely
* replaced with "script-binding".
* This event never happens anymore, and is included in this
* header only for compatibility.
*/
MPV_EVENT_SCRIPT_INPUT_DISPATCH = 15,
#endif
/**
* Triggered by the script-message input command. The command uses the
@@ -1436,18 +1311,6 @@ typedef enum mpv_event_id {
* because there is no such thing as audio output embedding.
*/
MPV_EVENT_AUDIO_RECONFIG = 18,
#if MPV_ENABLE_DEPRECATED
/**
* Happens when metadata (like file tags) is possibly updated. (It's left
* unspecified whether this happens on file start or only when it changes
* within a file.)
*
* @deprecated This is equivalent to using mpv_observe_property() on the
* "metadata" property. The event is redundant, and might
* be removed in the far future.
*/
MPV_EVENT_METADATA_UPDATE = 19,
#endif
/**
* Happens when a seek was initiated. Playback stops. Usually it will
* resume with MPV_EVENT_PLAYBACK_RESTART as soon as the seek is finished.
@@ -1465,16 +1328,6 @@ typedef enum mpv_event_id {
* See also mpv_event and mpv_event_property.
*/
MPV_EVENT_PROPERTY_CHANGE = 22,
#if MPV_ENABLE_DEPRECATED
/**
* Happens when the current chapter changes.
*
* @deprecated This is equivalent to using mpv_observe_property() on the
* "chapter" property. The event is redundant, and might
* be removed in the far future.
*/
MPV_EVENT_CHAPTER_CHANGE = 23,
#endif
/**
* Happens if the internal per-mpv_handle ringbuffer overflows, and at
* least 1 event had to be dropped. This can happen if the client doesn't
@@ -1509,7 +1362,7 @@ typedef enum mpv_event_id {
* The string is completely static, i.e. doesn't need to be deallocated,
* and is valid forever.
*/
const char *mpv_event_name(mpv_event_id event);
MPV_EXPORT const char *mpv_event_name(mpv_event_id event);
typedef struct mpv_event_property {
/**
@@ -1627,12 +1480,11 @@ typedef struct mpv_event_start_file {
typedef struct mpv_event_end_file {
/**
* Corresponds to the values in enum mpv_end_file_reason (the "int" type
* will be replaced with mpv_end_file_reason on the next ABI bump).
* Corresponds to the values in enum mpv_end_file_reason.
*
* Unknown values should be treated as unknown.
*/
int reason;
mpv_end_file_reason reason;
/**
* If reason==MPV_END_FILE_REASON_ERROR, this contains a mpv error code
* (one of MPV_ERROR_...) giving an approximate reason why playback
@@ -1670,15 +1522,6 @@ typedef struct mpv_event_end_file {
int playlist_insert_num_entries;
} mpv_event_end_file;
#if MPV_ENABLE_DEPRECATED
/** @deprecated see MPV_EVENT_SCRIPT_INPUT_DISPATCH for remarks
*/
typedef struct mpv_event_script_input_dispatch {
int arg0;
const char *type;
} mpv_event_script_input_dispatch;
#endif
typedef struct mpv_event_client_message {
/**
* Arbitrary arguments chosen by the sender of the message. If num_args > 0,
@@ -1782,7 +1625,7 @@ typedef struct mpv_event {
* prejudice of the C version of const).
* @return error code (MPV_ERROR_NOMEM only, if at all)
*/
int mpv_event_to_node(mpv_node *dst, mpv_event *src);
MPV_EXPORT int mpv_event_to_node(mpv_node *dst, mpv_event *src);
/**
* Enable or disable the given event.
@@ -1798,7 +1641,7 @@ int mpv_event_to_node(mpv_node *dst, mpv_event *src);
* @param enable 1 to enable receiving this event, 0 to disable it.
* @return error code
*/
int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable);
MPV_EXPORT int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable);
/**
* Enable or disable receiving of log messages. These are the messages the
@@ -1814,7 +1657,7 @@ int mpv_request_event(mpv_handle *ctx, mpv_event_id event, int enable);
* Also see mpv_log_level.
* @return error code
*/
int mpv_request_log_messages(mpv_handle *ctx, const char *min_level);
MPV_EXPORT int mpv_request_log_messages(mpv_handle *ctx, const char *min_level);
/**
* Wait for the next event, or until the timeout expires, or if another thread
@@ -1847,7 +1690,7 @@ int mpv_request_log_messages(mpv_handle *ctx, const char *min_level);
* released by the API on the next mpv_wait_event() call, or when the
* context is destroyed. The return value is never NULL.
*/
mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout);
MPV_EXPORT mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout);
/**
* Interrupt the current mpv_wait_event() call. This will wake up the thread
@@ -1862,7 +1705,7 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout);
*
* Safe to be called from mpv render API threads.
*/
void mpv_wakeup(mpv_handle *ctx);
MPV_EXPORT void mpv_wakeup(mpv_handle *ctx);
/**
* Set a custom function that should be called when there are new events. Use
@@ -1900,7 +1743,7 @@ void mpv_wakeup(mpv_handle *ctx);
* @param cb function that should be called if a wakeup is required
* @param d arbitrary userdata passed to cb
*/
void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d);
MPV_EXPORT void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d);
/**
* Block until all asynchronous requests are done. This affects functions like
@@ -1914,7 +1757,7 @@ void mpv_set_wakeup_callback(mpv_handle *ctx, void (*cb)(void *d), void *d);
* In case you called mpv_suspend() before, this will also forcibly reset the
* suspend counter of the given handle.
*/
void mpv_wait_async_requests(mpv_handle *ctx);
MPV_EXPORT void mpv_wait_async_requests(mpv_handle *ctx);
/**
* A hook is like a synchronous event that blocks the player. You register
@@ -1951,8 +1794,8 @@ void mpv_wait_async_requests(mpv_handle *ctx);
* @param priority See remarks above. Use 0 as a neutral default.
* @return error code (usually fails only on OOM)
*/
int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, int priority);
MPV_EXPORT int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
const char *name, int priority);
/**
* Respond to a MPV_EVENT_HOOK event. You must call this after you have handled
@@ -1970,7 +1813,7 @@ int mpv_hook_add(mpv_handle *ctx, uint64_t reply_userdata,
* corresponding MPV_EVENT_HOOK.
* @return error code
*/
int mpv_hook_continue(mpv_handle *ctx, uint64_t id);
MPV_EXPORT int mpv_hook_continue(mpv_handle *ctx, uint64_t id);
#if MPV_ENABLE_DEPRECATED
@@ -2032,31 +1875,7 @@ int mpv_hook_continue(mpv_handle *ctx, uint64_t id);
* @return A UNIX FD of the read end of the wakeup pipe, or -1 on error.
* On MS Windows/MinGW, this will always return -1.
*/
int mpv_get_wakeup_pipe(mpv_handle *ctx);
/**
* @deprecated use render.h
*/
typedef enum mpv_sub_api {
/**
* For using mpv's OpenGL renderer on an external OpenGL context.
* mpv_get_sub_api(MPV_SUB_API_OPENGL_CB) returns mpv_opengl_cb_context*.
* This context can be used with mpv_opengl_cb_* functions.
* Will return NULL if unavailable (if OpenGL support was not compiled in).
* See opengl_cb.h for details.
*
* @deprecated use render.h
*/
MPV_SUB_API_OPENGL_CB = 1
} mpv_sub_api;
/**
* This is used for additional APIs that are not strictly part of the core API.
* See the individual mpv_sub_api member values.
*
* @deprecated use render.h
*/
void *mpv_get_sub_api(mpv_handle *ctx, mpv_sub_api sub_api);
MPV_EXPORT int mpv_get_wakeup_pipe(mpv_handle *ctx);
#endif
Loaded 100 of 296 files, more files were not shown because too many files have changed in this diff. Show more