mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Cleanup - Make RollingSampleBuffer append methods more consistent.
This commit is contained in:
parent
0d42032ada
commit
5f51a4ff83
@ -57,8 +57,8 @@ public final class FakeTrackOutput implements TrackOutput {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sampleData(ExtractorInput input, int length) throws IOException,
|
||||
InterruptedException {
|
||||
public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
byte[] newData = new byte[length];
|
||||
input.readFully(newData, 0, length);
|
||||
sampleData = TestUtil.joinByteArrays(sampleData, newData);
|
||||
|
@ -127,8 +127,9 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sampleData(ExtractorInput input, int length) throws IOException, InterruptedException {
|
||||
return output.sampleData(input, length);
|
||||
public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
return output.sampleData(input, length, allowEndOfInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,8 +106,9 @@ public class ContainerMediaChunk extends BaseMediaChunk implements SingleTrackOu
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sampleData(ExtractorInput input, int length) throws IOException, InterruptedException {
|
||||
return getOutput().sampleData(input, length);
|
||||
public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
return getOutput().sampleData(input, length, allowEndOfInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,7 +138,8 @@ public final class InitializationChunk extends Chunk implements SingleTrackOutpu
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sampleData(ExtractorInput input, int length) throws IOException, InterruptedException {
|
||||
public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
throw new IllegalStateException("Unexpected sample data in initialization chunk");
|
||||
}
|
||||
|
||||
|
@ -109,10 +109,8 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
|
||||
// Load the sample data.
|
||||
int result = 0;
|
||||
while (result != C.RESULT_END_OF_INPUT) {
|
||||
result = getOutput().sampleData(dataSource, Integer.MAX_VALUE);
|
||||
if (result != C.RESULT_END_OF_INPUT) {
|
||||
bytesLoaded += result;
|
||||
}
|
||||
bytesLoaded += result;
|
||||
result = getOutput().sampleData(dataSource, Integer.MAX_VALUE, true);
|
||||
}
|
||||
int sampleSize = bytesLoaded;
|
||||
if (headerData != null) {
|
||||
|
@ -15,12 +15,14 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.extractor;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.MediaFormat;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.upstream.Allocator;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -225,8 +227,20 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
|
||||
// Called by the loading thread.
|
||||
|
||||
public int sampleData(DataSource dataSource, int length) throws IOException {
|
||||
return rollingBuffer.appendData(dataSource, length);
|
||||
/**
|
||||
* Invoked to write sample data to the output.
|
||||
*
|
||||
* @param dataSource A {@link DataSource} from which to read the sample data.
|
||||
* @param length The maximum length to read from the input.
|
||||
* @param allowEndOfInput True if encountering the end of the input having read no data is
|
||||
* allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
|
||||
* should be considered an error, causing an {@link EOFException} to be thrown.
|
||||
* @return The number of bytes appended.
|
||||
* @throws IOException If an error occurred reading from the input.
|
||||
*/
|
||||
public int sampleData(DataSource dataSource, int length, boolean allowEndOfInput)
|
||||
throws IOException {
|
||||
return rollingBuffer.appendData(dataSource, length, allowEndOfInput);
|
||||
}
|
||||
|
||||
// TrackOutput implementation. Called by the loading thread.
|
||||
@ -237,8 +251,9 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sampleData(ExtractorInput input, int length) throws IOException, InterruptedException {
|
||||
return rollingBuffer.appendData(input, length);
|
||||
public int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
return rollingBuffer.appendData(input, length, allowEndOfInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
@ -350,26 +351,27 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
* Appends data to the rolling buffer.
|
||||
*
|
||||
* @param dataSource The source from which to read.
|
||||
* @param length The maximum length of the read, or {@link C#LENGTH_UNBOUNDED} if the caller does
|
||||
* not wish to impose a limit.
|
||||
* @return The number of bytes appended.
|
||||
* @param length The maximum length of the read.
|
||||
* @param allowEndOfInput True if encountering the end of the input having appended no data is
|
||||
* allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
|
||||
* should be considered an error, causing an {@link EOFException} to be thrown.
|
||||
* @return The number of bytes appended, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
|
||||
* @throws IOException If an error occurs reading from the source.
|
||||
*/
|
||||
public int appendData(DataSource dataSource, int length) throws IOException {
|
||||
ensureSpaceForWrite();
|
||||
int remainingAllocationCapacity = allocationLength - lastAllocationOffset;
|
||||
length = length != C.LENGTH_UNBOUNDED ? Math.min(length, remainingAllocationCapacity)
|
||||
: remainingAllocationCapacity;
|
||||
|
||||
int bytesRead = dataSource.read(lastAllocation.data,
|
||||
public int appendData(DataSource dataSource, int length, boolean allowEndOfInput)
|
||||
throws IOException {
|
||||
length = prepareForAppend(length);
|
||||
int bytesAppended = dataSource.read(lastAllocation.data,
|
||||
lastAllocation.translateOffset(lastAllocationOffset), length);
|
||||
if (bytesRead == C.RESULT_END_OF_INPUT) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
if (bytesAppended == C.RESULT_END_OF_INPUT) {
|
||||
if (allowEndOfInput) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
}
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
lastAllocationOffset += bytesRead;
|
||||
totalBytesWritten += bytesRead;
|
||||
return bytesRead;
|
||||
lastAllocationOffset += bytesAppended;
|
||||
totalBytesWritten += bytesAppended;
|
||||
return bytesAppended;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -377,17 +379,27 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
*
|
||||
* @param input The source from which to read.
|
||||
* @param length The maximum length of the read.
|
||||
* @return The number of bytes appended.
|
||||
* @param allowEndOfInput True if encountering the end of the input having appended no data is
|
||||
* allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
|
||||
* should be considered an error, causing an {@link EOFException} to be thrown.
|
||||
* @return The number of bytes appended, or {@link C#RESULT_END_OF_INPUT} if the input has ended.
|
||||
* @throws IOException If an error occurs reading from the source.
|
||||
* @throws InterruptedException If the thread has been interrupted.
|
||||
*/
|
||||
public int appendData(ExtractorInput input, int length) throws IOException, InterruptedException {
|
||||
ensureSpaceForWrite();
|
||||
int thisWriteLength = Math.min(length, allocationLength - lastAllocationOffset);
|
||||
input.readFully(lastAllocation.data, lastAllocation.translateOffset(lastAllocationOffset),
|
||||
thisWriteLength);
|
||||
lastAllocationOffset += thisWriteLength;
|
||||
totalBytesWritten += thisWriteLength;
|
||||
return thisWriteLength;
|
||||
public int appendData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException {
|
||||
length = prepareForAppend(length);
|
||||
int bytesAppended = input.read(lastAllocation.data,
|
||||
lastAllocation.translateOffset(lastAllocationOffset), length);
|
||||
if (bytesAppended == C.RESULT_END_OF_INPUT) {
|
||||
if (allowEndOfInput) {
|
||||
return C.RESULT_END_OF_INPUT;
|
||||
}
|
||||
throw new EOFException();
|
||||
}
|
||||
lastAllocationOffset += bytesAppended;
|
||||
totalBytesWritten += bytesAppended;
|
||||
return bytesAppended;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -397,16 +409,14 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
* @param length The length of the data to append.
|
||||
*/
|
||||
public void appendData(ParsableByteArray buffer, int length) {
|
||||
int remainingWriteLength = length;
|
||||
while (remainingWriteLength > 0) {
|
||||
ensureSpaceForWrite();
|
||||
int thisWriteLength = Math.min(remainingWriteLength, allocationLength - lastAllocationOffset);
|
||||
while (length > 0) {
|
||||
int thisAppendLength = prepareForAppend(length);
|
||||
buffer.readBytes(lastAllocation.data, lastAllocation.translateOffset(lastAllocationOffset),
|
||||
thisWriteLength);
|
||||
lastAllocationOffset += thisWriteLength;
|
||||
remainingWriteLength -= thisWriteLength;
|
||||
thisAppendLength);
|
||||
lastAllocationOffset += thisAppendLength;
|
||||
totalBytesWritten += thisAppendLength;
|
||||
length -= thisAppendLength;
|
||||
}
|
||||
totalBytesWritten += length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -424,14 +434,16 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures at least one byte can be written, obtaining an additional allocation if necessary.
|
||||
* Prepares the rolling sample buffer for an append of up to {@code length} bytes, returning the
|
||||
* number of bytes that can actually be appended.
|
||||
*/
|
||||
private void ensureSpaceForWrite() {
|
||||
private int prepareForAppend(int length) {
|
||||
if (lastAllocationOffset == allocationLength) {
|
||||
lastAllocationOffset = 0;
|
||||
lastAllocation = allocator.allocate();
|
||||
dataQueue.add(lastAllocation);
|
||||
}
|
||||
return Math.min(length, allocationLength - lastAllocationOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,10 +15,12 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.extractor;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.MediaFormat;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -38,11 +40,15 @@ public interface TrackOutput {
|
||||
*
|
||||
* @param input An {@link ExtractorInput} from which to read the sample data.
|
||||
* @param length The maximum length to read from the input.
|
||||
* @param allowEndOfInput True if encountering the end of the input having read no data is
|
||||
* allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
|
||||
* should be considered an error, causing an {@link EOFException} to be thrown.
|
||||
* @return The number of bytes appended.
|
||||
* @throws IOException If an error occurred reading from the input.
|
||||
* @throws InterruptedException If the thread was interrupted.
|
||||
*/
|
||||
int sampleData(ExtractorInput input, int length) throws IOException, InterruptedException;
|
||||
int sampleData(ExtractorInput input, int length, boolean allowEndOfInput)
|
||||
throws IOException, InterruptedException;
|
||||
|
||||
/**
|
||||
* Invoked to write sample data to the output.
|
||||
@ -56,14 +62,16 @@ public interface TrackOutput {
|
||||
* Invoked when metadata associated with a sample has been extracted from the stream.
|
||||
* <p>
|
||||
* The corresponding sample data will have already been passed to the output via calls to
|
||||
* {@link #sampleData(ExtractorInput, int)} or {@link #sampleData(ParsableByteArray, int)}.
|
||||
* {@link #sampleData(ExtractorInput, int, boolean)} or
|
||||
* {@link #sampleData(ParsableByteArray, int)}.
|
||||
*
|
||||
* @param timeUs The media timestamp associated with the sample, in microseconds.
|
||||
* @param flags Flags associated with the sample. See {@link SampleHolder#flags}.
|
||||
* @param size The size of the sample data, in bytes.
|
||||
* @param offset The number of bytes that have been passed to
|
||||
* {@link #sampleData(ExtractorInput, int)} or {@link #sampleData(ParsableByteArray, int)}
|
||||
* since the last byte belonging to the sample whose metadata is being passed.
|
||||
* {@link #sampleData(ExtractorInput, int, boolean)} or
|
||||
* {@link #sampleData(ParsableByteArray, int)} since the last byte belonging to the sample
|
||||
* whose metadata is being passed.
|
||||
* @param encryptionKey The encryption key associated with the sample. May be null.
|
||||
*/
|
||||
void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey);
|
||||
|
@ -170,11 +170,11 @@ public final class Mp3Extractor implements Extractor {
|
||||
sampleBytesRemaining -= inputBuffer.drainToOutput(trackOutput, sampleBytesRemaining);
|
||||
if (sampleBytesRemaining > 0) {
|
||||
inputBuffer.mark();
|
||||
try {
|
||||
sampleBytesRemaining -= trackOutput.sampleData(extractorInput, sampleBytesRemaining);
|
||||
} catch (EOFException e) {
|
||||
int bytesAppended = trackOutput.sampleData(extractorInput, sampleBytesRemaining, true);
|
||||
if (bytesAppended == C.RESULT_END_OF_INPUT) {
|
||||
return RESULT_END_OF_INPUT;
|
||||
}
|
||||
sampleBytesRemaining -= bytesAppended;
|
||||
// Return if we still need more data.
|
||||
if (sampleBytesRemaining > 0) {
|
||||
return RESULT_CONTINUE;
|
||||
|
@ -663,14 +663,14 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
sampleSize += nalUnitLengthFieldLengthDiff;
|
||||
} else {
|
||||
// Write the payload of the NAL unit.
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleCurrentNalBytesRemaining);
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleCurrentNalBytesRemaining, false);
|
||||
sampleBytesWritten += writtenBytes;
|
||||
sampleCurrentNalBytesRemaining -= writtenBytes;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (sampleBytesWritten < sampleSize) {
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten);
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten, false);
|
||||
sampleBytesWritten += writtenBytes;
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +298,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
return RESULT_END_OF_INPUT;
|
||||
}
|
||||
Mp4Track track = tracks[trackIndex];
|
||||
TrackOutput trackOutput = track.trackOutput;
|
||||
int sampleIndex = track.sampleIndex;
|
||||
long position = track.sampleTable.offsets[sampleIndex];
|
||||
long skipAmount = position - input.getPosition() + sampleBytesWritten;
|
||||
@ -327,24 +328,24 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
sampleCurrentNalBytesRemaining = nalLength.readUnsignedIntToInt();
|
||||
// Write a start code for the current NAL unit.
|
||||
nalStartCode.setPosition(0);
|
||||
track.trackOutput.sampleData(nalStartCode, 4);
|
||||
trackOutput.sampleData(nalStartCode, 4);
|
||||
sampleBytesWritten += 4;
|
||||
sampleSize += nalUnitLengthFieldLengthDiff;
|
||||
} else {
|
||||
// Write the payload of the NAL unit.
|
||||
int writtenBytes = track.trackOutput.sampleData(input, sampleCurrentNalBytesRemaining);
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleCurrentNalBytesRemaining, false);
|
||||
sampleBytesWritten += writtenBytes;
|
||||
sampleCurrentNalBytesRemaining -= writtenBytes;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (sampleBytesWritten < sampleSize) {
|
||||
int writtenBytes = track.trackOutput.sampleData(input, sampleSize - sampleBytesWritten);
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten, false);
|
||||
sampleBytesWritten += writtenBytes;
|
||||
sampleCurrentNalBytesRemaining -= writtenBytes;
|
||||
}
|
||||
}
|
||||
track.trackOutput.sampleMetadata(track.sampleTable.timestampsUs[sampleIndex],
|
||||
trackOutput.sampleMetadata(track.sampleTable.timestampsUs[sampleIndex],
|
||||
track.sampleTable.flags[sampleIndex], sampleSize, 0, null);
|
||||
track.sampleIndex++;
|
||||
sampleBytesWritten = 0;
|
||||
|
@ -885,7 +885,7 @@ public final class WebmExtractor implements Extractor {
|
||||
bytesRead = Math.min(length, strippedBytesLeft);
|
||||
output.sampleData(sampleStrippedBytes, bytesRead);
|
||||
} else {
|
||||
bytesRead = output.sampleData(input, length);
|
||||
bytesRead = output.sampleData(input, length, false);
|
||||
}
|
||||
sampleBytesRead += bytesRead;
|
||||
sampleBytesWritten += bytesRead;
|
||||
|
Loading…
x
Reference in New Issue
Block a user