use serde::{Deserialize, Serialize};
use std::fmt;
use crate::packet::MediaKind;
use crate::rtp_::Frequency;
use super::format_params::FormatParams;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CodecSpec {
pub codec: Codec,
pub clock_rate: Frequency,
pub channels: Option<u8>,
pub format: FormatParams,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
#[allow(missing_docs)]
pub enum Codec {
Opus,
PCMU,
PCMA,
H264,
#[doc(hidden)]
H265,
Vp8,
Vp9,
#[doc(hidden)]
Av1,
#[doc(hidden)]
Rtx,
#[doc(hidden)]
Null,
#[doc(hidden)]
Unknown,
}
impl Codec {
pub fn is_audio(&self) -> bool {
use Codec::*;
matches!(self, Opus | PCMU | PCMA)
}
pub fn is_video(&self) -> bool {
use Codec::*;
matches!(self, H265 | H264 | Vp8 | Vp9 | Av1)
}
pub fn kind(&self) -> MediaKind {
if self.is_audio() {
MediaKind::Audio
} else {
MediaKind::Video
}
}
}
impl<'a> From<&'a str> for Codec {
fn from(v: &'a str) -> Self {
let lc = v.to_ascii_lowercase();
match &lc[..] {
"opus" => Codec::Opus,
"pcmu" => Codec::PCMU,
"pcma" => Codec::PCMA,
"h264" => Codec::H264,
"h265" => Codec::H265,
"vp8" => Codec::Vp8,
"vp9" => Codec::Vp9,
"av1" => Codec::Av1,
"rtx" => Codec::Rtx, _ => Codec::Unknown,
}
}
}
impl fmt::Display for Codec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Codec::Opus => write!(f, "opus"),
Codec::PCMU => write!(f, "PCMU"),
Codec::PCMA => write!(f, "PCMA"),
Codec::H264 => write!(f, "H264"),
Codec::H265 => write!(f, "H265"),
Codec::Vp8 => write!(f, "VP8"),
Codec::Vp9 => write!(f, "VP9"),
Codec::Av1 => write!(f, "AV1"),
Codec::Rtx => write!(f, "rtx"),
Codec::Null => write!(f, "null"),
Codec::Unknown => write!(f, "unknown"),
}
}
}