mpeg2ts_reader/psi/
pmt.rs1use crate::demultiplex::DemuxError;
4use crate::descriptor;
5use crate::packet;
6use crate::StreamType;
7use log::warn;
8use std::fmt;
9
10pub struct PmtSection<'buf> {
12 data: &'buf [u8],
13}
14impl<'buf> fmt::Debug for PmtSection<'buf> {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
16 f.debug_struct("PmtSection")
17 .field("pcr_pid", &self.pcr_pid())
18 .field("descriptors", &DescriptorsDebug(self))
19 .field("streams", &StreamsDebug(self))
20 .finish()
21 }
22}
23struct StreamsDebug<'buf>(&'buf PmtSection<'buf>);
24impl<'buf> fmt::Debug for StreamsDebug<'buf> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
26 f.debug_list().entries(self.0.streams()).finish()
27 }
28}
29struct DescriptorsDebug<'buf>(&'buf PmtSection<'buf>);
30impl<'buf> fmt::Debug for DescriptorsDebug<'buf> {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
32 f.debug_list()
33 .entries(self.0.descriptors::<descriptor::CoreDescriptors<'buf>>())
34 .finish()
35 }
36}
37
38impl<'buf> PmtSection<'buf> {
39 pub fn from_bytes(data: &'buf [u8]) -> Result<PmtSection<'buf>, DemuxError> {
42 if data.len() < Self::HEADER_SIZE {
43 Err(DemuxError::NotEnoughData {
44 field: "program_map_section",
45 expected: Self::HEADER_SIZE,
46 actual: data.len(),
47 })
48 } else {
49 let sect = PmtSection { data };
50 let expected = sect.program_info_length() as usize + Self::HEADER_SIZE;
51 if data.len() < expected {
52 Err(DemuxError::NotEnoughData {
53 field: "descriptor",
54 expected,
55 actual: data.len(),
56 })
57 } else {
58 Ok(sect)
59 }
60 }
61 }
62
63 pub fn buffer(&self) -> &[u8] {
65 self.data
66 }
67
68 const HEADER_SIZE: usize = 4;
69
70 pub fn pcr_pid(&self) -> packet::Pid {
72 packet::Pid::new(u16::from(self.data[0] & 0b0001_1111) << 8 | u16::from(self.data[1]))
73 }
74 fn program_info_length(&self) -> u16 {
75 u16::from(self.data[2] & 0b0000_1111) << 8 | u16::from(self.data[3])
76 }
77 pub fn descriptors<Desc: descriptor::Descriptor<'buf> + 'buf>(
79 &self,
80 ) -> impl Iterator<Item = Result<Desc, descriptor::DescriptorError>> + 'buf {
81 let descriptor_end = Self::HEADER_SIZE + self.program_info_length() as usize;
82 let descriptor_data = &self.data[Self::HEADER_SIZE..descriptor_end];
83 descriptor::DescriptorIter::new(descriptor_data)
84 }
85 pub fn streams(&self) -> impl Iterator<Item = StreamInfo<'buf>> {
87 let descriptor_end = Self::HEADER_SIZE + self.program_info_length() as usize;
88 if descriptor_end > self.data.len() {
89 warn!(
90 "program_info_length={} extends beyond end of PMT section (section_length={})",
91 self.program_info_length(),
92 self.data.len()
93 );
94 StreamInfoIter::new(&self.data[0..0])
96 } else {
97 StreamInfoIter::new(&self.data[descriptor_end..])
98 }
99 }
100}
101struct StreamInfoIter<'buf> {
103 buf: &'buf [u8],
104}
105impl<'buf> StreamInfoIter<'buf> {
106 fn new(buf: &'buf [u8]) -> StreamInfoIter<'buf> {
107 StreamInfoIter { buf }
108 }
109}
110impl<'buf> Iterator for StreamInfoIter<'buf> {
111 type Item = StreamInfo<'buf>;
112
113 fn next(&mut self) -> Option<Self::Item> {
114 if self.buf.is_empty() {
115 return None;
116 }
117 if let Some((stream_info, info_len)) = StreamInfo::from_bytes(self.buf) {
118 self.buf = &self.buf[info_len..];
119 Some(stream_info)
120 } else {
121 None
122 }
123 }
124}
125
126pub struct StreamInfo<'buf> {
135 data: &'buf [u8],
136}
137
138impl<'buf> StreamInfo<'buf> {
139 const HEADER_SIZE: usize = 5;
140
141 fn from_bytes(data: &'buf [u8]) -> Option<(StreamInfo<'buf>, usize)> {
142 if data.len() < Self::HEADER_SIZE {
143 warn!(
144 "only {} bytes remaining for stream info, at least {} required {:?}",
145 data.len(),
146 Self::HEADER_SIZE,
147 data
148 );
149 return None;
150 }
151 let result = StreamInfo { data };
152
153 let descriptor_end = Self::HEADER_SIZE + result.es_info_length() as usize;
154 if descriptor_end > data.len() {
155 warn!(
156 "PMT section of size {} is not large enough to contain es_info_length of {}",
157 data.len(),
158 result.es_info_length()
159 );
160 return None;
161 }
162 Some((result, descriptor_end))
163 }
164
165 pub fn stream_type(&self) -> StreamType {
167 StreamType(self.data[0])
168 }
169 pub fn elementary_pid(&self) -> packet::Pid {
171 packet::Pid::new(u16::from(self.data[1] & 0b0001_1111) << 8 | u16::from(self.data[2]))
172 }
173 fn es_info_length(&self) -> u16 {
174 u16::from(self.data[3] & 0b0000_1111) << 8 | u16::from(self.data[4])
175 }
176
177 pub fn descriptors<Desc: descriptor::Descriptor<'buf> + 'buf>(
179 &self,
180 ) -> impl Iterator<Item = Result<Desc, descriptor::DescriptorError>> + 'buf {
181 let descriptor_end = Self::HEADER_SIZE + self.es_info_length() as usize;
182 descriptor::DescriptorIter::new(&self.data[Self::HEADER_SIZE..descriptor_end])
183 }
184}
185impl<'buf> fmt::Debug for StreamInfo<'buf> {
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
187 f.debug_struct("StreamInfo")
188 .field("stream_type", &self.stream_type())
189 .field("elementary_pid", &self.elementary_pid())
190 .field("descriptors", &StreamInfoDescriptorsDebug(self))
191 .finish()
192 }
193}
194struct StreamInfoDescriptorsDebug<'buf>(&'buf StreamInfo<'buf>);
195impl<'buf> fmt::Debug for StreamInfoDescriptorsDebug<'buf> {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
197 f.debug_list()
198 .entries(self.0.descriptors::<descriptor::CoreDescriptors<'buf>>())
199 .finish()
200 }
201}
202
203#[cfg(test)]
204mod test {
205 use crate::demultiplex::test::make_test_data;
206 use crate::demultiplex::DemuxError;
207 use crate::descriptor::CoreDescriptors;
208 use crate::psi::pmt::PmtSection;
209 use assert_matches::assert_matches;
210 use bitstream_io::BitWrite;
211 use hex_literal::hex;
212
213 #[test]
214 fn debug_does_not_panic() {
215 let data = hex!("fd4df0001bfd4df00652010b70010411fd4ef01152010c0a04656e67007c025a007f02068211fd52f01252010d0a04656e67037c035880477f02060606fd51f00d5201055908656e671000010001");
216 let section = PmtSection::from_bytes(&data).unwrap();
217 assert!(!format!("{:?}", section).is_empty());
219 }
220
221 #[test]
222 fn far_too_small() {
223 let data = hex!("fd4df0");
224 assert_matches!(
225 PmtSection::from_bytes(&data),
226 Err(DemuxError::NotEnoughData {
227 expected: 4,
228 actual: 3,
229 ..
230 })
231 );
232 }
233
234 #[test]
235 fn descriptors_dont_fit() {
236 let data = make_test_data(|w| {
237 w.write(3, 0)?; w.write(13, 123)?; w.write(4, 0)?; w.write(12, 1) });
242 assert!(PmtSection::from_bytes(&data).is_err());
245 }
246
247 #[test]
248 fn truncated_descriptor() {
249 let data = make_test_data(|w| {
250 w.write(3, 0)?; w.write(13, 4)?; w.write(4, 0)?; w.write(12, 0x1)?; w.write(8, 0x1) });
256 let sect = PmtSection::from_bytes(&data).unwrap();
259 let mut iter = sect.descriptors::<CoreDescriptors<'_>>();
260 assert_matches!(iter.next(), Some(Err(_)));
261 assert_matches!(iter.next(), None);
262 }
263}