use std::collections::VecDeque;
use hang::catalog::VideoConfig;
use super::Frame;
use super::decoder::{Config, Decoder};
use crate::Error;
pub struct Consumer {
decoder: Decoder,
track: moq_mux::container::Consumer<moq_mux::container::legacy::Wire>,
pending: VecDeque<Frame>,
}
impl Consumer {
pub async fn new(
broadcast: &moq_net::broadcast::Consumer,
catalog: &VideoConfig,
name: impl Into<String>,
config: Config,
) -> Result<Self, Error> {
let decoder = Decoder::new(catalog, &config)?;
let name = name.into();
let track = broadcast
.track(&name)?
.subscribe(moq_net::track::Subscription::default().with_priority(hang::catalog::PRIORITY.video))
.await?;
let mut track = moq_mux::container::Consumer::new(track, moq_mux::container::legacy::Wire);
if let Some(latency) = config.latency_max {
track = track.with_latency(latency);
}
Ok(Self {
decoder,
track,
pending: VecDeque::new(),
})
}
pub fn name(&self) -> &str {
self.decoder.name()
}
pub async fn read(&mut self) -> Result<Option<Frame>, Error> {
loop {
if let Some(frame) = self.pending.pop_front() {
return Ok(Some(frame));
}
let Some(mux_frame) = self.track.read().await? else {
return Ok(None);
};
self.pending.extend(
self.decoder
.decode(&mux_frame.payload, mux_frame.timestamp, mux_frame.keyframe)?,
);
}
}
}