use std::collections::VecDeque;
use bytes::{Bytes, BytesMut};
#[derive(Clone)]
pub struct AccessUnit {
pts: u64,
dts: u64,
data: Bytes,
}
impl AccessUnit {
#[inline]
pub const fn new(pts: u64, dts: u64, data: Bytes) -> Self {
Self { pts, dts, data }
}
#[inline]
pub const fn presentation_timestamp(&self) -> u64 {
self.pts
}
#[inline]
pub const fn with_presentation_timestamp(mut self, dts: u64) -> Self {
self.dts = dts;
self
}
#[inline]
pub const fn decoding_timestamp(&self) -> u64 {
self.dts
}
#[inline]
pub const fn with_decoding_timestamp(mut self, dts: u64) -> Self {
self.dts = dts;
self
}
#[inline]
pub const fn data(&self) -> &Bytes {
&self.data
}
#[inline]
pub fn into_data(self) -> Bytes {
self.data
}
}
pub struct AccessUnitBuilder {
available_aus: VecDeque<AccessUnit>,
rtp_timestamp: Option<u64>,
data: BytesMut,
}
impl AccessUnitBuilder {
pub fn new() -> Self {
Self {
available_aus: VecDeque::new(),
rtp_timestamp: None,
data: BytesMut::new(),
}
}
pub fn push(&mut self, timestamp: u64, nal_unit: &[u8]) {
if let Some(ts) = self.rtp_timestamp {
if ts != timestamp {
self.commit();
}
}
self.rtp_timestamp = Some(timestamp);
self.data.reserve(3 + nal_unit.len());
self.data.extend_from_slice(&[0, 0, 1]);
self.data.extend_from_slice(nal_unit);
}
pub fn flush(&mut self) {
self.commit();
}
pub fn take(&mut self) -> Option<AccessUnit> {
self.available_aus.pop_front()
}
pub fn available(&self) -> usize {
self.available_aus.len()
}
fn commit(&mut self) {
let Some(timestamp) = self.rtp_timestamp.take() else {
return;
};
let data = self.data.split();
let au = AccessUnit::new(timestamp, 0, data.freeze());
self.available_aus.push_back(au);
}
}