1#![forbid(unsafe_code)]
27#![deny(rust_2018_idioms, future_incompatible)]
28
29pub use mpeg4_audio_const::{
33 AudioObjectType, ChannelConfiguration, SamplingFrequencyIndex, SamplingFrequencyIndexError,
34};
35use std::fmt;
36
37#[derive(Debug)]
38pub enum AdtsHeaderError {
39 BadSyncWord(u16),
42 NotEnoughData {
43 expected: usize,
44 actual: usize,
45 },
46 BadFrameLength {
49 minimum: usize,
50 actual: usize,
51 },
52 BadSamplingFrequency(SamplingFrequencyIndexError),
54}
55
56#[derive(Debug, PartialEq)]
59pub struct PayloadError {
60 pub expected: usize,
61 pub actual: usize,
62}
63
64#[derive(Debug, PartialEq)]
65pub enum MpegVersion {
66 Mpeg2,
67 Mpeg4,
68}
69
70#[derive(Debug, PartialEq)]
71pub enum ProtectionIndicator {
72 CrcPresent,
73 CrcAbsent,
74}
75
76#[derive(Debug, PartialEq)]
77pub enum Originality {
78 Original,
79 Copy,
80}
81
82#[derive(Debug, PartialEq, Clone, Copy)]
83pub enum BufferFullness {
84 Vbr,
86 Cbr(u16),
88}
89
90#[derive(Debug, PartialEq)]
91pub enum CopyrightIdentificationStart {
92 Start,
93 Other,
94}
95
96pub struct AdtsHeader<'buf> {
98 buf: &'buf [u8],
99}
100impl<'buf> AdtsHeader<'buf> {
101 pub fn from_bytes(buf: &'buf [u8]) -> Result<AdtsHeader<'buf>, AdtsHeaderError> {
111 assert!(!buf.is_empty());
112 let header_len = 7;
113 Self::check_len(header_len, buf.len())?;
114 let header = AdtsHeader { buf };
115 if header.sync_word() != 0xfff {
116 return Err(AdtsHeaderError::BadSyncWord(header.sync_word()));
117 }
118 let crc_len = 2;
119 if header.protection() == ProtectionIndicator::CrcPresent {
120 Self::check_len(header_len + crc_len, buf.len())?;
121 }
122 SamplingFrequencyIndex::try_from(header.buf[2] >> 2 & 0b1111)
123 .map_err(AdtsHeaderError::BadSamplingFrequency)?;
124 if header.frame_length() < header.header_length() {
125 return Err(AdtsHeaderError::BadFrameLength {
126 actual: header.frame_length() as usize,
127 minimum: header.header_length() as usize,
128 });
129 }
130 Ok(header)
131 }
132
133 fn check_len(expected: usize, actual: usize) -> Result<(), AdtsHeaderError> {
134 if actual < expected {
135 Err(AdtsHeaderError::NotEnoughData { expected, actual })
136 } else {
137 Ok(())
138 }
139 }
140
141 fn header_length(&self) -> u16 {
142 let fixed_len = 7;
143 if self.protection() == ProtectionIndicator::CrcPresent {
144 fixed_len + 2
145 } else {
146 fixed_len
147 }
148 }
149
150 fn sync_word(&self) -> u16 {
151 u16::from(self.buf[0]) << 4 | u16::from(self.buf[1] >> 4)
152 }
153
154 pub fn mpeg_version(&self) -> MpegVersion {
155 if self.buf[1] & 0b0000_1000 != 0 {
156 MpegVersion::Mpeg2
157 } else {
158 MpegVersion::Mpeg4
159 }
160 }
161
162 pub fn protection(&self) -> ProtectionIndicator {
163 if self.buf[1] & 0b0000_0001 != 0 {
164 ProtectionIndicator::CrcAbsent
165 } else {
166 ProtectionIndicator::CrcPresent
167 }
168 }
169
170 pub fn audio_object_type(&self) -> AudioObjectType {
172 match self.buf[2] & 0b1100_0000 {
173 0b0000_0000 => AudioObjectType::AAC_MAIN,
174 0b0100_0000 => AudioObjectType::AAC_LC,
175 0b1000_0000 => AudioObjectType::AAC_SSR,
176 0b1100_0000 => AudioObjectType::AAC_LTP,
177 v => panic!("impossible value {:#b}", v),
178 }
179 }
180
181 pub fn sampling_frequency(&self) -> SamplingFrequencyIndex {
182 SamplingFrequencyIndex::new(self.buf[2] >> 2 & 0b1111)
183 }
184
185 pub fn private_bit(&self) -> u8 {
187 (self.buf[2] >> 1) & 1
188 }
189
190 pub fn channel_configuration(&self) -> ChannelConfiguration {
191 ChannelConfiguration::new(self.buf[2] << 2 & 0b0100 | self.buf[3] >> 6)
192 }
193
194 pub fn originality(&self) -> Originality {
195 if self.buf[3] & 0b0010_0000 != 0 {
196 Originality::Original
197 } else {
198 Originality::Copy
199 }
200 }
201
202 pub fn home(&self) -> u8 {
204 self.buf[3] >> 4 & 1
205 }
206
207 pub fn copyright_identification_bit(&self) -> u8 {
209 self.buf[3] >> 3 & 1
210 }
211
212 pub fn copyright_identification_start(&self) -> CopyrightIdentificationStart {
213 if self.buf[3] & 0b0000_0100 != 0 {
214 CopyrightIdentificationStart::Start
215 } else {
216 CopyrightIdentificationStart::Other
217 }
218 }
219
220 pub fn frame_length(&self) -> u16 {
222 u16::from(self.buf[3] & 0b11) << 11
223 | u16::from(self.buf[4]) << 3
224 | u16::from(self.buf[5]) >> 5
225 }
226
227 pub fn payload_length(&self) -> Option<u16> {
231 let diff = self.frame_length() as i16 - self.header_length() as i16;
232 if diff >= 0 {
233 Some(diff as u16)
234 } else {
235 None
236 }
237 }
238
239 pub fn adts_buffer_fullness(&self) -> BufferFullness {
240 let raw = u16::from(self.buf[5] & 0b00011111) << 6 | u16::from(self.buf[6]) >> 2;
241 if raw == 0x7FF {
242 BufferFullness::Vbr
243 } else {
244 BufferFullness::Cbr(raw)
245 }
246 }
247
248 pub fn crc(&self) -> Option<u16> {
253 match self.protection() {
254 ProtectionIndicator::CrcAbsent => None,
255 ProtectionIndicator::CrcPresent => {
256 Some(u16::from(self.buf[7]) << 8 | u16::from(self.buf[8]))
257 }
258 }
259 }
260
261 pub fn number_of_raw_data_blocks_in_frame(&self) -> u8 {
268 (self.buf[6] & 0b11) + 1
269 }
270
271 pub fn payload(&self) -> Result<&'buf [u8], PayloadError> {
273 let len = self.frame_length() as usize;
274 if self.buf.len() < len {
275 Err(PayloadError {
276 expected: len,
277 actual: self.buf.len(),
278 })
279 } else {
280 Ok(&self.buf[self.header_length() as usize..len])
281 }
282 }
283}
284impl<'buf> fmt::Debug for AdtsHeader<'buf> {
285 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
286 f.debug_struct("AdtsHeader")
287 .field("mpeg_version", &self.mpeg_version())
288 .field("protection", &self.protection())
289 .field("audio_object_type", &self.audio_object_type())
290 .field("sampling_frequency", &self.sampling_frequency())
291 .field("private_bit", &self.private_bit())
292 .field("channel_configuration", &self.channel_configuration())
293 .field("originality", &self.originality())
294 .field("home", &self.home())
295 .field(
296 "copyright_identification_bit",
297 &self.copyright_identification_bit(),
298 )
299 .field(
300 "copyright_identification_start",
301 &self.copyright_identification_start(),
302 )
303 .field("frame_length", &self.frame_length())
304 .field("adts_buffer_fullness", &self.adts_buffer_fullness())
305 .field("crc", &self.crc())
306 .field(
307 "number_of_raw_data_blocks_in_frame",
308 &self.number_of_raw_data_blocks_in_frame(),
309 )
310 .finish()
311 }
312}
313
314#[derive(Debug, PartialEq)]
315pub enum CopyrightIdErr {
316 TooFewBits,
317 TooManyBits,
318}
319
320#[derive(Debug, PartialEq)]
321pub struct CopyrightIdentification {
322 pub copyright_identifier: u8,
323 pub copyright_number: u64,
324}
325
326#[derive(PartialEq)]
327enum AdtsState {
328 Start,
329 Incomplete,
330 Error,
331}
332
333#[derive(Debug, PartialEq)]
334pub enum AdtsParseError {
335 BadSyncWord,
336 BadFrameLength,
337 BadSamplingFrequency,
338}
339
340pub trait AdtsConsumer {
364 fn new_config(
372 &mut self,
373 mpeg_version: MpegVersion,
374 protection: ProtectionIndicator,
375 aot: AudioObjectType,
376 freq: SamplingFrequencyIndex,
377 private_bit: u8,
378 channels: ChannelConfiguration,
379 originality: Originality,
380 home: u8,
381 );
382
383 fn payload(&mut self, buffer_fullness: BufferFullness, number_of_blocks: u8, buf: &[u8]);
385
386 fn error(&mut self, err: AdtsParseError);
388}
389
390pub struct AdtsParser<C>
397where
398 C: AdtsConsumer,
399{
400 pub consumer: C,
401 current_config: [u8; 4],
402 state: AdtsState,
403 incomplete_frame: Vec<u8>,
404 desired_data_len: Option<usize>,
405}
406impl<C> AdtsParser<C>
407where
408 C: AdtsConsumer,
409{
410 pub fn new(consumer: C) -> AdtsParser<C> {
411 AdtsParser {
412 consumer,
413 current_config: [0; 4],
414 state: AdtsState::Start,
415 incomplete_frame: vec![],
416 desired_data_len: None,
417 }
418 }
419
420 fn is_new_config(&self, header_data: &[u8]) -> bool {
421 self.current_config[0..3] != header_data[0..3]
422 || self.current_config[3] != header_data[3] & 0b1111_0000
423 }
424
425 fn remember(&mut self, remaining_data: &[u8], desired_data_len: usize) {
426 self.state = AdtsState::Incomplete;
427 self.incomplete_frame.clear();
428 self.incomplete_frame.extend_from_slice(remaining_data);
429 self.desired_data_len = Some(desired_data_len);
430 }
431
432 pub fn start(&mut self) {
436 if self.state == AdtsState::Incomplete {
437 self.incomplete_frame.clear();
438 self.desired_data_len = None;
439 eprintln!("ADTS: incomplete data buffer dropped by call to start()");
440 }
441 self.state = AdtsState::Start;
442 }
443
444 pub fn push(&mut self, adts_buf: &[u8]) {
451 let mut buf = adts_buf;
452 match self.state {
453 AdtsState::Error => return, AdtsState::Incomplete => {
455 loop {
460 let bytes_needed_to_complete_frame =
461 self.desired_data_len.unwrap() - self.incomplete_frame.len();
462 if buf.len() < bytes_needed_to_complete_frame {
463 self.incomplete_frame.extend_from_slice(buf);
464 return;
465 }
466 self.incomplete_frame
467 .extend_from_slice(&buf[..bytes_needed_to_complete_frame]);
468 buf = &buf[bytes_needed_to_complete_frame..];
469 let mut still_more = false; match AdtsHeader::from_bytes(&self.incomplete_frame[..]) {
471 Ok(header) => {
472 if (header.frame_length() as usize) > self.incomplete_frame.len() {
473 self.desired_data_len = Some(header.frame_length() as usize);
474 still_more = true;
475 } else {
476 if self.is_new_config(&self.incomplete_frame[..]) {
477 Self::push_config(
478 &mut self.current_config,
479 &mut self.consumer,
480 &header,
481 &self.incomplete_frame[..],
482 );
483 }
484 Self::push_payload(&mut self.consumer, header);
485 self.state = AdtsState::Start;
486 }
487 }
488 Err(e) => match e {
489 AdtsHeaderError::BadSyncWord { .. } => {
490 self.state = AdtsState::Error;
491 self.consumer.error(AdtsParseError::BadSyncWord);
492 return;
493 }
494 AdtsHeaderError::BadFrameLength { .. } => {
495 self.state = AdtsState::Error;
496 self.consumer.error(AdtsParseError::BadFrameLength);
497 return;
498 }
499 AdtsHeaderError::BadSamplingFrequency(_) => {
500 self.state = AdtsState::Error;
501 self.consumer.error(AdtsParseError::BadSamplingFrequency);
502 return;
503 }
504 AdtsHeaderError::NotEnoughData { expected, .. } => {
505 self.desired_data_len = Some(expected);
506 still_more = true;
507 }
508 },
509 }
510 if !still_more {
511 break;
512 }
513 }
514 }
515 AdtsState::Start => (),
516 };
517 let mut pos = 0;
518 while pos < buf.len() {
519 let remaining_data = &buf[pos..];
520 let h = match AdtsHeader::from_bytes(remaining_data) {
521 Ok(header) => header,
522 Err(e) => {
523 self.state = AdtsState::Error;
524 match e {
525 AdtsHeaderError::BadSyncWord { .. } => {
526 self.consumer.error(AdtsParseError::BadSyncWord)
527 }
528 AdtsHeaderError::BadFrameLength { .. } => {
529 self.consumer.error(AdtsParseError::BadFrameLength);
530 return;
531 }
532 AdtsHeaderError::NotEnoughData { expected, .. } => {
533 self.remember(remaining_data, expected);
534 return;
535 }
536 AdtsHeaderError::BadSamplingFrequency(_) => {
537 self.consumer.error(AdtsParseError::BadSamplingFrequency);
538 }
539 }
540 return;
541 }
542 };
543 let new_pos = pos + h.frame_length() as usize;
544 if new_pos > buf.len() {
545 self.remember(remaining_data, h.frame_length() as usize);
546 return;
547 }
548 if self.is_new_config(remaining_data) {
549 Self::push_config(
550 &mut self.current_config,
551 &mut self.consumer,
552 &h,
553 remaining_data,
554 );
555 }
556 Self::push_payload(&mut self.consumer, h);
557 self.state = AdtsState::Start;
558 pos = new_pos;
559 }
560 }
561
562 fn push_config(
563 current_config: &mut [u8; 4],
564 consumer: &mut C,
565 h: &AdtsHeader<'_>,
566 frame_buffer: &[u8],
567 ) {
568 current_config[0..3].copy_from_slice(&frame_buffer[0..3]);
569 current_config[3] = frame_buffer[3] & 0b1111_0000;
570 consumer.new_config(
571 h.mpeg_version(),
572 h.protection(),
573 h.audio_object_type(),
574 h.sampling_frequency(),
575 h.private_bit(),
576 h.channel_configuration(),
577 h.originality(),
578 h.home(),
579 );
580 }
581
582 fn push_payload(consumer: &mut C, h: AdtsHeader<'_>) {
583 match h.payload() {
584 Ok(payload) => {
585 consumer.payload(
586 h.adts_buffer_fullness(),
587 h.number_of_raw_data_blocks_in_frame(),
588 payload,
589 );
590 }
591 Err(PayloadError { expected, actual }) => {
592 panic!(
595 "Unexpected payload size mismatch: expected {}, actual size {}",
596 expected, actual
597 );
598 }
599 }
600 }
601}
602
603#[cfg(test)]
604mod tests {
605 use super::*;
606 use bitstream_io::{BigEndian, BitWrite, BitWriter, BE};
607 use std::io;
608
609 fn make_test_data<F>(builder: F) -> Vec<u8>
610 where
611 F: Fn(BitWriter<&mut Vec<u8>, BE>) -> Result<(), io::Error>,
612 {
613 let mut data: Vec<u8> = Vec::new();
614 builder(BitWriter::endian(&mut data, BigEndian)).unwrap();
615 data
616 }
617
618 fn write_frame(w: &mut BitWriter<&mut Vec<u8>, BE>) -> Result<(), io::Error> {
619 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) }
636
637 #[test]
638 fn no_crc() {
639 let header_data = make_test_data(|mut w| write_frame(&mut w));
640 let header = AdtsHeader::from_bytes(&header_data[..]).unwrap();
641 assert_eq!(header.mpeg_version(), MpegVersion::Mpeg4);
642 assert_eq!(header.protection(), ProtectionIndicator::CrcAbsent);
643 assert_eq!(header.audio_object_type(), AudioObjectType::AAC_MAIN);
644 assert_eq!(
645 header.sampling_frequency(),
646 SamplingFrequencyIndex::FREQ_48000
647 );
648 assert_eq!(header.sampling_frequency().freq(), Some(48000));
649 assert_eq!(header.private_bit(), 1);
650 assert_eq!(header.channel_configuration(), ChannelConfiguration::STEREO);
651 assert_eq!(header.originality(), Originality::Original);
652 assert_eq!(header.home(), 0);
653 assert_eq!(header.copyright_identification_bit(), 0);
654 assert_eq!(
655 header.copyright_identification_start(),
656 CopyrightIdentificationStart::Start
657 );
658 assert_eq!(header.frame_length(), 8);
659 assert_eq!(header.payload_length(), Some(8 - 7));
660 assert_eq!(header.adts_buffer_fullness(), BufferFullness::Cbr(123));
661 assert_eq!(header.number_of_raw_data_blocks_in_frame(), 1);
662 assert_eq!(header.payload(), Ok(&[0b10000001][..]));
663 }
664
665 #[test]
666 fn large_buffer_fullness() {
667 let header_data = make_test_data(|mut w| {
668 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, 0)?; w.write(3, 1)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(13, 8)?; w.write(11, 0x7FF)?; w.write(2, 0)?; w.write(8, 0x00) });
685 let header = AdtsHeader::from_bytes(&header_data[..]).unwrap();
686 assert_eq!(header.adts_buffer_fullness(), BufferFullness::Vbr);
687 }
688
689 struct MockConsumer {
690 seq: usize,
691 payload_seq: usize,
692 payload_size: Option<usize>,
693 }
694 impl MockConsumer {
695 pub fn new() -> MockConsumer {
696 MockConsumer {
697 seq: 0,
698 payload_seq: 0,
699 payload_size: None,
700 }
701 }
702 pub fn assert_seq(&mut self, expected: usize) {
703 assert_eq!(expected, self.seq);
704 self.seq += 1;
705 }
706 }
707 impl AdtsConsumer for MockConsumer {
708 fn new_config(
710 &mut self,
711 mpeg_version: MpegVersion,
712 _protection: ProtectionIndicator,
713 _aot: AudioObjectType,
714 _freq: SamplingFrequencyIndex,
715 _private_bit: u8,
716 _channels: ChannelConfiguration,
717 _originality: Originality,
718 _home: u8,
719 ) {
720 self.assert_seq(0);
721 assert_eq!(mpeg_version, MpegVersion::Mpeg4);
722 }
723 fn payload(&mut self, _buffer_fullness: BufferFullness, _number_of_blocks: u8, buf: &[u8]) {
724 self.payload_seq += 1;
725 let new_payload_seq = self.payload_seq;
726 self.assert_seq(new_payload_seq);
727 self.payload_size = Some(buf.len());
728 }
729 fn error(&mut self, err: AdtsParseError) {
730 panic!("no errors expected in bitstream: {:?}", err);
731 }
732 }
733
734 #[test]
735 fn parser() {
736 let header_data = make_test_data(|mut w| {
737 write_frame(&mut w)?;
738 write_frame(&mut w)
739 });
740 for split in 0..header_data.len() {
741 let mut parser = AdtsParser::new(MockConsumer::new());
742 let (head, tail) = header_data.split_at(split);
743 parser.push(head);
744 parser.push(tail);
745 assert_eq!(2, parser.consumer.payload_seq);
746 assert_eq!(Some(1), parser.consumer.payload_size);
747 }
748 }
749
750 struct CountingConsumer {
751 payload_count: usize,
752 }
753 impl AdtsConsumer for CountingConsumer {
754 fn new_config(
755 &mut self,
756 _: MpegVersion,
757 _: ProtectionIndicator,
758 _: AudioObjectType,
759 _: SamplingFrequencyIndex,
760 _: u8,
761 _: ChannelConfiguration,
762 _: Originality,
763 _: u8,
764 ) {
765 }
766 fn payload(&mut self, _: BufferFullness, _: u8, _: &[u8]) {
767 self.payload_count += 1;
768 }
769 fn error(&mut self, err: AdtsParseError) {
770 panic!("no errors expected: {:?}", err);
771 }
772 }
773
774 #[test]
775 fn crc_frame_split_across_pushes() {
776 let frame_data = make_test_data(|mut w| {
782 w.write(12, 0xfff)?; w.write(1, 0)?; w.write(2, 0)?; w.write(1, 0)?; w.write(2, 0)?; w.write(4, 0b0011)?; w.write(1, 0)?; w.write(3, 2)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(13, 10)?; w.write(11, 100)?; w.write(2, 0)?; w.write(16, 0)?; w.write(8, 0xAB) });
800
801 let mut parser = AdtsParser::new(CountingConsumer { payload_count: 0 });
806 parser.push(&frame_data[..5]);
807 parser.push(&frame_data[5..7]);
808 assert_eq!(0, parser.consumer.payload_count, "no payload yet");
809 parser.push(&frame_data[7..]);
810 assert_eq!(
811 1, parser.consumer.payload_count,
812 "payload should have been delivered"
813 );
814 }
815
816 #[test]
817 fn too_short() {
818 let header_data = make_test_data(|mut w| write_frame(&mut w));
819 let mut parser = AdtsParser::new(MockConsumer::new());
820 parser.push(&header_data[..5]);
821 parser.push(&header_data[5..7]);
822 }
823
824 #[test]
825 fn bad_sampling_frequency() {
826 let header_data = make_test_data(|mut w| {
828 w.write(12, 0xfff)?; w.write(1, 0)?; w.write(2, 0)?; w.write(1, 1)?; w.write(2, 0)?; w.write(4, 0b1111)?; w.write(1, 0)?; w.write(3, 1)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(1, 0)?; w.write(13, 8)?; w.write(11, 0)?; w.write(2, 0)?; w.write(8, 0x00) });
845 assert!(matches!(
846 AdtsHeader::from_bytes(&header_data),
847 Err(AdtsHeaderError::BadSamplingFrequency(_))
848 ));
849 }
850}