docs: add v0.3.0-dragonfork CHANGELOG entry
Some checks failed
ci / race tests (push) Blocked by required conditions
ci / WebRTC smoke (5-viewer fanout) (push) Blocked by required conditions
ci / WebRTC latency p95 gate (push) Blocked by required conditions
ci / vet + build (push) Has been cancelled

Covers WHIP ingest backend, keyframe cache, Wild Dragon UI WHIP toggle,
seed-data.sh always-overwrite fix, and the full core/webrtc test suite.
This commit is contained in:
Zac Gaetano 2026-05-10 13:06:06 -04:00
parent 228ed4b09b
commit c4857f5581

View file

@ -1,5 +1,94 @@
# Datarhei — Dragon Fork
## v0.3.0-dragonfork (2026-05-10)
WebRTC ingest (WHIP) milestone. Browsers and OBS can now push a
WebRTC stream into a channel, and the first-frame experience for WHEP
viewers is dramatically improved by the in-memory keyframe cache.
Resolves issues #15, #16, #17.
### Added
- **WHIP ingest path** — browsers and OBS Studio can push a WebRTC
stream (H.264 + Opus) into any Dragon Fork channel via
`POST /api/v3/whip/{id}`. The publisher sends an SDP offer; Core
answers, allocates a loopback UDP pair, and injects RTP input legs
into the FFmpeg command line — the exact mirror of the WHEP egress
path. `DELETE /api/v3/whip/{id}/{resource}` tears down the publisher
cleanly. Closes #16.
- **`ProcessConfigWHIPIngest` API struct** in `http/api/process.go`
mapping `whip_ingest.{enabled,video_pt,audio_pt}` between the JSON
API and `app.ConfigWHIPIngest`. Without this struct, `WHIPIngest.Enabled`
was always false and WHIP could never activate via the API.
- **WHIP ingest lifecycle hooks**`onWHIPProcessStart` /
`onWHIPProcessStop` in `app/webrtc/whip_lifecycle.go` allocate and
teardown the ingest UDP port pair, controlled by the per-process
`whip_ingest.enabled` flag. Merged via `MergedHooks()` alongside the
existing WHEP egress hooks.
- **Wild Dragon UI — WHIP toggle control** (`overlay/src/misc/controls/WHIP.js`
in the `wilddragon-restreamer-ui` overlay). Mirrors WHEP.js exactly.
Renders an Enable checkbox with caption in the channel edit view.
- **Wild Dragon UI — Edit/index.js wiring** — renders the WHIP control
in the Edit view and patches `props.restreamer._upsertProcess` in the
`save()` handler to inject `whip_ingest.enabled` into the process
config before the SDK PUT reaches Core. The patch is required because
the Restreamer SDK's `UpsertIngest` does not forward `webrtc` or
`whip_ingest` fields (SDK gap).
- **In-memory H.264 keyframe cache** in `core/webrtc/keyframecache.go`.
Retains the most recent IDR burst (all RTP packets from the first IDR
NAL fragment until the next one) per video Source. Bounded at 512
packets / 2 MiB. Detects single-NAL IDR (type 5) and FU-A start
fragments (type 28, start bit set, inner type 5). Closes #17.
- **Subscribe pre-fill**`Source.Subscribe()` snapshots the keyframe
cache before registering the new subscriber, then drains the burst
into the channel immediately. New WHEP peers receive a complete
reference frame on join instead of waiting up to one GOP (≈ 2 s at
30 fps / GOP=60).
- **`Source.EnableKeyFrameCache()`** — opt-in method; called only on
video sources in `allocAdjacentPair()`. Audio sources are
intentionally uncached (Opus payloads would accumulate without ever
triggering a reset).
- **Test suite for `core/webrtc`**`keyframecache_test.go` (18
functions) and `source_test.go` (5 functions). Covers IDR detection
in all packetisation modes, cache reset, burst accumulation, capacity
caps, snapshot independence, concurrent read/write under `-race`, and
Subscribe pre-fill behaviour. All 34 tests in `core/webrtc` green
under `go test -race`.
### Fixed
- **`deploy/truenas/core/seed-data.sh`** — the old no-clobber-only
approach kept stale JS bundles alive on the data volume after image
rebuilds (`static/` was never refreshed because it already existed).
Fixed by splitting into two phases: always-overwrite for `index.html`,
`asset-manifest.json`, and `static/`; no-clobber for everything else
(channel data, player bundles, operator content). Prevents a class of
"new code never runs" deployment bugs.
### Upgrade (from v0.2)
```sh
cd deploy/truenas/core
git pull
docker compose build --no-cache core
docker compose up -d core
```
The `seed-data.sh` fix means there is no longer a need to manually
`docker exec` a static-bundle copy after rebuilds — it happens
automatically on container start.
---
## v0.2 backlog (2026-05-06)
Completes the open v0.2 issues from the post-GUI-ship backlog.