@@ -574,78 +574,79 @@ private void parseAdtsHeader() throws ParserException {
574574 }
575575
576576 @ RequiresNonNull ("currentOutput" )
577- void readAacProgramConfigElement () {
578- Format pendingOutputFormat = checkNotNull (this .pendingOutputFormat );
577+ private void readAacProgramConfigElement () throws ParserException {
579578 ParsableBitArray pceBuffer = checkNotNull (this .pceBuffer );
580579
581580 // See ISO 13818-7 Advanced Audio Coding (2006) Table 36 for PCE tag encoding.
582- if (pceBuffer .readBits (3 ) == 5 /* PCE tag */ ) {
583- // See ISO 13818-7 Advanced Audio Coding (2006) Table 25 for syntax of a PCE.
584- pceBuffer .skipBits (10 ); // element_instance_tag(4), profile(2), element_instance_tag(4)
585-
586- int channelBits = 0 ;
587- // num_front_channel_elements, front_element_is_cpe(1), front_element_tag_select(4)
588- channelBits += pceBuffer .readBits (4 ) * 5 ;
589- // num_side_channel_elements, side_element_is_cpe(1), side_element_tag_select(4)
590- channelBits += pceBuffer .readBits (4 ) * 5 ;
591- // num_back_channel_elements, back_element_is_cpe(1), back_element_tag_select(4)
592- channelBits += pceBuffer .readBits (4 ) * 5 ;
593- // num_lfe_channel_elements, lfe_element_tag_select(4)
594- channelBits += pceBuffer .readBits (2 ) * 4 ;
595- // num_assoc_data_elements, assoc_data_element_tag_select(4)
596- channelBits += pceBuffer .readBits (3 ) * 4 ;
597- // num_valid_cc_elements, cc_element_is_ind_sw(1), valid_cc_element_tag_select(4)
598- channelBits += pceBuffer .readBits (4 ) * 5 ;
599-
600- if (pceBuffer .readBit ()) { // mono_mixdown_present
601- pceBuffer .skipBits (4 ); // mono_mixdown_element_number
602- }
581+ if (pceBuffer .readBits (3 ) != 5 /* PCE tag */ ) {
582+ throw ParserException .createForMalformedContainer (/* message= */ null , /* cause= */ null );
583+ }
603584
604- if (pceBuffer .readBit ()) { // stereo_mixdown_present
605- pceBuffer .skipBits (4 ); // stereo_mixdown_element_number
606- }
585+ // See ISO 13818-7 Advanced Audio Coding (2006) Table 25 for syntax of a PCE.
586+ pceBuffer .skipBits (10 ); // element_instance_tag(4), profile(2), element_instance_tag(4)
587+
588+ int channelBits = 0 ;
589+ // num_front_channel_elements, front_element_is_cpe(1), front_element_tag_select(4)
590+ channelBits += pceBuffer .readBits (4 ) * 5 ;
591+ // num_side_channel_elements, side_element_is_cpe(1), side_element_tag_select(4)
592+ channelBits += pceBuffer .readBits (4 ) * 5 ;
593+ // num_back_channel_elements, back_element_is_cpe(1), back_element_tag_select(4)
594+ channelBits += pceBuffer .readBits (4 ) * 5 ;
595+ // num_lfe_channel_elements, lfe_element_tag_select(4)
596+ channelBits += pceBuffer .readBits (2 ) * 4 ;
597+ // num_assoc_data_elements, assoc_data_element_tag_select(4)
598+ channelBits += pceBuffer .readBits (3 ) * 4 ;
599+ // num_valid_cc_elements, cc_element_is_ind_sw(1), valid_cc_element_tag_select(4)
600+ channelBits += pceBuffer .readBits (4 ) * 5 ;
601+
602+ if (pceBuffer .readBit ()) { // mono_mixdown_present
603+ pceBuffer .skipBits (4 ); // mono_mixdown_element_number
604+ }
607605
608- if (pceBuffer .readBit ()) { // matrix_mixdown_idx_present
609- pceBuffer .skipBits (3 ); // matrix_mixdown_idx(2), matrix_mixdown_idx(1)
610- }
606+ if (pceBuffer .readBit ()) { // stereo_mixdown_present
607+ pceBuffer .skipBits (4 ); // stereo_mixdown_element_number
608+ }
611609
612- int numAlignmentBits =
613- 8 - ( pceBuffer .getPosition () + channelBits + 7 ) % 8 - 1 ; // byte_alignment
614- int commentSizeBits = 8 ; // comment_field_bytes
610+ if ( pceBuffer . readBit ()) { // matrix_mixdown_idx_present
611+ pceBuffer .skipBits ( 3 ) ; // matrix_mixdown_idx(2), matrix_mixdown_idx(1)
612+ }
615613
616- // Beyond this point, pceBuffer may be empty, so check before consuming.
617- if (pceBuffer .bitsLeft () >= channelBits + numAlignmentBits + commentSizeBits ) {
618- pceBuffer . skipBits ( channelBits );
614+ int numAlignmentBits =
615+ 8 - (pceBuffer .getPosition () + channelBits + 7 ) % 8 - 1 ; // byte_alignment
616+ int commentSizeBits = 8 ; // comment_field_bytes
619617
620- // Store PCE size excluding initial PCE tag, alignment bits and comment for later.
621- int numPceBits = pceBuffer .getPosition () - 3 /* PCE tag */ ;
618+ // Beyond this point, pceBuffer may be empty, so check before consuming.
619+ if (pceBuffer .bitsLeft () < channelBits + numAlignmentBits + commentSizeBits ) {
620+ throw ParserException .createForMalformedContainer (/* message= */ null , /* cause= */ null );
621+ }
622622
623- pceBuffer .skipBits (numAlignmentBits );
624- int commentSize = pceBuffer .readBits (commentSizeBits );
623+ pceBuffer .skipBits (channelBits );
625624
626- if (sampleSize >= pceBuffer .getBytePosition () + commentSize ) {
627- // Append PCE to format's audio specific config.
628- byte [] oldConfig = pendingOutputFormat .initializationData .get (0 );
625+ // Store PCE size excluding initial PCE tag, alignment bits and comment for later.
626+ int numPceBits = pceBuffer .getPosition () - 3 /* PCE tag */ ;
627+ pceBuffer .skipBits (numAlignmentBits );
628+ int commentSize = pceBuffer .readBits (commentSizeBits );
629629
630- int configSize = oldConfig . length ;
631- configSize += ( numPceBits + 7 ) / 8 + 1 ; // Byte align and add a zero length comment.
632- byte [] newConfig = Arrays . copyOf ( oldConfig , configSize );
630+ if ( sampleSize < pceBuffer . getBytePosition () + commentSize ) {
631+ throw ParserException . createForMalformedContainer ( /* message= */ null , /* cause= */ null );
632+ }
633633
634- pceBuffer .setPosition (3 /* PCE tag */ );
635- pceBuffer .readBits (newConfig , oldConfig .length , numPceBits );
634+ Format pendingOutputFormat = checkNotNull (this .pendingOutputFormat );
635+ // Append PCE to format's audio specific config.
636+ byte [] oldConfig = pendingOutputFormat .initializationData .get (0 );
637+ int configSize = oldConfig .length ;
638+ configSize += (numPceBits + 7 ) / 8 + 1 ; // Byte align and add a zero length comment.
639+ byte [] newConfig = Arrays .copyOf (oldConfig , configSize );
636640
637- pendingOutputFormat =
638- pendingOutputFormat
639- .buildUpon ()
640- .setInitializationData (ImmutableList .of (newConfig ))
641- .build ();
641+ pceBuffer .setPosition (3 /* PCE tag */ );
642+ pceBuffer .readBits (newConfig , oldConfig .length , numPceBits );
642643
643- // Submit PCE-appended output format.
644- currentOutput . format ( pendingOutputFormat );
645- hasOutputFormat = true ;
646- }
647- }
648- }
644+ pendingOutputFormat =
645+ pendingOutputFormat . buildUpon (). setInitializationData ( ImmutableList . of ( newConfig )). build ( );
646+
647+ // Submit PCE-appended output format.
648+ this . currentOutput . format ( pendingOutputFormat );
649+ this . hasOutputFormat = true ;
649650
650651 // Pass through all accumulated data as sample data.
651652 ParsableByteArray data = new ParsableByteArray (pceBuffer .data );
0 commit comments