Apple TV HLG Stuttering

Server Version#: 1.43.3.10896-cb3ebc72d — macOS 26.5.2, Apple Silicon (M4 Pro)
Player Version#: 8.45.9684 — Plex for Apple TV, on Apple TV 4K 3rd gen (AppleTV14,1), tvOS 27.0

Summary

The new video player in Plex for Apple TV cannot play HLG HDR content smoothly. It Direct Plays, the server does no work, the file arrives many times faster than realtime — and the picture is a staccato slideshow of a few frames per second. The same Apple TV Direct Plays HDR10 and Dolby Vision files of the same resolution, codec, profile, bit depth and frame rate, at three times the bitrate, flawlessly for hours.

The client log gives the cause directly: for HDR10 the player sets target-trc="pq" and keeps the zero-copy videotoolbox[rgbaf16] GPU surface. For HLG it sets target-trc="bt.1886" — an SDR target — which forces a tone-map, drops the frame to CPU-side yuv420p10, and re-uploads three planar textures per frame. HLG looks like it is simply missing from the check that decides a stream is HDR. Details and log lines below.

I ran controlled A/B/C tests rather than guessing, so this should be straightforward to act on.

The controlled test

Two files, identical on every axis that matters except the HDR transfer function. Both were
Direct Play — verified in the server log, so the server did precisely the same work in each case.

The Guest (2025) S01E01 Bookish (2025) S01E01
Container MKV MKV
Video HEVC Main 10, L5.1 HEVC Main 10
Resolution 3840×2160 3840×2160
Bit depth 10-bit 4:2:0 10-bit 4:2:0
Frame rate 25.000 fps CFR 25.000 fps CFR
Dolby Vision none none
Bitrate 18.3 Mb/s 15.2 Mb/s
Transfer / primaries arib-std-b67 (HLG) / BT.2020 bt709 (SDR) / bt709
Server decision direct play direct play
Result on screen severe stutter perfect

Root cause: HLG is not being treated as an HDR transfer function

This is the actionable part. I captured client logs for three Direct Play sessions on the same
device. All three report Using hardware decoding (videotoolbox). Here is the whole story in one table:

Content target-prim target-trc Decoder output format Result
SDR (bt709) bt.709 bt.1886 videotoolbox[rgbaf16] fine
HDR10 (PQ/BT.2020) bt.2020 pq videotoolbox[rgbaf16] fine
HLG (HLG/BT.2020) bt.709 bt.1886 yuv420p10 stutters

For HDR10 the player correctly targets an HDR output and the frame stays a zero-copy VideoToolbox GPU surface:

Setting MPV option target-prim="bt.2020"
Setting MPV option target-trc="pq"
[vd] v: Decoder format: 3840x2160 videotoolbox[rgbaf16] bt.2020-ncl/bt.2020/pq/limited/auto
[vf] v: [out]           3840x2160 videotoolbox[rgbaf16] rgb/bt.2020/pq/full/display
[cplayer] info: VO: [libmpv] 3840x2160 videotoolbox[rgbaf16]

For HLG the player targets an SDR output — the same target it uses for genuinely SDR content — even though the source is BT.2020 HLG:

Setting MPV option target-prim="bt.709"      <-- SDR
Setting MPV option target-trc="bt.1886"      <-- SDR
[vd] v: Decoder format: 3840x2160 yuv420p10 bt.2020-ncl/bt.2020/hlg/limited/auto
[vf] v: [out]           3840x2160 yuv420p10 bt.2020-ncl/bt.2020/hlg/limited/hlg
[cplayer] info: VO: [libmpv] 3840x2160 yuv420p10
[libmpv_render] v: Texture for plane 0: 3840x2160
[libmpv_render] v: Texture for plane 1: 1920x1080
[libmpv_render] v: Texture for plane 2: 1920x1080

Targeting BT.1886 forces an HLG→SDR tone-map. That drops the frame off the zero-copy path into CPU-side yuv420p10, which is then re-uploaded as three planar textures every frame. At 3840×2160 10-bit that is roughly 24 MB round-tripped 25 times a second — on a renderer that reports:

[libmpv_render] v: GL_RENDERER='Apple A15 GPU'  GL_VERSION='OpenGL ES 3.0 Metal - 105'
[libmpv_render] v: Disabling HDR peak computation (one or more of the following is not
                   supported: compute shaders=0, SSBO=0).
[libmpv_render] v: No advanced processing required. Enabling dumb mode.

That is the slideshow.

So: PQ is passed through to the display, HLG is not. HLG appears to be missing from whatever check decides that a stream is HDR and that the output should be switched to BT.2020. Setting target-trc="hlg" (or otherwise treating HLG as HDR passthrough, as PQ already is) should keep the videotoolbox[rgbaf16] surface and resolve this — the Apple TV 4K and tvOS both support HLG output natively.

This also explains why the 2023 report below found that disabling hardware decoding helped: it sidesteps the surface-format mismatch, at the cost of the HDR.

This is not bandwidth, and not thermal throttling

The stuttering file was delivered faster than the working one:

Bytes Time Rate Needed
The Guest (HLG, stutters) 165,593,088 4,591 ms 288.6 Mb/s 18.3 Mb/s
Bookish (SDR, fine) 180,518,912 10,805 ms 133.7 Mb/s 15.2 Mb/s

The failing file received roughly 16× realtime — the Apple TV had well over a minute of video buffered and then stopped requesting data, because its buffer was full. It was never starved.

Additional measurements on my original case (Ludwig S02E01, also HLG, also Direct Play): two attempts delivered at 70.8 Mb/s and 99.2 Mb/s against an 18.3 Mb/s file. Server load average was 1.27 with no transcoding running; the media share sustains 580 Mb/s against the 18 Mb/ s required.

Thermal throttling doesn’t fit either: this same Apple TV Direct Plays 4K HEVC 10-bit Dolby
Vision/HDR10 at 25.2 Mb/s for 95 minutes continuously without a stumble, and HDR10 at 24 Mb/s for 73 minutes. If the device were thermally limited, the heavier, longer, higher-bitrate sessions would fail first. They don’t. Only HLG fails, and it fails within seconds of starting cold.

Across my whole library and every client, HLG has been attempted once before this
investigation — and that attempt is the bug report.

“Use old video player” is not a fix — and it has a serious side effect

Enabling Settings → Use old video player makes HLG titles watchable, but it does not play HLG. It sends directPlay=0 and forces a server transcode that strips the HDR out before the Apple TV ever sees it:

scale_videotoolbox=w=3840:h=2160:format=nv12:pri=bt709:trc=bt709:csp=bt709
h264_videotoolbox -b:0 20000k

BT.2020 HLG → bt709 SDR, 10-bit → 8-bit, HEVC → H.264. So the workaround costs the HDR entirely.

More importantly, the old player refuses Direct Play for all MKV/HEVC, not just HLG. The
logged reason is no direct play video profile exists for http/mkv/hevc. I confirmed this with a 4K HEVC HDR10 title that Direct Plays perfectly on the new player:

Jurassic Park (1993) 2160p DTS-X Original Via old player
Video HEVC 10-bit HDR10, 59.3 Mb/s H.264 8-bit SDR, 20 Mb/s
Audio DTS-X AAC 5.1 @ 768 kb/s (DTS decoded in software)

So users who reach for this workaround are silently downgrading their entire 4K library and every lossless/object-based audio track. It is not a viable long-term setting.

This is not new — it has survived a full app rewrite

Reported in October 2023 against server 1.32.6.7557 and the old Apple TV app:
HLG (HDR) seems completely broken on Apple devices

That report describes the same symptom on a file with essentially the same profile as mine (MKV, HEVC Main 10@L5.1, 3840×2160, 10-bit, 25.000 fps CFR, ~18.6 Mb/s, BT.2020, HLG) and notes the same class of workaround — disabling hardware decoding, which also loses HDR. It received one reply and no fix.

Nearly three years later, on a new server generation and a completely rewritten player, it still
reproduces. The 2023 reporter also noted the same files play correctly on Windows, Nvidia Shield, Chromecast with Google TV, and in IINA on macOS — so this looks specific to Plex’s Apple playback path rather than to the files.

Steps to reproduce

  1. Add any BBC 4K WEB-DL — HEVC Main 10, 10-bit, 25 fps, BT.2020, transfer characteristic HLG (arib-std-b67), no Dolby Vision RPU.
  2. Play it on an Apple TV 4K with Plex for Apple TV 8.45, new video player, on a LAN where the server Direct Plays it.
  3. Video stutters heavily within seconds; audio continues normally.
  4. Play any SDR or HDR10 file of the same resolution/codec/frame rate — plays perfectly.

Attached

  • plex-bug-hlg-appletv-client-log-excerpt.txt — Plex for Apple TV client log for all three sessions (SDR, HDR10, HLG), showing the renderer initialisation, the target-prim/target-trc each one is given, and the resulting decoder output formats. This is the one with the cause in it.
  • plex-bug-hlg-server-log-excerpt.txt — Plex Media Server log covering all four cases: the failing HLG session, the passing SDR control, the original Ludwig session, and the old-player transcode of the HDR10 title.

plex-bug-hlg-appletv-client-log-excerpt.txt (5.3 KB)
plex-bug-hlg-server-log-excerpt.txt (8.4 KB)

Tokens, usernames, hostnames and machine identifiers are redacted in both.

Happy to supply the full unredacted logs privately, an HDR10 client-log comparison, full MediaInfo, or to test a build.

Have you tested with the new beta/preview app? The current app isn’t getting updates (hasn’t since Jan 2025) since they are eventually moving to the new experience version.

I would love to do that but I have never been able to access the tvOS preview. I have been enrolled in the iOS TestFlight for years and I have never had the tvOS version be available in the tvOS TestFlight as prescribed. I even filed a request years ago to get that fixed and no one card enough to help.

They opened up additional slots this week when they announced the updated navigation. Did you try again?

I was able to get into the Preview finally (thank you) and it does indeed solve this stuttering issue. However, the preview app is so unusable that it doesn’t matter. I literally struggled to just get the cursor to focus on the item I wanted to play. I know this is a preview, but wow. At least the bug will be fixed. But to say we need to be using a Preview app since Jan 2025 that is in this condition is not a reasonable response to a bug this serious that has existed for this long.