Doel
Echte HDR-weergave (HDR10/HLG-passthrough naar het display) en frame-rate-matching (Surface.setFrameRate) op Android — telefoons én Android TV. Vandaag wordt HDR-content altijd door mpv naar SDR getone-mapt omdat de video in een 8-bit Flutter-texture belandt.
Wat er al ligt (feature-branches)
Architectuur: een SurfaceView als hybrid-composition platform view naast de bestaande texture-route, aangestuurd door vo=gpu-next op mpv's androidvk-Vulkan-context met target-colorspace-hint (de GL-swapchain implementeert die hint niet — ook upstream niet). Op telefoons dual-mode: embedded blijft het texture-pad (SDR), fullscreen wisselt live naar SurfaceView/HDR. Achter een device-lokale instelling ("Echte HDR-weergave" + "Beeldsnelheid volgen"), alleen zichtbaar op HDR-schermen. Verder: HCPP (EnableHcpp), usesCleartextTraffic (http-naar-LAN werkte op Android nooit), hls-bitrate=max, betere tone mapping (bt.2446a) als SDR-fallback.
Bewezen op Pixel 9: SurfaceFlinger composit de app als HDR-layer (desiredRatio = sigPeak van de PQ-stream, hdrSdrRatio ≈ 8.0), setFrameRate toegepast, dual-mode-wissels stabiel.
Open punten
- MiTV-klasse (armv7, 2GB) trekt de Vulkan-route niet. Onder Vulkan bestaat alleen
hwdec=mediacodec-copy (het directe mediacodec-interop-pad hwdec_aimagereader is GL-only; ffmpeg heeft geen AHardwareBuffer→Vulkan-import). Zelfs 1080p24-HDR desynct er op ~100% CPU (ANR). Oplosrichting: per device kiezen welke motor het SurfaceView-pad aandrijft — krachtige devices gpu-next/Vulkan (behoudt libass-subs en auto-crop), zwakke TV-boxes vo=mediacodec_embed (decoder rechtstreeks op het Surface, nul kopieën, platform regelt HDR zoals native TV-apps; subs dan via Flutter's SubtitleView, geen auto-crop). Het SurfaceView-fundament, setFrameRate en de gating zijn voor beide motoren identiek; widListener heeft de mediacodec_embed-voorziening al.
- Surface komt niet terug na een TV-refresh-modewissel (
surfaceDestroyed na setFrameRate-modeswitch, geen hercreatie) — platform-view-hercreatie onderzoeken.
- 10-bit: mediacodec-copy levert nv12 (8-bit) i.p.v. P010 → mogelijke banding; uitzoeken (decoder-formaatonderhandeling in ffmpeg-mediacodec).
- Trage eerste Vulkan-start: gpu-next compileert shaders op de CPU bij elke start;
gpu-shader-cache-dir naar de app-cache zetten.
- Release-keten: libmpv-release maken (Vulkan-jars, alle ABI's), md5's in de fork, fork-sha her-pinnen in de player (de WIP-branches wijzen nu naar lokale spike-jars/path-overrides).
- Klein: zwarte flits bij de fullscreen-wissel (vo-herinit, inherent maar te verzachten);
Window.setDesiredHdrHeadroom (API 35+) om OS-brightnessherbalancering op telefoons te temperen; luidruchtige onschuldige logs (hevc_mediacodec surface NULL, lavf file cache).
Beperkingen (bewust geaccepteerd)
- HDR op telefoons alleen fullscreen (embedded platform views in een scrollende UI zijn structureel een compromis: HC = main-thread-jank, HCPP = overlay-artefact; dit is ook wat native video-apps doen).
MPVLogLevel.info niet gebruiken: wakeup-race in libmpv's client-lijst → SIGSEGV.
- Dolby Vision buiten scope (alleen HDR10/HLG; DV-profiel-5 blijft afwijkend).
Doel
Echte HDR-weergave (HDR10/HLG-passthrough naar het display) en frame-rate-matching (
Surface.setFrameRate) op Android — telefoons én Android TV. Vandaag wordt HDR-content altijd door mpv naar SDR getone-mapt omdat de video in een 8-bit Flutter-texture belandt.Wat er al ligt (feature-branches)
player→feature/hdr-vrrmedia-kit→feature/android-hdr-surfaceviewlibmpv-android-video-build→feature/android-vulkantestdata→feature/hdr-fixturesArchitectuur: een SurfaceView als hybrid-composition platform view naast de bestaande texture-route, aangestuurd door
vo=gpu-nextop mpv'sandroidvk-Vulkan-context mettarget-colorspace-hint(de GL-swapchain implementeert die hint niet — ook upstream niet). Op telefoons dual-mode: embedded blijft het texture-pad (SDR), fullscreen wisselt live naar SurfaceView/HDR. Achter een device-lokale instelling ("Echte HDR-weergave" + "Beeldsnelheid volgen"), alleen zichtbaar op HDR-schermen. Verder: HCPP (EnableHcpp),usesCleartextTraffic(http-naar-LAN werkte op Android nooit),hls-bitrate=max, betere tone mapping (bt.2446a) als SDR-fallback.Bewezen op Pixel 9: SurfaceFlinger composit de app als HDR-layer (
desiredRatio= sigPeak van de PQ-stream,hdrSdrRatio≈ 8.0),setFrameRatetoegepast, dual-mode-wissels stabiel.Open punten
hwdec=mediacodec-copy(het directe mediacodec-interop-padhwdec_aimagereaderis GL-only; ffmpeg heeft geen AHardwareBuffer→Vulkan-import). Zelfs 1080p24-HDR desynct er op ~100% CPU (ANR). Oplosrichting: per device kiezen welke motor het SurfaceView-pad aandrijft — krachtige devicesgpu-next/Vulkan (behoudt libass-subs en auto-crop), zwakke TV-boxesvo=mediacodec_embed(decoder rechtstreeks op het Surface, nul kopieën, platform regelt HDR zoals native TV-apps; subs dan via Flutter's SubtitleView, geen auto-crop). Het SurfaceView-fundament,setFrameRateen de gating zijn voor beide motoren identiek;widListenerheeft demediacodec_embed-voorziening al.surfaceDestroyednasetFrameRate-modeswitch, geen hercreatie) — platform-view-hercreatie onderzoeken.gpu-shader-cache-dirnaar de app-cache zetten.Window.setDesiredHdrHeadroom(API 35+) om OS-brightnessherbalancering op telefoons te temperen; luidruchtige onschuldige logs (hevc_mediacodec surface NULL,lavf file cache).Beperkingen (bewust geaccepteerd)
MPVLogLevel.infoniet gebruiken: wakeup-race in libmpv's client-lijst → SIGSEGV.