chore(docs): add downstream task evidence runbook artifacts

This commit consolidates operational documentation and runbooks used to drive task execution and release validation.

It includes evidence writeups, caveat/matrix references, release gate outputs, plan/notepad context, and generated SDP fixture needed for reproducible downstream review, keeping them separate from code and generated artifacts.

This separation lets runtime and harness changes be reviewed as implementation units while process documentation remains in an independent governance/history commit.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-03-05 20:32:22 +08:00
parent 991f7ded34
commit 9f98a38797
5 changed files with 916 additions and 0 deletions
+283
View File
@@ -0,0 +1,283 @@
# 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_sim --label acc_1_rtp_h264 ...
# Bad (28 bytes, will fail)
./build/cvmmap_sim --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_sim \
--width 640 \
--height 360 \
--fps 200 \
--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_sim cvmmap_streamer rtp_receiver_tester rtmp_stub_tester; do
test -x "downstream/cvmmap-streamer/build/$bin" || echo "Missing: $bin"
done
```
### Test Individual Components
```bash
# Test simulator only
./build/cvmmap_sim --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)
```
+186
View File
@@ -0,0 +1,186 @@
# Compatibility Matrix
This document defines the complete protocol, codec, and RTMP mode compatibility matrix for cv-mmap streamer. It explicitly separates mandatory (blocking) checks from optional (non-blocking) checks.
## Mandatory Checks (Blocking for Release)
These checks must ALL pass for a release to be considered valid. They require no external servers and run entirely in standalone mode.
### Protocol/Codec Matrix
| Row | Protocol | Codec | RTMP Mode | Test Command | Evidence |
|-----|----------|-------|-----------|--------------|----------|
| 1 | RTP | H.264 | N/A | `./scripts/acceptance_standalone.sh` (row 1) | task-14-acceptance.txt |
| 2 | RTP | H.265 | N/A | `./scripts/acceptance_standalone.sh` (row 2) | task-14-acceptance.txt |
| 3 | RTMP | H.264 | enhanced | `./scripts/acceptance_standalone.sh` (row 3) | task-14-acceptance.txt |
| 4 | RTMP | H.265 | enhanced | `./scripts/acceptance_standalone.sh` (row 4) | task-14-acceptance.txt |
| 5 | RTMP | H.265 | domestic | `./scripts/acceptance_standalone.sh` (row 5) | task-14-acceptance.txt |
**Pass Criteria:**
- Exit code 0 from `acceptance_standalone.sh`
- JSON summary shows `total=5 pass=5 fail=0 skip=0`
- All tester processes receive expected packet/frame counts
### Fault Scenarios
| Scenario | Description | Test Command | Evidence |
|----------|-------------|--------------|----------|
| Torn Read | Coherent snapshot rejects torn frames | `./scripts/fault_suite.sh` | task-15-fault-suite.txt |
| Sink Stall | Backpressure containment under slow consumer | `./scripts/fault_suite.sh` | task-15-fault-suite.txt |
| Reset Storm | Stream reset recovery | `./scripts/fault_suite.sh` | task-15-fault-suite.txt |
**Pass Criteria:**
- Exit code 0 from `fault_suite.sh`
- All fault scenarios PASS status
- No violations of latency/drop thresholds
## Invalid Combinations (Explicitly Rejected)
These combinations are rejected at startup with clear error messages and non-zero exit codes.
| Combination | Error | Exit Code |
|-------------|-------|-----------|
| RTMP + H.264 + domestic mode | H.264 does not support domestic mode | 1 |
| RTP without --rtp-endpoint | Missing required RTP endpoint | 1 |
| RTMP without --rtmp-url | Missing required RTMP URL | 1 |
| --rtmp-mode without H.265 codec | Domestic mode requires H.265 | 1 |
## Optional Checks (Non-Blocking)
These checks are provided for interoperability validation but are NOT required for release acceptance. If the environment is unavailable, these should be skipped.
### Server Smoke Tests
| Server | Protocols | H.265 Support | Status |
|--------|-----------|---------------|--------|
| SRS 6.0+ | RTMP, HTTP-FLV, HLS, WebRTC | Enhanced-RTMP | Optional |
| ZLMediaKit | RTMP, HTTP-FLV, HTTP-TS, RTSP, WebRTC | Enhanced + Domestic | Optional |
**Skip Conditions:**
- Docker not available
- Port 1935 in use by another service
- Server container fails to start
- Network isolation prevents connection
**Expected Behavior When Skipped:**
- Script exits with status 0 (SKIP)
- Evidence file notes the skip reason
- Mandatory acceptance still proceeds
## RTMP H.265 Dual Mode Details
### Enhanced-RTMP Mode (Recommended)
**Specification:** [Enhanced RTMP](https://github.com/veovera/enhanced-rtmp)
**Characteristics:**
- Video codec header byte: `0x90` (sequence) / `0x91` (frame)
- FourCC: `hvc1` or `hev1`
- Standardized, widely supported
- FFmpeg 6.0+ native support
- OBS 29+ support
- SRS 6.0+ native support
- ZLMediaKit default mode
**When to use:**
- Greenfield deployments
- Modern CDN ingestion
- Cross-platform compatibility requirements
### Domestic Extension Mode (Legacy Compatibility)
**Specification:** Proprietary FLV extension using codec-id 12
**Characteristics:**
- Video codec header byte: `0x1c` (keyframe) / `0x2c` (inter)
- FLV codec-id: 12 (non-standard)
- Legacy Chinese CDN compatibility
- Requires explicit config in ZLMediaKit (`enhanced=0`)
- Not supported by all players
**When to use:**
- Legacy CDN requirements
- Existing domestic-mode infrastructure
- Backward compatibility with older systems
### Mode Selection Decision Tree
```
Is codec H.265?
├── No (H.264) ──> Use enhanced mode only (domestic invalid)
└── Yes (H.265)
├── Target is modern CDN/player? ──> enhanced
├── Target requires domestic mode? ──> domestic
└── Unknown? ──> enhanced (safer default)
```
## Validation Commands
### Verify Mandatory Matrix
```bash
cd downstream/cvmmap-streamer
./scripts/acceptance_standalone.sh
echo "Exit code: $?"
```
### Verify Individual Row (RTP H.264)
```bash
# Terminal 1: Tester
./build/rtp_receiver_tester \
--port 51040 \
--expect-pt 96 \
--packet-threshold 1 \
--timeout-ms 10000
# Terminal 2: Simulator + Streamer
./build/cvmmap_sim \
--shm-name test_rtp_h264 \
--zmq-endpoint "ipc:///tmp/test_rtp_h264.ipc" \
--label rtp_h264 \
--frames 320 \
--fps 200 \
--width 640 \
--height 360 &
./build/cvmmap_streamer \
--run-mode pipeline \
--codec h264 \
--shm-name test_rtp_h264 \
--zmq-endpoint "ipc:///tmp/test_rtp_h264.ipc" \
--queue-size 1 \
--gop 30 \
--b-frames 0 \
--ingest-max-frames 120 \
--rtp \
--rtp-endpoint "127.0.0.1:51040" \
--rtp-payload-type 96 \
--rtp-sdp /tmp/test_rtp_h264.sdp
```
### Verify Invalid Combination Rejection
```bash
# Should fail with clear error
./build/cvmmap_streamer \
--codec h264 \
--rtmp-mode domestic \
--shm-name test \
--zmq-endpoint "ipc:///tmp/test.ipc"
echo "Exit code: $?" # Expected: 2 (invalid mode matrix)
```
## Evidence Locations
All test evidence is written to `.sisyphus/evidence/`:
| Evidence File | Description |
|---------------|-------------|
| task-14-acceptance.txt | Latest acceptance run pointer |
| task-14-acceptance-summary.json | Acceptance summary JSON |
| task-14-acceptance/RUN_ID/ | Per-run logs for each matrix row |
| task-15-fault-suite.txt | Latest fault suite run pointer |
| task-15-fault-suite-summary.json | Fault suite summary JSON |
| task-15-fault-suite/RUN_ID/ | Per-run logs for each scenario |
+207
View File
@@ -0,0 +1,207 @@
# SRS Smoke Test Profile
## Status
**OPTIONAL / NON-BLOCKING**
This document provides optional interoperability checks for SRS (Simple Realtime Server). These checks are not mandatory for acceptance. If the SRS environment is unavailable, skip these tests without failing the mandatory acceptance criteria.
---
## Purpose
Validate RTMP streaming interoperability with SRS, specifically for:
- RTMP H.264 publishing and playback
- Enhanced RTMP HEVC (H.265) via [Enhanced RTMP spec](https://github.com/veovera/enhanced-rtmp)
- Low-latency streaming configurations
---
## Prerequisites
- Docker (recommended) or SRS built from source
- FFmpeg or the project streaming binary
- Optional: ffplay, VLC for playback verification
---
## Quick Start (Docker)
```bash
# Run SRS with RTMP support
docker run --rm -it -p 1935:1935 -p 8080:8080 ossrs/srs:6 \
./objs/srs -c conf/rtmp.conf
# For HEVC support, use hevc.flv.conf or hevc.ts.conf
docker run --rm -it -p 1935:1935 -p 8080:8080 ossrs/srs:6 \
./objs/srs -c conf/hevc.flv.conf
```
---
## Smoke Commands
### 1. Basic RTMP H.264 Stream Test
```bash
# Publish test stream to SRS
ffmpeg -re -f lavfi -i testsrc=duration=60:size=1280x720:rate=30 \
-f lavfi -i sine=frequency=1000:duration=60 \
-pix_fmt yuv420p -c:v libx264 -preset fast -b:v 3000k \
-c:a aac -b:a 128k -f flv rtmp://localhost/live/smoke_test
```
```bash
# Playback verification
ffplay rtmp://localhost/live/smoke_test
```
### 2. Enhanced RTMP HEVC (H.265) Test
**Prerequisites:**
- SRS 6.0.4+ with HEVC configuration
- FFmpeg 6.0+ with libx265 and enhanced RTMP support (or use `ossrs/srs:encoder` Docker image)
```bash
# Publish HEVC stream (Enhanced RTMP)
ffmpeg -re -f lavfi -i testsrc=duration=60:size=1280x720:rate=30 \
-f lavfi -i sine=frequency=1000:duration=60 \
-pix_fmt yuv420p -c:v libx265 -preset fast -b:v 2000k \
-c:a aac -b:a 128k -f flv rtmp://localhost/live/smoke_hevc
# Alternative using project binary (if HEVC enabled)
# ./cvmmap-streamer --output rtmp://localhost/live/smoke_hevc --codec hevc
```
```bash
# Playback HEVC stream
ffplay rtmp://localhost/live/smoke_hevc
```
### 3. Low-Latency Configuration
For minimal latency with SRS, use this configuration snippet:
```bash
# rtmp.conf with low-latency settings
listen 1935;
chunk_size 128;
vhost __defaultVhost__ {
# Disable merged-read for lower latency
publish {
mr off;
mr_latency 100;
}
play {
# Disable GOP cache for lower latency (may cause startup delay)
gop_cache off;
# Reduce queue length
queue_length 5;
# Enable TCP_NODELAY
tcp_nodelay on;
# Reduce merged-write latency
mw_latency 100;
mw_msgs 1;
}
}
```
**Caveats for low-latency mode:**
- `gop_cache off` means players wait for next I-frame (startup delay)
- Lower `mw_latency` increases CPU usage
- Network jitter may cause more visible artifacts
---
## HEVC Compatibility Notes
### Enhanced RTMP (Standard)
SRS 6.0+ supports HEVC via the [Enhanced RTMP](https://github.com/veovera/enhanced-rtmp) specification:
- Uses FourCC `hvc1` for HEVC
- Supported by FFmpeg 6.0+ without patches
- Supported by OBS 29+
### Domestic HEVC Extension
Some older systems use the domestic HEVC FLV extension (code 12):
- Requires patched FFmpeg for some versions
- SRS supports both formats but prefers Enhanced RTMP
- When using FFmpeg 4.x/5.x, you may need the [runner365 patch](https://github.com/runner365/ffmpeg_rtmp_h265)
**Recommendation:** Use FFmpeg 6.0+ or the `ossrs/srs:encoder` Docker image to avoid compatibility issues.
---
## Environment Variable Overrides
SRS supports environment variable configuration:
```bash
# Override listen port
docker run --rm -it -p 1935:1935 -e SRS_LISTEN=1935 ossrs/srs:6 \
./objs/srs -c conf/rtmp.conf
# Enable low latency for all vhosts
docker run --rm -it -p 1935:1935 \
-e SRS_VHOST_PUBLISH_MR=off \
-e SRS_VHOST_PLAY_GOP_CACHE=off \
-e SRS_VHOST_PLAY_MW_LATENCY=100 \
ossrs/srs:6 \
./objs/srs -c conf/rtmp.conf
```
---
## Health Check
```bash
# Check SRS HTTP API (if enabled)
curl http://localhost:8080/api/v1/versions
# Check stream statistics
curl http://localhost:8080/api/v1/streams
```
---
## Missing Server Environment Behavior
If SRS is not available or the Docker container fails to start:
1. **SKIP** - Do not fail mandatory acceptance
2. **Log** - Document the environment issue
3. **Continue** - Proceed with other tests
Example skip condition:
```bash
if ! docker run --rm -p 1935:1935 ossrs/srs:6 true 2>/dev/null; then
echo "SRS environment unavailable - skipping smoke tests"
exit 0
fi
```
---
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Connection refused | Check port 1935 is not in use; verify SRS started |
| Stream not found | Verify app/stream name matches; check SRS logs |
| HEVC playback fails | Ensure player supports HEVC (Chrome 105+, ffplay, VLC 3.0+) |
| High latency | Disable gop_cache, reduce mw_latency/mr_latency |
| Artifacts in stream | Check encoder settings; verify network stability |
---
## References
- [SRS RTMP Documentation](https://ossrs.io/lts/en-us/docs/v7/doc/rtmp)
- [SRS HEVC Documentation](https://ossrs.io/lts/en-us/docs/v7/doc/hevc)
- [Enhanced RTMP Specification](https://github.com/veovera/enhanced-rtmp)
+233
View File
@@ -0,0 +1,233 @@
# ZLMediaKit Smoke Test Profile
## Status
**OPTIONAL / NON-BLOCKING**
This document provides optional interoperability checks for ZLMediaKit. These checks are not mandatory for acceptance. If the ZLMediaKit environment is unavailable, skip these tests without failing the mandatory acceptance criteria.
---
## Purpose
Validate RTMP streaming interoperability with ZLMediaKit, specifically for:
- RTMP H.264 publishing and playback
- Enhanced RTMP HEVC (H.265) support
- Low-latency streaming configurations
- HTTP-FLV, HTTP-TS, and WebRTC protocols
---
## Prerequisites
- Docker (recommended) or ZLMediaKit built from source
- FFmpeg or the project streaming binary
- Optional: ffplay, VLC for playback verification
---
## Quick Start (Docker)
```bash
# Run ZLMediaKit with default configuration
docker run --rm -it -p 1935:1935 -p 8080:80 -p 8554:554 \
-p 10000:10000 -p 30000-30500:30000-30500/udp \
zlmediakit/zlmediakit:master
# With custom config (mount your config.ini)
docker run --rm -it -p 1935:1935 -p 8080:80 \
-v $(pwd)/config.ini:/opt/media/conf/config.ini \
zlmediakit/zlmediakit:master
```
---
## Smoke Commands
### 1. Basic RTMP H.264 Stream Test
```bash
# Publish test stream to ZLMediaKit
ffmpeg -re -f lavfi -i testsrc=duration=60:size=1280x720:rate=30 \
-f lavfi -i sine=frequency=1000:duration=60 \
-pix_fmt yuv420p -c:v libx264 -preset fast -b:v 3000k \
-c:a aac -b:a 128k -f flv rtmp://localhost/live/smoke_test
```
```bash
# Playback via RTMP
ffplay rtmp://localhost/live/smoke_test
# Playback via HTTP-FLV
ffplay http://localhost:8080/live/smoke_test.live.flv
# Playback via HTTP-TS
ffplay http://localhost:8080/live/smoke_test.live.ts
```
### 2. Enhanced RTMP HEVC (H.265) Test
**Prerequisites:**
- ZLMediaKit with HEVC support enabled in config
- FFmpeg 6.0+ with libx265 and enhanced RTMP support
**Configuration in config.ini:**
```ini
[rtmp]
port=1935
# h265 rtmp packing: 1 = Enhanced RTMP (standard), 0 = Domestic extension
enhanced=1
[protocol]
enable_rtmp=1
```
```bash
# Publish HEVC stream (Enhanced RTMP)
ffmpeg -re -f lavfi -i testsrc=duration=60:size=1280x720:rate=30 \
-f lavfi -i sine=frequency=1000:duration=60 \
-pix_fmt yuv420p -c:v libx265 -preset fast -b:v 2000k \
-c:a aac -b:a 128k -f flv rtmp://localhost/live/smoke_hevc
# Alternative using project binary (if HEVC enabled)
# ./cvmmap-streamer --output rtmp://localhost/live/smoke_hevc --codec hevc
```
```bash
# Playback HEVC stream via various protocols
ffplay rtmp://localhost/live/smoke_hevc
ffplay http://localhost:8080/live/smoke_hevc.live.flv
ffplay http://localhost:8080/live/smoke_hevc.live.ts
```
### 3. Low-Latency Configuration
For minimal latency with ZLMediaKit, modify config.ini:
```ini
[general]
# Disable merge write (0 = immediate write)
mergeWriteMS=0
[protocol]
# Frame timestamp override: 0=source, 1=system, 2=relative
modify_stamp=0
# Protocol demand mode (1 = generate on demand, reduces latency)
rtmp_demand=1
flv_demand=1
ts_demand=1
[rtmp]
handshakeSecond=5
keepAliveSecond=5
[rtp]
# Low latency mode (WARNING: may cause artifacts with H.264 multi-slice)
lowLatency=1
```
**Caveats for low-latency mode:**
- mergeWriteMS=0 disables write buffering (higher CPU, more syscalls)
- modify_stamp=0 uses source timestamps (requires stable encoder timing)
- *_demand=1 causes first viewer to wait for next GOP
- lowLatency=1 in RTP may cause artifacts with certain H.264 streams
### 4. Stream Proxy Test (Optional)
ZLMediaKit can proxy streams from other sources:
```bash
# Add stream proxy via HTTP API
curl -X POST "http://localhost:8080/index/api/addStreamProxy" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc" \
-d "vhost=__defaultVhost__" \
-d "app=proxy" \
-d "stream=test" \
-d "url=rtmp://localhost/live/smoke_test"
```
---
## HEVC Compatibility Notes
### Enhanced RTMP vs Domestic Extension
ZLMediaKit supports both HEVC packing formats via the enhanced config option:
**Enhanced RTMP (enhanced=1, RECOMMENDED):**
- Uses standard FourCC hvc1
- Compatible with FFmpeg 6.0+, OBS 29+
- SRS 6.0+, ZLMediaKit master
**Domestic Extension (enhanced=0):**
- Uses FLV codec ID 12
- Required for some legacy Chinese CDN providers
- May need patched FFmpeg for older versions
### Codec Priority in WebRTC
When using WebRTC with ZLMediaKit, codec priority can be configured:
```ini
[rtc]
# Video codec priority (first = highest)
preferredCodecV=H264,H265,AV1,VP9,VP8
```
**Note:** Chrome does not yet support HEVC in WebRTC; Safari does with experimental flags.
---
## Health Check
```bash
# Get server statistics
curl "http://localhost:8080/index/api/getStatistic?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"
# Get MediaServer list
curl "http://localhost:8080/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"
# Check if stream exists
curl "http://localhost:8080/index/api/isMediaOnline?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost=__defaultVhost__&app=live&stream=smoke_test&schema=rtmp"
```
---
## Missing Server Environment Behavior
If ZLMediaKit is not available or the Docker container fails to start:
1. **SKIP** - Do not fail mandatory acceptance
2. **Log** - Document the environment issue
3. **Continue** - Proceed with other tests
Example skip condition:
```bash
if ! docker run --rm -p 1935:1935 zlmediakit/zlmediakit:master true 2>/dev/null; then
echo "ZLMediaKit environment unavailable - skipping smoke tests"
exit 0
fi
```
---
## Troubleshooting
| Issue | Solution |
|-------|----------|
| Connection refused | Check port 1935/8080 not in use; verify server started |
| Stream not found | Verify app/stream name; check ZLMediaKit logs |
| HEVC playback fails | Ensure player supports HEVC; check enhanced setting |
| High latency | Disable mergeWriteMS, use modify_stamp=0 |
| Artifacts in stream | Disable rtp.lowLatency if H.264 multi-slice |
| API returns 401 | Verify secret parameter matches config.ini |
---
## References
- [ZLMediaKit GitHub](https://github.com/ZLMediaKit/ZLMediaKit)
- [ZLMediaKit Wiki](https://github.com/ZLMediaKit/ZLMediaKit/wiki)
- [Enhanced RTMP Specification](https://github.com/veovera/enhanced-rtmp)