Skip to content

Add csv output for latency benchmarks to local_video example - #1320

Open
chenosaurus wants to merge 5 commits into
mainfrom
dc/latency_metrics_csv
Open

Add csv output for latency benchmarks to local_video example#1320
chenosaurus wants to merge 5 commits into
mainfrom
dc/latency_metrics_csv

Conversation

@chenosaurus

Copy link
Copy Markdown
Contributor
  • add logging output of the video pipeline timing metrics to csv
  • add python script to generate report from logged csv

@chenosaurus
chenosaurus requested a review from ladvoc as a code owner August 6, 2026 18:06

@devin-ai-integration devin-ai-integration Bot left a comment

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.

Devin Review found 1 potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

Comment on lines 737 to +744
if updated_sample.is_complete() {
self.latest_complete_sample = Some(updated_sample);
if let Some(frame_log) = self.frame_log.as_mut() {
if let Err(error) = frame_log.record(updated_sample) {
warn!("Publisher CSV logging disabled after write failure: {error}");
self.frame_log = None;
}
}

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.

🟡 Publisher metrics file records the same video frame several times when multiple quality layers are published

Each extra timing notification for a frame that already has all of its stages filled in writes another row for that frame (frame_log.record(updated_sample) at examples/local_video/src/publisher.rs:739) instead of only writing the frame once, so the metrics file contains repeated entries for the same frame.
Impact: With simulcast publishing, the generated CSV and PDF report show several times more frames than were really sent, with near-zero frame intervals and blank frame-gap values, making the latency/loss numbers misleading.

Why extra timing events arrive per frame and how they duplicate rows

PublisherTimingState::record_sdk_event (examples/local_video/src/publisher.rs:715-747) keys samples by capture timestamp and calls PublisherCsvLogger::record on every event whose sample is_complete(). is_complete() becomes true as soon as encoder-upload, encoder-output and packetize timestamps are all present, and it stays true for all later events with the same capture timestamp.

In webrtc-sys/src/packet_trailer.cpp:228-266, TransformSend emits EncoderOutput and WebrtcPacketize per transformed frame per SSRC. With --simulcast there are multiple SSRCs/layers per captured frame, all carrying the same user_timestamp and frame_id, so the same sample is re-completed several times and record() writes an additional CSV row each time.

Duplicate rows increment sample_count, set packetize_interval_ms to the tiny inter-layer delta, and produce empty frame_id_gap (because frame_id.checked_sub(previous) is 0 and checked_sub(1) yields None). The Python report then counts these rows as distinct frames (examples/local_video/scripts/generate_frame_report.py:436) and uses the intervals for freeze inference (examples/local_video/scripts/generate_frame_report.py:135-147).

Prompt for agents
In examples/local_video/src/publisher.rs, PublisherTimingState::record_sdk_event calls PublisherCsvLogger::record for every SDK timing event whose sample is already complete. Because libwebrtc emits EncoderOutput/WebrtcPacketize per encoded layer (see webrtc-sys/src/packet_trailer.cpp TransformSend, which runs once per SSRC), a simulcast publish re-completes the same capture-timestamp sample multiple times and writes duplicate CSV rows for one captured frame. Fix by only logging on the transition from incomplete to complete: capture whether the sample was complete before applying the event and record only when it just became complete. Alternatively, make PublisherCsvLogger ignore samples whose frame_id/capture timestamp equals the last logged one.
Open in Devin Review

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant