#[cfg(test)]
mod h264_test;
use super::*;
fn profile_level_id_matches(a: &str, b: &str) -> bool {
let aa = match hex::decode(a) {
Ok(aa) => {
if aa.len() < 2 {
return false;
}
aa
}
Err(_) => return false,
};
let bb = match hex::decode(b) {
Ok(bb) => {
if bb.len() < 2 {
return false;
}
bb
}
Err(_) => return false,
};
aa[0] == bb[0] && aa[1] == bb[1]
}
#[derive(Debug, PartialEq)]
pub(crate) struct H264Fmtp {
pub(crate) parameters: HashMap<String, String>,
}
impl Fmtp for H264Fmtp {
fn mime_type(&self) -> &str {
"video/h264"
}
fn match_fmtp(&self, f: &dyn Fmtp) -> bool {
if let Some(c) = f.as_any().downcast_ref::<H264Fmtp>() {
let hpmode = match self.parameters.get("packetization-mode") {
Some(s) => s,
None => return false,
};
let cpmode = match c.parameters.get("packetization-mode") {
Some(s) => s,
None => return false,
};
if hpmode != cpmode {
return false;
}
let hplid = match self.parameters.get("profile-level-id") {
Some(s) => s,
None => return false,
};
let cplid = match c.parameters.get("profile-level-id") {
Some(s) => s,
None => return false,
};
if !profile_level_id_matches(hplid, cplid) {
return false;
}
true
} else {
false
}
}
fn parameter(&self, key: &str) -> Option<&String> {
self.parameters.get(key)
}
fn equal(&self, other: &dyn Fmtp) -> bool {
other.as_any().downcast_ref::<H264Fmtp>() == Some(self)
}
fn as_any(&self) -> &dyn Any {
self
}
}