input testing
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 3m2s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
Aiden
2026-05-12 20:06:23 +10:00
parent 2c5e925b97
commit ce28904891
19 changed files with 911 additions and 198 deletions

View File

@@ -40,11 +40,11 @@ Startup warms up real rendered frames before DeckLink scheduled playback starts.
Included now:
- output-only DeckLink
- optional DeckLink input edge with BGRA8 capture or UYVY8-to-BGRA8 CPU conversion
- non-blocking startup when DeckLink output is unavailable
- hidden render-thread-owned OpenGL context
- simple smooth-motion renderer
- BGRA8-only output
- synthetic BGRA8 input producer
- non-blocking latest-frame input mailbox
- render-thread-owned input texture upload
- async PBO readback
@@ -74,7 +74,6 @@ Included now:
Intentionally not included yet:
- real DeckLink input capture
- input format conversion
- temporal/history/feedback shader storage
- texture/LUT asset upload
@@ -118,12 +117,12 @@ This tracks parity with `apps/LoopThroughWithOpenGLCompositing`.
- [x] Runtime parameter updates from HTTP controls
- [x] Layer reorder/bypass/set-shader/update-parameter/reset-parameter HTTP controls
- [x] Trigger parameter pulse count/time for latest trigger events
- [x] Synthetic BGRA8 frame input producer
- [x] Optional DeckLink input capture
- [x] UYVY8-to-BGRA8 input conversion
- [x] Latest-frame CPU input mailbox
- [x] Render-owned input texture upload
- [x] Runtime shaders receive input through `gVideoInput`
- [ ] DeckLink input capture
- [ ] Live DeckLink input bound to `gVideoInput`
- [x] Live DeckLink input bound to `gVideoInput`
- [ ] Input format conversion/scaling
- [ ] Temporal history buffers
- [ ] Feedback buffers
@@ -240,6 +239,20 @@ If DeckLink discovery or output setup fails, the app logs a warning and continue
`/api/state` reports the output status in `videoIO.statusMessage`.
## Optional DeckLink Input
DeckLink input is an optional edge service in this app.
Startup order is:
1. create `InputFrameMailbox`
2. try to attach DeckLink input for the configured input mode
3. prefer BGRA8 capture, otherwise accept UYVY8 capture and convert to BGRA8 before the mailbox
4. start `DeckLinkInputThread`
5. leave input absent if discovery, setup, format support, or stream startup fails
`DeckLinkInput` and `DeckLinkInputThread` are deliberately narrow. They capture BGRA8 frames directly or convert UYVY8 frames to BGRA8 before submitting to `InputFrameMailbox`; they do not call GL, render, preview, screenshot, shader, or output scheduling code. Unsupported input modes or formats outside BGRA8/UYVY8 are reported explicitly and treated as an unavailable edge rather than silently converted.
The app samples telemetry once per second.
Normal cadence samples are available through `GET /api/state` and are not printed to the console. The telemetry monitor only logs health events:
@@ -248,6 +261,24 @@ Normal cadence samples are available through `GET /api/state` and are not printe
- warning when schedule failures increase
- error when the app/DeckLink output buffer is starved
Input telemetry:
- `inputFramesReceived`: frames accepted into `InputFrameMailbox`
- `inputFramesDropped`: ready input frames dropped or missed because the mailbox was full
- `inputLatestAgeMs`: age of the newest submitted input frame
- `inputUploadMs`: render-thread GL upload time for the latest uploaded input frame
- `inputFormatSupported`: whether the latest frame reaching the render upload path was BGRA8-compatible
- `inputSignalPresent`: whether any input frame has reached the mailbox
- `inputCaptureFps`: DeckLink input callback capture rate
- `inputConvertMs`: input-edge UYVY8-to-BGRA8 conversion time for the latest converted frame
- `inputSubmitMs`: time spent submitting the latest captured/converted input frame to `InputFrameMailbox`
- `inputCaptureFormat`: selected DeckLink input format (`BGRA8`, `UYVY8`, or `none`)
- `inputNoSignalFrames`: DeckLink callbacks reporting no input source
- `inputUnsupportedFrames`: input frames rejected before mailbox submission
- `inputSubmitMisses`: input frames that could not be submitted to the mailbox
Runtime shaders continue rendering when input is missing. If no mailbox frame has been uploaded yet, shader samplers use the runtime fallback source texture; once DeckLink input is flowing, shaders such as CRT and trigger-ripple sample the real/latest input through `gVideoInput`.
Healthy first-run signs:
- visible DeckLink output is smooth
@@ -282,10 +313,18 @@ Current runtime shader support is deliberately limited to stateless full-frame p
- HTTP controls can update runtime parameter values without rebuilding GL programs when the shader program is unchanged
- trigger parameters are treated as latest-pulse controls: each press increments the trigger count and records the current runtime time
- repeated trigger history is not stored yet, so effects such as `trigger-ripple` restart from the latest trigger rather than accumulating overlapping ripples
- the first layer receives a small fallback source texture until DeckLink input is added
- the first layer receives the latest synthetic input texture through both `gVideoInput` and `gLayerInput` when input frames are available
- the first layer receives a small fallback source texture until DeckLink input is available
- the first layer receives the latest DeckLink input texture through both `gVideoInput` and `gLayerInput` when input frames are available
- stacked layers receive the original input through `gVideoInput` and the previous ready layer output through `gLayerInput`
Shader source semantics:
- `gVideoInput` means the raw latest input frame for every layer.
- `gLayerInput` means the previous layer output.
- the first layer may receive `gLayerInput = gVideoInput`.
- later layers receive `gVideoInput = original input` and `gLayerInput = previous layer`.
- named intermediate pass inputs inside a multipass layer are still routed through the selected pass-source slot; layer stacking should use `gLayerInput`.
The `/api/state` shader list uses the same support rules as runtime shader compilation and reports only packages this app can run today. Unsupported manifest feature sets such as temporal, feedback, texture-backed, font-backed, or text-parameter shaders are hidden from the control UI for now.
Runtime shaders are exposed through `RuntimeLayerModel` as display layers with manifest parameter definitions, current parameter values, build status, and render-ready artifacts. POST controls mutate this app-owned model and may start background shader builds when the selected shader changes.
@@ -341,7 +380,6 @@ This app keeps the same core behavior but splits it into modules that can grow:
- `platform/`: COM/Win32/hidden GL context support
- `render/`: cadence thread, clock, and simple renderer
- `frames/InputFrameMailbox`: non-blocking latest-frame CPU input handoff
- `video/SyntheticInputProducer`: temporary BGRA8 test-pattern producer for proving the frame-input path
- `render/InputFrameTexture`: render-thread-owned upload of the latest CPU input frame into GL
- `render/readback/`: PBO-backed BGRA8 readback and completed-frame publication
- `render/runtime/RuntimeRenderScene`: render-thread-owned GL scene for ready runtime shader layers
@@ -365,4 +403,4 @@ Only after this app matches the probe's smooth output:
3. port runtime snapshots/live state
4. add control services
5. add preview/screenshot from system-memory frames
6. replace synthetic input with DeckLink input capture into the existing CPU latest-frame mailbox
6. add scaling and additional input format support after the BGRA8/UYVY8 input edge is stable