Media Foundation buffers remain locked after rejected output and input lock failures are unchecked #2835

Open
opened 2026-11-12 16:54:31 +00:00 by github-sync · 0 comments
Owner

@Arkex-ai opened on GitHub · 2026-11-12 15:56 UTC · original

Problem

The Media Foundation AV1 path in host/mf_av1.c at 51da0464b4cf0c7f56b81ebd6bb309325835e175 unlocks an output buffer only when its picture reaches the callback. A successful lock followed by a rejected pointer or pitch still needs an unlock. The input path also copies through the buffer pointer without checking whether IMFMediaBuffer::Lock succeeded, and ignores failures while setting the input length or attaching buffers to samples.

Reproduction

A Windows test uses an actual MFCreate2DMediaBuffer object and the unmodified pull function, with an authored transform returning one deliberately unsupported bottom-up RGB picture to the NV12 path. The callback correctly receives no picture, but GetScanline0AndPitch shows the buffer still locked after pull returns. The candidate balances that lock. This is rejected-picture cleanup, not evidence that an actual AV1 decoder returns bottom-up RGB or that it caused an observed game crash.

A separate game-free regression injects HRESULT failures into the actual pull and mf_av1_decode bodies. It covers 15 output/input scenarios, including normal 2D and linear buffers, the linear fallback, rejected pictures, failed locks, failed sample/buffer creation and failed buffer attachment. It checks lock counts, reference counts, callback geometry and copied input bytes. The candidate passes every case with Clang 23.1.5 on Windows; the base has behavioral failures. Invalid baseline copies are intercepted by the fixture rather than dereferenced.

Scope

Draft #2859 makes a narrow buffer acquisition/release correction, keeping decoder selection, output format, successful-picture content, GPU policy and COM initialization policy unchanged. The delivered team-room claim names this scope; private investigation preceded it. Current open-PR file inventory found no host/mf_av1.c overlap.

No gameplay run, FPS improvement or RAM-saving magnitude is claimed. The PR will remain draft until runtime validation. This is fallback hardening with no observed gameplay symptom, not a Windows-wide improvement. Windows normally tries dav1d first; MF is used when that decoder is absent or cannot open. Linux does not compile mf_av1.c. Reach and priority are left unranked pending actual incidence; the speculative worklist row and unrelated encoding change were removed in bc5078ac.

The lock contract requires one matching unlock per successful acquisition: IMF2DBuffer::Lock2D, IMFMediaBuffer::Lock.

The outstanding runtime check must explicitly use Media Foundation, identified by HOS_VIDEO_LOG, and play the intro plus a movie through its end/drain. A normal dav1d session or the native authored RGB-buffer control does not satisfy that check.

> [@Arkex-ai](https://github.com/Arkex-ai) opened on GitHub · 2026-11-12 15:56 UTC · [original](https://github.com/NotRexed/Hookshot/issues/2835) ## Problem The Media Foundation AV1 path in `host/mf_av1.c` at `51da0464b4cf0c7f56b81ebd6bb309325835e175` unlocks an output buffer only when its picture reaches the callback. A successful lock followed by a rejected pointer or pitch still needs an unlock. The input path also copies through the buffer pointer without checking whether `IMFMediaBuffer::Lock` succeeded, and ignores failures while setting the input length or attaching buffers to samples. ## Reproduction A Windows test uses an actual `MFCreate2DMediaBuffer` object and the unmodified `pull` function, with an authored transform returning one deliberately unsupported bottom-up RGB picture to the NV12 path. The callback correctly receives no picture, but `GetScanline0AndPitch` shows the buffer still locked after `pull` returns. The candidate balances that lock. This is rejected-picture cleanup, not evidence that an actual AV1 decoder returns bottom-up RGB or that it caused an observed game crash. A separate game-free regression injects HRESULT failures into the actual `pull` and `mf_av1_decode` bodies. It covers 15 output/input scenarios, including normal 2D and linear buffers, the linear fallback, rejected pictures, failed locks, failed sample/buffer creation and failed buffer attachment. It checks lock counts, reference counts, callback geometry and copied input bytes. The candidate passes every case with Clang 23.1.5 on Windows; the base has behavioral failures. Invalid baseline copies are intercepted by the fixture rather than dereferenced. ## Scope Draft #2859 makes a narrow buffer acquisition/release correction, keeping decoder selection, output format, successful-picture content, GPU policy and COM initialization policy unchanged. The delivered team-room claim names this scope; private investigation preceded it. Current open-PR file inventory found no `host/mf_av1.c` overlap. No gameplay run, FPS improvement or RAM-saving magnitude is claimed. The PR will remain draft until runtime validation. This is fallback hardening with no observed gameplay symptom, not a Windows-wide improvement. Windows normally tries dav1d first; MF is used when that decoder is absent or cannot open. Linux does not compile mf_av1.c. Reach and priority are left unranked pending actual incidence; the speculative worklist row and unrelated encoding change were removed in bc5078ac. The lock contract requires one matching unlock per successful acquisition: [IMF2DBuffer::Lock2D](https://learn.microsoft.com/en-us/windows/win32/api/mfobjects/nf-mfobjects-imf2dbuffer-lock2d), [IMFMediaBuffer::Lock](https://learn.microsoft.com/en-us/windows/win32/api/mfobjects/nf-mfobjects-imfmediabuffer-lock). The outstanding runtime check must explicitly use Media Foundation, identified by HOS_VIDEO_LOG, and play the intro plus a movie through its end/drain. A normal dav1d session or the native authored RGB-buffer control does not satisfy that check. <!-- github-sync:item:2835 -->
Commenting is not possible because the repository is archived.
No milestone
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Hookshot#2835
No description provided.