Skip to content

Commit 83cc9e2

Browse files
committed
Changes based on internal review
1 parent 2c3eac4 commit 83cc9e2

File tree

2 files changed

+67
-73
lines changed

2 files changed

+67
-73
lines changed

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

Lines changed: 66 additions & 72 deletions
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
/**
@@ -573,87 +572,82 @@ private void parseAdtsHeader() throws ParserException {
573572
}
574573
}
575574

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

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

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

612-
int numAlignmentBits =
613-
8 - (pceBuffer.getPosition() + channelBits + 7) % 8 - 1; // byte_alignment
614-
int commentSizeBits = 8; // comment_field_bytes
606+
if (pceBuffer.readBit()) { // matrix_mixdown_idx_present
607+
pceBuffer.skipBits(3); // matrix_mixdown_idx(2), matrix_mixdown_idx(1)
608+
}
615609

616-
// Beyond this point, pceBuffer may be empty, so check before consuming.
617-
if (pceBuffer.bitsLeft() >= channelBits + numAlignmentBits + commentSizeBits) {
618-
pceBuffer.skipBits(channelBits);
610+
int numAlignmentBits =
611+
8 - (pceBuffer.getPosition() + channelBits + 7) % 8 - 1; // byte_alignment
612+
int commentSizeBits = 8; // comment_field_bytes
619613

620-
// Store PCE size excluding initial PCE tag, alignment bits and comment for later.
621-
int numPceBits = pceBuffer.getPosition() - 3 /* PCE tag */;
614+
// Beyond this point, pceBuffer may be empty, so check before consuming.
615+
if (pceBuffer.bitsLeft() < channelBits + numAlignmentBits + commentSizeBits) {
616+
throw ParserException.createForMalformedContainer(/* message= */ null, /* cause= */ null);
617+
}
622618

623-
pceBuffer.skipBits(numAlignmentBits);
624-
int commentSize = pceBuffer.readBits(commentSizeBits);
619+
pceBuffer.skipBits(channelBits);
625620

626-
if (sampleSize >= pceBuffer.getBytePosition() + commentSize) {
627-
// Append PCE to format's audio specific config.
628-
byte[] oldConfig = pendingOutputFormat.initializationData.get(0);
621+
// Store PCE size excluding initial PCE tag, alignment bits and comment for later.
622+
int numPceBits = pceBuffer.getPosition() - 3 /* PCE tag */;
629623

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);
624+
pceBuffer.skipBits(numAlignmentBits);
625+
int commentSize = pceBuffer.readBits(commentSizeBits);
633626

634-
pceBuffer.setPosition(3 /* PCE tag */);
635-
pceBuffer.readBits(newConfig, oldConfig.length, numPceBits);
627+
if (sampleSize < pceBuffer.getBytePosition() + commentSize) {
628+
throw ParserException.createForMalformedContainer(/* message= */ null, /* cause= */ null);
629+
}
636630

637-
pendingOutputFormat =
638-
pendingOutputFormat
639-
.buildUpon()
640-
.setInitializationData(ImmutableList.of(newConfig))
641-
.build();
631+
Format pendingOutputFormat = checkNotNull(this.pendingOutputFormat);
632+
// Append PCE to format's audio specific config.
633+
byte[] oldConfig = pendingOutputFormat.initializationData.get(0);
642634

643-
// Submit PCE-appended output format.
644-
currentOutput.format(pendingOutputFormat);
645-
hasOutputFormat = true;
646-
}
647-
}
648-
}
635+
int configSize = oldConfig.length;
636+
configSize += (numPceBits + 7) / 8 + 1; // Byte align and add a zero length comment.
637+
byte[] newConfig = Arrays.copyOf(oldConfig, configSize);
649638

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);
639+
pceBuffer.setPosition(3 /* PCE tag */);
640+
pceBuffer.readBits(newConfig, oldConfig.length, numPceBits);
641+
642+
pendingOutputFormat =
643+
pendingOutputFormat.buildUpon().setInitializationData(ImmutableList.of(newConfig)).build();
654644

645+
// Submit PCE-appended output format.
646+
checkNotNull(currentOutput).format(pendingOutputFormat);
647+
this.hasOutputFormat = true;
655648
this.pendingOutputFormat = null;
656-
this.pceBuffer = null;
649+
650+
setReadingSampleState(currentOutput, currentSampleDuration, 0, sampleSize);
657651
}
658652

659653
/** Reads the rest of the sample */

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

Lines changed: 1 addition & 1 deletion
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)