#![forbid(unsafe_code)]
mod formats;
mod frame;
mod gpu;
pub use bytes::Bytes;
pub use formats::{PixelFormat, SampleFormat};
pub use frame::{AudioFrame, VideoFrame, VideoFrameStorage};
pub use gpu::{GpuBufferHandle, GpuDeviceHandle, NativeHandle};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Rational {
pub num: u64,
pub den: u32,
}
impl Rational {
#[must_use]
pub const fn new(num: u64, den: u32) -> Self {
Self { num, den }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CodecKind {
H264,
Hevc,
Av1,
Vp9,
Aac,
Opus,
Mp3,
Vorbis,
WebVtt,
Tx3g,
RawVideo,
RawAudio,
}
impl CodecKind {
#[must_use]
pub const fn is_video(self) -> bool {
matches!(
self,
Self::H264 | Self::Hevc | Self::Av1 | Self::Vp9 | Self::RawVideo
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct VideoGeometry {
pub width: u32,
pub height: u32,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum StreamInfo {
Video {
id: u32,
codec: CodecKind,
time_base: Rational,
geometry: VideoGeometry,
extra_data: Bytes,
},
Audio {
id: u32,
codec: CodecKind,
time_base: Rational,
extra_data: Bytes,
sample_rate: u32,
channels: u16,
},
}
impl StreamInfo {
#[must_use]
pub const fn id(&self) -> u32 {
match self {
Self::Video { id, .. } | Self::Audio { id, .. } => *id,
}
}
#[must_use]
pub fn with_id(self, id: u32) -> Self {
match self {
Self::Video {
codec,
time_base,
geometry,
extra_data,
..
} => Self::Video {
id,
codec,
time_base,
geometry,
extra_data,
},
Self::Audio {
codec,
time_base,
extra_data,
sample_rate,
channels,
..
} => Self::Audio {
id,
codec,
time_base,
extra_data,
sample_rate,
channels,
},
}
}
#[must_use]
pub const fn codec(&self) -> CodecKind {
match self {
Self::Video { codec, .. } | Self::Audio { codec, .. } => *codec,
}
}
#[must_use]
pub const fn time_base(&self) -> Rational {
match self {
Self::Video { time_base, .. } | Self::Audio { time_base, .. } => *time_base,
}
}
#[must_use]
pub const fn extra_data(&self) -> &Bytes {
match self {
Self::Video { extra_data, .. } | Self::Audio { extra_data, .. } => extra_data,
}
}
#[must_use]
pub const fn geometry(&self) -> Option<VideoGeometry> {
match self {
Self::Video { geometry, .. } => Some(*geometry),
Self::Audio { .. } => None,
}
}
#[must_use]
pub const fn sample_rate(&self) -> Option<u32> {
match self {
Self::Audio { sample_rate, .. } => Some(*sample_rate),
Self::Video { .. } => None,
}
}
#[must_use]
pub const fn channels(&self) -> Option<u16> {
match self {
Self::Audio { channels, .. } => Some(*channels),
Self::Video { .. } => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Packet {
pub stream_id: u32,
pub pts: i64,
pub dts: i64,
pub duration: u64,
pub is_keyframe: bool,
pub is_discard: bool,
pub payload: Bytes,
}
#[cfg(test)]
#[path = "lib_tests.rs"]
mod tests;