diff --git a/quest/m0/README.md b/quest/m0/README.md index 007b836..97e79a7 100644 --- a/quest/m0/README.md +++ b/quest/m0/README.md @@ -107,7 +107,6 @@ repository. - [moq-video's browser backends are pinned](/quest/m0/pin-browser-video.md) - the web studio's video slice and browser composition - [moq-audio's browser backends are pinned](/quest/m0/pin-browser-audio.md) - the web studio's audio slice - [moq-audio's source tap is pinned](/quest/m0/pin-audio-tap.md) - the samples clap-to-measure sync times a clap from -- [A replayed media file never repeats a timestamp](/quest/m0/media-replay-timestamps.md) - a media source that starts over publishes strictly increasing timestamps, and its flaky test passes every run ## Related diff --git a/quest/m0/media-replay-timestamps.md b/quest/m0/media-replay-timestamps.md deleted file mode 100644 index ec72a1b..0000000 --- a/quest/m0/media-replay-timestamps.md +++ /dev/null @@ -1,25 +0,0 @@ -# [S] A replayed media file never repeats a timestamp - -## Goal - -A media source that starts over while on program publishes its pictures with -strictly increasing timestamps every time, and -`publish::tests::a_media_file_is_published_on_one_timeline` -(`rs/moq-scene/src/publish.rs`) passes on every run. - -## Plan - -Planned 2026-11-07 (maintainer, /quest-complete): ✅ m0 (rejected: m1), since -the test is in `just test`, so it flakes the merge gate for every PR, and the -repeat may reach viewers. ✅ A quest of its own (rejected: fixing it in the moq -pin bump, [moq-dev/studio#104](https://github.com/moq-dev/studio/pull/104)). - -The test fails about half its runs with two equal timestamps in a row: 4 of 8 -on `main` at d42fd70, 3 of 6 after the bump to moq 079a646. It came with -[moq-dev/studio#44](https://github.com/moq-dev/studio/pull/44); name that PR -under `## Caused by` if the bug is in its code. The test runs on a paused -clock, so the variation comes from work outside it, such as the encoder's -thread, racing the restart (`feed.play()`). Reproduce it first, then find -whether the published track can repeat a picture's time at a restart (a real -bug) or only the test reads too early, and fix that root cause rather than -retry or loosen the assertion. diff --git a/rs/moq-scene/src/source.rs b/rs/moq-scene/src/source.rs index 44b8ca1..1c1749f 100644 --- a/rs/moq-scene/src/source.rs +++ b/rs/moq-scene/src/source.rs @@ -1701,7 +1701,13 @@ impl Driver { if let (Some(frame), Some((_, config))) = (&picture, &video) { self.open(own, frame, config).await; } - let begin = begin.unwrap_or_else(|| kio::clock::now() + BUS_LATENCY); + // A cut's play begins after the last picture already published, even + // one cut off before it showed, so the track's time never repeats. + let begin = begin.unwrap_or_else(|| { + let soonest = kio::clock::now() + BUS_LATENCY; + own.stamped + .map_or(soonest, |stamped| soonest.max(stamped + Duration::from_millis(1))) + }); self.ran(play, |run| { run.begun.get_or_insert(begin); }); @@ -1796,6 +1802,7 @@ impl Driver { ) -> Result<(), Error> { self.open(own, frame, config).await; if let Some(video) = &mut own.track { + own.stamped = Some(shows); let stamp = shows.saturating_duration_since(own.origin); frame.timestamp = moq_net::Timestamp::from_micros(stamp.as_micros() as u64).map_err(moq_video::Error::from)?; @@ -1863,6 +1870,8 @@ struct Own<'a, 'b> { /// Whether the track was opened, or failed to, so it is tried once. opened: bool, origin: Instant, + /// When the last picture encoded onto the track shows. + stamped: Option, } impl<'a, 'b> Own<'a, 'b> { @@ -1872,6 +1881,7 @@ impl<'a, 'b> Own<'a, 'b> { track: None, opened: false, origin, + stamped: None, } } }