use core::fmt;
use ffmpeg_next::ffi::AVCodecID;
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct CodecId(i32);
impl CodecId {
#[inline]
pub const fn from_raw(raw: i32) -> Self {
Self(raw)
}
#[inline]
pub const fn raw(self) -> i32 {
self.0
}
pub const NONE: Self = Self(AVCodecID::AV_CODEC_ID_NONE as i32);
pub const H264: Self = Self(AVCodecID::AV_CODEC_ID_H264 as i32);
pub const HEVC: Self = Self(AVCodecID::AV_CODEC_ID_HEVC as i32);
pub const AV1: Self = Self(AVCodecID::AV_CODEC_ID_AV1 as i32);
pub const VP9: Self = Self(AVCodecID::AV_CODEC_ID_VP9 as i32);
pub const VP8: Self = Self(AVCodecID::AV_CODEC_ID_VP8 as i32);
pub const MPEG2VIDEO: Self = Self(AVCodecID::AV_CODEC_ID_MPEG2VIDEO as i32);
pub const MPEG4: Self = Self(AVCodecID::AV_CODEC_ID_MPEG4 as i32);
pub const PRORES: Self = Self(AVCodecID::AV_CODEC_ID_PRORES as i32);
pub const DNXHD: Self = Self(AVCodecID::AV_CODEC_ID_DNXHD as i32);
pub const FFV1: Self = Self(AVCodecID::AV_CODEC_ID_FFV1 as i32);
pub const JPEG2000: Self = Self(AVCodecID::AV_CODEC_ID_JPEG2000 as i32);
pub const MJPEG: Self = Self(AVCodecID::AV_CODEC_ID_MJPEG as i32);
pub const VC1: Self = Self(AVCodecID::AV_CODEC_ID_VC1 as i32);
pub const VVC: Self = Self(AVCodecID::AV_CODEC_ID_VVC as i32);
pub const AAC: Self = Self(AVCodecID::AV_CODEC_ID_AAC as i32);
pub const MP3: Self = Self(AVCodecID::AV_CODEC_ID_MP3 as i32);
pub const OPUS: Self = Self(AVCodecID::AV_CODEC_ID_OPUS as i32);
pub const FLAC: Self = Self(AVCodecID::AV_CODEC_ID_FLAC as i32);
pub const AC3: Self = Self(AVCodecID::AV_CODEC_ID_AC3 as i32);
pub const EAC3: Self = Self(AVCodecID::AV_CODEC_ID_EAC3 as i32);
pub const ALAC: Self = Self(AVCodecID::AV_CODEC_ID_ALAC as i32);
pub const DTS: Self = Self(AVCodecID::AV_CODEC_ID_DTS as i32);
pub const VORBIS: Self = Self(AVCodecID::AV_CODEC_ID_VORBIS as i32);
pub const PCM_S16LE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_S16LE as i32);
pub const PCM_S16BE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_S16BE as i32);
pub const PCM_S24LE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_S24LE as i32);
pub const PCM_S32LE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_S32LE as i32);
pub const PCM_F32LE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_F32LE as i32);
pub const PCM_F64LE: Self = Self(AVCodecID::AV_CODEC_ID_PCM_F64LE as i32);
pub const SUBRIP: Self = Self(AVCodecID::AV_CODEC_ID_SUBRIP as i32);
pub const ASS: Self = Self(AVCodecID::AV_CODEC_ID_ASS as i32);
pub const WEBVTT: Self = Self(AVCodecID::AV_CODEC_ID_WEBVTT as i32);
pub const MOV_TEXT: Self = Self(AVCodecID::AV_CODEC_ID_MOV_TEXT as i32);
pub const DVB_SUBTITLE: Self = Self(AVCodecID::AV_CODEC_ID_DVB_SUBTITLE as i32);
pub const HDMV_PGS_SUBTITLE: Self = Self(AVCodecID::AV_CODEC_ID_HDMV_PGS_SUBTITLE as i32);
pub const DVD_SUBTITLE: Self = Self(AVCodecID::AV_CODEC_ID_DVD_SUBTITLE as i32);
}
impl fmt::Debug for CodecId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match *self {
Self::NONE => "NONE",
Self::H264 => "H264",
Self::HEVC => "HEVC",
Self::AV1 => "AV1",
Self::VP9 => "VP9",
Self::VP8 => "VP8",
Self::MPEG2VIDEO => "MPEG2VIDEO",
Self::MPEG4 => "MPEG4",
Self::PRORES => "PRORES",
Self::DNXHD => "DNXHD",
Self::FFV1 => "FFV1",
Self::JPEG2000 => "JPEG2000",
Self::MJPEG => "MJPEG",
Self::VC1 => "VC1",
Self::VVC => "VVC",
Self::AAC => "AAC",
Self::MP3 => "MP3",
Self::OPUS => "OPUS",
Self::FLAC => "FLAC",
Self::AC3 => "AC3",
Self::EAC3 => "EAC3",
Self::ALAC => "ALAC",
Self::DTS => "DTS",
Self::VORBIS => "VORBIS",
Self::PCM_S16LE => "PCM_S16LE",
Self::PCM_S16BE => "PCM_S16BE",
Self::PCM_S24LE => "PCM_S24LE",
Self::PCM_S32LE => "PCM_S32LE",
Self::PCM_F32LE => "PCM_F32LE",
Self::PCM_F64LE => "PCM_F64LE",
Self::SUBRIP => "SUBRIP",
Self::ASS => "ASS",
Self::WEBVTT => "WEBVTT",
Self::MOV_TEXT => "MOV_TEXT",
Self::DVB_SUBTITLE => "DVB_SUBTITLE",
Self::HDMV_PGS_SUBTITLE => "HDMV_PGS_SUBTITLE",
Self::DVD_SUBTITLE => "DVD_SUBTITLE",
_ => return write!(f, "CodecId({})", self.0),
};
write!(f, "CodecId::{name}")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_raw_round_trips() {
let id = CodecId::from_raw(27);
assert_eq!(id.raw(), 27);
}
#[test]
fn known_constants_match_av_values() {
assert_eq!(CodecId::H264.raw(), AVCodecID::AV_CODEC_ID_H264 as i32);
assert_eq!(CodecId::AAC.raw(), AVCodecID::AV_CODEC_ID_AAC as i32);
assert_eq!(CodecId::SUBRIP.raw(), AVCodecID::AV_CODEC_ID_SUBRIP as i32);
}
#[test]
fn debug_uses_name_for_known_codecs() {
assert_eq!(format!("{:?}", CodecId::H264), "CodecId::H264");
assert_eq!(format!("{:?}", CodecId::AAC), "CodecId::AAC");
}
#[test]
fn debug_falls_back_to_raw_for_unknown() {
let unknown = CodecId::from_raw(-99_999);
assert_eq!(format!("{:?}", unknown), "CodecId(-99999)");
}
#[test]
fn equality_is_value_based() {
assert_eq!(CodecId::H264, CodecId::from_raw(CodecId::H264.raw()));
assert_ne!(CodecId::H264, CodecId::HEVC);
}
}