phase0 closed — root cause isolated to mpv vo_dmabuf_wayland plane-semantics
Eight directed A/B tests on ohm ruled out every layer that doesn't matter (libva, decoder content, color tags, kwin-fourier 0001 patch, Mesa 26.0.6 vs 26.0.5, Wayland generally, kernel 6.19.10 vs 7.0, KWin Vulkan vs OpenGL backend). WAYLAND_DEBUG=1 capture surfaced the real bug at the protocol-message layer: add(fd 41, plane=0, offset=0, stride=1920, mod=0,0) add(fd 42, plane=1, offset=2088960, stride=1920, mod=0,0) mpv mixes per-plane fds (V4L2 MPLANE export semantics) with single-allocation offset for plane 1 (single-fd export semantics). KWin reads UV from past-EOF on the UV-plane fd → all-zero NV12 → dark green render (Y=U=V=0 in BT.601/709 ≈ RGB(0,70,0)). Filed at marfrit/dmabuf-modifier-triage#1 with full diagnosis + suggested fix path. Iter1 fix work is blocked on libva-multiplanar iter9 (need clean libva path to verify which producer is at fault or whether mpv VO is the sole bug). Working interim path is mpv --hwdec=v4l2request --vo=gpu (correct picture, slow shader path). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+56
-2
@@ -2,7 +2,61 @@
|
|||||||
|
|
||||||
**Locked 2026-05-08.** Iter1 phase 0 substrate.
|
**Locked 2026-05-08.** Iter1 phase 0 substrate.
|
||||||
|
|
||||||
## Locked research question
|
> **PHASE 0 CLOSED 2026-05-08** — root cause isolated within hours of opening, faster than expected. See "Phase 0 conclusion" below. The original deliverables list (modifier captures, A/B tests) is preserved as historical record; the elimination ladder went deeper than the planned items but landed at a clear answer.
|
||||||
|
|
||||||
|
## Phase 0 conclusion
|
||||||
|
|
||||||
|
**Root cause:** mpv's `vo_dmabuf_wayland.c` constructs the `zwp_linux_buffer_params_v1` protocol message with **internally inconsistent plane semantics** — different fds per plane (V4L2 MPLANE export semantics) combined with single-allocation offset for plane 1 (single-fd export semantics). KWin imports plane 1 from the wrong byte address, reads zeros for the UV chroma plane, and the all-zero NV12 buffer renders as dark green. Filed at [marfrit/dmabuf-modifier-triage#1](https://git.reauktion.de/marfrit/dmabuf-modifier-triage/issues/1).
|
||||||
|
|
||||||
|
**Trace (one buffer cycle, abbreviated):**
|
||||||
|
|
||||||
|
```
|
||||||
|
create_params #54
|
||||||
|
add(fd 41, plane=0, offset=0, stride=1920, modifier=0,0) ← Y plane
|
||||||
|
add(fd 42, plane=1, offset=2088960, stride=1920, modifier=0,0) ← UV plane
|
||||||
|
create_immed(wl_buffer#56, 1920, 1080, NV12, flags=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
`1920×1088 = 2088960` is the size of the Y plane (height-aligned 1080→1088). Correct offset for "both planes in one allocation"; wrong when plane 1 is in its own fd.
|
||||||
|
|
||||||
|
**Color analysis** — why all-zero NV12 = dark green specifically: Y=0 + U=0 + V=0 in BT.601/709 → RGB ≈ (0, 70, 0), which is the dark green the user reported.
|
||||||
|
|
||||||
|
**Layers ruled out via directed A/B (in order):**
|
||||||
|
|
||||||
|
| Layer | Verdict | Test |
|
||||||
|
|---|---|---|
|
||||||
|
| libva | not the cause | `--hwdec=v4l2request` (libva-bypassed) also greens |
|
||||||
|
| Decoder content | correct | `--vo=gpu --hwdec=v4l2request` shows real picture |
|
||||||
|
| Color tagging / HDR PQ | not the cause | `--target-colorspace-hint=no` + explicit BT.709 SDR triple no effect |
|
||||||
|
| kwin-fourier 0001 (`watchDmaBuf` bypass) | exonerated | stock arch `kwin` also greens |
|
||||||
|
| Mesa 26.0.6 vs 26.0.5 | exonerated | downgrade to 26.0.5 still greens |
|
||||||
|
| Wayland / KWin generally | exonerated | `--vo=wlshm` shows correct picture |
|
||||||
|
| Kernel besser-7.0 vs pinetab2-6.19.10 | exonerated | boot.scr swap + reboot, both kernels green |
|
||||||
|
| KWin Vulkan vs OpenGL backend | exonerated | qdbus6 confirms KWin runs OpenGL + Mesa-panfrost (same path mpv's vo=gpu uses successfully) |
|
||||||
|
|
||||||
|
**Why the layer-strip works the way it does:**
|
||||||
|
|
||||||
|
- mpv's `vo=gpu` is fine because it imports the dmabuf via libva's `vaExportSurfaceHandle` / ffmpeg's `av_hwframe_transfer_data` directly into mpv's own EGL context — those APIs return *correct* per-plane structure.
|
||||||
|
- mpv's `vo=dmabuf-wayland` is the unique broken path because it constructs the wl_dmabuf protocol message itself, mishandling the producer's plane semantics.
|
||||||
|
- mpv's `vo=wlshm` is fine because it goes through CPU memcpy, bypassing the dmabuf protocol entirely.
|
||||||
|
|
||||||
|
**Deferred verifier (gates iter1's actual fix):**
|
||||||
|
|
||||||
|
Re-run the WAYLAND_DEBUG capture with `--hwdec=vaapi` (libva path) once `libva-v4l2-request-fourier#1` is fixed and the cap_pool/REQBUFS cascade stops blocking libva playback. If both paths produce the same wrong `.add()` pattern → bug is purely in mpv VO. If only one does → that path's producer (libva or ffmpeg V4L2 hwaccel respectively) is the bug.
|
||||||
|
|
||||||
|
This means iter1's fix work cannot start until libva-multiplanar iter9 lands. dmabuf-modifier-triage iter1 is **blocked-on**: libva-multiplanar/iter9.
|
||||||
|
|
||||||
|
**Working ohm HW-decode workflow until fix lands:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mpv --hwdec=v4l2request --vo=gpu fourier-test/bbb_1080p30_h264.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
Correct picture, slow due to GPU shader path on Mali-G52. Documented as the campaign's interim recommended path.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Locked research question (original — superseded by Phase 0 conclusion above)
|
||||||
|
|
||||||
> Identify the layer responsible for the dmabuf-wayland green on ohm —
|
> Identify the layer responsible for the dmabuf-wayland green on ohm —
|
||||||
> libva (`vaExportSurfaceHandle` modifier reporting), ffmpeg V4L2 request
|
> libva (`vaExportSurfaceHandle` modifier reporting), ffmpeg V4L2 request
|
||||||
@@ -11,7 +65,7 @@
|
|||||||
> hantro driver (buffer attribute reporting). File upstream where
|
> hantro driver (buffer attribute reporting). File upstream where
|
||||||
> appropriate; fix what's locally in scope.
|
> appropriate; fix what's locally in scope.
|
||||||
|
|
||||||
Bug tracker: [marfrit/libva-multiplanar#1](https://git.reauktion.de/marfrit/libva-multiplanar/issues/1).
|
Bug tracker: [marfrit/libva-multiplanar#1](https://git.reauktion.de/marfrit/libva-multiplanar/issues/1) (user-visible symptom). Root-cause issue: [marfrit/dmabuf-modifier-triage#1](https://git.reauktion.de/marfrit/dmabuf-modifier-triage/issues/1) (mpv vo_dmabuf_wayland plane-semantics).
|
||||||
|
|
||||||
## Reproduction (verbatim from issue tracker)
|
## Reproduction (verbatim from issue tracker)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user