Skip to content
Merged
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
4 changes: 2 additions & 2 deletions rs/moq-cli/src/play/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,11 +494,11 @@ async fn play_audio<O: Output>(
let mut quiet = fit.pad + timing.silence.saturating_sub(fit.skip);
while quiet > 0 {
let part = (quiet as usize * stride).min(silence.len());
let _ = sink.write(&silence[..part])?;
sink.write(&silence[..part])?;
quiet -= (part / stride) as u64;
}
let skip = fit.skip.saturating_sub(timing.silence) as usize * stride;
let _ = sink.write(&frame.data[skip.min(frame.data.len())..])?;
sink.write(&frame.data[skip.min(frame.data.len())..])?;

// Anchor the playout clock on where the speaker has actually reached, which
// is the only half of the pipeline that cannot skip ahead. A move has to
Expand Down
21 changes: 15 additions & 6 deletions rs/moq-net/benches/origin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,10 @@ fn bench_reprice_duplicate(c: &mut Criterion) {
for cost in [incumbent_cost - 1, incumbent_cost + 1] {
route.update(peer_route(challenger, cost)).unwrap();
for cursor in &mut cursors {
// The winner switches between epochless routes, which is another instance.
let event = cursor.next().now_or_never().flatten().expect("winner changed");
let moq_net::announce::Event::Update(update) = event else {
panic!("expected an update: got {event:?}");
let moq_net::announce::Event::Restart(update) = event else {
panic!("expected a restart: got {event:?}");
};
assert_eq!(update.route.cost, moq_net::origin::Cost::new(cost.min(incumbent_cost)));
}
Expand Down Expand Up @@ -654,8 +655,10 @@ fn bench_pool_cursors(c: &mut Criterion) {

/// Publisher handoff at one path: a subscriber is reading from one local
/// source when a second announces at the same path and takes over (newest
/// wins). Measured from the standby's attach to the subscriber receiving its
/// first group, with `publishers` unrelated broadcasts in the table.
/// wins). An open subscription stays on the old instance, so the subscriber
/// re-requests the broadcast. Measured from the standby's attach to the
/// re-request receiving its first group, with `publishers` unrelated
/// broadcasts in the table.
fn bench_handoff(c: &mut Criterion) {
let mut group = c.benchmark_group("origin/handoff");
group.measurement_time(Duration::from_secs(5));
Expand Down Expand Up @@ -695,14 +698,20 @@ fn bench_handoff(c: &mut Criterion) {
second.finish().unwrap();
// Announcing is what makes the standby a route the front can take.
standby.announce(origin::Route::default()).unwrap();
subscription.recv_group().await.unwrap().expect("standby group");
let replaced = consumer.request_broadcast("room/live", None).await.unwrap();
let mut replacement = replaced.track("video").unwrap().subscribe(None).await.unwrap();
let group = replacement.recv_group().await.unwrap().expect("standby group");
total += started.elapsed();
// Rejoining the incumbent would replay its cached group 0 instead.
assert_eq!(group.sequence, 1, "standby group");

drop(subscription);
drop(replacement);
incumbent.close();
standby.close();
// Wait for the front to close so the next iteration starts a fresh one.
// Wait for the fronts to close so the next iteration starts fresh ones.
resolved.closed().await;
replaced.closed().await;
}
total
})
Expand Down
36 changes: 6 additions & 30 deletions rs/moq-video/src/render/dmabuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,29 +299,10 @@ unsafe fn adopt_plane(
/// would produce, with pixels it chose itself.
#[cfg(all(test, feature = "vaapi"))]
pub(super) mod fixture {
use std::os::fd::OwnedFd;
use std::sync::Arc;

use super::*;

/// A DMA-BUF built from an already exported descriptor.
///
/// The export holds its own reference on the underlying allocation, so the
/// VA-API surface it came from is long gone by the time anything imports
/// this. Downloading is not implemented: the point of the fixture is the
/// zero-copy path, and a test comparing against the CPU one builds its
/// reference from the bytes it uploaded rather than reading them back.
struct Exported(OwnedFd);

impl crate::frame::DmaBufFrame for Exported {
fn export(&self) -> std::io::Result<OwnedFd> {
self.0.try_clone()
}

fn download_i420(&self) -> Result<crate::frame::I420, Error> {
Err(err("the DMA-BUF fixture does not implement downloading"))
}
}
use crate::DmaBufLayout;

/// The VA-API fourcc naming the same layout as a DRM format.
///
Expand Down Expand Up @@ -422,16 +403,11 @@ pub(super) mod fixture {
.collect();
let fd = object.fd.try_clone().expect("duplicate the exported descriptor");

DmaBuf::new(
format,
object.drm_format_modifier,
size.width,
size.height,
planes,
None,
Arc::new(Exported(fd)),
)
.expect("a well-formed DMA-BUF")
// The export holds its own reference on the allocation, so the VA-API
// surface it came from can go away before anything imports this.
let mut layout = DmaBufLayout::new(format, size, planes);
layout.modifier = object.drm_format_modifier;
DmaBuf::new(fd, layout, ()).expect("a well-formed DMA-BUF")
}

/// Copy tightly packed planes into a surface, honoring the image's own plane
Expand Down
Loading