State Machine
Create/run/stop/fail/restart semantics, idempotency and recovery.
State machine
A session has exactly one legal path; any out-of-order call returns a negative error code instead of being ignored.
idle ──Start──▶ starting ──sink started──▶ recording ──Stop──▶ stopping ──verified output──▶ stopped
│ │ │
└──sink failed─────────────┴────────────────────┴──▶ error| State | Meaning | Entered by |
|---|---|---|
idle | Nothing started | initial |
starting | Options validated, sink starting | RecordingPipeline::Start |
recording | Sink ready, frames accepted | sink started |
stopping | Frames stopped, muxer finalising | Stop |
stopped | Output verified (exists, non-empty, container, duration > 0) | verification passed |
error | Start/write/verify failure | any failure; onError is raised |
Illegal transitions
| Call | Current state | Result |
|---|---|---|
Start | starting / recording / stopping | -ERR_INVALID_STATE |
PushVideoFrame | not recording | -ERR_INVALID_STATE |
Stop | not recording/starting | -ERR_INVALID_STATE |
joinChannel | a session already exists | -ERR_ALREADY_IN_USE |
leaveChannel | no session | -ERR_LEAVE_CHANNEL_REJECTED |
Why stopped cannot be faked
stopped is unreachable without a verified file: on failure the pipeline moves to error, records the code and reports it to the caller. The TestNoSilentSuccess test pins this with a sink that claims success without producing output.