use std::sync::Arc;
use crate::{Chunked, MemBlock, Void, fourcc::Fourcc};
use bitflags::bitflags;
use bytes::Buf;
bitflags! {
#[repr(transparent)]
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FrameFlags: u32 {
const KEYFRAME = 0b1 << 0; const LAST = 0b1 << 1; const LIVE = 0b1 << 2; const TIME_SYNCED = 0b1 << 3; const HAS_PARAMS = 0b1 << 4; const HAS_START_TIMESTAMP = 0b1 << 5; const MULTICHANNEL = 0b1 << 6; const ENCODED = 0b1 << 7; const DUMMY = 0b1 << 8; const ANNEXB = 0b1 << 9;
const AUDIO_STREAM = 0b1 << 16;
const VIDEO_STREAM = 0b1 << 17;
const METADATA_STREAM = 0b1 << 18;
}
}
pub enum FrameSourceKind {
Unknown,
File,
Url,
}
pub trait FrameSource: Sync + Send + Default + Clone + PartialEq + 'static {
type Source: FrameSource;
fn source(&self) -> &Self::Source;
#[inline]
fn kind(&self) -> FrameSourceKind {
self.source().kind()
}
#[inline]
fn url(&self) -> &str {
self.source().url()
}
#[inline]
fn name(&self) -> &str {
self.source().name()
}
}
impl<T: FrameSource> FrameSource for Arc<T> {
type Source = T::Source;
fn kind(&self) -> FrameSourceKind {
(**self).kind()
}
fn url(&self) -> &str {
(**self).url()
}
fn name(&self) -> &str {
(**self).name()
}
fn source(&self) -> &Self::Source {
(**self).source()
}
}
impl FrameSource for () {
type Source = Void;
fn kind(&self) -> FrameSourceKind {
FrameSourceKind::Unknown
}
fn url(&self) -> &str {
""
}
fn name(&self) -> &str {
""
}
fn source(&self) -> &Self::Source {
unreachable!()
}
}
impl FrameSource for String {
type Source = Void;
fn kind(&self) -> FrameSourceKind {
FrameSourceKind::Unknown
}
fn url(&self) -> &str {
self
}
fn name(&self) -> &str {
self
}
fn source(&self) -> &Self::Source {
unreachable!()
}
}
pub trait DataFrame: Send + Clone {
type Source: FrameSource;
type Chunk: Send + MemBlock;
fn source(&self) -> &Self::Source;
fn chunks(&self) -> impl Send + Iterator<Item = <Self::Chunk as MemBlock>::Ref<'_>>;
fn into_chunks(self) -> impl Send + Iterator<Item = Self::Chunk>;
fn put_into(self, chunks: &mut Chunked<Self::Chunk>)
where
Self::Chunk: Buf,
{
for chunk in self.into_chunks() {
chunks.put(chunk);
}
}
}
pub trait Frame: DataFrame {
fn timestamp(&self) -> u64;
fn codec(&self) -> Fourcc;
fn flags(&self) -> FrameFlags;
#[inline]
fn has_flag(&self, flag: FrameFlags) -> bool {
self.flags().contains(flag)
}
#[inline]
fn is_keyframe(&self) -> bool {
self.has_flag(FrameFlags::KEYFRAME)
}
#[inline]
fn is_live(&self) -> bool {
self.has_flag(FrameFlags::LIVE)
}
#[inline]
fn is_multichannel(&self) -> bool {
self.has_flag(FrameFlags::MULTICHANNEL)
}
#[inline]
fn is_encoded(&self) -> bool {
self.has_flag(FrameFlags::ENCODED)
}
#[inline]
fn is_last(&self) -> bool {
self.has_flag(FrameFlags::LAST)
}
#[inline]
fn has_params(&self) -> bool {
self.has_flag(FrameFlags::HAS_PARAMS)
}
#[inline]
fn has_start_timestamp(&self) -> bool {
self.has_flag(FrameFlags::HAS_START_TIMESTAMP)
}
#[inline]
fn is_audio(&self) -> bool {
self.has_flag(FrameFlags::AUDIO_STREAM)
}
#[inline]
fn is_video(&self) -> bool {
self.has_flag(FrameFlags::VIDEO_STREAM)
}
#[inline]
fn is_metadata(&self) -> bool {
self.has_flag(FrameFlags::METADATA_STREAM)
}
}
pub trait Live: Frame {
fn timestamp(&self) -> u64;
}
pub trait EncodedFrame: Frame {
type Param: AsRef<[u8]>;
#[inline]
fn dts(&self) -> u64 {
self.timestamp()
}
fn pts(&self) -> i64;
fn params(&self) -> impl Iterator<Item = &Self::Param>;
}
pub trait Multichannel: Frame {
fn track(&self) -> u32;
}
pub trait VideoFrame: Frame {
fn dimensions(&self) -> (u16, u16);
fn bit_depth(&self) -> u8;
}