package androidx.media3.extractor.ts; import androidx.media3.common.Format; import androidx.media3.common.ParserException; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; import androidx.media3.common.util.ParsableBitArray; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.Util; import androidx.media3.extractor.AacUtil; import androidx.media3.extractor.DummyTrackOutput; import androidx.media3.extractor.ExtractorOutput; import androidx.media3.extractor.TrackOutput; import androidx.media3.extractor.ts.TsPayloadReader; import java.util.Arrays; import java.util.Collections; import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.checkerframework.checker.nullness.qual.RequiresNonNull; /* loaded from: classes2.dex */ public final class AdtsReader implements ElementaryStreamReader { private static final int CRC_SIZE = 2; private static final int HEADER_SIZE = 5; private static final int ID3_HEADER_SIZE = 10; private static final byte[] ID3_IDENTIFIER = {73, 68, 51}; private static final int ID3_SIZE_OFFSET = 6; private static final int MATCH_STATE_FF = 512; private static final int MATCH_STATE_I = 768; private static final int MATCH_STATE_ID = 1024; private static final int MATCH_STATE_START = 256; private static final int MATCH_STATE_VALUE_SHIFT = 8; private static final int STATE_CHECKING_ADTS_HEADER = 1; private static final int STATE_FINDING_SAMPLE = 0; private static final int STATE_READING_ADTS_HEADER = 3; private static final int STATE_READING_ID3_HEADER = 2; private static final int STATE_READING_SAMPLE = 4; private static final String TAG = "AdtsReader"; private static final int VERSION_UNSET = -1; private final ParsableBitArray adtsScratch; private int bytesRead; private int currentFrameVersion; private TrackOutput currentOutput; private long currentSampleDuration; private final boolean exposeId3; private int firstFrameSampleRateIndex; private int firstFrameVersion; private String formatId; private boolean foundFirstFrame; private boolean hasCrc; private boolean hasOutputFormat; private final ParsableByteArray id3HeaderBuffer; private TrackOutput id3Output; private final String language; private int matchState; private TrackOutput output; private long sampleDurationUs; private int sampleSize; private int state; private long timeUs; public static boolean isAdtsSyncWord(int i) { return (i & 65526) == 65520; } private void setCheckingAdtsHeaderState() { this.state = 1; this.bytesRead = 0; } private void setFindingSampleState() { this.state = 0; this.bytesRead = 0; this.matchState = 256; } private void setReadingAdtsHeaderState() { this.state = 3; this.bytesRead = 0; } private void setReadingSampleState(TrackOutput trackOutput, long j, int i, int i2) { this.state = 4; this.bytesRead = i; this.currentOutput = trackOutput; this.currentSampleDuration = j; this.sampleSize = i2; } public long getSampleDurationUs() { return this.sampleDurationUs; } @Override // androidx.media3.extractor.ts.ElementaryStreamReader public void packetFinished() { } @Override // androidx.media3.extractor.ts.ElementaryStreamReader public void packetStarted(long j, int i) { if (j != -9223372036854775807L) { this.timeUs = j; } } public AdtsReader(boolean z) { this(z, null); } public AdtsReader(boolean z, String str) { this.adtsScratch = new ParsableBitArray(new byte[7]); this.id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, 10)); setFindingSampleState(); this.firstFrameVersion = -1; this.firstFrameSampleRateIndex = -1; this.sampleDurationUs = -9223372036854775807L; this.timeUs = -9223372036854775807L; this.exposeId3 = z; this.language = str; } @Override // androidx.media3.extractor.ts.ElementaryStreamReader public void seek() { this.timeUs = -9223372036854775807L; resetSync(); } @Override // androidx.media3.extractor.ts.ElementaryStreamReader public void createTracks(ExtractorOutput extractorOutput, TsPayloadReader.TrackIdGenerator trackIdGenerator) { trackIdGenerator.generateNewId(); this.formatId = trackIdGenerator.getFormatId(); TrackOutput track = extractorOutput.track(trackIdGenerator.getTrackId(), 1); this.output = track; this.currentOutput = track; if (this.exposeId3) { trackIdGenerator.generateNewId(); TrackOutput track2 = extractorOutput.track(trackIdGenerator.getTrackId(), 5); this.id3Output = track2; track2.format(new Format.Builder().setId(trackIdGenerator.getFormatId()).setSampleMimeType("application/id3").build()); return; } this.id3Output = new DummyTrackOutput(); } @Override // androidx.media3.extractor.ts.ElementaryStreamReader public void consume(ParsableByteArray parsableByteArray) throws ParserException { assertTracksCreated(); while (parsableByteArray.bytesLeft() > 0) { int i = this.state; if (i == 0) { findNextSample(parsableByteArray); } else if (i == 1) { checkAdtsHeader(parsableByteArray); } else if (i != 2) { if (i == 3) { if (continueRead(parsableByteArray, this.adtsScratch.data, this.hasCrc ? 7 : 5)) { parseAdtsHeader(); } } else if (i == 4) { readSample(parsableByteArray); } else { throw new IllegalStateException(); } } else if (continueRead(parsableByteArray, this.id3HeaderBuffer.getData(), 10)) { parseId3Header(); } } } private void resetSync() { this.foundFirstFrame = false; setFindingSampleState(); } private boolean continueRead(ParsableByteArray parsableByteArray, byte[] bArr, int i) { int min = Math.min(parsableByteArray.bytesLeft(), i - this.bytesRead); parsableByteArray.readBytes(bArr, this.bytesRead, min); int i2 = this.bytesRead + min; this.bytesRead = i2; return i2 == i; } private void setReadingId3HeaderState() { this.state = 2; this.bytesRead = ID3_IDENTIFIER.length; this.sampleSize = 0; this.id3HeaderBuffer.setPosition(0); } private void findNextSample(ParsableByteArray parsableByteArray) { byte[] data = parsableByteArray.getData(); int position = parsableByteArray.getPosition(); int limit = parsableByteArray.limit(); while (position < limit) { int i = position + 1; byte b = data[position]; int i2 = b & 255; if (this.matchState == 512 && isAdtsSyncBytes((byte) -1, (byte) i2) && (this.foundFirstFrame || checkSyncPositionValid(parsableByteArray, position - 1))) { this.currentFrameVersion = (b & 8) >> 3; this.hasCrc = (b & 1) == 0; if (!this.foundFirstFrame) { setCheckingAdtsHeaderState(); } else { setReadingAdtsHeaderState(); } parsableByteArray.setPosition(i); return; } int i3 = this.matchState; int i4 = i2 | i3; if (i4 == 329) { this.matchState = 768; } else if (i4 == 511) { this.matchState = 512; } else if (i4 == 836) { this.matchState = 1024; } else if (i4 == 1075) { setReadingId3HeaderState(); parsableByteArray.setPosition(i); return; } else if (i3 != 256) { this.matchState = 256; } position = i; } parsableByteArray.setPosition(position); } private void checkAdtsHeader(ParsableByteArray parsableByteArray) { if (parsableByteArray.bytesLeft() == 0) { return; } this.adtsScratch.data[0] = parsableByteArray.getData()[parsableByteArray.getPosition()]; this.adtsScratch.setPosition(2); int readBits = this.adtsScratch.readBits(4); int i = this.firstFrameSampleRateIndex; if (i != -1 && readBits != i) { resetSync(); return; } if (!this.foundFirstFrame) { this.foundFirstFrame = true; this.firstFrameVersion = this.currentFrameVersion; this.firstFrameSampleRateIndex = readBits; } setReadingAdtsHeaderState(); } private boolean checkSyncPositionValid(ParsableByteArray parsableByteArray, int i) { parsableByteArray.setPosition(i + 1); if (!tryRead(parsableByteArray, this.adtsScratch.data, 1)) { return false; } this.adtsScratch.setPosition(4); int readBits = this.adtsScratch.readBits(1); int i2 = this.firstFrameVersion; if (i2 != -1 && readBits != i2) { return false; } if (this.firstFrameSampleRateIndex != -1) { if (!tryRead(parsableByteArray, this.adtsScratch.data, 1)) { return true; } this.adtsScratch.setPosition(2); if (this.adtsScratch.readBits(4) != this.firstFrameSampleRateIndex) { return false; } parsableByteArray.setPosition(i + 2); } if (!tryRead(parsableByteArray, this.adtsScratch.data, 4)) { return true; } this.adtsScratch.setPosition(14); int readBits2 = this.adtsScratch.readBits(13); if (readBits2 < 7) { return false; } byte[] data = parsableByteArray.getData(); int limit = parsableByteArray.limit(); int i3 = i + readBits2; if (i3 >= limit) { return true; } byte b = data[i3]; if (b == -1) { int i4 = i3 + 1; if (i4 == limit) { return true; } return isAdtsSyncBytes((byte) -1, data[i4]) && ((data[i4] & 8) >> 3) == readBits; } if (b != 73) { return false; } int i5 = i3 + 1; if (i5 == limit) { return true; } if (data[i5] != 68) { return false; } int i6 = i3 + 2; return i6 == limit || data[i6] == 51; } private boolean isAdtsSyncBytes(byte b, byte b2) { return isAdtsSyncWord(((b & 255) << 8) | (b2 & 255)); } private boolean tryRead(ParsableByteArray parsableByteArray, byte[] bArr, int i) { if (parsableByteArray.bytesLeft() < i) { return false; } parsableByteArray.readBytes(bArr, 0, i); return true; } @RequiresNonNull({"id3Output"}) private void parseId3Header() { this.id3Output.sampleData(this.id3HeaderBuffer, 10); this.id3HeaderBuffer.setPosition(6); setReadingSampleState(this.id3Output, 0L, 10, this.id3HeaderBuffer.readSynchSafeInt() + 10); } @RequiresNonNull({"output"}) private void parseAdtsHeader() throws ParserException { this.adtsScratch.setPosition(0); if (!this.hasOutputFormat) { int i = 2; int readBits = this.adtsScratch.readBits(2) + 1; if (readBits != 2) { Log.w(TAG, "Detected audio object type: " + readBits + ", but assuming AAC LC."); } else { i = readBits; } this.adtsScratch.skipBits(5); byte[] buildAudioSpecificConfig = AacUtil.buildAudioSpecificConfig(i, this.firstFrameSampleRateIndex, this.adtsScratch.readBits(3)); AacUtil.Config parseAudioSpecificConfig = AacUtil.parseAudioSpecificConfig(buildAudioSpecificConfig); Format build = new Format.Builder().setId(this.formatId).setSampleMimeType("audio/mp4a-latm").setCodecs(parseAudioSpecificConfig.codecs).setChannelCount(parseAudioSpecificConfig.channelCount).setSampleRate(parseAudioSpecificConfig.sampleRateHz).setInitializationData(Collections.singletonList(buildAudioSpecificConfig)).setLanguage(this.language).build(); this.sampleDurationUs = 1024000000 / build.sampleRate; this.output.format(build); this.hasOutputFormat = true; } else { this.adtsScratch.skipBits(10); } this.adtsScratch.skipBits(4); int readBits2 = this.adtsScratch.readBits(13); int i2 = readBits2 - 7; if (this.hasCrc) { i2 = readBits2 - 9; } setReadingSampleState(this.output, this.sampleDurationUs, 0, i2); } @RequiresNonNull({"currentOutput"}) private void readSample(ParsableByteArray parsableByteArray) { int min = Math.min(parsableByteArray.bytesLeft(), this.sampleSize - this.bytesRead); this.currentOutput.sampleData(parsableByteArray, min); int i = this.bytesRead + min; this.bytesRead = i; int i2 = this.sampleSize; if (i == i2) { long j = this.timeUs; if (j != -9223372036854775807L) { this.currentOutput.sampleMetadata(j, 1, i2, 0, null); this.timeUs += this.currentSampleDuration; } setFindingSampleState(); } } @EnsuresNonNull({"output", "currentOutput", "id3Output"}) private void assertTracksCreated() { Assertions.checkNotNull(this.output); Util.castNonNull(this.currentOutput); Util.castNonNull(this.id3Output); } }