use crate::audio::AudioInfoFrame;
use crate::avi::AviInfoFrame;
use crate::decoded::Decoded;
use crate::dynamic_hdr::DynamicHdrFragment;
use crate::error::DecodeError;
use crate::frame::InfoFramePacket;
use crate::hdmi_forum_vsi::{HDMI_FORUM_OUI, HdmiForumVsi};
use crate::hdr_static::HdrStaticInfoFrame;
use crate::warn::Warning;
pub(crate) mod type_code {
pub(crate) const VSIF: u8 = 0x81;
pub(crate) const AVI: u8 = 0x82;
pub(crate) const AUDIO: u8 = 0x84;
pub(crate) const HDR_STATIC: u8 = 0x87;
pub(crate) const DYNAMIC_HDR: u8 = 0x20;
}
pub fn decode(packet: &[u8; 31]) -> Result<Decoded<InfoFramePacket, Warning>, DecodeError> {
let length = packet[2];
if length > 27 {
return Err(DecodeError::Truncated { claimed: length });
}
let type_code = packet[0];
let version = packet[1];
let mut payload = [0u8; 27];
payload.copy_from_slice(&packet[4..31]);
match type_code {
type_code::AVI => {
Ok(AviInfoFrame::decode(packet)?.wrap(InfoFramePacket::Avi, Warning::Avi))
}
type_code::AUDIO => {
Ok(AudioInfoFrame::decode(packet)?.wrap(InfoFramePacket::Audio, Warning::Audio))
}
type_code::HDR_STATIC => Ok(HdrStaticInfoFrame::decode(packet)?
.wrap(InfoFramePacket::HdrStatic, Warning::HdrStatic)),
type_code::VSIF => {
if packet[4..7] == HDMI_FORUM_OUI {
Ok(HdmiForumVsi::decode(packet)?
.wrap(InfoFramePacket::HdmiForumVsi, Warning::HdmiForumVsi))
} else {
Ok(Decoded::new(InfoFramePacket::Unknown {
type_code,
version,
payload,
}))
}
}
type_code::DYNAMIC_HDR => Ok(DynamicHdrFragment::decode(packet)?
.wrap(InfoFramePacket::DynamicHdrFragment, Warning::DynamicHdr)),
_ => Ok(Decoded::new(InfoFramePacket::Unknown {
type_code,
version,
payload,
})),
}
}
#[cfg(test)]
#[path = "decode_tests.rs"]
mod tests;