Context
SwiftVLC is built on VLC 4, and our current libVLC build script pins upstream VLC master at c833c4be0.
We should investigate HDR as a real product capability, but with a narrow and honest first target: native VideoView HDR10/HLG playback through VLC 4's Apple-native rendering path.
Current understanding
- SwiftVLC's normal
VideoView path uses libvlc_media_player_set_nsobject, so playback is delegated to libVLC's native drawable/video-output selection.
- VLC 4 has a new Apple
samplebufferdisplay video output based on AVSampleBufferDisplayLayer. It is the high-priority/default Apple display path unless legacy rendering is forced or selected as a fallback.
- That path can render CoreVideo pixel buffers directly. When VideoToolbox decodes HDR HEVC Main10, VLC 4 can keep 10-bit bi-planar P010/CVPX buffers instead of forcing an 8-bit BGRA conversion.
- VLC 4 maps Apple/CoreVideo color metadata for BT.2020, PQ/ST2084, and HLG, and its VideoToolbox path attaches color properties so native Apple display APIs can make tone-mapping/display decisions.
- Legacy OpenGL/GLES should not be the primary HDR target. VLC 4 explicitly rejects
CVPX_P010 on iOS/tvOS OpenGL because native Darwin OpenGLES cannot allocate the needed >8-bit textures. Fallback paths can end up in BGRA/SDR behavior.
- SwiftVLC's current PiP implementation is separate from the normal native
VideoView path. It uses libVLC video callbacks/vmem and forces BGRA CVPixelBuffers, so it should be treated as SDR-only for now.
- libVLC 4 exposes some color/bitdepth fields in custom output callbacks, but the HDR metadata callback is documented as D3D11-only and there is no Apple Metal custom output engine. For Apple HDR, native
VideoView/samplebufferdisplay is the promising path.
- SwiftVLC/libVLC track metadata exposed today does not appear to expose enough video color fields to reliably answer "is this track HDR?" from
Track alone.
Proposed initial scope
Support or experimentally validate HDR playback for the native VideoView path only:
- HDR10 HEVC Main10, PQ/ST2084, BT.2020
- HLG HEVC, BT.2020
- Hardware-backed VideoToolbox decode where available
- Native display behavior on iPhone/iPad, macOS HDR displays, and Apple TV 4K
Out of initial scope:
- HDR support for
PiPVideoView
- Dolby Vision support claims
- HDR10+ dynamic metadata support claims
- A custom Metal/libVLC output callback implementation
- Broad "full HDR" marketing language until validated
Validation plan
- Add or enable diagnostics that record:
- Selected VLC video-output module (
samplebufferdisplay vs OpenGL/GLES/other fallback)
- Decode path (
videotoolbox vs software)
- Output chroma/pixel format (
CVPX_P010 vs NV12/BGRA)
- Color primaries, transfer function, color space, and bit depth when available
- Test a sample matrix:
- HDR10 HEVC Main10 PQ / BT.2020
- HLG HEVC / BT.2020
- AV1 HDR, if supported by the target platform/build
- HDR10+ sample, as a negative/unknown-support case
- Dolby Vision sample, as a negative/unknown-support case
- Test on real HDR hardware:
- iPhone with HDR-capable OLED display
- MacBook Pro XDR or Mac connected to HDR display
- Apple TV 4K connected to an HDR TV
- Confirm that native
VideoView stays on VLC's Apple samplebufferdisplay path and does not fall back to BGRA/SDR rendering.
- Confirm behavior when legacy display is forced or native display fails.
Acceptance criteria
- We can state a clear support matrix for SwiftVLC HDR playback by platform and rendering path.
- Native
VideoView can successfully play at least HDR10 and/or HLG samples on real HDR hardware, or we can identify the exact blocker inside VLC/libVLC/our wrapper.
- The docs distinguish native
VideoView from PiP/custom callback rendering.
- We avoid claiming Dolby Vision or HDR10+ support unless those are independently verified.
Relevant repo locations
scripts/build-libvlc.sh pins/builds VLC 4.
Sources/SwiftVLC/Player/Player.swift attaches native views with libvlc_media_player_set_nsobject.
Sources/SwiftVLC/Video/VideoView.swift is the native view wrapper.
Sources/SwiftVLC/PiP/PiPController.swift uses libVLC video callbacks for PiP.
Sources/SwiftVLC/PiP/PixelBufferRenderer.swift currently forces BGRA pixel buffers.
Upstream references
Context
SwiftVLC is built on VLC 4, and our current libVLC build script pins upstream VLC
masteratc833c4be0.We should investigate HDR as a real product capability, but with a narrow and honest first target: native
VideoViewHDR10/HLG playback through VLC 4's Apple-native rendering path.Current understanding
VideoViewpath useslibvlc_media_player_set_nsobject, so playback is delegated to libVLC's native drawable/video-output selection.samplebufferdisplayvideo output based onAVSampleBufferDisplayLayer. It is the high-priority/default Apple display path unless legacy rendering is forced or selected as a fallback.CVPX_P010on iOS/tvOS OpenGL because native Darwin OpenGLES cannot allocate the needed >8-bit textures. Fallback paths can end up in BGRA/SDR behavior.VideoViewpath. It uses libVLC video callbacks/vmem and forces BGRACVPixelBuffers, so it should be treated as SDR-only for now.VideoView/samplebufferdisplayis the promising path.Trackalone.Proposed initial scope
Support or experimentally validate HDR playback for the native
VideoViewpath only:Out of initial scope:
PiPVideoViewValidation plan
samplebufferdisplayvs OpenGL/GLES/other fallback)videotoolboxvs software)CVPX_P010vs NV12/BGRA)VideoViewstays on VLC's Applesamplebufferdisplaypath and does not fall back to BGRA/SDR rendering.Acceptance criteria
VideoViewcan successfully play at least HDR10 and/or HLG samples on real HDR hardware, or we can identify the exact blocker inside VLC/libVLC/our wrapper.VideoViewfrom PiP/custom callback rendering.Relevant repo locations
scripts/build-libvlc.shpins/builds VLC 4.Sources/SwiftVLC/Player/Player.swiftattaches native views withlibvlc_media_player_set_nsobject.Sources/SwiftVLC/Video/VideoView.swiftis the native view wrapper.Sources/SwiftVLC/PiP/PiPController.swiftuses libVLC video callbacks for PiP.Sources/SwiftVLC/PiP/PixelBufferRenderer.swiftcurrently forces BGRA pixel buffers.Upstream references
AVSampleBufferDisplayLayervideo output: https://code.videolan.org/videolan/vlc/-/commit/629d4a343045b425cf98962c588909438a85728d