Closed general

desktop_record_start: encoder init timeouts and WriteSample sample-allocator failure (0xC00D4A3E) after another recorder hung

John Lauer · 1mo ago ·closed by John Lauer

What happened (Adom Bridge 2.1.170 on AdomLapper, Windows, NVIDIA GPU, 2026-10-07)

While recording a ~3 min screen capture for a video, desktop_record_start failed repeatedly, then later worked:

  1. {"monitor":"primary","fps":30,"codec":"h265","audio":false}: error: encoder init timed out: timed out waiting on channel.
  2. The same with codec: h264, and with defaults: client-side Request timed out (20 s), also with timeoutSeconds: 90 (gave up at ~47 s). desktop_record_status showed 0 running each time, so nothing was left registered.
  3. {"hwnd":<Hydrogen>} (window capture) started (ok, ~22 s), but desktop_record_stop later returned record_failed: Recording finished with an encoder error: WriteSample failed at frame 367: The sample allocator is currently empty, due to outstanding requests. (0xC00D4A3E). Only 367 frames were kept, ending before the content we wanted.
  4. With {"codec":"h264","gpu":false} (software path): Request timed out again.
  5. About 30 minutes later, with nothing restarted, desktop_record_start {"monitor":"primary"} worked first time (876 ms). Two full 3+ minute takes followed at a steady 30 fps, 0 dropped frames, 0 backlog, and finalised cleanly.

Just before the failures, Hydrogen's own native recorder (WGC + MFT) had hung on stop and left an unfinalised file (companion issue on adom/hydrogen). Our guess is a hardware encoder session was left held, and the bridge's MFT init or allocation waited on it until it was released.

Asks

  1. When encoder init can't get a hardware session, fail fast with a clear errorCode (e.g. encoder_busy) and a hint ("another process holds the GPU encoder; close other recorders, or retry with gpu:false"), instead of a timeout with no take registered.
  2. On WriteSample sample-allocator exhaustion, recover (drain or retry) or fall back to software encoding, instead of ending the take; at least keep the frames up to the failure finalised.
  3. Make gpu:false (Media Foundation software H.264) truly independent of the hardware path, so it works as a fallback while the GPU encoder is busy.
  4. desktop_record_encoders should report "available but busy", not just "available".

1 Reply

John Lauer · 1mo ago

Shipped in 2.1.171 (insiders now).

  1. Fail fast. If the video encoder does not start within 8 s, desktop_record_start answers errorCode: encoder_busy immediately: "Another program is probably holding it ... close other recorders, or retry with gpu:false". The "Request timed out" in the report was ab itself: after the 8 s init timeout it then waited for the encoder thread, which was stuck in the driver, so the request hung until the caller gave up. It now detaches that thread and answers.
  2. Sample allocator empty. WriteSample returning 0xC00D4A3E is back-pressure, not a broken take. The tick is dropped (counted in droppedFrames) and recording continues. Only a run long enough to mean the encoder is gone (about 10 s) ends the take.
  3. gpu:false is really independent now. It used to switch only the frame path; the encoder was still NVENC. It now leaves hardware transforms off, so Media Foundation uses the software H.264 encoder. Checked on arav-rog: gpu:true → NVIDIA H.264 Encoder MFT, hardwareEncoder: true; gpu:false → H264 Encoder MFT, hardwareEncoder: false.
  4. Not done: reporting "available but busy" in desktop_record_encoders. Media Foundation offers no way to ask whether a hardware session is free without opening one, so the honest signal is the fast encoder_busy at start.

I could not reproduce the hung-encoder state on purpose, so items 1 and 2 are checked by code path rather than by a live repro.

John Lauer closed this · 1mo ago

Log in to reply.