Skip to content

Commit 6d1951a

Browse files
committed
Changes based on internal review
1 parent 2c3eac4 commit 6d1951a

File tree

2 files changed

+67
-72
lines changed

2 files changed

+67
-72
lines changed

libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java

+66-71
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ public final class AdtsReader implements ElementaryStreamReader {
101101

102102
// Used when reading the AAC PCE.
103103
@Nullable private Format pendingOutputFormat;
104-
@Nullable private ParsableBitArray pceBuffer;
105104

106105
// Used when reading the samples.
107106
private long timeUs;
@@ -192,10 +191,11 @@ public void consume(ParsableByteArray data) throws ParserException {
192191
}
193192
break;
194193
case STATE_READING_AAC_PCE:
195-
checkNotNull(pceBuffer);
196-
if (continueRead(data, pceBuffer.data, pceBuffer.data.length)) {
197-
readAacProgramConfigElement();
198-
}
194+
int offset = data.getPosition();
195+
int limit = offset + min(sampleSize, AAC_PCE_MAX_SIZE);
196+
ParsableBitArray pceBuffer =
197+
new ParsableBitArray(Arrays.copyOfRange(data.getData(), offset, limit));
198+
readAacProgramConfigElement(pceBuffer);
199199
break;
200200
case STATE_READING_SAMPLE:
201201
readSample(data);
@@ -301,7 +301,6 @@ private void setReadingAacPceState(
301301
this.currentOutput = outputToUse;
302302
this.currentSampleDuration = currentSampleDuration;
303303
this.sampleSize = sampleSize;
304-
pceBuffer = new ParsableBitArray(new byte[min(sampleSize, AAC_PCE_MAX_SIZE)]);
305304
}
306305

307306
/**
@@ -574,86 +573,82 @@ private void parseAdtsHeader() throws ParserException {
574573
}
575574

576575
@RequiresNonNull("currentOutput")
577-
void readAacProgramConfigElement() {
578-
Format pendingOutputFormat = checkNotNull(this.pendingOutputFormat);
579-
ParsableBitArray pceBuffer = checkNotNull(this.pceBuffer);
580-
576+
private void readAacProgramConfigElement(ParsableBitArray pceBuffer) throws ParserException {
581577
// 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-
}
578+
if (pceBuffer.readBits(3) != 5 /* PCE tag */) {
579+
throw ParserException.createForMalformedContainer(/* message= */ null, /* cause= */ null);
580+
}
603581

604-
if (pceBuffer.readBit()) { // stereo_mixdown_present
605-
pceBuffer.skipBits(4); // stereo_mixdown_element_number
606-
}
582+
// See ISO 13818-7 Advanced Audio Coding (2006) Table 25 for syntax of a PCE.
583+
pceBuffer.skipBits(10); // element_instance_tag(4), profile(2), element_instance_tag(4)
584+
585+
int channelBits = 0;
586+
// num_front_channel_elements, front_element_is_cpe(1), front_element_tag_select(4)
587+
channelBits += pceBuffer.readBits(4) * 5;
588+
// num_side_channel_elements, side_element_is_cpe(1), side_element_tag_select(4)
589+
channelBits += pceBuffer.readBits(4) * 5;
590+
// num_back_channel_elements, back_element_is_cpe(1), back_element_tag_select(4)
591+
channelBits += pceBuffer.readBits(4) * 5;
592+
// num_lfe_channel_elements, lfe_element_tag_select(4)
593+
channelBits += pceBuffer.readBits(2) * 4;
594+
// num_assoc_data_elements, assoc_data_element_tag_select(4)
595+
channelBits += pceBuffer.readBits(3) * 4;
596+
// num_valid_cc_elements, cc_element_is_ind_sw(1), valid_cc_element_tag_select(4)
597+
channelBits += pceBuffer.readBits(4) * 5;
598+
599+
if (pceBuffer.readBit()) { // mono_mixdown_present
600+
pceBuffer.skipBits(4); // mono_mixdown_element_number
601+
}
607602

608-
if (pceBuffer.readBit()) { // matrix_mixdown_idx_present
609-
pceBuffer.skipBits(3); // matrix_mixdown_idx(2), matrix_mixdown_idx(1)
610-
}
603+
if (pceBuffer.readBit()) { // stereo_mixdown_present
604+
pceBuffer.skipBits(4); // stereo_mixdown_element_number
605+
}
606+
607+
if (pceBuffer.readBit()) { // matrix_mixdown_idx_present
608+
pceBuffer.skipBits(3); // matrix_mixdown_idx(2), matrix_mixdown_idx(1)
609+
}
611610

612-
int numAlignmentBits =
613-
8 - (pceBuffer.getPosition() + channelBits + 7) % 8 - 1; // byte_alignment
614-
int commentSizeBits = 8; // comment_field_bytes
611+
int numAlignmentBits =
612+
8 - (pceBuffer.getPosition() + channelBits + 7) % 8 - 1; // byte_alignment
613+
int commentSizeBits = 8; // comment_field_bytes
615614

616-
// Beyond this point, pceBuffer may be empty, so check before consuming.
617-
if (pceBuffer.bitsLeft() >= channelBits + numAlignmentBits + commentSizeBits) {
618-
pceBuffer.skipBits(channelBits);
615+
// Beyond this point, pceBuffer may be empty, so check before consuming.
616+
if (pceBuffer.bitsLeft() < channelBits + numAlignmentBits + commentSizeBits) {
617+
throw ParserException.createForMalformedContainer(/* message= */ null, /* cause= */ null);
618+
}
619619

620-
// Store PCE size excluding initial PCE tag, alignment bits and comment for later.
621-
int numPceBits = pceBuffer.getPosition() - 3 /* PCE tag */;
620+
pceBuffer.skipBits(channelBits);
622621

623-
pceBuffer.skipBits(numAlignmentBits);
624-
int commentSize = pceBuffer.readBits(commentSizeBits);
622+
// Store PCE size excluding initial PCE tag, alignment bits and comment for later.
623+
int numPceBits = pceBuffer.getPosition() - 3 /* PCE tag */;
625624

626-
if (sampleSize >= pceBuffer.getBytePosition() + commentSize) {
627-
// Append PCE to format's audio specific config.
628-
byte[] oldConfig = pendingOutputFormat.initializationData.get(0);
625+
pceBuffer.skipBits(numAlignmentBits);
626+
int commentSize = pceBuffer.readBits(commentSizeBits);
629627

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);
628+
if (sampleSize < pceBuffer.getBytePosition() + commentSize) {
629+
throw ParserException.createForMalformedContainer(/* message= */ null, /* cause= */ null);
630+
}
633631

634-
pceBuffer.setPosition(3 /* PCE tag */);
635-
pceBuffer.readBits(newConfig, oldConfig.length, numPceBits);
632+
Format pendingOutputFormat = checkNotNull(this.pendingOutputFormat);
633+
// Append PCE to format's audio specific config.
634+
byte[] oldConfig = pendingOutputFormat.initializationData.get(0);
636635

637-
pendingOutputFormat =
638-
pendingOutputFormat
639-
.buildUpon()
640-
.setInitializationData(ImmutableList.of(newConfig))
641-
.build();
636+
int configSize = oldConfig.length;
637+
configSize += (numPceBits + 7) / 8 + 1; // Byte align and add a zero length comment.
638+
byte[] newConfig = Arrays.copyOf(oldConfig, configSize);
642639

643-
// Submit PCE-appended output format.
644-
currentOutput.format(pendingOutputFormat);
645-
hasOutputFormat = true;
646-
}
647-
}
648-
}
640+
pceBuffer.setPosition(3 /* PCE tag */);
641+
pceBuffer.readBits(newConfig, oldConfig.length, numPceBits);
649642

650-
// Pass through all accumulated data as sample data.
651-
ParsableByteArray data = new ParsableByteArray(pceBuffer.data);
652-
setReadingSampleState(currentOutput, currentSampleDuration, 0, sampleSize);
653-
readSample(data);
643+
pendingOutputFormat =
644+
pendingOutputFormat.buildUpon().setInitializationData(ImmutableList.of(newConfig)).build();
654645

646+
// Submit PCE-appended output format.
647+
this.currentOutput.format(pendingOutputFormat);
648+
this.hasOutputFormat = true;
655649
this.pendingOutputFormat = null;
656-
this.pceBuffer = null;
650+
651+
setReadingSampleState(currentOutput, currentSampleDuration, 0, sampleSize);
657652
}
658653

659654
/** Reads the rest of the sample */

libraries/extractor/src/test/java/androidx/media3/extractor/ts/AdtsReaderTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ public void aacPceDataFail() throws ParserException {
219219
bytes[AAC_PCE_ADTS_HEADER.length] |= 0x20;
220220

221221
// Should throw as FakeTrackOutput expects a format before sampleMetadata.
222-
assertThrows(IllegalStateException.class, this::feed);
222+
assertThrows(ParserException.class, this::feed);
223223
}
224224

225225
private void feedLimited(int limit) throws ParserException {

0 commit comments

Comments
 (0)