fix(webcam): reader-output-subtype ladder + record WinRT per-call wrap rule
A browser grabbing the C920 kills our reader startup: the camera stays in MJPG 1920x1080@30 (another app's format) and our OBS-refusal to re-negotiate under SharedReadOnly contention (`SetMediaStreamPropertiesAsync` throws 'file in use / CaptureMode is SharedReadOnly') leaves it there. CreateFrameReaderAsync(.., Bgra8) + StartAsync then refuses with OutputFormatNotSupported — the MJPG-active source only exposes NV12 at the reader level (clue: startup.log 19:01/19:05 sessions, same hardware that started YUY2 640x480 fine at 08:52). Fresh launches showed no webcam and 'Add Webcam' failed. Reader creation is now a per-candidate ladder (ReaderSubtypeCandidates): Bgra8 for uncompressed cameras (unchanged fast path); NV12 then the source-default for MJPG cameras — converted in OnFrameArrived like any non-BGRA frame. Each candidate is allocated AND started under its OWN catch: WinRT answers an unsupported subtype with a throw (E_INVALIDARG), not a status, so a single rejected format must degrade to the next candidate instead of aborting acquisition (creator rule — see MyMistakes WINRT resource-allocation recipe). Rejections are logged and collected into the final error. Good Dog: 4 unit tests lock the candidate ordering (MJPG never Bgra8, case-insensitive, uncompressed keeps Bgra8 first, unknown/null -> Bgra8). 301/301 green, 0 warnings. [no push]
This commit is contained in:
@@ -385,6 +385,18 @@ This replaces the old five-seeder cluster (`Seed{Starting,Brb,Ending,Chat}Backgr
|
||||
`CreateFrameReaderAsync(colorSource, MediaEncodingSubtypes.Bgra8)` — the pipeline does any format
|
||||
conversion, so every `FrameArrived` yields a ready BGRA8 `SoftwareBitmap` (bytes read via
|
||||
`WindowsRuntimeMarshal.TryGetDataUnsafe`, not marshalled copies).
|
||||
- **Reader-output subtype ladder (2026-09-15 webcam-take fix):** the reader is created per-candidate
|
||||
by `ReaderSubtypeCandidates(activeSubtype)` — Bgra8 for uncompressed cameras (fast path), NV12 then
|
||||
source-default for cameras sitting in MJPG. A camera another app left in MJPG mode cannot be read as
|
||||
Bgra8 by a `MediaFrameReader` (`StartAsync` → `OutputFormatNotSupported`; the MJPG pipeline exposes
|
||||
NV12, not BGRA) — exactly what a browser grabbing the webcam produces. When the app can't re-negotiate
|
||||
(our `SetMediaStreamPropertiesAsync` refuses with "file in use / CaptureMode is SharedReadOnly" under
|
||||
msedge + NVIDIA Broadcast contention), an MJPG-active reader otherwise aborts the whole acquisition.
|
||||
Each candidate is allocated AND started under its OWN catch — WinRT answers an unsupported subtype
|
||||
with a THROW (`E_INVALIDARG`), not a status; one rejected format must never abort the ladder. Failures
|
||||
degrade to the next candidate; rejections are logged + collected into the final error; only the outer
|
||||
catch nets device-level errors (see `MyMistakes.md` → WINRT RESOURCE-ALLOCATION RECIPE). Anything not
|
||||
Bgra8 is converted in `OnFrameArrived`, which already handled non-BGRA software bitmaps.
|
||||
- **Source pick, not first hit:** the frame reader is bound to the first source that is `VideoPreview`
|
||||
(preferred) or `VideoRecord`, not blindly the first preview source. If a camera exposes neither, the
|
||||
failure names the device and the stream types it *does* expose. `SharedReadOnly` lets the capture
|
||||
|
||||
Reference in New Issue
Block a user