use super::imp::CAT;
use super::utils;
#[derive(Clone, Debug, PartialEq)]
pub(super) struct AudioInfo {
pub(super) rate: i32,
pub(super) channels: i32,
}
#[derive(Clone, Debug, Default, PartialEq)]
pub(super) enum MediaFormat {
#[default]
None,
Mpeg1Audio(AudioInfo),
AacAudio(AudioInfo),
FlacAudio(AudioInfo, Vec<gst::Buffer>),
OggAudio(AudioInfo, &'static str, Vec<gst::Buffer>),
}
impl MediaFormat {
pub(super) fn from_caps(caps: &gst::Caps) -> Result<Self, gst::LoggableError> {
let s = caps.structure(0).unwrap();
let media_format = match s.name().as_str() {
"audio/mpeg" => {
let rate = s.get::<i32>("rate").unwrap();
let channels = s.get::<i32>("channels").unwrap();
let mpegversion = s.get::<i32>("mpegversion").unwrap();
let audio_info = AudioInfo { rate, channels };
match mpegversion {
1 => MediaFormat::Mpeg1Audio(audio_info),
2 | 4 => MediaFormat::AacAudio(audio_info),
_ => unreachable!(),
}
}
"audio/x-flac" => {
let rate = s.get::<i32>("rate").unwrap();
let channels = s.get::<i32>("channels").unwrap();
let audio_info = AudioInfo { rate, channels };
let streamheaders = utils::get_streamheaders_from_caps(s)?;
MediaFormat::FlacAudio(audio_info, streamheaders)
}
"audio/ogg" => {
let streamheaders = utils::get_streamheaders_from_caps(s)?;
let (codec_name, audio_info) = utils::parse_ogg_audio_streamheaders(&streamheaders)
.map_err(|error_string| gst::loggable_error!(CAT, "{}", error_string))?;
MediaFormat::OggAudio(audio_info, codec_name, streamheaders)
}
media_type => {
unreachable!("Caps with unexpected media type {media_type}");
}
};
Ok(media_format)
}
pub(super) fn content_type(&self) -> Option<String> {
let content_type = match self {
MediaFormat::None => return None,
MediaFormat::Mpeg1Audio(..) => "audio/mpeg".to_string(),
MediaFormat::AacAudio(..) => "audio/aac".to_string(),
MediaFormat::FlacAudio(..) => "audio/flac".to_string(),
MediaFormat::OggAudio(_, _codec_name, ..) => "audio/ogg".to_string(),
};
Some(content_type)
}
pub(super) fn ice_audio_info(&self) -> Option<String> {
match self {
MediaFormat::None => None,
MediaFormat::Mpeg1Audio(audio_info)
| MediaFormat::AacAudio(audio_info)
| MediaFormat::FlacAudio(audio_info, ..)
| MediaFormat::OggAudio(audio_info, ..) => Some(format!(
"channels={};samplerate={}",
audio_info.channels, audio_info.rate
)),
}
}
pub(super) fn stream_headers(&self) -> Vec<gst::Buffer> {
match self {
MediaFormat::None => vec![],
MediaFormat::Mpeg1Audio(..) => vec![],
MediaFormat::AacAudio(..) => vec![],
MediaFormat::FlacAudio(_, stream_headers) => stream_headers.clone(),
MediaFormat::OggAudio(_, _, stream_headers) => stream_headers.clone(),
}
}
}