Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4624490
moq-net: refactor Timestamp to runtime scale
claude May 21, 2026
de27411
moq-net: add Track.timescale, Frame.timestamp, zigzag varint
claude May 21, 2026
c116793
moq-net: Lite05 wire format with timescale and delta timestamps
claude May 21, 2026
a75f864
moq-net: make subscribe_track async to await timescale
claude May 21, 2026
3a527fd
hang: subscribe example uses async subscribe_track
claude May 21, 2026
1e3bb3f
moq-net: async subscribe, immutable tracks, Subscription split, Times…
kixelated May 22, 2026
72da67f
Merge origin/main and resolve conflicts
kixelated May 23, 2026
61e6c9e
Merge remote-tracking branch 'origin/main' into claude/moq-net-timest…
kixelated May 23, 2026
69b8c2b
moq-gst: update subscribe_track call sites and timestamp delta
kixelated May 23, 2026
c5f9898
py: await subscribe_* calls now that the FFI methods are async
kixelated May 23, 2026
3e0b093
moq-net: handle ALPN_LITE_05 in client and server ALPN dispatch
kixelated May 23, 2026
871a186
moq-net: gate Lite05 behind a WIP ALPN until the wire format is final…
kixelated May 23, 2026
89b6027
moq-net: make divide-by-zero unrepresentable in Timestamp/Timescale
kixelated May 28, 2026
0a4bda7
Merge origin/dev into claude/moq-net-timestamp-support-ieCkL
kixelated May 28, 2026
6bc50a0
Merge origin/dev into claude/moq-net-timestamp-support-ieCkL
kixelated Jun 1, 2026
97d622f
moq-net: Lite05 wire format for per-frame timestamps
kixelated Jun 1, 2026
19a2e65
moq-net: gate Lite05 timestamp byte on negotiated timescale
kixelated Jun 1, 2026
a953eaf
moq-net: validate frame.timestamp at the model layer
kixelated Jun 1, 2026
f7458eb
Merge origin/dev: pick up TrackConsumer split (#1576)
kixelated Jun 1, 2026
0f832bd
moq-net(tests): adopt consume_track().subscribe() in Lite05 round-trips
kixelated Jun 1, 2026
a613c83
moq-net: cargo fmt
kixelated Jun 1, 2026
10cf9dc
moq-net + moq-mux + moq-rtc: stamp timescale on hang tracks
kixelated Jun 1, 2026
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
10 changes: 8 additions & 2 deletions rs/hang/src/container/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,15 @@ impl Frame {
let mut header = BytesMut::new();
value.encode_quic(&mut header).map_err(moq_net::Error::from)?;

let size = header.len() + self.payload.len();
let size = (header.len() + self.payload.len()) as u64;

let mut chunked = group.create_frame(size.into())?;
// Stamp the moq-net frame timestamp too so Lite05+ can delta-encode it on the
// wire independently of the container-level prefix.
let net_frame = moq_net::Frame {
size,
timestamp: Some(timestamp),
};
let mut chunked = group.create_frame(net_frame)?;
chunked.write(header.freeze())?;
chunked.write(self.payload.clone())?;
chunked.finish()?;
Expand Down
6 changes: 6 additions & 0 deletions rs/kio/src/waiter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ impl Waiter {
pub fn register(&self, list: &mut WaiterList) {
list.register(self);
}

/// The underlying [`Waker`]. Useful for bridging into other async machinery
/// (e.g. `futures::task::AtomicWaker`) that needs a `Waker` directly.
pub fn waker(&self) -> &Waker {
&self.waker
}
}

/// A list of weak wakers waiting for notification.
Expand Down
6 changes: 5 additions & 1 deletion rs/moq-audio/src/producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ impl AudioProducer {
};

let name = name.into();
let track = broadcast.create_track(moq_net::Track::new(name.clone()))?;
// Audio hang frames carry microsecond timestamps; advertise that on the
// track so Lite05 subscribers know what scale to expect and the model
// layer accepts Frame::timestamp on append.
let track =
broadcast.create_track(moq_net::Track::new(name.clone()).with_timescale(hang::container::TIMESCALE))?;
let track = moq_mux::container::Producer::new(track, moq_mux::container::legacy::Wire);

let mut catalog_mut = catalog.clone();
Expand Down
4 changes: 3 additions & 1 deletion rs/moq-mux/src/codec/aac/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ impl Import {
mut catalog: crate::catalog::hang::Producer,
config: Config,
) -> crate::Result<Self> {
let track = broadcast.unique_track(".aac")?;
let track = broadcast.create_track(
moq_net::Track::new(broadcast.unique_name(".aac")).with_timescale(hang::container::TIMESCALE),
)?;

let mut audio_config = hang::catalog::AudioConfig::new(
hang::catalog::AAC {
Expand Down
12 changes: 9 additions & 3 deletions rs/moq-mux/src/codec/av1/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ impl Import {
self.catalog.lock().video.renditions.remove(&track.name);
}

let track = self.broadcast.unique_track(".av01")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".av01")).with_timescale(hang::container::TIMESCALE),
)?;
tracing::debug!(name = ?track.name, ?config, "starting track");
self.catalog
.lock()
Expand Down Expand Up @@ -129,7 +131,9 @@ impl Import {
});
config.container = hang::catalog::Container::Legacy;

let track = self.broadcast.unique_track(".av01")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".av01")).with_timescale(hang::container::TIMESCALE),
)?;
tracing::debug!(name = ?track.name, "starting track with minimal config");
self.catalog
.lock()
Expand Down Expand Up @@ -206,7 +210,9 @@ impl Import {
self.catalog.lock().video.renditions.remove(&track.name);
}

let track = self.broadcast.unique_track(".av01")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".av01")).with_timescale(hang::container::TIMESCALE),
)?;
self.catalog
.lock()
.video
Expand Down
4 changes: 3 additions & 1 deletion rs/moq-mux/src/codec/h264/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,9 @@ mod tests {

// Producer side: publish the broadcast with one length-prefixed video track.
let mut broadcast = moq_net::Broadcast::new().produce();
let mut track = broadcast.create_track(moq_net::Track::new("video.m4s")).unwrap();
let mut track = broadcast
.create_track(moq_net::Track::new("video.m4s").with_timescale(hang::container::TIMESCALE))
.unwrap();

// Group 0 (keyframe-starting group): one IDR frame.
let mut g0 = track.create_group(moq_net::Group { sequence: 0 }).unwrap();
Expand Down
12 changes: 9 additions & 3 deletions rs/moq-mux/src/codec/h264/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ impl Import {
};
}
Mode::Avc3 => {
let track = self.broadcast.unique_track(".avc3")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".avc3")).with_timescale(hang::container::TIMESCALE),
)?;
self.track = Some(crate::container::Producer::new(
track,
crate::catalog::hang::Container::Legacy,
Expand Down Expand Up @@ -167,7 +169,9 @@ impl Import {
pps: None,
};
if self.track.is_none() {
let track = self.broadcast.unique_track(".avc3")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".avc3")).with_timescale(hang::container::TIMESCALE),
)?;
self.track = Some(crate::container::Producer::new(
track,
crate::catalog::hang::Container::Legacy,
Expand Down Expand Up @@ -426,7 +430,9 @@ impl Import {
tracing::debug!(name = ?track.name, "reinitializing H.264 track");
catalog.video.renditions.remove(&track.name);
}
let track = self.broadcast.unique_track(suffix)?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(suffix)).with_timescale(hang::container::TIMESCALE),
)?;
tracing::debug!(name = ?track.name, ?config, "starting H.264 track");
catalog.video.renditions.insert(track.name.clone(), config.clone());

Expand Down
4 changes: 3 additions & 1 deletion rs/moq-mux/src/codec/h265/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ impl Import {
catalog.video.renditions.remove(&track.name);
}

let track = self.broadcast.unique_track(".hev1")?;
let track = self.broadcast.create_track(
moq_net::Track::new(self.broadcast.unique_name(".hev1")).with_timescale(hang::container::TIMESCALE),
)?;
tracing::debug!(name = ?track.name, ?config, "starting track");
catalog.video.renditions.insert(track.name.clone(), config.clone());

Expand Down
4 changes: 3 additions & 1 deletion rs/moq-mux/src/codec/opus/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ impl Import {
mut catalog: crate::catalog::hang::Producer,
config: Config,
) -> crate::Result<Self> {
let track = broadcast.unique_track(".opus")?;
let track = broadcast.create_track(
moq_net::Track::new(broadcast.unique_name(".opus")).with_timescale(hang::container::TIMESCALE),
)?;

let mut audio_config = hang::catalog::AudioConfig::new(
hang::catalog::AudioCodec::Opus,
Expand Down
Loading
Loading