Skip to content

Fix camera capture: pass ppv to IMFActivate::ActivateObject - #132

Closed
btsouth wants to merge 1 commit into
masterfrom
fix/camera-activateobject-capture
Closed

btsouth wants to merge 1 commit into
masterfrom
fix/camera-activateobject-capture

Conversation

@btsouth

@btsouth btsouth commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

The camera bridge never captured a frame. IMFActivate::ActivateObject was called with three arguments instead of two, so the arguments shifted and ppv was NULL. The call returned E_POINTER (0x80004003).

Live evidence from the v0.0.20 re-test (launcher afdcd7a2…), by talking to the launcher's own camera bridge on 127.0.0.1:4453:

{"status":"unavailable","reason":"the camera could not be opened (0x80004003)"}

Because source.start() always failed, the launcher reported the camera as unavailable and the guest kept the black frame its bridge primes on purpose. No crash, just no picture.

Changes

  • app/camera_mf_windows.go: ask IMFActivate::ActivateObject for IID_IMFMediaSource and pass the destination pointer, dropping the stray third argument. The result is handed straight to MFCreateSourceReaderFromMediaSource, so IMFMediaSource is the interface it wants.
  • Fix the source-reader flush: IMFSourceReader::Flush is vtable slot 10; the code called slot 8, which is SetCurrentPosition, invoked there with a bogus REFGUID.

Why the existing tests missed it

TestMediaFoundationExportsResolve only checks that the entry points resolve. CI has no camera, so the call itself was never exercised.

Test plan

  • Windows CI compiles (GOOS=windows go build)
  • Re-test on the laptop with a real camera once built: the bridge should report streaming, /dev/video42 should show the real camera, and journalctl --user -u omarchy-windows-camera-bridge -b should log streaming Windows Camera at 1280x720.

The Flush slot fix is not observable from the happy path, but the current slot is clearly wrong.

Related: direct file drops on this same pass are blocked by a separate issue — the launcher tries to subclass QEMU's window from another process, which Windows does not allow. The runtime already reports drops over QMP (DISPLAY_FILE_DROP), so that is the path to fix separately.

…rity

ActivateObject takes (riid, ppv); the call passed three arguments, so the extra one shifted the arguments and ppv was NULL. The call returned E_POINTER (0x80004003), the bridge reported the camera as unavailable, and the guest kept the black frame it primes on purpose. Ask for IID_IMFMediaSource and drop the stray argument.

Also fix the source reader flush: IMFSourceReader::Flush is vtable slot 10, not 8 (slot 8 is SetCurrentPosition).
@btsouth

btsouth commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks. The camera fix landed in #137, including the ActivateObject signature and Flush vtable slot. Closing as superseded.

@btsouth btsouth closed this Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant