Files
cvmmap-streamer/docs/caveats.md
T

287 lines
7.5 KiB
Markdown

# Operational Caveats
This document captures known environment constraints, behavioral edge cases, and operational considerations for the cv-mmap streamer.
## Environment Constraints
### Simulator Label Length Limit
The cv-mmap simulator uses POSIX shared memory naming that imposes a 24-byte maximum on the `--label` parameter.
**Constraint:**
- Maximum label length: 24 bytes
- Exceeding this causes immediate exit with code 2
**Error message:**
```
--label exceeds 24 bytes
```
**Workaround:**
Use compact deterministic labels:
```bash
# Good (19 bytes)
./build/cvmmap_streamer --run-mode pipeline --input-mode dummy --dummy-label acc_1_rtp_h264 ...
# Bad (28 bytes, will fail)
./build/cvmmap_streamer --run-mode pipeline --input-mode dummy --dummy-label acceptance_rtp_h264_test ...
```
### Deterministic Simulator Sizing
Small frame sizes can trigger GStreamer caps negotiation failures before the first encoded access unit on certain hosts.
**Constraint:**
- Minimum recommended frame size: 640x360
- Smaller sizes may cause `not-negotiated` pipeline errors
**Recommended simulator parameters for validation:**
```bash
./build/cvmmap_streamer \
--run-mode pipeline \
--input-mode dummy \
--dummy-label acc_1_rtp_h264 \
--dummy-width 640 \
--dummy-height 360 \
--dummy-fps 200 \
--dummy-frames 320
```
### Build Path Isolation
The downstream project must use its own build directory. Sharing the root `build/` folder with the main cv-mmap project causes cache collision.
**Constraint:**
- Use `downstream/cvmmap-streamer/build`
- Do not use root `build/`
**Error symptom:**
Configure errors referencing sibling repo paths or stale cache entries.
**Resolution:**
```bash
cmake --fresh -B downstream/cvmmap-streamer/build -S downstream/cvmmap-streamer
```
### GStreamer Version Requirements
The NVENC pipeline requires GStreamer 1.20+ with full development headers. Missing elements are detected at configure time.
**Constraint:**
- GStreamer 1.20+ required
- Development headers required for build
- `nvh264enc` and `nvh265enc` elements checked at runtime
**Missing NVENC error:**
```
FATAL: NVENC encoder not available (nvh264enc/nvh265enc)
Run: gst-inspect-1.0 nvh264enc nvh265enc
```
**Note:** The pipeline falls back to software encoding (`x264enc`, `x265enc`) if NVENC produces zero encoded access units after 60 frames.
## Dual-Mode H.265 RTMP Caveats
### Mode Selection is Binding
Once selected, the RTMP mode cannot be changed without restarting the streamer process. The mode determines packetization format for the entire session.
**Enhanced-RTMP mode:**
- Uses `0x90`/`0x91` header bytes
- FourCC signaling (`hvc1`)
- Compatible with FFmpeg 6.0+, OBS 29+, SRS 6.0+, ZLMediaKit
**Domestic extension mode:**
- Uses `0x1c`/`0x2c` header bytes
- FLV codec-id 12 signaling
- Legacy Chinese CDN compatibility
- Not supported by all players
### Server Configuration Requirements
**ZLMediaKit:**
Must set `enhanced=1` in config.ini for Enhanced-RTMP mode:
```ini
[rtmp]
port=1935
enhanced=1 # 1 = Enhanced RTMP, 0 = Domestic extension
```
**SRS:**
Use `hevc.flv.conf` or `hevc.ts.conf` for HEVC support:
```bash
docker run --rm -it -p 1935:1935 ossrs/srs:6 \
./objs/srs -c conf/hevc.flv.conf
```
### Player Compatibility
| Player | H.264 RTMP | H.265 Enhanced | H.265 Domestic |
|--------|------------|----------------|----------------|
| FFmpeg 6.0+ | Yes | Yes | With patch |
| ffplay | Yes | Yes | Variable |
| VLC 3.0+ | Yes | Yes | No |
| Chrome 105+ (MSE) | Yes | HTTP-FLV/TS only | No |
| OBS 29+ | Yes | Yes | No |
### Mode Mismatch Detection
The `rtmp_stub_tester` validates mode expectations and fails with exit code 6 on mismatch:
```bash
# Start stub expecting domestic mode
./build/rtmp_stub_tester --mode h265-domestic ...
# Streamer sends enhanced mode
./build/cvmmap_streamer --codec h265 --rtmp-mode enhanced ...
# Result: tester exits 6 (ModeMismatch)
```
## Low-Latency Configuration Trade-offs
### Queue Size
| Setting | Latency | Behavior |
|---------|---------|----------|
| `--queue-size 1` | Lowest | Latest-frame semantics, drops old frames |
| `--queue-size 5` | Medium | Small backlog, some frame retention |
| `--queue-size 0` | N/A | Unbounded (NOT recommended) |
### Encoder Settings
| Setting | Low-Latency Value | Trade-off |
|---------|-------------------|-----------|
| `--b-frames 0` | Disabled | Slightly lower compression efficiency |
| `--gop 30` | 1 second at 30fps | Larger GOP = better compression, higher seek latency |
| `rc-lookahead` | 0 (NVENC) | Slightly lower quality prediction |
| `zerolatency` | true | Disables encoder buffering |
### Server-Side Latency (Optional)
When using SRS or ZLMediaKit, additional latency can be introduced by server buffering.
**SRS low-latency settings:**
```
publish { mr off; }
play { gop_cache off; queue_length 5; tcp_nodelay on; }
```
**Trade-offs:**
- `gop_cache off`: Players wait for next I-frame (startup delay)
- `mr off`: Higher CPU usage
- `queue_length 5`: More susceptible to network jitter
## Fault Scenario Behaviors
### Torn Frame Handling
When the coherent snapshot detects a torn read (metadata changed during copy):
1. Frame is dropped
2. `torn_frames` counter increments
3. Ingest loop continues
4. Next sync message triggers new snapshot attempt
**Expected log:**
```
SNAPSHOT_TORN frame_count=A/B timestamp=X/Y
```
### Stream Reset Handling
When `MODULE_STATUS_STREAM_RESET` is received:
1. Ingest queue is flushed
2. Frame counters reset
3. Pipeline may rebuild if resolution/format changed
4. RTMP publishers send sequence header rebase
5. `resets` counter increments
**Expected log:**
```
STREAM_RESET_RECEIVED
RTMP_STREAM_RESET_REBASE mode=<mode>
```
### Backpressure Containment
When downstream sinks are slower than ingest:
1. Queue fills to capacity
2. Oldest frames evicted before push
3. `dropped_frames` counter increments
4. Latest frame always prioritized
5. Latency remains bounded
**Expected log:**
```
QUEUE_DROP dropped_frames=N queue_depth=1
```
## Known Limitations
### No Audio Support
Version 1.0 does not support audio capture or muxing. Video-only streams.
### No Direct RTSP/WebRTC Publishing
RTSP and WebRTC are not direct publisher outputs. They require server-side conversion from RTMP or RTP.
### Single Codec Per Session
Runtime codec switching is not supported. To change codecs, restart the streamer process.
### NVENC Requires NVIDIA GPU
NVENC hardware encoding requires an NVIDIA GPU with encode support. Falls back to software encoding on non-NVIDIA systems or when NVENC is unavailable.
### UDP RTP Only
RTP output uses UDP unicast only. No multicast or TCP interleaving support in v1.
## Debugging Tips
### Enable Verbose Logging
All binaries use spdlog. Set the environment variable for debug output:
```bash
export SPDLOG_LEVEL=debug
./build/cvmmap_streamer ...
```
### Check Evidence Logs
Failed runs leave detailed logs:
```bash
# Find latest run
ls -lt .sisyphus/evidence/task-14-acceptance/ | head
# Examine specific row logs
cat .sisyphus/evidence/task-14-acceptance/RUN_ID/1-rtp_h264/streamer.log
```
### Verify Binary Existence
Before running scripts, verify all binaries are built:
```bash
for bin in cvmmap_streamer rtp_receiver_tester rtmp_stub_tester; do
test -x "build/$bin" || echo "Missing: $bin"
done
```
### Test Individual Components
```bash
# Test simulator only
./build/cvmmap_streamer --run-mode pipeline --help
# Test streamer config validation only
./build/cvmmap_streamer --codec h264 --shm-name test --zmq-endpoint ipc:///tmp/test.ipc
# (Will fail with "No output enabled" but validates config parsing)
```