2.4 KiB
2.4 KiB
Group call: WASM Opus FEC / PLC decode path
Receive-side decoding can use libopus in a dedicated Worker (gcall-opus-fec.worker.ts) so PLC (zero-length decode) and in-band FEC (decode_fec = 1) match the encoder when the browser sends FEC (useinbandfec in useGroupVoiceCall).
Build (only if you change the native wrapper)
The app always tries the WASM FEC decode path in group calls. The prebuilt bundle is committed at src/wasm-libopus-fec/libopus-fec.js. Rebuild only after editing native/libopus-fec-wasm/ (requires emsdk at repo root .emsdk/):
./native/libopus-fec-wasm/build.sh
If the worker or WASM fails to initialize, the hook falls back to WebCodecs AudioDecoder (no libopus FEC control).
Emergency disable (debugging only): VITE_GCALL_WASM_FEC=0 in .env, or localStorage.setItem('gcallWasmFec','0') then reload.
Behaviour
- +1 frame jitter hold when the flag is desired (see
JitterBufferextra hold), so the next packet is more often present before decode (FEC window). - PLC/FEC sequence per pop matches the plan: PLC for early burst losses, then FEC + normal on the same packet with separate PCM buffers.
MAX_PCM_FRAMES_PER_TICK: excess PCM is deferred to the next scheduler tick (seeGCALL_WASM_FEC_MAX_PCM_PER_TICK).- Large seq gap (
> 32): worker decoder is reset before processing. - Metrics:
GroupCallPerformanceTrackerrecordswasmFecPlcFrames,wasmFecAttempts,wasmFecSuccessCoarse(coarse heuristic),wasmFecDeferredPcmTickson the snapshot and per-source window metrics.
Manual verification
- Two clients on a group call with WASM path enabled.
- Confirm sender path:
groupCallWindowMetrics/ logs should show encoder FEC whenAudioEncoder.isConfigSupportedacceptsuseinbandfec. - Induce loss (throttle network or drop packets in a test build) and compare concealment / missing-frame stats with flag on vs off.
- Inspect snapshot:
wasmFecAttemptsandwasmFecSuccessCoarseshould move under loss;fecSuccessCoarseis approximate (non-zero energy after FEC decode).
Files
native/libopus-fec-wasm/— C wrapper +build.shsrc/wasm-libopus-fec/libopus-fec.js— generated bundlesrc/workers/gcall-opus-fec.worker.ts— decode workersrc/hooks/useGroupVoiceCall.ts— jitter drain, worker wiring, metrics