mirror of
git://f0xx.org/ac/ac-docs
synced 2026-07-29 07:39:25 +03:00
initial
This commit is contained in:
191
OPUS_SPEEX_VALIDATION.md
Normal file
191
OPUS_SPEEX_VALIDATION.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Opus / Speex / stream protection — validation checklist (task 3)
|
||||
|
||||
<!-- doc-meta:start -->
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Author | Anton Afanasyeu |
|
||||
| Revision | R1 |
|
||||
| Creation date | 2026-06-05 |
|
||||
| Last modification date | 2026-06-05 |
|
||||
| Co-authored | |
|
||||
| Severity | medium |
|
||||
| State | pending review |
|
||||
| Document type | technical |
|
||||
<!-- doc-meta:end -->
|
||||
|
||||
\newpage
|
||||
\newpage
|
||||
|
||||
---
|
||||
|
||||
|
||||
E2E validation guide for **audio codecs** and **UDP stream protection** (FEC, NACK, negotiation). Code is on **`next`**; this doc is the operator checklist.
|
||||
|
||||
**See also:** [ndk/README.md](../ndk/README.md), [ROADMAP.md](ROADMAP.md), [AV_QUALITY_QA_SESSION.md](AV_QUALITY_QA_SESSION.md).
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- toc -->
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Automated baseline (CI / dev machine)](#automated-baseline-ci-dev-machine)
|
||||
- [User settings (both peers)](#user-settings-both-peers)
|
||||
- [Developer settings](#developer-settings)
|
||||
- [E2E matrix — run on two devices](#e2e-matrix-run-on-two-devices)
|
||||
- [A. Handshake and negotiation](#a-handshake-and-negotiation)
|
||||
- [B. Audio codec](#b-audio-codec)
|
||||
- [C. Controls (user vs developer)](#c-controls-user-vs-developer)
|
||||
- [D. Stress (optional)](#d-stress-optional)
|
||||
- [What to capture per run](#what-to-capture-per-run)
|
||||
- [Pass criteria](#pass-criteria)
|
||||
- [Known limits (next)](#known-limits-next)
|
||||
<!-- /toc -->
|
||||
|
||||
**Documentation index:** [README.md](README.md)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Two Android devices (or sender + receiver) on **same LAN** for first pass; repeat subset on lossy/WAN if possible.
|
||||
- Debug builds with NDK codecs built if testing native Opus/Speex probes:
|
||||
|
||||
```bash
|
||||
./scripts/build-native-codecs.sh arm64-v8a # optional; see ndk/README.md
|
||||
./gradlew :app:assembleDebug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Automated baseline (CI / dev machine)
|
||||
|
||||
Run before field soak:
|
||||
|
||||
```bash
|
||||
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.network.transport.StreamProtectionNegotiatorTest'
|
||||
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.media.AudioNegotiatorTest'
|
||||
./gradlew :app:testDebugUnitTest --tests 'com.foxx.androidcast.media.codec.*'
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```bash
|
||||
bash scripts/validate_opus_speex.sh
|
||||
```
|
||||
|
||||
Expect **BUILD SUCCESSFUL** and all tests green.
|
||||
|
||||
---
|
||||
|
||||
## User settings (both peers)
|
||||
|
||||
**Global settings** (main UI):
|
||||
|
||||
| Control | Location | Notes |
|
||||
|---------|----------|--------|
|
||||
| Transport | Sender / receiver | Use **UDP** for FEC/NACK tests |
|
||||
| Stream protection (UDP) | Global settings | Default **None**; try FEC 3/4, NACK, FEC+NACK |
|
||||
| Audio codec | Global settings | **AUTO**, **Opus**, **Speex**, AAC baseline |
|
||||
|
||||
After changing protection, **start a new session** — negotiation runs at handshake (`CastSession` / `StreamProtectionNegotiator`).
|
||||
|
||||
---
|
||||
|
||||
## Developer settings
|
||||
|
||||
Enable **Developer options** on both devices if testing passthrough / debug audio:
|
||||
|
||||
| Control | Purpose |
|
||||
|---------|---------|
|
||||
| Passthrough / debug audio | `PASSTHROUGH_DEBUG` path |
|
||||
| Codec overrides | Align with `CodecCatalog` / `PassthroughCodecPolicy` |
|
||||
| Diagnostics export | Session stats + negotiated mime + protection string |
|
||||
|
||||
Check **session diagnostics** after connect: protection line should match `PassthroughCodecPolicy.protectionDescription()`.
|
||||
|
||||
---
|
||||
|
||||
## E2E matrix — run on two devices
|
||||
|
||||
Mark each cell **PASS / FAIL / SKIP** in a ticket tagged `20260604`.
|
||||
|
||||
### A. Handshake and negotiation
|
||||
|
||||
| # | Sender protection | Receiver capability | Audio | Expected |
|
||||
|---|-------------------|---------------------|-------|----------|
|
||||
| A1 | None | Any | AUTO | No FEC/NACK; stable video+audio |
|
||||
| A2 | FEC 3/4 | FEC 3/4 | AUTO | Agreed FEC 3/4; loss recovery under artificial drop |
|
||||
| A3 | NACK | NACK | AUTO | Retransmit under single-packet loss |
|
||||
| A4 | FEC+NACK | FEC+NACK | AUTO | Combined behavior; no deadlock |
|
||||
| A5 | FEC 3/4 | NONE only | AUTO | Prompt or downgrade per `StreamProtectionNegotiator` |
|
||||
|
||||
### B. Audio codec
|
||||
|
||||
| # | Sender audio | Receiver audio | Expected |
|
||||
|---|--------------|----------------|----------|
|
||||
| B1 | AUTO | AUTO | AAC or negotiated fallback |
|
||||
| B2 | Opus | Opus | Opus native if `.so` present; else stub/fallback per `AudioNegotiator` |
|
||||
| B3 | Speex | Speex | Speex native if built; else fallback |
|
||||
| B4 | Opus | AUTO (no Opus) | Fallback — no silent failure |
|
||||
|
||||
### C. Controls (user vs developer)
|
||||
|
||||
| # | Check |
|
||||
|---|--------|
|
||||
| C1 | User can change transport UDP ↔ TCP without crash |
|
||||
| C2 | User protection change applies on **next** session |
|
||||
| C3 | Developer diagnostics show negotiated video mime + audio + protection |
|
||||
| C4 | Receiver UI shows aligned protection label after handshake |
|
||||
|
||||
### D. Stress (optional)
|
||||
|
||||
| # | Check |
|
||||
|---|--------|
|
||||
| D1 | Background/rotate sender — session recovers or fails cleanly |
|
||||
| D2 | ~5 min soak with FEC on — no memory runaway (logcat) |
|
||||
| D3 | Switch Wi‑Fi ↔ mobile data mid-cast — defined behavior (fail or reconnect) |
|
||||
|
||||
---
|
||||
|
||||
## What to capture per run
|
||||
|
||||
1. **Diagnostics** export from both devices (or logcat filter `androidcast|CastSession|StreamProtection|AudioNegotiator`).
|
||||
2. Negotiated lines: `negotiatedVideoMime`, `audioCodec`, `streamProtection`, `wantsNack`.
|
||||
3. Subjective: audio dropouts, video freezes, recovery after packet loss (FEC/NACK test: weak Wi‑Fi or `tc netem` on Linux AP if available).
|
||||
|
||||
---
|
||||
|
||||
## Pass criteria
|
||||
|
||||
- All **automated** tests green (`validate_opus_speex.sh`).
|
||||
- Matrix **A1–A4** and **B1–B2** pass on reference hardware.
|
||||
- No unexplained **silent** fallback (user sees toast/prompt when negotiation downgrades).
|
||||
- Diagnostics string matches actual wire behavior for UDP protection.
|
||||
|
||||
---
|
||||
|
||||
## Known limits (next)
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| Opus / Speex native encode | Probe + bridge; full native path per [ndk/README.md](../ndk/README.md) |
|
||||
| FEC 3/4 + RS | Per-shard wire (`FecShardWire`); v1 monolithic still accepted |
|
||||
| TCP transport | Protection spinners disabled / N/A for TCP |
|
||||
|
||||
File issues under Tickets → tag **`20260604`**, component Opus/Speex.
|
||||
Reference in New Issue
Block a user