5 Commits

Author SHA1 Message Date
Arkadiusz Fal
6aa5fd8ee7 Fix periodic tvOS playback stutter from render stalls on mpvQueue
Build 264 stutters for a split second every ~10 seconds. The periodic
playback-stats task fetches ~30 debug properties in one ~190ms block on
mpvQueue, and MPVClient.render() wrapped mpv_render_context_render in
mpvQueue.sync - so the render thread queued behind the fetch and stalled
~190ms, at exactly the stats interval. Build 261 predates the stats
task, which is why it was unaffected.

libmpv's render API is documented thread-safe relative to the client
API, so render-context calls no longer go through mpvQueue:

- New renderContextLock protects renderContext lifecycle vs use;
  render(), renderWithDepth(), renderSoftware(), reportSwap(),
  shouldRenderUpdateFrame() and hasRenderContext use it
- Render-update callbacks dispatch on a dedicated renderEventQueue so
  frame-ready notifications can't queue behind property/command work
- destroyRenderContext takes mpvQueue then the lock, still excluding
  in-flight renders during teardown
- The stats task skips its property fetch on iOS/tvOS unless verbose
  MPV logging is on (macOS keeps it for the render watchdog)
- performRender slow-frame warnings now break down render vs present
  time and report frame-delivery gaps for future triage
2026-07-19 00:53:06 +02:00
Arkadiusz Fal
4effe5d7a5 Fix low-FPS iOS PiP by reporting swaps while PiP is active
Since 1d9c5e3b performRender feeds swap timing to mpv via
mpv_render_context_report_swap, but only after presentRenderbuffer -
which is skipped while PiP is active. Once swap reports stop mid-stream,
display-vdrop's vsync estimation goes stale and mpv drops nearly every
frame (vo drop counter climbing ~19/s on a 24fps stream), turning PiP
into a slideshow.

The frame is genuinely displayed during PiP via the
AVSampleBufferDisplayLayer, so report the swap on that path too.
2026-06-15 09:26:43 +02:00
Arkadiusz Fal
76e5220c95 Fix no video on iOS/tvOS devices after GL two-thread hardening
1d9c5e3b removed the main-thread EAGLContext bind from setupAsync so
the context is never left current on two threads. But libmpv's
mpv_render_context_create requires a current GL context on the calling
thread (it probes glGetString(GL_VERSION)), so render context creation
failed with MPV_ERROR_UNSUPPORTED (-18) and every video played with no
--vo ("No render context set") on real iOS/tvOS devices.

Bind the context around the createRenderContext call and unbind right
after. The bind is scoped to setup, before the display link starts and
before any frame is rendered, so the never-left-current invariant that
protects the A10X fence fix (#947/#949) still holds.

Verified on Apple TV 4K (3rd gen): createRenderContext succeeds and
video frames render.

Claude-Session: https://claude.ai/code/session_01UEXP5f6F4S1zLdY8fdVuLJ
2026-06-04 21:24:43 +02:00
Arkadiusz Fal
fa6ad2235c Fix tvOS GL render pipeline defects behind A10X IOFence crash
Apple TV 4K 1st gen on tvOS 26 crashes to the home screen with a
"blocked by IOFence" gpuEvent at playback start (#949) and stutters
with a starved demuxer cache (#947). Defensive fixes in the shared
iOS/tvOS OpenGL path:

- Drain in-flight GPU work (glFinish) before destroying the
  renderbuffer, so a pending presentRenderbuffer fence can't hold the
  CAEAGLLayer IOSurface being torn down or reallocated
- Never leave the EAGLContext current on the main thread: framebuffer
  create/destroy and the background glFinish now unbind on exit, and
  setup no longer binds the context on main at all
- Disable retained backing on tvOS; it exists only for iOS PiP frame
  capture and adds per-frame IOSurface fence pressure
- Report swaps to mpv after each present so display-vdrop (the tvOS
  default video-sync) gets swap-timing feedback, matching macOS

Add verbose-gated diagnostics for remote triage: playback stats every
10s (cache fill/rate, dropped frames, hwdec, avsync) and a rate-limited
slow-frame warning in performRender.

Addresses #949 and #947
2026-05-31 11:27:09 +02:00
Arkadiusz Fal
100df744d9 Yattee v2 rewrite 2026-04-18 20:37:24 +02:00