Rename SampleHolder to DecoderInputBuffer.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=118040127
This commit is contained in:
parent
98fb6d150d
commit
ce9b309aa1
@ -28,8 +28,8 @@ public class CTest extends TestCase {
|
||||
@SuppressLint("InlinedApi")
|
||||
public static final void testContants() {
|
||||
// Sanity check that constant values match those defined by the platform.
|
||||
assertEquals(MediaCodec.BUFFER_FLAG_KEY_FRAME, C.SAMPLE_FLAG_SYNC);
|
||||
assertEquals(MediaCodec.BUFFER_FLAG_END_OF_STREAM, C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
assertEquals(MediaCodec.BUFFER_FLAG_KEY_FRAME, C.BUFFER_FLAG_KEY_FRAME);
|
||||
assertEquals(MediaCodec.BUFFER_FLAG_END_OF_STREAM, C.BUFFER_FLAG_END_OF_STREAM);
|
||||
assertEquals(MediaCodec.CRYPTO_MODE_AES_CTR, C.CRYPTO_MODE_AES_CTR);
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public final class Mp4ExtractorTest extends TestCase {
|
||||
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
|
||||
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
|
||||
byte[] sampleData = getOutputSampleData(i, true);
|
||||
int sampleFlags = SAMPLE_IS_SYNC[i] ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
int sampleFlags = SAMPLE_IS_SYNC[i] ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
|
||||
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
|
||||
}
|
||||
@ -155,7 +155,7 @@ public final class Mp4ExtractorTest extends TestCase {
|
||||
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
|
||||
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
|
||||
byte[] sampleData = getOutputSampleData(i, true);
|
||||
int sampleFlags = C.SAMPLE_FLAG_SYNC;
|
||||
int sampleFlags = C.BUFFER_FLAG_KEY_FRAME;
|
||||
long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
|
||||
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
|
||||
}
|
||||
@ -182,7 +182,7 @@ public final class Mp4ExtractorTest extends TestCase {
|
||||
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
|
||||
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
|
||||
byte[] sampleData = getOutputSampleData(i, false);
|
||||
int sampleFlags = SAMPLE_IS_SYNC[i] ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
int sampleFlags = SAMPLE_IS_SYNC[i] ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
|
||||
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public class AdtsReaderTest extends TestCase {
|
||||
ADTS_CONTENT));
|
||||
feed();
|
||||
assertSampleCounts(0, 1);
|
||||
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
|
||||
public void testNoData() throws Exception {
|
||||
@ -120,20 +120,20 @@ public class AdtsReaderTest extends TestCase {
|
||||
public void testConsumeWholeId3Packet() throws Exception {
|
||||
feedLimited(ID3_DATA_1.length);
|
||||
assertSampleCounts(1, 0);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
|
||||
public void testMultiId3Packet() throws Exception {
|
||||
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length - 1);
|
||||
assertSampleCounts(1, 0);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
|
||||
public void testMultiId3PacketConsumed() throws Exception {
|
||||
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length);
|
||||
assertSampleCounts(2, 0);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(1, ID3_DATA_2, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(0, ID3_DATA_1, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
id3Output.assertSample(1, ID3_DATA_2, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
|
||||
public void testMultiPacketConsumed() throws Exception {
|
||||
@ -145,9 +145,9 @@ public class AdtsReaderTest extends TestCase {
|
||||
int j = i * 2;
|
||||
assertSampleCounts(j + 2, i + 1);
|
||||
|
||||
id3Output.assertSample(j, ID3_DATA_1, timeUs, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(j + 1, ID3_DATA_2, timeUs, C.SAMPLE_FLAG_SYNC, null);
|
||||
adtsOutput.assertSample(i, ADTS_CONTENT, timeUs, C.SAMPLE_FLAG_SYNC, null);
|
||||
id3Output.assertSample(j, ID3_DATA_1, timeUs, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
id3Output.assertSample(j + 1, ID3_DATA_2, timeUs, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
adtsOutput.assertSample(i, ADTS_CONTENT, timeUs, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ public class AdtsReaderTest extends TestCase {
|
||||
data.setPosition(ID3_DATA_1.length + ID3_DATA_2.length);
|
||||
feed();
|
||||
assertSampleCounts(0, 1);
|
||||
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.SAMPLE_FLAG_SYNC, null);
|
||||
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.BUFFER_FLAG_KEY_FRAME, null);
|
||||
}
|
||||
|
||||
private void feedLimited(int limit) {
|
||||
|
@ -788,9 +788,9 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
|
||||
StreamBuilder.TEST_INITIALIZATION_VECTOR, expectedMedia);
|
||||
}
|
||||
int flags = 0;
|
||||
flags |= keyframe ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
flags |= invisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0;
|
||||
flags |= encryptionKey != null ? C.SAMPLE_FLAG_ENCRYPTED : 0;
|
||||
flags |= keyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
flags |= invisible ? C.BUFFER_FLAG_DECODE_ONLY : 0;
|
||||
flags |= encryptionKey != null ? C.BUFFER_FLAG_ENCRYPTED : 0;
|
||||
output.assertSample(index, expectedMedia, timeUs, flags, encryptionKey);
|
||||
}
|
||||
|
||||
|
@ -88,26 +88,26 @@ public final class C {
|
||||
? AudioFormat.CHANNEL_OUT_7POINT1 : AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
|
||||
|
||||
/**
|
||||
* Indicates that a sample is a synchronization sample.
|
||||
* Indicates that a buffer holds a synchronization sample.
|
||||
*/
|
||||
@SuppressWarnings("InlinedApi")
|
||||
public static final int SAMPLE_FLAG_SYNC = MediaCodec.BUFFER_FLAG_KEY_FRAME;
|
||||
public static final int BUFFER_FLAG_KEY_FRAME = MediaCodec.BUFFER_FLAG_KEY_FRAME;
|
||||
|
||||
/**
|
||||
* Flag for empty buffers that signal that the end of the stream was reached.
|
||||
*/
|
||||
@SuppressWarnings("InlinedApi")
|
||||
public static final int SAMPLE_FLAG_END_OF_STREAM = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
||||
public static final int BUFFER_FLAG_END_OF_STREAM = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
|
||||
|
||||
/**
|
||||
* Indicates that a sample is (at least partially) encrypted.
|
||||
* Indicates that a buffer is (at least partially) encrypted.
|
||||
*/
|
||||
public static final int SAMPLE_FLAG_ENCRYPTED = 0x40000000;
|
||||
public static final int BUFFER_FLAG_ENCRYPTED = 0x40000000;
|
||||
|
||||
/**
|
||||
* Indicates that a sample should be decoded but not rendered.
|
||||
* Indicates that a buffer should be decoded but not rendered.
|
||||
*/
|
||||
public static final int SAMPLE_FLAG_DECODE_ONLY = 0x80000000;
|
||||
public static final int BUFFER_FLAG_DECODE_ONLY = 0x80000000;
|
||||
|
||||
/**
|
||||
* A return value for methods where the end of an input was encountered.
|
||||
|
@ -20,9 +20,9 @@ import com.google.android.exoplayer.util.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Holds sample data and corresponding metadata.
|
||||
* Holds input for a decoder and corresponding metadata.
|
||||
*/
|
||||
public class SampleHolder extends Buffer {
|
||||
public class DecoderInputBuffer extends Buffer {
|
||||
|
||||
/**
|
||||
* Disallows buffer replacement.
|
||||
@ -40,17 +40,17 @@ public class SampleHolder extends Buffer {
|
||||
public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2;
|
||||
|
||||
/**
|
||||
* {@link CryptoInfo} for encrypted samples.
|
||||
* {@link CryptoInfo} for encrypted data.
|
||||
*/
|
||||
public final CryptoInfo cryptoInfo;
|
||||
|
||||
/**
|
||||
* A buffer holding the sample data, or {@code null} if no sample data has been set.
|
||||
* The buffer's data, or {@code null} if no data has been set.
|
||||
*/
|
||||
public ByteBuffer data;
|
||||
|
||||
/**
|
||||
* The size of the sample in bytes.
|
||||
* The size of the data in bytes.
|
||||
*/
|
||||
public int size;
|
||||
|
||||
@ -66,7 +66,7 @@ public class SampleHolder extends Buffer {
|
||||
* of {@link #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} and
|
||||
* {@link #BUFFER_REPLACEMENT_MODE_DIRECT}.
|
||||
*/
|
||||
public SampleHolder(int bufferReplacementMode) {
|
||||
public DecoderInputBuffer(int bufferReplacementMode) {
|
||||
this.cryptoInfo = new CryptoInfo();
|
||||
this.bufferReplacementMode = bufferReplacementMode;
|
||||
}
|
||||
@ -85,7 +85,7 @@ public class SampleHolder extends Buffer {
|
||||
*/
|
||||
public void ensureSpaceForWrite(int length) throws IllegalStateException {
|
||||
if (data == null) {
|
||||
data = createReplacementBuffer(length);
|
||||
data = createReplacementByteBuffer(length);
|
||||
return;
|
||||
}
|
||||
// Check whether the current buffer is sufficient.
|
||||
@ -96,7 +96,7 @@ public class SampleHolder extends Buffer {
|
||||
return;
|
||||
}
|
||||
// Instantiate a new buffer if possible.
|
||||
ByteBuffer newData = createReplacementBuffer(requiredCapacity);
|
||||
ByteBuffer newData = createReplacementByteBuffer(requiredCapacity);
|
||||
// Copy data up to the current position from the old buffer to the new one.
|
||||
if (position > 0) {
|
||||
data.position(0);
|
||||
@ -108,10 +108,10 @@ public class SampleHolder extends Buffer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the sample has the {@link C#SAMPLE_FLAG_ENCRYPTED} flag set.
|
||||
* Returns whether the {@link C#BUFFER_FLAG_ENCRYPTED} flag is set.
|
||||
*/
|
||||
public final boolean isEncrypted() {
|
||||
return getFlag(C.SAMPLE_FLAG_ENCRYPTED);
|
||||
return getFlag(C.BUFFER_FLAG_ENCRYPTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,7 +122,7 @@ public class SampleHolder extends Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBuffer createReplacementBuffer(int requiredCapacity) {
|
||||
private ByteBuffer createReplacementByteBuffer(int requiredCapacity) {
|
||||
if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_NORMAL) {
|
||||
return ByteBuffer.allocate(requiredCapacity);
|
||||
} else if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DIRECT) {
|
@ -212,7 +212,7 @@ public final class FrameworkSampleSource implements SampleSource {
|
||||
return TrackStream.NO_RESET;
|
||||
}
|
||||
|
||||
/* package */ int readData(int track, FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
Assertions.checkState(trackStates[track] != TRACK_STATE_DISABLED);
|
||||
if (pendingResets[track]) {
|
||||
return TrackStream.NOTHING_READ;
|
||||
@ -225,28 +225,28 @@ public final class FrameworkSampleSource implements SampleSource {
|
||||
}
|
||||
int extractorTrackIndex = extractor.getSampleTrackIndex();
|
||||
if (extractorTrackIndex == track) {
|
||||
if (sampleHolder.data != null) {
|
||||
int offset = sampleHolder.data.position();
|
||||
sampleHolder.size = extractor.readSampleData(sampleHolder.data, offset);
|
||||
sampleHolder.data.position(offset + sampleHolder.size);
|
||||
if (buffer.data != null) {
|
||||
int offset = buffer.data.position();
|
||||
buffer.size = extractor.readSampleData(buffer.data, offset);
|
||||
buffer.data.position(offset + buffer.size);
|
||||
} else {
|
||||
sampleHolder.size = 0;
|
||||
buffer.size = 0;
|
||||
}
|
||||
sampleHolder.timeUs = extractor.getSampleTime();
|
||||
buffer.timeUs = extractor.getSampleTime();
|
||||
int flags = extractor.getSampleFlags();
|
||||
if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_SYNC);
|
||||
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
|
||||
}
|
||||
if ((flags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_ENCRYPTED);
|
||||
sampleHolder.cryptoInfo.setFromExtractorV16(extractor);
|
||||
buffer.addFlag(C.BUFFER_FLAG_ENCRYPTED);
|
||||
buffer.cryptoInfo.setFromExtractorV16(extractor);
|
||||
}
|
||||
pendingSeekPositionUs = C.UNKNOWN_TIME_US;
|
||||
extractor.advance();
|
||||
return TrackStream.SAMPLE_READ;
|
||||
return TrackStream.BUFFER_READ;
|
||||
} else if (extractorTrackIndex < 0) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return TrackStream.END_OF_STREAM;
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return TrackStream.BUFFER_READ;
|
||||
} else {
|
||||
return TrackStream.NOTHING_READ;
|
||||
}
|
||||
@ -392,8 +392,8 @@ public final class FrameworkSampleSource implements SampleSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
return FrameworkSampleSource.this.readData(track, formatHolder, sampleHolder);
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
return FrameworkSampleSource.this.readData(track, formatHolder, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
private final MediaCodecSelector mediaCodecSelector;
|
||||
private final DrmSessionManager drmSessionManager;
|
||||
private final boolean playClearSamplesWithoutKeys;
|
||||
private final SampleHolder sampleHolder;
|
||||
private final DecoderInputBuffer buffer;
|
||||
private final FormatHolder formatHolder;
|
||||
private final List<Long> decodeOnlyPresentationTimestamps;
|
||||
private final MediaCodec.BufferInfo outputBufferInfo;
|
||||
@ -255,7 +255,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
this.eventHandler = eventHandler;
|
||||
this.eventListener = eventListener;
|
||||
codecCounters = new CodecCounters();
|
||||
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||
formatHolder = new FormatHolder();
|
||||
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
||||
outputBufferInfo = new MediaCodec.BufferInfo();
|
||||
@ -554,8 +554,8 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
if (inputIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
sampleHolder.data = inputBuffers[inputIndex];
|
||||
sampleHolder.clear();
|
||||
buffer.data = inputBuffers[inputIndex];
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
|
||||
@ -574,19 +574,19 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
|
||||
int result;
|
||||
if (waitingForKeys) {
|
||||
// We've already read an encrypted sample into sampleHolder, and are waiting for keys.
|
||||
result = TrackStream.SAMPLE_READ;
|
||||
// We've already read an encrypted sample into buffer, and are waiting for keys.
|
||||
result = TrackStream.BUFFER_READ;
|
||||
} else {
|
||||
// For adaptive reconfiguration OMX decoders expect all reconfiguration data to be supplied
|
||||
// at the start of the buffer that also contains the first frame in the new format.
|
||||
if (codecReconfigurationState == RECONFIGURATION_STATE_WRITE_PENDING) {
|
||||
for (int i = 0; i < format.initializationData.size(); i++) {
|
||||
byte[] data = format.initializationData.get(i);
|
||||
sampleHolder.data.put(data);
|
||||
buffer.data.put(data);
|
||||
}
|
||||
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
|
||||
}
|
||||
result = readSource(formatHolder, sampleHolder);
|
||||
result = readSource(formatHolder, buffer);
|
||||
if (firstFeed && sourceState == SOURCE_STATE_READY && result == TrackStream.NOTHING_READ) {
|
||||
sourceState = SOURCE_STATE_READY_READ_MAY_FAIL;
|
||||
}
|
||||
@ -599,18 +599,20 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
|
||||
// We received two formats in a row. Clear the current buffer of any reconfiguration data
|
||||
// associated with the first format.
|
||||
sampleHolder.clear();
|
||||
buffer.clear();
|
||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||
}
|
||||
onInputFormatChanged(formatHolder);
|
||||
return true;
|
||||
}
|
||||
if (result == TrackStream.END_OF_STREAM) {
|
||||
|
||||
// We've read a buffer.
|
||||
if (buffer.isEndOfStream()) {
|
||||
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
|
||||
// We received a new format immediately before the end of the stream. We need to clear
|
||||
// the corresponding reconfiguration data from the current buffer, but re-write it into
|
||||
// a subsequent buffer if there are any (e.g. if the user seeks backwards).
|
||||
sampleHolder.clear();
|
||||
buffer.clear();
|
||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||
}
|
||||
inputStreamEnded = true;
|
||||
@ -632,30 +634,30 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean sampleEncrypted = sampleHolder.isEncrypted();
|
||||
waitingForKeys = shouldWaitForKeys(sampleEncrypted);
|
||||
boolean bufferEncrypted = buffer.isEncrypted();
|
||||
waitingForKeys = shouldWaitForKeys(bufferEncrypted);
|
||||
if (waitingForKeys) {
|
||||
return false;
|
||||
}
|
||||
if (codecNeedsDiscardToSpsWorkaround && !sampleEncrypted) {
|
||||
NalUnitUtil.discardToSps(sampleHolder.data);
|
||||
if (sampleHolder.data.position() == 0) {
|
||||
if (codecNeedsDiscardToSpsWorkaround && !bufferEncrypted) {
|
||||
NalUnitUtil.discardToSps(buffer.data);
|
||||
if (buffer.data.position() == 0) {
|
||||
return true;
|
||||
}
|
||||
codecNeedsDiscardToSpsWorkaround = false;
|
||||
}
|
||||
try {
|
||||
int bufferSize = sampleHolder.data.position();
|
||||
int adaptiveReconfigurationBytes = bufferSize - sampleHolder.size;
|
||||
long presentationTimeUs = sampleHolder.timeUs;
|
||||
if (sampleHolder.isDecodeOnly()) {
|
||||
int bufferSize = buffer.data.position();
|
||||
int adaptiveReconfigurationBytes = bufferSize - buffer.size;
|
||||
long presentationTimeUs = buffer.timeUs;
|
||||
if (buffer.isDecodeOnly()) {
|
||||
decodeOnlyPresentationTimestamps.add(presentationTimeUs);
|
||||
}
|
||||
|
||||
onQueuedInputBuffer(presentationTimeUs, sampleHolder.data, bufferSize, sampleEncrypted);
|
||||
onQueuedInputBuffer(presentationTimeUs, buffer.data, bufferSize, bufferEncrypted);
|
||||
|
||||
if (sampleEncrypted) {
|
||||
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(sampleHolder,
|
||||
if (bufferEncrypted) {
|
||||
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer,
|
||||
adaptiveReconfigurationBytes);
|
||||
codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0);
|
||||
} else {
|
||||
@ -672,9 +674,9 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
return true;
|
||||
}
|
||||
|
||||
private static MediaCodec.CryptoInfo getFrameworkCryptoInfo(SampleHolder sampleHolder,
|
||||
private static MediaCodec.CryptoInfo getFrameworkCryptoInfo(DecoderInputBuffer buffer,
|
||||
int adaptiveReconfigurationBytes) {
|
||||
MediaCodec.CryptoInfo cryptoInfo = sampleHolder.cryptoInfo.getFrameworkCryptoInfoV16();
|
||||
MediaCodec.CryptoInfo cryptoInfo = buffer.cryptoInfo.getFrameworkCryptoInfoV16();
|
||||
if (adaptiveReconfigurationBytes == 0) {
|
||||
return cryptoInfo;
|
||||
}
|
||||
@ -688,7 +690,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
return cryptoInfo;
|
||||
}
|
||||
|
||||
private boolean shouldWaitForKeys(boolean sampleEncrypted) throws ExoPlaybackException {
|
||||
private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
|
||||
if (!openedDrmSession) {
|
||||
return false;
|
||||
}
|
||||
@ -697,7 +699,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
throw ExoPlaybackException.createForRenderer(drmSessionManager.getError(), getIndex());
|
||||
}
|
||||
if (drmManagerState != DrmSessionManager.STATE_OPENED_WITH_KEYS &&
|
||||
(sampleEncrypted || !playClearSamplesWithoutKeys)) {
|
||||
(bufferEncrypted || !playClearSamplesWithoutKeys)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -758,11 +760,11 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||
*
|
||||
* @param presentationTimeUs The timestamp associated with the input buffer.
|
||||
* @param buffer The buffer to be queued.
|
||||
* @param bufferSize the size of the sample data stored in the buffer.
|
||||
* @param sampleEncrypted Whether the sample data is encrypted.
|
||||
* @param bufferSize The size of the sample data stored in the buffer.
|
||||
* @param bufferEncrypted Whether the buffer is encrypted.
|
||||
*/
|
||||
protected void onQueuedInputBuffer(
|
||||
long presentationTimeUs, ByteBuffer buffer, int bufferSize, boolean sampleEncrypted) {
|
||||
protected void onQueuedInputBuffer(long presentationTimeUs, ByteBuffer buffer, int bufferSize,
|
||||
boolean bufferEncrypted) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
@ -64,18 +64,10 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
|
||||
/**
|
||||
* Reads from the enabled upstream source.
|
||||
*
|
||||
* @param formatHolder A {@link FormatHolder} object to populate in the case of a new format.
|
||||
* @param sampleHolder A {@link SampleHolder} object to populate in the case of a new sample.
|
||||
* If the caller requires the sample data then it must ensure that {@link SampleHolder#data}
|
||||
* references a valid output buffer. If the end of the stream has been reached,
|
||||
* {@link TrackStream#END_OF_STREAM} will be returned and {@link C#SAMPLE_FLAG_END_OF_STREAM}
|
||||
* will be set on the sample holder.
|
||||
* @return The result, which can be {@link TrackStream#SAMPLE_READ},
|
||||
* {@link TrackStream#FORMAT_READ}, {@link TrackStream#NOTHING_READ} or
|
||||
* {@link TrackStream#END_OF_STREAM}.
|
||||
* @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
|
||||
*/
|
||||
protected final int readSource(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
return trackStream.readData(formatHolder, sampleHolder);
|
||||
protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
return trackStream.readData(formatHolder, buffer);
|
||||
}
|
||||
|
||||
// Abstract methods.
|
||||
|
@ -186,10 +186,10 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (streamState == STREAM_STATE_END_OF_STREAM) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return END_OF_STREAM;
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return BUFFER_READ;
|
||||
} else if (streamState == STREAM_STATE_SEND_FORMAT) {
|
||||
formatHolder.format = format;
|
||||
streamState = STREAM_STATE_SEND_SAMPLE;
|
||||
@ -200,13 +200,13 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
|
||||
if (!loadingFinished) {
|
||||
return NOTHING_READ;
|
||||
} else {
|
||||
sampleHolder.timeUs = 0;
|
||||
sampleHolder.size = sampleSize;
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_SYNC);
|
||||
sampleHolder.ensureSpaceForWrite(sampleHolder.size);
|
||||
sampleHolder.data.put(sampleData, 0, sampleSize);
|
||||
buffer.timeUs = 0;
|
||||
buffer.size = sampleSize;
|
||||
buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
|
||||
buffer.ensureSpaceForWrite(buffer.size);
|
||||
buffer.data.put(sampleData, 0, sampleSize);
|
||||
streamState = STREAM_STATE_END_OF_STREAM;
|
||||
return SAMPLE_READ;
|
||||
return BUFFER_READ;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,22 +22,18 @@ import java.io.IOException;
|
||||
*/
|
||||
public interface TrackStream {
|
||||
|
||||
/**
|
||||
* The end of stream has been reached.
|
||||
*/
|
||||
int END_OF_STREAM = -1;
|
||||
/**
|
||||
* Nothing was read.
|
||||
*/
|
||||
int NOTHING_READ = -2;
|
||||
int NOTHING_READ = -1;
|
||||
/**
|
||||
* A sample was read.
|
||||
* The buffer was populated.
|
||||
*/
|
||||
int SAMPLE_READ = -3;
|
||||
int BUFFER_READ = -2;
|
||||
/**
|
||||
* A format was read.
|
||||
*/
|
||||
int FORMAT_READ = -4;
|
||||
int FORMAT_READ = -3;
|
||||
/**
|
||||
* Returned from {@link #readReset()} to indicate no reset is required.
|
||||
*/
|
||||
@ -46,8 +42,8 @@ public interface TrackStream {
|
||||
/**
|
||||
* Returns whether data is available to be read.
|
||||
* <p>
|
||||
* Note: If the stream has ended then {@link #END_OF_STREAM} can always be read from
|
||||
* {@link #readData(FormatHolder, SampleHolder)}. Hence an ended stream is always ready.
|
||||
* Note: If the stream has ended then a buffer with the end of stream flag can always be read from
|
||||
* {@link #readData(FormatHolder, DecoderInputBuffer)}. Hence an ended stream is always ready.
|
||||
*
|
||||
* @return True if data is available to be read. False otherwise.
|
||||
*/
|
||||
@ -69,20 +65,19 @@ public interface TrackStream {
|
||||
long readReset();
|
||||
|
||||
/**
|
||||
* Attempts to read the next format or sample.
|
||||
* Attempts to read from the stream.
|
||||
* <p>
|
||||
* This method will always return {@link #NOTHING_READ} in the case that there's a pending
|
||||
* discontinuity to be read from {@link #readReset} for the specified track.
|
||||
*
|
||||
* @param formatHolder A {@link FormatHolder} to populate in the case of a new format.
|
||||
* @param sampleHolder A {@link SampleHolder} to populate in the case of a new sample. If the
|
||||
* caller requires the sample data then it must ensure that {@link SampleHolder#data}
|
||||
* references a valid output buffer. If the end of the stream has been reached,
|
||||
* {@link #END_OF_STREAM} will be returned and {@link C#SAMPLE_FLAG_END_OF_STREAM} will be set
|
||||
* on the sample holder.
|
||||
* @return The result, which can be {@link #END_OF_STREAM}, {@link #NOTHING_READ},
|
||||
* {@link #FORMAT_READ} or {@link #SAMPLE_READ}.
|
||||
* @param formatHolder A {@link FormatHolder} to populate in the case of reading a format.
|
||||
* @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
|
||||
* end of the stream. If the caller requires the sample data then it must ensure that
|
||||
* {@link DecoderInputBuffer#data} references a valid buffer. If the end of the stream has
|
||||
* been reached, the {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
|
||||
* @return The result, which can be {@link #NOTHING_READ}, {@link #FORMAT_READ} or
|
||||
* {@link #BUFFER_READ}.
|
||||
*/
|
||||
int readData(FormatHolder formatHolder, SampleHolder sampleHolder);
|
||||
int readData(FormatHolder formatHolder, DecoderInputBuffer buffer);
|
||||
|
||||
}
|
||||
|
@ -16,10 +16,10 @@
|
||||
package com.google.android.exoplayer.chunk;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.LoadControl;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -246,7 +246,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (pendingReset || isPendingReset()) {
|
||||
return NOTHING_READ;
|
||||
}
|
||||
@ -277,18 +277,18 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
||||
|
||||
if (!haveSamples) {
|
||||
if (loadingFinished) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return END_OF_STREAM;
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return BUFFER_READ;
|
||||
}
|
||||
return NOTHING_READ;
|
||||
}
|
||||
|
||||
if (sampleQueue.getSample(sampleHolder)) {
|
||||
if (sampleHolder.timeUs < lastSeekPositionUs) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
|
||||
if (sampleQueue.getSample(buffer)) {
|
||||
if (buffer.timeUs < lastSeekPositionUs) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
onSampleRead(currentChunk, sampleHolder);
|
||||
return SAMPLE_READ;
|
||||
onSampleRead(currentChunk, buffer);
|
||||
return BUFFER_READ;
|
||||
}
|
||||
|
||||
return NOTHING_READ;
|
||||
@ -395,9 +395,9 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
|
||||
* the sample is returned.
|
||||
*
|
||||
* @param mediaChunk The chunk from which the sample was obtained.
|
||||
* @param sampleHolder Holds the read sample.
|
||||
* @param buffer Holds the read sample.
|
||||
*/
|
||||
protected void onSampleRead(MediaChunk mediaChunk, SampleHolder sampleHolder) {
|
||||
protected void onSampleRead(MediaChunk mediaChunk, DecoderInputBuffer buffer) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
|
||||
result = getOutput().sampleData(extractorInput, Integer.MAX_VALUE, true);
|
||||
}
|
||||
int sampleSize = bytesLoaded;
|
||||
getOutput().sampleMetadata(startTimeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
getOutput().sampleMetadata(startTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
} finally {
|
||||
dataSource.close();
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.extractor;
|
||||
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.upstream.Allocator;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
|
||||
@ -29,7 +29,7 @@ import java.io.IOException;
|
||||
public class DefaultTrackOutput implements TrackOutput {
|
||||
|
||||
private final RollingSampleBuffer rollingBuffer;
|
||||
private final SampleHolder sampleInfoHolder;
|
||||
private final DecoderInputBuffer sampleBuffer;
|
||||
|
||||
// Accessed only by the consuming thread.
|
||||
private boolean needKeyframe;
|
||||
@ -45,7 +45,7 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
*/
|
||||
public DefaultTrackOutput(Allocator allocator) {
|
||||
rollingBuffer = new RollingSampleBuffer(allocator);
|
||||
sampleInfoHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||
sampleBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||
needKeyframe = true;
|
||||
lastReadTimeUs = Long.MIN_VALUE;
|
||||
spliceOutTimeUs = Long.MIN_VALUE;
|
||||
@ -79,7 +79,7 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
*/
|
||||
public void discardUpstreamSamples(int discardFromIndex) {
|
||||
rollingBuffer.discardUpstreamSamples(discardFromIndex);
|
||||
largestParsedTimestampUs = rollingBuffer.peekSample(sampleInfoHolder) ? sampleInfoHolder.timeUs
|
||||
largestParsedTimestampUs = rollingBuffer.peekSample(sampleBuffer) ? sampleBuffer.timeUs
|
||||
: Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
@ -122,23 +122,23 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the next sample from the head of the queue, writing it into the provided holder.
|
||||
* Removes the next sample from the head of the queue, writing it into the provided buffer.
|
||||
* <p>
|
||||
* The first sample returned is guaranteed to be a keyframe, since any non-keyframe samples
|
||||
* queued prior to the first keyframe are discarded.
|
||||
*
|
||||
* @param holder A {@link SampleHolder} into which the sample should be read.
|
||||
* @param buffer A {@link DecoderInputBuffer} into which the sample should be read.
|
||||
* @return True if a sample was read. False otherwise.
|
||||
*/
|
||||
public boolean getSample(SampleHolder holder) {
|
||||
public boolean getSample(DecoderInputBuffer buffer) {
|
||||
boolean foundEligibleSample = advanceToEligibleSample();
|
||||
if (!foundEligibleSample) {
|
||||
return false;
|
||||
}
|
||||
// Write the sample into the holder.
|
||||
rollingBuffer.readSample(holder);
|
||||
// Write the sample into the buffer.
|
||||
rollingBuffer.readSample(buffer);
|
||||
needKeyframe = false;
|
||||
lastReadTimeUs = holder.timeUs;
|
||||
lastReadTimeUs = buffer.timeUs;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
* @param timeUs The time up to which samples should be discarded, in microseconds.
|
||||
*/
|
||||
public void discardUntil(long timeUs) {
|
||||
while (rollingBuffer.peekSample(sampleInfoHolder) && sampleInfoHolder.timeUs < timeUs) {
|
||||
while (rollingBuffer.peekSample(sampleBuffer) && sampleBuffer.timeUs < timeUs) {
|
||||
rollingBuffer.skipSample();
|
||||
// We're discarding one or more samples. A subsequent read will need to start at a keyframe.
|
||||
needKeyframe = true;
|
||||
@ -178,22 +178,22 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
return true;
|
||||
}
|
||||
long firstPossibleSpliceTime;
|
||||
if (rollingBuffer.peekSample(sampleInfoHolder)) {
|
||||
firstPossibleSpliceTime = sampleInfoHolder.timeUs;
|
||||
if (rollingBuffer.peekSample(sampleBuffer)) {
|
||||
firstPossibleSpliceTime = sampleBuffer.timeUs;
|
||||
} else {
|
||||
firstPossibleSpliceTime = lastReadTimeUs + 1;
|
||||
}
|
||||
RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer;
|
||||
while (nextRollingBuffer.peekSample(sampleInfoHolder)
|
||||
&& (sampleInfoHolder.timeUs < firstPossibleSpliceTime || !sampleInfoHolder.isSyncFrame())) {
|
||||
while (nextRollingBuffer.peekSample(sampleBuffer)
|
||||
&& (sampleBuffer.timeUs < firstPossibleSpliceTime || !sampleBuffer.isKeyFrame())) {
|
||||
// Discard samples from the next queue for as long as they are before the earliest possible
|
||||
// splice time, or not keyframes.
|
||||
nextRollingBuffer.skipSample();
|
||||
}
|
||||
if (nextRollingBuffer.peekSample(sampleInfoHolder)) {
|
||||
if (nextRollingBuffer.peekSample(sampleBuffer)) {
|
||||
// We've found a keyframe in the next queue that can serve as the splice point. Set the
|
||||
// splice point now.
|
||||
spliceOutTimeUs = sampleInfoHolder.timeUs;
|
||||
spliceOutTimeUs = sampleBuffer.timeUs;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -206,17 +206,17 @@ public class DefaultTrackOutput implements TrackOutput {
|
||||
* buffer has been emptied.
|
||||
*/
|
||||
private boolean advanceToEligibleSample() {
|
||||
boolean haveNext = rollingBuffer.peekSample(sampleInfoHolder);
|
||||
boolean haveNext = rollingBuffer.peekSample(sampleBuffer);
|
||||
if (needKeyframe) {
|
||||
while (haveNext && !sampleInfoHolder.isSyncFrame()) {
|
||||
while (haveNext && !sampleBuffer.isKeyFrame()) {
|
||||
rollingBuffer.skipSample();
|
||||
haveNext = rollingBuffer.peekSample(sampleInfoHolder);
|
||||
haveNext = rollingBuffer.peekSample(sampleBuffer);
|
||||
}
|
||||
}
|
||||
if (!haveNext) {
|
||||
return false;
|
||||
}
|
||||
if (spliceOutTimeUs != Long.MIN_VALUE && sampleInfoHolder.timeUs >= spliceOutTimeUs) {
|
||||
if (spliceOutTimeUs != Long.MIN_VALUE && sampleBuffer.timeUs >= spliceOutTimeUs) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -16,9 +16,9 @@
|
||||
package com.google.android.exoplayer.extractor;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.ParserException;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -445,7 +445,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
return TrackStream.NO_RESET;
|
||||
}
|
||||
|
||||
/* package */ int readData(int track, FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
/* package */ int readData(int track, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (pendingResets[track] || isPendingReset()) {
|
||||
return TrackStream.NOTHING_READ;
|
||||
}
|
||||
@ -458,22 +458,22 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
return TrackStream.FORMAT_READ;
|
||||
}
|
||||
|
||||
if (sampleQueue.getSample(sampleHolder)) {
|
||||
if (sampleHolder.timeUs < lastSeekPositionUs) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
|
||||
if (sampleQueue.getSample(buffer)) {
|
||||
if (buffer.timeUs < lastSeekPositionUs) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
if (havePendingNextSampleUs) {
|
||||
// Set the offset to make the timestamp of this sample equal to pendingNextSampleUs.
|
||||
sampleTimeOffsetUs = pendingNextSampleUs - sampleHolder.timeUs;
|
||||
sampleTimeOffsetUs = pendingNextSampleUs - buffer.timeUs;
|
||||
havePendingNextSampleUs = false;
|
||||
}
|
||||
sampleHolder.timeUs += sampleTimeOffsetUs;
|
||||
return TrackStream.SAMPLE_READ;
|
||||
buffer.timeUs += sampleTimeOffsetUs;
|
||||
return TrackStream.BUFFER_READ;
|
||||
}
|
||||
|
||||
if (loadingFinished) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return TrackStream.END_OF_STREAM;
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return TrackStream.BUFFER_READ;
|
||||
}
|
||||
|
||||
return TrackStream.NOTHING_READ;
|
||||
@ -764,8 +764,8 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
return ExtractorSampleSource.this.readData(track, formatHolder, sampleHolder);
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
return ExtractorSampleSource.this.readData(track, formatHolder, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
package com.google.android.exoplayer.extractor;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.upstream.Allocation;
|
||||
import com.google.android.exoplayer.upstream.Allocator;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
@ -40,7 +40,7 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
private final InfoQueue infoQueue;
|
||||
private final LinkedBlockingDeque<Allocation> dataQueue;
|
||||
private final SampleExtrasHolder extrasHolder;
|
||||
private final BufferExtrasHolder extrasHolder;
|
||||
private final ParsableByteArray scratch;
|
||||
|
||||
// Accessed only by the consuming thread.
|
||||
@ -59,7 +59,7 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
allocationLength = allocator.getIndividualAllocationLength();
|
||||
infoQueue = new InfoQueue();
|
||||
dataQueue = new LinkedBlockingDeque<>();
|
||||
extrasHolder = new SampleExtrasHolder();
|
||||
extrasHolder = new BufferExtrasHolder();
|
||||
scratch = new ParsableByteArray(INITIAL_SCRATCH_SIZE);
|
||||
lastAllocationOffset = allocationLength;
|
||||
}
|
||||
@ -133,15 +133,16 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills {@code holder} with information about the current sample, but does not write its data.
|
||||
* Fills {@code buffer} with information about the current sample, but does not write its data.
|
||||
* <p>
|
||||
* Populates {@link SampleHolder#size}, {@link SampleHolder#timeUs} and the sample flags.
|
||||
* Populates {@link DecoderInputBuffer#size}, {@link DecoderInputBuffer#timeUs} and the buffer
|
||||
* flags.
|
||||
*
|
||||
* @param holder The holder into which the current sample information should be written.
|
||||
* @return True if the holder was filled. False if there is no current sample.
|
||||
* @param buffer The buffer into which the current sample information should be written.
|
||||
* @return True if the buffer was filled. False if there is no current sample.
|
||||
*/
|
||||
public boolean peekSample(SampleHolder holder) {
|
||||
return infoQueue.peekSample(holder, extrasHolder);
|
||||
public boolean peekSample(DecoderInputBuffer buffer) {
|
||||
return infoQueue.peekSample(buffer, extrasHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,23 +171,23 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
/**
|
||||
* Reads the current sample, advancing the read index to the next sample.
|
||||
*
|
||||
* @param sampleHolder The holder into which the current sample should be written.
|
||||
* @param buffer The buffer into which the current sample should be written.
|
||||
* @return True if a sample was read. False if there is no current sample.
|
||||
*/
|
||||
public boolean readSample(SampleHolder sampleHolder) {
|
||||
// Write the sample information into the holder and extrasHolder.
|
||||
boolean haveSample = infoQueue.peekSample(sampleHolder, extrasHolder);
|
||||
public boolean readSample(DecoderInputBuffer buffer) {
|
||||
// Write the sample information into the buffer and extrasHolder.
|
||||
boolean haveSample = infoQueue.peekSample(buffer, extrasHolder);
|
||||
if (!haveSample) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read encryption data if the sample is encrypted.
|
||||
if (sampleHolder.isEncrypted()) {
|
||||
readEncryptionData(sampleHolder, extrasHolder);
|
||||
if (buffer.isEncrypted()) {
|
||||
readEncryptionData(buffer, extrasHolder);
|
||||
}
|
||||
// Write the sample data into the holder.
|
||||
sampleHolder.ensureSpaceForWrite(sampleHolder.size);
|
||||
readData(extrasHolder.offset, sampleHolder.data, sampleHolder.size);
|
||||
buffer.ensureSpaceForWrite(buffer.size);
|
||||
readData(extrasHolder.offset, buffer.data, buffer.size);
|
||||
// Advance the read head.
|
||||
long nextOffset = infoQueue.moveToNextSample();
|
||||
dropDownstreamTo(nextOffset);
|
||||
@ -196,14 +197,14 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
/**
|
||||
* Reads encryption data for the current sample.
|
||||
* <p>
|
||||
* The encryption data is written into {@code sampleHolder.cryptoInfo}, and
|
||||
* {@code sampleHolder.size} is adjusted to subtract the number of bytes that were read. The
|
||||
* same value is added to {@code extrasHolder.offset}.
|
||||
* The encryption data is written into {@link DecoderInputBuffer#cryptoInfo}, and
|
||||
* {@link DecoderInputBuffer#size} is adjusted to subtract the number of bytes that were read. The
|
||||
* same value is added to {@link BufferExtrasHolder#offset}.
|
||||
*
|
||||
* @param sampleHolder The holder into which the encryption data should be written.
|
||||
* @param buffer The buffer into which the encryption data should be written.
|
||||
* @param extrasHolder The extras holder whose offset should be read and subsequently adjusted.
|
||||
*/
|
||||
private void readEncryptionData(SampleHolder sampleHolder, SampleExtrasHolder extrasHolder) {
|
||||
private void readEncryptionData(DecoderInputBuffer buffer, BufferExtrasHolder extrasHolder) {
|
||||
long offset = extrasHolder.offset;
|
||||
|
||||
// Read the signal byte.
|
||||
@ -214,10 +215,10 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
int ivSize = signalByte & 0x7F;
|
||||
|
||||
// Read the initialization vector.
|
||||
if (sampleHolder.cryptoInfo.iv == null) {
|
||||
sampleHolder.cryptoInfo.iv = new byte[16];
|
||||
if (buffer.cryptoInfo.iv == null) {
|
||||
buffer.cryptoInfo.iv = new byte[16];
|
||||
}
|
||||
readData(offset, sampleHolder.cryptoInfo.iv, ivSize);
|
||||
readData(offset, buffer.cryptoInfo.iv, ivSize);
|
||||
offset += ivSize;
|
||||
|
||||
// Read the subsample count, if present.
|
||||
@ -232,11 +233,11 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
|
||||
// Write the clear and encrypted subsample sizes.
|
||||
int[] clearDataSizes = sampleHolder.cryptoInfo.numBytesOfClearData;
|
||||
int[] clearDataSizes = buffer.cryptoInfo.numBytesOfClearData;
|
||||
if (clearDataSizes == null || clearDataSizes.length < subsampleCount) {
|
||||
clearDataSizes = new int[subsampleCount];
|
||||
}
|
||||
int[] encryptedDataSizes = sampleHolder.cryptoInfo.numBytesOfEncryptedData;
|
||||
int[] encryptedDataSizes = buffer.cryptoInfo.numBytesOfEncryptedData;
|
||||
if (encryptedDataSizes == null || encryptedDataSizes.length < subsampleCount) {
|
||||
encryptedDataSizes = new int[subsampleCount];
|
||||
}
|
||||
@ -252,17 +253,17 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
} else {
|
||||
clearDataSizes[0] = 0;
|
||||
encryptedDataSizes[0] = sampleHolder.size - (int) (offset - extrasHolder.offset);
|
||||
encryptedDataSizes[0] = buffer.size - (int) (offset - extrasHolder.offset);
|
||||
}
|
||||
|
||||
// Populate the cryptoInfo.
|
||||
sampleHolder.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes,
|
||||
extrasHolder.encryptionKeyId, sampleHolder.cryptoInfo.iv, C.CRYPTO_MODE_AES_CTR);
|
||||
buffer.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes,
|
||||
extrasHolder.encryptionKeyId, buffer.cryptoInfo.iv, C.CRYPTO_MODE_AES_CTR);
|
||||
|
||||
// Adjust the offset and size to take into account the bytes read.
|
||||
int bytesRead = (int) (offset - extrasHolder.offset);
|
||||
extrasHolder.offset += bytesRead;
|
||||
sampleHolder.size -= bytesRead;
|
||||
buffer.size -= bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,7 +419,7 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
* Indicates the end point for the current sample, making it available for consumption.
|
||||
*
|
||||
* @param sampleTimeUs The sample timestamp.
|
||||
* @param flags Flags that accompany the sample. See {@code C.SAMPLE_FLAG_*}.
|
||||
* @param flags Flags that accompany the sample. See {@code C.BUFFER_FLAG_*}.
|
||||
* @param position The position of the sample data in the rolling buffer.
|
||||
* @param size The size of the sample, in bytes.
|
||||
* @param encryptionKey The encryption key associated with the sample, or null.
|
||||
@ -523,24 +524,25 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills {@code holder} with information about the current sample, but does not write its data.
|
||||
* The first entry in {@code offsetHolder} is filled with the absolute position of the sample's
|
||||
* data in the rolling buffer.
|
||||
* <p>
|
||||
* Populates {@link SampleHolder#size}, {@link SampleHolder#timeUs}, the sample flags and
|
||||
* Fills {@code buffer} with information about the current sample, but does not write its data.
|
||||
* The absolute position of the sample's data in the rolling buffer is stored in
|
||||
* {@code extrasHolder}.
|
||||
* <p>
|
||||
* Populates {@link DecoderInputBuffer#size}, {@link DecoderInputBuffer#timeUs}, the buffer
|
||||
* flags and {@code extrasHolder}.
|
||||
*
|
||||
* @param holder The holder into which the current sample information should be written.
|
||||
* @param buffer The buffer into which the current sample information should be written.
|
||||
* @param extrasHolder The holder into which extra sample information should be written.
|
||||
* @return True if the holders were filled. False if there is no current sample.
|
||||
* @return True if the buffer and extras were filled. False if there is no current sample.
|
||||
*/
|
||||
public synchronized boolean peekSample(SampleHolder holder, SampleExtrasHolder extrasHolder) {
|
||||
public synchronized boolean peekSample(DecoderInputBuffer buffer,
|
||||
BufferExtrasHolder extrasHolder) {
|
||||
if (queueSize == 0) {
|
||||
return false;
|
||||
}
|
||||
holder.timeUs = timesUs[relativeReadIndex];
|
||||
holder.size = sizes[relativeReadIndex];
|
||||
holder.setFlags(flags[relativeReadIndex]);
|
||||
buffer.timeUs = timesUs[relativeReadIndex];
|
||||
buffer.size = sizes[relativeReadIndex];
|
||||
buffer.setFlags(flags[relativeReadIndex]);
|
||||
extrasHolder.offset = offsets[relativeReadIndex];
|
||||
extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex];
|
||||
return true;
|
||||
@ -590,7 +592,7 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
if (timesUs[searchIndex] > timeUs) {
|
||||
// We've gone too far.
|
||||
break;
|
||||
} else if ((flags[searchIndex] & C.SAMPLE_FLAG_SYNC) != 0) {
|
||||
} else if ((flags[searchIndex] & C.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
// We've found a keyframe, and we're still before the seek position.
|
||||
sampleCountToKeyframe = sampleCount;
|
||||
}
|
||||
@ -660,9 +662,9 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds additional sample information not held by {@link SampleHolder}.
|
||||
* Holds additional buffer information not held by {@link DecoderInputBuffer}.
|
||||
*/
|
||||
private static final class SampleExtrasHolder {
|
||||
private static final class BufferExtrasHolder {
|
||||
|
||||
public long offset;
|
||||
public byte[] encryptionKeyId;
|
||||
|
@ -65,7 +65,7 @@ public interface TrackOutput {
|
||||
* {@link #sampleData(ParsableByteArray, int)}.
|
||||
*
|
||||
* @param timeUs The media timestamp associated with the sample, in microseconds.
|
||||
* @param flags Flags associated with the sample. See {@code C.SAMPLE_FLAG_*}.
|
||||
* @param flags Flags associated with the sample. See {@code C.BUFFER_FLAG_*}.
|
||||
* @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, boolean)} or
|
||||
|
@ -95,7 +95,7 @@ import java.util.Collections;
|
||||
// Sample audio AAC frames
|
||||
int bytesToWrite = data.bytesLeft();
|
||||
output.sampleData(data, bytesToWrite);
|
||||
output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, bytesToWrite, 0, null);
|
||||
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, bytesToWrite, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ import java.util.List;
|
||||
output.sampleData(data, bytesToWrite);
|
||||
bytesWritten += bytesToWrite;
|
||||
}
|
||||
output.sampleMetadata(timeUs, frameType == VIDEO_FRAME_KEYFRAME ? C.SAMPLE_FLAG_SYNC : 0,
|
||||
output.sampleMetadata(timeUs, frameType == VIDEO_FRAME_KEYFRAME ? C.BUFFER_FLAG_KEY_FRAME : 0,
|
||||
bytesWritten, 0, null);
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +151,8 @@ public final class Mp3Extractor implements Extractor {
|
||||
return RESULT_CONTINUE;
|
||||
}
|
||||
long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate);
|
||||
trackOutput.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, synchronizedHeader.frameSize, 0, null);
|
||||
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, synchronizedHeader.frameSize, 0,
|
||||
null);
|
||||
samplesRead += synchronizedHeader.samplesPerFrame;
|
||||
sampleBytesRemaining = 0;
|
||||
return RESULT_CONTINUE;
|
||||
|
@ -196,9 +196,9 @@ import java.util.List;
|
||||
timestamps[i] = timestampTimeUnits + timestampOffset;
|
||||
|
||||
// All samples are synchronization samples if the stss is not present.
|
||||
flags[i] = stss == null ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
flags[i] = stss == null ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
if (i == nextSynchronizationSampleIndex) {
|
||||
flags[i] = C.SAMPLE_FLAG_SYNC;
|
||||
flags[i] = C.BUFFER_FLAG_KEY_FRAME;
|
||||
remainingSynchronizationSamples--;
|
||||
if (remainingSynchronizationSamples > 0) {
|
||||
nextSynchronizationSampleIndex = stss.readUnsignedIntToInt() - 1;
|
||||
@ -330,7 +330,7 @@ import java.util.List;
|
||||
|
||||
boolean hasSyncSample = false;
|
||||
for (int i = 0; i < editedFlags.length && !hasSyncSample; i++) {
|
||||
hasSyncSample |= (editedFlags[i] & C.SAMPLE_FLAG_SYNC) != 0;
|
||||
hasSyncSample |= (editedFlags[i] & C.BUFFER_FLAG_KEY_FRAME) != 0;
|
||||
}
|
||||
if (!hasSyncSample) {
|
||||
throw new ParserException("The edited sample sequence does not contain a sync sample.");
|
||||
|
@ -874,8 +874,8 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
}
|
||||
|
||||
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
|
||||
int sampleFlags = (fragment.definesEncryptionData ? C.SAMPLE_FLAG_ENCRYPTED : 0)
|
||||
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.SAMPLE_FLAG_SYNC : 0);
|
||||
int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0)
|
||||
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0);
|
||||
int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex;
|
||||
byte[] encryptionKey = fragment.definesEncryptionData
|
||||
? track.sampleDescriptionEncryptionBoxes[sampleDescriptionIndex].keyId : null;
|
||||
|
@ -79,7 +79,7 @@ import com.google.android.exoplayer.util.Util;
|
||||
// Frames are not reordered past synchronization samples so this works in practice.
|
||||
int startIndex = Util.binarySearchFloor(timestampsUs, timeUs, true, false);
|
||||
for (int i = startIndex; i >= 0; i--) {
|
||||
if ((flags[i] & C.SAMPLE_FLAG_SYNC) != 0) {
|
||||
if ((flags[i] & C.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -96,7 +96,7 @@ import com.google.android.exoplayer.util.Util;
|
||||
public int getIndexOfLaterOrEqualSynchronizationSample(long timeUs) {
|
||||
int startIndex = Util.binarySearchCeil(timestampsUs, timeUs, true, false);
|
||||
for (int i = startIndex; i < timestampsUs.length; i++) {
|
||||
if ((flags[i] & C.SAMPLE_FLAG_SYNC) != 0) {
|
||||
if ((flags[i] & C.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ public final class OggVorbisExtractor implements Extractor, SeekMap {
|
||||
// Calculate time and send audio data to codec.
|
||||
long timeUs = elapsedSamples * C.MICROS_PER_SECOND / vorbisSetup.idHeader.sampleRate;
|
||||
trackOutput.sampleData(scratch, scratch.limit());
|
||||
trackOutput.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, scratch.limit(), 0, null);
|
||||
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, scratch.limit(), 0, null);
|
||||
targetGranule = -1;
|
||||
}
|
||||
// Update state in members for next iteration.
|
||||
|
@ -103,7 +103,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
output.sampleData(data, bytesToRead);
|
||||
bytesRead += bytesToRead;
|
||||
if (bytesRead == sampleSize) {
|
||||
output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
timeUs += sampleDurationUs;
|
||||
state = STATE_FINDING_SYNC;
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ import java.util.Collections;
|
||||
currentOutput.sampleData(data, bytesToRead);
|
||||
bytesRead += bytesToRead;
|
||||
if (bytesRead == sampleSize) {
|
||||
currentOutput.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
currentOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
timeUs += currentSampleDuration;
|
||||
setFindingSampleState();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
output.sampleData(data, bytesToRead);
|
||||
bytesRead += bytesToRead;
|
||||
if (bytesRead == sampleSize) {
|
||||
output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
timeUs += sampleDurationUs;
|
||||
state = STATE_FINDING_SYNC;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ import java.util.Collections;
|
||||
if (hasOutputFormat && (startCodeValue == START_GROUP || startCodeValue == START_PICTURE)) {
|
||||
int bytesWrittenPastStartCode = limit - startCodeOffset;
|
||||
if (foundFirstFrameInGroup) {
|
||||
int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
int flags = isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
int size = (int) (totalBytesWritten - framePosition) - bytesWrittenPastStartCode;
|
||||
output.sampleMetadata(frameTimeUs, flags, size, bytesWrittenPastStartCode, null);
|
||||
isKeyframe = false;
|
||||
|
@ -431,7 +431,7 @@ import java.util.List;
|
||||
}
|
||||
|
||||
private void outputSample(int offset) {
|
||||
int flags = sampleIsKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
int flags = sampleIsKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
int size = (int) (nalUnitStartPosition - samplePosition);
|
||||
output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ import java.util.Collections;
|
||||
}
|
||||
|
||||
private void outputSample(int offset) {
|
||||
int flags = sampleIsKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
|
||||
int flags = sampleIsKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
|
||||
int size = (int) (nalUnitStartPosition - samplePosition);
|
||||
output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
if (!writingSample || sampleSize == 0 || sampleBytesRead != sampleSize) {
|
||||
return;
|
||||
}
|
||||
output.sampleMetadata(sampleTimeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
writingSample = false;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
return;
|
||||
}
|
||||
|
||||
output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, frameSize, 0, null);
|
||||
output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, frameSize, 0, null);
|
||||
timeUs += frameDurationUs;
|
||||
frameBytesRead = 0;
|
||||
state = STATE_FINDING_HEADER;
|
||||
|
@ -55,7 +55,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
// Process the payload.
|
||||
if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) {
|
||||
output.sampleData(seiBuffer, payloadSize);
|
||||
output.sampleMetadata(pesTimeUs, C.SAMPLE_FLAG_SYNC, payloadSize, 0, null);
|
||||
output.sampleMetadata(pesTimeUs, C.BUFFER_FLAG_KEY_FRAME, payloadSize, 0, null);
|
||||
} else {
|
||||
seiBuffer.skipBytes(payloadSize);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public final class WavExtractor implements Extractor, SeekMap {
|
||||
}
|
||||
|
||||
trackOutput.sampleMetadata(
|
||||
wavHeader.getTimeUs(inputPosition), C.SAMPLE_FLAG_SYNC, bytesRead, 0, null);
|
||||
wavHeader.getTimeUs(inputPosition), C.BUFFER_FLAG_KEY_FRAME, bytesRead, 0, null);
|
||||
return RESULT_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ public final class WebmExtractor implements Extractor {
|
||||
}
|
||||
// If the ReferenceBlock element was not found for this sample, then it is a keyframe.
|
||||
if (!sampleSeenReferenceBlock) {
|
||||
blockFlags |= C.SAMPLE_FLAG_SYNC;
|
||||
blockFlags |= C.BUFFER_FLAG_KEY_FRAME;
|
||||
}
|
||||
commitSampleToOutput(tracks.get(blockTrackNumber), blockTimeUs);
|
||||
blockState = BLOCK_STATE_START;
|
||||
@ -766,8 +766,8 @@ public final class WebmExtractor implements Extractor {
|
||||
boolean isInvisible = (scratch.data[2] & 0x08) == 0x08;
|
||||
boolean isKeyframe = track.type == TRACK_TYPE_AUDIO
|
||||
|| (id == ID_SIMPLE_BLOCK && (scratch.data[2] & 0x80) == 0x80);
|
||||
blockFlags = (isKeyframe ? C.SAMPLE_FLAG_SYNC : 0)
|
||||
| (isInvisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0);
|
||||
blockFlags = (isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0)
|
||||
| (isInvisible ? C.BUFFER_FLAG_DECODE_ONLY : 0);
|
||||
blockState = BLOCK_STATE_DATA;
|
||||
blockLacingSampleIndex = 0;
|
||||
}
|
||||
@ -850,7 +850,7 @@ public final class WebmExtractor implements Extractor {
|
||||
if (track.hasContentEncryption) {
|
||||
// If the sample is encrypted, read its encryption signal byte and set the IV size.
|
||||
// Clear the encrypted flag.
|
||||
blockFlags &= ~C.SAMPLE_FLAG_ENCRYPTED;
|
||||
blockFlags &= ~C.BUFFER_FLAG_ENCRYPTED;
|
||||
input.readFully(scratch.data, 0, 1);
|
||||
sampleBytesRead++;
|
||||
if ((scratch.data[0] & 0x80) == 0x80) {
|
||||
@ -861,7 +861,7 @@ public final class WebmExtractor implements Extractor {
|
||||
scratch.setPosition(0);
|
||||
output.sampleData(scratch, 1);
|
||||
sampleBytesWritten++;
|
||||
blockFlags |= C.SAMPLE_FLAG_ENCRYPTED;
|
||||
blockFlags |= C.BUFFER_FLAG_ENCRYPTED;
|
||||
}
|
||||
} else if (track.sampleStrippedBytes != null) {
|
||||
// If the sample has header stripping, prepare to read/output the stripped bytes first.
|
||||
|
@ -15,8 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.hls;
|
||||
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.drm.DrmInitData;
|
||||
import com.google.android.exoplayer.extractor.DefaultTrackOutput;
|
||||
import com.google.android.exoplayer.extractor.Extractor;
|
||||
@ -182,12 +182,12 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
* This method must only be called after the extractor has been prepared.
|
||||
*
|
||||
* @param track The track from which to read.
|
||||
* @param holder A {@link SampleHolder} into which the sample should be read.
|
||||
* @param buffer A {@link DecoderInputBuffer} to populate with a sample.
|
||||
* @return True if a sample was read. False otherwise.
|
||||
*/
|
||||
public boolean getSample(int track, SampleHolder holder) {
|
||||
public boolean getSample(int track, DecoderInputBuffer buffer) {
|
||||
Assertions.checkState(isPrepared());
|
||||
return sampleQueues.valueAt(track).getSample(holder);
|
||||
return sampleQueues.valueAt(track).getSample(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,13 +204,13 @@ public final class HlsExtractorWrapper implements ExtractorOutput {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether samples are available for reading from {@link #getSample(int, SampleHolder)} for the
|
||||
* specified track.
|
||||
* Whether samples are available for reading from {@link #getSample(int, DecoderInputBuffer)} for
|
||||
* the specified track.
|
||||
* <p>
|
||||
* This method must only be called after the extractor has been prepared.
|
||||
*
|
||||
* @return True if samples are available for reading from {@link #getSample(int, SampleHolder)}
|
||||
* for the specified track. False otherwise.
|
||||
* @return True if samples are available for reading from
|
||||
* {@link #getSample(int, DecoderInputBuffer)} for the specified track. False otherwise.
|
||||
*/
|
||||
public boolean hasSamples(int track) {
|
||||
Assertions.checkState(isPrepared());
|
||||
|
@ -16,10 +16,10 @@
|
||||
package com.google.android.exoplayer.hls;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.LoadControl;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.SampleSource;
|
||||
import com.google.android.exoplayer.TrackGroup;
|
||||
import com.google.android.exoplayer.TrackGroupArray;
|
||||
@ -293,7 +293,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
||||
return TrackStream.NO_RESET;
|
||||
}
|
||||
|
||||
/* package */ int readData(int group, FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
/* package */ int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
if (pendingResets[group] || isPendingReset()) {
|
||||
return TrackStream.NOTHING_READ;
|
||||
}
|
||||
@ -332,16 +332,16 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
||||
return TrackStream.FORMAT_READ;
|
||||
}
|
||||
|
||||
if (extractor.getSample(group, sampleHolder)) {
|
||||
if (sampleHolder.timeUs < lastSeekPositionUs) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
|
||||
if (extractor.getSample(group, buffer)) {
|
||||
if (buffer.timeUs < lastSeekPositionUs) {
|
||||
buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
return TrackStream.SAMPLE_READ;
|
||||
return TrackStream.BUFFER_READ;
|
||||
}
|
||||
|
||||
if (loadingFinished) {
|
||||
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return TrackStream.END_OF_STREAM;
|
||||
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return TrackStream.BUFFER_READ;
|
||||
}
|
||||
|
||||
return TrackStream.NOTHING_READ;
|
||||
@ -836,8 +836,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
|
||||
return HlsSampleSource.this.readData(group, formatHolder, sampleHolder);
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
|
||||
return HlsSampleSource.this.readData(group, formatHolder, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ import java.util.regex.Pattern;
|
||||
// Output the sample.
|
||||
sampleDataWrapper.reset(sampleData, sampleSize);
|
||||
trackOutput.sampleData(sampleDataWrapper, sampleSize);
|
||||
trackOutput.sampleMetadata(sampleTimeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null);
|
||||
trackOutput.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
|
||||
}
|
||||
|
||||
private TrackOutput buildTrackOutput(long subsampleOffsetUs) {
|
||||
|
@ -15,10 +15,10 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.metadata;
|
||||
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.ExoPlaybackException;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.SampleSourceTrackRenderer;
|
||||
import com.google.android.exoplayer.TrackRenderer;
|
||||
import com.google.android.exoplayer.TrackStream;
|
||||
@ -60,7 +60,7 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
|
||||
private final MetadataRenderer<T> metadataRenderer;
|
||||
private final Handler metadataHandler;
|
||||
private final FormatHolder formatHolder;
|
||||
private final SampleHolder sampleHolder;
|
||||
private final DecoderInputBuffer buffer;
|
||||
|
||||
private boolean inputStreamEnded;
|
||||
private long pendingMetadataTimestamp;
|
||||
@ -82,7 +82,7 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
|
||||
this.metadataHandler = metadataRendererLooper == null ? null
|
||||
: new Handler(metadataRendererLooper, this);
|
||||
formatHolder = new FormatHolder();
|
||||
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,17 +101,19 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
|
||||
protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
|
||||
throws ExoPlaybackException {
|
||||
if (!inputStreamEnded && pendingMetadata == null) {
|
||||
sampleHolder.clear();
|
||||
int result = readSource(formatHolder, sampleHolder);
|
||||
if (result == TrackStream.SAMPLE_READ) {
|
||||
pendingMetadataTimestamp = sampleHolder.timeUs;
|
||||
try {
|
||||
pendingMetadata = metadataParser.parse(sampleHolder.data.array(), sampleHolder.size);
|
||||
} catch (IOException e) {
|
||||
throw ExoPlaybackException.createForRenderer(e, getIndex());
|
||||
buffer.clear();
|
||||
int result = readSource(formatHolder, buffer);
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
} else {
|
||||
pendingMetadataTimestamp = buffer.timeUs;
|
||||
try {
|
||||
pendingMetadata = metadataParser.parse(buffer.data.array(), buffer.size);
|
||||
} catch (IOException e) {
|
||||
throw ExoPlaybackException.createForRenderer(e, getIndex());
|
||||
}
|
||||
}
|
||||
} else if (result == TrackStream.END_OF_STREAM) {
|
||||
inputStreamEnded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,17 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.text;
|
||||
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
|
||||
/**
|
||||
* An input buffer for {@link SubtitleParser}.
|
||||
*/
|
||||
/* package */ final class SubtitleInputBuffer extends SampleHolder {
|
||||
/* package */ final class SubtitleInputBuffer extends DecoderInputBuffer {
|
||||
|
||||
public long subsampleOffsetUs;
|
||||
|
||||
public SubtitleInputBuffer() {
|
||||
super(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
super(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -176,11 +176,14 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
|
||||
}
|
||||
// Try and read the next subtitle from the source.
|
||||
int result = readSource(formatHolder, nextInputBuffer);
|
||||
if (result == TrackStream.SAMPLE_READ) {
|
||||
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
|
||||
parser.queueInputBuffer(nextInputBuffer);
|
||||
} else if (result == TrackStream.END_OF_STREAM) {
|
||||
inputStreamEnded = true;
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (nextInputBuffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
// TODO: Queue the end of stream buffer.
|
||||
} else {
|
||||
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
|
||||
parser.queueInputBuffer(nextInputBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ParserException e) {
|
||||
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.text.eia608;
|
||||
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
import com.google.android.exoplayer.util.ParsableBitArray;
|
||||
import com.google.android.exoplayer.util.ParsableByteArray;
|
||||
@ -116,14 +116,14 @@ public final class Eia608Parser {
|
||||
return mimeType.equals(MimeTypes.APPLICATION_EIA608);
|
||||
}
|
||||
|
||||
/* package */ ClosedCaptionList parse(SampleHolder sampleHolder) {
|
||||
if (sampleHolder.size < 10) {
|
||||
/* package */ ClosedCaptionList parse(DecoderInputBuffer buffer) {
|
||||
if (buffer.size < 10) {
|
||||
return null;
|
||||
}
|
||||
|
||||
captions.clear();
|
||||
stringBuilder.setLength(0);
|
||||
seiBuffer.reset(sampleHolder.data.array());
|
||||
seiBuffer.reset(buffer.data.array());
|
||||
|
||||
// country_code (8) + provider_code (16) + user_identifier (32) + user_data_type_code (8) +
|
||||
// reserved (1) + process_cc_data_flag (1) + zero_bit (1)
|
||||
@ -200,7 +200,7 @@ public final class Eia608Parser {
|
||||
|
||||
ClosedCaption[] captionArray = new ClosedCaption[captions.size()];
|
||||
captions.toArray(captionArray);
|
||||
return new ClosedCaptionList(sampleHolder.timeUs, sampleHolder.isDecodeOnly(), captionArray);
|
||||
return new ClosedCaptionList(buffer.timeUs, buffer.isDecodeOnly(), captionArray);
|
||||
}
|
||||
|
||||
private static char getChar(byte ccData) {
|
||||
|
@ -16,10 +16,10 @@
|
||||
package com.google.android.exoplayer.text.eia608;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.ExoPlaybackException;
|
||||
import com.google.android.exoplayer.Format;
|
||||
import com.google.android.exoplayer.FormatHolder;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.SampleSourceTrackRenderer;
|
||||
import com.google.android.exoplayer.TrackRenderer;
|
||||
import com.google.android.exoplayer.TrackStream;
|
||||
@ -51,13 +51,13 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
// The default number of rows to display in roll-up captions mode.
|
||||
private static final int DEFAULT_CAPTIONS_ROW_COUNT = 4;
|
||||
// The maximum duration that captions are parsed ahead of the current position.
|
||||
private static final int MAX_SAMPLE_READAHEAD_US = 5000000;
|
||||
private static final int MAX_BUFFER_READAHEAD_US = 5000000;
|
||||
|
||||
private final Eia608Parser eia608Parser;
|
||||
private final TextRenderer textRenderer;
|
||||
private final Handler textRendererHandler;
|
||||
private final FormatHolder formatHolder;
|
||||
private final SampleHolder sampleHolder;
|
||||
private final DecoderInputBuffer buffer;
|
||||
private final StringBuilder captionStringBuilder;
|
||||
private final TreeSet<ClosedCaptionList> pendingCaptionLists;
|
||||
|
||||
@ -81,7 +81,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
textRendererHandler = textRendererLooper == null ? null : new Handler(textRendererLooper, this);
|
||||
eia608Parser = new Eia608Parser();
|
||||
formatHolder = new FormatHolder();
|
||||
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
|
||||
captionStringBuilder = new StringBuilder();
|
||||
pendingCaptionLists = new TreeSet<>();
|
||||
}
|
||||
@ -97,7 +97,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
inputStreamEnded = false;
|
||||
repeatableControl = null;
|
||||
pendingCaptionLists.clear();
|
||||
clearPendingSample();
|
||||
clearPendingBuffer();
|
||||
captionRowCount = DEFAULT_CAPTIONS_ROW_COUNT;
|
||||
setCaptionMode(CC_MODE_UNKNOWN);
|
||||
invokeRenderer(null);
|
||||
@ -106,17 +106,20 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
@Override
|
||||
protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
|
||||
throws ExoPlaybackException {
|
||||
if (isSamplePending()) {
|
||||
maybeParsePendingSample(positionUs);
|
||||
if (isBufferPending()) {
|
||||
maybeParsePendingBuffer(positionUs);
|
||||
}
|
||||
|
||||
int result = inputStreamEnded ? TrackStream.END_OF_STREAM : TrackStream.SAMPLE_READ;
|
||||
while (!isSamplePending() && result == TrackStream.SAMPLE_READ) {
|
||||
result = readSource(formatHolder, sampleHolder);
|
||||
if (result == TrackStream.SAMPLE_READ) {
|
||||
maybeParsePendingSample(positionUs);
|
||||
} else if (result == TrackStream.END_OF_STREAM) {
|
||||
inputStreamEnded = true;
|
||||
while (!isBufferPending() && !inputStreamEnded) {
|
||||
int result = readSource(formatHolder, buffer);
|
||||
if (result == TrackStream.BUFFER_READ) {
|
||||
if (buffer.isEndOfStream()) {
|
||||
inputStreamEnded = true;
|
||||
} else {
|
||||
maybeParsePendingBuffer(positionUs);
|
||||
}
|
||||
} else if (result == TrackStream.NOTHING_READ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,13 +180,13 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeParsePendingSample(long positionUs) {
|
||||
if (sampleHolder.timeUs > positionUs + MAX_SAMPLE_READAHEAD_US) {
|
||||
// We're too early to parse the sample.
|
||||
private void maybeParsePendingBuffer(long positionUs) {
|
||||
if (buffer.timeUs > positionUs + MAX_BUFFER_READAHEAD_US) {
|
||||
// We're too early to parse the buffer.
|
||||
return;
|
||||
}
|
||||
ClosedCaptionList holder = eia608Parser.parse(sampleHolder);
|
||||
clearPendingSample();
|
||||
ClosedCaptionList holder = eia608Parser.parse(buffer);
|
||||
clearPendingBuffer();
|
||||
if (holder != null) {
|
||||
pendingCaptionLists.add(holder);
|
||||
}
|
||||
@ -338,13 +341,13 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
|
||||
return captionStringBuilder.substring(0, endIndex - startIndex);
|
||||
}
|
||||
|
||||
private void clearPendingSample() {
|
||||
sampleHolder.clear();
|
||||
sampleHolder.timeUs = C.UNKNOWN_TIME_US;
|
||||
private void clearPendingBuffer() {
|
||||
buffer.clear();
|
||||
buffer.timeUs = C.UNKNOWN_TIME_US;
|
||||
}
|
||||
|
||||
private boolean isSamplePending() {
|
||||
return sampleHolder.timeUs != C.UNKNOWN_TIME_US;
|
||||
private boolean isBufferPending() {
|
||||
return buffer.timeUs != C.UNKNOWN_TIME_US;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,30 +32,30 @@ public abstract class Buffer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link C#SAMPLE_FLAG_DECODE_ONLY} flag is set.
|
||||
* Returns whether the {@link C#BUFFER_FLAG_DECODE_ONLY} flag is set.
|
||||
*/
|
||||
public final boolean isDecodeOnly() {
|
||||
return getFlag(C.SAMPLE_FLAG_DECODE_ONLY);
|
||||
return getFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link C#SAMPLE_FLAG_END_OF_STREAM} flag is set.
|
||||
* Returns whether the {@link C#BUFFER_FLAG_END_OF_STREAM} flag is set.
|
||||
*/
|
||||
public final boolean isEndOfStream() {
|
||||
return getFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
return getFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the sample has the {@link C#SAMPLE_FLAG_SYNC} flag set.
|
||||
* Returns whether the {@link C#BUFFER_FLAG_KEY_FRAME} flag is set.
|
||||
*/
|
||||
public final boolean isSyncFrame() {
|
||||
return getFlag(C.SAMPLE_FLAG_SYNC);
|
||||
public final boolean isKeyFrame() {
|
||||
return getFlag(C.BUFFER_FLAG_KEY_FRAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces this buffer's flags with {@code flags}.
|
||||
*
|
||||
* @param flags The flags to set, which should be a combination of the {@code C.SAMPLE_FLAG_*}
|
||||
* @param flags The flags to set, which should be a combination of the {@code C.BUFFER_FLAG_*}
|
||||
* constants.
|
||||
*/
|
||||
public final void setFlags(int flags) {
|
||||
@ -66,7 +66,7 @@ public abstract class Buffer {
|
||||
* Adds the {@code flag} to this buffer's flags.
|
||||
*
|
||||
* @param flag The flag to add to this buffer's flags, which should be one of the
|
||||
* {@code C.SAMPLE_FLAG_*} constants.
|
||||
* {@code C.BUFFER_FLAG_*} constants.
|
||||
*/
|
||||
public final void addFlag(int flag) {
|
||||
flags |= flag;
|
||||
|
@ -16,7 +16,7 @@
|
||||
package com.google.android.exoplayer.util.extensions;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.SampleHolder;
|
||||
import com.google.android.exoplayer.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer.util.Assertions;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@ -24,7 +24,7 @@ import java.util.LinkedList;
|
||||
/**
|
||||
* Base class for {@link Decoder}s that use their own decode thread.
|
||||
*/
|
||||
public abstract class SimpleDecoder<I extends SampleHolder, O extends OutputBuffer,
|
||||
public abstract class SimpleDecoder<I extends DecoderInputBuffer, O extends OutputBuffer,
|
||||
E extends Exception> extends Thread implements Decoder<I, O, E> {
|
||||
|
||||
/**
|
||||
@ -218,10 +218,10 @@ public abstract class SimpleDecoder<I extends SampleHolder, O extends OutputBuff
|
||||
}
|
||||
|
||||
if (inputBuffer.isEndOfStream()) {
|
||||
outputBuffer.addFlag(C.SAMPLE_FLAG_END_OF_STREAM);
|
||||
outputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
} else {
|
||||
if (inputBuffer.isDecodeOnly()) {
|
||||
outputBuffer.addFlag(C.SAMPLE_FLAG_DECODE_ONLY);
|
||||
outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
|
||||
}
|
||||
exception = decode(inputBuffer, outputBuffer);
|
||||
if (exception != null) {
|
||||
@ -276,7 +276,7 @@ public abstract class SimpleDecoder<I extends SampleHolder, O extends OutputBuff
|
||||
*
|
||||
* @param inputBuffer The buffer to decode.
|
||||
* @param outputBuffer The output buffer to store decoded data. The flag
|
||||
* {@link C#SAMPLE_FLAG_DECODE_ONLY} will be set if the same flag is set on
|
||||
* {@link C#BUFFER_FLAG_DECODE_ONLY} will be set if the same flag is set on
|
||||
* {@code inputBuffer}, but the decoder may set/unset the flag if required. If the flag is set
|
||||
* after this method returns, any output will not be presented.
|
||||
* @return A decoder exception if an error occurred, or null if decoding was successful.
|
||||
|
Loading…
x
Reference in New Issue
Block a user