Search for synch' when sniffing ADTS and check four frames.
Issue: #791
This commit is contained in:
parent
721956710f
commit
908e4dfd5d
@ -20,6 +20,7 @@ import com.google.android.exoplayer.extractor.ExtractorInput;
|
|||||||
import com.google.android.exoplayer.extractor.ExtractorOutput;
|
import com.google.android.exoplayer.extractor.ExtractorOutput;
|
||||||
import com.google.android.exoplayer.extractor.PositionHolder;
|
import com.google.android.exoplayer.extractor.PositionHolder;
|
||||||
import com.google.android.exoplayer.extractor.SeekMap;
|
import com.google.android.exoplayer.extractor.SeekMap;
|
||||||
|
import com.google.android.exoplayer.util.ParsableBitArray;
|
||||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
@ -32,6 +33,12 @@ import java.io.IOException;
|
|||||||
public final class AdtsExtractor implements Extractor {
|
public final class AdtsExtractor implements Extractor {
|
||||||
|
|
||||||
private static final int MAX_PACKET_SIZE = 200;
|
private static final int MAX_PACKET_SIZE = 200;
|
||||||
|
private static final int ID3_TAG = Util.getIntegerCodeForString("ID3");
|
||||||
|
/**
|
||||||
|
* The maximum number of bytes to search when sniffing, excluding the header, before giving up.
|
||||||
|
* Frame sizes are represented by 13-bit fields, so expect a valid frame in the first 8192 bytes.
|
||||||
|
*/
|
||||||
|
private static final int MAX_SNIFF_BYTES = 8 * 1024;
|
||||||
|
|
||||||
private final long firstSampleTimestampUs;
|
private final long firstSampleTimestampUs;
|
||||||
private final ParsableByteArray packetBuffer;
|
private final ParsableByteArray packetBuffer;
|
||||||
@ -52,20 +59,53 @@ public final class AdtsExtractor implements Extractor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
|
public boolean sniff(ExtractorInput input) throws IOException, InterruptedException {
|
||||||
|
// Skip any ID3 headers.
|
||||||
ParsableByteArray scratch = new ParsableByteArray(10);
|
ParsableByteArray scratch = new ParsableByteArray(10);
|
||||||
|
ParsableBitArray scratchBits = new ParsableBitArray(scratch.data);
|
||||||
|
int startPosition = 0;
|
||||||
|
while (true) {
|
||||||
input.peekFully(scratch.data, 0, 10);
|
input.peekFully(scratch.data, 0, 10);
|
||||||
int value = scratch.readUnsignedInt24();
|
scratch.setPosition(0);
|
||||||
if (value != Util.getIntegerCodeForString("ID3")) {
|
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
||||||
value = value >> 8;
|
break;
|
||||||
} else {
|
}
|
||||||
int length = (scratch.data[6] & 0x7F) << 21 | ((scratch.data[7] & 0x7F) << 14)
|
int length = (scratch.data[6] & 0x7F) << 21 | ((scratch.data[7] & 0x7F) << 14)
|
||||||
| ((scratch.data[8] & 0x7F) << 7) | (scratch.data[9] & 0x7F);
|
| ((scratch.data[8] & 0x7F) << 7) | (scratch.data[9] & 0x7F);
|
||||||
|
startPosition += 10 + length;
|
||||||
input.advancePeekPosition(length);
|
input.advancePeekPosition(length);
|
||||||
|
}
|
||||||
|
input.resetPeekPosition();
|
||||||
|
input.advancePeekPosition(startPosition);
|
||||||
|
|
||||||
|
// Try to find four or more consecutive AAC audio frames, exceeding the MPEG TS packet size.
|
||||||
|
int headerPosition = startPosition;
|
||||||
|
int validFramesSize = 0;
|
||||||
|
int validFramesCount = 0;
|
||||||
|
while (true) {
|
||||||
input.peekFully(scratch.data, 0, 2);
|
input.peekFully(scratch.data, 0, 2);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
value = scratch.readUnsignedShort();
|
int syncBytes = scratch.readUnsignedShort();
|
||||||
|
if ((syncBytes & 0xFFF6) != 0xFFF0) {
|
||||||
|
validFramesCount = 0;
|
||||||
|
validFramesSize = 0;
|
||||||
|
input.resetPeekPosition();
|
||||||
|
if (++headerPosition - startPosition >= MAX_SNIFF_BYTES) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
input.advancePeekPosition(headerPosition);
|
||||||
|
} else {
|
||||||
|
if (++validFramesCount >= 4 && validFramesSize > 188) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the frame.
|
||||||
|
input.peekFully(scratch.data, 0, 4);
|
||||||
|
scratchBits.setPosition(14);
|
||||||
|
int frameSize = scratchBits.readBits(13);
|
||||||
|
input.advancePeekPosition(frameSize - 6);
|
||||||
|
validFramesSize += frameSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (value & 0xFFF6) == 0xFFF0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user