@@ -507,14 +507,18 @@ impl Descriptor for DecoderSpecificDescriptor {
507
507
}
508
508
509
509
fn desc_size ( & self ) -> u32 {
510
- 2
510
+ if self . profile < 31 {
511
+ 2
512
+ } else {
513
+ 3
514
+ }
511
515
}
512
516
}
513
517
514
518
fn get_audio_object_type ( byte_a : u8 , byte_b : u8 ) -> u8 {
515
519
let mut profile = byte_a >> 3 ;
516
520
if profile == 31 {
517
- profile = 32 + ( ( byte_a & 7 ) | ( byte_b >> 5 ) ) ;
521
+ profile = 32 + ( ( byte_a & 7 ) << 3 | ( byte_b >> 5 ) ) ;
518
522
}
519
523
520
524
profile
@@ -533,7 +537,7 @@ fn get_chan_conf<R: Read + Seek>(
533
537
chan_conf = ( ( sample_rate >> 4 ) & 0x0F ) as u8 ;
534
538
} else if extended_profile {
535
539
let byte_c = reader. read_u8 ( ) ?;
536
- chan_conf = ( byte_b & 1 ) | ( byte_c & 0xE0 ) ;
540
+ chan_conf = ( byte_b & 1 ) << 3 | ( byte_c >> 5 ) ;
537
541
} else {
538
542
chan_conf = ( byte_b >> 3 ) & 0x0F ;
539
543
}
@@ -569,8 +573,15 @@ impl<W: Write> WriteDesc<&mut W> for DecoderSpecificDescriptor {
569
573
let size = self . desc_size ( ) ;
570
574
write_desc ( writer, Self :: desc_tag ( ) , size) ?;
571
575
572
- writer. write_u8 ( ( self . profile << 3 ) + ( self . freq_index >> 1 ) ) ?;
573
- writer. write_u8 ( ( self . freq_index << 7 ) + ( self . chan_conf << 3 ) ) ?;
576
+ if self . profile < 31 {
577
+ writer. write_u8 ( ( self . profile << 3 ) | ( self . freq_index >> 1 ) ) ?;
578
+ writer. write_u8 ( ( self . freq_index << 7 ) | ( self . chan_conf << 3 ) ) ?;
579
+ } else {
580
+ let profile_minus_32 = self . profile - 32 ;
581
+ writer. write_u8 ( 31u8 << 3 | profile_minus_32 >> 3 ) ?;
582
+ writer. write_u8 ( profile_minus_32 << 5 | self . freq_index << 1 | self . chan_conf >> 7 ) ?;
583
+ writer. write_u8 ( ( self . chan_conf & 7 ) << 5 ) ?;
584
+ }
574
585
575
586
Ok ( size)
576
587
}
@@ -682,4 +693,48 @@ mod tests {
682
693
let dst_box = Mp4aBox :: read_box ( & mut reader, header. size ) . unwrap ( ) ;
683
694
assert_eq ! ( src_box, dst_box) ;
684
695
}
696
+
697
+ #[ test]
698
+ fn test_decoder_specific_descriptor ( ) {
699
+ let test_dec_spec = |src_dec_spec : DecoderSpecificDescriptor | {
700
+ let mut buf = Vec :: new ( ) ;
701
+ let written = src_dec_spec. write_desc ( & mut buf) . unwrap ( ) ;
702
+ // expect two extra bytes for the tag and size fields
703
+ assert_eq ! ( buf. len( ) , written as usize + 2 ) ;
704
+
705
+ let mut reader = Cursor :: new ( & buf) ;
706
+ let ( tag, size) = read_desc ( & mut reader) . unwrap ( ) ;
707
+ assert_eq ! ( 5 , tag) ;
708
+ assert_eq ! ( size, written) ;
709
+
710
+ let dst_dec_spec = DecoderSpecificDescriptor :: read_desc ( & mut reader, written) . unwrap ( ) ;
711
+ assert_eq ! ( src_dec_spec, dst_dec_spec) ;
712
+ } ;
713
+
714
+ test_dec_spec ( DecoderSpecificDescriptor {
715
+ profile : 2 , // LC
716
+ freq_index : 4 , // 44100
717
+ chan_conf : 2 , // Stereo
718
+ } ) ;
719
+ test_dec_spec ( DecoderSpecificDescriptor {
720
+ profile : 5 , // SpectralBandReplication (HEv1)
721
+ freq_index : 3 , // 48000
722
+ chan_conf : 1 , // Mono
723
+ } ) ;
724
+ test_dec_spec ( DecoderSpecificDescriptor {
725
+ profile : 29 , // ParametricStereo (HEv2)
726
+ freq_index : 2 , // 64000
727
+ chan_conf : 7 , // SevenOne
728
+ } ) ;
729
+ test_dec_spec ( DecoderSpecificDescriptor {
730
+ profile : 34 , // MpegLayer3 (xHE)
731
+ freq_index : 4 , // 44100
732
+ chan_conf : 2 , // Stereo
733
+ } ) ;
734
+ test_dec_spec ( DecoderSpecificDescriptor {
735
+ profile : 42 , // UnifiedSpeechAudioCoding (xHE)
736
+ freq_index : 11 , // 8000
737
+ chan_conf : 6 , // FiveOne
738
+ } ) ;
739
+ }
685
740
}
0 commit comments