From 0a6865fa188a99a66ee43b4ae8d25b39f4e48eb2 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Thu, 30 Jul 2026 02:51:25 +0200 Subject: [PATCH] fix(macos): unbound the AVFoundation AO's PCM lookahead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MPVKit 1.0.15 bounded how far ahead ao_avfoundation enqueues PCM on macOS — about 450ms of queue against the renderer's own ~1.7s — and disarms the feed between refills, re-arming from a half-bound timer. 2.10 is the first release to carry it: the AO pin went 1.0.12 to 1.0.16 over that release. #1711 reports macOS audio skipping roughly every half second on 2.10 that 2.9.1 does not have, and that bound is the only change to this path in the window, so restore the renderer-owned depth 2.9.1 shipped. The option documents 0 as exactly that. The AO itself stays. allowedAudioSpatializationFormats is a property of AVSampleBufferAudioRenderer, and the compressed E-AC3 JOC sink lives there too, while ao_coreaudio drives the HAL device and exposes no spatialization control at all — CoreAudio is the fallback, not an alternative. The cost is the latency the bound was added to remove: mpv multiplies --volume into the samples as it hands them over, so a volume change stays inaudible until the renderer queue drains. That is 2.9.1's behaviour, and the fix for it belongs to the AO's gain domain rather than to how far ahead it may buffer. Verified against the pinned MPVKit 1.0.16 libmpv on macOS: both option writes are accepted, playback lands on ao_avfoundation and advances at 0.997x real time. Runner's native suite passes. --- macos/Runner/MpvPlayer/MpvPlayerCore.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/macos/Runner/MpvPlayer/MpvPlayerCore.swift b/macos/Runner/MpvPlayer/MpvPlayerCore.swift index 32404c5f..7f619642 100644 --- a/macos/Runner/MpvPlayer/MpvPlayerCore.swift +++ b/macos/Runner/MpvPlayer/MpvPlayerCore.swift @@ -102,7 +102,21 @@ class MpvPlayerCore: MpvPlayerCoreBase { } override func configurePlatformMpvOptions(mpv: OpaquePointer) { + // AVFoundation stays the macOS output. Spatialization is only reachable + // through the AVFoundation renderer — allowedAudioSpatializationFormats is a + // property of AVSampleBufferAudioRenderer (macOS 12+), and the AO opts + // compressed playback into the multichannel format — and the E-AC3 JOC sink + // lives there too. CoreAudio writes straight to the HAL device and exposes no + // spatialization control at all, so it is a fallback, not an alternative. checkError(mpv_set_option_string(mpv, "ao", "avfoundation,coreaudio")) + // Unbound the AO's PCM lookahead, restoring the renderer-owned queue depth + // 2.9.1 shipped (#1711). The macOS-only 0.5s bound MPVKit 1.0.15 added is the + // only change to this path between 2.9.1 and 2.10, and 2.10 skips audio at + // roughly that cadence. Its purpose was making mpv's software --volume, which + // is baked into the samples handed to the AO, audible before the queue + // drains; that latency is back, and belongs to the AO's gain domain rather + // than to how far ahead it may buffer. + checkError(mpv_set_option_string(mpv, "ao-avfoundation-max-lookahead", "0")) } func reattachMetalLayer() {