#![forbid(unsafe_code)]
#![deny(rust_2018_idioms, future_incompatible, missing_docs)]
macro_rules! const_assert {
($x:expr $(,)?) => {
#[allow(unknown_lints, clippy::eq_op)]
{
const ASSERT: [(); 1] = [()];
let _ = ASSERT[!($x) as usize];
}
};
}
pub mod packet;
#[macro_use]
pub mod demultiplex;
pub mod descriptor;
pub mod mpegts_crc;
pub mod pes;
pub mod psi;
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum StreamType {
Iso11172Video,
H262,
Iso11172Audio,
Iso138183Audio,
H2220PrivateSections,
H2220PesPrivateData,
Mheg,
H2220DsmCc,
H2221,
Iso138186MultiprotocolEncapsulation,
DsmccUnMessages,
DsmccStreamDescriptors,
DsmccSections,
H2220Auxiliary,
Adts,
Iso144962Visual,
Latm,
FlexMuxPes,
FlexMuxIso14496Sections,
SynchronizedDownloadProtocol,
MetadataInPes,
MetadataInMetadataSections,
DsmccDataCarouselMetadata,
DsmccObjectCarouselMetadata,
SynchronizedDownloadProtocolMetadata,
Ipmp,
H264,
AudioWithoutTransportSyntax,
Iso1449617text,
H265,
ChineseVideoStandard,
AtscDolbyDigitalAudio,
AtscDsmccNetworkResourcesTable,
AtscDsmccSynchronousData,
Private(u8),
Reserved(u8),
}
impl StreamType {
pub fn is_pes(self) -> bool {
match self {
StreamType::Iso11172Video
| StreamType::H262
| StreamType::Iso11172Audio
| StreamType::Iso138183Audio
| StreamType::H2220PesPrivateData
| StreamType::Mheg
| StreamType::H2220DsmCc
| StreamType::H2221
| StreamType::Iso138186MultiprotocolEncapsulation
| StreamType::DsmccUnMessages
| StreamType::DsmccStreamDescriptors
| StreamType::DsmccSections
| StreamType::H2220Auxiliary
| StreamType::Adts
| StreamType::Iso144962Visual
| StreamType::Latm
| StreamType::FlexMuxPes
| StreamType::FlexMuxIso14496Sections
| StreamType::SynchronizedDownloadProtocol
| StreamType::MetadataInPes
| StreamType::MetadataInMetadataSections
| StreamType::DsmccDataCarouselMetadata
| StreamType::DsmccObjectCarouselMetadata
| StreamType::SynchronizedDownloadProtocolMetadata
| StreamType::Ipmp
| StreamType::H264
| StreamType::AudioWithoutTransportSyntax
| StreamType::Iso1449617text
| StreamType::H265
| StreamType::ChineseVideoStandard
| StreamType::AtscDolbyDigitalAudio
| StreamType::AtscDsmccNetworkResourcesTable
| StreamType::AtscDsmccSynchronousData => true,
StreamType::H2220PrivateSections | StreamType::Reserved(_) | StreamType::Private(_) => {
false
}
}
}
}
impl From<u8> for StreamType {
fn from(val: u8) -> Self {
match val {
0x01 => StreamType::Iso11172Video,
0x02 => StreamType::H262,
0x03 => StreamType::Iso11172Audio,
0x04 => StreamType::Iso138183Audio,
0x05 => StreamType::H2220PrivateSections,
0x06 => StreamType::H2220PesPrivateData,
0x07 => StreamType::Mheg,
0x08 => StreamType::H2220DsmCc,
0x09 => StreamType::H2221,
0x0A => StreamType::Iso138186MultiprotocolEncapsulation,
0x0B => StreamType::DsmccUnMessages,
0x0C => StreamType::DsmccStreamDescriptors,
0x0D => StreamType::DsmccSections,
0x0E => StreamType::H2220Auxiliary,
0x0F => StreamType::Adts,
0x10 => StreamType::Iso144962Visual,
0x11 => StreamType::Latm,
0x12 => StreamType::FlexMuxPes,
0x13 => StreamType::FlexMuxIso14496Sections,
0x14 => StreamType::SynchronizedDownloadProtocol,
0x15 => StreamType::MetadataInPes,
0x16 => StreamType::MetadataInMetadataSections,
0x17 => StreamType::DsmccDataCarouselMetadata,
0x18 => StreamType::DsmccObjectCarouselMetadata,
0x19 => StreamType::SynchronizedDownloadProtocolMetadata,
0x1a => StreamType::Ipmp,
0x1b => StreamType::H264,
0x1c => StreamType::AudioWithoutTransportSyntax,
0x1d => StreamType::Iso1449617text,
0x24 => StreamType::H265,
0x42 => StreamType::ChineseVideoStandard,
0x81 => StreamType::AtscDolbyDigitalAudio,
0x95 => StreamType::AtscDsmccNetworkResourcesTable,
0xc2 => StreamType::AtscDsmccSynchronousData,
_ => {
if val >= 0x80 {
StreamType::Private(val)
} else {
StreamType::Reserved(val)
}
}
}
}
}
impl From<StreamType> for u8 {
fn from(val: StreamType) -> Self {
match val {
StreamType::Iso11172Video => 0x01,
StreamType::H262 => 0x02,
StreamType::Iso11172Audio => 0x03,
StreamType::Iso138183Audio => 0x04,
StreamType::H2220PrivateSections => 0x05,
StreamType::H2220PesPrivateData => 0x06,
StreamType::Mheg => 0x07,
StreamType::H2220DsmCc => 0x08,
StreamType::H2221 => 0x09,
StreamType::Iso138186MultiprotocolEncapsulation => 0x0A,
StreamType::DsmccUnMessages => 0x0B,
StreamType::DsmccStreamDescriptors => 0x0C,
StreamType::DsmccSections => 0x0D,
StreamType::H2220Auxiliary => 0x0E,
StreamType::Adts => 0x0F,
StreamType::Iso144962Visual => 0x10,
StreamType::Latm => 0x11,
StreamType::FlexMuxPes => 0x12,
StreamType::FlexMuxIso14496Sections => 0x13,
StreamType::SynchronizedDownloadProtocol => 0x14,
StreamType::MetadataInPes => 0x15,
StreamType::MetadataInMetadataSections => 0x16,
StreamType::DsmccDataCarouselMetadata => 0x17,
StreamType::DsmccObjectCarouselMetadata => 0x18,
StreamType::SynchronizedDownloadProtocolMetadata => 0x19,
StreamType::Ipmp => 0x1a,
StreamType::H264 => 0x1b,
StreamType::AudioWithoutTransportSyntax => 0x1c,
StreamType::Iso1449617text => 0x1d,
StreamType::H265 => 0x24,
StreamType::ChineseVideoStandard => 0x42,
StreamType::AtscDolbyDigitalAudio => 0x81,
StreamType::AtscDsmccNetworkResourcesTable => 0x95,
StreamType::AtscDsmccSynchronousData => 0xc2,
StreamType::Reserved(val) => val,
StreamType::Private(val) => val,
}
}
}
pub const STUFFING_PID: packet::Pid = packet::Pid::new(0x1fff);
#[cfg(test)]
mod test {
use super::StreamType;
#[test]
fn mappings() {
for st in 0..=255 {
assert_eq!(st, StreamType::from(st).into())
}
}
#[test]
fn pes() {
for st in 0..=255 {
let ty = StreamType::from(st);
match ty {
StreamType::H2220PrivateSections
| StreamType::Reserved(_)
| StreamType::Private(_) => assert!(!ty.is_pes(), "{:?}", ty),
_ => assert!(ty.is_pes(), "{:?}", ty),
}
}
}
}