From 53f2619dbd740b71bdd4277f096d077ffb8d571b Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 25 Sep 2024 23:47:16 -0400 Subject: [PATCH 01/21] options: force --ab-loop-count and --loop-file notification Since f411f3145ba2f6eebc658917d0879d5e573bbdf0, these properties no longer change with each loop. This however caused a regression on the behavior of resetting loop count by resetting these properties. Previously, after the loop count is decreased, it is possible to reset these properties back their original values and thus reset the remaining loop count. Currently, because setting properties has no effect if the new value is the same as the existing value (which no longer changes), resetting these properties does nothing, and remaining-*-loops (which are read-only) remain unchanged. There is no way to reset them other than temporarily setting them to a different value, which is awkward. Fortunately, this can be fixed by marking these properties as force_update, which always notifies changes when being set. --- options/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/options/options.c b/options/options.c index aaf7748d8d29b..72b9802edd298 100644 --- a/options/options.c +++ b/options/options.c @@ -603,7 +603,7 @@ static const m_option_t mp_opts[] = { {"ab-loop-a", OPT_TIME(ab_loop[0]), .flags = M_OPT_ALLOW_NO}, {"ab-loop-b", OPT_TIME(ab_loop[1]), .flags = M_OPT_ALLOW_NO}, {"ab-loop-count", OPT_CHOICE(ab_loop_count, {"inf", -1}), - M_RANGE(0, INT_MAX)}, + M_RANGE(0, INT_MAX), .force_update = true}, {"playlist-start", OPT_CHOICE(playlist_pos, {"auto", -1}, {"no", -1}), M_RANGE(0, INT_MAX)}, @@ -821,7 +821,7 @@ static const m_option_t mp_opts[] = { {"no", 0}, {"inf", -1}, {"yes", -1}), - M_RANGE(0, 10000)}, + M_RANGE(0, 10000), .force_update = true}, {"loop", OPT_ALIAS("loop-file")}, {"resume-playback", OPT_BOOL(position_resume)}, From c365e2f7b17e6a890827802e063b823bf6e4385f Mon Sep 17 00:00:00 2001 From: Andreas Klauer Date: Fri, 27 Sep 2024 19:35:37 +0200 Subject: [PATCH 02/21] misc/random: seed using libavutil/random_seed When starting multiple processes of `mpv --shuffle` in parallel, sometimes the random seed happens to be identical, so files are played in the same random order. mp_rand_seed(0) now uses a random seed provided by libavutil, and only falls back to time in case of failure. --- misc/random.c | 13 +++++++++++++ misc/random.h | 2 +- osdep/timer.c | 2 -- player/main.c | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/misc/random.c b/misc/random.c index d40474bee612f..83cf0a727ed21 100644 --- a/misc/random.c +++ b/misc/random.c @@ -20,7 +20,10 @@ #include +#include + #include "osdep/threads.h" +#include "osdep/timer.h" #include "random.h" static uint64_t state[4]; @@ -44,6 +47,16 @@ void mp_rand_seed(uint64_t seed) #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION seed = 42; #endif + + if (seed == 0) { + uint8_t buf[sizeof(seed)]; + if (av_random_bytes(buf, sizeof(buf)) < 0) { + seed = mp_raw_time_ns(); + } else { + memcpy(&seed, buf, sizeof(seed)); + } + } + mp_mutex_lock(&state_mutex); state[0] = seed; for (int i = 1; i < 4; i++) diff --git a/misc/random.h b/misc/random.h index dae66a0939e83..23b4f82399fe1 100644 --- a/misc/random.h +++ b/misc/random.h @@ -24,7 +24,7 @@ /* * Initialize the pseudo-random number generator's state with - * the given 64-bit seed. + * the given 64-bit seed. If the seed is 0, it is randomized. */ void mp_rand_seed(uint64_t seed); diff --git a/osdep/timer.c b/osdep/timer.c index 86cfaebf8891e..c0aac8972b735 100644 --- a/osdep/timer.c +++ b/osdep/timer.c @@ -22,7 +22,6 @@ #include "common/common.h" #include "common/msg.h" -#include "misc/random.h" #include "threads.h" #include "timer.h" @@ -32,7 +31,6 @@ static mp_once timer_init_once = MP_STATIC_ONCE_INITIALIZER; static void do_timer_init(void) { mp_raw_time_init(); - mp_rand_seed(mp_raw_time_ns()); raw_time_offset = mp_raw_time_ns(); assert(raw_time_offset > 0); } diff --git a/player/main.c b/player/main.c index 21478a6e5f9ba..8ed0f4d94df34 100644 --- a/player/main.c +++ b/player/main.c @@ -30,6 +30,7 @@ #include "mpv_talloc.h" #include "misc/dispatch.h" +#include "misc/random.h" #include "misc/thread_pool.h" #include "osdep/io.h" #include "osdep/terminal.h" @@ -263,6 +264,7 @@ struct MPContext *mp_create(void) talloc_enable_leak_report(); mp_time_init(); + mp_rand_seed(0); struct MPContext *mpctx = talloc(NULL, MPContext); *mpctx = (struct MPContext){ From c3d9243a3eadf3d7eecdb11c8c98e5d88862ab12 Mon Sep 17 00:00:00 2001 From: Misaki Kasumi Date: Fri, 27 Sep 2024 11:01:03 +0800 Subject: [PATCH 03/21] ao_coreaudio: fix nan in ca_get_device_latency_ns --- audio/out/ao_coreaudio_utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 78cdcad39315b..f06d3fae26852 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -442,12 +442,14 @@ int64_t ca_get_device_latency_ns(struct ao *ao, AudioDeviceID device) } } - double sample_rate = ao->samplerate; + double sample_rate; OSStatus err = CA_GET_O(device, kAudioDevicePropertyNominalSampleRate, &sample_rate); CHECK_CA_WARN("cannot get device sample rate, falling back to AO sample rate!"); if (err == noErr) { MP_VERBOSE(ao, "Device sample rate: %f\n", sample_rate); + } else { + sample_rate = ao->samplerate; } return MP_TIME_S_TO_NS(latency_frames / sample_rate); From 2c2755992daa3f214f571d6b13df2d26d098f0e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Wed, 25 Sep 2024 01:50:02 +0200 Subject: [PATCH 04/21] bstr: use vsnprintf with a proper size of 0 instead of a 1-sized buffer There is no need for that, use of 0 size is well defined. --- misc/bstr.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/misc/bstr.c b/misc/bstr.c index baf736058ea89..4a8bf16ac11e6 100644 --- a/misc/bstr.c +++ b/misc/bstr.c @@ -393,10 +393,7 @@ void bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, va_copy(copy, ap); size_t avail = talloc_get_size(s->start) - s->len; char *dest = s->start ? s->start + s->len : NULL; - char c; - if (avail < 1) - dest = &c; - size = vsnprintf(dest, MPMAX(avail, 1), fmt, copy); + size = vsnprintf(dest, avail, fmt, copy); va_end(copy); if (size < 0) From 96006fa97bd41c593279730e29ebfa932088f437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Wed, 25 Sep 2024 02:00:03 +0200 Subject: [PATCH 05/21] bstr: don't abort on format error in bstr_xappend_vasprintf Most of the time it is recoverable error, and it makes no sense to abort here. --- misc/bstr.c | 12 +++++++----- misc/bstr.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/misc/bstr.c b/misc/bstr.c index 4a8bf16ac11e6..120abef8fe16b 100644 --- a/misc/bstr.c +++ b/misc/bstr.c @@ -376,17 +376,18 @@ void bstr_xappend(void *talloc_ctx, bstr *s, bstr append) s->start[s->len] = '\0'; } -void bstr_xappend_asprintf(void *talloc_ctx, bstr *s, const char *fmt, ...) +int bstr_xappend_asprintf(void *talloc_ctx, bstr *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - bstr_xappend_vasprintf(talloc_ctx, s, fmt, ap); + int ret = bstr_xappend_vasprintf(talloc_ctx, s, fmt, ap); va_end(ap); + return ret; } // Exactly as bstr_xappend(), but with a formatted string. -void bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, - va_list ap) +int bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, + va_list ap) { int size; va_list copy; @@ -397,13 +398,14 @@ void bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, va_end(copy); if (size < 0) - abort(); + return size; if (avail < 1 || size + 1 > avail) { resize_append(talloc_ctx, s, size + 1); vsnprintf(s->start + s->len, size + 1, fmt, ap); } s->len += size; + return size; } bool bstr_case_startswith(struct bstr s, struct bstr prefix) diff --git a/misc/bstr.h b/misc/bstr.h index 5cc124ec36f79..d279a3a088526 100644 --- a/misc/bstr.h +++ b/misc/bstr.h @@ -136,9 +136,9 @@ static inline struct bstr bstr_getline(struct bstr str, struct bstr *rest) struct bstr bstr_strip_linebreaks(struct bstr str); void bstr_xappend(void *talloc_ctx, bstr *s, bstr append); -void bstr_xappend_asprintf(void *talloc_ctx, bstr *s, const char *fmt, ...) +int bstr_xappend_asprintf(void *talloc_ctx, bstr *s, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, va_list va) +int bstr_xappend_vasprintf(void *talloc_ctx, bstr *s, const char *fmt, va_list va) PRINTF_ATTRIBUTE(3, 0); // If s starts/ends with prefix, return true and return the rest of the string From 4c19df1ded597985c8e7f7ba2613481b2f7c3e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Thu, 26 Sep 2024 22:45:07 +0200 Subject: [PATCH 06/21] msg: print format string on format errors --- common/msg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/msg.c b/common/msg.c index 792d233892c69..cbb06e9e97a8a 100644 --- a/common/msg.c +++ b/common/msg.c @@ -570,7 +570,10 @@ void mp_msg_va(struct mp_log *log, int lev, const char *format, va_list va) bstr_xappend(root, &root->buffer, log->partial[lev]); log->partial[lev].len = 0; - bstr_xappend_vasprintf(root, &root->buffer, format, va); + if (bstr_xappend_vasprintf(root, &root->buffer, format, va) < 0) { + bstr_xappend(root, &root->buffer, bstr0("format error: ")); + bstr_xappend(root, &root->buffer, bstr0(format)); + } // Remember last status message and restore it to ensure that it is // always displayed From 151fa748060466f3137d71148285bdb69e076f41 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Sun, 29 Sep 2024 14:56:15 -0400 Subject: [PATCH 07/21] player/external_files: fix null deref when cover-art-whitelist is empty This can happen when using --cover-art-whitelist-clr. Fixes: d384a6b79303ef21b7330555e968a99d59a7c5b0 --- player/external_files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player/external_files.c b/player/external_files.c index 996344405f0bf..82b39464a12e9 100644 --- a/player/external_files.c +++ b/player/external_files.c @@ -47,7 +47,7 @@ static int test_ext(MPOpts *opts, bstr ext) static int test_cover_filename(bstr fname, char **cover_files) { - for (int n = 0; cover_files[n]; n++) { + for (int n = 0; cover_files && cover_files[n]; n++) { if (bstrcasecmp(bstr0(cover_files[n]), fname) == 0) { size_t size = n; while (cover_files[++size]); From ffb40ab95869805a0de216f07d1d9af46e0e90f0 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:01:51 -0400 Subject: [PATCH 08/21] video/decode/vd_lavc: fix null deref when hwdec is empty This can happen when using --hwdec-clr. Fixes: 9ff8c9e78020bcda19f3435ed88ebd6a302d2cc2 --- video/decode/vd_lavc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 62f0835d54111..cf65cd0ff0eba 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -481,7 +481,7 @@ static void select_and_set_hwdec(struct mp_filter *vd) add_all_hwdec_methods(&hwdecs, &num_hwdecs); char **hwdec_api = ctx->opts->hwdec_api; - for (int i = 0; hwdec_api[i]; i++) { + for (int i = 0; hwdec_api && hwdec_api[i]; i++) { bstr opt = bstr0(hwdec_api[i]); bool hwdec_requested = !bstr_equals0(opt, "no"); From 6ca3752f758c1e5452f90348993fc2b2653aaa2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Mon, 23 Sep 2024 16:24:57 +0200 Subject: [PATCH 09/21] vf_d3d11vpp: add NVIDIA RTX Video HDR support Fixes: #13352 --- DOCS/interface-changes/nvidia-true-hdr.txt | 1 + DOCS/man/vf.rst | 2 ++ video/filter/vf_d3d11vpp.c | 39 +++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 DOCS/interface-changes/nvidia-true-hdr.txt diff --git a/DOCS/interface-changes/nvidia-true-hdr.txt b/DOCS/interface-changes/nvidia-true-hdr.txt new file mode 100644 index 0000000000000..cdd0e406283e8 --- /dev/null +++ b/DOCS/interface-changes/nvidia-true-hdr.txt @@ -0,0 +1 @@ +add `--vf=d3d11vpp=nvidia-true-hdr` diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst index 150b180f3d127..0331c7e15175a 100644 --- a/DOCS/man/vf.rst +++ b/DOCS/man/vf.rst @@ -722,6 +722,8 @@ Available mpv-only filters are: which algorithm is actually selected. ``none`` always falls back. On most if not all hardware, this option will probably do nothing, because a video processor usually supports all modes or none. + ``nvidia-true-hdr`` + Enable NVIDIA RTX Video HDR processing. ``fingerprint=...`` Compute video frame fingerprints and provide them as metadata. Actually, it diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c index 2cec1f2645acd..4cda42adb2e15 100644 --- a/video/filter/vf_d3d11vpp.c +++ b/video/filter/vf_d3d11vpp.c @@ -43,6 +43,12 @@ DEFINE_GUID(NVIDIA_PPE_INTERFACE_GUID, 0xc3, 0xc2, 0x53, 0x75, 0xe6, 0xf7); #endif +#ifndef NVIDIA_TRUE_HDR_INTERFACE_GUID +DEFINE_GUID(NVIDIA_TRUE_HDR_INTERFACE_GUID, + 0xfdd62bb4, 0x620b, 0x4fd7, 0x9a, 0xb3, + 0x1e, 0x59, 0xd0, 0xd5, 0x44, 0xb3); +#endif + #ifndef INTEL_VPE_INTERFACE_GUID DEFINE_GUID(INTEL_VPE_INTERFACE_GUID, 0xedd1d4b9, 0x8659, 0x4cbc, 0xa4, 0xd6, @@ -72,6 +78,7 @@ struct opts { int mode; int field_parity; int format; + bool nvidia_true_hdr; }; struct priv { @@ -142,6 +149,31 @@ static void enable_nvidia_rtx_extension(struct mp_filter *vf) } } +static void enable_nvidia_true_hdr(struct mp_filter *vf) +{ + struct priv *p = vf->priv; + + struct nvidia_ext { + unsigned int version; + unsigned int method; + unsigned int enable : 1; + unsigned int reserved : 31; + } ext = {4, 3, 1}; + + HRESULT hr = ID3D11VideoContext_VideoProcessorSetStreamExtension(p->video_ctx, + p->video_proc, + 0, + &NVIDIA_TRUE_HDR_INTERFACE_GUID, + sizeof(ext), + &ext); + + if (FAILED(hr)) { + MP_WARN(vf, "Failed to enable NVIDIA RTX Video HDR: %s\n", mp_HRESULT_to_str(hr)); + } else { + MP_VERBOSE(vf, "NVIDIA RTX Video HDR enabled\n"); + } +} + static void enable_intel_vsr_extension(struct mp_filter *vf) { struct priv *p = vf->priv; @@ -289,6 +321,9 @@ static int recreate_video_proc(struct mp_filter *vf) break; } + if (p->opts->nvidia_true_hdr) + enable_nvidia_true_hdr(vf); + return 0; fail: destroy_video_proc(vf); @@ -468,7 +503,8 @@ static void vf_d3d11vpp_process(struct mp_filter *vf) p->require_filtering = p->params.hw_subfmt != p->out_params.hw_subfmt || p->params.w != p->out_params.w || - p->params.h != p->out_params.h; + p->params.h != p->out_params.h || + p->opts->nvidia_true_hdr; } if (!mp_refqueue_can_output(p->queue)) @@ -617,6 +653,7 @@ static const m_option_t vf_opts_fields[] = { {"tff", MP_FIELD_PARITY_TFF}, {"bff", MP_FIELD_PARITY_BFF}, {"auto", MP_FIELD_PARITY_AUTO})}, + {"nvidia-true-hdr", OPT_BOOL(nvidia_true_hdr)}, {0} }; From c5aa7d83ac7fc1b4ffbd1e47e6758e21b26c1694 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sun, 29 Sep 2024 13:39:26 -0500 Subject: [PATCH 10/21] wayland_common: fix some stray tabs quite unfortunate --- video/out/wayland_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index cdc5215a5c39d..6f9eb8e5f493c 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1880,14 +1880,14 @@ static void get_gpu_drm_formats(struct vo_wayland_state *wl) // Only check the formats on the first primary plane we find as a crude guess. int index = -1; for (int i = 0; i < res->count_planes; ++i) { - drmModeObjectProperties *props = NULL; - props = drmModeObjectGetProperties(fd, res->planes[i], DRM_MODE_OBJECT_PLANE); + drmModeObjectProperties *props = NULL; + props = drmModeObjectGetProperties(fd, res->planes[i], DRM_MODE_OBJECT_PLANE); if (!props) { MP_VERBOSE(wl, "Unable to get DRM plane properties: %s\n", mp_strerror(errno)); continue; } for (int j = 0; j < props->count_props; ++j) { - drmModePropertyRes *prop = drmModeGetProperty(fd, props->props[j]); + drmModePropertyRes *prop = drmModeGetProperty(fd, props->props[j]); if (!prop) { MP_VERBOSE(wl, "Unable to get DRM plane property: %s\n", mp_strerror(errno)); continue; @@ -1898,7 +1898,7 @@ static void get_gpu_drm_formats(struct vo_wayland_state *wl) index = i; } } - drmModeFreeProperty(prop); + drmModeFreeProperty(prop); if (index > -1) break; } From 99d4dec38f62e0bc1aaf808ca2b95f5fe5764dc3 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sun, 29 Sep 2024 12:19:35 -0500 Subject: [PATCH 11/21] wayland: rename gpu_formats to planar_formats The old name is misleading. We do want these formats, but it is not accurate to call them "gpu formats". Call it "planar" instead so it's more obvious these come from drm primary planes. --- video/out/wayland_common.c | 18 +++++++++--------- video/out/wayland_common.h | 4 ++-- video/out/wldmabuf/ra_wldmabuf.c | 14 +++++++------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 6f9eb8e5f493c..b131c904dad1c 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -212,7 +212,7 @@ static int spawn_cursor(struct vo_wayland_state *wl); static void add_feedback(struct vo_wayland_feedback_pool *fback_pool, struct wp_presentation_feedback *fback); static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *height); -static void get_gpu_drm_formats(struct vo_wayland_state *wl); +static void get_planar_drm_formats(struct vo_wayland_state *wl); static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s); static void guess_focus(struct vo_wayland_state *wl); static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, uint32_t state, bool no_emit); @@ -1406,7 +1406,7 @@ static void tranche_target_device(void *data, memcpy(&wl->target_device_id, id, sizeof(dev_t)); break; } - get_gpu_drm_formats(wl); + get_planar_drm_formats(wl); } } @@ -1828,7 +1828,7 @@ static char **get_displays_spanned(struct vo_wayland_state *wl) return names; } -static void get_gpu_drm_formats(struct vo_wayland_state *wl) +static void get_planar_drm_formats(struct vo_wayland_state *wl) { #if HAVE_DRM drmDevice *device = NULL; @@ -1913,15 +1913,15 @@ static void get_gpu_drm_formats(struct vo_wayland_state *wl) } plane = drmModeGetPlane(fd, res->planes[index]); - wl->num_gpu_formats = plane->count_formats; + wl->num_planar_formats = plane->count_formats; - if (wl->gpu_formats) - talloc_free(wl->gpu_formats); + if (wl->planar_formats) + talloc_free(wl->planar_formats); - wl->gpu_formats = talloc_zero_array(wl, int, wl->num_gpu_formats); - for (int i = 0; i < wl->num_gpu_formats; ++i) { + wl->planar_formats = talloc_zero_array(wl, int, wl->num_planar_formats); + for (int i = 0; i < wl->num_planar_formats; ++i) { MP_DBG(wl, "DRM primary plane supports drm format: %s\n", mp_tag_str(plane->formats[i])); - wl->gpu_formats[i] = plane->formats[i]; + wl->planar_formats[i] = plane->formats[i]; } done: diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 0ea4d8f805e20..4621310625904 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -115,8 +115,8 @@ struct vo_wayland_state { uint32_t compositor_format_size; struct drm_format *compositor_formats; int num_compositor_formats; - uint32_t *gpu_formats; - int num_gpu_formats; + uint32_t *planar_formats; + int num_planar_formats; /* presentation-time */ struct wp_presentation *presentation; diff --git a/video/out/wldmabuf/ra_wldmabuf.c b/video/out/wldmabuf/ra_wldmabuf.c index 39e48726660c3..cd3bcdd35cefb 100644 --- a/video/out/wldmabuf/ra_wldmabuf.c +++ b/video/out/wldmabuf/ra_wldmabuf.c @@ -35,17 +35,17 @@ bool ra_compatible_format(struct ra *ra, int imgfmt, uint32_t drm_format, uint64 struct drm_format *formats = wl->compositor_formats; - // If we were able to make the DRM query, filter out the GPU formats. + // If we were able to make the DRM query, filter out the planar formats. // If not, just assume they all work and hope for the best. - if (wl->gpu_formats) { - bool supported_gpu_format = false; - for (int i = 0; i < wl->num_gpu_formats; i++) { - if (drm_format == wl->gpu_formats[i]) { - supported_gpu_format = true; + if (wl->planar_formats) { + bool supported_planar_format = false; + for (int i = 0; i < wl->num_planar_formats; i++) { + if (drm_format == wl->planar_formats[i]) { + supported_planar_format = true; break; } } - if (!supported_gpu_format) + if (!supported_planar_format) return false; } From 344ce9200da5feadd5b72620eddcc9b3afe905e6 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sun, 29 Sep 2024 12:35:26 -0500 Subject: [PATCH 12/21] ra_wldambuf: don't unconditionally filter out non-planar formats 4d09cde8f92577fc6d8522a0e14db2e238a6c3a8 added this behavior and made the format filtering more aggressive, but it's over correcting. The misunderstanding on my part is that the problem was with modifiers not with formats. There is hardware that do not have any valid modifiers which means certain formats cannot possibly work correctly with vo_dmabuf_wayland (broken colors etc.). Formats on the primary plane do not require modifiers so if it happens to be a planar format, we can accept it and possibly use mpv's autoconverter. If we do get a valid format + modifier pair from the compositor, then we should always accept it regardless if it is planar or not. --- video/out/wldmabuf/ra_wldmabuf.c | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/video/out/wldmabuf/ra_wldmabuf.c b/video/out/wldmabuf/ra_wldmabuf.c index cd3bcdd35cefb..5285738d96a24 100644 --- a/video/out/wldmabuf/ra_wldmabuf.c +++ b/video/out/wldmabuf/ra_wldmabuf.c @@ -15,6 +15,8 @@ * License along with mpv. If not, see . */ +#include + #include "video/out/wayland_common.h" #include "video/out/gpu/ra.h" #include "ra_wldmabuf.h" @@ -34,25 +36,26 @@ bool ra_compatible_format(struct ra *ra, int imgfmt, uint32_t drm_format, uint64 struct vo_wayland_state *wl = p->vo->wl; struct drm_format *formats = wl->compositor_formats; + // Always check if the compositor supports the format. + bool supported_compositor_format = false; + for (int i = 0; i < wl->num_compositor_formats; ++i) { + if (formats[i].format != drm_format || formats[i].modifier == DRM_FORMAT_MOD_INVALID) + continue; + if (modifier == formats[i].modifier) + return true; + supported_compositor_format = true; + } + + if (!supported_compositor_format) + return false; - // If we were able to make the DRM query, filter out the planar formats. - // If not, just assume they all work and hope for the best. + // If the compositor supports the format but there are no valid modifiers, + // see if this is a planar format which can be still be supported. if (wl->planar_formats) { - bool supported_planar_format = false; for (int i = 0; i < wl->num_planar_formats; i++) { - if (drm_format == wl->planar_formats[i]) { - supported_planar_format = true; - break; - } + if (drm_format == wl->planar_formats[i]) + return true; } - if (!supported_planar_format) - return false; - } - - // Always check if the compositor supports the format. - for (int i = 0; i < wl->num_compositor_formats; ++i) { - if (drm_format == formats[i].format && modifier == formats[i].modifier) - return true; } return false; From ce0452fa0dea75c8909270c62225fcfc44541fe1 Mon Sep 17 00:00:00 2001 From: Guido Cella Date: Sun, 29 Sep 2024 22:14:19 +0200 Subject: [PATCH 13/21] zsh-completion: fix completing --screenshot-avif-opts-* The list options --screenshot-avif-opts and --vo-image-opts are completed with an extra 8), e.g. --screenshot-avif-opts-add=8), because *= in screenshot-avif-opts=-:Key/value list (default\: usage=allintra,crf=0,cpu-used=8): matches up to cpu-used= instead of instead of up to screenshot-avif-opts=. Fix this by enabling non-greedy matching. --- etc/_mpv.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/_mpv.zsh b/etc/_mpv.zsh index 64795ddb2377b..2e4fec408b4f2 100644 --- a/etc/_mpv.zsh +++ b/etc/_mpv.zsh @@ -65,7 +65,7 @@ function _mpv_generate_arguments { _mpv_completion_arguments+="$name" else # Find the parent option and use that with this option's name - _mpv_completion_arguments+="${_mpv_completion_arguments[(R)${name%-*}=*]/*=/$name=}" + _mpv_completion_arguments+="${(S)_mpv_completion_arguments[(R)${name%-*}=*]/*=/$name=}" fi elif [[ $desc == Print* ]]; then From c11239be8cc7719218259db4f701760854a69e03 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sun, 29 Sep 2024 15:19:52 +0200 Subject: [PATCH 14/21] options: enable handling --no-hwdec as --hwdec=no Reusing M_OPT_ALLOW_NO has the side-effect of applying to --ab-loop-[ab], which makes sense. --- options/m_config_frontend.c | 5 ++++- options/m_option.h | 2 ++ video/decode/vd_lavc.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/options/m_config_frontend.c b/options/m_config_frontend.c index 28db357dd15c5..1182983d31edf 100644 --- a/options/m_config_frontend.c +++ b/options/m_config_frontend.c @@ -662,10 +662,13 @@ static struct m_config_option *m_config_mogrify_cli_opt(struct m_config *config, bstr no_name = *name; if (!co && bstr_eatstart0(&no_name, "no-")) { co = m_config_get_co(config, no_name); + if (!co) + return NULL; // Not all choice types have this value - if they don't, then parsing // them will simply result in an error. Good enough. - if (!co || !(co->opt->type->flags & M_OPT_TYPE_CHOICE)) + if (!(co->opt->type->flags & M_OPT_TYPE_CHOICE) && + !(co->opt->flags & M_OPT_ALLOW_NO)) return NULL; *name = no_name; diff --git a/options/m_option.h b/options/m_option.h index 7facb563e1f04..63a69667746f6 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -468,6 +468,8 @@ char *format_file_size(int64_t size); #define M_OPT_DEFAULT_NAN (1 << 26) // type time: string "no" maps to MP_NOPTS_VALUE (if unset, NOPTS is rejected) +// and +// parsing: "--no-opt" is parsed as "--opt=no" #define M_OPT_ALLOW_NO (1 << 27) // type channels: disallow "auto" (still accept ""), limit list to at most 1 item. diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index cf65cd0ff0eba..d75f2d7530245 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -124,7 +124,7 @@ const struct m_sub_options vd_lavc_conf = { {"vd-apply-cropping", OPT_BOOL(apply_cropping)}, {"hwdec", OPT_STRINGLIST(hwdec_api), .help = hwdec_opt_help, - .flags = M_OPT_OPTIONAL_PARAM | UPDATE_HWDEC}, + .flags = M_OPT_OPTIONAL_PARAM | M_OPT_ALLOW_NO | UPDATE_HWDEC}, {"hwdec-codecs", OPT_STRING(hwdec_codecs)}, {"hwdec-image-format", OPT_IMAGEFORMAT(hwdec_image_format)}, {"hwdec-extra-frames", OPT_INT(hwdec_extra_frames), M_RANGE(0, 256)}, From 7202406fe8c32abebfef2f8acbd745b962bb21fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 1 Oct 2024 03:09:11 +0200 Subject: [PATCH 15/21] various: remove global.h inclusion where not needed --- audio/decode/ad_lavc.c | 1 - options/m_config_frontend.c | 1 - options/m_config_frontend.h | 1 - options/parse_commandline.c | 1 - player/client.c | 1 - player/configfiles.c | 1 - player/loadfile.c | 1 - player/misc.c | 1 - player/screenshot.c | 1 - player/sub.c | 1 - stream/stream_cb.c | 1 - sub/ass_mp.c | 1 - test/repack.c | 1 - video/decode/vd_lavc.c | 1 - video/filter/vf_gpu.h | 3 ++- video/out/gpu/video.c | 1 - video/out/opengl/context.h | 1 - video/out/vo_dmabuf_wayland.c | 1 - video/out/vo_gpu.c | 1 - 19 files changed, 2 insertions(+), 19 deletions(-) diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 9eb308528de52..512ef9012c3d5 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -33,7 +33,6 @@ #include "audio/fmt-conversion.h" #include "common/av_common.h" #include "common/codecs.h" -#include "common/global.h" #include "common/msg.h" #include "demux/packet.h" #include "demux/stheader.h" diff --git a/options/m_config_frontend.c b/options/m_config_frontend.c index 1182983d31edf..99d936cfc4fd5 100644 --- a/options/m_config_frontend.c +++ b/options/m_config_frontend.c @@ -27,7 +27,6 @@ #include "libmpv/client.h" #include "common/common.h" -#include "common/global.h" #include "common/msg_control.h" #include "common/msg.h" #include "m_config_frontend.h" diff --git a/options/m_config_frontend.h b/options/m_config_frontend.h index 6108d9feeccc2..10b27206348d8 100644 --- a/options/m_config_frontend.h +++ b/options/m_config_frontend.h @@ -23,7 +23,6 @@ #include #include "common/common.h" -#include "common/global.h" #include "common/msg.h" #include "common/msg_control.h" #include "m_config_core.h" diff --git a/options/parse_commandline.c b/options/parse_commandline.c index ce776030c3372..b07d8e66db77a 100644 --- a/options/parse_commandline.c +++ b/options/parse_commandline.c @@ -23,7 +23,6 @@ #include #include "osdep/io.h" -#include "common/global.h" #include "common/msg.h" #include "common/msg_control.h" #include "m_option.h" diff --git a/player/client.c b/player/client.c index 42b311ee5da9a..b5112d14908c5 100644 --- a/player/client.c +++ b/player/client.c @@ -26,7 +26,6 @@ #include "common/global.h" #include "common/msg.h" #include "common/msg_control.h" -#include "common/global.h" #include "input/input.h" #include "input/cmd.h" #include "misc/ctype.h" diff --git a/player/configfiles.c b/player/configfiles.c index 3ecb5a19c887c..b48c857b35cb6 100644 --- a/player/configfiles.c +++ b/player/configfiles.c @@ -34,7 +34,6 @@ #include "osdep/io.h" -#include "common/global.h" #include "common/encode.h" #include "common/msg.h" #include "misc/ctype.h" diff --git a/player/loadfile.c b/player/loadfile.c index 964b7ef748225..57c134c1e461d 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -34,7 +34,6 @@ #include "client.h" #include "common/msg.h" #include "common/msg_control.h" -#include "common/global.h" #include "options/path.h" #include "options/m_config.h" #include "options/parse_configfile.h" diff --git a/player/misc.c b/player/misc.c index 036da5cf0b1ab..a19dd17f88666 100644 --- a/player/misc.c +++ b/player/misc.c @@ -32,7 +32,6 @@ #include "options/m_property.h" #include "options/m_config.h" #include "common/common.h" -#include "common/global.h" #include "common/encode.h" #include "common/playlist.h" #include "input/input.h" diff --git a/player/screenshot.c b/player/screenshot.c index aa637e6e63126..2bcef87a3093f 100644 --- a/player/screenshot.c +++ b/player/screenshot.c @@ -21,7 +21,6 @@ #include -#include "common/global.h" #include "osdep/io.h" #include "mpv_talloc.h" diff --git a/player/sub.c b/player/sub.c index bdd19540b00e8..3902c692b4540 100644 --- a/player/sub.c +++ b/player/sub.c @@ -26,7 +26,6 @@ #include "common/msg.h" #include "options/options.h" #include "common/common.h" -#include "common/global.h" #include "stream/stream.h" #include "sub/dec_sub.h" diff --git a/stream/stream_cb.c b/stream/stream_cb.c index 104fff0b053d8..70128cb476884 100644 --- a/stream/stream_cb.c +++ b/stream/stream_cb.c @@ -8,7 +8,6 @@ #include "common/common.h" #include "common/msg.h" -#include "common/global.h" #include "stream.h" #include "options/m_option.h" #include "options/path.h" diff --git a/sub/ass_mp.c b/sub/ass_mp.c index 255d0a077fc82..c02eb2a545367 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -29,7 +29,6 @@ #include #include "common/common.h" -#include "common/global.h" #include "common/msg.h" #include "options/path.h" #include "ass_mp.h" diff --git a/test/repack.c b/test/repack.c index c6ec506ecee59..cf6de36aa925f 100644 --- a/test/repack.c +++ b/test/repack.c @@ -3,7 +3,6 @@ #include #include "common/common.h" -#include "common/global.h" #include "img_utils.h" #include "sub/draw_bmp.h" #include "sub/osd.h" diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index d75f2d7530245..0a69ba4f3ec17 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -30,7 +30,6 @@ #include #include "mpv_talloc.h" -#include "common/global.h" #include "common/msg.h" #include "options/m_config.h" #include "options/options.h" diff --git a/video/filter/vf_gpu.h b/video/filter/vf_gpu.h index 2cc9a16eea065..e2387e28e003b 100644 --- a/video/filter/vf_gpu.h +++ b/video/filter/vf_gpu.h @@ -18,7 +18,8 @@ #pragma once #include "common/common.h" -#include "common/global.h" + +struct mpv_global; struct offscreen_ctx { struct mp_log *log; diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 037d93ca2623d..6bd1bf1169d75 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -30,7 +30,6 @@ #include "misc/bstr.h" #include "options/m_config.h" #include "options/path.h" -#include "common/global.h" #include "options/options.h" #include "utils.h" #include "hwdec.h" diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h index c96450ebd5b07..915583fd04cbe 100644 --- a/video/out/opengl/context.h +++ b/video/out/opengl/context.h @@ -1,6 +1,5 @@ #pragma once -#include "common/global.h" #include "video/out/gpu/context.h" #include "common.h" diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c index 8d5d0c5b0a401..0ff30b649567d 100644 --- a/video/out/vo_dmabuf_wayland.c +++ b/video/out/vo_dmabuf_wayland.c @@ -24,7 +24,6 @@ #include #endif -#include "common/global.h" #include "gpu/hwdec.h" #include "gpu/video.h" #include "mpv_talloc.h" diff --git a/video/out/vo_gpu.c b/video/out/vo_gpu.c index d49a6ba8a2f72..36a36b019b72b 100644 --- a/video/out/vo_gpu.c +++ b/video/out/vo_gpu.c @@ -30,7 +30,6 @@ #include "common/common.h" #include "misc/bstr.h" #include "common/msg.h" -#include "common/global.h" #include "options/m_config.h" #include "vo.h" #include "video/mp_image.h" From 9440ab9b8890521e53ed7d58d5622f54680ec320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 1 Oct 2024 20:20:00 +0200 Subject: [PATCH 16/21] ci/mingw: update freetype to 2.13.3 And change the mirror to working one. --- ci/build-mingw64.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index 34f5a702f4b88..a0212a613b16a 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -219,8 +219,8 @@ _libplacebo () { _libplacebo_mark=lib/libplacebo.dll.a _freetype () { - local ver=2.13.2 - gettar "https://mirror.netcologne.de/savannah/freetype/freetype-${ver}.tar.xz" + local ver=2.13.3 + gettar "https://download.savannah.gnu.org/releases/freetype/freetype-${ver}.tar.xz" builddir freetype-${ver} meson setup .. --cross-file "$prefix_dir/crossfile" makeplusinstall From 816c17d3630fd69aa8ddc91f32f733a78a25f7e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 1 Oct 2024 20:54:49 +0200 Subject: [PATCH 17/21] ci/mingw: update harfbuzz to 10.0.1 --- ci/build-mingw64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index a0212a613b16a..ecdf3976c168b 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -240,7 +240,7 @@ _fribidi () { _fribidi_mark=lib/libfribidi.dll.a _harfbuzz () { - local ver=9.0.0 + local ver=10.0.1 gettar "https://github.com/harfbuzz/harfbuzz/releases/download/${ver}/harfbuzz-${ver}.tar.xz" builddir harfbuzz-${ver} meson setup .. --cross-file "$prefix_dir/crossfile" \ From 171c91623d7fcf123d9f2dbfe6902eaa803739e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Tue, 1 Oct 2024 20:55:21 +0200 Subject: [PATCH 18/21] ci/mingw: update fribidi to 1.0.16 --- ci/build-mingw64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index ecdf3976c168b..820fff8253ad9 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -229,7 +229,7 @@ _freetype () { _freetype_mark=lib/libfreetype.dll.a _fribidi () { - local ver=1.0.15 + local ver=1.0.16 gettar "https://github.com/fribidi/fribidi/releases/download/v${ver}/fribidi-${ver}.tar.xz" builddir fribidi-${ver} meson setup .. --cross-file "$prefix_dir/crossfile" \ From f1865f312cfddbe39c71ff707ae8b15a79887eb8 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Tue, 1 Oct 2024 12:21:48 -0500 Subject: [PATCH 19/21] vo_{dmabuf_wayland,wlshm}: use proper values with MP_ALIGN_{UP,DOWN} Both of these VOs draw buffers in software via wl_shm to an mp_image, so they are affected by the internals of whatever mpv does for alignment. When wlshm was originally written, mp_sws was aligning to 16 bytes and thus it chose this value but it was hardcoded. vo_dmabuf_wayland later blindly copied this value. e1157cb6e8191f98b60813dc91342e3baf577d92 actually changed the internal value to 64 bytes. In theory, this doesn't probably doesn't really matter since 16 should also work in most cases, but we might as well stop using a magic number and be consistent. Additionally, wl_shm did some funny alignments that no other software output did. The reasoning was apparently due to warning messages from ffmpeg while cropping*. This was left in at the time, but I'm not able to reproduce any such warning messages on my end when I make this match other software VOs. Go ahead and remove the MP_MAX business and align to the fmt x/y like the other VOs do. *: https://github.com/mpv-player/mpv/pull/6240#discussion_r227930233 --- video/out/vo_dmabuf_wayland.c | 4 ++-- video/out/vo_wlshm.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c index 0ff30b649567d..3c45757387488 100644 --- a/video/out/vo_dmabuf_wayland.c +++ b/video/out/vo_dmabuf_wayland.c @@ -451,7 +451,7 @@ static void create_shm_pool(struct vo *vo) struct vo_wayland_state *wl = vo->wl; struct priv *p = vo->priv; - int stride = MP_ALIGN_UP(vo->dwidth * 4, 16); + int stride = MP_ALIGN_UP(vo->dwidth * 4, MP_IMAGE_BYTE_ALIGN); size_t size = vo->dheight * stride; int fd = vo_wayland_allocate_memfd(vo, size); if (fd < 0) @@ -783,7 +783,7 @@ static int preinit(struct vo *vo) } else { int width = 1; int height = 1; - int stride = MP_ALIGN_UP(width * 4, 16); + int stride = MP_ALIGN_UP(width * 4, MP_IMAGE_BYTE_ALIGN); int fd = vo_wayland_allocate_memfd(vo, stride); if (fd < 0) goto err; diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c index 3a13b82d0f46d..3132d7a563959 100644 --- a/video/out/vo_wlshm.c +++ b/video/out/vo_wlshm.c @@ -85,7 +85,7 @@ static struct buffer *buffer_create(struct vo *vo, int width, int height) uint8_t *data; struct buffer *buf; - stride = MP_ALIGN_UP(width * 4, 16); + stride = MP_ALIGN_UP(width * 4, MP_IMAGE_BYTE_ALIGN); size = height * stride; fd = vo_wayland_allocate_memfd(vo, size); if (fd < 0) @@ -264,12 +264,12 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame) struct mp_image dst = buf->mpi; struct mp_rect src_rc; struct mp_rect dst_rc; - src_rc.x0 = MP_ALIGN_DOWN(p->src.x0, MPMAX(src->fmt.align_x, 4)); - src_rc.y0 = MP_ALIGN_DOWN(p->src.y0, MPMAX(src->fmt.align_y, 4)); + src_rc.x0 = MP_ALIGN_DOWN(p->src.x0, src->fmt.align_x); + src_rc.y0 = MP_ALIGN_DOWN(p->src.y0, src->fmt.align_y); src_rc.x1 = p->src.x1 - (p->src.x0 - src_rc.x0); src_rc.y1 = p->src.y1 - (p->src.y0 - src_rc.y0); - dst_rc.x0 = MP_ALIGN_DOWN(p->dst.x0, MPMAX(dst.fmt.align_x, 4)); - dst_rc.y0 = MP_ALIGN_DOWN(p->dst.y0, MPMAX(dst.fmt.align_y, 4)); + dst_rc.x0 = MP_ALIGN_DOWN(p->dst.x0, dst.fmt.align_x); + dst_rc.y0 = MP_ALIGN_DOWN(p->dst.y0, dst.fmt.align_y); dst_rc.x1 = p->dst.x1 - (p->dst.x0 - dst_rc.x0); dst_rc.y1 = p->dst.y1 - (p->dst.y0 - dst_rc.y0); mp_image_crop_rc(src, src_rc); From 7ca5fd2ad23a31b0dbfcf133e942a9234597b052 Mon Sep 17 00:00:00 2001 From: Bergmann Atmet Date: Wed, 2 Oct 2024 13:22:52 +0300 Subject: [PATCH 20/21] ci/mingw: pass --enable-gpl to ffmpeg's configure A bunch of lavfi filters were presumably not available in mingw builds because of this. ``` % grep -E '=(".+ |")gpl("| .+")$' configure blackframe_filter_deps="gpl" boxblur_filter_deps="gpl" boxblur_opencl_filter_deps="opencl gpl" colormatrix_filter_deps="gpl" cover_rect_filter_deps="avcodec avformat gpl" cropdetect_filter_deps="gpl" delogo_filter_deps="gpl" eq_filter_deps="gpl" find_rect_filter_deps="avcodec avformat gpl" fspp_filter_deps="gpl" histeq_filter_deps="gpl" hqdn3d_filter_deps="gpl" interlace_filter_deps="gpl" kerndeint_filter_deps="gpl" mcdeint_filter_deps="avcodec gpl" mpdecimate_filter_deps="gpl" mptestsrc_filter_deps="gpl" nnedi_filter_deps="gpl" owdenoise_filter_deps="gpl" perspective_filter_deps="gpl" phase_filter_deps="gpl" pp7_filter_deps="gpl" pp_filter_deps="gpl postproc" pullup_filter_deps="gpl" repeatfields_filter_deps="gpl" sab_filter_deps="gpl swscale" signature_filter_deps="gpl avcodec avformat" smartblur_filter_deps="gpl swscale" spp_filter_deps="gpl avcodec" stereo3d_filter_deps="gpl" super2xsai_filter_deps="gpl" tinterlace_filter_deps="gpl" uspp_filter_deps="gpl avcodec" vaguedenoiser_filter_deps="gpl" postproc_deps="avutil gpl" ``` Also include built postproc in dlls. Signed-off-by: Bergmann Atmet --- ci/build-mingw64.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index 820fff8253ad9..e837cdcec290c 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -146,7 +146,7 @@ _ffmpeg () { [ -d ffmpeg ] || $gitclone https://github.com/FFmpeg/FFmpeg.git ffmpeg builddir ffmpeg local args=( - --pkg-config=pkg-config --target-os=mingw32 + --pkg-config=pkg-config --target-os=mingw32 --enable-gpl --enable-cross-compile --cross-prefix=$TARGET- --arch=${TARGET%%-*} --cc="$CC" --cxx="$CXX" $commonflags --disable-{doc,programs} @@ -320,7 +320,7 @@ if [ "$2" = pack ]; then pushd artifact/tmp dlls=( libgcc_*.dll lib{ssp,stdc++,winpthread}-[0-9]*.dll # compiler runtime - av*.dll sw*.dll lib{ass,freetype,fribidi,harfbuzz,iconv,placebo}-[0-9]*.dll + av*.dll sw*.dll postproc-[0-9]*.dll lib{ass,freetype,fribidi,harfbuzz,iconv,placebo}-[0-9]*.dll lib{shaderc_shared,spirv-cross-c-shared,dav1d}.dll zlib1.dll ) if [[ -f vulkan-1.dll ]]; then From 0d7b4d64a5ec9b9ef132c07c1fb6712b1653101f Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Mon, 30 Sep 2024 22:11:16 -0500 Subject: [PATCH 21/21] wayland: support multiple devices and tranches when querying formats The multi device part is mostly theoretical, but it turns out that plasma does send multiple tranches to the same device so we have to take that into account. And that means taking into account multiple devices as well. In theory, a compositor should give us tranches for any device that will work so as long as we find a match it should be OK. This is still technically incomplete since mpv's core wouldn't react to a device being hotplugged. --- video/out/hwdec/dmabuf_interop_wl.c | 4 +- video/out/vo_dmabuf_wayland.c | 4 +- video/out/wayland_common.c | 144 +++++++++++++++++++++------- video/out/wayland_common.h | 19 ++-- video/out/wldmabuf/ra_wldmabuf.c | 30 +----- video/out/wldmabuf/ra_wldmabuf.h | 2 +- 6 files changed, 124 insertions(+), 79 deletions(-) diff --git a/video/out/hwdec/dmabuf_interop_wl.c b/video/out/hwdec/dmabuf_interop_wl.c index eab1bf50f45bd..3227d88cdb04f 100644 --- a/video/out/hwdec/dmabuf_interop_wl.c +++ b/video/out/hwdec/dmabuf_interop_wl.c @@ -44,8 +44,8 @@ static bool map(struct ra_hwdec_mapper *mapper, if (mapper_p->desc.nb_layers != 1) { MP_VERBOSE(mapper, "Mapped surface has separate layers - expected composed layers.\n"); return false; - } else if (!ra_compatible_format(mapper->ra, mapper->src->params.hw_subfmt, - drm_format, mapper_p->desc.objects[0].format_modifier)) { + } else if (!ra_compatible_format(mapper->ra, drm_format, + mapper_p->desc.objects[0].format_modifier)) { MP_VERBOSE(mapper, "Mapped surface with format %s; drm format '%s(%016" PRIx64 ")' " "is not supported by compositor and GPU combination.\n", mp_imgfmt_to_name(mapper->src->params.hw_subfmt), diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c index 3c45757387488..9a79eb947ceff 100644 --- a/video/out/vo_dmabuf_wayland.c +++ b/video/out/vo_dmabuf_wayland.c @@ -198,7 +198,7 @@ static void vaapi_dmabuf_importer(struct buffer *buf, struct mp_image *src, goto done; } buf->drm_format = desc.layers[layer_no].drm_format; - if (!ra_compatible_format(p->ctx->ra, src->params.hw_subfmt, buf->drm_format, desc.objects[0].drm_format_modifier)) { + if (!ra_compatible_format(p->ctx->ra, buf->drm_format, desc.objects[0].drm_format_modifier)) { MP_VERBOSE(vo, "%s(%016" PRIx64 ") is not supported.\n", mp_tag_str(buf->drm_format), desc.objects[0].drm_format_modifier); buf->drm_format = 0; @@ -680,7 +680,7 @@ static int reconfig(struct vo *vo, struct mp_image *img) return VO_ERROR; } - if (!ra_compatible_format(p->ctx->ra, img->params.hw_subfmt, p->drm_format, p->drm_modifier)) { + if (!ra_compatible_format(p->ctx->ra, p->drm_format, p->drm_modifier)) { MP_ERR(vo, "Format '%s' with modifier '(%016" PRIx64 ")' is not supported by" " the compositor.\n", mp_tag_str(p->drm_format), p->drm_modifier); return VO_ERROR; diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index b131c904dad1c..4406d53d38ae3 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -47,6 +47,7 @@ #include "fractional-scale-v1.h" #if HAVE_DRM +#include #include #include #endif @@ -147,6 +148,12 @@ static const struct mp_keymap keymap[] = { {0, 0} }; +struct compositor_format { + uint32_t format; + uint32_t padding; + uint64_t modifier; +}; + struct vo_wayland_feedback_pool { struct wp_presentation_feedback **fback; struct vo_wayland_state *wl; @@ -199,6 +206,15 @@ struct vo_wayland_seat { int num_keyboard_entering_keys; }; +struct vo_wayland_tranche { + struct drm_format *compositor_formats; + int num_compositor_formats; + uint32_t *planar_formats; + int num_planar_formats; + dev_t device_id; + struct wl_list link; +}; + static bool single_output_spanned(struct vo_wayland_state *wl); static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels, @@ -1383,15 +1399,20 @@ static void main_device(void *data, struct wl_array *device) { struct vo_wayland_state *wl = data; - wl->add_tranche = true; + // Remove any old devices and tranches if we get this again. + struct vo_wayland_tranche *tranche, *tranche_tmp; + wl_list_for_each_safe(tranche, tranche_tmp, &wl->tranche_list, link) { + wl_list_remove(&tranche->link); + talloc_free(tranche); + } } static void tranche_done(void *data, struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1) { struct vo_wayland_state *wl = data; - wl->add_tranche = false; + wl->current_tranche = NULL; } static void tranche_target_device(void *data, @@ -1399,15 +1420,18 @@ static void tranche_target_device(void *data, struct wl_array *device) { struct vo_wayland_state *wl = data; - // Only use the first tranche device we get. - if (wl->add_tranche) { - dev_t *id; - wl_array_for_each(id, device) { - memcpy(&wl->target_device_id, id, sizeof(dev_t)); - break; - } - get_planar_drm_formats(wl); + struct vo_wayland_tranche *tranche = talloc_zero(wl, struct vo_wayland_tranche); + + dev_t *id; + wl_array_for_each(id, device) { + memcpy(&tranche->device_id, id, sizeof(dev_t)); + break; } + static_assert(sizeof(tranche->device_id) == sizeof(dev_t), ""); + + wl->current_tranche = tranche; + get_planar_drm_formats(wl); + wl_list_insert(&wl->tranche_list, &tranche->link); } static void tranche_formats(void *data, @@ -1416,22 +1440,22 @@ static void tranche_formats(void *data, { struct vo_wayland_state *wl = data; - // Only grab formats from the first tranche and ignore the rest. - if (!wl->add_tranche) - return; - // Should never happen. if (!wl->compositor_format_map) { MP_WARN(wl, "Compositor did not send a format and modifier table!\n"); return; } - const compositor_format *formats = wl->compositor_format_map; - MP_RESIZE_ARRAY(wl, wl->compositor_formats, indices->size); - wl->num_compositor_formats = 0; + struct vo_wayland_tranche *tranche = wl->current_tranche; + if (!tranche) + return; + + const struct compositor_format *formats = wl->compositor_format_map; uint16_t *index; + MP_DBG(wl, "Querying available drm format and modifier pairs from tranche on device '%lu'\n", + tranche->device_id); wl_array_for_each(index, indices) { - MP_TARRAY_APPEND(wl, wl->compositor_formats, wl->num_compositor_formats, + MP_TARRAY_APPEND(tranche, tranche->compositor_formats, tranche->num_compositor_formats, (struct drm_format) { formats[*index].format, formats[*index].modifier, @@ -1445,6 +1469,9 @@ static void tranche_flags(void *data, struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1, uint32_t flags) { + struct vo_wayland_state *wl = data; + if (flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT) + MP_DBG(wl, "Tranche has direct scanout.\n"); } static const struct zwp_linux_dmabuf_feedback_v1_listener dmabuf_feedback_listener = { @@ -1806,6 +1833,19 @@ static void add_feedback(struct vo_wayland_feedback_pool *fback_pool, } } +static bool devices_are_equal(dev_t a, dev_t b) +{ + bool ret = false; +#if HAVE_DRM + drmDevice *deviceA, *deviceB; + if (!drmGetDeviceFromDevId(a, 0, &deviceA) && !drmGetDeviceFromDevId(b, 0, &deviceB)) + ret = drmDevicesEqual(deviceA, deviceB); + drmFreeDevice(&deviceA); + drmFreeDevice(&deviceB); +#endif + return ret; +} + static void do_minimize(struct vo_wayland_state *wl) { if (wl->opts->window_minimized) @@ -1831,12 +1871,23 @@ static char **get_displays_spanned(struct vo_wayland_state *wl) static void get_planar_drm_formats(struct vo_wayland_state *wl) { #if HAVE_DRM + struct vo_wayland_tranche *tranche; + wl_list_for_each(tranche, &wl->tranche_list, link) { + // If there is a device equality, just copy the pointer over. + if (devices_are_equal(tranche->device_id, wl->current_tranche->device_id)) { + wl->current_tranche->planar_formats = tranche->planar_formats; + wl->current_tranche->num_planar_formats = tranche->num_planar_formats; + return; + } + } + + tranche = wl->current_tranche; drmDevice *device = NULL; drmModePlaneRes *res = NULL; drmModePlane *plane = NULL; - if (drmGetDeviceFromDevId(wl->target_device_id, 0, &device) != 0) { - MP_WARN(wl, "Unable to get drm device from device id: %s\n", mp_strerror(errno)); + if (drmGetDeviceFromDevId(tranche->device_id, 0, &device) != 0) { + MP_VERBOSE(wl, "Unable to get drm device from device id: %s\n", mp_strerror(errno)); goto done; } @@ -1850,30 +1901,30 @@ static void get_planar_drm_formats(struct vo_wayland_state *wl) } if (!path || !path[0]) { - MP_WARN(wl, "Unable to find a valid drm device node.\n"); + MP_VERBOSE(wl, "Unable to find a valid drm device node.\n"); goto done; } int fd = open(path, O_RDWR | O_CLOEXEC); if (fd < 0) { - MP_WARN(wl, "Unable to open DRM node path '%s': %s\n", path, mp_strerror(errno)); + MP_VERBOSE(wl, "Unable to open DRM node path '%s': %s\n", path, mp_strerror(errno)); goto done; } // Need to set this in order to access plane information. if (drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1)) { - MP_WARN(wl, "Unable to set DRM atomic cap: %s\n", mp_strerror(errno)); + MP_VERBOSE(wl, "Unable to set DRM atomic cap: %s\n", mp_strerror(errno)); goto done; } res = drmModeGetPlaneResources(fd); if (!res) { - MP_WARN(wl, "Unable to get DRM plane resources: %s\n", mp_strerror(errno)); + MP_VERBOSE(wl, "Unable to get DRM plane resources: %s\n", mp_strerror(errno)); goto done; } if (!res->count_planes) { - MP_WARN(wl, "No DRM planes were found.\n"); + MP_VERBOSE(wl, "No DRM planes were found.\n"); goto done; } @@ -1908,20 +1959,17 @@ static void get_planar_drm_formats(struct vo_wayland_state *wl) } if (index == -1) { - MP_WARN(wl, "Unable to get DRM plane: %s\n", mp_strerror(errno)); + MP_VERBOSE(wl, "Unable to get DRM plane: %s\n", mp_strerror(errno)); goto done; } plane = drmModeGetPlane(fd, res->planes[index]); - wl->num_planar_formats = plane->count_formats; - - if (wl->planar_formats) - talloc_free(wl->planar_formats); + tranche->num_planar_formats = plane->count_formats; + tranche->planar_formats = talloc_zero_array(tranche, int, tranche->num_planar_formats); - wl->planar_formats = talloc_zero_array(wl, int, wl->num_planar_formats); - for (int i = 0; i < wl->num_planar_formats; ++i) { + for (int i = 0; i < tranche->num_planar_formats; ++i) { MP_DBG(wl, "DRM primary plane supports drm format: %s\n", mp_tag_str(plane->formats[i])); - wl->planar_formats[i] = plane->formats[i]; + tranche->planar_formats[i] = plane->formats[i]; } done: @@ -2722,6 +2770,35 @@ void vo_wayland_handle_scale(struct vo_wayland_state *wl) lround(mp_rect_h(wl->geometry) / wl->scaling_factor)); } +bool vo_wayland_valid_format(struct vo_wayland_state *wl, uint32_t drm_format, uint64_t modifier) +{ +#if HAVE_DRM + // Tranches are grouped by preference and the first tranche is at the end of + // the list. It doesn't really matter for us since we search everything + // anyways, but might as well start from the most preferred tranche. + struct vo_wayland_tranche *tranche; + wl_list_for_each_reverse(tranche, &wl->tranche_list, link) { + bool supported_compositor_format = false; + struct drm_format *formats = tranche->compositor_formats; + for (int i = 0; i < tranche->num_compositor_formats; ++i) { + if (formats[i].format != drm_format) + continue; + if (modifier == formats[i].modifier && modifier != DRM_FORMAT_MOD_INVALID) + return true; + supported_compositor_format = true; + } + + if (supported_compositor_format && tranche->planar_formats) { + for (int i = 0; i < tranche->num_planar_formats; i++) { + if (drm_format == tranche->planar_formats[i]) + return true; + } + } + } +#endif + return false; +} + bool vo_wayland_init(struct vo *vo) { if (!getenv("WAYLAND_DISPLAY")) @@ -2749,6 +2826,7 @@ bool vo_wayland_init(struct vo *vo) wl_list_init(&wl->output_list); wl_list_init(&wl->seat_list); + wl_list_init(&wl->tranche_list); if (!wl->display) goto err; diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 4621310625904..23cca5b8e9594 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -22,13 +22,9 @@ #include "input/event.h" #include "vo.h" +struct compositor_format; struct vo_wayland_seat; - -typedef struct { - uint32_t format; - uint32_t padding; - uint64_t modifier; -} compositor_format; +struct vo_wayland_tranche; struct drm_format { uint32_t format; @@ -107,16 +103,12 @@ struct vo_wayland_state { struct zwp_idle_inhibitor_v1 *idle_inhibitor; /* linux-dmabuf */ - dev_t target_device_id; + struct wl_list tranche_list; + struct vo_wayland_tranche *current_tranche; struct zwp_linux_dmabuf_v1 *dmabuf; struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback; - bool add_tranche; - compositor_format *compositor_format_map; + struct compositor_format *compositor_format_map; uint32_t compositor_format_size; - struct drm_format *compositor_formats; - int num_compositor_formats; - uint32_t *planar_formats; - int num_planar_formats; /* presentation-time */ struct wp_presentation *presentation; @@ -168,6 +160,7 @@ struct vo_wayland_state { }; bool vo_wayland_check_visible(struct vo *vo); +bool vo_wayland_valid_format(struct vo_wayland_state *wl, uint32_t drm_format, uint64_t modifier); bool vo_wayland_init(struct vo *vo); bool vo_wayland_reconfig(struct vo *vo); diff --git a/video/out/wldmabuf/ra_wldmabuf.c b/video/out/wldmabuf/ra_wldmabuf.c index 5285738d96a24..3e3c894aff943 100644 --- a/video/out/wldmabuf/ra_wldmabuf.c +++ b/video/out/wldmabuf/ra_wldmabuf.c @@ -15,8 +15,6 @@ * License along with mpv. If not, see . */ -#include - #include "video/out/wayland_common.h" #include "video/out/gpu/ra.h" #include "ra_wldmabuf.h" @@ -30,35 +28,11 @@ static void destroy(struct ra *ra) talloc_free(ra->priv); } -bool ra_compatible_format(struct ra *ra, int imgfmt, uint32_t drm_format, uint64_t modifier) +bool ra_compatible_format(struct ra *ra, uint32_t drm_format, uint64_t modifier) { struct priv *p = ra->priv; struct vo_wayland_state *wl = p->vo->wl; - struct drm_format *formats = wl->compositor_formats; - - // Always check if the compositor supports the format. - bool supported_compositor_format = false; - for (int i = 0; i < wl->num_compositor_formats; ++i) { - if (formats[i].format != drm_format || formats[i].modifier == DRM_FORMAT_MOD_INVALID) - continue; - if (modifier == formats[i].modifier) - return true; - supported_compositor_format = true; - } - - if (!supported_compositor_format) - return false; - - // If the compositor supports the format but there are no valid modifiers, - // see if this is a planar format which can be still be supported. - if (wl->planar_formats) { - for (int i = 0; i < wl->num_planar_formats; i++) { - if (drm_format == wl->planar_formats[i]) - return true; - } - } - - return false; + return vo_wayland_valid_format(wl, drm_format, modifier); } static struct ra_fns ra_fns_wldmabuf = { diff --git a/video/out/wldmabuf/ra_wldmabuf.h b/video/out/wldmabuf/ra_wldmabuf.h index 245077c2284f4..c6907e1b5f9ba 100644 --- a/video/out/wldmabuf/ra_wldmabuf.h +++ b/video/out/wldmabuf/ra_wldmabuf.h @@ -19,5 +19,5 @@ #include "video/out/wayland_common.h" struct ra *ra_create_wayland(struct mp_log *log, struct vo *vo); -bool ra_compatible_format(struct ra *ra, int imgfmt, uint32_t drm_format, uint64_t modifier); +bool ra_compatible_format(struct ra *ra, uint32_t drm_format, uint64_t modifier); bool ra_is_wldmabuf(struct ra *ra);