use std::task::Poll;
use bytes::Bytes;
mod consumer;
mod group;
mod producer;
mod source;
#[cfg(test)]
pub(crate) mod test_util;
pub mod flv;
pub mod fmp4;
pub mod legacy;
pub mod loc;
pub mod mkv;
pub mod ts;
pub use consumer::Consumer;
pub use group::GroupConsumer;
pub use producer::Producer;
pub(crate) use source::ExportSource;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Kind {
Audio,
Video,
Data,
}
#[derive(Clone, Debug)]
pub struct Frame {
pub timestamp: moq_net::Timestamp,
pub duration: Option<moq_net::Timestamp>,
pub payload: Bytes,
pub keyframe: bool,
}
pub(crate) fn close_duration(frame: &mut Frame, bound: moq_net::Timestamp) {
if frame.duration.is_some() {
return;
}
let Some(delta) = bound.as_micros().checked_sub(frame.timestamp.as_micros()) else {
return;
};
if delta == 0 {
return;
}
let Ok(delta) = u64::try_from(delta) else {
return;
};
if let Ok(duration) = moq_net::Timestamp::from_micros(delta) {
frame.duration = Some(duration);
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("missing keyframe: a group must open on a keyframe")]
pub struct MissingKeyframe;
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("video group endpoint precedes its last frame")]
pub struct InvalidEnd;
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("frame timestamp is below the live edge")]
pub struct TimestampRewind;
pub trait Container {
type Error: std::error::Error
+ Send
+ Sync
+ Unpin
+ From<moq_net::Error>
+ From<MissingKeyframe>
+ From<InvalidEnd>
+ From<TimestampRewind>;
fn write(&self, group: &mut moq_net::group::Producer, frames: &[Frame]) -> Result<(), Self::Error>;
fn poll_read(
&self,
group: &mut moq_net::group::Consumer,
waiter: &kio::Waiter,
) -> Poll<Result<Option<Vec<Frame>>, Self::Error>>;
fn end(&self, _frame: &Frame) -> Option<moq_net::Timestamp> {
None
}
fn kind(&self) -> Kind {
Kind::Data
}
fn finish_group(
&self,
_group: &mut moq_net::group::Producer,
_end: Option<moq_net::Timestamp>,
) -> Result<(), Self::Error> {
Ok(())
}
fn read(
&self,
group: &mut moq_net::group::Consumer,
) -> impl std::future::Future<Output = Result<Option<Vec<Frame>>, Self::Error>>
where
Self: Sync,
{
async { kio::wait(|waiter| self.poll_read(group, waiter)).await }
}
}