1#![forbid(unsafe_code)]
27#![deny(rust_2018_idioms, future_incompatible)]
28
29use std::fmt;
33
34#[derive(Debug)]
35pub enum AdtsHeaderError {
36 BadSyncWord(u16),
39 NotEnoughData {
40 expected: usize,
41 actual: usize,
42 },
43 BadFrameLength {
46 minimum: usize,
47 actual: usize,
48 },
49}
50
51#[derive(Debug, PartialEq)]
54pub struct PayloadError {
55 pub expected: usize,
56 pub actual: usize,
57}
58
59#[derive(Debug, PartialEq)]
60pub enum MpegVersion {
61 Mpeg2,
62 Mpeg4,
63}
64
65#[derive(Debug, PartialEq, Clone, Copy)]
66pub enum AudioObjectType {
67 AacMain,
69 AacLC,
71 AacSSR,
73 AacLTP,
75}
76
77#[derive(Debug, PartialEq)]
78pub enum ProtectionIndicator {
79 CrcPresent,
80 CrcAbsent,
81}
82
83#[derive(Debug, PartialEq, Clone, Copy)]
84pub enum SamplingFrequency {
85 Freq96000 = 0x0,
87 Freq88200 = 0x1,
89 Freq64000 = 0x2,
91 Freq48000 = 0x3,
93 Freq44100 = 0x4,
95 Freq32000 = 0x5,
97 Freq24000 = 0x6,
99 Freq22050 = 0x7,
101 Freq16000 = 0x8,
103 Freq12000 = 0x9,
105 Freq11025 = 0xa,
107 Freq8000 = 0xb,
109 FreqReserved0xc = 0xc,
110 FreqReserved0xd = 0xd,
111 FreqReserved0xe = 0xe,
112 FreqReserved0xf = 0xf,
113}
114
115impl SamplingFrequency {
116 fn from(value: u8) -> SamplingFrequency {
117 match value {
118 0x0 => SamplingFrequency::Freq96000,
119 0x1 => SamplingFrequency::Freq88200,
120 0x2 => SamplingFrequency::Freq64000,
121 0x3 => SamplingFrequency::Freq48000,
122 0x4 => SamplingFrequency::Freq44100,
123 0x5 => SamplingFrequency::Freq32000,
124 0x6 => SamplingFrequency::Freq24000,
125 0x7 => SamplingFrequency::Freq22050,
126 0x8 => SamplingFrequency::Freq16000,
127 0x9 => SamplingFrequency::Freq12000,
128 0xa => SamplingFrequency::Freq11025,
129 0xb => SamplingFrequency::Freq8000,
130 0xc => SamplingFrequency::FreqReserved0xc,
131 0xd => SamplingFrequency::FreqReserved0xd,
132 0xe => SamplingFrequency::FreqReserved0xe,
133 0xf => SamplingFrequency::FreqReserved0xf,
134 _ => panic!("invalud value {:x}", value),
135 }
136 }
137
138 pub fn freq(&self) -> Option<u32> {
139 match self {
140 &SamplingFrequency::Freq96000 => Some(96000),
141 &SamplingFrequency::Freq88200 => Some(88200),
142 &SamplingFrequency::Freq64000 => Some(64000),
143 &SamplingFrequency::Freq48000 => Some(48000),
144 &SamplingFrequency::Freq44100 => Some(44100),
145 &SamplingFrequency::Freq32000 => Some(32000),
146 &SamplingFrequency::Freq24000 => Some(24000),
147 &SamplingFrequency::Freq22050 => Some(22050),
148 &SamplingFrequency::Freq16000 => Some(16000),
149 &SamplingFrequency::Freq12000 => Some(12000),
150 &SamplingFrequency::Freq11025 => Some(11025),
151 &SamplingFrequency::Freq8000 => Some(8000),
152 &SamplingFrequency::FreqReserved0xc => None,
153 &SamplingFrequency::FreqReserved0xd => None,
154 &SamplingFrequency::FreqReserved0xe => None,
155 &SamplingFrequency::FreqReserved0xf => None,
156 }
157 }
158}
159
160#[derive(Debug, PartialEq, Clone, Copy)]
161pub enum ChannelConfiguration {
162 ObjectTypeSpecificConfig = 0x0,
163 Mono = 0x1,
164 Stereo = 0x2,
165 Three = 0x3,
166 Four = 0x4,
167 Five = 0x5,
168 FiveOne = 0x6,
169 SevenOne = 0x7,
170}
171impl ChannelConfiguration {
172 fn from(value: u8) -> ChannelConfiguration {
173 match value {
174 0x0 => ChannelConfiguration::ObjectTypeSpecificConfig,
175 0x1 => ChannelConfiguration::Mono,
176 0x2 => ChannelConfiguration::Stereo,
177 0x3 => ChannelConfiguration::Three,
178 0x4 => ChannelConfiguration::Four,
179 0x5 => ChannelConfiguration::Five,
180 0x6 => ChannelConfiguration::FiveOne,
181 0x7 => ChannelConfiguration::SevenOne,
182 _ => panic!("invalid value {}", value),
183 }
184 }
185}
186
187#[derive(Debug, PartialEq)]
188pub enum Originality {
189 Original,
190 Copy,
191}
192
193#[derive(Debug, PartialEq)]
194pub enum CopyrightIdentificationStart {
195 Start,
196 Other,
197}
198
199pub struct AdtsHeader<'buf> {
201 buf: &'buf [u8],
202}
203impl<'buf> AdtsHeader<'buf> {
204 pub fn from_bytes(buf: &'buf [u8]) -> Result<AdtsHeader<'_>, AdtsHeaderError> {
214 assert!(!buf.is_empty());
215 let header_len = 7;
216 Self::check_len(header_len, buf.len())?;
217 let header = AdtsHeader { buf };
218 if header.sync_word() != 0xfff {
219 return Err(AdtsHeaderError::BadSyncWord(header.sync_word()));
220 }
221 let crc_len = 2;
222 if header.protection() == ProtectionIndicator::CrcPresent {
223 Self::check_len(header_len + crc_len, buf.len())?;
224 }
225 if header.frame_length() < header.header_length() {
226 return Err(AdtsHeaderError::BadFrameLength {
227 actual: header.frame_length() as usize,
228 minimum: header.header_length() as usize,
229 });
230 }
231 Ok(header)
232 }
233
234 fn check_len(expected: usize, actual: usize) -> Result<(), AdtsHeaderError> {
235 if actual < expected {
236 Err(AdtsHeaderError::NotEnoughData { expected, actual })
237 } else {
238 Ok(())
239 }
240 }
241
242 fn header_length(&self) -> u16 {
243 let fixed_len = 7;
244 if self.protection() == ProtectionIndicator::CrcPresent {
245 fixed_len + 2
246 } else {
247 fixed_len
248 }
249 }
250
251 fn sync_word(&self) -> u16 {
252 u16::from(self.buf[0]) << 4 | u16::from(self.buf[1] >> 4)
253 }
254
255 pub fn mpeg_version(&self) -> MpegVersion {
256 if self.buf[1] & 0b0000_1000 != 0 {
257 MpegVersion::Mpeg2
258 } else {
259 MpegVersion::Mpeg4
260 }
261 }
262
263 pub fn protection(&self) -> ProtectionIndicator {
264 if self.buf[1] & 0b0000_0001 != 0 {
265 ProtectionIndicator::CrcAbsent
266 } else {
267 ProtectionIndicator::CrcPresent
268 }
269 }
270
271 pub fn audio_object_type(&self) -> AudioObjectType {
273 match self.buf[2] & 0b1100_0000 {
274 0b0000_0000 => AudioObjectType::AacMain,
275 0b0100_0000 => AudioObjectType::AacLC,
276 0b1000_0000 => AudioObjectType::AacSSR,
277 0b1100_0000 => AudioObjectType::AacLTP,
278 v => panic!("impossible value {:#b}", v),
279 }
280 }
281
282 pub fn sampling_frequency(&self) -> SamplingFrequency {
283 SamplingFrequency::from(self.buf[2] >> 2 & 0b1111)
284 }
285
286 pub fn private_bit(&self) -> u8 {
288 self.buf[2] & 1
289 }
290
291 pub fn channel_configuration(&self) -> ChannelConfiguration {
292 ChannelConfiguration::from(self.buf[2] << 2 & 0b0100 | self.buf[3] >> 6)
293 }
294
295 pub fn originality(&self) -> Originality {
296 if self.buf[3] & 0b0010_0000 != 0 {
297 Originality::Copy
298 } else {
299 Originality::Original
300 }
301 }
302
303 pub fn home(&self) -> u8 {
305 self.buf[3] >> 4 & 1
306 }
307
308 pub fn copyright_identification_bit(&self) -> u8 {
310 self.buf[3] >> 3 & 1
311 }
312
313 pub fn copyright_identification_start(&self) -> CopyrightIdentificationStart {
314 if self.buf[3] & 0b0000_0100 != 0 {
315 CopyrightIdentificationStart::Start
316 } else {
317 CopyrightIdentificationStart::Other
318 }
319 }
320
321 pub fn frame_length(&self) -> u16 {
323 u16::from(self.buf[3] & 0b11) << 11
324 | u16::from(self.buf[4]) << 3
325 | u16::from(self.buf[5]) >> 5
326 }
327
328 pub fn payload_length(&self) -> Option<u16> {
332 let diff = self.frame_length() as i16 - self.header_length() as i16;
333 if diff >= 0 {
334 Some(diff as u16)
335 } else {
336 None
337 }
338 }
339
340 pub fn adts_buffer_fullness(&self) -> u16 {
341 u16::from(self.buf[5] & 0b00000011) << 6 | u16::from(self.buf[6]) >> 2
342 }
343
344 pub fn crc(&self) -> Option<u16> {
349 match self.protection() {
350 ProtectionIndicator::CrcAbsent => None,
351 ProtectionIndicator::CrcPresent => {
352 Some(u16::from(self.buf[7]) << 8 | u16::from(self.buf[8]))
353 }
354 }
355 }
356
357 pub fn number_of_raw_data_blocks_in_frame(&self) -> u8 {
364 (self.buf[6] & 0b11) + 1
365 }
366
367 pub fn payload(&self) -> Result<&'buf [u8], PayloadError> {
369 let len = self.frame_length() as usize;
370 if self.buf.len() < len {
371 Err(PayloadError {
372 expected: len,
373 actual: self.buf.len(),
374 })
375 } else {
376 Ok(&self.buf[self.header_length() as usize..len])
377 }
378 }
379}
380impl<'buf> fmt::Debug for AdtsHeader<'buf> {
381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
382 f.debug_struct("AdtsHeader")
383 .field("mpeg_version", &self.mpeg_version())
384 .field("protection", &self.protection())
385 .field("audio_object_type", &self.audio_object_type())
386 .field("sampling_frequency", &self.sampling_frequency())
387 .field("private_bit", &self.private_bit())
388 .field("channel_configuration", &self.channel_configuration())
389 .field("originality", &self.originality())
390 .field("home", &self.home())
391 .field(
392 "copyright_identification_bit",
393 &self.copyright_identification_bit(),
394 )
395 .field(
396 "copyright_identification_start",
397 &self.copyright_identification_start(),
398 )
399 .field("frame_length", &self.frame_length())
400 .field("adts_buffer_fullness", &self.adts_buffer_fullness())
401 .field("crc", &self.crc())
402 .field(
403 "number_of_raw_data_blocks_in_frame",
404 &self.number_of_raw_data_blocks_in_frame(),
405 )
406 .finish()
407 }
408}
409
410#[derive(Debug, PartialEq)]
411pub enum CopyrightIdErr {
412 TooFewBits,
413 TooManyBits,
414}
415
416#[derive(Debug, PartialEq)]
417pub struct CopyrightIdentification {
418 pub copyright_identifier: u8,
419 pub copyright_number: u64,
420}
421
422#[derive(PartialEq)]
423enum AdtsState {
424 Start,
425 Incomplete,
426 Error,
427}
428
429#[derive(Debug, PartialEq)]
430pub enum AdtsParseError {
431 BadSyncWord,
432 BadFrameLength,
433}
434
435pub trait AdtsConsumer {
459 fn new_config(
467 &mut self,
468 mpeg_version: MpegVersion,
469 protection: ProtectionIndicator,
470 aot: AudioObjectType,
471 freq: SamplingFrequency,
472 private_bit: u8,
473 channels: ChannelConfiguration,
474 originality: Originality,
475 home: u8,
476 );
477
478 fn payload(&mut self, buffer_fullness: u16, number_of_blocks: u8, buf: &[u8]);
480
481 fn error(&mut self, err: AdtsParseError);
483}
484
485pub struct AdtsParser<C>
492where
493 C: AdtsConsumer,
494{
495 pub consumer: C,
496 current_config: [u8; 3],
497 state: AdtsState,
498 incomplete_frame: Vec<u8>,
499 desired_data_len: Option<usize>,
500}
501impl<C> AdtsParser<C>
502where
503 C: AdtsConsumer,
504{
505 pub fn new(consumer: C) -> AdtsParser<C> {
506 AdtsParser {
507 consumer,
508 current_config: [0; 3],
509 state: AdtsState::Start,
510 incomplete_frame: vec![],
511 desired_data_len: None,
512 }
513 }
514
515 fn is_new_config(&self, header_data: &[u8]) -> bool {
516 self.current_config != header_data[0..3]
517 }
518
519 fn remember(&mut self, remaining_data: &[u8], desired_data_len: usize) {
520 self.state = AdtsState::Incomplete;
521 self.incomplete_frame.clear();
522 self.incomplete_frame.extend_from_slice(remaining_data);
523 self.desired_data_len = Some(desired_data_len);
524 }
525
526 pub fn start(&mut self) {
530 if self.state == AdtsState::Incomplete {
531 self.incomplete_frame.clear();
532 self.desired_data_len = None;
533 eprintln!("ADTS: incomplete data buffer dropped by call to start()");
534 }
535 self.state = AdtsState::Start;
536 }
537
538 pub fn push(&mut self, adts_buf: &[u8]) {
545 let mut buf = adts_buf;
546 match self.state {
547 AdtsState::Error => return, AdtsState::Incomplete => {
549 loop {
554 let bytes_needed_to_complete_frame = self.desired_data_len.unwrap() - self.incomplete_frame.len();
555 if buf.len() < bytes_needed_to_complete_frame {
556 self.incomplete_frame.extend_from_slice(buf);
557 return;
558 }
559 self.incomplete_frame
560 .extend_from_slice(&buf[..bytes_needed_to_complete_frame]);
561 buf = &buf[bytes_needed_to_complete_frame..];
562 let mut still_more = false; match AdtsHeader::from_bytes(&self.incomplete_frame[..]) {
564 Ok(header) => {
565 if (header.frame_length() as usize) > self.incomplete_frame.len() {
566 self.desired_data_len = Some(header.frame_length() as usize);
567 still_more = true;
568 } else {
569 if self.is_new_config(&self.incomplete_frame[..]) {
570 Self::push_config(
571 &mut self.current_config,
572 &mut self.consumer,
573 &header,
574 &self.incomplete_frame[..],
575 );
576 }
577 Self::push_payload(&mut self.consumer, header);
578 self.state = AdtsState::Start;
579 }
580 }
581 Err(e) => {
582 self.state = AdtsState::Error;
583 match e {
584 AdtsHeaderError::BadSyncWord { .. } => {
585 self.consumer.error(AdtsParseError::BadSyncWord);
586 return;
587 }
588 AdtsHeaderError::BadFrameLength { .. } => {
589 self.consumer.error(AdtsParseError::BadFrameLength);
590 return;
591 }
592 AdtsHeaderError::NotEnoughData { expected, .. } => {
593 self.desired_data_len = Some(expected);
594 still_more = true;
595 }
596 }
597 }
598 }
599 if !still_more {
600 break;
601 }
602 }
603 }
604 AdtsState::Start => (),
605 };
606 let mut pos = 0;
607 while pos < buf.len() {
608 let remaining_data = &buf[pos..];
609 let h = match AdtsHeader::from_bytes(remaining_data) {
610 Ok(header) => header,
611 Err(e) => {
612 self.state = AdtsState::Error;
613 match e {
614 AdtsHeaderError::BadSyncWord { .. } => {
615 self.consumer.error(AdtsParseError::BadSyncWord)
616 }
617 AdtsHeaderError::BadFrameLength { .. } => {
618 self.consumer.error(AdtsParseError::BadFrameLength);
619 return;
620 }
621 AdtsHeaderError::NotEnoughData { expected, .. } => {
622 self.remember(remaining_data, expected);
623 return;
624 }
625 }
626 return;
627 }
628 };
629 let new_pos = pos + h.frame_length() as usize;
630 if new_pos > buf.len() {
631 self.remember(remaining_data, h.frame_length() as usize);
632 return;
633 }
634 if self.is_new_config(remaining_data) {
635 Self::push_config(
636 &mut self.current_config,
637 &mut self.consumer,
638 &h,
639 remaining_data,
640 );
641 }
642 Self::push_payload(&mut self.consumer, h);
643 self.state = AdtsState::Start;
644 pos = new_pos;
645 }
646 }
647
648 fn push_config(
649 current_config: &mut [u8; 3],
650 consumer: &mut C,
651 h: &AdtsHeader<'_>,
652 frame_buffer: &[u8],
653 ) {
654 current_config.copy_from_slice(&frame_buffer[0..3]);
655 consumer.new_config(
656 h.mpeg_version(),
657 h.protection(),
658 h.audio_object_type(),
659 h.sampling_frequency(),
660 h.private_bit(),
661 h.channel_configuration(),
662 h.originality(),
663 h.home(),
664 );
665 }
666
667 fn push_payload(consumer: &mut C, h: AdtsHeader<'_>) {
668 match h.payload() {
669 Ok(payload) => {
670 consumer.payload(
671 h.adts_buffer_fullness(),
672 h.number_of_raw_data_blocks_in_frame(),
673 payload,
674 );
675 }
676 Err(PayloadError { expected, actual }) => {
677 panic!(
680 "Unexpected payload size mismatch: expected {}, actual size {}",
681 expected, actual
682 );
683 }
684 }
685 }
686}
687
688#[cfg(test)]
689mod tests {
690 use bitstream_io::{BitWriter, BE};
691 use std::io;
692 use super::*;
693
694 fn make_test_data<F>(builder: F) -> Vec<u8>
695 where
696 F: Fn(BitWriter<'_, BE>) -> Result<(), io::Error>,
697 {
698 let mut data: Vec<u8> = Vec::new();
699 builder(BitWriter::<BE>::new(&mut data)).unwrap();
700 data
701 }
702
703 fn write_frame(w: &mut BitWriter<'_, BE>) -> Result<(), io::Error> {
704 w.write(12, 0xfff)?; w.write(1, 0)?; w.write(2, 0)?; w.write(1, 1)?; w.write(2, 0)?; w.write(4, 0b0011)?; w.write(1, 1)?; w.write(3, 2)?; w.write(1, 1)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 1)?; w.write(13, 8)?; w.write(11, 123)?; w.write(2, 0)?; w.write(8, 0b10000001) }
721
722 #[test]
723 fn no_crc() {
724 let header_data = make_test_data(|mut w| write_frame(&mut w));
725 let header = AdtsHeader::from_bytes(&header_data[..]).unwrap();
726 assert_eq!(header.mpeg_version(), MpegVersion::Mpeg4);
727 assert_eq!(header.protection(), ProtectionIndicator::CrcAbsent);
728 assert_eq!(header.audio_object_type(), AudioObjectType::AacMain);
729 assert_eq!(header.sampling_frequency(), SamplingFrequency::Freq48000);
730 assert_eq!(header.sampling_frequency().freq(), Some(48000));
731 assert_eq!(header.channel_configuration(), ChannelConfiguration::Stereo);
732 assert_eq!(header.originality(), Originality::Copy);
733 assert_eq!(header.home(), 0);
734 assert_eq!(header.copyright_identification_bit(), 0);
735 assert_eq!(
736 header.copyright_identification_start(),
737 CopyrightIdentificationStart::Start
738 );
739 assert_eq!(header.frame_length(), 8);
740 assert_eq!(header.payload_length(), Some(8 - 7));
741 assert_eq!(header.adts_buffer_fullness(), 123);
742 assert_eq!(header.number_of_raw_data_blocks_in_frame(), 1);
743 assert_eq!(header.payload(), Ok(&[0b10000001][..]));
744 }
745
746 struct MockConsumer {
747 seq: usize,
748 payload_seq: usize,
749 payload_size: Option<usize>,
750 }
751 impl MockConsumer {
752 pub fn new() -> MockConsumer {
753 MockConsumer {
754 seq: 0,
755 payload_seq: 0,
756 payload_size: None
757 }
758 }
759 pub fn assert_seq(&mut self, expected: usize) {
760 assert_eq!(expected, self.seq);
761 self.seq += 1;
762 }
763 }
764 impl AdtsConsumer for MockConsumer {
765 fn new_config(
767 &mut self,
768 mpeg_version: MpegVersion,
769 _protection: ProtectionIndicator,
770 _aot: AudioObjectType,
771 _freq: SamplingFrequency,
772 _private_bit: u8,
773 _channels: ChannelConfiguration,
774 _originality: Originality,
775 _home: u8,
776 ) {
777 self.assert_seq(0);
778 assert_eq!(mpeg_version, MpegVersion::Mpeg4);
779 }
780 fn payload(&mut self, _buffer_fullness: u16, _number_of_blocks: u8, buf: &[u8]) {
781 self.payload_seq += 1;
782 let new_payload_seq = self.payload_seq;
783 self.assert_seq(new_payload_seq);
784 self.payload_size = Some(buf.len());
785 }
786 fn error(&mut self, err: AdtsParseError) {
787 panic!("no errors expected in bitstream: {:?}", err);
788 }
789 }
790
791 #[test]
792 fn parser() {
793 let header_data = make_test_data(|mut w| {
794 write_frame(&mut w)?;
795 write_frame(&mut w)
796 });
797 for split in 0..header_data.len() {
798 let mut parser = AdtsParser::new(MockConsumer::new());
799 let (head, tail) = header_data.split_at(split);
800 parser.push(head);
801 parser.push(tail);
802 assert_eq!(2, parser.consumer.payload_seq);
803 assert_eq!(Some(1), parser.consumer.payload_size);
804 }
805 }
806
807 #[test]
808 fn too_short() {
809 let header_data = make_test_data(|mut w| write_frame(&mut w));
810 let mut parser = AdtsParser::new(MockConsumer::new());
811 parser.push(&header_data[..5]);
812 parser.push(&header_data[5..7]);
813 }
814}