Skip to content

Slice 4 Review

Retrospective review of slice 4 per docs/13 and docs/20, run before the slice was committed. The slice puts the first real capability on real sources: fjarr.camera reads its tracks from config, resolves each source = … through the agent’s registry (built-in gst/test/v4l2/ rtsp and types the embedding application registered), and the demo robot streams a pattern, the lab’s RTSP simulator and — with an opt-in override — the host webcam. One reviewer pass on the C++ and the harness, plus what the lab and the unit tests found while it was built.

Found byDefectFix
lab rtsp test, second runthe second start of an rtsp producer streamed 3 fps: after the tier grace set the pipeline to NULL, decodebin rebuilt its pads and the ghost pad kept its stale targeta shared late-ghost helper for decodebin-based bins re-targets when the current target’s pad is gone (docs/23)
lab /sources testconfigured sources were invisible until a session registered their tracks, so the docs/26 “missing device, with the reason” behaviour had nothing to show a doctor or a dashboardCapability::configured_sources() and VideoSource::unavailable_reason() (docs/09); /sources lists configured sources first, the plane adds caps and tiers once a track is registered
lab, three viewerspresented-frame counts of 3–16 per two seconds with two VA-API producers on this host’s iGPU (the 3c throttle state); identical code streams 30 fps to every viewer on the software encodernot a code defect: two hardware encodes at the floor clock; the software path (CI’s) is the gate, the GPU runner measures VA-API
#SeverityFindingResolution
1highonly format = "mjpeg" v4l2 sources could stream: yuyv and auto+size ended the description in a bare caps string (does not parse), and auto without a size let the parser ghost decodebin’s internal typefind padevery form emits an explicit capsfilter; auto without a size decodes through the same late-ghost helper as rtsp; a test builds a bin with a src pad for every form
2highunplugging a camera did not remove its track (the hot-plug callback re-offered the full set and the core skips ids already offered), while the producer’s bus error walked the restart ladder into a plane rebuild that closed every sessionthe callback re-offers only what is available (the core’s diff removes the rest, valve first); a producer error from inside the source bin is the track’s failure: slow retry (1 s → 30 s), reported as the track’s reason, never a plane rebuild (docs/23); loop test with identity error-after inside the source bin
3highan unreachable RTSP camera was offered, failed asynchronously and took the agent down the same ladder (every session closed, exit 2 within minutes)same classification: its track degrades with the bus error as reason
4highthe camera lab tests read stamps that are painted only for fjarr.test trackspresented frames (readable or not) are what the camera tests count; watchers start once the video element exists
5mediuman RTSP camera announcing audio first would give decodebin’s single sink to the audio streamrtspsrc::select-stream accepts video only (documented: video only in slice 4)
6medium--check skipped the schema validation the agent runs and could abort on a track without sourcefjarr::validate_json_schema (public, the same the agent uses), every failure printed, never an abort
7mediumconfigure() cleared state before it could throwbuilt aside, swapped in at the end
8mediumthe hot-plug trampoline could let an exception unwind through GLibcaught and logged, as the kit’s trampolines do
9mediumthe demo’s webcam default and the override could not exercise real hot-plug (a container’s devices: are static) and the gate text implied they coulddocs/12 and the docs/23 gate say bare metal; FJARR_DEMO_WEBCAM documented
10mediumdocs/06 put output inside the source table; the code reads it beside sourcedocs/06 corrected and extended with required, v4l2 and rtsp forms
11mediumthe 500 ms re-enable measurement included Playwright’s polling backoffpolled at 20 ms on the freshly mounted video
—lowan empty device indexed a string; the rtsp pad-added connection is per source, not per bin (latent, the plane serializes producers); GIO polls a missing by-id directory (~4 s)minLength: 1 and a guard; comments; docs/23 note

Checked and found fine: the RAII gate over the new code; the targetless ghost linked before its target exists (frames flow once pad-added sets it); GIO monitors created with the core context as thread-default (the unit test asserts the callback runs on the loop); session_detached ordering against the hot-plug callback; the plane’s registration refcounts through update_tracks; docs/09 against the headers; the dev-only packages in docs/14; rtsp-sim started by CI through depends_on.

  1. Three lab pages watch pattern and rtsp of the demo robot at once (one producer per track, three hub subscribers each); a toggle takes effect without renegotiation and re-enabling shows a frame well under 500 ms (the hub’s ring catch-up).
  2. The RTSP track streams from the simulator in CI; the v4l2 track with no device is missing with no such device: … in /sources and absent from the manifest; arrival and departure re-offer every session (unit test on a by-id directory, with a recording session context); a source that errors degrades its own track only (loop test).
  3. --probe-source reports caps, memory type and fps for test, a description, the RTSP simulator (26.5 fps decoded) and a missing v4l2 device with its reason; --check prints a row per configured source and fails on a required one that is missing.
  4. Every 3b/3c gate green on the software path, the soak included.
  • Elementary-stream passthrough for cameras that encode on board (an rtsp source decodes today), loss recovery and adaptive bitrate: slice 6.
  • Real hot-plug through the compose override (Docker cannot hot-plug a devices: node): bare metal and the GPU runner.
  • Audio outputs of a source (fjarr.audio).