Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions examples/local_video/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,21 @@ Publisher usage:
--identity cam-1 \
--e2ee-key my-secret-key

# publish and display the outgoing video locally
# publish and display the outgoing video locally with separate diagnostics
cargo run -p local_video -F desktop --bin publisher -- \
--camera-index 0 \
--room-name demo \
--identity cam-1 \
--display-video

# log publisher metrics for frames 301 through 1200 (inclusive)
cargo run --release -p local_video -F desktop --bin publisher -- \
--camera-index 0 \
--room-name demo \
--identity cam-1 \
--log-csv publisher.csv \
--log-start-frame-id 301 \
--log-end-frame-id 1200
```

List devices usage:
Expand Down Expand Up @@ -134,8 +143,12 @@ Publisher flags (in addition to the common connection flags above):
- `--attach-timestamp`: Attach the current wall-clock time (microseconds since UNIX epoch) as the user timestamp on each published frame. The subscriber can display this to measure end-to-end latency.
- `--burn-timestamp`: Burn the attached timestamp into the video frame as a visible overlay. Has no effect unless `--attach-timestamp` is also set.
- `--attach-frame-id`: Attach a monotonically increasing frame ID to each published frame via the packet trailer. The subscriber displays this in the timestamp overlay when `--display-timestamp` is used.
- `--display-video`: Open a window that displays the video frames being published.
- `--display-timing`: Burn publisher timing metrics into the local preview window. Requires `--display-video`.
- `--attach-user-data`: Attach six keyboard-controlled channel values to each frame. Focus the diagnostics window and use Q/A, W/S, E/D, R/F, T/G, and Y/H to adjust channels 1-6. Requires `--display-video`.
- `--display-video`: Open a video preview window and a separate publisher diagnostics window. The video window repaints only when a frame arrives; diagnostics update independently at 10 Hz.
- `--display-timing`: Show publisher timing metrics in the diagnostics window. Requires `--display-video`.
- `--log-csv <path>`: Write one CSV row per packetized frame with capture, encoder, packetization, frame-gap, and inter-frame timing metrics. This automatically enables timestamp and frame-ID metadata.
- `--log-start-frame-id <id>`: Start CSV logging at this frame ID (inclusive). Requires `--log-csv`.
- `--log-end-frame-id <id>`: Flush the terminal packetized frame to CSV, then stop the publisher process. Requires `--log-csv`.
- `--e2ee-key <key>`: Enable end-to-end encryption with the given shared key. The subscriber must use the same key to decrypt.

Subscriber usage:
Expand Down Expand Up @@ -174,14 +187,37 @@ Subscriber usage:
--room-name demo \
--identity viewer-1 \
--e2ee-key my-secret-key

# log rendered-frame metrics for the same inclusive frame-ID window
cargo run --release -p local_video -F desktop --bin subscriber -- \
--room-name demo \
--identity viewer-1 \
--log-csv subscriber.csv \
--log-start-frame-id 301 \
--log-end-frame-id 1200
```

Subscriber flags (in addition to the common connection flags above):
- `--participant <identity>`: Only subscribe to video tracks from the specified participant.
- `--low-latency`: Force zero video playout delay so received frames render as soon as possible. This can increase visible stutter when packets arrive late or out of order.
- `--display-timestamp`: Show detailed frame ID, publisher timestamp, subscriber timing stages, and end-to-end latency in the separate diagnostics window. Timestamp fields require the publisher to use `--attach-timestamp`; frame ID requires `--attach-frame-id`.
- `--display-timestamp`: Show detailed frame ID, publisher timestamp, first-packet receive/assembly (including jitter-buffer scheduling), actual decoder processing, render, and end-to-end timing in the separate diagnostics window. Timestamp fields require the publisher to use `--attach-timestamp`; frame ID requires `--attach-frame-id`.
- `--log-csv <path>`: Write one CSV row per GPU-completed frame with receive/assembly through decode start, actual decode processing, render, detailed render-boundary timestamps, end-to-end latency, frame-gap, inter-frame timing, and WebRTC loss/freeze metrics. The publisher must use `--log-csv` or both `--attach-timestamp` and `--attach-frame-id`.
- `--log-start-frame-id <id>`: Start CSV logging at this frame ID (inclusive). Requires `--log-csv`.
- `--log-end-frame-id <id>`: Flush the terminal GPU-completed frame to CSV, then stop the subscriber process. Requires `--log-csv`.
- `--e2ee-key <key>`: Enable end-to-end decryption with the given shared key. Must match the key used by the publisher.

Generate a PDF report from the publisher log, subscriber log, or both:
```
python3 -m pip install reportlab

python3 examples/local_video/scripts/generate_frame_report.py \
--publisher publisher.csv \
--subscriber subscriber.csv \
--output frame-report.pdf
```
Comment on lines +209 to +217

@devin-ai-integration devin-ai-integration Bot Aug 10, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Pull request is missing the required change-documentation entry

The change adds new cross-crate functionality (new subscribe-timing and decode-timestamp entry points at webrtc-sys/src/video_frame.rs:46-49) without adding the change note the repository requires for every pull request, so the release notes and version bumps will omit it.
Impact: Released crates will not document or bump versions for this behavioral change.

Repository rule and current state

AGENTS.md states under "Documenting changes": "Every PR needs a changeset" and "Changeset must list any crates which need to be bumped stemming from the change". git diff --name-only <merge-base> HEAD -- .changeset/ returns nothing for this PR; the only file in /.changeset comes from an earlier commit (0aea78ff). This PR touches libwebrtc, webrtc-sys (new FFI surface decode_start_timestamp_us, decode_finish_timestamp_us, emit_subscribe_timing_at) and changes receive/decode timing semantics, so those crates need to be listed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


Omit either `--publisher` or `--subscriber` to create a single-sided report. The report plots latency over the logged duration and marks frame-ID gaps and freezes. With paired logs, frame loss is the set of packetized publisher frame IDs that were not rendered by the subscriber. Subscriber freezes use WebRTC's reported freeze counters; publisher-only reports infer a freeze from an inter-frame gap greater than three times the median interval.

The subscriber reports two render boundaries. `frame draw encoded` is the CPU time immediately after the WGPU draw command is recorded; it does not mean that the command has been submitted or executed. `frame GPU complete` is when the subscriber observes completion of the GPU submission containing that draw. This measurement does not include surface presentation, compositor queuing, display scanout, or physical pixel illumination, so use an OS presentation API or optical measurement when those later boundaries matter. Exposure-to-GPU measurements across different publisher and subscriber hosts also require synchronized system clocks (for example, NTP or PTP).

Notes:
Expand Down
Loading
Loading