use crate::{
Timebase, Timestamp,
adapter::{AudioAdapter, SubtitleAdapter, VideoAdapter},
frame::{AudioFrame, SubtitleFrame, VideoFrame},
packet::{AudioPacket, SubtitlePacket, VideoPacket},
};
#[trait_variant::make(SendVideoStreamDecoder: Send)]
pub trait VideoStreamDecoder {
type Adapter: VideoAdapter;
type Buffer: AsRef<[u8]>;
type Error;
async fn send_packet(
&mut self,
packet: &VideoPacket<<Self::Adapter as VideoAdapter>::PacketExtra, Self::Buffer>,
) -> Result<(), Self::Error>;
async fn receive_frame(
&mut self,
dst: &mut VideoFrame<
<Self::Adapter as VideoAdapter>::PixelFormat,
<Self::Adapter as VideoAdapter>::FrameExtra,
Self::Buffer,
>,
) -> Result<(), Self::Error>;
async fn send_eof(&mut self) -> Result<(), Self::Error>;
async fn flush(&mut self) -> Result<(), Self::Error>;
}
#[trait_variant::make(SendVideoFrameSource: Send)]
pub trait VideoFrameSource {
type Adapter: VideoAdapter;
type Buffer: AsRef<[u8]>;
type ClipMeta;
type Error;
fn frame_count(&self) -> u64;
fn frame_rate(&self) -> Timebase;
fn duration(&self) -> Timestamp;
fn clip_meta(&self) -> &Self::ClipMeta;
async fn decode_frame(
&mut self,
index: u64,
dst: &mut VideoFrame<
<Self::Adapter as VideoAdapter>::PixelFormat,
<Self::Adapter as VideoAdapter>::FrameExtra,
Self::Buffer,
>,
) -> Result<(), Self::Error>;
}
#[trait_variant::make(SendAudioStreamDecoder: Send)]
pub trait AudioStreamDecoder {
type Adapter: AudioAdapter;
type Buffer: AsRef<[u8]>;
type Error;
async fn send_packet(
&mut self,
packet: &AudioPacket<<Self::Adapter as AudioAdapter>::PacketExtra, Self::Buffer>,
) -> Result<(), Self::Error>;
async fn receive_frame(
&mut self,
dst: &mut AudioFrame<
<Self::Adapter as AudioAdapter>::SampleFormat,
<Self::Adapter as AudioAdapter>::ChannelLayout,
<Self::Adapter as AudioAdapter>::FrameExtra,
Self::Buffer,
>,
) -> Result<(), Self::Error>;
async fn send_eof(&mut self) -> Result<(), Self::Error>;
async fn flush(&mut self) -> Result<(), Self::Error>;
}
#[trait_variant::make(SendAudioFrameSource: Send)]
pub trait AudioFrameSource {
type Adapter: AudioAdapter;
type Buffer: AsRef<[u8]>;
type ClipMeta;
type Error;
fn sample_count(&self) -> u64;
fn sample_rate(&self) -> u32;
fn channel_count(&self) -> u8;
fn clip_meta(&self) -> &Self::ClipMeta;
async fn decode_block(
&mut self,
sample_offset: u64,
sample_count: u32,
dst: &mut AudioFrame<
<Self::Adapter as AudioAdapter>::SampleFormat,
<Self::Adapter as AudioAdapter>::ChannelLayout,
<Self::Adapter as AudioAdapter>::FrameExtra,
Self::Buffer,
>,
) -> Result<(), Self::Error>;
}
#[trait_variant::make(SendSubtitleDecoder: Send)]
pub trait SubtitleDecoder {
type Adapter: SubtitleAdapter;
type Buffer: AsRef<[u8]>;
type Error;
async fn send_packet(
&mut self,
packet: &SubtitlePacket<<Self::Adapter as SubtitleAdapter>::PacketExtra, Self::Buffer>,
) -> Result<(), Self::Error>;
async fn receive_frame(
&mut self,
dst: &mut SubtitleFrame<<Self::Adapter as SubtitleAdapter>::FrameExtra, Self::Buffer>,
) -> Result<(), Self::Error>;
async fn send_eof(&mut self) -> Result<(), Self::Error>;
async fn flush(&mut self) -> Result<(), Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
use core::num::NonZeroU32;
struct VLoop;
impl VideoAdapter for VLoop {
type CodecId = u32;
type PixelFormat = u32;
type PacketExtra = ();
type FrameExtra = ();
}
struct ALoop;
impl AudioAdapter for ALoop {
type CodecId = u32;
type SampleFormat = u32;
type ChannelLayout = u32;
type PacketExtra = ();
type FrameExtra = ();
}
struct SLoop;
impl SubtitleAdapter for SLoop {
type CodecId = u32;
type PacketExtra = ();
type FrameExtra = ();
}
#[derive(Debug)]
struct LoopError;
struct AsyncVideo;
impl VideoStreamDecoder for AsyncVideo {
type Adapter = VLoop;
type Buffer = &'static [u8];
type Error = LoopError;
async fn send_packet(&mut self, _: &VideoPacket<(), &'static [u8]>) -> Result<(), LoopError> {
Ok(())
}
async fn receive_frame(
&mut self,
_: &mut VideoFrame<u32, (), &'static [u8]>,
) -> Result<(), LoopError> {
Err(LoopError)
}
async fn send_eof(&mut self) -> Result<(), LoopError> {
Ok(())
}
async fn flush(&mut self) -> Result<(), LoopError> {
Ok(())
}
}
struct AsyncVideoSrc;
impl VideoFrameSource for AsyncVideoSrc {
type Adapter = VLoop;
type Buffer = &'static [u8];
type ClipMeta = ();
type Error = LoopError;
fn frame_count(&self) -> u64 {
0
}
fn frame_rate(&self) -> Timebase {
Timebase::new(30, NonZeroU32::new(1).unwrap())
}
fn duration(&self) -> Timestamp {
Timestamp::new(0, self.frame_rate())
}
fn clip_meta(&self) -> &() {
&()
}
async fn decode_frame(
&mut self,
_: u64,
_: &mut VideoFrame<u32, (), &'static [u8]>,
) -> Result<(), LoopError> {
Err(LoopError)
}
}
struct AsyncAudio;
impl AudioStreamDecoder for AsyncAudio {
type Adapter = ALoop;
type Buffer = &'static [u8];
type Error = LoopError;
async fn send_packet(&mut self, _: &AudioPacket<(), &'static [u8]>) -> Result<(), LoopError> {
Ok(())
}
async fn receive_frame(
&mut self,
_: &mut AudioFrame<u32, u32, (), &'static [u8]>,
) -> Result<(), LoopError> {
Err(LoopError)
}
async fn send_eof(&mut self) -> Result<(), LoopError> {
Ok(())
}
async fn flush(&mut self) -> Result<(), LoopError> {
Ok(())
}
}
struct AsyncAudioSrc;
impl AudioFrameSource for AsyncAudioSrc {
type Adapter = ALoop;
type Buffer = &'static [u8];
type ClipMeta = ();
type Error = LoopError;
fn sample_count(&self) -> u64 {
0
}
fn sample_rate(&self) -> u32 {
48_000
}
fn channel_count(&self) -> u8 {
2
}
fn clip_meta(&self) -> &() {
&()
}
async fn decode_block(
&mut self,
_: u64,
_: u32,
_: &mut AudioFrame<u32, u32, (), &'static [u8]>,
) -> Result<(), LoopError> {
Err(LoopError)
}
}
struct AsyncSubtitle;
impl SubtitleDecoder for AsyncSubtitle {
type Adapter = SLoop;
type Buffer = &'static [u8];
type Error = LoopError;
async fn send_packet(
&mut self,
_: &SubtitlePacket<(), &'static [u8]>,
) -> Result<(), LoopError> {
Ok(())
}
async fn receive_frame(
&mut self,
_: &mut SubtitleFrame<(), &'static [u8]>,
) -> Result<(), LoopError> {
Err(LoopError)
}
async fn send_eof(&mut self) -> Result<(), LoopError> {
Ok(())
}
async fn flush(&mut self) -> Result<(), LoopError> {
Ok(())
}
}
#[test]
fn local_traits_are_implementable() {
fn _v<D: VideoStreamDecoder>() {}
fn _vs<D: VideoFrameSource>() {}
fn _a<D: AudioStreamDecoder>() {}
fn _as<D: AudioFrameSource>() {}
fn _s<D: SubtitleDecoder>() {}
_v::<AsyncVideo>();
_vs::<AsyncVideoSrc>();
_a::<AsyncAudio>();
_as::<AsyncAudioSrc>();
_s::<AsyncSubtitle>();
}
}