Skip to content

moq-rtc: A/V sync has no NTP anchor (RTCP SR ignored on ingest; egress SR wallclock is dequeue time) #2005

Description

@kixelated

Summary

Two related A/V sync gaps in moq-rtc, both verified on main:

  1. Ingest ignores RTCP Sender Reports. IngestClock anchors each track to the arrival Instant of its first frame and thereafter follows that track's own RTP deltas. str0m surfaces MediaData::last_sender_info, but it is never read. Audio (48 kHz) and video (90 kHz) are cross-aligned purely by first-packet arrival time, so differential network jitter between the first audio packet and the first (large, paced) video keyframe is baked in as a fixed lip-sync offset for the entire session, typically tens of ms, with no re-sync ever.

  2. Egress uses dequeue time as the RTCP SR wallclock. session.rs calls egress::dispatch(&mut rtc, req, Instant::now()) (main rs/moq-rtc/src/session.rs:222), and that now() becomes the wallclock str0m uses to build Sender Reports. Bursty MoQ group delivery dispatches several frames back-to-back at nearly the same now() while their rtp_time spans 100+ ms, skewing the receiver's SR-derived clock model.

Suggested fix

On ingest, correlate each track's RTP timeline to NTP via last_sender_info when available (fall back to arrival anchoring until the first SR). On egress, derive the SR wallclock from the frame's presentation time against a session epoch instead of dispatch time.

Found during a full review of the dev branch.

(Written by Claude Fable 5)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions