mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Hide ParsableByteArray#data behind a getter
This allows us to enforce the limit because the array can only be reassigned through reset(byte[]) or reset(byte[], int) (which update the limit) PiperOrigin-RevId: 323339960
This commit is contained in:
parent
478f59fd08
commit
ce2e6e2fd6
67 changed files with 320 additions and 282 deletions
|
|
@ -210,7 +210,7 @@ public final class FlacExtractor implements Extractor {
|
||||||
if (this.streamMetadata == null) {
|
if (this.streamMetadata == null) {
|
||||||
this.streamMetadata = streamMetadata;
|
this.streamMetadata = streamMetadata;
|
||||||
outputBuffer.reset(streamMetadata.getMaxDecodedFrameSize());
|
outputBuffer.reset(streamMetadata.getMaxDecodedFrameSize());
|
||||||
outputFrameHolder = new OutputFrameHolder(ByteBuffer.wrap(outputBuffer.data));
|
outputFrameHolder = new OutputFrameHolder(ByteBuffer.wrap(outputBuffer.getData()));
|
||||||
binarySearchSeeker =
|
binarySearchSeeker =
|
||||||
outputSeekMap(
|
outputSeekMap(
|
||||||
flacDecoderJni,
|
flacDecoderJni,
|
||||||
|
|
|
||||||
|
|
@ -223,13 +223,14 @@ public final class Ac4Util {
|
||||||
public static void getAc4SampleHeader(int size, ParsableByteArray buffer) {
|
public static void getAc4SampleHeader(int size, ParsableByteArray buffer) {
|
||||||
// See ETSI TS 103 190-1 V1.3.1, Annex G.
|
// See ETSI TS 103 190-1 V1.3.1, Annex G.
|
||||||
buffer.reset(SAMPLE_HEADER_SIZE);
|
buffer.reset(SAMPLE_HEADER_SIZE);
|
||||||
buffer.data[0] = (byte) 0xAC;
|
byte[] data = buffer.getData();
|
||||||
buffer.data[1] = 0x40;
|
data[0] = (byte) 0xAC;
|
||||||
buffer.data[2] = (byte) 0xFF;
|
data[1] = 0x40;
|
||||||
buffer.data[3] = (byte) 0xFF;
|
data[2] = (byte) 0xFF;
|
||||||
buffer.data[4] = (byte) ((size >> 16) & 0xFF);
|
data[3] = (byte) 0xFF;
|
||||||
buffer.data[5] = (byte) ((size >> 8) & 0xFF);
|
data[4] = (byte) ((size >> 16) & 0xFF);
|
||||||
buffer.data[6] = (byte) (size & 0xFF);
|
data[5] = (byte) ((size >> 8) & 0xFF);
|
||||||
|
data[6] = (byte) (size & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int readVariableBits(ParsableBitArray data, int bitsPerRead) {
|
private static int readVariableBits(ParsableBitArray data, int bitsPerRead) {
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public final class EventMessageDecoder extends SimpleMetadataDecoder {
|
||||||
long durationMs = emsgData.readUnsignedInt();
|
long durationMs = emsgData.readUnsignedInt();
|
||||||
long id = emsgData.readUnsignedInt();
|
long id = emsgData.readUnsignedInt();
|
||||||
byte[] messageData =
|
byte[] messageData =
|
||||||
Arrays.copyOfRange(emsgData.data, emsgData.getPosition(), emsgData.limit());
|
Arrays.copyOfRange(emsgData.getData(), emsgData.getPosition(), emsgData.limit());
|
||||||
return new EventMessage(schemeIdUri, value, durationMs, id, messageData);
|
return new EventMessage(schemeIdUri, value, durationMs, id, messageData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -601,9 +601,10 @@ public final class Id3Decoder extends SimpleMetadataDecoder {
|
||||||
@Nullable FramePredicate framePredicate)
|
@Nullable FramePredicate framePredicate)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
int framePosition = id3Data.getPosition();
|
int framePosition = id3Data.getPosition();
|
||||||
int chapterIdEndIndex = indexOfZeroByte(id3Data.data, framePosition);
|
int chapterIdEndIndex = indexOfZeroByte(id3Data.getData(), framePosition);
|
||||||
String chapterId = new String(id3Data.data, framePosition, chapterIdEndIndex - framePosition,
|
String chapterId =
|
||||||
"ISO-8859-1");
|
new String(
|
||||||
|
id3Data.getData(), framePosition, chapterIdEndIndex - framePosition, "ISO-8859-1");
|
||||||
id3Data.setPosition(chapterIdEndIndex + 1);
|
id3Data.setPosition(chapterIdEndIndex + 1);
|
||||||
|
|
||||||
int startTime = id3Data.readInt();
|
int startTime = id3Data.readInt();
|
||||||
|
|
@ -640,9 +641,10 @@ public final class Id3Decoder extends SimpleMetadataDecoder {
|
||||||
@Nullable FramePredicate framePredicate)
|
@Nullable FramePredicate framePredicate)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
int framePosition = id3Data.getPosition();
|
int framePosition = id3Data.getPosition();
|
||||||
int elementIdEndIndex = indexOfZeroByte(id3Data.data, framePosition);
|
int elementIdEndIndex = indexOfZeroByte(id3Data.getData(), framePosition);
|
||||||
String elementId = new String(id3Data.data, framePosition, elementIdEndIndex - framePosition,
|
String elementId =
|
||||||
"ISO-8859-1");
|
new String(
|
||||||
|
id3Data.getData(), framePosition, elementIdEndIndex - framePosition, "ISO-8859-1");
|
||||||
id3Data.setPosition(elementIdEndIndex + 1);
|
id3Data.setPosition(elementIdEndIndex + 1);
|
||||||
|
|
||||||
int ctocFlags = id3Data.readUnsignedByte();
|
int ctocFlags = id3Data.readUnsignedByte();
|
||||||
|
|
@ -653,8 +655,8 @@ public final class Id3Decoder extends SimpleMetadataDecoder {
|
||||||
String[] children = new String[childCount];
|
String[] children = new String[childCount];
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
int startIndex = id3Data.getPosition();
|
int startIndex = id3Data.getPosition();
|
||||||
int endIndex = indexOfZeroByte(id3Data.data, startIndex);
|
int endIndex = indexOfZeroByte(id3Data.getData(), startIndex);
|
||||||
children[i] = new String(id3Data.data, startIndex, endIndex - startIndex, "ISO-8859-1");
|
children[i] = new String(id3Data.getData(), startIndex, endIndex - startIndex, "ISO-8859-1");
|
||||||
id3Data.setPosition(endIndex + 1);
|
id3Data.setPosition(endIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -721,7 +723,7 @@ public final class Id3Decoder extends SimpleMetadataDecoder {
|
||||||
* @return The length of the data after processing.
|
* @return The length of the data after processing.
|
||||||
*/
|
*/
|
||||||
private static int removeUnsynchronization(ParsableByteArray data, int length) {
|
private static int removeUnsynchronization(ParsableByteArray data, int length) {
|
||||||
byte[] bytes = data.data;
|
byte[] bytes = data.getData();
|
||||||
int startPosition = data.getPosition();
|
int startPosition = data.getPosition();
|
||||||
for (int i = startPosition; i + 1 < startPosition + length; i++) {
|
for (int i = startPosition; i + 1 < startPosition + length; i++) {
|
||||||
if ((bytes[i] & 0xFF) == 0xFF && bytes[i + 1] == 0x00) {
|
if ((bytes[i] & 0xFF) == 0xFF && bytes[i + 1] == 0x00) {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ public final class ParsableBitArray {
|
||||||
* @param parsableByteArray The {@link ParsableByteArray}.
|
* @param parsableByteArray The {@link ParsableByteArray}.
|
||||||
*/
|
*/
|
||||||
public void reset(ParsableByteArray parsableByteArray) {
|
public void reset(ParsableByteArray parsableByteArray) {
|
||||||
reset(parsableByteArray.data, parsableByteArray.limit());
|
reset(parsableByteArray.getData(), parsableByteArray.limit());
|
||||||
setPosition(parsableByteArray.getPosition() * 8);
|
setPosition(parsableByteArray.getPosition() * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,8 @@ import java.nio.charset.Charset;
|
||||||
*/
|
*/
|
||||||
public final class ParsableByteArray {
|
public final class ParsableByteArray {
|
||||||
|
|
||||||
public byte[] data;
|
private byte[] data;
|
||||||
|
|
||||||
private int position;
|
private int position;
|
||||||
|
|
||||||
// TODO(internal b/147657250): Enforce this limit on all read methods.
|
// TODO(internal b/147657250): Enforce this limit on all read methods.
|
||||||
private int limit;
|
private int limit;
|
||||||
|
|
||||||
|
|
@ -138,13 +136,6 @@ public final class ParsableByteArray {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the capacity of the array, which may be larger than the limit.
|
|
||||||
*/
|
|
||||||
public int capacity() {
|
|
||||||
return data.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the reading offset in the array.
|
* Sets the reading offset in the array.
|
||||||
*
|
*
|
||||||
|
|
@ -158,6 +149,23 @@ public final class ParsableByteArray {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the underlying array.
|
||||||
|
*
|
||||||
|
* <p>Changes to this array are reflected in the results of the {@code read...()} methods.
|
||||||
|
*
|
||||||
|
* <p>This reference must be assumed to become invalid when {@link #reset} is called (because the
|
||||||
|
* array might get reallocated).
|
||||||
|
*/
|
||||||
|
public byte[] getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the capacity of the array, which may be larger than the limit. */
|
||||||
|
public int capacity() {
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the reading offset by {@code bytes}.
|
* Moves the reading offset by {@code bytes}.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -2046,14 +2046,14 @@ public final class Util {
|
||||||
if (input.bytesLeft() <= 0) {
|
if (input.bytesLeft() <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
byte[] outputData = output.data;
|
byte[] outputData = output.getData();
|
||||||
if (outputData.length < input.bytesLeft()) {
|
if (outputData.length < input.bytesLeft()) {
|
||||||
outputData = new byte[2 * input.bytesLeft()];
|
outputData = new byte[2 * input.bytesLeft()];
|
||||||
}
|
}
|
||||||
if (inflater == null) {
|
if (inflater == null) {
|
||||||
inflater = new Inflater();
|
inflater = new Inflater();
|
||||||
}
|
}
|
||||||
inflater.setInput(input.data, input.getPosition(), input.bytesLeft());
|
inflater.setInput(input.getData(), input.getPosition(), input.bytesLeft());
|
||||||
try {
|
try {
|
||||||
int outputSize = 0;
|
int outputSize = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ public final class AvcConfig {
|
||||||
int length = data.readUnsignedShort();
|
int length = data.readUnsignedShort();
|
||||||
int offset = data.getPosition();
|
int offset = data.getPosition();
|
||||||
data.skipBytes(length);
|
data.skipBytes(length);
|
||||||
return CodecSpecificDataUtil.buildNalUnit(data.data, offset, length);
|
return CodecSpecificDataUtil.buildNalUnit(data.getData(), offset, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ public final class HevcConfig {
|
||||||
System.arraycopy(NalUnitUtil.NAL_START_CODE, 0, buffer, bufferPosition,
|
System.arraycopy(NalUnitUtil.NAL_START_CODE, 0, buffer, bufferPosition,
|
||||||
NalUnitUtil.NAL_START_CODE.length);
|
NalUnitUtil.NAL_START_CODE.length);
|
||||||
bufferPosition += NalUnitUtil.NAL_START_CODE.length;
|
bufferPosition += NalUnitUtil.NAL_START_CODE.length;
|
||||||
System
|
System.arraycopy(
|
||||||
.arraycopy(data.data, data.getPosition(), buffer, bufferPosition, nalUnitLength);
|
data.getData(), data.getPosition(), buffer, bufferPosition, nalUnitLength);
|
||||||
bufferPosition += nalUnitLength;
|
bufferPosition += nalUnitLength;
|
||||||
data.skipBytes(nalUnitLength);
|
data.skipBytes(nalUnitLength);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public final class ParsableByteArrayTest {
|
||||||
|
|
||||||
private static ParsableByteArray getTestDataArray() {
|
private static ParsableByteArray getTestDataArray() {
|
||||||
ParsableByteArray testArray = new ParsableByteArray(TEST_DATA.length);
|
ParsableByteArray testArray = new ParsableByteArray(TEST_DATA.length);
|
||||||
System.arraycopy(TEST_DATA, 0, testArray.data, 0, TEST_DATA.length);
|
System.arraycopy(TEST_DATA, 0, testArray.getData(), 0, TEST_DATA.length);
|
||||||
return testArray;
|
return testArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,7 +246,7 @@ public final class ParsableByteArrayTest {
|
||||||
ParsableByteArray parsableByteArray = getTestDataArray();
|
ParsableByteArray parsableByteArray = getTestDataArray();
|
||||||
|
|
||||||
// When modifying the wrapped byte array
|
// When modifying the wrapped byte array
|
||||||
byte[] data = parsableByteArray.data;
|
byte[] data = parsableByteArray.getData();
|
||||||
long readValue = parsableByteArray.readUnsignedInt();
|
long readValue = parsableByteArray.readUnsignedInt();
|
||||||
data[0] = (byte) (TEST_DATA[0] + 1);
|
data[0] = (byte) (TEST_DATA[0] + 1);
|
||||||
parsableByteArray.setPosition(0);
|
parsableByteArray.setPosition(0);
|
||||||
|
|
@ -259,7 +259,7 @@ public final class ParsableByteArrayTest {
|
||||||
ParsableByteArray parsableByteArray = getTestDataArray();
|
ParsableByteArray parsableByteArray = getTestDataArray();
|
||||||
|
|
||||||
// Given an array with the most-significant bit set on the top byte
|
// Given an array with the most-significant bit set on the top byte
|
||||||
byte[] data = parsableByteArray.data;
|
byte[] data = parsableByteArray.getData();
|
||||||
data[0] = (byte) 0x80;
|
data[0] = (byte) 0x80;
|
||||||
// Then reading an unsigned long throws.
|
// Then reading an unsigned long throws.
|
||||||
try {
|
try {
|
||||||
|
|
@ -291,7 +291,7 @@ public final class ParsableByteArrayTest {
|
||||||
byte[] copy = new byte[length];
|
byte[] copy = new byte[length];
|
||||||
parsableByteArray.readBytes(copy, 0, length);
|
parsableByteArray.readBytes(copy, 0, length);
|
||||||
// Then the array elements are the same.
|
// Then the array elements are the same.
|
||||||
assertThat(copy).isEqualTo(parsableByteArray.data);
|
assertThat(copy).isEqualTo(parsableByteArray.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -873,7 +873,7 @@ public class UtilTest {
|
||||||
ParsableByteArray output = new ParsableByteArray();
|
ParsableByteArray output = new ParsableByteArray();
|
||||||
assertThat(Util.inflate(input, output, /* inflater= */ null)).isTrue();
|
assertThat(Util.inflate(input, output, /* inflater= */ null)).isTrue();
|
||||||
assertThat(output.limit()).isEqualTo(testData.length);
|
assertThat(output.limit()).isEqualTo(testData.length);
|
||||||
assertThat(Arrays.copyOf(output.data, output.limit())).isEqualTo(testData);
|
assertThat(Arrays.copyOf(output.getData(), output.limit())).isEqualTo(testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Revert to @Config(sdk = Config.ALL_SDKS) once b/143232359 is resolved
|
// TODO: Revert to @Config(sdk = Config.ALL_SDKS) once b/143232359 is resolved
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ import java.util.Arrays;
|
||||||
if (buffer.hasSupplementalData()) {
|
if (buffer.hasSupplementalData()) {
|
||||||
// If there is supplemental data, the sample data is prefixed by its size.
|
// If there is supplemental data, the sample data is prefixed by its size.
|
||||||
scratch.reset(4);
|
scratch.reset(4);
|
||||||
readData(extrasHolder.offset, scratch.data, 4);
|
readData(extrasHolder.offset, scratch.getData(), 4);
|
||||||
int sampleSize = scratch.readUnsignedIntToInt();
|
int sampleSize = scratch.readUnsignedIntToInt();
|
||||||
extrasHolder.offset += 4;
|
extrasHolder.offset += 4;
|
||||||
extrasHolder.size -= 4;
|
extrasHolder.size -= 4;
|
||||||
|
|
@ -223,9 +223,9 @@ import java.util.Arrays;
|
||||||
|
|
||||||
// Read the signal byte.
|
// Read the signal byte.
|
||||||
scratch.reset(1);
|
scratch.reset(1);
|
||||||
readData(offset, scratch.data, 1);
|
readData(offset, scratch.getData(), 1);
|
||||||
offset++;
|
offset++;
|
||||||
byte signalByte = scratch.data[0];
|
byte signalByte = scratch.getData()[0];
|
||||||
boolean subsampleEncryption = (signalByte & 0x80) != 0;
|
boolean subsampleEncryption = (signalByte & 0x80) != 0;
|
||||||
int ivSize = signalByte & 0x7F;
|
int ivSize = signalByte & 0x7F;
|
||||||
|
|
||||||
|
|
@ -244,7 +244,7 @@ import java.util.Arrays;
|
||||||
int subsampleCount;
|
int subsampleCount;
|
||||||
if (subsampleEncryption) {
|
if (subsampleEncryption) {
|
||||||
scratch.reset(2);
|
scratch.reset(2);
|
||||||
readData(offset, scratch.data, 2);
|
readData(offset, scratch.getData(), 2);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
subsampleCount = scratch.readUnsignedShort();
|
subsampleCount = scratch.readUnsignedShort();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -263,7 +263,7 @@ import java.util.Arrays;
|
||||||
if (subsampleEncryption) {
|
if (subsampleEncryption) {
|
||||||
int subsampleDataLength = 6 * subsampleCount;
|
int subsampleDataLength = 6 * subsampleCount;
|
||||||
scratch.reset(subsampleDataLength);
|
scratch.reset(subsampleDataLength);
|
||||||
readData(offset, scratch.data, subsampleDataLength);
|
readData(offset, scratch.getData(), subsampleDataLength);
|
||||||
offset += subsampleDataLength;
|
offset += subsampleDataLength;
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
for (int i = 0; i < subsampleCount; i++) {
|
for (int i = 0; i < subsampleCount; i++) {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
||||||
inflater = new Inflater();
|
inflater = new Inflater();
|
||||||
}
|
}
|
||||||
if (Util.inflate(buffer, inflatedBuffer, inflater)) {
|
if (Util.inflate(buffer, inflatedBuffer, inflater)) {
|
||||||
buffer.reset(inflatedBuffer.data, inflatedBuffer.limit());
|
buffer.reset(inflatedBuffer.getData(), inflatedBuffer.limit());
|
||||||
} // else assume data is not compressed.
|
} // else assume data is not compressed.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +183,7 @@ public final class PgsDecoder extends SimpleSubtitleDecoder {
|
||||||
int limit = bitmapData.limit();
|
int limit = bitmapData.limit();
|
||||||
if (position < limit && sectionLength > 0) {
|
if (position < limit && sectionLength > 0) {
|
||||||
int bytesToRead = Math.min(sectionLength, limit - position);
|
int bytesToRead = Math.min(sectionLength, limit - position);
|
||||||
buffer.readBytes(bitmapData.data, position, bytesToRead);
|
buffer.readBytes(bitmapData.getData(), position, bytesToRead);
|
||||||
bitmapData.setPosition(position + bytesToRead);
|
bitmapData.setPosition(position + bytesToRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ import java.util.regex.Pattern;
|
||||||
stringBuilder.setLength(0);
|
stringBuilder.setLength(0);
|
||||||
int initialInputPosition = input.getPosition();
|
int initialInputPosition = input.getPosition();
|
||||||
skipStyleBlock(input);
|
skipStyleBlock(input);
|
||||||
styleInput.reset(input.data, input.getPosition());
|
styleInput.reset(input.getData(), input.getPosition());
|
||||||
styleInput.setPosition(initialInputPosition);
|
styleInput.setPosition(initialInputPosition);
|
||||||
|
|
||||||
List<WebvttCssStyle> styles = new ArrayList<>();
|
List<WebvttCssStyle> styles = new ArrayList<>();
|
||||||
|
|
@ -154,7 +154,7 @@ import java.util.regex.Pattern;
|
||||||
int limit = input.limit();
|
int limit = input.limit();
|
||||||
boolean cueTargetEndFound = false;
|
boolean cueTargetEndFound = false;
|
||||||
while (position < limit && !cueTargetEndFound) {
|
while (position < limit && !cueTargetEndFound) {
|
||||||
char c = (char) input.data[position++];
|
char c = (char) input.getData()[position++];
|
||||||
cueTargetEndFound = c == ')';
|
cueTargetEndFound = c == ')';
|
||||||
}
|
}
|
||||||
return input.readString(--position - input.getPosition()).trim();
|
return input.readString(--position - input.getPosition()).trim();
|
||||||
|
|
@ -267,7 +267,7 @@ import java.util.regex.Pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static char peekCharAtPosition(ParsableByteArray input, int position) {
|
private static char peekCharAtPosition(ParsableByteArray input, int position) {
|
||||||
return (char) input.data[position];
|
return (char) input.getData()[position];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
@ -297,7 +297,7 @@ import java.util.regex.Pattern;
|
||||||
private static boolean maybeSkipComment(ParsableByteArray input) {
|
private static boolean maybeSkipComment(ParsableByteArray input) {
|
||||||
int position = input.getPosition();
|
int position = input.getPosition();
|
||||||
int limit = input.limit();
|
int limit = input.limit();
|
||||||
byte[] data = input.data;
|
byte[] data = input.getData();
|
||||||
if (position + 2 <= limit && data[position++] == '/' && data[position++] == '*') {
|
if (position + 2 <= limit && data[position++] == '/' && data[position++] == '*') {
|
||||||
while (position + 1 < limit) {
|
while (position + 1 < limit) {
|
||||||
char skippedChar = (char) data[position++];
|
char skippedChar = (char) data[position++];
|
||||||
|
|
@ -320,7 +320,7 @@ import java.util.regex.Pattern;
|
||||||
int limit = input.limit();
|
int limit = input.limit();
|
||||||
boolean identifierEndFound = false;
|
boolean identifierEndFound = false;
|
||||||
while (position < limit && !identifierEndFound) {
|
while (position < limit && !identifierEndFound) {
|
||||||
char c = (char) input.data[position];
|
char c = (char) input.getData()[position];
|
||||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '#'
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '#'
|
||||||
|| c == '-' || c == '.' || c == '_') {
|
|| c == '-' || c == '.' || c == '_') {
|
||||||
position++;
|
position++;
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ public final class Mp4WebvttDecoder extends SimpleSubtitleDecoder {
|
||||||
remainingCueBoxBytes -= BOX_HEADER_SIZE;
|
remainingCueBoxBytes -= BOX_HEADER_SIZE;
|
||||||
int payloadLength = boxSize - BOX_HEADER_SIZE;
|
int payloadLength = boxSize - BOX_HEADER_SIZE;
|
||||||
String boxPayload =
|
String boxPayload =
|
||||||
Util.fromUtf8Bytes(sampleData.data, sampleData.getPosition(), payloadLength);
|
Util.fromUtf8Bytes(sampleData.getData(), sampleData.getPosition(), payloadLength);
|
||||||
sampleData.skipBytes(payloadLength);
|
sampleData.skipBytes(payloadLength);
|
||||||
remainingCueBoxBytes -= payloadLength;
|
remainingCueBoxBytes -= payloadLength;
|
||||||
if (boxType == TYPE_sttg) {
|
if (boxType == TYPE_sttg) {
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ public final class ProjectionDecoder {
|
||||||
final double log2 = Math.log(2.0);
|
final double log2 = Math.log(2.0);
|
||||||
int coordinateCountSizeBits = (int) Math.ceil(Math.log(2.0 * coordinateCount) / log2);
|
int coordinateCountSizeBits = (int) Math.ceil(Math.log(2.0 * coordinateCount) / log2);
|
||||||
|
|
||||||
ParsableBitArray bitInput = new ParsableBitArray(input.data);
|
ParsableBitArray bitInput = new ParsableBitArray(input.getData());
|
||||||
bitInput.setPosition(input.getPosition() * 8);
|
bitInput.setPosition(input.getPosition() * 8);
|
||||||
float[] vertices = new float[vertexCount * 5];
|
float[] vertices = new float[vertexCount * 5];
|
||||||
int[] coordinateIndices = new int[5];
|
int[] coordinateIndices = new int[5];
|
||||||
|
|
|
||||||
|
|
@ -107,10 +107,11 @@ public final class FlacFrameReader {
|
||||||
|
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
frameStartBytes, /* srcPos= */ 0, scratch.data, /* destPos= */ 0, /* length= */ 2);
|
frameStartBytes, /* srcPos= */ 0, scratch.getData(), /* destPos= */ 0, /* length= */ 2);
|
||||||
|
|
||||||
int totalBytesPeeked =
|
int totalBytesPeeked =
|
||||||
ExtractorUtil.peekToLength(input, scratch.data, 2, FlacConstants.MAX_FRAME_HEADER_SIZE - 2);
|
ExtractorUtil.peekToLength(
|
||||||
|
input, scratch.getData(), 2, FlacConstants.MAX_FRAME_HEADER_SIZE - 2);
|
||||||
scratch.setLimit(totalBytesPeeked);
|
scratch.setLimit(totalBytesPeeked);
|
||||||
|
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
|
@ -145,7 +146,7 @@ public final class FlacFrameReader {
|
||||||
int maxUtf8SampleNumberSize = isBlockSizeVariable ? 7 : 6;
|
int maxUtf8SampleNumberSize = isBlockSizeVariable ? 7 : 6;
|
||||||
ParsableByteArray scratch = new ParsableByteArray(maxUtf8SampleNumberSize);
|
ParsableByteArray scratch = new ParsableByteArray(maxUtf8SampleNumberSize);
|
||||||
int totalBytesPeeked =
|
int totalBytesPeeked =
|
||||||
ExtractorUtil.peekToLength(input, scratch.data, 0, maxUtf8SampleNumberSize);
|
ExtractorUtil.peekToLength(input, scratch.getData(), 0, maxUtf8SampleNumberSize);
|
||||||
scratch.setLimit(totalBytesPeeked);
|
scratch.setLimit(totalBytesPeeked);
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
|
||||||
|
|
@ -325,7 +326,7 @@ public final class FlacFrameReader {
|
||||||
int crc = data.readUnsignedByte();
|
int crc = data.readUnsignedByte();
|
||||||
int frameEndPosition = data.getPosition();
|
int frameEndPosition = data.getPosition();
|
||||||
int expectedCrc =
|
int expectedCrc =
|
||||||
Util.crc8(data.data, frameStartPosition, frameEndPosition - 1, /* initialValue= */ 0);
|
Util.crc8(data.getData(), frameStartPosition, frameEndPosition - 1, /* initialValue= */ 0);
|
||||||
return crc == expectedCrc;
|
return crc == expectedCrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public final class FlacMetadataReader {
|
||||||
*/
|
*/
|
||||||
public static boolean checkAndPeekStreamMarker(ExtractorInput input) throws IOException {
|
public static boolean checkAndPeekStreamMarker(ExtractorInput input) throws IOException {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
||||||
input.peekFully(scratch.data, 0, FlacConstants.STREAM_MARKER_SIZE);
|
input.peekFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
|
||||||
return scratch.readUnsignedInt() == STREAM_MARKER;
|
return scratch.readUnsignedInt() == STREAM_MARKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ public final class FlacMetadataReader {
|
||||||
*/
|
*/
|
||||||
public static void readStreamMarker(ExtractorInput input) throws IOException {
|
public static void readStreamMarker(ExtractorInput input) throws IOException {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.STREAM_MARKER_SIZE);
|
||||||
input.readFully(scratch.data, 0, FlacConstants.STREAM_MARKER_SIZE);
|
input.readFully(scratch.getData(), 0, FlacConstants.STREAM_MARKER_SIZE);
|
||||||
if (scratch.readUnsignedInt() != STREAM_MARKER) {
|
if (scratch.readUnsignedInt() != STREAM_MARKER) {
|
||||||
throw new ParserException("Failed to read FLAC stream marker.");
|
throw new ParserException("Failed to read FLAC stream marker.");
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +228,7 @@ public final class FlacMetadataReader {
|
||||||
public static int getFrameStartMarker(ExtractorInput input) throws IOException {
|
public static int getFrameStartMarker(ExtractorInput input) throws IOException {
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
ParsableByteArray scratch = new ParsableByteArray(2);
|
ParsableByteArray scratch = new ParsableByteArray(2);
|
||||||
input.peekFully(scratch.data, 0, 2);
|
input.peekFully(scratch.getData(), 0, 2);
|
||||||
|
|
||||||
int frameStartMarker = scratch.readUnsignedShort();
|
int frameStartMarker = scratch.readUnsignedShort();
|
||||||
int syncCode = frameStartMarker >> 2;
|
int syncCode = frameStartMarker >> 2;
|
||||||
|
|
@ -251,14 +251,14 @@ public final class FlacMetadataReader {
|
||||||
private static FlacStreamMetadata.SeekTable readSeekTableMetadataBlock(
|
private static FlacStreamMetadata.SeekTable readSeekTableMetadataBlock(
|
||||||
ExtractorInput input, int length) throws IOException {
|
ExtractorInput input, int length) throws IOException {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(length);
|
ParsableByteArray scratch = new ParsableByteArray(length);
|
||||||
input.readFully(scratch.data, 0, length);
|
input.readFully(scratch.getData(), 0, length);
|
||||||
return readSeekTableMetadataBlock(scratch);
|
return readSeekTableMetadataBlock(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> readVorbisCommentMetadataBlock(ExtractorInput input, int length)
|
private static List<String> readVorbisCommentMetadataBlock(ExtractorInput input, int length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(length);
|
ParsableByteArray scratch = new ParsableByteArray(length);
|
||||||
input.readFully(scratch.data, 0, length);
|
input.readFully(scratch.getData(), 0, length);
|
||||||
scratch.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
|
scratch.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
|
||||||
CommentHeader commentHeader =
|
CommentHeader commentHeader =
|
||||||
VorbisUtil.readVorbisCommentHeader(
|
VorbisUtil.readVorbisCommentHeader(
|
||||||
|
|
@ -269,7 +269,7 @@ public final class FlacMetadataReader {
|
||||||
private static PictureFrame readPictureMetadataBlock(ExtractorInput input, int length)
|
private static PictureFrame readPictureMetadataBlock(ExtractorInput input, int length)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(length);
|
ParsableByteArray scratch = new ParsableByteArray(length);
|
||||||
input.readFully(scratch.data, 0, length);
|
input.readFully(scratch.getData(), 0, length);
|
||||||
scratch.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
|
scratch.skipBytes(FlacConstants.METADATA_BLOCK_HEADER_SIZE);
|
||||||
|
|
||||||
int pictureType = scratch.readInt();
|
int pictureType = scratch.readInt();
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public final class Id3Peeker {
|
||||||
@Nullable Metadata metadata = null;
|
@Nullable Metadata metadata = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, Id3Decoder.ID3_HEADER_LENGTH);
|
input.peekFully(scratch.getData(), /* offset= */ 0, Id3Decoder.ID3_HEADER_LENGTH);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
// If input has less than ID3_HEADER_LENGTH, ignore the rest.
|
// If input has less than ID3_HEADER_LENGTH, ignore the rest.
|
||||||
break;
|
break;
|
||||||
|
|
@ -68,7 +68,7 @@ public final class Id3Peeker {
|
||||||
|
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
byte[] id3Data = new byte[tagLength];
|
byte[] id3Data = new byte[tagLength];
|
||||||
System.arraycopy(scratch.data, 0, id3Data, 0, Id3Decoder.ID3_HEADER_LENGTH);
|
System.arraycopy(scratch.getData(), 0, id3Data, 0, Id3Decoder.ID3_HEADER_LENGTH);
|
||||||
input.peekFully(id3Data, Id3Decoder.ID3_HEADER_LENGTH, framesLength);
|
input.peekFully(id3Data, Id3Decoder.ID3_HEADER_LENGTH, framesLength);
|
||||||
|
|
||||||
metadata = new Id3Decoder(id3FramePredicate).decode(id3Data, tagLength);
|
metadata = new Id3Decoder(id3FramePredicate).decode(id3Data, tagLength);
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ public final class VorbisUtil {
|
||||||
|
|
||||||
boolean framingFlag = (headerData.readUnsignedByte() & 0x01) > 0;
|
boolean framingFlag = (headerData.readUnsignedByte() & 0x01) > 0;
|
||||||
// raw data of Vorbis setup header has to be passed to decoder as CSD buffer #1
|
// raw data of Vorbis setup header has to be passed to decoder as CSD buffer #1
|
||||||
byte[] data = Arrays.copyOf(headerData.data, headerData.limit());
|
byte[] data = Arrays.copyOf(headerData.getData(), headerData.limit());
|
||||||
|
|
||||||
return new VorbisIdHeader(
|
return new VorbisIdHeader(
|
||||||
version,
|
version,
|
||||||
|
|
@ -309,7 +309,7 @@ public final class VorbisUtil {
|
||||||
|
|
||||||
int numberOfBooks = headerData.readUnsignedByte() + 1;
|
int numberOfBooks = headerData.readUnsignedByte() + 1;
|
||||||
|
|
||||||
VorbisBitArray bitArray = new VorbisBitArray(headerData.data);
|
VorbisBitArray bitArray = new VorbisBitArray(headerData.getData());
|
||||||
bitArray.skipBits(headerData.getPosition() * 8);
|
bitArray.skipBits(headerData.getPosition() * 8);
|
||||||
|
|
||||||
for (int i = 0; i < numberOfBooks; i++) {
|
for (int i = 0; i < numberOfBooks; i++) {
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,9 @@ public final class FlacExtractor implements Extractor {
|
||||||
if (currentLimit < BUFFER_LENGTH) {
|
if (currentLimit < BUFFER_LENGTH) {
|
||||||
int bytesRead =
|
int bytesRead =
|
||||||
input.read(
|
input.read(
|
||||||
buffer.data, /* offset= */ currentLimit, /* length= */ BUFFER_LENGTH - currentLimit);
|
buffer.getData(),
|
||||||
|
/* offset= */ currentLimit,
|
||||||
|
/* length= */ BUFFER_LENGTH - currentLimit);
|
||||||
foundEndOfInput = bytesRead == C.RESULT_END_OF_INPUT;
|
foundEndOfInput = bytesRead == C.RESULT_END_OF_INPUT;
|
||||||
if (!foundEndOfInput) {
|
if (!foundEndOfInput) {
|
||||||
buffer.setLimit(currentLimit + bytesRead);
|
buffer.setLimit(currentLimit + bytesRead);
|
||||||
|
|
@ -300,7 +302,11 @@ public final class FlacExtractor implements Extractor {
|
||||||
// The next frame header may not fit in the rest of the buffer, so put the trailing bytes at
|
// The next frame header may not fit in the rest of the buffer, so put the trailing bytes at
|
||||||
// the start of the buffer, and reset the position and limit.
|
// the start of the buffer, and reset the position and limit.
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
buffer.data, buffer.getPosition(), buffer.data, /* destPos= */ 0, buffer.bytesLeft());
|
buffer.getData(),
|
||||||
|
buffer.getPosition(),
|
||||||
|
buffer.getData(),
|
||||||
|
/* destPos= */ 0,
|
||||||
|
buffer.bytesLeft());
|
||||||
buffer.reset(buffer.bytesLeft());
|
buffer.reset(buffer.bytesLeft());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,21 +98,21 @@ public final class FlvExtractor implements Extractor {
|
||||||
@Override
|
@Override
|
||||||
public boolean sniff(ExtractorInput input) throws IOException {
|
public boolean sniff(ExtractorInput input) throws IOException {
|
||||||
// Check if file starts with "FLV" tag
|
// Check if file starts with "FLV" tag
|
||||||
input.peekFully(scratch.data, 0, 3);
|
input.peekFully(scratch.getData(), 0, 3);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
if (scratch.readUnsignedInt24() != FLV_TAG) {
|
if (scratch.readUnsignedInt24() != FLV_TAG) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking reserved flags are set to 0
|
// Checking reserved flags are set to 0
|
||||||
input.peekFully(scratch.data, 0, 2);
|
input.peekFully(scratch.getData(), 0, 2);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
if ((scratch.readUnsignedShort() & 0xFA) != 0) {
|
if ((scratch.readUnsignedShort() & 0xFA) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read data offset
|
// Read data offset
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int dataOffset = scratch.readInt();
|
int dataOffset = scratch.readInt();
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ public final class FlvExtractor implements Extractor {
|
||||||
input.advancePeekPosition(dataOffset);
|
input.advancePeekPosition(dataOffset);
|
||||||
|
|
||||||
// Checking first "previous tag size" is set to 0
|
// Checking first "previous tag size" is set to 0
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
|
|
||||||
return scratch.readInt() == 0;
|
return scratch.readInt() == 0;
|
||||||
|
|
@ -182,7 +182,7 @@ public final class FlvExtractor implements Extractor {
|
||||||
*/
|
*/
|
||||||
@RequiresNonNull("extractorOutput")
|
@RequiresNonNull("extractorOutput")
|
||||||
private boolean readFlvHeader(ExtractorInput input) throws IOException {
|
private boolean readFlvHeader(ExtractorInput input) throws IOException {
|
||||||
if (!input.readFully(headerBuffer.data, 0, FLV_HEADER_SIZE, true)) {
|
if (!input.readFully(headerBuffer.getData(), 0, FLV_HEADER_SIZE, true)) {
|
||||||
// We've reached the end of the stream.
|
// We've reached the end of the stream.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +228,7 @@ public final class FlvExtractor implements Extractor {
|
||||||
* @throws IOException If an error occurred reading or parsing data from the source.
|
* @throws IOException If an error occurred reading or parsing data from the source.
|
||||||
*/
|
*/
|
||||||
private boolean readTagHeader(ExtractorInput input) throws IOException {
|
private boolean readTagHeader(ExtractorInput input) throws IOException {
|
||||||
if (!input.readFully(tagHeaderBuffer.data, 0, FLV_TAG_HEADER_SIZE, true)) {
|
if (!input.readFully(tagHeaderBuffer.getData(), 0, FLV_TAG_HEADER_SIZE, true)) {
|
||||||
// We've reached the end of the stream.
|
// We've reached the end of the stream.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ public final class FlvExtractor implements Extractor {
|
||||||
tagData.setPosition(0);
|
tagData.setPosition(0);
|
||||||
}
|
}
|
||||||
tagData.setLimit(tagDataSize);
|
tagData.setLimit(tagDataSize);
|
||||||
input.readFully(tagData.data, 0, tagDataSize);
|
input.readFully(tagData.getData(), 0, tagDataSize);
|
||||||
return tagData;
|
return tagData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ import java.util.Map;
|
||||||
int size = data.readUnsignedShort();
|
int size = data.readUnsignedShort();
|
||||||
int position = data.getPosition();
|
int position = data.getPosition();
|
||||||
data.skipBytes(size);
|
data.skipBytes(size);
|
||||||
return new String(data.data, position, size);
|
return new String(data.getData(), position, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ import com.google.android.exoplayer2.video.AvcConfig;
|
||||||
// Parse avc sequence header in case this was not done before.
|
// Parse avc sequence header in case this was not done before.
|
||||||
if (packetType == AVC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
|
if (packetType == AVC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
|
||||||
ParsableByteArray videoSequence = new ParsableByteArray(new byte[data.bytesLeft()]);
|
ParsableByteArray videoSequence = new ParsableByteArray(new byte[data.bytesLeft()]);
|
||||||
data.readBytes(videoSequence.data, 0, data.bytesLeft());
|
data.readBytes(videoSequence.getData(), 0, data.bytesLeft());
|
||||||
AvcConfig avcConfig = AvcConfig.parse(videoSequence);
|
AvcConfig avcConfig = AvcConfig.parse(videoSequence);
|
||||||
nalUnitLengthFieldLength = avcConfig.nalUnitLengthFieldLength;
|
nalUnitLengthFieldLength = avcConfig.nalUnitLengthFieldLength;
|
||||||
// Construct and output the format.
|
// Construct and output the format.
|
||||||
|
|
@ -109,7 +109,7 @@ import com.google.android.exoplayer2.video.AvcConfig;
|
||||||
// TODO: Deduplicate with Mp4Extractor.
|
// TODO: Deduplicate with Mp4Extractor.
|
||||||
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
||||||
// they're only 1 or 2 bytes long.
|
// they're only 1 or 2 bytes long.
|
||||||
byte[] nalLengthData = nalLength.data;
|
byte[] nalLengthData = nalLength.getData();
|
||||||
nalLengthData[0] = 0;
|
nalLengthData[0] = 0;
|
||||||
nalLengthData[1] = 0;
|
nalLengthData[1] = 0;
|
||||||
nalLengthData[2] = 0;
|
nalLengthData[2] = 0;
|
||||||
|
|
@ -121,7 +121,7 @@ import com.google.android.exoplayer2.video.AvcConfig;
|
||||||
int bytesToWrite;
|
int bytesToWrite;
|
||||||
while (data.bytesLeft() > 0) {
|
while (data.bytesLeft() > 0) {
|
||||||
// Read the NAL length so that we know where we find the next one.
|
// Read the NAL length so that we know where we find the next one.
|
||||||
data.readBytes(nalLength.data, nalUnitLengthFieldLengthDiff, nalUnitLengthFieldLength);
|
data.readBytes(nalLength.getData(), nalUnitLengthFieldLengthDiff, nalUnitLengthFieldLength);
|
||||||
nalLength.setPosition(0);
|
nalLength.setPosition(0);
|
||||||
bytesToWrite = nalLength.readUnsignedIntToInt();
|
bytesToWrite = nalLength.readUnsignedIntToInt();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1068,8 +1068,8 @@ public class MatroskaExtractor implements Extractor {
|
||||||
protected void binaryElement(int id, int contentSize, ExtractorInput input) throws IOException {
|
protected void binaryElement(int id, int contentSize, ExtractorInput input) throws IOException {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case ID_SEEK_ID:
|
case ID_SEEK_ID:
|
||||||
Arrays.fill(seekEntryIdBytes.data, (byte) 0);
|
Arrays.fill(seekEntryIdBytes.getData(), (byte) 0);
|
||||||
input.readFully(seekEntryIdBytes.data, 4 - contentSize, contentSize);
|
input.readFully(seekEntryIdBytes.getData(), 4 - contentSize, contentSize);
|
||||||
seekEntryIdBytes.setPosition(0);
|
seekEntryIdBytes.setPosition(0);
|
||||||
seekEntryId = (int) seekEntryIdBytes.readUnsignedInt();
|
seekEntryId = (int) seekEntryIdBytes.readUnsignedInt();
|
||||||
break;
|
break;
|
||||||
|
|
@ -1119,7 +1119,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
if (blockState == BLOCK_STATE_HEADER) {
|
if (blockState == BLOCK_STATE_HEADER) {
|
||||||
// Read the relative timecode (2 bytes) and flags (1 byte).
|
// Read the relative timecode (2 bytes) and flags (1 byte).
|
||||||
readScratch(input, 3);
|
readScratch(input, 3);
|
||||||
int lacing = (scratch.data[2] & 0x06) >> 1;
|
int lacing = (scratch.getData()[2] & 0x06) >> 1;
|
||||||
if (lacing == LACING_NONE) {
|
if (lacing == LACING_NONE) {
|
||||||
blockSampleCount = 1;
|
blockSampleCount = 1;
|
||||||
blockSampleSizes = ensureArrayCapacity(blockSampleSizes, 1);
|
blockSampleSizes = ensureArrayCapacity(blockSampleSizes, 1);
|
||||||
|
|
@ -1127,7 +1127,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
} else {
|
} else {
|
||||||
// Read the sample count (1 byte).
|
// Read the sample count (1 byte).
|
||||||
readScratch(input, 4);
|
readScratch(input, 4);
|
||||||
blockSampleCount = (scratch.data[3] & 0xFF) + 1;
|
blockSampleCount = (scratch.getData()[3] & 0xFF) + 1;
|
||||||
blockSampleSizes = ensureArrayCapacity(blockSampleSizes, blockSampleCount);
|
blockSampleSizes = ensureArrayCapacity(blockSampleSizes, blockSampleCount);
|
||||||
if (lacing == LACING_FIXED_SIZE) {
|
if (lacing == LACING_FIXED_SIZE) {
|
||||||
int blockLacingSampleSize =
|
int blockLacingSampleSize =
|
||||||
|
|
@ -1141,7 +1141,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
int byteValue;
|
int byteValue;
|
||||||
do {
|
do {
|
||||||
readScratch(input, ++headerSize);
|
readScratch(input, ++headerSize);
|
||||||
byteValue = scratch.data[headerSize - 1] & 0xFF;
|
byteValue = scratch.getData()[headerSize - 1] & 0xFF;
|
||||||
blockSampleSizes[sampleIndex] += byteValue;
|
blockSampleSizes[sampleIndex] += byteValue;
|
||||||
} while (byteValue == 0xFF);
|
} while (byteValue == 0xFF);
|
||||||
totalSamplesSize += blockSampleSizes[sampleIndex];
|
totalSamplesSize += blockSampleSizes[sampleIndex];
|
||||||
|
|
@ -1154,20 +1154,20 @@ public class MatroskaExtractor implements Extractor {
|
||||||
for (int sampleIndex = 0; sampleIndex < blockSampleCount - 1; sampleIndex++) {
|
for (int sampleIndex = 0; sampleIndex < blockSampleCount - 1; sampleIndex++) {
|
||||||
blockSampleSizes[sampleIndex] = 0;
|
blockSampleSizes[sampleIndex] = 0;
|
||||||
readScratch(input, ++headerSize);
|
readScratch(input, ++headerSize);
|
||||||
if (scratch.data[headerSize - 1] == 0) {
|
if (scratch.getData()[headerSize - 1] == 0) {
|
||||||
throw new ParserException("No valid varint length mask found");
|
throw new ParserException("No valid varint length mask found");
|
||||||
}
|
}
|
||||||
long readValue = 0;
|
long readValue = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
int lengthMask = 1 << (7 - i);
|
int lengthMask = 1 << (7 - i);
|
||||||
if ((scratch.data[headerSize - 1] & lengthMask) != 0) {
|
if ((scratch.getData()[headerSize - 1] & lengthMask) != 0) {
|
||||||
int readPosition = headerSize - 1;
|
int readPosition = headerSize - 1;
|
||||||
headerSize += i;
|
headerSize += i;
|
||||||
readScratch(input, headerSize);
|
readScratch(input, headerSize);
|
||||||
readValue = (scratch.data[readPosition++] & 0xFF) & ~lengthMask;
|
readValue = (scratch.getData()[readPosition++] & 0xFF) & ~lengthMask;
|
||||||
while (readPosition < headerSize) {
|
while (readPosition < headerSize) {
|
||||||
readValue <<= 8;
|
readValue <<= 8;
|
||||||
readValue |= (scratch.data[readPosition++] & 0xFF);
|
readValue |= (scratch.getData()[readPosition++] & 0xFF);
|
||||||
}
|
}
|
||||||
// The first read value is the first size. Later values are signed offsets.
|
// The first read value is the first size. Later values are signed offsets.
|
||||||
if (sampleIndex > 0) {
|
if (sampleIndex > 0) {
|
||||||
|
|
@ -1194,10 +1194,11 @@ public class MatroskaExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int timecode = (scratch.data[0] << 8) | (scratch.data[1] & 0xFF);
|
int timecode = (scratch.getData()[0] << 8) | (scratch.getData()[1] & 0xFF);
|
||||||
blockTimeUs = clusterTimecodeUs + scaleTimecodeToUs(timecode);
|
blockTimeUs = clusterTimecodeUs + scaleTimecodeToUs(timecode);
|
||||||
boolean isKeyframe = track.type == TRACK_TYPE_AUDIO
|
boolean isKeyframe =
|
||||||
|| (id == ID_SIMPLE_BLOCK && (scratch.data[2] & 0x80) == 0x80);
|
track.type == TRACK_TYPE_AUDIO
|
||||||
|
|| (id == ID_SIMPLE_BLOCK && (scratch.getData()[2] & 0x80) == 0x80);
|
||||||
blockFlags = isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
blockFlags = isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||||
blockState = BLOCK_STATE_DATA;
|
blockState = BLOCK_STATE_DATA;
|
||||||
blockSampleIndex = 0;
|
blockSampleIndex = 0;
|
||||||
|
|
@ -1246,7 +1247,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
if (blockAdditionalId == BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
|
if (blockAdditionalId == BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
|
||||||
&& CODEC_ID_VP9.equals(track.codecId)) {
|
&& CODEC_ID_VP9.equals(track.codecId)) {
|
||||||
blockAdditionalData.reset(contentSize);
|
blockAdditionalData.reset(contentSize);
|
||||||
input.readFully(blockAdditionalData.data, 0, contentSize);
|
input.readFully(blockAdditionalData.getData(), 0, contentSize);
|
||||||
} else {
|
} else {
|
||||||
// Unhandled block additional data.
|
// Unhandled block additional data.
|
||||||
input.skipFully(contentSize);
|
input.skipFully(contentSize);
|
||||||
|
|
@ -1264,7 +1265,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
} else if (blockDurationUs == C.TIME_UNSET) {
|
} else if (blockDurationUs == C.TIME_UNSET) {
|
||||||
Log.w(TAG, "Skipping subtitle sample with no duration.");
|
Log.w(TAG, "Skipping subtitle sample with no duration.");
|
||||||
} else {
|
} else {
|
||||||
setSubtitleEndTime(track.codecId, blockDurationUs, subtitleSample.data);
|
setSubtitleEndTime(track.codecId, blockDurationUs, subtitleSample.getData());
|
||||||
// Note: If we ever want to support DRM protected subtitles then we'll need to output the
|
// Note: If we ever want to support DRM protected subtitles then we'll need to output the
|
||||||
// appropriate encryption data here.
|
// appropriate encryption data here.
|
||||||
track.output.sampleData(subtitleSample, subtitleSample.limit());
|
track.output.sampleData(subtitleSample, subtitleSample.limit());
|
||||||
|
|
@ -1299,10 +1300,11 @@ public class MatroskaExtractor implements Extractor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scratch.capacity() < requiredLength) {
|
if (scratch.capacity() < requiredLength) {
|
||||||
scratch.reset(Arrays.copyOf(scratch.data, Math.max(scratch.data.length * 2, requiredLength)),
|
scratch.reset(
|
||||||
|
Arrays.copyOf(scratch.getData(), Math.max(scratch.getData().length * 2, requiredLength)),
|
||||||
scratch.limit());
|
scratch.limit());
|
||||||
}
|
}
|
||||||
input.readFully(scratch.data, scratch.limit(), requiredLength - scratch.limit());
|
input.readFully(scratch.getData(), scratch.limit(), requiredLength - scratch.limit());
|
||||||
scratch.setLimit(requiredLength);
|
scratch.setLimit(requiredLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1331,12 +1333,12 @@ public class MatroskaExtractor implements Extractor {
|
||||||
// Clear the encrypted flag.
|
// Clear the encrypted flag.
|
||||||
blockFlags &= ~C.BUFFER_FLAG_ENCRYPTED;
|
blockFlags &= ~C.BUFFER_FLAG_ENCRYPTED;
|
||||||
if (!sampleSignalByteRead) {
|
if (!sampleSignalByteRead) {
|
||||||
input.readFully(scratch.data, 0, 1);
|
input.readFully(scratch.getData(), 0, 1);
|
||||||
sampleBytesRead++;
|
sampleBytesRead++;
|
||||||
if ((scratch.data[0] & 0x80) == 0x80) {
|
if ((scratch.getData()[0] & 0x80) == 0x80) {
|
||||||
throw new ParserException("Extension bit is set in signal byte");
|
throw new ParserException("Extension bit is set in signal byte");
|
||||||
}
|
}
|
||||||
sampleSignalByte = scratch.data[0];
|
sampleSignalByte = scratch.getData()[0];
|
||||||
sampleSignalByteRead = true;
|
sampleSignalByteRead = true;
|
||||||
}
|
}
|
||||||
boolean isEncrypted = (sampleSignalByte & 0x01) == 0x01;
|
boolean isEncrypted = (sampleSignalByte & 0x01) == 0x01;
|
||||||
|
|
@ -1344,11 +1346,12 @@ public class MatroskaExtractor implements Extractor {
|
||||||
boolean hasSubsampleEncryption = (sampleSignalByte & 0x02) == 0x02;
|
boolean hasSubsampleEncryption = (sampleSignalByte & 0x02) == 0x02;
|
||||||
blockFlags |= C.BUFFER_FLAG_ENCRYPTED;
|
blockFlags |= C.BUFFER_FLAG_ENCRYPTED;
|
||||||
if (!sampleInitializationVectorRead) {
|
if (!sampleInitializationVectorRead) {
|
||||||
input.readFully(encryptionInitializationVector.data, 0, ENCRYPTION_IV_SIZE);
|
input.readFully(encryptionInitializationVector.getData(), 0, ENCRYPTION_IV_SIZE);
|
||||||
sampleBytesRead += ENCRYPTION_IV_SIZE;
|
sampleBytesRead += ENCRYPTION_IV_SIZE;
|
||||||
sampleInitializationVectorRead = true;
|
sampleInitializationVectorRead = true;
|
||||||
// Write the signal byte, containing the IV size and the subsample encryption flag.
|
// Write the signal byte, containing the IV size and the subsample encryption flag.
|
||||||
scratch.data[0] = (byte) (ENCRYPTION_IV_SIZE | (hasSubsampleEncryption ? 0x80 : 0x00));
|
scratch.getData()[0] =
|
||||||
|
(byte) (ENCRYPTION_IV_SIZE | (hasSubsampleEncryption ? 0x80 : 0x00));
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
output.sampleData(scratch, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION);
|
output.sampleData(scratch, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION);
|
||||||
sampleBytesWritten++;
|
sampleBytesWritten++;
|
||||||
|
|
@ -1362,7 +1365,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
if (hasSubsampleEncryption) {
|
if (hasSubsampleEncryption) {
|
||||||
if (!samplePartitionCountRead) {
|
if (!samplePartitionCountRead) {
|
||||||
input.readFully(scratch.data, 0, 1);
|
input.readFully(scratch.getData(), 0, 1);
|
||||||
sampleBytesRead++;
|
sampleBytesRead++;
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
samplePartitionCount = scratch.readUnsignedByte();
|
samplePartitionCount = scratch.readUnsignedByte();
|
||||||
|
|
@ -1370,7 +1373,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
int samplePartitionDataSize = samplePartitionCount * 4;
|
int samplePartitionDataSize = samplePartitionCount * 4;
|
||||||
scratch.reset(samplePartitionDataSize);
|
scratch.reset(samplePartitionDataSize);
|
||||||
input.readFully(scratch.data, 0, samplePartitionDataSize);
|
input.readFully(scratch.getData(), 0, samplePartitionDataSize);
|
||||||
sampleBytesRead += samplePartitionDataSize;
|
sampleBytesRead += samplePartitionDataSize;
|
||||||
short subsampleCount = (short) (1 + (samplePartitionCount / 2));
|
short subsampleCount = (short) (1 + (samplePartitionCount / 2));
|
||||||
int subsampleDataSize = 2 + 6 * subsampleCount;
|
int subsampleDataSize = 2 + 6 * subsampleCount;
|
||||||
|
|
@ -1423,10 +1426,10 @@ public class MatroskaExtractor implements Extractor {
|
||||||
// If there is supplemental data, the structure of the sample data is:
|
// If there is supplemental data, the structure of the sample data is:
|
||||||
// sample size (4 bytes) || sample data || supplemental data
|
// sample size (4 bytes) || sample data || supplemental data
|
||||||
scratch.reset(/* limit= */ 4);
|
scratch.reset(/* limit= */ 4);
|
||||||
scratch.data[0] = (byte) ((size >> 24) & 0xFF);
|
scratch.getData()[0] = (byte) ((size >> 24) & 0xFF);
|
||||||
scratch.data[1] = (byte) ((size >> 16) & 0xFF);
|
scratch.getData()[1] = (byte) ((size >> 16) & 0xFF);
|
||||||
scratch.data[2] = (byte) ((size >> 8) & 0xFF);
|
scratch.getData()[2] = (byte) ((size >> 8) & 0xFF);
|
||||||
scratch.data[3] = (byte) (size & 0xFF);
|
scratch.getData()[3] = (byte) (size & 0xFF);
|
||||||
output.sampleData(scratch, 4, TrackOutput.SAMPLE_DATA_PART_SUPPLEMENTAL);
|
output.sampleData(scratch, 4, TrackOutput.SAMPLE_DATA_PART_SUPPLEMENTAL);
|
||||||
sampleBytesWritten += 4;
|
sampleBytesWritten += 4;
|
||||||
}
|
}
|
||||||
|
|
@ -1440,7 +1443,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
|
|
||||||
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
||||||
// they're only 1 or 2 bytes long.
|
// they're only 1 or 2 bytes long.
|
||||||
byte[] nalLengthData = nalLength.data;
|
byte[] nalLengthData = nalLength.getData();
|
||||||
nalLengthData[0] = 0;
|
nalLengthData[0] = 0;
|
||||||
nalLengthData[1] = 0;
|
nalLengthData[1] = 0;
|
||||||
nalLengthData[2] = 0;
|
nalLengthData[2] = 0;
|
||||||
|
|
@ -1526,11 +1529,11 @@ public class MatroskaExtractor implements Extractor {
|
||||||
if (subtitleSample.capacity() < sizeWithPrefix) {
|
if (subtitleSample.capacity() < sizeWithPrefix) {
|
||||||
// Initialize subripSample to contain the required prefix and have space to hold a subtitle
|
// Initialize subripSample to contain the required prefix and have space to hold a subtitle
|
||||||
// twice as long as this one.
|
// twice as long as this one.
|
||||||
subtitleSample.data = Arrays.copyOf(samplePrefix, sizeWithPrefix + size);
|
subtitleSample.reset(Arrays.copyOf(samplePrefix, sizeWithPrefix + size));
|
||||||
} else {
|
} else {
|
||||||
System.arraycopy(samplePrefix, 0, subtitleSample.data, 0, samplePrefix.length);
|
System.arraycopy(samplePrefix, 0, subtitleSample.getData(), 0, samplePrefix.length);
|
||||||
}
|
}
|
||||||
input.readFully(subtitleSample.data, samplePrefix.length, size);
|
input.readFully(subtitleSample.getData(), samplePrefix.length, size);
|
||||||
subtitleSample.reset(sizeWithPrefix);
|
subtitleSample.reset(sizeWithPrefix);
|
||||||
// Defer writing the data to the track output. We need to modify the sample data by setting
|
// Defer writing the data to the track output. We need to modify the sample data by setting
|
||||||
// the correct end timecode, which we might not have yet.
|
// the correct end timecode, which we might not have yet.
|
||||||
|
|
@ -2243,7 +2246,7 @@ public class MatroskaExtractor implements Extractor {
|
||||||
// Search for the initialization data from the end of the BITMAPINFOHEADER. The last 20
|
// Search for the initialization data from the end of the BITMAPINFOHEADER. The last 20
|
||||||
// bytes of which are: sizeImage(4), xPel/m (4), yPel/m (4), clrUsed(4), clrImportant(4).
|
// bytes of which are: sizeImage(4), xPel/m (4), yPel/m (4), clrUsed(4), clrImportant(4).
|
||||||
int startOffset = buffer.getPosition() + 20;
|
int startOffset = buffer.getPosition() + 20;
|
||||||
byte[] bufferData = buffer.data;
|
byte[] bufferData = buffer.getData();
|
||||||
for (int offset = startOffset; offset < bufferData.length - 4; offset++) {
|
for (int offset = startOffset; offset < bufferData.length - 4; offset++) {
|
||||||
if (bufferData[offset] == 0x00
|
if (bufferData[offset] == 0x00
|
||||||
&& bufferData[offset + 1] == 0x00
|
&& bufferData[offset + 1] == 0x00
|
||||||
|
|
|
||||||
|
|
@ -45,16 +45,16 @@ import java.io.IOException;
|
||||||
int bytesToSearch = (int) (inputLength == C.LENGTH_UNSET || inputLength > SEARCH_LENGTH
|
int bytesToSearch = (int) (inputLength == C.LENGTH_UNSET || inputLength > SEARCH_LENGTH
|
||||||
? SEARCH_LENGTH : inputLength);
|
? SEARCH_LENGTH : inputLength);
|
||||||
// Find four bytes equal to ID_EBML near the start of the input.
|
// Find four bytes equal to ID_EBML near the start of the input.
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
long tag = scratch.readUnsignedInt();
|
long tag = scratch.readUnsignedInt();
|
||||||
peekLength = 4;
|
peekLength = 4;
|
||||||
while (tag != ID_EBML) {
|
while (tag != ID_EBML) {
|
||||||
if (++peekLength == bytesToSearch) {
|
if (++peekLength == bytesToSearch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
input.peekFully(scratch.data, 0, 1);
|
input.peekFully(scratch.getData(), 0, 1);
|
||||||
tag = (tag << 8) & 0xFFFFFF00;
|
tag = (tag << 8) & 0xFFFFFF00;
|
||||||
tag |= scratch.data[0] & 0xFF;
|
tag |= scratch.getData()[0] & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the size of the EBML header and make sure it is within the stream.
|
// Read the size of the EBML header and make sure it is within the stream.
|
||||||
|
|
@ -86,8 +86,8 @@ import java.io.IOException;
|
||||||
|
|
||||||
/** Peeks a variable-length unsigned EBML integer from the input. */
|
/** Peeks a variable-length unsigned EBML integer from the input. */
|
||||||
private long readUint(ExtractorInput input) throws IOException {
|
private long readUint(ExtractorInput input) throws IOException {
|
||||||
input.peekFully(scratch.data, 0, 1);
|
input.peekFully(scratch.getData(), 0, 1);
|
||||||
int value = scratch.data[0] & 0xFF;
|
int value = scratch.getData()[0] & 0xFF;
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
return Long.MIN_VALUE;
|
return Long.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
@ -98,10 +98,10 @@ import java.io.IOException;
|
||||||
length++;
|
length++;
|
||||||
}
|
}
|
||||||
value &= ~mask;
|
value &= ~mask;
|
||||||
input.peekFully(scratch.data, 1, length);
|
input.peekFully(scratch.getData(), 1, length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
value <<= 8;
|
value <<= 8;
|
||||||
value += scratch.data[i + 1] & 0xFF;
|
value += scratch.getData()[i + 1] & 0xFF;
|
||||||
}
|
}
|
||||||
peekLength += length + 1;
|
peekLength += length + 1;
|
||||||
return value;
|
return value;
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ public final class Mp3Extractor implements Extractor {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return !extractorInput.peekFully(
|
return !extractorInput.peekFully(
|
||||||
scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true);
|
scratch.getData(), /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -471,7 +471,7 @@ public final class Mp3Extractor implements Extractor {
|
||||||
@Nullable
|
@Nullable
|
||||||
private Seeker maybeReadSeekFrame(ExtractorInput input) throws IOException {
|
private Seeker maybeReadSeekFrame(ExtractorInput input) throws IOException {
|
||||||
ParsableByteArray frame = new ParsableByteArray(synchronizedHeader.frameSize);
|
ParsableByteArray frame = new ParsableByteArray(synchronizedHeader.frameSize);
|
||||||
input.peekFully(frame.data, 0, synchronizedHeader.frameSize);
|
input.peekFully(frame.getData(), 0, synchronizedHeader.frameSize);
|
||||||
int xingBase = (synchronizedHeader.version & 1) != 0
|
int xingBase = (synchronizedHeader.version & 1) != 0
|
||||||
? (synchronizedHeader.channels != 1 ? 36 : 21) // MPEG 1
|
? (synchronizedHeader.channels != 1 ? 36 : 21) // MPEG 1
|
||||||
: (synchronizedHeader.channels != 1 ? 21 : 13); // MPEG 2 or 2.5
|
: (synchronizedHeader.channels != 1 ? 21 : 13); // MPEG 2 or 2.5
|
||||||
|
|
@ -483,7 +483,7 @@ public final class Mp3Extractor implements Extractor {
|
||||||
// If there is a Xing header, read gapless playback metadata at a fixed offset.
|
// If there is a Xing header, read gapless playback metadata at a fixed offset.
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
input.advancePeekPosition(xingBase + 141);
|
input.advancePeekPosition(xingBase + 141);
|
||||||
input.peekFully(scratch.data, 0, 3);
|
input.peekFully(scratch.getData(), 0, 3);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
gaplessInfoHolder.setFromXingHeaderValue(scratch.readUnsignedInt24());
|
gaplessInfoHolder.setFromXingHeaderValue(scratch.readUnsignedInt24());
|
||||||
}
|
}
|
||||||
|
|
@ -505,7 +505,7 @@ public final class Mp3Extractor implements Extractor {
|
||||||
|
|
||||||
/** Peeks the next frame and returns a {@link ConstantBitrateSeeker} based on its bitrate. */
|
/** Peeks the next frame and returns a {@link ConstantBitrateSeeker} based on its bitrate. */
|
||||||
private Seeker getConstantBitrateSeeker(ExtractorInput input) throws IOException {
|
private Seeker getConstantBitrateSeeker(ExtractorInput input) throws IOException {
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
synchronizedHeader.setForHeaderData(scratch.readInt());
|
synchronizedHeader.setForHeaderData(scratch.readInt());
|
||||||
return new ConstantBitrateSeeker(input.getLength(), input.getPosition(), synchronizedHeader);
|
return new ConstantBitrateSeeker(input.getLength(), input.getPosition(), synchronizedHeader);
|
||||||
|
|
|
||||||
|
|
@ -729,7 +729,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
int durationPosition = tkhd.getPosition();
|
int durationPosition = tkhd.getPosition();
|
||||||
int durationByteCount = version == 0 ? 4 : 8;
|
int durationByteCount = version == 0 ? 4 : 8;
|
||||||
for (int i = 0; i < durationByteCount; i++) {
|
for (int i = 0; i < durationByteCount; i++) {
|
||||||
if (tkhd.data[durationPosition + i] != -1) {
|
if (tkhd.getData()[durationPosition + i] != -1) {
|
||||||
durationUnknown = false;
|
durationUnknown = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1513,7 +1513,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
int childAtomSize = parent.readInt();
|
int childAtomSize = parent.readInt();
|
||||||
int childAtomType = parent.readInt();
|
int childAtomType = parent.readInt();
|
||||||
if (childAtomType == Atom.TYPE_proj) {
|
if (childAtomType == Atom.TYPE_proj) {
|
||||||
return Arrays.copyOfRange(parent.data, childPosition, childPosition + childAtomSize);
|
return Arrays.copyOfRange(parent.getData(), childPosition, childPosition + childAtomSize);
|
||||||
}
|
}
|
||||||
childPosition += childAtomSize;
|
childPosition += childAtomSize;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
private boolean readAtomHeader(ExtractorInput input) throws IOException {
|
private boolean readAtomHeader(ExtractorInput input) throws IOException {
|
||||||
if (atomHeaderBytesRead == 0) {
|
if (atomHeaderBytesRead == 0) {
|
||||||
// Read the standard length atom header.
|
// Read the standard length atom header.
|
||||||
if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
|
if (!input.readFully(atomHeader.getData(), 0, Atom.HEADER_SIZE, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
atomHeaderBytesRead = Atom.HEADER_SIZE;
|
atomHeaderBytesRead = Atom.HEADER_SIZE;
|
||||||
|
|
@ -358,7 +358,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
||||||
// Read the large size.
|
// Read the large size.
|
||||||
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
|
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
|
||||||
input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
|
input.readFully(atomHeader.getData(), Atom.HEADER_SIZE, headerBytesRemaining);
|
||||||
atomHeaderBytesRead += headerBytesRemaining;
|
atomHeaderBytesRead += headerBytesRemaining;
|
||||||
atomSize = atomHeader.readUnsignedLongToLong();
|
atomSize = atomHeader.readUnsignedLongToLong();
|
||||||
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
||||||
|
|
@ -421,7 +421,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
|
throw new ParserException("Leaf atom with length > 2147483647 (unsupported).");
|
||||||
}
|
}
|
||||||
atomData = new ParsableByteArray((int) atomSize);
|
atomData = new ParsableByteArray((int) atomSize);
|
||||||
System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
|
System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
|
||||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||||
} else {
|
} else {
|
||||||
if (atomSize > Integer.MAX_VALUE) {
|
if (atomSize > Integer.MAX_VALUE) {
|
||||||
|
|
@ -437,7 +437,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
private void readAtomPayload(ExtractorInput input) throws IOException {
|
private void readAtomPayload(ExtractorInput input) throws IOException {
|
||||||
int atomPayloadSize = (int) atomSize - atomHeaderBytesRead;
|
int atomPayloadSize = (int) atomSize - atomHeaderBytesRead;
|
||||||
if (atomData != null) {
|
if (atomData != null) {
|
||||||
input.readFully(atomData.data, Atom.HEADER_SIZE, atomPayloadSize);
|
input.readFully(atomData.getData(), Atom.HEADER_SIZE, atomPayloadSize);
|
||||||
onLeafAtomRead(new LeafAtom(atomType, atomData), input.getPosition());
|
onLeafAtomRead(new LeafAtom(atomType, atomData), input.getPosition());
|
||||||
} else {
|
} else {
|
||||||
input.skipFully(atomPayloadSize);
|
input.skipFully(atomPayloadSize);
|
||||||
|
|
@ -1330,7 +1330,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
if (track.nalUnitLengthFieldLength != 0) {
|
if (track.nalUnitLengthFieldLength != 0) {
|
||||||
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
||||||
// they're only 1 or 2 bytes long.
|
// they're only 1 or 2 bytes long.
|
||||||
byte[] nalPrefixData = nalPrefix.data;
|
byte[] nalPrefixData = nalPrefix.getData();
|
||||||
nalPrefixData[0] = 0;
|
nalPrefixData[0] = 0;
|
||||||
nalPrefixData[1] = 0;
|
nalPrefixData[1] = 0;
|
||||||
nalPrefixData[2] = 0;
|
nalPrefixData[2] = 0;
|
||||||
|
|
@ -1364,11 +1364,12 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
if (processSeiNalUnitPayload) {
|
if (processSeiNalUnitPayload) {
|
||||||
// Read and write the payload of the SEI NAL unit.
|
// Read and write the payload of the SEI NAL unit.
|
||||||
nalBuffer.reset(sampleCurrentNalBytesRemaining);
|
nalBuffer.reset(sampleCurrentNalBytesRemaining);
|
||||||
input.readFully(nalBuffer.data, 0, sampleCurrentNalBytesRemaining);
|
input.readFully(nalBuffer.getData(), 0, sampleCurrentNalBytesRemaining);
|
||||||
output.sampleData(nalBuffer, sampleCurrentNalBytesRemaining);
|
output.sampleData(nalBuffer, sampleCurrentNalBytesRemaining);
|
||||||
writtenBytes = sampleCurrentNalBytesRemaining;
|
writtenBytes = sampleCurrentNalBytesRemaining;
|
||||||
// Unescape and process the SEI NAL unit.
|
// Unescape and process the SEI NAL unit.
|
||||||
int unescapedLength = NalUnitUtil.unescapeStream(nalBuffer.data, nalBuffer.limit());
|
int unescapedLength =
|
||||||
|
NalUnitUtil.unescapeStream(nalBuffer.getData(), nalBuffer.limit());
|
||||||
// If the format is H.265/HEVC the NAL unit header has two bytes so skip one more byte.
|
// If the format is H.265/HEVC the NAL unit header has two bytes so skip one more byte.
|
||||||
nalBuffer.setPosition(MimeTypes.VIDEO_H265.equals(track.format.sampleMimeType) ? 1 : 0);
|
nalBuffer.setPosition(MimeTypes.VIDEO_H265.equals(track.format.sampleMimeType) ? 1 : 0);
|
||||||
nalBuffer.setLimit(unescapedLength);
|
nalBuffer.setLimit(unescapedLength);
|
||||||
|
|
@ -1466,7 +1467,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
if (schemeDatas == null) {
|
if (schemeDatas == null) {
|
||||||
schemeDatas = new ArrayList<>();
|
schemeDatas = new ArrayList<>();
|
||||||
}
|
}
|
||||||
byte[] psshData = child.data.data;
|
byte[] psshData = child.data.getData();
|
||||||
@Nullable UUID uuid = PsshAtomUtil.parseUuid(psshData);
|
@Nullable UUID uuid = PsshAtomUtil.parseUuid(psshData);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
Log.w(TAG, "Skipped pssh atom (failed to extract uuid)");
|
Log.w(TAG, "Skipped pssh atom (failed to extract uuid)");
|
||||||
|
|
@ -1706,7 +1707,7 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
boolean writeSubsampleEncryptionData = haveSubsampleEncryptionTable || clearHeaderSize != 0;
|
boolean writeSubsampleEncryptionData = haveSubsampleEncryptionTable || clearHeaderSize != 0;
|
||||||
|
|
||||||
// Write the signal byte, containing the vector size and the subsample encryption flag.
|
// Write the signal byte, containing the vector size and the subsample encryption flag.
|
||||||
encryptionSignalByte.data[0] =
|
encryptionSignalByte.getData()[0] =
|
||||||
(byte) (vectorSize | (writeSubsampleEncryptionData ? 0x80 : 0));
|
(byte) (vectorSize | (writeSubsampleEncryptionData ? 0x80 : 0));
|
||||||
encryptionSignalByte.setPosition(0);
|
encryptionSignalByte.setPosition(0);
|
||||||
output.sampleData(encryptionSignalByte, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION);
|
output.sampleData(encryptionSignalByte, 1, TrackOutput.SAMPLE_DATA_PART_ENCRYPTION);
|
||||||
|
|
@ -1724,16 +1725,17 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
// into account.
|
// into account.
|
||||||
scratch.reset(SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH);
|
scratch.reset(SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH);
|
||||||
// subsampleCount = 1 (unsigned short)
|
// subsampleCount = 1 (unsigned short)
|
||||||
scratch.data[0] = (byte) 0;
|
byte[] data = scratch.getData();
|
||||||
scratch.data[1] = (byte) 1;
|
data[0] = (byte) 0;
|
||||||
|
data[1] = (byte) 1;
|
||||||
// clearDataSize = clearHeaderSize (unsigned short)
|
// clearDataSize = clearHeaderSize (unsigned short)
|
||||||
scratch.data[2] = (byte) ((clearHeaderSize >> 8) & 0xFF);
|
data[2] = (byte) ((clearHeaderSize >> 8) & 0xFF);
|
||||||
scratch.data[3] = (byte) (clearHeaderSize & 0xFF);
|
data[3] = (byte) (clearHeaderSize & 0xFF);
|
||||||
// encryptedDataSize = sampleSize (unsigned int)
|
// encryptedDataSize = sampleSize (unsigned int)
|
||||||
scratch.data[4] = (byte) ((sampleSize >> 24) & 0xFF);
|
data[4] = (byte) ((sampleSize >> 24) & 0xFF);
|
||||||
scratch.data[5] = (byte) ((sampleSize >> 16) & 0xFF);
|
data[5] = (byte) ((sampleSize >> 16) & 0xFF);
|
||||||
scratch.data[6] = (byte) ((sampleSize >> 8) & 0xFF);
|
data[6] = (byte) ((sampleSize >> 8) & 0xFF);
|
||||||
scratch.data[7] = (byte) (sampleSize & 0xFF);
|
data[7] = (byte) (sampleSize & 0xFF);
|
||||||
output.sampleData(
|
output.sampleData(
|
||||||
scratch,
|
scratch,
|
||||||
SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH,
|
SINGLE_SUBSAMPLE_ENCRYPTION_DATA_LENGTH,
|
||||||
|
|
@ -1750,13 +1752,14 @@ public class FragmentedMp4Extractor implements Extractor {
|
||||||
// We need to account for the additional clear header by adding clearHeaderSize to
|
// We need to account for the additional clear header by adding clearHeaderSize to
|
||||||
// clearDataSize for the first subsample specified in the subsample encryption data.
|
// clearDataSize for the first subsample specified in the subsample encryption data.
|
||||||
scratch.reset(subsampleDataLength);
|
scratch.reset(subsampleDataLength);
|
||||||
scratch.readBytes(subsampleEncryptionData.data, /* offset= */ 0, subsampleDataLength);
|
scratch.readBytes(subsampleEncryptionData.getData(), /* offset= */ 0, subsampleDataLength);
|
||||||
subsampleEncryptionData.skipBytes(subsampleDataLength);
|
subsampleEncryptionData.skipBytes(subsampleDataLength);
|
||||||
|
|
||||||
int clearDataSize = (scratch.data[2] & 0xFF) << 8 | (scratch.data[3] & 0xFF);
|
byte[] data = scratch.getData();
|
||||||
|
int clearDataSize = (data[2] & 0xFF) << 8 | (data[3] & 0xFF);
|
||||||
int adjustedClearDataSize = clearDataSize + clearHeaderSize;
|
int adjustedClearDataSize = clearDataSize + clearHeaderSize;
|
||||||
scratch.data[2] = (byte) ((adjustedClearDataSize >> 8) & 0xFF);
|
data[2] = (byte) ((adjustedClearDataSize >> 8) & 0xFF);
|
||||||
scratch.data[3] = (byte) (adjustedClearDataSize & 0xFF);
|
data[3] = (byte) (adjustedClearDataSize & 0xFF);
|
||||||
subsampleEncryptionData = scratch;
|
subsampleEncryptionData = scratch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -277,7 +277,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
private boolean readAtomHeader(ExtractorInput input) throws IOException {
|
private boolean readAtomHeader(ExtractorInput input) throws IOException {
|
||||||
if (atomHeaderBytesRead == 0) {
|
if (atomHeaderBytesRead == 0) {
|
||||||
// Read the standard length atom header.
|
// Read the standard length atom header.
|
||||||
if (!input.readFully(atomHeader.data, 0, Atom.HEADER_SIZE, true)) {
|
if (!input.readFully(atomHeader.getData(), 0, Atom.HEADER_SIZE, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
atomHeaderBytesRead = Atom.HEADER_SIZE;
|
atomHeaderBytesRead = Atom.HEADER_SIZE;
|
||||||
|
|
@ -289,7 +289,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
||||||
// Read the large size.
|
// Read the large size.
|
||||||
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
|
int headerBytesRemaining = Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE;
|
||||||
input.readFully(atomHeader.data, Atom.HEADER_SIZE, headerBytesRemaining);
|
input.readFully(atomHeader.getData(), Atom.HEADER_SIZE, headerBytesRemaining);
|
||||||
atomHeaderBytesRead += headerBytesRemaining;
|
atomHeaderBytesRead += headerBytesRemaining;
|
||||||
atomSize = atomHeader.readUnsignedLongToLong();
|
atomSize = atomHeader.readUnsignedLongToLong();
|
||||||
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
||||||
|
|
@ -329,7 +329,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
|
Assertions.checkState(atomHeaderBytesRead == Atom.HEADER_SIZE);
|
||||||
Assertions.checkState(atomSize <= Integer.MAX_VALUE);
|
Assertions.checkState(atomSize <= Integer.MAX_VALUE);
|
||||||
ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
|
ParsableByteArray atomData = new ParsableByteArray((int) atomSize);
|
||||||
System.arraycopy(atomHeader.data, 0, atomData.data, 0, Atom.HEADER_SIZE);
|
System.arraycopy(atomHeader.getData(), 0, atomData.getData(), 0, Atom.HEADER_SIZE);
|
||||||
this.atomData = atomData;
|
this.atomData = atomData;
|
||||||
parserState = STATE_READING_ATOM_PAYLOAD;
|
parserState = STATE_READING_ATOM_PAYLOAD;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -352,7 +352,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
boolean seekRequired = false;
|
boolean seekRequired = false;
|
||||||
@Nullable ParsableByteArray atomData = this.atomData;
|
@Nullable ParsableByteArray atomData = this.atomData;
|
||||||
if (atomData != null) {
|
if (atomData != null) {
|
||||||
input.readFully(atomData.data, atomHeaderBytesRead, (int) atomPayloadSize);
|
input.readFully(atomData.getData(), atomHeaderBytesRead, (int) atomPayloadSize);
|
||||||
if (atomType == Atom.TYPE_ftyp) {
|
if (atomType == Atom.TYPE_ftyp) {
|
||||||
isQuickTime = processFtypAtom(atomData);
|
isQuickTime = processFtypAtom(atomData);
|
||||||
} else if (!containerAtoms.isEmpty()) {
|
} else if (!containerAtoms.isEmpty()) {
|
||||||
|
|
@ -509,7 +509,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
if (track.track.nalUnitLengthFieldLength != 0) {
|
if (track.track.nalUnitLengthFieldLength != 0) {
|
||||||
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
// Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
|
||||||
// they're only 1 or 2 bytes long.
|
// they're only 1 or 2 bytes long.
|
||||||
byte[] nalLengthData = nalLength.data;
|
byte[] nalLengthData = nalLength.getData();
|
||||||
nalLengthData[0] = 0;
|
nalLengthData[0] = 0;
|
||||||
nalLengthData[1] = 0;
|
nalLengthData[1] = 0;
|
||||||
nalLengthData[2] = 0;
|
nalLengthData[2] = 0;
|
||||||
|
|
@ -651,7 +651,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||||
// (iso) [1 byte version + 3 bytes flags][4 byte size of next atom]
|
// (iso) [1 byte version + 3 bytes flags][4 byte size of next atom]
|
||||||
// (qt) [4 byte size of next atom ][4 byte hdlr atom type ]
|
// (qt) [4 byte size of next atom ][4 byte hdlr atom type ]
|
||||||
// In case of (iso) we need to skip the next 4 bytes.
|
// In case of (iso) we need to skip the next 4 bytes.
|
||||||
input.peekFully(scratch.data, 0, 8);
|
input.peekFully(scratch.getData(), 0, 8);
|
||||||
scratch.skipBytes(4);
|
scratch.skipBytes(4);
|
||||||
if (scratch.readInt() == Atom.TYPE_hdlr) {
|
if (scratch.readInt() == Atom.TYPE_hdlr) {
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
|
|
||||||
|
|
@ -99,13 +99,14 @@ import java.io.IOException;
|
||||||
// Read an atom header.
|
// Read an atom header.
|
||||||
int headerSize = Atom.HEADER_SIZE;
|
int headerSize = Atom.HEADER_SIZE;
|
||||||
buffer.reset(headerSize);
|
buffer.reset(headerSize);
|
||||||
input.peekFully(buffer.data, 0, headerSize);
|
input.peekFully(buffer.getData(), 0, headerSize);
|
||||||
long atomSize = buffer.readUnsignedInt();
|
long atomSize = buffer.readUnsignedInt();
|
||||||
int atomType = buffer.readInt();
|
int atomType = buffer.readInt();
|
||||||
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
if (atomSize == Atom.DEFINES_LARGE_SIZE) {
|
||||||
// Read the large atom size.
|
// Read the large atom size.
|
||||||
headerSize = Atom.LONG_HEADER_SIZE;
|
headerSize = Atom.LONG_HEADER_SIZE;
|
||||||
input.peekFully(buffer.data, Atom.HEADER_SIZE, Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE);
|
input.peekFully(
|
||||||
|
buffer.getData(), Atom.HEADER_SIZE, Atom.LONG_HEADER_SIZE - Atom.HEADER_SIZE);
|
||||||
buffer.setLimit(Atom.LONG_HEADER_SIZE);
|
buffer.setLimit(Atom.LONG_HEADER_SIZE);
|
||||||
atomSize = buffer.readLong();
|
atomSize = buffer.readLong();
|
||||||
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
} else if (atomSize == Atom.EXTENDS_TO_END_SIZE) {
|
||||||
|
|
@ -153,7 +154,7 @@ import java.io.IOException;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buffer.reset(atomDataSize);
|
buffer.reset(atomDataSize);
|
||||||
input.peekFully(buffer.data, 0, atomDataSize);
|
input.peekFully(buffer.getData(), 0, atomDataSize);
|
||||||
int brandsCount = atomDataSize / 4;
|
int brandsCount = atomDataSize / 4;
|
||||||
for (int i = 0; i < brandsCount; i++) {
|
for (int i = 0; i < brandsCount; i++) {
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
* @param input An {@link ExtractorInput} from which to read the encryption data.
|
* @param input An {@link ExtractorInput} from which to read the encryption data.
|
||||||
*/
|
*/
|
||||||
public void fillEncryptionData(ExtractorInput input) throws IOException {
|
public void fillEncryptionData(ExtractorInput input) throws IOException {
|
||||||
input.readFully(sampleEncryptionData.data, 0, sampleEncryptionData.limit());
|
input.readFully(sampleEncryptionData.getData(), 0, sampleEncryptionData.limit());
|
||||||
sampleEncryptionData.setPosition(0);
|
sampleEncryptionData.setPosition(0);
|
||||||
sampleEncryptionDataNeedsFill = false;
|
sampleEncryptionDataNeedsFill = false;
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +185,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
* @param source A source from which to read the encryption data.
|
* @param source A source from which to read the encryption data.
|
||||||
*/
|
*/
|
||||||
public void fillEncryptionData(ParsableByteArray source) {
|
public void fillEncryptionData(ParsableByteArray source) {
|
||||||
source.readBytes(sampleEncryptionData.data, 0, sampleEncryptionData.limit());
|
source.readBytes(sampleEncryptionData.getData(), 0, sampleEncryptionData.limit());
|
||||||
sampleEncryptionData.setPosition(0);
|
sampleEncryptionData.setPosition(0);
|
||||||
sampleEncryptionDataNeedsFill = false;
|
sampleEncryptionDataNeedsFill = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ import java.util.Arrays;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected long preparePayload(ParsableByteArray packet) {
|
protected long preparePayload(ParsableByteArray packet) {
|
||||||
if (!isAudioPacket(packet.data)) {
|
if (!isAudioPacket(packet.getData())) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return getFlacFrameBlockSize(packet);
|
return getFlacFrameBlockSize(packet);
|
||||||
|
|
@ -69,7 +69,7 @@ import java.util.Arrays;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) {
|
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) {
|
||||||
byte[] data = packet.data;
|
byte[] data = packet.getData();
|
||||||
@Nullable FlacStreamMetadata streamMetadata = this.streamMetadata;
|
@Nullable FlacStreamMetadata streamMetadata = this.streamMetadata;
|
||||||
if (streamMetadata == null) {
|
if (streamMetadata == null) {
|
||||||
streamMetadata = new FlacStreamMetadata(data, 17);
|
streamMetadata = new FlacStreamMetadata(data, 17);
|
||||||
|
|
@ -92,7 +92,7 @@ import java.util.Arrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getFlacFrameBlockSize(ParsableByteArray packet) {
|
private int getFlacFrameBlockSize(ParsableByteArray packet) {
|
||||||
int blockSizeKey = (packet.data[2] & 0xFF) >> 4;
|
int blockSizeKey = (packet.getData()[2] & 0xFF) >> 4;
|
||||||
if (blockSizeKey == 6 || blockSizeKey == 7) {
|
if (blockSizeKey == 6 || blockSizeKey == 7) {
|
||||||
// Skip the sample number.
|
// Skip the sample number.
|
||||||
packet.skipBytes(FRAME_HEADER_SAMPLE_NUMBER_OFFSET);
|
packet.skipBytes(FRAME_HEADER_SAMPLE_NUMBER_OFFSET);
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ public class OggExtractor implements Extractor {
|
||||||
|
|
||||||
int length = Math.min(header.bodySize, MAX_VERIFICATION_BYTES);
|
int length = Math.min(header.bodySize, MAX_VERIFICATION_BYTES);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(length);
|
ParsableByteArray scratch = new ParsableByteArray(length);
|
||||||
input.peekFully(scratch.data, 0, length);
|
input.peekFully(scratch.getData(), 0, length);
|
||||||
|
|
||||||
if (FlacReader.verifyBitstreamType(resetPosition(scratch))) {
|
if (FlacReader.verifyBitstreamType(resetPosition(scratch))) {
|
||||||
streamReader = new FlacReader();
|
streamReader = new FlacReader();
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,9 @@ import java.util.Arrays;
|
||||||
int segmentIndex = currentSegmentIndex + segmentCount;
|
int segmentIndex = currentSegmentIndex + segmentCount;
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
if (packetArray.capacity() < packetArray.limit() + size) {
|
if (packetArray.capacity() < packetArray.limit() + size) {
|
||||||
packetArray.data = Arrays.copyOf(packetArray.data, packetArray.limit() + size);
|
packetArray.reset(Arrays.copyOf(packetArray.getData(), packetArray.limit() + size));
|
||||||
}
|
}
|
||||||
input.readFully(packetArray.data, packetArray.limit(), size);
|
input.readFully(packetArray.getData(), packetArray.limit(), size);
|
||||||
packetArray.setLimit(packetArray.limit() + size);
|
packetArray.setLimit(packetArray.limit() + size);
|
||||||
populated = pageHeader.laces[segmentIndex - 1] != 255;
|
populated = pageHeader.laces[segmentIndex - 1] != 255;
|
||||||
}
|
}
|
||||||
|
|
@ -124,11 +124,12 @@ import java.util.Arrays;
|
||||||
* Trims the packet data array.
|
* Trims the packet data array.
|
||||||
*/
|
*/
|
||||||
public void trimPayload() {
|
public void trimPayload() {
|
||||||
if (packetArray.data.length == OggPageHeader.MAX_PAGE_PAYLOAD) {
|
if (packetArray.getData().length == OggPageHeader.MAX_PAGE_PAYLOAD) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
packetArray.data = Arrays.copyOf(packetArray.data, Math.max(OggPageHeader.MAX_PAGE_PAYLOAD,
|
packetArray.reset(
|
||||||
packetArray.limit()));
|
Arrays.copyOf(
|
||||||
|
packetArray.getData(), Math.max(OggPageHeader.MAX_PAGE_PAYLOAD, packetArray.limit())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ import java.io.IOException;
|
||||||
public boolean skipToNextPage(ExtractorInput input, long limit) throws IOException {
|
public boolean skipToNextPage(ExtractorInput input, long limit) throws IOException {
|
||||||
Assertions.checkArgument(input.getPosition() == input.getPeekPosition());
|
Assertions.checkArgument(input.getPosition() == input.getPeekPosition());
|
||||||
while ((limit == C.POSITION_UNSET || input.getPosition() + CAPTURE_PATTERN_SIZE < limit)
|
while ((limit == C.POSITION_UNSET || input.getPosition() + CAPTURE_PATTERN_SIZE < limit)
|
||||||
&& peekSafely(input, scratch.data, 0, CAPTURE_PATTERN_SIZE, /* quiet= */ true)) {
|
&& peekSafely(input, scratch.getData(), 0, CAPTURE_PATTERN_SIZE, /* quiet= */ true)) {
|
||||||
scratch.reset();
|
scratch.reset();
|
||||||
if (scratch.readUnsignedInt() == CAPTURE_PATTERN) {
|
if (scratch.readUnsignedInt() == CAPTURE_PATTERN) {
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
|
@ -133,7 +133,7 @@ import java.io.IOException;
|
||||||
public boolean populate(ExtractorInput input, boolean quiet) throws IOException {
|
public boolean populate(ExtractorInput input, boolean quiet) throws IOException {
|
||||||
reset();
|
reset();
|
||||||
scratch.reset();
|
scratch.reset();
|
||||||
if (!peekSafely(input, scratch.data, 0, EMPTY_PAGE_HEADER_SIZE, quiet)
|
if (!peekSafely(input, scratch.getData(), 0, EMPTY_PAGE_HEADER_SIZE, quiet)
|
||||||
|| scratch.readUnsignedInt() != CAPTURE_PATTERN) {
|
|| scratch.readUnsignedInt() != CAPTURE_PATTERN) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
// calculate total size of header including laces
|
// calculate total size of header including laces
|
||||||
scratch.reset();
|
scratch.reset();
|
||||||
input.peekFully(scratch.data, 0, pageSegmentCount);
|
input.peekFully(scratch.getData(), 0, pageSegmentCount);
|
||||||
for (int i = 0; i < pageSegmentCount; i++) {
|
for (int i = 0; i < pageSegmentCount; i++) {
|
||||||
laces[i] = scratch.readUnsignedByte();
|
laces[i] = scratch.readUnsignedByte();
|
||||||
bodySize += laces[i];
|
bodySize += laces[i];
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,13 @@ import java.util.List;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected long preparePayload(ParsableByteArray packet) {
|
protected long preparePayload(ParsableByteArray packet) {
|
||||||
return convertTimeToGranule(getPacketDurationUs(packet.data));
|
return convertTimeToGranule(getPacketDurationUs(packet.getData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) {
|
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) {
|
||||||
if (!headerRead) {
|
if (!headerRead) {
|
||||||
byte[] metadata = Arrays.copyOf(packet.data, packet.limit());
|
byte[] metadata = Arrays.copyOf(packet.getData(), packet.limit());
|
||||||
int channelCount = metadata[9] & 0xFF;
|
int channelCount = metadata[9] & 0xFF;
|
||||||
int preskip = ((metadata[11] & 0xFF) << 8) | (metadata[10] & 0xFF);
|
int preskip = ((metadata[11] & 0xFF) << 8) | (metadata[10] & 0xFF);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,12 @@ import java.util.ArrayList;
|
||||||
@Override
|
@Override
|
||||||
protected long preparePayload(ParsableByteArray packet) {
|
protected long preparePayload(ParsableByteArray packet) {
|
||||||
// if this is not an audio packet...
|
// if this is not an audio packet...
|
||||||
if ((packet.data[0] & 0x01) == 1) {
|
if ((packet.getData()[0] & 0x01) == 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... we need to decode the block size
|
// ... we need to decode the block size
|
||||||
int packetBlockSize = decodeBlockSize(packet.data[0], vorbisSetup);
|
int packetBlockSize = decodeBlockSize(packet.getData()[0], vorbisSetup);
|
||||||
// a packet contains samples produced from overlapping the previous and current frame data
|
// a packet contains samples produced from overlapping the previous and current frame data
|
||||||
// (https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-350001.3.2)
|
// (https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-350001.3.2)
|
||||||
int samplesInPacket = seenFirstAudioPacket ? (packetBlockSize + previousPacketBlockSize) / 4
|
int samplesInPacket = seenFirstAudioPacket ? (packetBlockSize + previousPacketBlockSize) / 4
|
||||||
|
|
@ -134,7 +134,7 @@ import java.util.ArrayList;
|
||||||
// the third packet contains the setup header
|
// the third packet contains the setup header
|
||||||
byte[] setupHeaderData = new byte[scratch.limit()];
|
byte[] setupHeaderData = new byte[scratch.limit()];
|
||||||
// raw data of vorbis setup header has to be passed to decoder as CSD buffer #2
|
// raw data of vorbis setup header has to be passed to decoder as CSD buffer #2
|
||||||
System.arraycopy(scratch.data, 0, setupHeaderData, 0, scratch.limit());
|
System.arraycopy(scratch.getData(), 0, setupHeaderData, 0, scratch.limit());
|
||||||
// partially decode setup header to get the modes
|
// partially decode setup header to get the modes
|
||||||
Mode[] modes = VorbisUtil.readVorbisModes(scratch, vorbisIdHeader.channels);
|
Mode[] modes = VorbisUtil.readVorbisModes(scratch, vorbisIdHeader.channels);
|
||||||
// we need the ilog of modes all the time when extracting, so we compute it once
|
// we need the ilog of modes all the time when extracting, so we compute it once
|
||||||
|
|
@ -164,10 +164,11 @@ import java.util.ArrayList;
|
||||||
buffer.setLimit(buffer.limit() + 4);
|
buffer.setLimit(buffer.limit() + 4);
|
||||||
// The vorbis decoder expects the number of samples in the packet
|
// The vorbis decoder expects the number of samples in the packet
|
||||||
// to be appended to the audio data as an int32
|
// to be appended to the audio data as an int32
|
||||||
buffer.data[buffer.limit() - 4] = (byte) (packetSampleCount & 0xFF);
|
byte[] data = buffer.getData();
|
||||||
buffer.data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
|
data[buffer.limit() - 4] = (byte) (packetSampleCount & 0xFF);
|
||||||
buffer.data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
|
data[buffer.limit() - 3] = (byte) ((packetSampleCount >>> 8) & 0xFF);
|
||||||
buffer.data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
|
data[buffer.limit() - 2] = (byte) ((packetSampleCount >>> 16) & 0xFF);
|
||||||
|
data[buffer.limit() - 1] = (byte) ((packetSampleCount >>> 24) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int decodeBlockSize(byte firstByteOfAudioPacket, VorbisSetup vorbisSetup) {
|
private static int decodeBlockSize(byte firstByteOfAudioPacket, VorbisSetup vorbisSetup) {
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ public final class RawCcExtractor implements Extractor {
|
||||||
@Override
|
@Override
|
||||||
public boolean sniff(ExtractorInput input) throws IOException {
|
public boolean sniff(ExtractorInput input) throws IOException {
|
||||||
dataScratch.reset();
|
dataScratch.reset();
|
||||||
input.peekFully(dataScratch.data, 0, HEADER_SIZE);
|
input.peekFully(dataScratch.getData(), 0, HEADER_SIZE);
|
||||||
return dataScratch.readInt() == HEADER_ID;
|
return dataScratch.readInt() == HEADER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +119,7 @@ public final class RawCcExtractor implements Extractor {
|
||||||
|
|
||||||
private boolean parseHeader(ExtractorInput input) throws IOException {
|
private boolean parseHeader(ExtractorInput input) throws IOException {
|
||||||
dataScratch.reset();
|
dataScratch.reset();
|
||||||
if (input.readFully(dataScratch.data, 0, HEADER_SIZE, true)) {
|
if (input.readFully(dataScratch.getData(), 0, HEADER_SIZE, true)) {
|
||||||
if (dataScratch.readInt() != HEADER_ID) {
|
if (dataScratch.readInt() != HEADER_ID) {
|
||||||
throw new IOException("Input not RawCC");
|
throw new IOException("Input not RawCC");
|
||||||
}
|
}
|
||||||
|
|
@ -134,13 +134,13 @@ public final class RawCcExtractor implements Extractor {
|
||||||
private boolean parseTimestampAndSampleCount(ExtractorInput input) throws IOException {
|
private boolean parseTimestampAndSampleCount(ExtractorInput input) throws IOException {
|
||||||
dataScratch.reset();
|
dataScratch.reset();
|
||||||
if (version == 0) {
|
if (version == 0) {
|
||||||
if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V0 + 1, true)) {
|
if (!input.readFully(dataScratch.getData(), 0, TIMESTAMP_SIZE_V0 + 1, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// version 0 timestamps are 45kHz, so we need to convert them into us
|
// version 0 timestamps are 45kHz, so we need to convert them into us
|
||||||
timestampUs = dataScratch.readUnsignedInt() * 1000 / 45;
|
timestampUs = dataScratch.readUnsignedInt() * 1000 / 45;
|
||||||
} else if (version == 1) {
|
} else if (version == 1) {
|
||||||
if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V1 + 1, true)) {
|
if (!input.readFully(dataScratch.getData(), 0, TIMESTAMP_SIZE_V1 + 1, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
timestampUs = dataScratch.readLong();
|
timestampUs = dataScratch.readLong();
|
||||||
|
|
@ -157,7 +157,7 @@ public final class RawCcExtractor implements Extractor {
|
||||||
private void parseSamples(ExtractorInput input) throws IOException {
|
private void parseSamples(ExtractorInput input) throws IOException {
|
||||||
for (; remainingSampleCount > 0; remainingSampleCount--) {
|
for (; remainingSampleCount > 0; remainingSampleCount--) {
|
||||||
dataScratch.reset();
|
dataScratch.reset();
|
||||||
input.readFully(dataScratch.data, 0, 3);
|
input.readFully(dataScratch.getData(), 0, 3);
|
||||||
|
|
||||||
trackOutput.sampleData(dataScratch, 3);
|
trackOutput.sampleData(dataScratch, 3);
|
||||||
sampleBytesWritten += 3;
|
sampleBytesWritten += 3;
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public final class Ac3Extractor implements Extractor {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
ParsableByteArray scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
||||||
int startPosition = 0;
|
int startPosition = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, ID3_HEADER_LENGTH);
|
input.peekFully(scratch.getData(), /* offset= */ 0, ID3_HEADER_LENGTH);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -82,7 +82,7 @@ public final class Ac3Extractor implements Extractor {
|
||||||
int headerPosition = startPosition;
|
int headerPosition = startPosition;
|
||||||
int validFramesCount = 0;
|
int validFramesCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, 0, 6);
|
input.peekFully(scratch.getData(), 0, 6);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int syncBytes = scratch.readUnsignedShort();
|
int syncBytes = scratch.readUnsignedShort();
|
||||||
if (syncBytes != AC3_SYNC_WORD) {
|
if (syncBytes != AC3_SYNC_WORD) {
|
||||||
|
|
@ -96,7 +96,7 @@ public final class Ac3Extractor implements Extractor {
|
||||||
if (++validFramesCount >= 4) {
|
if (++validFramesCount >= 4) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int frameSize = Ac3Util.parseAc3SyncframeSize(scratch.data);
|
int frameSize = Ac3Util.parseAc3SyncframeSize(scratch.getData());
|
||||||
if (frameSize == C.LENGTH_UNSET) {
|
if (frameSize == C.LENGTH_UNSET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +125,7 @@ public final class Ac3Extractor implements Extractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
||||||
int bytesRead = input.read(sampleData.data, 0, MAX_SYNC_FRAME_SIZE);
|
int bytesRead = input.read(sampleData.getData(), 0, MAX_SYNC_FRAME_SIZE);
|
||||||
if (bytesRead == C.RESULT_END_OF_INPUT) {
|
if (bytesRead == C.RESULT_END_OF_INPUT) {
|
||||||
return RESULT_END_OF_INPUT;
|
return RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,13 +117,13 @@ public final class Ac3Reader implements ElementaryStreamReader {
|
||||||
case STATE_FINDING_SYNC:
|
case STATE_FINDING_SYNC:
|
||||||
if (skipToNextSync(data)) {
|
if (skipToNextSync(data)) {
|
||||||
state = STATE_READING_HEADER;
|
state = STATE_READING_HEADER;
|
||||||
headerScratchBytes.data[0] = 0x0B;
|
headerScratchBytes.getData()[0] = 0x0B;
|
||||||
headerScratchBytes.data[1] = 0x77;
|
headerScratchBytes.getData()[1] = 0x77;
|
||||||
bytesRead = 2;
|
bytesRead = 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_HEADER:
|
||||||
if (continueRead(data, headerScratchBytes.data, HEADER_SIZE)) {
|
if (continueRead(data, headerScratchBytes.getData(), HEADER_SIZE)) {
|
||||||
parseHeader();
|
parseHeader();
|
||||||
headerScratchBytes.setPosition(0);
|
headerScratchBytes.setPosition(0);
|
||||||
output.sampleData(headerScratchBytes, HEADER_SIZE);
|
output.sampleData(headerScratchBytes, HEADER_SIZE);
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ public final class Ac4Extractor implements Extractor {
|
||||||
ParsableByteArray scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
ParsableByteArray scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
||||||
int startPosition = 0;
|
int startPosition = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, ID3_HEADER_LENGTH);
|
input.peekFully(scratch.getData(), /* offset= */ 0, ID3_HEADER_LENGTH);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -89,7 +89,7 @@ public final class Ac4Extractor implements Extractor {
|
||||||
int headerPosition = startPosition;
|
int headerPosition = startPosition;
|
||||||
int validFramesCount = 0;
|
int validFramesCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, /* length= */ FRAME_HEADER_SIZE);
|
input.peekFully(scratch.getData(), /* offset= */ 0, /* length= */ FRAME_HEADER_SIZE);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int syncBytes = scratch.readUnsignedShort();
|
int syncBytes = scratch.readUnsignedShort();
|
||||||
if (syncBytes != AC40_SYNCWORD && syncBytes != AC41_SYNCWORD) {
|
if (syncBytes != AC40_SYNCWORD && syncBytes != AC41_SYNCWORD) {
|
||||||
|
|
@ -103,7 +103,7 @@ public final class Ac4Extractor implements Extractor {
|
||||||
if (++validFramesCount >= 4) {
|
if (++validFramesCount >= 4) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int frameSize = Ac4Util.parseAc4SyncframeSize(scratch.data, syncBytes);
|
int frameSize = Ac4Util.parseAc4SyncframeSize(scratch.getData(), syncBytes);
|
||||||
if (frameSize == C.LENGTH_UNSET) {
|
if (frameSize == C.LENGTH_UNSET) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,8 @@ public final class Ac4Extractor implements Extractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
||||||
int bytesRead = input.read(sampleData.data, /* offset= */ 0, /* length= */ READ_BUFFER_SIZE);
|
int bytesRead =
|
||||||
|
input.read(sampleData.getData(), /* offset= */ 0, /* length= */ READ_BUFFER_SIZE);
|
||||||
if (bytesRead == C.RESULT_END_OF_INPUT) {
|
if (bytesRead == C.RESULT_END_OF_INPUT) {
|
||||||
return RESULT_END_OF_INPUT;
|
return RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,13 +116,13 @@ public final class Ac4Reader implements ElementaryStreamReader {
|
||||||
case STATE_FINDING_SYNC:
|
case STATE_FINDING_SYNC:
|
||||||
if (skipToNextSync(data)) {
|
if (skipToNextSync(data)) {
|
||||||
state = STATE_READING_HEADER;
|
state = STATE_READING_HEADER;
|
||||||
headerScratchBytes.data[0] = (byte) 0xAC;
|
headerScratchBytes.getData()[0] = (byte) 0xAC;
|
||||||
headerScratchBytes.data[1] = (byte) (hasCRC ? 0x41 : 0x40);
|
headerScratchBytes.getData()[1] = (byte) (hasCRC ? 0x41 : 0x40);
|
||||||
bytesRead = 2;
|
bytesRead = 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_HEADER:
|
||||||
if (continueRead(data, headerScratchBytes.data, Ac4Util.HEADER_SIZE_FOR_PARSER)) {
|
if (continueRead(data, headerScratchBytes.getData(), Ac4Util.HEADER_SIZE_FOR_PARSER)) {
|
||||||
parseHeader();
|
parseHeader();
|
||||||
headerScratchBytes.setPosition(0);
|
headerScratchBytes.setPosition(0);
|
||||||
output.sampleData(headerScratchBytes, Ac4Util.HEADER_SIZE_FOR_PARSER);
|
output.sampleData(headerScratchBytes, Ac4Util.HEADER_SIZE_FOR_PARSER);
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
firstFramePosition = C.POSITION_UNSET;
|
firstFramePosition = C.POSITION_UNSET;
|
||||||
// Allocate scratch space for an ID3 header. The same buffer is also used to read 4 byte values.
|
// Allocate scratch space for an ID3 header. The same buffer is also used to read 4 byte values.
|
||||||
scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
scratch = new ParsableByteArray(ID3_HEADER_LENGTH);
|
||||||
scratchBits = new ParsableBitArray(scratch.data);
|
scratchBits = new ParsableBitArray(scratch.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extractor implementation.
|
// Extractor implementation.
|
||||||
|
|
@ -129,7 +129,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
int totalValidFramesSize = 0;
|
int totalValidFramesSize = 0;
|
||||||
int validFramesCount = 0;
|
int validFramesCount = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, 0, 2);
|
input.peekFully(scratch.getData(), 0, 2);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int syncBytes = scratch.readUnsignedShort();
|
int syncBytes = scratch.readUnsignedShort();
|
||||||
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
|
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
|
||||||
|
|
@ -146,7 +146,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip the frame.
|
// Skip the frame.
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratchBits.setPosition(14);
|
scratchBits.setPosition(14);
|
||||||
int frameSize = scratchBits.readBits(13);
|
int frameSize = scratchBits.readBits(13);
|
||||||
// Either the stream is malformed OR we're not parsing an ADTS stream.
|
// Either the stream is malformed OR we're not parsing an ADTS stream.
|
||||||
|
|
@ -189,7 +189,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
calculateAverageFrameSize(input);
|
calculateAverageFrameSize(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bytesRead = input.read(packetBuffer.data, 0, MAX_PACKET_SIZE);
|
int bytesRead = input.read(packetBuffer.getData(), 0, MAX_PACKET_SIZE);
|
||||||
boolean readEndOfStream = bytesRead == RESULT_END_OF_INPUT;
|
boolean readEndOfStream = bytesRead == RESULT_END_OF_INPUT;
|
||||||
maybeOutputSeekMap(inputLength, canUseConstantBitrateSeeking, readEndOfStream);
|
maybeOutputSeekMap(inputLength, canUseConstantBitrateSeeking, readEndOfStream);
|
||||||
if (readEndOfStream) {
|
if (readEndOfStream) {
|
||||||
|
|
@ -214,7 +214,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
private int peekId3Header(ExtractorInput input) throws IOException {
|
private int peekId3Header(ExtractorInput input) throws IOException {
|
||||||
int firstFramePosition = 0;
|
int firstFramePosition = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, ID3_HEADER_LENGTH);
|
input.peekFully(scratch.getData(), /* offset= */ 0, ID3_HEADER_LENGTH);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
if (scratch.readUnsignedInt24() != ID3_TAG) {
|
||||||
break;
|
break;
|
||||||
|
|
@ -270,7 +270,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
long totalValidFramesSize = 0;
|
long totalValidFramesSize = 0;
|
||||||
try {
|
try {
|
||||||
while (input.peekFully(
|
while (input.peekFully(
|
||||||
scratch.data, /* offset= */ 0, /* length= */ 2, /* allowEndOfInput= */ true)) {
|
scratch.getData(), /* offset= */ 0, /* length= */ 2, /* allowEndOfInput= */ true)) {
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int syncBytes = scratch.readUnsignedShort();
|
int syncBytes = scratch.readUnsignedShort();
|
||||||
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
|
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
|
||||||
|
|
@ -281,7 +281,7 @@ public final class AdtsExtractor implements Extractor {
|
||||||
} else {
|
} else {
|
||||||
// Read the frame size.
|
// Read the frame size.
|
||||||
if (!input.peekFully(
|
if (!input.peekFully(
|
||||||
scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true)) {
|
scratch.getData(), /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
scratchBits.setPosition(14);
|
scratchBits.setPosition(14);
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
||||||
findNextSample(data);
|
findNextSample(data);
|
||||||
break;
|
break;
|
||||||
case STATE_READING_ID3_HEADER:
|
case STATE_READING_ID3_HEADER:
|
||||||
if (continueRead(data, id3HeaderBuffer.data, ID3_HEADER_SIZE)) {
|
if (continueRead(data, id3HeaderBuffer.getData(), ID3_HEADER_SIZE)) {
|
||||||
parseId3Header();
|
parseId3Header();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -277,7 +277,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
||||||
* @param pesBuffer The buffer whose position should be advanced.
|
* @param pesBuffer The buffer whose position should be advanced.
|
||||||
*/
|
*/
|
||||||
private void findNextSample(ParsableByteArray pesBuffer) {
|
private void findNextSample(ParsableByteArray pesBuffer) {
|
||||||
byte[] adtsData = pesBuffer.data;
|
byte[] adtsData = pesBuffer.getData();
|
||||||
int position = pesBuffer.getPosition();
|
int position = pesBuffer.getPosition();
|
||||||
int endOffset = pesBuffer.limit();
|
int endOffset = pesBuffer.limit();
|
||||||
while (position < endOffset) {
|
while (position < endOffset) {
|
||||||
|
|
@ -335,7 +335,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Peek the next byte of buffer into scratch array.
|
// Peek the next byte of buffer into scratch array.
|
||||||
adtsScratch.data[0] = buffer.data[buffer.getPosition()];
|
adtsScratch.data[0] = buffer.getData()[buffer.getPosition()];
|
||||||
|
|
||||||
adtsScratch.setPosition(2);
|
adtsScratch.setPosition(2);
|
||||||
int currentFrameSampleRateIndex = adtsScratch.readBits(4);
|
int currentFrameSampleRateIndex = adtsScratch.readBits(4);
|
||||||
|
|
@ -416,7 +416,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
||||||
|
|
||||||
// The bytes following the frame must be either another SYNC word with the same MPEG version, or
|
// The bytes following the frame must be either another SYNC word with the same MPEG version, or
|
||||||
// the start of an ID3 header.
|
// the start of an ID3 header.
|
||||||
byte[] data = pesBuffer.data;
|
byte[] data = pesBuffer.getData();
|
||||||
int dataLimit = pesBuffer.limit();
|
int dataLimit = pesBuffer.limit();
|
||||||
int nextSyncPosition = syncPositionCandidate + frameSize;
|
int nextSyncPosition = syncPositionCandidate + frameSize;
|
||||||
if (nextSyncPosition >= dataLimit) {
|
if (nextSyncPosition >= dataLimit) {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_HEADER:
|
||||||
if (continueRead(data, headerScratchBytes.data, HEADER_SIZE)) {
|
if (continueRead(data, headerScratchBytes.getData(), HEADER_SIZE)) {
|
||||||
parseHeader();
|
parseHeader();
|
||||||
headerScratchBytes.setPosition(0);
|
headerScratchBytes.setPosition(0);
|
||||||
output.sampleData(headerScratchBytes, HEADER_SIZE);
|
output.sampleData(headerScratchBytes, HEADER_SIZE);
|
||||||
|
|
@ -155,10 +155,11 @@ public final class DtsReader implements ElementaryStreamReader {
|
||||||
syncBytes <<= 8;
|
syncBytes <<= 8;
|
||||||
syncBytes |= pesBuffer.readUnsignedByte();
|
syncBytes |= pesBuffer.readUnsignedByte();
|
||||||
if (DtsUtil.isSyncWord(syncBytes)) {
|
if (DtsUtil.isSyncWord(syncBytes)) {
|
||||||
headerScratchBytes.data[0] = (byte) ((syncBytes >> 24) & 0xFF);
|
byte[] headerData = headerScratchBytes.getData();
|
||||||
headerScratchBytes.data[1] = (byte) ((syncBytes >> 16) & 0xFF);
|
headerData[0] = (byte) ((syncBytes >> 24) & 0xFF);
|
||||||
headerScratchBytes.data[2] = (byte) ((syncBytes >> 8) & 0xFF);
|
headerData[1] = (byte) ((syncBytes >> 16) & 0xFF);
|
||||||
headerScratchBytes.data[3] = (byte) (syncBytes & 0xFF);
|
headerData[2] = (byte) ((syncBytes >> 8) & 0xFF);
|
||||||
|
headerData[3] = (byte) (syncBytes & 0xFF);
|
||||||
bytesRead = 4;
|
bytesRead = 4;
|
||||||
syncBytes = 0;
|
syncBytes = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -170,7 +171,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
||||||
/** Parses the sample header. */
|
/** Parses the sample header. */
|
||||||
@RequiresNonNull("output")
|
@RequiresNonNull("output")
|
||||||
private void parseHeader() {
|
private void parseHeader() {
|
||||||
byte[] frameData = headerScratchBytes.data;
|
byte[] frameData = headerScratchBytes.getData();
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
format = DtsUtil.parseDtsFormat(frameData, formatId, language, null);
|
format = DtsUtil.parseDtsFormat(frameData, formatId, language, null);
|
||||||
output.format(format);
|
output.format(format);
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
checkStateNotNull(output); // Asserts that createTracks has been called.
|
checkStateNotNull(output); // Asserts that createTracks has been called.
|
||||||
int offset = data.getPosition();
|
int offset = data.getPosition();
|
||||||
int limit = data.limit();
|
int limit = data.limit();
|
||||||
byte[] dataArray = data.data;
|
byte[] dataArray = data.getData();
|
||||||
|
|
||||||
// Append the data to the buffer.
|
// Append the data to the buffer.
|
||||||
totalBytesWritten += data.bytesLeft();
|
totalBytesWritten += data.bytesLeft();
|
||||||
|
|
@ -144,7 +144,7 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've found a start code with the following value.
|
// We've found a start code with the following value.
|
||||||
int startCodeValue = data.data[startCodeOffset + 3] & 0xFF;
|
int startCodeValue = data.getData()[startCodeOffset + 3] & 0xFF;
|
||||||
// This is the number of bytes from the current offset to the start of the next start
|
// This is the number of bytes from the current offset to the start of the next start
|
||||||
// code. It may be negative if the start code started in the previously consumed data.
|
// code. It may be negative if the start code started in the previously consumed data.
|
||||||
int lengthToStartCode = startCodeOffset - offset;
|
int lengthToStartCode = startCodeOffset - offset;
|
||||||
|
|
@ -178,7 +178,7 @@ public final class H262Reader implements ElementaryStreamReader {
|
||||||
Util.castNonNull(userDataReader).consume(sampleTimeUs, userDataParsable);
|
Util.castNonNull(userDataReader).consume(sampleTimeUs, userDataParsable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startCodeValue == START_USER_DATA && data.data[startCodeOffset + 2] == 0x1) {
|
if (startCodeValue == START_USER_DATA && data.getData()[startCodeOffset + 2] == 0x1) {
|
||||||
userData.startNalUnit(startCodeValue);
|
userData.startNalUnit(startCodeValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ public final class H263Reader implements ElementaryStreamReader {
|
||||||
checkStateNotNull(output);
|
checkStateNotNull(output);
|
||||||
int offset = data.getPosition();
|
int offset = data.getPosition();
|
||||||
int limit = data.limit();
|
int limit = data.limit();
|
||||||
byte[] dataArray = data.data;
|
byte[] dataArray = data.getData();
|
||||||
|
|
||||||
// Append the data to the buffer.
|
// Append the data to the buffer.
|
||||||
totalBytesWritten += data.bytesLeft();
|
totalBytesWritten += data.bytesLeft();
|
||||||
|
|
@ -155,7 +155,7 @@ public final class H263Reader implements ElementaryStreamReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've found a start code with the following value.
|
// We've found a start code with the following value.
|
||||||
int startCodeValue = data.data[startCodeOffset + 3] & 0xFF;
|
int startCodeValue = data.getData()[startCodeOffset + 3] & 0xFF;
|
||||||
// This is the number of bytes from the current offset to the start of the next start
|
// This is the number of bytes from the current offset to the start of the next start
|
||||||
// code. It may be negative if the start code started in the previously consumed data.
|
// code. It may be negative if the start code started in the previously consumed data.
|
||||||
int lengthToStartCode = startCodeOffset - offset;
|
int lengthToStartCode = startCodeOffset - offset;
|
||||||
|
|
@ -191,7 +191,8 @@ public final class H263Reader implements ElementaryStreamReader {
|
||||||
castNonNull(userDataReader).consume(pesTimeUs, userDataParsable);
|
castNonNull(userDataReader).consume(pesTimeUs, userDataParsable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startCodeValue == START_CODE_VALUE_USER_DATA && data.data[startCodeOffset + 2] == 0x1) {
|
if (startCodeValue == START_CODE_VALUE_USER_DATA
|
||||||
|
&& data.getData()[startCodeOffset + 2] == 0x1) {
|
||||||
userData.startNalUnit(startCodeValue);
|
userData.startNalUnit(startCodeValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ public final class H264Reader implements ElementaryStreamReader {
|
||||||
|
|
||||||
int offset = data.getPosition();
|
int offset = data.getPosition();
|
||||||
int limit = data.limit();
|
int limit = data.limit();
|
||||||
byte[] dataArray = data.data;
|
byte[] dataArray = data.getData();
|
||||||
|
|
||||||
// Append the data to the buffer.
|
// Append the data to the buffer.
|
||||||
totalBytesWritten += data.bytesLeft();
|
totalBytesWritten += data.bytesLeft();
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ public final class H265Reader implements ElementaryStreamReader {
|
||||||
while (data.bytesLeft() > 0) {
|
while (data.bytesLeft() > 0) {
|
||||||
int offset = data.getPosition();
|
int offset = data.getPosition();
|
||||||
int limit = data.limit();
|
int limit = data.limit();
|
||||||
byte[] dataArray = data.data;
|
byte[] dataArray = data.getData();
|
||||||
|
|
||||||
// Append the data to the buffer.
|
// Append the data to the buffer.
|
||||||
totalBytesWritten += data.bytesLeft();
|
totalBytesWritten += data.bytesLeft();
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,11 @@ public final class Id3Reader implements ElementaryStreamReader {
|
||||||
if (sampleBytesRead < ID3_HEADER_LENGTH) {
|
if (sampleBytesRead < ID3_HEADER_LENGTH) {
|
||||||
// We're still reading the ID3 header.
|
// We're still reading the ID3 header.
|
||||||
int headerBytesAvailable = Math.min(bytesAvailable, ID3_HEADER_LENGTH - sampleBytesRead);
|
int headerBytesAvailable = Math.min(bytesAvailable, ID3_HEADER_LENGTH - sampleBytesRead);
|
||||||
System.arraycopy(data.data, data.getPosition(), id3Header.data, sampleBytesRead,
|
System.arraycopy(
|
||||||
|
data.getData(),
|
||||||
|
data.getPosition(),
|
||||||
|
id3Header.getData(),
|
||||||
|
sampleBytesRead,
|
||||||
headerBytesAvailable);
|
headerBytesAvailable);
|
||||||
if (sampleBytesRead + headerBytesAvailable == ID3_HEADER_LENGTH) {
|
if (sampleBytesRead + headerBytesAvailable == ID3_HEADER_LENGTH) {
|
||||||
// We've finished reading the ID3 header. Extract the sample size.
|
// We've finished reading the ID3 header. Extract the sample size.
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
||||||
public LatmReader(@Nullable String language) {
|
public LatmReader(@Nullable String language) {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE);
|
sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE);
|
||||||
sampleBitArray = new ParsableBitArray(sampleDataBuffer.data);
|
sampleBitArray = new ParsableBitArray(sampleDataBuffer.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -122,7 +122,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
||||||
break;
|
break;
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_HEADER:
|
||||||
sampleSize = ((secondHeaderByte & ~SYNC_BYTE_SECOND) << 8) | data.readUnsignedByte();
|
sampleSize = ((secondHeaderByte & ~SYNC_BYTE_SECOND) << 8) | data.readUnsignedByte();
|
||||||
if (sampleSize > sampleDataBuffer.data.length) {
|
if (sampleSize > sampleDataBuffer.getData().length) {
|
||||||
resetBufferForSize(sampleSize);
|
resetBufferForSize(sampleSize);
|
||||||
}
|
}
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
|
|
@ -302,7 +302,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
||||||
} else {
|
} else {
|
||||||
// Sample data is not byte-aligned and we need align it ourselves before outputting.
|
// Sample data is not byte-aligned and we need align it ourselves before outputting.
|
||||||
// Byte alignment is needed because LATM framing is not supported by MediaCodec.
|
// Byte alignment is needed because LATM framing is not supported by MediaCodec.
|
||||||
data.readBits(sampleDataBuffer.data, 0, muxLengthBytes * 8);
|
data.readBits(sampleDataBuffer.getData(), 0, muxLengthBytes * 8);
|
||||||
sampleDataBuffer.setPosition(0);
|
sampleDataBuffer.setPosition(0);
|
||||||
}
|
}
|
||||||
output.sampleData(sampleDataBuffer, muxLengthBytes);
|
output.sampleData(sampleDataBuffer, muxLengthBytes);
|
||||||
|
|
@ -312,7 +312,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
||||||
|
|
||||||
private void resetBufferForSize(int newSize) {
|
private void resetBufferForSize(int newSize) {
|
||||||
sampleDataBuffer.reset(newSize);
|
sampleDataBuffer.reset(newSize);
|
||||||
sampleBitArray.reset(sampleDataBuffer.data);
|
sampleBitArray.reset(sampleDataBuffer.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long latmGetValue(ParsableBitArray data) {
|
private static long latmGetValue(ParsableBitArray data) {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
||||||
state = STATE_FINDING_HEADER;
|
state = STATE_FINDING_HEADER;
|
||||||
// The first byte of an MPEG Audio frame header is always 0xFF.
|
// The first byte of an MPEG Audio frame header is always 0xFF.
|
||||||
headerScratch = new ParsableByteArray(4);
|
headerScratch = new ParsableByteArray(4);
|
||||||
headerScratch.data[0] = (byte) 0xFF;
|
headerScratch.getData()[0] = (byte) 0xFF;
|
||||||
header = new MpegAudioUtil.Header();
|
header = new MpegAudioUtil.Header();
|
||||||
this.language = language;
|
this.language = language;
|
||||||
}
|
}
|
||||||
|
|
@ -129,7 +129,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
||||||
* @param source The source from which to read.
|
* @param source The source from which to read.
|
||||||
*/
|
*/
|
||||||
private void findHeader(ParsableByteArray source) {
|
private void findHeader(ParsableByteArray source) {
|
||||||
byte[] data = source.data;
|
byte[] data = source.getData();
|
||||||
int startOffset = source.getPosition();
|
int startOffset = source.getPosition();
|
||||||
int endOffset = source.limit();
|
int endOffset = source.limit();
|
||||||
for (int i = startOffset; i < endOffset; i++) {
|
for (int i = startOffset; i < endOffset; i++) {
|
||||||
|
|
@ -140,7 +140,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
||||||
source.setPosition(i + 1);
|
source.setPosition(i + 1);
|
||||||
// Reset lastByteWasFF for next time.
|
// Reset lastByteWasFF for next time.
|
||||||
lastByteWasFF = false;
|
lastByteWasFF = false;
|
||||||
headerScratch.data[1] = data[i];
|
headerScratch.getData()[1] = data[i];
|
||||||
frameBytesRead = 2;
|
frameBytesRead = 2;
|
||||||
state = STATE_READING_HEADER;
|
state = STATE_READING_HEADER;
|
||||||
return;
|
return;
|
||||||
|
|
@ -168,7 +168,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
||||||
@RequiresNonNull("output")
|
@RequiresNonNull("output")
|
||||||
private void readHeaderRemainder(ParsableByteArray source) {
|
private void readHeaderRemainder(ParsableByteArray source) {
|
||||||
int bytesToRead = Math.min(source.bytesLeft(), HEADER_SIZE - frameBytesRead);
|
int bytesToRead = Math.min(source.bytesLeft(), HEADER_SIZE - frameBytesRead);
|
||||||
source.readBytes(headerScratch.data, frameBytesRead, bytesToRead);
|
source.readBytes(headerScratch.getData(), frameBytesRead, bytesToRead);
|
||||||
frameBytesRead += bytesToRead;
|
frameBytesRead += bytesToRead;
|
||||||
if (frameBytesRead < HEADER_SIZE) {
|
if (frameBytesRead < HEADER_SIZE) {
|
||||||
// We haven't read the whole header yet.
|
// We haven't read the whole header yet.
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ import java.io.IOException;
|
||||||
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);
|
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
return searchForScrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
|
return searchForScrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ import java.io.IOException;
|
||||||
long lastScrTimeUsInRange = C.TIME_UNSET;
|
long lastScrTimeUsInRange = C.TIME_UNSET;
|
||||||
|
|
||||||
while (packetBuffer.bytesLeft() >= 4) {
|
while (packetBuffer.bytesLeft() >= 4) {
|
||||||
int nextStartCode = peekIntAtPosition(packetBuffer.data, packetBuffer.getPosition());
|
int nextStartCode = peekIntAtPosition(packetBuffer.getData(), packetBuffer.getPosition());
|
||||||
if (nextStartCode != PsExtractor.PACK_START_CODE) {
|
if (nextStartCode != PsExtractor.PACK_START_CODE) {
|
||||||
packetBuffer.skipBytes(1);
|
packetBuffer.skipBytes(1);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -162,7 +162,7 @@ import java.io.IOException;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextStartCode = peekIntAtPosition(packetBuffer.data, packetBuffer.getPosition());
|
int nextStartCode = peekIntAtPosition(packetBuffer.getData(), packetBuffer.getPosition());
|
||||||
if (nextStartCode == PsExtractor.SYSTEM_HEADER_START_CODE) {
|
if (nextStartCode == PsExtractor.SYSTEM_HEADER_START_CODE) {
|
||||||
packetBuffer.skipBytes(4);
|
packetBuffer.skipBytes(4);
|
||||||
int systemHeaderLength = packetBuffer.readUnsignedShort();
|
int systemHeaderLength = packetBuffer.readUnsignedShort();
|
||||||
|
|
@ -178,7 +178,7 @@ import java.io.IOException;
|
||||||
// If we couldn't find these codes within the buffer, return the buffer limit, or return
|
// If we couldn't find these codes within the buffer, return the buffer limit, or return
|
||||||
// the first position which PES packets pattern does not match (some malformed packets).
|
// the first position which PES packets pattern does not match (some malformed packets).
|
||||||
while (packetBuffer.bytesLeft() >= 4) {
|
while (packetBuffer.bytesLeft() >= 4) {
|
||||||
nextStartCode = peekIntAtPosition(packetBuffer.data, packetBuffer.getPosition());
|
nextStartCode = peekIntAtPosition(packetBuffer.getData(), packetBuffer.getPosition());
|
||||||
if (nextStartCode == PsExtractor.PACK_START_CODE
|
if (nextStartCode == PsExtractor.PACK_START_CODE
|
||||||
|| nextStartCode == PsExtractor.MPEG_PROGRAM_END_CODE) {
|
|| nextStartCode == PsExtractor.MPEG_PROGRAM_END_CODE) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
firstScrValue = readFirstScrValueFromBuffer(packetBuffer);
|
firstScrValue = readFirstScrValueFromBuffer(packetBuffer);
|
||||||
isFirstScrValueRead = true;
|
isFirstScrValueRead = true;
|
||||||
|
|
@ -158,7 +158,7 @@ import java.io.IOException;
|
||||||
for (int searchPosition = searchStartPosition;
|
for (int searchPosition = searchStartPosition;
|
||||||
searchPosition < searchEndPosition - 3;
|
searchPosition < searchEndPosition - 3;
|
||||||
searchPosition++) {
|
searchPosition++) {
|
||||||
int nextStartCode = peekIntAtPosition(packetBuffer.data, searchPosition);
|
int nextStartCode = peekIntAtPosition(packetBuffer.getData(), searchPosition);
|
||||||
if (nextStartCode == PsExtractor.PACK_START_CODE) {
|
if (nextStartCode == PsExtractor.PACK_START_CODE) {
|
||||||
packetBuffer.setPosition(searchPosition + 4);
|
packetBuffer.setPosition(searchPosition + 4);
|
||||||
long scrValue = readScrValueFromPack(packetBuffer);
|
long scrValue = readScrValueFromPack(packetBuffer);
|
||||||
|
|
@ -182,7 +182,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
lastScrValue = readLastScrValueFromBuffer(packetBuffer);
|
lastScrValue = readLastScrValueFromBuffer(packetBuffer);
|
||||||
isLastScrValueRead = true;
|
isLastScrValueRead = true;
|
||||||
|
|
@ -195,7 +195,7 @@ import java.io.IOException;
|
||||||
for (int searchPosition = searchEndPosition - 4;
|
for (int searchPosition = searchEndPosition - 4;
|
||||||
searchPosition >= searchStartPosition;
|
searchPosition >= searchStartPosition;
|
||||||
searchPosition--) {
|
searchPosition--) {
|
||||||
int nextStartCode = peekIntAtPosition(packetBuffer.data, searchPosition);
|
int nextStartCode = peekIntAtPosition(packetBuffer.getData(), searchPosition);
|
||||||
if (nextStartCode == PsExtractor.PACK_START_CODE) {
|
if (nextStartCode == PsExtractor.PACK_START_CODE) {
|
||||||
packetBuffer.setPosition(searchPosition + 4);
|
packetBuffer.setPosition(searchPosition + 4);
|
||||||
long scrValue = readScrValueFromPack(packetBuffer);
|
long scrValue = readScrValueFromPack(packetBuffer);
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ public final class PsExtractor implements Extractor {
|
||||||
return RESULT_END_OF_INPUT;
|
return RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
// First peek and check what type of start code is next.
|
// First peek and check what type of start code is next.
|
||||||
if (!input.peekFully(psPacketBuffer.data, 0, 4, true)) {
|
if (!input.peekFully(psPacketBuffer.getData(), 0, 4, true)) {
|
||||||
return RESULT_END_OF_INPUT;
|
return RESULT_END_OF_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,7 +192,7 @@ public final class PsExtractor implements Extractor {
|
||||||
return RESULT_END_OF_INPUT;
|
return RESULT_END_OF_INPUT;
|
||||||
} else if (nextStartCode == PACK_START_CODE) {
|
} else if (nextStartCode == PACK_START_CODE) {
|
||||||
// Now peek the rest of the pack_header.
|
// Now peek the rest of the pack_header.
|
||||||
input.peekFully(psPacketBuffer.data, 0, 10);
|
input.peekFully(psPacketBuffer.getData(), 0, 10);
|
||||||
|
|
||||||
// We only care about the pack_stuffing_length in here, skip the first 77 bits.
|
// We only care about the pack_stuffing_length in here, skip the first 77 bits.
|
||||||
psPacketBuffer.setPosition(9);
|
psPacketBuffer.setPosition(9);
|
||||||
|
|
@ -205,7 +205,7 @@ public final class PsExtractor implements Extractor {
|
||||||
return RESULT_CONTINUE;
|
return RESULT_CONTINUE;
|
||||||
} else if (nextStartCode == SYSTEM_HEADER_START_CODE) {
|
} else if (nextStartCode == SYSTEM_HEADER_START_CODE) {
|
||||||
// We just skip all this, but we need to get the length first.
|
// We just skip all this, but we need to get the length first.
|
||||||
input.peekFully(psPacketBuffer.data, 0, 2);
|
input.peekFully(psPacketBuffer.getData(), 0, 2);
|
||||||
|
|
||||||
// Length is the next 2 bytes.
|
// Length is the next 2 bytes.
|
||||||
psPacketBuffer.setPosition(0);
|
psPacketBuffer.setPosition(0);
|
||||||
|
|
@ -260,7 +260,7 @@ public final class PsExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The next 2 bytes are the length. Once we have that we can consume the complete packet.
|
// The next 2 bytes are the length. Once we have that we can consume the complete packet.
|
||||||
input.peekFully(psPacketBuffer.data, 0, 2);
|
input.peekFully(psPacketBuffer.getData(), 0, 2);
|
||||||
psPacketBuffer.setPosition(0);
|
psPacketBuffer.setPosition(0);
|
||||||
int payloadLength = psPacketBuffer.readUnsignedShort();
|
int payloadLength = psPacketBuffer.readUnsignedShort();
|
||||||
int pesLength = payloadLength + 6;
|
int pesLength = payloadLength + 6;
|
||||||
|
|
@ -271,7 +271,7 @@ public final class PsExtractor implements Extractor {
|
||||||
} else {
|
} else {
|
||||||
psPacketBuffer.reset(pesLength);
|
psPacketBuffer.reset(pesLength);
|
||||||
// Read the whole packet and the header for consumption.
|
// Read the whole packet and the header for consumption.
|
||||||
input.readFully(psPacketBuffer.data, 0, pesLength);
|
input.readFully(psPacketBuffer.getData(), 0, pesLength);
|
||||||
psPacketBuffer.setPosition(6);
|
psPacketBuffer.setPosition(6);
|
||||||
payloadReader.consume(psPacketBuffer);
|
payloadReader.consume(psPacketBuffer);
|
||||||
psPacketBuffer.setLimit(psPacketBuffer.capacity());
|
psPacketBuffer.setLimit(psPacketBuffer.capacity());
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ public final class SectionReader implements TsPayloadReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int headerBytesToRead = Math.min(data.bytesLeft(), SECTION_HEADER_LENGTH - bytesRead);
|
int headerBytesToRead = Math.min(data.bytesLeft(), SECTION_HEADER_LENGTH - bytesRead);
|
||||||
data.readBytes(sectionData.data, bytesRead, headerBytesToRead);
|
data.readBytes(sectionData.getData(), bytesRead, headerBytesToRead);
|
||||||
bytesRead += headerBytesToRead;
|
bytesRead += headerBytesToRead;
|
||||||
if (bytesRead == SECTION_HEADER_LENGTH) {
|
if (bytesRead == SECTION_HEADER_LENGTH) {
|
||||||
sectionData.reset(SECTION_HEADER_LENGTH);
|
sectionData.reset(SECTION_HEADER_LENGTH);
|
||||||
|
|
@ -100,21 +100,21 @@ public final class SectionReader implements TsPayloadReader {
|
||||||
(((secondHeaderByte & 0x0F) << 8) | thirdHeaderByte) + SECTION_HEADER_LENGTH;
|
(((secondHeaderByte & 0x0F) << 8) | thirdHeaderByte) + SECTION_HEADER_LENGTH;
|
||||||
if (sectionData.capacity() < totalSectionLength) {
|
if (sectionData.capacity() < totalSectionLength) {
|
||||||
// Ensure there is enough space to keep the whole section.
|
// Ensure there is enough space to keep the whole section.
|
||||||
byte[] bytes = sectionData.data;
|
byte[] bytes = sectionData.getData();
|
||||||
sectionData.reset(
|
sectionData.reset(
|
||||||
Math.min(MAX_SECTION_LENGTH, Math.max(totalSectionLength, bytes.length * 2)));
|
Math.min(MAX_SECTION_LENGTH, Math.max(totalSectionLength, bytes.length * 2)));
|
||||||
System.arraycopy(bytes, 0, sectionData.data, 0, SECTION_HEADER_LENGTH);
|
System.arraycopy(bytes, 0, sectionData.getData(), 0, SECTION_HEADER_LENGTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Reading the body.
|
// Reading the body.
|
||||||
int bodyBytesToRead = Math.min(data.bytesLeft(), totalSectionLength - bytesRead);
|
int bodyBytesToRead = Math.min(data.bytesLeft(), totalSectionLength - bytesRead);
|
||||||
data.readBytes(sectionData.data, bytesRead, bodyBytesToRead);
|
data.readBytes(sectionData.getData(), bytesRead, bodyBytesToRead);
|
||||||
bytesRead += bodyBytesToRead;
|
bytesRead += bodyBytesToRead;
|
||||||
if (bytesRead == totalSectionLength) {
|
if (bytesRead == totalSectionLength) {
|
||||||
if (sectionSyntaxIndicator) {
|
if (sectionSyntaxIndicator) {
|
||||||
// This section has common syntax as defined in ISO/IEC 13818-1, section 2.4.4.11.
|
// This section has common syntax as defined in ISO/IEC 13818-1, section 2.4.4.11.
|
||||||
if (Util.crc32(sectionData.data, 0, totalSectionLength, 0xFFFFFFFF) != 0) {
|
if (Util.crc32(sectionData.getData(), 0, totalSectionLength, 0xFFFFFFFF) != 0) {
|
||||||
// The CRC is invalid so discard the section.
|
// The CRC is invalid so discard the section.
|
||||||
waitingForPayloadStart = true;
|
waitingForPayloadStart = true;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ import java.io.IOException;
|
||||||
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);
|
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
return searchForPcrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
|
return searchForPcrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +94,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
while (packetBuffer.bytesLeft() >= TsExtractor.TS_PACKET_SIZE) {
|
while (packetBuffer.bytesLeft() >= TsExtractor.TS_PACKET_SIZE) {
|
||||||
int startOfPacket =
|
int startOfPacket =
|
||||||
TsUtil.findSyncBytePosition(packetBuffer.data, packetBuffer.getPosition(), limit);
|
TsUtil.findSyncBytePosition(packetBuffer.getData(), packetBuffer.getPosition(), limit);
|
||||||
int endOfPacket = startOfPacket + TsExtractor.TS_PACKET_SIZE;
|
int endOfPacket = startOfPacket + TsExtractor.TS_PACKET_SIZE;
|
||||||
if (endOfPacket > limit) {
|
if (endOfPacket > limit) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
firstPcrValue = readFirstPcrValueFromBuffer(packetBuffer, pcrPid);
|
firstPcrValue = readFirstPcrValueFromBuffer(packetBuffer, pcrPid);
|
||||||
isFirstPcrValueRead = true;
|
isFirstPcrValueRead = true;
|
||||||
|
|
@ -145,7 +145,7 @@ import java.io.IOException;
|
||||||
for (int searchPosition = searchStartPosition;
|
for (int searchPosition = searchStartPosition;
|
||||||
searchPosition < searchEndPosition;
|
searchPosition < searchEndPosition;
|
||||||
searchPosition++) {
|
searchPosition++) {
|
||||||
if (packetBuffer.data[searchPosition] != TsExtractor.TS_SYNC_BYTE) {
|
if (packetBuffer.getData()[searchPosition] != TsExtractor.TS_SYNC_BYTE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
||||||
|
|
@ -168,7 +168,7 @@ import java.io.IOException;
|
||||||
|
|
||||||
packetBuffer.reset(bytesToSearch);
|
packetBuffer.reset(bytesToSearch);
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
|
input.peekFully(packetBuffer.getData(), /* offset= */ 0, bytesToSearch);
|
||||||
|
|
||||||
lastPcrValue = readLastPcrValueFromBuffer(packetBuffer, pcrPid);
|
lastPcrValue = readLastPcrValueFromBuffer(packetBuffer, pcrPid);
|
||||||
isLastPcrValueRead = true;
|
isLastPcrValueRead = true;
|
||||||
|
|
@ -181,7 +181,7 @@ import java.io.IOException;
|
||||||
for (int searchPosition = searchEndPosition - 1;
|
for (int searchPosition = searchEndPosition - 1;
|
||||||
searchPosition >= searchStartPosition;
|
searchPosition >= searchStartPosition;
|
||||||
searchPosition--) {
|
searchPosition--) {
|
||||||
if (packetBuffer.data[searchPosition] != TsExtractor.TS_SYNC_BYTE) {
|
if (packetBuffer.getData()[searchPosition] != TsExtractor.TS_SYNC_BYTE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
long pcrValue = TsUtil.readPcrFromPacket(packetBuffer, searchPosition, pcrPid);
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ public final class TsExtractor implements Extractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sniff(ExtractorInput input) throws IOException {
|
public boolean sniff(ExtractorInput input) throws IOException {
|
||||||
byte[] buffer = tsPacketBuffer.data;
|
byte[] buffer = tsPacketBuffer.getData();
|
||||||
input.peekFully(buffer, 0, TS_PACKET_SIZE * SNIFF_TS_PACKET_COUNT);
|
input.peekFully(buffer, 0, TS_PACKET_SIZE * SNIFF_TS_PACKET_COUNT);
|
||||||
for (int startPosCandidate = 0; startPosCandidate < TS_PACKET_SIZE; startPosCandidate++) {
|
for (int startPosCandidate = 0; startPosCandidate < TS_PACKET_SIZE; startPosCandidate++) {
|
||||||
// Try to identify at least SNIFF_TS_PACKET_COUNT packets starting with TS_SYNC_BYTE.
|
// Try to identify at least SNIFF_TS_PACKET_COUNT packets starting with TS_SYNC_BYTE.
|
||||||
|
|
@ -374,7 +374,7 @@ public final class TsExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fillBufferWithAtLeastOnePacket(ExtractorInput input) throws IOException {
|
private boolean fillBufferWithAtLeastOnePacket(ExtractorInput input) throws IOException {
|
||||||
byte[] data = tsPacketBuffer.data;
|
byte[] data = tsPacketBuffer.getData();
|
||||||
// Shift bytes to the start of the buffer if there isn't enough space left at the end.
|
// Shift bytes to the start of the buffer if there isn't enough space left at the end.
|
||||||
if (BUFFER_SIZE - tsPacketBuffer.getPosition() < TS_PACKET_SIZE) {
|
if (BUFFER_SIZE - tsPacketBuffer.getPosition() < TS_PACKET_SIZE) {
|
||||||
int bytesLeft = tsPacketBuffer.bytesLeft();
|
int bytesLeft = tsPacketBuffer.bytesLeft();
|
||||||
|
|
@ -404,7 +404,8 @@ public final class TsExtractor implements Extractor {
|
||||||
private int findEndOfFirstTsPacketInBuffer() throws ParserException {
|
private int findEndOfFirstTsPacketInBuffer() throws ParserException {
|
||||||
int searchStart = tsPacketBuffer.getPosition();
|
int searchStart = tsPacketBuffer.getPosition();
|
||||||
int limit = tsPacketBuffer.limit();
|
int limit = tsPacketBuffer.limit();
|
||||||
int syncBytePosition = TsUtil.findSyncBytePosition(tsPacketBuffer.data, searchStart, limit);
|
int syncBytePosition =
|
||||||
|
TsUtil.findSyncBytePosition(tsPacketBuffer.getData(), searchStart, limit);
|
||||||
// Discard all bytes before the sync byte.
|
// Discard all bytes before the sync byte.
|
||||||
// If sync byte is not found, this means discard the whole buffer.
|
// If sync byte is not found, this means discard the whole buffer.
|
||||||
tsPacketBuffer.setPosition(syncBytePosition);
|
tsPacketBuffer.setPosition(syncBytePosition);
|
||||||
|
|
@ -710,8 +711,11 @@ public final class TsExtractor implements Extractor {
|
||||||
data.skipBytes(positionOfNextDescriptor - data.getPosition());
|
data.skipBytes(positionOfNextDescriptor - data.getPosition());
|
||||||
}
|
}
|
||||||
data.setPosition(descriptorsEndPosition);
|
data.setPosition(descriptorsEndPosition);
|
||||||
return new EsInfo(streamType, language, dvbSubtitleInfos,
|
return new EsInfo(
|
||||||
Arrays.copyOfRange(data.data, descriptorsStartPosition, descriptorsEndPosition));
|
streamType,
|
||||||
|
language,
|
||||||
|
dvbSubtitleInfos,
|
||||||
|
Arrays.copyOfRange(data.getData(), descriptorsStartPosition, descriptorsEndPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,7 @@ public final class WavExtractor implements Extractor {
|
||||||
private void decode(byte[] input, int blockCount, ParsableByteArray output) {
|
private void decode(byte[] input, int blockCount, ParsableByteArray output) {
|
||||||
for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
||||||
for (int channelIndex = 0; channelIndex < header.numChannels; channelIndex++) {
|
for (int channelIndex = 0; channelIndex < header.numChannels; channelIndex++) {
|
||||||
decodeBlockForChannel(input, blockIndex, channelIndex, output.data);
|
decodeBlockForChannel(input, blockIndex, channelIndex, output.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int decodedDataSize = numOutputFramesToBytes(framesPerBlock * blockCount);
|
int decodedDataSize = numOutputFramesToBytes(framesPerBlock * blockCount);
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ import java.io.IOException;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.peekFully(scratch.data, 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int riffFormat = scratch.readInt();
|
int riffFormat = scratch.readInt();
|
||||||
if (riffFormat != WavUtil.WAVE_FOURCC) {
|
if (riffFormat != WavUtil.WAVE_FOURCC) {
|
||||||
|
|
@ -70,7 +70,7 @@ import java.io.IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assertions.checkState(chunkHeader.size >= 16);
|
Assertions.checkState(chunkHeader.size >= 16);
|
||||||
input.peekFully(scratch.data, 0, 16);
|
input.peekFully(scratch.getData(), 0, 16);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int audioFormatType = scratch.readLittleEndianUnsignedShort();
|
int audioFormatType = scratch.readLittleEndianUnsignedShort();
|
||||||
int numChannels = scratch.readLittleEndianUnsignedShort();
|
int numChannels = scratch.readLittleEndianUnsignedShort();
|
||||||
|
|
@ -175,7 +175,7 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public static ChunkHeader peek(ExtractorInput input, ParsableByteArray scratch)
|
public static ChunkHeader peek(ExtractorInput input, ParsableByteArray scratch)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
input.peekFully(scratch.data, /* offset= */ 0, /* length= */ SIZE_IN_BYTES);
|
input.peekFully(scratch.getData(), /* offset= */ 0, /* length= */ SIZE_IN_BYTES);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
|
|
||||||
int id = scratch.readInt();
|
int id = scratch.readInt();
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public class FlacFrameReaderTest {
|
||||||
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
||||||
int frameStartMarker = FlacMetadataReader.getFrameStartMarker(input);
|
int frameStartMarker = FlacMetadataReader.getFrameStartMarker(input);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
input.read(scratch.data, 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
input.read(scratch.getData(), 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
|
|
||||||
FlacFrameReader.checkAndReadFrameHeader(
|
FlacFrameReader.checkAndReadFrameHeader(
|
||||||
scratch,
|
scratch,
|
||||||
|
|
@ -67,7 +67,7 @@ public class FlacFrameReaderTest {
|
||||||
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
||||||
int frameStartMarker = FlacMetadataReader.getFrameStartMarker(input);
|
int frameStartMarker = FlacMetadataReader.getFrameStartMarker(input);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
input.read(scratch.data, 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
input.read(scratch.getData(), 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
|
|
||||||
boolean result =
|
boolean result =
|
||||||
FlacFrameReader.checkAndReadFrameHeader(
|
FlacFrameReader.checkAndReadFrameHeader(
|
||||||
|
|
@ -90,7 +90,7 @@ public class FlacFrameReaderTest {
|
||||||
// Skip first frame.
|
// Skip first frame.
|
||||||
input.skip(5030);
|
input.skip(5030);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
input.read(scratch.data, 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
input.read(scratch.getData(), 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
SampleNumberHolder sampleNumberHolder = new SampleNumberHolder();
|
SampleNumberHolder sampleNumberHolder = new SampleNumberHolder();
|
||||||
|
|
||||||
FlacFrameReader.checkAndReadFrameHeader(
|
FlacFrameReader.checkAndReadFrameHeader(
|
||||||
|
|
@ -107,7 +107,7 @@ public class FlacFrameReaderTest {
|
||||||
buildExtractorInputReadingFromFirstFrame(
|
buildExtractorInputReadingFromFirstFrame(
|
||||||
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
"flac/bear_one_metadata_block.flac", streamMetadataHolder);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
ParsableByteArray scratch = new ParsableByteArray(FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
input.read(scratch.data, 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
input.read(scratch.getData(), 0, FlacConstants.MAX_FRAME_HEADER_SIZE);
|
||||||
|
|
||||||
// The first bytes of the frame are not equal to the frame start marker.
|
// The first bytes of the frame are not equal to the frame start marker.
|
||||||
boolean result =
|
boolean result =
|
||||||
|
|
@ -276,7 +276,7 @@ public class FlacFrameReaderTest {
|
||||||
// Skip to block size bits of last frame.
|
// Skip to block size bits of last frame.
|
||||||
input.skipFully(164033);
|
input.skipFully(164033);
|
||||||
ParsableByteArray scratch = new ParsableByteArray(2);
|
ParsableByteArray scratch = new ParsableByteArray(2);
|
||||||
input.readFully(scratch.data, 0, 2);
|
input.readFully(scratch.getData(), 0, 2);
|
||||||
|
|
||||||
int result = FlacFrameReader.readFrameBlockSizeSamplesFromKey(scratch, /* blockSizeKey= */ 7);
|
int result = FlacFrameReader.readFrameBlockSizeSamplesFromKey(scratch, /* blockSizeKey= */ 7);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ public class FlacMetadataReaderTest {
|
||||||
input.skipFully(FlacConstants.STREAM_MARKER_SIZE + FlacConstants.STREAM_INFO_BLOCK_SIZE);
|
input.skipFully(FlacConstants.STREAM_MARKER_SIZE + FlacConstants.STREAM_INFO_BLOCK_SIZE);
|
||||||
int seekTableBlockSize = 598;
|
int seekTableBlockSize = 598;
|
||||||
ParsableByteArray scratch = new ParsableByteArray(seekTableBlockSize);
|
ParsableByteArray scratch = new ParsableByteArray(seekTableBlockSize);
|
||||||
input.read(scratch.data, 0, seekTableBlockSize);
|
input.read(scratch.getData(), 0, seekTableBlockSize);
|
||||||
|
|
||||||
FlacMetadataReader.readSeekTableMetadataBlock(scratch);
|
FlacMetadataReader.readSeekTableMetadataBlock(scratch);
|
||||||
|
|
||||||
|
|
@ -332,7 +332,7 @@ public class FlacMetadataReaderTest {
|
||||||
input.skipFully(FlacConstants.STREAM_MARKER_SIZE + FlacConstants.STREAM_INFO_BLOCK_SIZE);
|
input.skipFully(FlacConstants.STREAM_MARKER_SIZE + FlacConstants.STREAM_INFO_BLOCK_SIZE);
|
||||||
int seekTableBlockSize = 598;
|
int seekTableBlockSize = 598;
|
||||||
ParsableByteArray scratch = new ParsableByteArray(seekTableBlockSize);
|
ParsableByteArray scratch = new ParsableByteArray(seekTableBlockSize);
|
||||||
input.read(scratch.data, 0, seekTableBlockSize);
|
input.read(scratch.getData(), 0, seekTableBlockSize);
|
||||||
|
|
||||||
FlacStreamMetadata.SeekTable seekTable = FlacMetadataReader.readSeekTableMetadataBlock(scratch);
|
FlacStreamMetadata.SeekTable seekTable = FlacMetadataReader.readSeekTableMetadataBlock(scratch);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ public final class OggPacketTest {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
assertThat(readPacket(extractorInput)).isTrue();
|
assertThat(readPacket(extractorInput)).isTrue();
|
||||||
ParsableByteArray payload = oggPacket.getPayload();
|
ParsableByteArray payload = oggPacket.getPayload();
|
||||||
assertThat(Arrays.copyOf(payload.data, payload.limit())).isEqualTo(expected);
|
assertThat(Arrays.copyOf(payload.getData(), payload.limit())).isEqualTo(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertReadEof(FakeExtractorInput extractorInput) throws IOException {
|
private void assertReadEof(FakeExtractorInput extractorInput) throws IOException {
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ public final class VorbisReaderTest {
|
||||||
buffer.setLimit(0);
|
buffer.setLimit(0);
|
||||||
VorbisReader.appendNumberOfSamples(buffer, 0x01234567);
|
VorbisReader.appendNumberOfSamples(buffer, 0x01234567);
|
||||||
assertThat(buffer.limit()).isEqualTo(4);
|
assertThat(buffer.limit()).isEqualTo(4);
|
||||||
assertThat(buffer.data[0]).isEqualTo(0x67);
|
assertThat(buffer.getData()[0]).isEqualTo(0x67);
|
||||||
assertThat(buffer.data[1]).isEqualTo(0x45);
|
assertThat(buffer.getData()[1]).isEqualTo(0x45);
|
||||||
assertThat(buffer.data[2]).isEqualTo(0x23);
|
assertThat(buffer.getData()[2]).isEqualTo(0x23);
|
||||||
assertThat(buffer.data[3]).isEqualTo(0x01);
|
assertThat(buffer.getData()[3]).isEqualTo(0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
private long peekId3PrivTimestamp(ExtractorInput input) throws IOException {
|
private long peekId3PrivTimestamp(ExtractorInput input) throws IOException {
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
try {
|
try {
|
||||||
input.peekFully(scratchId3Data.data, 0, Id3Decoder.ID3_HEADER_LENGTH);
|
input.peekFully(scratchId3Data.getData(), 0, Id3Decoder.ID3_HEADER_LENGTH);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
// The input isn't long enough for there to be any ID3 data.
|
// The input isn't long enough for there to be any ID3 data.
|
||||||
return C.TIME_UNSET;
|
return C.TIME_UNSET;
|
||||||
|
|
@ -469,12 +469,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
int id3Size = scratchId3Data.readSynchSafeInt();
|
int id3Size = scratchId3Data.readSynchSafeInt();
|
||||||
int requiredCapacity = id3Size + Id3Decoder.ID3_HEADER_LENGTH;
|
int requiredCapacity = id3Size + Id3Decoder.ID3_HEADER_LENGTH;
|
||||||
if (requiredCapacity > scratchId3Data.capacity()) {
|
if (requiredCapacity > scratchId3Data.capacity()) {
|
||||||
byte[] data = scratchId3Data.data;
|
byte[] data = scratchId3Data.getData();
|
||||||
scratchId3Data.reset(requiredCapacity);
|
scratchId3Data.reset(requiredCapacity);
|
||||||
System.arraycopy(data, 0, scratchId3Data.data, 0, Id3Decoder.ID3_HEADER_LENGTH);
|
System.arraycopy(data, 0, scratchId3Data.getData(), 0, Id3Decoder.ID3_HEADER_LENGTH);
|
||||||
}
|
}
|
||||||
input.peekFully(scratchId3Data.data, Id3Decoder.ID3_HEADER_LENGTH, id3Size);
|
input.peekFully(scratchId3Data.getData(), Id3Decoder.ID3_HEADER_LENGTH, id3Size);
|
||||||
Metadata metadata = id3Decoder.decode(scratchId3Data.data, id3Size);
|
Metadata metadata = id3Decoder.decode(scratchId3Data.getData(), id3Size);
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
return C.TIME_UNSET;
|
return C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
|
|
@ -485,7 +485,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
PrivFrame privFrame = (PrivFrame) frame;
|
PrivFrame privFrame = (PrivFrame) frame;
|
||||||
if (PRIV_TIMESTAMP_FRAME_OWNER.equals(privFrame.owner)) {
|
if (PRIV_TIMESTAMP_FRAME_OWNER.equals(privFrame.owner)) {
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
privFrame.privateData, 0, scratchId3Data.data, 0, 8 /* timestamp size */);
|
privFrame.privateData, 0, scratchId3Data.getData(), 0, 8 /* timestamp size */);
|
||||||
scratchId3Data.reset(8);
|
scratchId3Data.reset(8);
|
||||||
// The top 31 bits should be zeros, but explicitly zero them to wrap in the case that the
|
// The top 31 bits should be zeros, but explicitly zero them to wrap in the case that the
|
||||||
// streaming provider forgot. See: https://github.com/google/ExoPlayer/pull/3495.
|
// streaming provider forgot. See: https://github.com/google/ExoPlayer/pull/3495.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue