mod bitreader;
pub mod parser;
#[cfg(test)]
pub(crate) mod testutil;
pub use parser::{CodecConfig, CodecParser, VideoParams};
#[cfg(feature = "_nal")]
pub mod nal;
#[cfg(feature = "codec-h264")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-h264")))]
pub mod h264;
#[cfg(feature = "codec-h265")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-h265")))]
pub mod h265;
#[cfg(feature = "codec-vvc")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-vvc")))]
pub mod vvc;
#[cfg(feature = "codec-av1")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-av1")))]
pub mod av1;
#[cfg(feature = "codec-av1")]
pub(crate) mod obu;
#[cfg(feature = "codec-vp9")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-vp9")))]
pub mod vp9;
#[cfg(feature = "codec-aac")]
#[cfg_attr(docsrs, doc(cfg(feature = "codec-aac")))]
pub mod aac;
#[cfg(feature = "codec-aac")]
pub use aac::{parse_adts, AdtsHeader};
#[cfg(feature = "codec-h264")]
pub use h264::{annexb_to_avcc, avcc_to_annexb, iter_nals_annexb, parse_sps, SpsInfo};
pub mod dispatch {
use super::*;
use crate::CodecId;
#[allow(unused_variables)]
pub fn parse_config(codec: CodecId, data: &[u8]) -> Option<VideoParams> {
match codec {
#[cfg(feature = "codec-h264")]
CodecId::H264 => <h264::H264 as CodecParser>::parse_config(data),
#[cfg(feature = "codec-h265")]
CodecId::H265 => <h265::H265 as CodecParser>::parse_config(data),
#[cfg(feature = "codec-vvc")]
CodecId::VVC => <vvc::Vvc as CodecParser>::parse_config(data),
#[cfg(feature = "codec-av1")]
CodecId::AV1 => <av1::Av1 as CodecParser>::parse_config(data),
#[cfg(feature = "codec-vp9")]
CodecId::VP9 => <vp9::Vp9 as CodecParser>::parse_config(data),
_ => None,
}
}
#[allow(unused_variables)]
pub fn is_random_access_point(codec: CodecId, data: &[u8]) -> bool {
match codec {
#[cfg(feature = "codec-h264")]
CodecId::H264 => <h264::H264 as CodecParser>::is_random_access_point(data),
#[cfg(feature = "codec-h265")]
CodecId::H265 => <h265::H265 as CodecParser>::is_random_access_point(data),
#[cfg(feature = "codec-vvc")]
CodecId::VVC => <vvc::Vvc as CodecParser>::is_random_access_point(data),
#[cfg(feature = "codec-av1")]
CodecId::AV1 => <av1::Av1 as CodecParser>::is_random_access_point(data),
#[cfg(feature = "codec-vp9")]
CodecId::VP9 => <vp9::Vp9 as CodecParser>::is_random_access_point(data),
_ => false,
}
}
#[allow(unused_variables)]
pub fn parameter_sets(codec: CodecId, annexb: &[u8]) -> Option<bytes::Bytes> {
use crate::codec::nal::iter_nals;
let is_param_set = |nal: &[u8]| -> bool {
let Some(&b0) = nal.first() else { return false };
match codec {
#[cfg(feature = "codec-h264")]
CodecId::H264 => matches!(b0 & 0x1f, h264::NAL_SPS | h264::NAL_PPS),
#[cfg(feature = "codec-h265")]
CodecId::H265 => {
matches!(
(b0 >> 1) & 0x3f,
h265::NAL_VPS | h265::NAL_SPS | h265::NAL_PPS
)
}
_ => false,
}
};
let mut out = Vec::new();
for nal in iter_nals(annexb) {
if is_param_set(nal) {
out.extend_from_slice(&[0, 0, 0, 1]);
out.extend_from_slice(nal);
}
}
(!out.is_empty()).then(|| bytes::Bytes::from(out))
}
#[allow(unused_variables)]
pub fn hls_codec_string(codec: CodecId, params: &VideoParams) -> Option<String> {
match codec {
#[cfg(feature = "codec-h264")]
CodecId::H264 => Some(<h264::H264 as CodecParser>::hls_codec_string(params)),
#[cfg(feature = "codec-h265")]
CodecId::H265 => Some(<h265::H265 as CodecParser>::hls_codec_string(params)),
#[cfg(feature = "codec-vvc")]
CodecId::VVC => Some(<vvc::Vvc as CodecParser>::hls_codec_string(params)),
#[cfg(feature = "codec-av1")]
CodecId::AV1 => Some(<av1::Av1 as CodecParser>::hls_codec_string(params)),
#[cfg(feature = "codec-vp9")]
CodecId::VP9 => Some(<vp9::Vp9 as CodecParser>::hls_codec_string(params)),
_ => None,
}
}
}