1pub mod pps;
8pub mod sei;
9pub mod slice;
10pub mod sps;
11
12use crate::rbsp;
13use hex_slice::AsHex;
14use std::fmt;
15
16#[derive(PartialEq, Hash, Debug, Copy, Clone)]
17pub enum UnitType {
18 Unspecified(u8),
20 SliceLayerWithoutPartitioningNonIdr,
21 SliceDataPartitionALayer,
22 SliceDataPartitionBLayer,
23 SliceDataPartitionCLayer,
24 SliceLayerWithoutPartitioningIdr,
25 SEI,
27 SeqParameterSet,
28 PicParameterSet,
29 AccessUnitDelimiter,
30 EndOfSeq,
31 EndOfStream,
32 FillerData,
33 SeqParameterSetExtension,
34 PrefixNALUnit,
35 SubsetSeqParameterSet,
36 DepthParameterSet,
37 SliceLayerWithoutPartitioningAux,
38 SliceExtension,
39 SliceExtensionViewComponent,
40 Reserved(u8),
42}
43impl UnitType {
44 pub fn for_id(id: u8) -> Result<UnitType, UnitTypeError> {
45 if id > 31 {
46 Err(UnitTypeError::ValueOutOfRange(id))
47 } else {
48 let t = match id {
49 0 => UnitType::Unspecified(0),
50 1 => UnitType::SliceLayerWithoutPartitioningNonIdr,
51 2 => UnitType::SliceDataPartitionALayer,
52 3 => UnitType::SliceDataPartitionBLayer,
53 4 => UnitType::SliceDataPartitionCLayer,
54 5 => UnitType::SliceLayerWithoutPartitioningIdr,
55 6 => UnitType::SEI,
56 7 => UnitType::SeqParameterSet,
57 8 => UnitType::PicParameterSet,
58 9 => UnitType::AccessUnitDelimiter,
59 10 => UnitType::EndOfSeq,
60 11 => UnitType::EndOfStream,
61 12 => UnitType::FillerData,
62 13 => UnitType::SeqParameterSetExtension,
63 14 => UnitType::PrefixNALUnit,
64 15 => UnitType::SubsetSeqParameterSet,
65 16 => UnitType::DepthParameterSet,
66 17..=18 => UnitType::Reserved(id),
67 19 => UnitType::SliceLayerWithoutPartitioningAux,
68 20 => UnitType::SliceExtension,
69 21 => UnitType::SliceExtensionViewComponent,
70 22..=23 => UnitType::Reserved(id),
71 24..=31 => UnitType::Unspecified(id),
72 _ => panic!("unexpected {}", id), };
74 Ok(t)
75 }
76 }
77
78 pub fn id(self) -> u8 {
79 match self {
80 UnitType::Unspecified(v) => v,
81 UnitType::SliceLayerWithoutPartitioningNonIdr => 1,
82 UnitType::SliceDataPartitionALayer => 2,
83 UnitType::SliceDataPartitionBLayer => 3,
84 UnitType::SliceDataPartitionCLayer => 4,
85 UnitType::SliceLayerWithoutPartitioningIdr => 5,
86 UnitType::SEI => 6,
87 UnitType::SeqParameterSet => 7,
88 UnitType::PicParameterSet => 8,
89 UnitType::AccessUnitDelimiter => 9,
90 UnitType::EndOfSeq => 10,
91 UnitType::EndOfStream => 11,
92 UnitType::FillerData => 12,
93 UnitType::SeqParameterSetExtension => 13,
94 UnitType::PrefixNALUnit => 14,
95 UnitType::SubsetSeqParameterSet => 15,
96 UnitType::DepthParameterSet => 16,
97 UnitType::SliceLayerWithoutPartitioningAux => 19,
98 UnitType::SliceExtension => 20,
99 UnitType::SliceExtensionViewComponent => 21,
100 UnitType::Reserved(v) => v,
101 }
102 }
103}
104
105#[derive(Debug)]
106pub enum UnitTypeError {
107 ValueOutOfRange(u8),
109}
110
111#[derive(Copy, Clone, PartialEq, Eq)]
112pub struct NalHeader(u8);
113
114#[derive(Debug)]
115pub enum NalHeaderError {
116 ForbiddenZeroBit,
118}
119impl NalHeader {
120 pub fn new(header_value: u8) -> Result<NalHeader, NalHeaderError> {
121 if header_value & 0b1000_0000 != 0 {
122 Err(NalHeaderError::ForbiddenZeroBit)
123 } else {
124 Ok(NalHeader(header_value))
125 }
126 }
127
128 pub fn nal_ref_idc(self) -> u8 {
129 (self.0 & 0b0110_0000) >> 5
130 }
131
132 pub fn nal_unit_type(self) -> UnitType {
133 UnitType::for_id(self.0 & 0b0001_1111).unwrap()
134 }
135}
136impl From<NalHeader> for u8 {
137 fn from(v: NalHeader) -> Self {
138 v.0
139 }
140}
141
142impl fmt::Debug for NalHeader {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
144 f.debug_struct("NalHeader")
145 .field("nal_ref_idc", &self.nal_ref_idc())
146 .field("nal_unit_type", &self.nal_unit_type())
147 .finish()
148 }
149}
150
151pub trait Nal {
203 type BufRead: std::io::BufRead + Clone;
204
205 fn is_complete(&self) -> bool;
207
208 fn header(&self) -> Result<NalHeader, NalHeaderError>;
210
211 fn reader(&self) -> Self::BufRead;
215
216 #[inline]
219 fn rbsp_bytes(&self) -> rbsp::ByteReader<Self::BufRead> {
220 rbsp::ByteReader::skipping_h264_header(self.reader())
221 }
222
223 #[inline]
225 fn rbsp_bits(&self) -> rbsp::BitReader<rbsp::ByteReader<Self::BufRead>> {
226 rbsp::BitReader::new(self.rbsp_bytes())
227 }
228}
229
230#[derive(Clone, Eq, PartialEq)]
232pub struct RefNal<'a> {
233 header: u8,
234 complete: bool,
235
236 head: &'a [u8],
238 tail: &'a [&'a [u8]],
239}
240impl<'a> RefNal<'a> {
241 #[inline]
243 pub fn new(head: &'a [u8], tail: &'a [&'a [u8]], complete: bool) -> Self {
244 for buf in tail {
245 debug_assert!(!buf.is_empty());
246 }
247 Self {
248 header: *head.first().expect("RefNal must be non-empty"),
249 head,
250 tail,
251 complete,
252 }
253 }
254}
255impl<'a> Nal for RefNal<'a> {
256 type BufRead = RefNalReader<'a>;
257
258 #[inline]
259 fn is_complete(&self) -> bool {
260 self.complete
261 }
262
263 #[inline]
264 fn header(&self) -> Result<NalHeader, NalHeaderError> {
265 NalHeader::new(self.header)
266 }
267
268 #[inline]
269 fn reader(&self) -> Self::BufRead {
270 RefNalReader {
271 cur: self.head,
272 tail: self.tail,
273 complete: self.complete,
274 }
275 }
276}
277impl<'a> std::fmt::Debug for RefNal<'a> {
278 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
279 f.debug_struct("RefNal")
281 .field("header", &self.header())
282 .field(
283 "data",
284 &RefNalReader {
285 cur: self.head,
286 tail: self.tail,
287 complete: self.complete,
288 },
289 )
290 .finish()
291 }
292}
293
294#[derive(Clone)]
300pub struct RefNalReader<'a> {
301 cur: &'a [u8],
303 tail: &'a [&'a [u8]],
304 complete: bool,
305}
306impl<'a> RefNalReader<'a> {
307 fn next_chunk(&mut self) {
308 match self.tail {
309 [first, tail @ ..] => {
310 self.cur = first;
311 self.tail = tail;
312 }
313 _ => self.cur = &[], }
315 }
316}
317impl<'a> std::io::Read for RefNalReader<'a> {
318 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
319 let len;
320 if buf.is_empty() {
321 len = 0;
322 } else if self.cur.is_empty() && !self.complete {
323 return Err(std::io::Error::new(
324 std::io::ErrorKind::WouldBlock,
325 "reached end of partially-buffered NAL",
326 ));
327 } else if buf.len() < self.cur.len() {
328 len = buf.len();
329 let (copy, keep) = self.cur.split_at(len);
330 buf.copy_from_slice(copy);
331 self.cur = keep;
332 } else {
333 len = self.cur.len();
334 buf[..len].copy_from_slice(self.cur);
335 self.next_chunk();
336 }
337 Ok(len)
338 }
339}
340impl<'a> std::io::BufRead for RefNalReader<'a> {
341 fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
342 if self.cur.is_empty() && !self.complete {
343 return Err(std::io::Error::new(
344 std::io::ErrorKind::WouldBlock,
345 "reached end of partially-buffered NAL",
346 ));
347 }
348 Ok(self.cur)
349 }
350 fn consume(&mut self, amt: usize) {
351 self.cur = &self.cur[amt..];
352 if self.cur.is_empty() {
353 self.next_chunk();
354 }
355 }
356}
357impl<'a> std::fmt::Debug for RefNalReader<'a> {
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 write!(f, "{:02x}", self.cur.plain_hex(true))?;
360 for buf in self.tail {
361 write!(f, " {:02x}", buf.plain_hex(true))?;
362 }
363 if !self.complete {
364 f.write_str(" ...")?;
365 }
366 Ok(())
367 }
368}
369
370#[cfg(test)]
371mod test {
372 use std::io::{BufRead, Read};
373
374 use super::*;
375
376 #[test]
377 fn header() {
378 let h = NalHeader::new(0b0101_0001).unwrap();
379 assert_eq!(0b10, h.nal_ref_idc());
380 assert_eq!(UnitType::Reserved(17), h.nal_unit_type());
381 }
382
383 #[test]
384 fn ref_nal() {
385 fn common<'a>(head: &'a [u8], tail: &'a [&'a [u8]], complete: bool) -> RefNal<'a> {
386 let nal = RefNal::new(head, tail, complete);
387 assert_eq!(NalHeader::new(0b0101_0001).unwrap(), nal.header().unwrap());
388
389 let mut r = nal.reader();
391 let mut buf = [0u8; 5];
392 r.read_exact(&mut buf).unwrap();
393 assert_eq!(&buf[..], &[0b0101_0001, 1, 2, 3, 4]);
394 if complete {
395 assert_eq!(r.read(&mut buf[..]).unwrap(), 0);
396
397 let mut buf = Vec::new();
399 nal.reader().read_to_end(&mut buf).unwrap();
400 assert_eq!(buf, &[0b0101_0001, 1, 2, 3, 4]);
401 } else {
402 assert_eq!(
403 r.read(&mut buf[..]).unwrap_err().kind(),
404 std::io::ErrorKind::WouldBlock
405 );
406 }
407
408 nal
410 }
411
412 let nal = common(&[0b0101_0001, 1, 2, 3, 4], &[], false);
414 let mut r = nal.reader();
415 assert_eq!(r.fill_buf().unwrap(), &[0b0101_0001, 1, 2, 3, 4]);
416 r.consume(1);
417 assert_eq!(r.fill_buf().unwrap(), &[1, 2, 3, 4]);
418 r.consume(4);
419 assert_eq!(
420 r.fill_buf().unwrap_err().kind(),
421 std::io::ErrorKind::WouldBlock
422 );
423
424 let nal = common(&[0b0101_0001], &[&[1, 2], &[3, 4]], false);
426 let mut r = nal.reader();
427 assert_eq!(r.fill_buf().unwrap(), &[0b0101_0001]);
428 r.consume(1);
429 assert_eq!(r.fill_buf().unwrap(), &[1, 2]);
430 r.consume(2);
431 assert_eq!(r.fill_buf().unwrap(), &[3, 4]);
432 r.consume(1);
433 assert_eq!(r.fill_buf().unwrap(), &[4]);
434 r.consume(1);
435 assert_eq!(
436 r.fill_buf().unwrap_err().kind(),
437 std::io::ErrorKind::WouldBlock
438 );
439
440 let nal = common(&[0b0101_0001, 1, 2, 3, 4], &[], true);
442 let mut r = nal.reader();
443 assert_eq!(r.fill_buf().unwrap(), &[0b0101_0001, 1, 2, 3, 4]);
444 r.consume(1);
445 assert_eq!(r.fill_buf().unwrap(), &[1, 2, 3, 4]);
446 r.consume(4);
447 assert!(r.fill_buf().unwrap().is_empty());
448 }
449
450 #[test]
451 fn reader_debug() {
452 assert_eq!(
453 format!(
454 "{:?}",
455 RefNalReader {
456 cur: &b"\x00"[..],
457 tail: &[&b"\x01"[..], &b"\x02\x03"[..]],
458 complete: false,
459 }
460 ),
461 "00 01 02 03 ..."
462 );
463 }
464}