Rename SampleHolder to DecoderInputBuffer.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=118040127
This commit is contained in:
andrewlewis 2016-03-24 10:18:30 -07:00 committed by Oliver Woodman
parent 98fb6d150d
commit ce9b309aa1
45 changed files with 322 additions and 322 deletions

View File

@ -28,8 +28,8 @@ public class CTest extends TestCase {
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
public static final void testContants() { public static final void testContants() {
// Sanity check that constant values match those defined by the platform. // 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_KEY_FRAME, C.BUFFER_FLAG_KEY_FRAME);
assertEquals(MediaCodec.BUFFER_FLAG_END_OF_STREAM, C.SAMPLE_FLAG_END_OF_STREAM); assertEquals(MediaCodec.BUFFER_FLAG_END_OF_STREAM, C.BUFFER_FLAG_END_OF_STREAM);
assertEquals(MediaCodec.CRYPTO_MODE_AES_CTR, C.CRYPTO_MODE_AES_CTR); assertEquals(MediaCodec.CRYPTO_MODE_AES_CTR, C.CRYPTO_MODE_AES_CTR);
} }

View File

@ -137,7 +137,7 @@ public final class Mp4ExtractorTest extends TestCase {
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length); videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) { for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
byte[] sampleData = getOutputSampleData(i, true); 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]); long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null); videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
} }
@ -155,7 +155,7 @@ public final class Mp4ExtractorTest extends TestCase {
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length); videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) { for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
byte[] sampleData = getOutputSampleData(i, true); byte[] sampleData = getOutputSampleData(i, true);
int sampleFlags = C.SAMPLE_FLAG_SYNC; int sampleFlags = C.BUFFER_FLAG_KEY_FRAME;
long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]); long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null); videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
} }
@ -182,7 +182,7 @@ public final class Mp4ExtractorTest extends TestCase {
videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length); videoTrackOutput.assertSampleCount(SAMPLE_TIMESTAMPS.length);
for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) { for (int i = 0; i < SAMPLE_TIMESTAMPS.length; i++) {
byte[] sampleData = getOutputSampleData(i, false); 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]); long sampleTimestampUs = getVideoTimestampUs(SAMPLE_TIMESTAMPS[i]);
videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null); videoTrackOutput.assertSample(i, sampleData, sampleTimestampUs, sampleFlags, null);
} }

View File

@ -94,7 +94,7 @@ public class AdtsReaderTest extends TestCase {
ADTS_CONTENT)); ADTS_CONTENT));
feed(); feed();
assertSampleCounts(0, 1); 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 { public void testNoData() throws Exception {
@ -120,20 +120,20 @@ public class AdtsReaderTest extends TestCase {
public void testConsumeWholeId3Packet() throws Exception { public void testConsumeWholeId3Packet() throws Exception {
feedLimited(ID3_DATA_1.length); feedLimited(ID3_DATA_1.length);
assertSampleCounts(1, 0); 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 { public void testMultiId3Packet() throws Exception {
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length - 1); feedLimited(ID3_DATA_1.length + ID3_DATA_2.length - 1);
assertSampleCounts(1, 0); 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 { public void testMultiId3PacketConsumed() throws Exception {
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length); feedLimited(ID3_DATA_1.length + ID3_DATA_2.length);
assertSampleCounts(2, 0); assertSampleCounts(2, 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);
id3Output.assertSample(1, ID3_DATA_2, 0, C.SAMPLE_FLAG_SYNC, null); id3Output.assertSample(1, ID3_DATA_2, 0, C.BUFFER_FLAG_KEY_FRAME, null);
} }
public void testMultiPacketConsumed() throws Exception { public void testMultiPacketConsumed() throws Exception {
@ -145,9 +145,9 @@ public class AdtsReaderTest extends TestCase {
int j = i * 2; int j = i * 2;
assertSampleCounts(j + 2, i + 1); assertSampleCounts(j + 2, i + 1);
id3Output.assertSample(j, ID3_DATA_1, 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.SAMPLE_FLAG_SYNC, null); id3Output.assertSample(j + 1, ID3_DATA_2, timeUs, C.BUFFER_FLAG_KEY_FRAME, null);
adtsOutput.assertSample(i, ADTS_CONTENT, timeUs, C.SAMPLE_FLAG_SYNC, 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); data.setPosition(ID3_DATA_1.length + ID3_DATA_2.length);
feed(); feed();
assertSampleCounts(0, 1); 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) { private void feedLimited(int limit) {

View File

@ -788,9 +788,9 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
StreamBuilder.TEST_INITIALIZATION_VECTOR, expectedMedia); StreamBuilder.TEST_INITIALIZATION_VECTOR, expectedMedia);
} }
int flags = 0; int flags = 0;
flags |= keyframe ? C.SAMPLE_FLAG_SYNC : 0; flags |= keyframe ? C.BUFFER_FLAG_KEY_FRAME : 0;
flags |= invisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0; flags |= invisible ? C.BUFFER_FLAG_DECODE_ONLY : 0;
flags |= encryptionKey != null ? C.SAMPLE_FLAG_ENCRYPTED : 0; flags |= encryptionKey != null ? C.BUFFER_FLAG_ENCRYPTED : 0;
output.assertSample(index, expectedMedia, timeUs, flags, encryptionKey); output.assertSample(index, expectedMedia, timeUs, flags, encryptionKey);
} }

View File

@ -88,26 +88,26 @@ public final class C {
? AudioFormat.CHANNEL_OUT_7POINT1 : AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; ? 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") @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. * Flag for empty buffers that signal that the end of the stream was reached.
*/ */
@SuppressWarnings("InlinedApi") @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. * A return value for methods where the end of an input was encountered.

View File

@ -20,9 +20,9 @@ import com.google.android.exoplayer.util.Buffer;
import java.nio.ByteBuffer; 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. * Disallows buffer replacement.
@ -40,17 +40,17 @@ public class SampleHolder extends Buffer {
public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2; public static final int BUFFER_REPLACEMENT_MODE_DIRECT = 2;
/** /**
* {@link CryptoInfo} for encrypted samples. * {@link CryptoInfo} for encrypted data.
*/ */
public final CryptoInfo cryptoInfo; 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; public ByteBuffer data;
/** /**
* The size of the sample in bytes. * The size of the data in bytes.
*/ */
public int size; public int size;
@ -66,7 +66,7 @@ public class SampleHolder extends Buffer {
* of {@link #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} and * of {@link #BUFFER_REPLACEMENT_MODE_DISABLED}, {@link #BUFFER_REPLACEMENT_MODE_NORMAL} and
* {@link #BUFFER_REPLACEMENT_MODE_DIRECT}. * {@link #BUFFER_REPLACEMENT_MODE_DIRECT}.
*/ */
public SampleHolder(int bufferReplacementMode) { public DecoderInputBuffer(int bufferReplacementMode) {
this.cryptoInfo = new CryptoInfo(); this.cryptoInfo = new CryptoInfo();
this.bufferReplacementMode = bufferReplacementMode; this.bufferReplacementMode = bufferReplacementMode;
} }
@ -85,7 +85,7 @@ public class SampleHolder extends Buffer {
*/ */
public void ensureSpaceForWrite(int length) throws IllegalStateException { public void ensureSpaceForWrite(int length) throws IllegalStateException {
if (data == null) { if (data == null) {
data = createReplacementBuffer(length); data = createReplacementByteBuffer(length);
return; return;
} }
// Check whether the current buffer is sufficient. // Check whether the current buffer is sufficient.
@ -96,7 +96,7 @@ public class SampleHolder extends Buffer {
return; return;
} }
// Instantiate a new buffer if possible. // 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. // Copy data up to the current position from the old buffer to the new one.
if (position > 0) { if (position > 0) {
data.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() { public final boolean isEncrypted() {
return getFlag(C.SAMPLE_FLAG_ENCRYPTED); return getFlag(C.BUFFER_FLAG_ENCRYPTED);
} }
@Override @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) { if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_NORMAL) {
return ByteBuffer.allocate(requiredCapacity); return ByteBuffer.allocate(requiredCapacity);
} else if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DIRECT) { } else if (bufferReplacementMode == BUFFER_REPLACEMENT_MODE_DIRECT) {

View File

@ -212,7 +212,7 @@ public final class FrameworkSampleSource implements SampleSource {
return TrackStream.NO_RESET; 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); Assertions.checkState(trackStates[track] != TRACK_STATE_DISABLED);
if (pendingResets[track]) { if (pendingResets[track]) {
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
@ -225,28 +225,28 @@ public final class FrameworkSampleSource implements SampleSource {
} }
int extractorTrackIndex = extractor.getSampleTrackIndex(); int extractorTrackIndex = extractor.getSampleTrackIndex();
if (extractorTrackIndex == track) { if (extractorTrackIndex == track) {
if (sampleHolder.data != null) { if (buffer.data != null) {
int offset = sampleHolder.data.position(); int offset = buffer.data.position();
sampleHolder.size = extractor.readSampleData(sampleHolder.data, offset); buffer.size = extractor.readSampleData(buffer.data, offset);
sampleHolder.data.position(offset + sampleHolder.size); buffer.data.position(offset + buffer.size);
} else { } else {
sampleHolder.size = 0; buffer.size = 0;
} }
sampleHolder.timeUs = extractor.getSampleTime(); buffer.timeUs = extractor.getSampleTime();
int flags = extractor.getSampleFlags(); int flags = extractor.getSampleFlags();
if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) { 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) { if ((flags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) {
sampleHolder.addFlag(C.SAMPLE_FLAG_ENCRYPTED); buffer.addFlag(C.BUFFER_FLAG_ENCRYPTED);
sampleHolder.cryptoInfo.setFromExtractorV16(extractor); buffer.cryptoInfo.setFromExtractorV16(extractor);
} }
pendingSeekPositionUs = C.UNKNOWN_TIME_US; pendingSeekPositionUs = C.UNKNOWN_TIME_US;
extractor.advance(); extractor.advance();
return TrackStream.SAMPLE_READ; return TrackStream.BUFFER_READ;
} else if (extractorTrackIndex < 0) { } else if (extractorTrackIndex < 0) {
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.BUFFER_READ;
} else { } else {
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
} }
@ -392,8 +392,8 @@ public final class FrameworkSampleSource implements SampleSource {
} }
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return FrameworkSampleSource.this.readData(track, formatHolder, sampleHolder); return FrameworkSampleSource.this.readData(track, formatHolder, buffer);
} }
} }

View File

@ -199,7 +199,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
private final MediaCodecSelector mediaCodecSelector; private final MediaCodecSelector mediaCodecSelector;
private final DrmSessionManager drmSessionManager; private final DrmSessionManager drmSessionManager;
private final boolean playClearSamplesWithoutKeys; private final boolean playClearSamplesWithoutKeys;
private final SampleHolder sampleHolder; private final DecoderInputBuffer buffer;
private final FormatHolder formatHolder; private final FormatHolder formatHolder;
private final List<Long> decodeOnlyPresentationTimestamps; private final List<Long> decodeOnlyPresentationTimestamps;
private final MediaCodec.BufferInfo outputBufferInfo; private final MediaCodec.BufferInfo outputBufferInfo;
@ -255,7 +255,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.eventListener = eventListener; this.eventListener = eventListener;
codecCounters = new CodecCounters(); codecCounters = new CodecCounters();
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
decodeOnlyPresentationTimestamps = new ArrayList<>(); decodeOnlyPresentationTimestamps = new ArrayList<>();
outputBufferInfo = new MediaCodec.BufferInfo(); outputBufferInfo = new MediaCodec.BufferInfo();
@ -554,8 +554,8 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
if (inputIndex < 0) { if (inputIndex < 0) {
return false; return false;
} }
sampleHolder.data = inputBuffers[inputIndex]; buffer.data = inputBuffers[inputIndex];
sampleHolder.clear(); buffer.clear();
} }
if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) { if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
@ -574,19 +574,19 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
int result; int result;
if (waitingForKeys) { if (waitingForKeys) {
// We've already read an encrypted sample into sampleHolder, and are waiting for keys. // We've already read an encrypted sample into buffer, and are waiting for keys.
result = TrackStream.SAMPLE_READ; result = TrackStream.BUFFER_READ;
} else { } else {
// For adaptive reconfiguration OMX decoders expect all reconfiguration data to be supplied // 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. // at the start of the buffer that also contains the first frame in the new format.
if (codecReconfigurationState == RECONFIGURATION_STATE_WRITE_PENDING) { if (codecReconfigurationState == RECONFIGURATION_STATE_WRITE_PENDING) {
for (int i = 0; i < format.initializationData.size(); i++) { for (int i = 0; i < format.initializationData.size(); i++) {
byte[] data = format.initializationData.get(i); byte[] data = format.initializationData.get(i);
sampleHolder.data.put(data); buffer.data.put(data);
} }
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING; codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
} }
result = readSource(formatHolder, sampleHolder); result = readSource(formatHolder, buffer);
if (firstFeed && sourceState == SOURCE_STATE_READY && result == TrackStream.NOTHING_READ) { if (firstFeed && sourceState == SOURCE_STATE_READY && result == TrackStream.NOTHING_READ) {
sourceState = SOURCE_STATE_READY_READ_MAY_FAIL; sourceState = SOURCE_STATE_READY_READ_MAY_FAIL;
} }
@ -599,18 +599,20 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) { if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// We received two formats in a row. Clear the current buffer of any reconfiguration data // We received two formats in a row. Clear the current buffer of any reconfiguration data
// associated with the first format. // associated with the first format.
sampleHolder.clear(); buffer.clear();
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
} }
onInputFormatChanged(formatHolder); onInputFormatChanged(formatHolder);
return true; return true;
} }
if (result == TrackStream.END_OF_STREAM) {
// We've read a buffer.
if (buffer.isEndOfStream()) {
if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) { if (codecReconfigurationState == RECONFIGURATION_STATE_QUEUE_PENDING) {
// We received a new format immediately before the end of the stream. We need to clear // 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 // 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). // a subsequent buffer if there are any (e.g. if the user seeks backwards).
sampleHolder.clear(); buffer.clear();
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING; codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
} }
inputStreamEnded = true; inputStreamEnded = true;
@ -632,30 +634,30 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
} }
return false; return false;
} }
boolean sampleEncrypted = sampleHolder.isEncrypted(); boolean bufferEncrypted = buffer.isEncrypted();
waitingForKeys = shouldWaitForKeys(sampleEncrypted); waitingForKeys = shouldWaitForKeys(bufferEncrypted);
if (waitingForKeys) { if (waitingForKeys) {
return false; return false;
} }
if (codecNeedsDiscardToSpsWorkaround && !sampleEncrypted) { if (codecNeedsDiscardToSpsWorkaround && !bufferEncrypted) {
NalUnitUtil.discardToSps(sampleHolder.data); NalUnitUtil.discardToSps(buffer.data);
if (sampleHolder.data.position() == 0) { if (buffer.data.position() == 0) {
return true; return true;
} }
codecNeedsDiscardToSpsWorkaround = false; codecNeedsDiscardToSpsWorkaround = false;
} }
try { try {
int bufferSize = sampleHolder.data.position(); int bufferSize = buffer.data.position();
int adaptiveReconfigurationBytes = bufferSize - sampleHolder.size; int adaptiveReconfigurationBytes = bufferSize - buffer.size;
long presentationTimeUs = sampleHolder.timeUs; long presentationTimeUs = buffer.timeUs;
if (sampleHolder.isDecodeOnly()) { if (buffer.isDecodeOnly()) {
decodeOnlyPresentationTimestamps.add(presentationTimeUs); decodeOnlyPresentationTimestamps.add(presentationTimeUs);
} }
onQueuedInputBuffer(presentationTimeUs, sampleHolder.data, bufferSize, sampleEncrypted); onQueuedInputBuffer(presentationTimeUs, buffer.data, bufferSize, bufferEncrypted);
if (sampleEncrypted) { if (bufferEncrypted) {
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(sampleHolder, MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer,
adaptiveReconfigurationBytes); adaptiveReconfigurationBytes);
codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0); codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0);
} else { } else {
@ -672,9 +674,9 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
return true; return true;
} }
private static MediaCodec.CryptoInfo getFrameworkCryptoInfo(SampleHolder sampleHolder, private static MediaCodec.CryptoInfo getFrameworkCryptoInfo(DecoderInputBuffer buffer,
int adaptiveReconfigurationBytes) { int adaptiveReconfigurationBytes) {
MediaCodec.CryptoInfo cryptoInfo = sampleHolder.cryptoInfo.getFrameworkCryptoInfoV16(); MediaCodec.CryptoInfo cryptoInfo = buffer.cryptoInfo.getFrameworkCryptoInfoV16();
if (adaptiveReconfigurationBytes == 0) { if (adaptiveReconfigurationBytes == 0) {
return cryptoInfo; return cryptoInfo;
} }
@ -688,7 +690,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
return cryptoInfo; return cryptoInfo;
} }
private boolean shouldWaitForKeys(boolean sampleEncrypted) throws ExoPlaybackException { private boolean shouldWaitForKeys(boolean bufferEncrypted) throws ExoPlaybackException {
if (!openedDrmSession) { if (!openedDrmSession) {
return false; return false;
} }
@ -697,7 +699,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
throw ExoPlaybackException.createForRenderer(drmSessionManager.getError(), getIndex()); throw ExoPlaybackException.createForRenderer(drmSessionManager.getError(), getIndex());
} }
if (drmManagerState != DrmSessionManager.STATE_OPENED_WITH_KEYS && if (drmManagerState != DrmSessionManager.STATE_OPENED_WITH_KEYS &&
(sampleEncrypted || !playClearSamplesWithoutKeys)) { (bufferEncrypted || !playClearSamplesWithoutKeys)) {
return true; return true;
} }
return false; return false;
@ -758,11 +760,11 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
* *
* @param presentationTimeUs The timestamp associated with the input buffer. * @param presentationTimeUs The timestamp associated with the input buffer.
* @param buffer The buffer to be queued. * @param buffer The buffer to be queued.
* @param bufferSize the size of the sample data stored in the buffer. * @param bufferSize The size of the sample data stored in the buffer.
* @param sampleEncrypted Whether the sample data is encrypted. * @param bufferEncrypted Whether the buffer is encrypted.
*/ */
protected void onQueuedInputBuffer( protected void onQueuedInputBuffer(long presentationTimeUs, ByteBuffer buffer, int bufferSize,
long presentationTimeUs, ByteBuffer buffer, int bufferSize, boolean sampleEncrypted) { boolean bufferEncrypted) {
// Do nothing. // Do nothing.
} }

View File

@ -64,18 +64,10 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
/** /**
* Reads from the enabled upstream source. * Reads from the enabled upstream source.
* *
* @param formatHolder A {@link FormatHolder} object to populate in the case of a new format. * @see TrackStream#readData(FormatHolder, DecoderInputBuffer)
* @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}.
*/ */
protected final int readSource(FormatHolder formatHolder, SampleHolder sampleHolder) { protected final int readSource(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return trackStream.readData(formatHolder, sampleHolder); return trackStream.readData(formatHolder, buffer);
} }
// Abstract methods. // Abstract methods.

View File

@ -186,10 +186,10 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
} }
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
if (streamState == STREAM_STATE_END_OF_STREAM) { if (streamState == STREAM_STATE_END_OF_STREAM) {
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return END_OF_STREAM; return BUFFER_READ;
} else if (streamState == STREAM_STATE_SEND_FORMAT) { } else if (streamState == STREAM_STATE_SEND_FORMAT) {
formatHolder.format = format; formatHolder.format = format;
streamState = STREAM_STATE_SEND_SAMPLE; streamState = STREAM_STATE_SEND_SAMPLE;
@ -200,13 +200,13 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
if (!loadingFinished) { if (!loadingFinished) {
return NOTHING_READ; return NOTHING_READ;
} else { } else {
sampleHolder.timeUs = 0; buffer.timeUs = 0;
sampleHolder.size = sampleSize; buffer.size = sampleSize;
sampleHolder.addFlag(C.SAMPLE_FLAG_SYNC); buffer.addFlag(C.BUFFER_FLAG_KEY_FRAME);
sampleHolder.ensureSpaceForWrite(sampleHolder.size); buffer.ensureSpaceForWrite(buffer.size);
sampleHolder.data.put(sampleData, 0, sampleSize); buffer.data.put(sampleData, 0, sampleSize);
streamState = STREAM_STATE_END_OF_STREAM; streamState = STREAM_STATE_END_OF_STREAM;
return SAMPLE_READ; return BUFFER_READ;
} }
} }

View File

@ -22,22 +22,18 @@ import java.io.IOException;
*/ */
public interface TrackStream { public interface TrackStream {
/**
* The end of stream has been reached.
*/
int END_OF_STREAM = -1;
/** /**
* Nothing was read. * 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. * A format was read.
*/ */
int FORMAT_READ = -4; int FORMAT_READ = -3;
/** /**
* Returned from {@link #readReset()} to indicate no reset is required. * 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. * Returns whether data is available to be read.
* <p> * <p>
* Note: If the stream has ended then {@link #END_OF_STREAM} can always be read from * Note: If the stream has ended then a buffer with the end of stream flag can always be read from
* {@link #readData(FormatHolder, SampleHolder)}. Hence an ended stream is always ready. * {@link #readData(FormatHolder, DecoderInputBuffer)}. Hence an ended stream is always ready.
* *
* @return True if data is available to be read. False otherwise. * @return True if data is available to be read. False otherwise.
*/ */
@ -69,20 +65,19 @@ public interface TrackStream {
long readReset(); long readReset();
/** /**
* Attempts to read the next format or sample. * Attempts to read from the stream.
* <p> * <p>
* This method will always return {@link #NOTHING_READ} in the case that there's a pending * 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. * 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 formatHolder A {@link FormatHolder} to populate in the case of reading a format.
* @param sampleHolder A {@link SampleHolder} to populate in the case of a new sample. If the * @param buffer A {@link DecoderInputBuffer} to populate in the case of reading a sample or the
* caller requires the sample data then it must ensure that {@link SampleHolder#data} * end of the stream. If the caller requires the sample data then it must ensure that
* references a valid output buffer. If the end of the stream has been reached, * {@link DecoderInputBuffer#data} references a valid buffer. If the end of the stream has
* {@link #END_OF_STREAM} will be returned and {@link C#SAMPLE_FLAG_END_OF_STREAM} will be set * been reached, the {@link C#BUFFER_FLAG_END_OF_STREAM} flag will be set on the buffer.
* on the sample holder. * @return The result, which can be {@link #NOTHING_READ}, {@link #FORMAT_READ} or
* @return The result, which can be {@link #END_OF_STREAM}, {@link #NOTHING_READ}, * {@link #BUFFER_READ}.
* {@link #FORMAT_READ} or {@link #SAMPLE_READ}.
*/ */
int readData(FormatHolder formatHolder, SampleHolder sampleHolder); int readData(FormatHolder formatHolder, DecoderInputBuffer buffer);
} }

View File

@ -16,10 +16,10 @@
package com.google.android.exoplayer.chunk; package com.google.android.exoplayer.chunk;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.LoadControl; import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackGroup; import com.google.android.exoplayer.TrackGroup;
import com.google.android.exoplayer.TrackGroupArray; import com.google.android.exoplayer.TrackGroupArray;
@ -246,7 +246,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
} }
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
if (pendingReset || isPendingReset()) { if (pendingReset || isPendingReset()) {
return NOTHING_READ; return NOTHING_READ;
} }
@ -277,18 +277,18 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
if (!haveSamples) { if (!haveSamples) {
if (loadingFinished) { if (loadingFinished) {
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return END_OF_STREAM; return BUFFER_READ;
} }
return NOTHING_READ; return NOTHING_READ;
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(buffer)) {
if (sampleHolder.timeUs < lastSeekPositionUs) { if (buffer.timeUs < lastSeekPositionUs) {
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY); buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
} }
onSampleRead(currentChunk, sampleHolder); onSampleRead(currentChunk, buffer);
return SAMPLE_READ; return BUFFER_READ;
} }
return NOTHING_READ; return NOTHING_READ;
@ -395,9 +395,9 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
* the sample is returned. * the sample is returned.
* *
* @param mediaChunk The chunk from which the sample was obtained. * @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. // Do nothing.
} }

View File

@ -104,7 +104,7 @@ public final class SingleSampleMediaChunk extends BaseMediaChunk {
result = getOutput().sampleData(extractorInput, Integer.MAX_VALUE, true); result = getOutput().sampleData(extractorInput, Integer.MAX_VALUE, true);
} }
int sampleSize = bytesLoaded; 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 { } finally {
dataSource.close(); dataSource.close();
} }

View File

@ -15,8 +15,8 @@
*/ */
package com.google.android.exoplayer.extractor; package com.google.android.exoplayer.extractor;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.upstream.Allocator; import com.google.android.exoplayer.upstream.Allocator;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
@ -29,7 +29,7 @@ import java.io.IOException;
public class DefaultTrackOutput implements TrackOutput { public class DefaultTrackOutput implements TrackOutput {
private final RollingSampleBuffer rollingBuffer; private final RollingSampleBuffer rollingBuffer;
private final SampleHolder sampleInfoHolder; private final DecoderInputBuffer sampleBuffer;
// Accessed only by the consuming thread. // Accessed only by the consuming thread.
private boolean needKeyframe; private boolean needKeyframe;
@ -45,7 +45,7 @@ public class DefaultTrackOutput implements TrackOutput {
*/ */
public DefaultTrackOutput(Allocator allocator) { public DefaultTrackOutput(Allocator allocator) {
rollingBuffer = new RollingSampleBuffer(allocator); rollingBuffer = new RollingSampleBuffer(allocator);
sampleInfoHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_DISABLED); sampleBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
needKeyframe = true; needKeyframe = true;
lastReadTimeUs = Long.MIN_VALUE; lastReadTimeUs = Long.MIN_VALUE;
spliceOutTimeUs = Long.MIN_VALUE; spliceOutTimeUs = Long.MIN_VALUE;
@ -79,7 +79,7 @@ public class DefaultTrackOutput implements TrackOutput {
*/ */
public void discardUpstreamSamples(int discardFromIndex) { public void discardUpstreamSamples(int discardFromIndex) {
rollingBuffer.discardUpstreamSamples(discardFromIndex); rollingBuffer.discardUpstreamSamples(discardFromIndex);
largestParsedTimestampUs = rollingBuffer.peekSample(sampleInfoHolder) ? sampleInfoHolder.timeUs largestParsedTimestampUs = rollingBuffer.peekSample(sampleBuffer) ? sampleBuffer.timeUs
: Long.MIN_VALUE; : 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> * <p>
* The first sample returned is guaranteed to be a keyframe, since any non-keyframe samples * The first sample returned is guaranteed to be a keyframe, since any non-keyframe samples
* queued prior to the first keyframe are discarded. * 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. * @return True if a sample was read. False otherwise.
*/ */
public boolean getSample(SampleHolder holder) { public boolean getSample(DecoderInputBuffer buffer) {
boolean foundEligibleSample = advanceToEligibleSample(); boolean foundEligibleSample = advanceToEligibleSample();
if (!foundEligibleSample) { if (!foundEligibleSample) {
return false; return false;
} }
// Write the sample into the holder. // Write the sample into the buffer.
rollingBuffer.readSample(holder); rollingBuffer.readSample(buffer);
needKeyframe = false; needKeyframe = false;
lastReadTimeUs = holder.timeUs; lastReadTimeUs = buffer.timeUs;
return true; return true;
} }
@ -148,7 +148,7 @@ public class DefaultTrackOutput implements TrackOutput {
* @param timeUs The time up to which samples should be discarded, in microseconds. * @param timeUs The time up to which samples should be discarded, in microseconds.
*/ */
public void discardUntil(long timeUs) { public void discardUntil(long timeUs) {
while (rollingBuffer.peekSample(sampleInfoHolder) && sampleInfoHolder.timeUs < timeUs) { while (rollingBuffer.peekSample(sampleBuffer) && sampleBuffer.timeUs < timeUs) {
rollingBuffer.skipSample(); rollingBuffer.skipSample();
// We're discarding one or more samples. A subsequent read will need to start at a keyframe. // We're discarding one or more samples. A subsequent read will need to start at a keyframe.
needKeyframe = true; needKeyframe = true;
@ -178,22 +178,22 @@ public class DefaultTrackOutput implements TrackOutput {
return true; return true;
} }
long firstPossibleSpliceTime; long firstPossibleSpliceTime;
if (rollingBuffer.peekSample(sampleInfoHolder)) { if (rollingBuffer.peekSample(sampleBuffer)) {
firstPossibleSpliceTime = sampleInfoHolder.timeUs; firstPossibleSpliceTime = sampleBuffer.timeUs;
} else { } else {
firstPossibleSpliceTime = lastReadTimeUs + 1; firstPossibleSpliceTime = lastReadTimeUs + 1;
} }
RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer; RollingSampleBuffer nextRollingBuffer = nextQueue.rollingBuffer;
while (nextRollingBuffer.peekSample(sampleInfoHolder) while (nextRollingBuffer.peekSample(sampleBuffer)
&& (sampleInfoHolder.timeUs < firstPossibleSpliceTime || !sampleInfoHolder.isSyncFrame())) { && (sampleBuffer.timeUs < firstPossibleSpliceTime || !sampleBuffer.isKeyFrame())) {
// Discard samples from the next queue for as long as they are before the earliest possible // Discard samples from the next queue for as long as they are before the earliest possible
// splice time, or not keyframes. // splice time, or not keyframes.
nextRollingBuffer.skipSample(); 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 // We've found a keyframe in the next queue that can serve as the splice point. Set the
// splice point now. // splice point now.
spliceOutTimeUs = sampleInfoHolder.timeUs; spliceOutTimeUs = sampleBuffer.timeUs;
return true; return true;
} }
return false; return false;
@ -206,17 +206,17 @@ public class DefaultTrackOutput implements TrackOutput {
* buffer has been emptied. * buffer has been emptied.
*/ */
private boolean advanceToEligibleSample() { private boolean advanceToEligibleSample() {
boolean haveNext = rollingBuffer.peekSample(sampleInfoHolder); boolean haveNext = rollingBuffer.peekSample(sampleBuffer);
if (needKeyframe) { if (needKeyframe) {
while (haveNext && !sampleInfoHolder.isSyncFrame()) { while (haveNext && !sampleBuffer.isKeyFrame()) {
rollingBuffer.skipSample(); rollingBuffer.skipSample();
haveNext = rollingBuffer.peekSample(sampleInfoHolder); haveNext = rollingBuffer.peekSample(sampleBuffer);
} }
} }
if (!haveNext) { if (!haveNext) {
return false; return false;
} }
if (spliceOutTimeUs != Long.MIN_VALUE && sampleInfoHolder.timeUs >= spliceOutTimeUs) { if (spliceOutTimeUs != Long.MIN_VALUE && sampleBuffer.timeUs >= spliceOutTimeUs) {
return false; return false;
} }
return true; return true;

View File

@ -16,9 +16,9 @@
package com.google.android.exoplayer.extractor; package com.google.android.exoplayer.extractor;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.ParserException; import com.google.android.exoplayer.ParserException;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackGroup; import com.google.android.exoplayer.TrackGroup;
import com.google.android.exoplayer.TrackGroupArray; import com.google.android.exoplayer.TrackGroupArray;
@ -445,7 +445,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
return TrackStream.NO_RESET; 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()) { if (pendingResets[track] || isPendingReset()) {
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
} }
@ -458,22 +458,22 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
return TrackStream.FORMAT_READ; return TrackStream.FORMAT_READ;
} }
if (sampleQueue.getSample(sampleHolder)) { if (sampleQueue.getSample(buffer)) {
if (sampleHolder.timeUs < lastSeekPositionUs) { if (buffer.timeUs < lastSeekPositionUs) {
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY); buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
} }
if (havePendingNextSampleUs) { if (havePendingNextSampleUs) {
// Set the offset to make the timestamp of this sample equal to pendingNextSampleUs. // Set the offset to make the timestamp of this sample equal to pendingNextSampleUs.
sampleTimeOffsetUs = pendingNextSampleUs - sampleHolder.timeUs; sampleTimeOffsetUs = pendingNextSampleUs - buffer.timeUs;
havePendingNextSampleUs = false; havePendingNextSampleUs = false;
} }
sampleHolder.timeUs += sampleTimeOffsetUs; buffer.timeUs += sampleTimeOffsetUs;
return TrackStream.SAMPLE_READ; return TrackStream.BUFFER_READ;
} }
if (loadingFinished) { if (loadingFinished) {
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.BUFFER_READ;
} }
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
@ -764,8 +764,8 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
} }
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return ExtractorSampleSource.this.readData(track, formatHolder, sampleHolder); return ExtractorSampleSource.this.readData(track, formatHolder, buffer);
} }
} }

View File

@ -16,7 +16,7 @@
package com.google.android.exoplayer.extractor; package com.google.android.exoplayer.extractor;
import com.google.android.exoplayer.C; 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.Allocation;
import com.google.android.exoplayer.upstream.Allocator; import com.google.android.exoplayer.upstream.Allocator;
import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSource;
@ -40,7 +40,7 @@ import java.util.concurrent.LinkedBlockingDeque;
private final InfoQueue infoQueue; private final InfoQueue infoQueue;
private final LinkedBlockingDeque<Allocation> dataQueue; private final LinkedBlockingDeque<Allocation> dataQueue;
private final SampleExtrasHolder extrasHolder; private final BufferExtrasHolder extrasHolder;
private final ParsableByteArray scratch; private final ParsableByteArray scratch;
// Accessed only by the consuming thread. // Accessed only by the consuming thread.
@ -59,7 +59,7 @@ import java.util.concurrent.LinkedBlockingDeque;
allocationLength = allocator.getIndividualAllocationLength(); allocationLength = allocator.getIndividualAllocationLength();
infoQueue = new InfoQueue(); infoQueue = new InfoQueue();
dataQueue = new LinkedBlockingDeque<>(); dataQueue = new LinkedBlockingDeque<>();
extrasHolder = new SampleExtrasHolder(); extrasHolder = new BufferExtrasHolder();
scratch = new ParsableByteArray(INITIAL_SCRATCH_SIZE); scratch = new ParsableByteArray(INITIAL_SCRATCH_SIZE);
lastAllocationOffset = allocationLength; 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> * <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. * @param buffer The buffer into which the current sample information should be written.
* @return True if the holder was filled. False if there is no current sample. * @return True if the buffer was filled. False if there is no current sample.
*/ */
public boolean peekSample(SampleHolder holder) { public boolean peekSample(DecoderInputBuffer buffer) {
return infoQueue.peekSample(holder, extrasHolder); 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. * 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. * @return True if a sample was read. False if there is no current sample.
*/ */
public boolean readSample(SampleHolder sampleHolder) { public boolean readSample(DecoderInputBuffer buffer) {
// Write the sample information into the holder and extrasHolder. // Write the sample information into the buffer and extrasHolder.
boolean haveSample = infoQueue.peekSample(sampleHolder, extrasHolder); boolean haveSample = infoQueue.peekSample(buffer, extrasHolder);
if (!haveSample) { if (!haveSample) {
return false; return false;
} }
// Read encryption data if the sample is encrypted. // Read encryption data if the sample is encrypted.
if (sampleHolder.isEncrypted()) { if (buffer.isEncrypted()) {
readEncryptionData(sampleHolder, extrasHolder); readEncryptionData(buffer, extrasHolder);
} }
// Write the sample data into the holder. // Write the sample data into the holder.
sampleHolder.ensureSpaceForWrite(sampleHolder.size); buffer.ensureSpaceForWrite(buffer.size);
readData(extrasHolder.offset, sampleHolder.data, sampleHolder.size); readData(extrasHolder.offset, buffer.data, buffer.size);
// Advance the read head. // Advance the read head.
long nextOffset = infoQueue.moveToNextSample(); long nextOffset = infoQueue.moveToNextSample();
dropDownstreamTo(nextOffset); dropDownstreamTo(nextOffset);
@ -196,14 +197,14 @@ import java.util.concurrent.LinkedBlockingDeque;
/** /**
* Reads encryption data for the current sample. * Reads encryption data for the current sample.
* <p> * <p>
* The encryption data is written into {@code sampleHolder.cryptoInfo}, and * The encryption data is written into {@link DecoderInputBuffer#cryptoInfo}, and
* {@code sampleHolder.size} is adjusted to subtract the number of bytes that were read. The * {@link DecoderInputBuffer#size} is adjusted to subtract the number of bytes that were read. The
* same value is added to {@code extrasHolder.offset}. * 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. * @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; long offset = extrasHolder.offset;
// Read the signal byte. // Read the signal byte.
@ -214,10 +215,10 @@ import java.util.concurrent.LinkedBlockingDeque;
int ivSize = signalByte & 0x7F; int ivSize = signalByte & 0x7F;
// Read the initialization vector. // Read the initialization vector.
if (sampleHolder.cryptoInfo.iv == null) { if (buffer.cryptoInfo.iv == null) {
sampleHolder.cryptoInfo.iv = new byte[16]; buffer.cryptoInfo.iv = new byte[16];
} }
readData(offset, sampleHolder.cryptoInfo.iv, ivSize); readData(offset, buffer.cryptoInfo.iv, ivSize);
offset += ivSize; offset += ivSize;
// Read the subsample count, if present. // Read the subsample count, if present.
@ -232,11 +233,11 @@ import java.util.concurrent.LinkedBlockingDeque;
} }
// Write the clear and encrypted subsample sizes. // Write the clear and encrypted subsample sizes.
int[] clearDataSizes = sampleHolder.cryptoInfo.numBytesOfClearData; int[] clearDataSizes = buffer.cryptoInfo.numBytesOfClearData;
if (clearDataSizes == null || clearDataSizes.length < subsampleCount) { if (clearDataSizes == null || clearDataSizes.length < subsampleCount) {
clearDataSizes = new int[subsampleCount]; clearDataSizes = new int[subsampleCount];
} }
int[] encryptedDataSizes = sampleHolder.cryptoInfo.numBytesOfEncryptedData; int[] encryptedDataSizes = buffer.cryptoInfo.numBytesOfEncryptedData;
if (encryptedDataSizes == null || encryptedDataSizes.length < subsampleCount) { if (encryptedDataSizes == null || encryptedDataSizes.length < subsampleCount) {
encryptedDataSizes = new int[subsampleCount]; encryptedDataSizes = new int[subsampleCount];
} }
@ -252,17 +253,17 @@ import java.util.concurrent.LinkedBlockingDeque;
} }
} else { } else {
clearDataSizes[0] = 0; clearDataSizes[0] = 0;
encryptedDataSizes[0] = sampleHolder.size - (int) (offset - extrasHolder.offset); encryptedDataSizes[0] = buffer.size - (int) (offset - extrasHolder.offset);
} }
// Populate the cryptoInfo. // Populate the cryptoInfo.
sampleHolder.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes, buffer.cryptoInfo.set(subsampleCount, clearDataSizes, encryptedDataSizes,
extrasHolder.encryptionKeyId, sampleHolder.cryptoInfo.iv, C.CRYPTO_MODE_AES_CTR); extrasHolder.encryptionKeyId, buffer.cryptoInfo.iv, C.CRYPTO_MODE_AES_CTR);
// Adjust the offset and size to take into account the bytes read. // Adjust the offset and size to take into account the bytes read.
int bytesRead = (int) (offset - extrasHolder.offset); int bytesRead = (int) (offset - extrasHolder.offset);
extrasHolder.offset += bytesRead; 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. * Indicates the end point for the current sample, making it available for consumption.
* *
* @param sampleTimeUs The sample timestamp. * @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 position The position of the sample data in the rolling buffer.
* @param size The size of the sample, in bytes. * @param size The size of the sample, in bytes.
* @param encryptionKey The encryption key associated with the sample, or null. * @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. * Fills {@code buffer} 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 * The absolute position of the sample's data in the rolling buffer is stored in
* data in the rolling buffer.
* <p>
* Populates {@link SampleHolder#size}, {@link SampleHolder#timeUs}, the sample flags and
* {@code extrasHolder}. * {@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. * @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) { if (queueSize == 0) {
return false; return false;
} }
holder.timeUs = timesUs[relativeReadIndex]; buffer.timeUs = timesUs[relativeReadIndex];
holder.size = sizes[relativeReadIndex]; buffer.size = sizes[relativeReadIndex];
holder.setFlags(flags[relativeReadIndex]); buffer.setFlags(flags[relativeReadIndex]);
extrasHolder.offset = offsets[relativeReadIndex]; extrasHolder.offset = offsets[relativeReadIndex];
extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex]; extrasHolder.encryptionKeyId = encryptionKeys[relativeReadIndex];
return true; return true;
@ -590,7 +592,7 @@ import java.util.concurrent.LinkedBlockingDeque;
if (timesUs[searchIndex] > timeUs) { if (timesUs[searchIndex] > timeUs) {
// We've gone too far. // We've gone too far.
break; 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. // We've found a keyframe, and we're still before the seek position.
sampleCountToKeyframe = sampleCount; 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 long offset;
public byte[] encryptionKeyId; public byte[] encryptionKeyId;

View File

@ -65,7 +65,7 @@ public interface TrackOutput {
* {@link #sampleData(ParsableByteArray, int)}. * {@link #sampleData(ParsableByteArray, int)}.
* *
* @param timeUs The media timestamp associated with the sample, in microseconds. * @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 size The size of the sample data, in bytes.
* @param offset The number of bytes that have been passed to * @param offset The number of bytes that have been passed to
* {@link #sampleData(ExtractorInput, int, boolean)} or * {@link #sampleData(ExtractorInput, int, boolean)} or

View File

@ -95,7 +95,7 @@ import java.util.Collections;
// Sample audio AAC frames // Sample audio AAC frames
int bytesToWrite = data.bytesLeft(); int bytesToWrite = data.bytesLeft();
output.sampleData(data, bytesToWrite); 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);
} }
} }

View File

@ -129,7 +129,7 @@ import java.util.List;
output.sampleData(data, bytesToWrite); output.sampleData(data, bytesToWrite);
bytesWritten += 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); bytesWritten, 0, null);
} }
} }

View File

@ -151,7 +151,8 @@ public final class Mp3Extractor implements Extractor {
return RESULT_CONTINUE; return RESULT_CONTINUE;
} }
long timeUs = basisTimeUs + (samplesRead * C.MICROS_PER_SECOND / synchronizedHeader.sampleRate); 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; samplesRead += synchronizedHeader.samplesPerFrame;
sampleBytesRemaining = 0; sampleBytesRemaining = 0;
return RESULT_CONTINUE; return RESULT_CONTINUE;

View File

@ -196,9 +196,9 @@ import java.util.List;
timestamps[i] = timestampTimeUnits + timestampOffset; timestamps[i] = timestampTimeUnits + timestampOffset;
// All samples are synchronization samples if the stss is not present. // 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) { if (i == nextSynchronizationSampleIndex) {
flags[i] = C.SAMPLE_FLAG_SYNC; flags[i] = C.BUFFER_FLAG_KEY_FRAME;
remainingSynchronizationSamples--; remainingSynchronizationSamples--;
if (remainingSynchronizationSamples > 0) { if (remainingSynchronizationSamples > 0) {
nextSynchronizationSampleIndex = stss.readUnsignedIntToInt() - 1; nextSynchronizationSampleIndex = stss.readUnsignedIntToInt() - 1;
@ -330,7 +330,7 @@ import java.util.List;
boolean hasSyncSample = false; boolean hasSyncSample = false;
for (int i = 0; i < editedFlags.length && !hasSyncSample; i++) { 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) { if (!hasSyncSample) {
throw new ParserException("The edited sample sequence does not contain a sync sample."); throw new ParserException("The edited sample sequence does not contain a sync sample.");

View File

@ -874,8 +874,8 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L; long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
int sampleFlags = (fragment.definesEncryptionData ? C.SAMPLE_FLAG_ENCRYPTED : 0) int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0)
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.SAMPLE_FLAG_SYNC : 0); | (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0);
int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex; int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex;
byte[] encryptionKey = fragment.definesEncryptionData byte[] encryptionKey = fragment.definesEncryptionData
? track.sampleDescriptionEncryptionBoxes[sampleDescriptionIndex].keyId : null; ? track.sampleDescriptionEncryptionBoxes[sampleDescriptionIndex].keyId : null;

View File

@ -79,7 +79,7 @@ import com.google.android.exoplayer.util.Util;
// Frames are not reordered past synchronization samples so this works in practice. // Frames are not reordered past synchronization samples so this works in practice.
int startIndex = Util.binarySearchFloor(timestampsUs, timeUs, true, false); int startIndex = Util.binarySearchFloor(timestampsUs, timeUs, true, false);
for (int i = startIndex; i >= 0; i--) { 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; return i;
} }
} }
@ -96,7 +96,7 @@ import com.google.android.exoplayer.util.Util;
public int getIndexOfLaterOrEqualSynchronizationSample(long timeUs) { public int getIndexOfLaterOrEqualSynchronizationSample(long timeUs) {
int startIndex = Util.binarySearchCeil(timestampsUs, timeUs, true, false); int startIndex = Util.binarySearchCeil(timestampsUs, timeUs, true, false);
for (int i = startIndex; i < timestampsUs.length; i++) { 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; return i;
} }
} }

View File

@ -164,7 +164,7 @@ public final class OggVorbisExtractor implements Extractor, SeekMap {
// Calculate time and send audio data to codec. // Calculate time and send audio data to codec.
long timeUs = elapsedSamples * C.MICROS_PER_SECOND / vorbisSetup.idHeader.sampleRate; long timeUs = elapsedSamples * C.MICROS_PER_SECOND / vorbisSetup.idHeader.sampleRate;
trackOutput.sampleData(scratch, scratch.limit()); 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; targetGranule = -1;
} }
// Update state in members for next iteration. // Update state in members for next iteration.

View File

@ -103,7 +103,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
output.sampleData(data, bytesToRead); output.sampleData(data, bytesToRead);
bytesRead += bytesToRead; bytesRead += bytesToRead;
if (bytesRead == sampleSize) { 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; timeUs += sampleDurationUs;
state = STATE_FINDING_SYNC; state = STATE_FINDING_SYNC;
} }

View File

@ -302,7 +302,7 @@ import java.util.Collections;
currentOutput.sampleData(data, bytesToRead); currentOutput.sampleData(data, bytesToRead);
bytesRead += bytesToRead; bytesRead += bytesToRead;
if (bytesRead == sampleSize) { 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; timeUs += currentSampleDuration;
setFindingSampleState(); setFindingSampleState();
} }

View File

@ -100,7 +100,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
output.sampleData(data, bytesToRead); output.sampleData(data, bytesToRead);
bytesRead += bytesToRead; bytesRead += bytesToRead;
if (bytesRead == sampleSize) { 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; timeUs += sampleDurationUs;
state = STATE_FINDING_SYNC; state = STATE_FINDING_SYNC;
} }

View File

@ -131,7 +131,7 @@ import java.util.Collections;
if (hasOutputFormat && (startCodeValue == START_GROUP || startCodeValue == START_PICTURE)) { if (hasOutputFormat && (startCodeValue == START_GROUP || startCodeValue == START_PICTURE)) {
int bytesWrittenPastStartCode = limit - startCodeOffset; int bytesWrittenPastStartCode = limit - startCodeOffset;
if (foundFirstFrameInGroup) { 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; int size = (int) (totalBytesWritten - framePosition) - bytesWrittenPastStartCode;
output.sampleMetadata(frameTimeUs, flags, size, bytesWrittenPastStartCode, null); output.sampleMetadata(frameTimeUs, flags, size, bytesWrittenPastStartCode, null);
isKeyframe = false; isKeyframe = false;

View File

@ -431,7 +431,7 @@ import java.util.List;
} }
private void outputSample(int offset) { 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); int size = (int) (nalUnitStartPosition - samplePosition);
output.sampleMetadata(sampleTimeUs, flags, size, offset, null); output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
} }

View File

@ -453,7 +453,7 @@ import java.util.Collections;
} }
private void outputSample(int offset) { 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); int size = (int) (nalUnitStartPosition - samplePosition);
output.sampleMetadata(sampleTimeUs, flags, size, offset, null); output.sampleMetadata(sampleTimeUs, flags, size, offset, null);
} }

View File

@ -87,7 +87,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
if (!writingSample || sampleSize == 0 || sampleBytesRead != sampleSize) { if (!writingSample || sampleSize == 0 || sampleBytesRead != sampleSize) {
return; return;
} }
output.sampleMetadata(sampleTimeUs, C.SAMPLE_FLAG_SYNC, sampleSize, 0, null); output.sampleMetadata(sampleTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null);
writingSample = false; writingSample = false;
} }

View File

@ -194,7 +194,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
return; return;
} }
output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, frameSize, 0, null); output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, frameSize, 0, null);
timeUs += frameDurationUs; timeUs += frameDurationUs;
frameBytesRead = 0; frameBytesRead = 0;
state = STATE_FINDING_HEADER; state = STATE_FINDING_HEADER;

View File

@ -55,7 +55,7 @@ import com.google.android.exoplayer.util.ParsableByteArray;
// Process the payload. // Process the payload.
if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) { if (Eia608Parser.isSeiMessageEia608(payloadType, payloadSize, seiBuffer)) {
output.sampleData(seiBuffer, payloadSize); 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 { } else {
seiBuffer.skipBytes(payloadSize); seiBuffer.skipBytes(payloadSize);
} }

View File

@ -83,7 +83,7 @@ public final class WavExtractor implements Extractor, SeekMap {
} }
trackOutput.sampleMetadata( 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; return RESULT_CONTINUE;
} }

View File

@ -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 the ReferenceBlock element was not found for this sample, then it is a keyframe.
if (!sampleSeenReferenceBlock) { if (!sampleSeenReferenceBlock) {
blockFlags |= C.SAMPLE_FLAG_SYNC; blockFlags |= C.BUFFER_FLAG_KEY_FRAME;
} }
commitSampleToOutput(tracks.get(blockTrackNumber), blockTimeUs); commitSampleToOutput(tracks.get(blockTrackNumber), blockTimeUs);
blockState = BLOCK_STATE_START; blockState = BLOCK_STATE_START;
@ -766,8 +766,8 @@ public final class WebmExtractor implements Extractor {
boolean isInvisible = (scratch.data[2] & 0x08) == 0x08; boolean isInvisible = (scratch.data[2] & 0x08) == 0x08;
boolean isKeyframe = track.type == TRACK_TYPE_AUDIO boolean isKeyframe = track.type == TRACK_TYPE_AUDIO
|| (id == ID_SIMPLE_BLOCK && (scratch.data[2] & 0x80) == 0x80); || (id == ID_SIMPLE_BLOCK && (scratch.data[2] & 0x80) == 0x80);
blockFlags = (isKeyframe ? C.SAMPLE_FLAG_SYNC : 0) blockFlags = (isKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0)
| (isInvisible ? C.SAMPLE_FLAG_DECODE_ONLY : 0); | (isInvisible ? C.BUFFER_FLAG_DECODE_ONLY : 0);
blockState = BLOCK_STATE_DATA; blockState = BLOCK_STATE_DATA;
blockLacingSampleIndex = 0; blockLacingSampleIndex = 0;
} }
@ -850,7 +850,7 @@ public final class WebmExtractor implements Extractor {
if (track.hasContentEncryption) { if (track.hasContentEncryption) {
// If the sample is encrypted, read its encryption signal byte and set the IV size. // If the sample is encrypted, read its encryption signal byte and set the IV size.
// Clear the encrypted flag. // Clear the encrypted flag.
blockFlags &= ~C.SAMPLE_FLAG_ENCRYPTED; blockFlags &= ~C.BUFFER_FLAG_ENCRYPTED;
input.readFully(scratch.data, 0, 1); input.readFully(scratch.data, 0, 1);
sampleBytesRead++; sampleBytesRead++;
if ((scratch.data[0] & 0x80) == 0x80) { if ((scratch.data[0] & 0x80) == 0x80) {
@ -861,7 +861,7 @@ public final class WebmExtractor implements Extractor {
scratch.setPosition(0); scratch.setPosition(0);
output.sampleData(scratch, 1); output.sampleData(scratch, 1);
sampleBytesWritten++; sampleBytesWritten++;
blockFlags |= C.SAMPLE_FLAG_ENCRYPTED; blockFlags |= C.BUFFER_FLAG_ENCRYPTED;
} }
} else if (track.sampleStrippedBytes != null) { } else if (track.sampleStrippedBytes != null) {
// If the sample has header stripping, prepare to read/output the stripped bytes first. // If the sample has header stripping, prepare to read/output the stripped bytes first.

View File

@ -15,8 +15,8 @@
*/ */
package com.google.android.exoplayer.hls; package com.google.android.exoplayer.hls;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.drm.DrmInitData; import com.google.android.exoplayer.drm.DrmInitData;
import com.google.android.exoplayer.extractor.DefaultTrackOutput; import com.google.android.exoplayer.extractor.DefaultTrackOutput;
import com.google.android.exoplayer.extractor.Extractor; 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. * This method must only be called after the extractor has been prepared.
* *
* @param track The track from which to read. * @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. * @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()); 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 * Whether samples are available for reading from {@link #getSample(int, DecoderInputBuffer)} for
* specified track. * the specified track.
* <p> * <p>
* This method must only be called after the extractor has been prepared. * 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)} * @return True if samples are available for reading from
* for the specified track. False otherwise. * {@link #getSample(int, DecoderInputBuffer)} for the specified track. False otherwise.
*/ */
public boolean hasSamples(int track) { public boolean hasSamples(int track) {
Assertions.checkState(isPrepared()); Assertions.checkState(isPrepared());

View File

@ -16,10 +16,10 @@
package com.google.android.exoplayer.hls; package com.google.android.exoplayer.hls;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.LoadControl; import com.google.android.exoplayer.LoadControl;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.SampleSource;
import com.google.android.exoplayer.TrackGroup; import com.google.android.exoplayer.TrackGroup;
import com.google.android.exoplayer.TrackGroupArray; import com.google.android.exoplayer.TrackGroupArray;
@ -293,7 +293,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
return TrackStream.NO_RESET; 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()) { if (pendingResets[group] || isPendingReset()) {
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
} }
@ -332,16 +332,16 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
return TrackStream.FORMAT_READ; return TrackStream.FORMAT_READ;
} }
if (extractor.getSample(group, sampleHolder)) { if (extractor.getSample(group, buffer)) {
if (sampleHolder.timeUs < lastSeekPositionUs) { if (buffer.timeUs < lastSeekPositionUs) {
sampleHolder.addFlag(C.SAMPLE_FLAG_DECODE_ONLY); buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
} }
return TrackStream.SAMPLE_READ; return TrackStream.BUFFER_READ;
} }
if (loadingFinished) { if (loadingFinished) {
sampleHolder.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
return TrackStream.END_OF_STREAM; return TrackStream.BUFFER_READ;
} }
return TrackStream.NOTHING_READ; return TrackStream.NOTHING_READ;
@ -836,8 +836,8 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
} }
@Override @Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) { public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer) {
return HlsSampleSource.this.readData(group, formatHolder, sampleHolder); return HlsSampleSource.this.readData(group, formatHolder, buffer);
} }
} }

View File

@ -156,7 +156,7 @@ import java.util.regex.Pattern;
// Output the sample. // Output the sample.
sampleDataWrapper.reset(sampleData, sampleSize); sampleDataWrapper.reset(sampleData, sampleSize);
trackOutput.sampleData(sampleDataWrapper, 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) { private TrackOutput buildTrackOutput(long subsampleOffsetUs) {

View File

@ -15,10 +15,10 @@
*/ */
package com.google.android.exoplayer.metadata; package com.google.android.exoplayer.metadata;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer; import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; 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 MetadataRenderer<T> metadataRenderer;
private final Handler metadataHandler; private final Handler metadataHandler;
private final FormatHolder formatHolder; private final FormatHolder formatHolder;
private final SampleHolder sampleHolder; private final DecoderInputBuffer buffer;
private boolean inputStreamEnded; private boolean inputStreamEnded;
private long pendingMetadataTimestamp; private long pendingMetadataTimestamp;
@ -82,7 +82,7 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
this.metadataHandler = metadataRendererLooper == null ? null this.metadataHandler = metadataRendererLooper == null ? null
: new Handler(metadataRendererLooper, this); : new Handler(metadataRendererLooper, this);
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
} }
@Override @Override
@ -101,17 +101,19 @@ public final class MetadataTrackRenderer<T> extends SampleSourceTrackRenderer im
protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (!inputStreamEnded && pendingMetadata == null) { if (!inputStreamEnded && pendingMetadata == null) {
sampleHolder.clear(); buffer.clear();
int result = readSource(formatHolder, sampleHolder); int result = readSource(formatHolder, buffer);
if (result == TrackStream.SAMPLE_READ) { if (result == TrackStream.BUFFER_READ) {
pendingMetadataTimestamp = sampleHolder.timeUs; if (buffer.isEndOfStream()) {
try { inputStreamEnded = true;
pendingMetadata = metadataParser.parse(sampleHolder.data.array(), sampleHolder.size); } else {
} catch (IOException e) { pendingMetadataTimestamp = buffer.timeUs;
throw ExoPlaybackException.createForRenderer(e, getIndex()); 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;
} }
} }

View File

@ -15,17 +15,17 @@
*/ */
package com.google.android.exoplayer.text; package com.google.android.exoplayer.text;
import com.google.android.exoplayer.SampleHolder; import com.google.android.exoplayer.DecoderInputBuffer;
/** /**
* An input buffer for {@link SubtitleParser}. * An input buffer for {@link SubtitleParser}.
*/ */
/* package */ final class SubtitleInputBuffer extends SampleHolder { /* package */ final class SubtitleInputBuffer extends DecoderInputBuffer {
public long subsampleOffsetUs; public long subsampleOffsetUs;
public SubtitleInputBuffer() { public SubtitleInputBuffer() {
super(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL); super(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
} }
} }

View File

@ -176,11 +176,14 @@ public final class TextTrackRenderer extends SampleSourceTrackRenderer implement
} }
// Try and read the next subtitle from the source. // Try and read the next subtitle from the source.
int result = readSource(formatHolder, nextInputBuffer); int result = readSource(formatHolder, nextInputBuffer);
if (result == TrackStream.SAMPLE_READ) { if (result == TrackStream.BUFFER_READ) {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs; if (nextInputBuffer.isEndOfStream()) {
parser.queueInputBuffer(nextInputBuffer); inputStreamEnded = true;
} else if (result == TrackStream.END_OF_STREAM) { // TODO: Queue the end of stream buffer.
inputStreamEnded = true; } else {
nextInputBuffer.subsampleOffsetUs = formatHolder.format.subsampleOffsetUs;
parser.queueInputBuffer(nextInputBuffer);
}
} }
} }
} catch (ParserException e) { } catch (ParserException e) {

View File

@ -15,7 +15,7 @@
*/ */
package com.google.android.exoplayer.text.eia608; 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.MimeTypes;
import com.google.android.exoplayer.util.ParsableBitArray; import com.google.android.exoplayer.util.ParsableBitArray;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
@ -116,14 +116,14 @@ public final class Eia608Parser {
return mimeType.equals(MimeTypes.APPLICATION_EIA608); return mimeType.equals(MimeTypes.APPLICATION_EIA608);
} }
/* package */ ClosedCaptionList parse(SampleHolder sampleHolder) { /* package */ ClosedCaptionList parse(DecoderInputBuffer buffer) {
if (sampleHolder.size < 10) { if (buffer.size < 10) {
return null; return null;
} }
captions.clear(); captions.clear();
stringBuilder.setLength(0); 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) + // country_code (8) + provider_code (16) + user_identifier (32) + user_data_type_code (8) +
// reserved (1) + process_cc_data_flag (1) + zero_bit (1) // reserved (1) + process_cc_data_flag (1) + zero_bit (1)
@ -200,7 +200,7 @@ public final class Eia608Parser {
ClosedCaption[] captionArray = new ClosedCaption[captions.size()]; ClosedCaption[] captionArray = new ClosedCaption[captions.size()];
captions.toArray(captionArray); 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) { private static char getChar(byte ccData) {

View File

@ -16,10 +16,10 @@
package com.google.android.exoplayer.text.eia608; package com.google.android.exoplayer.text.eia608;
import com.google.android.exoplayer.C; import com.google.android.exoplayer.C;
import com.google.android.exoplayer.DecoderInputBuffer;
import com.google.android.exoplayer.ExoPlaybackException; import com.google.android.exoplayer.ExoPlaybackException;
import com.google.android.exoplayer.Format; import com.google.android.exoplayer.Format;
import com.google.android.exoplayer.FormatHolder; import com.google.android.exoplayer.FormatHolder;
import com.google.android.exoplayer.SampleHolder;
import com.google.android.exoplayer.SampleSourceTrackRenderer; import com.google.android.exoplayer.SampleSourceTrackRenderer;
import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.TrackStream; 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. // The default number of rows to display in roll-up captions mode.
private static final int DEFAULT_CAPTIONS_ROW_COUNT = 4; private static final int DEFAULT_CAPTIONS_ROW_COUNT = 4;
// The maximum duration that captions are parsed ahead of the current position. // 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 Eia608Parser eia608Parser;
private final TextRenderer textRenderer; private final TextRenderer textRenderer;
private final Handler textRendererHandler; private final Handler textRendererHandler;
private final FormatHolder formatHolder; private final FormatHolder formatHolder;
private final SampleHolder sampleHolder; private final DecoderInputBuffer buffer;
private final StringBuilder captionStringBuilder; private final StringBuilder captionStringBuilder;
private final TreeSet<ClosedCaptionList> pendingCaptionLists; private final TreeSet<ClosedCaptionList> pendingCaptionLists;
@ -81,7 +81,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
textRendererHandler = textRendererLooper == null ? null : new Handler(textRendererLooper, this); textRendererHandler = textRendererLooper == null ? null : new Handler(textRendererLooper, this);
eia608Parser = new Eia608Parser(); eia608Parser = new Eia608Parser();
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
sampleHolder = new SampleHolder(SampleHolder.BUFFER_REPLACEMENT_MODE_NORMAL); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
captionStringBuilder = new StringBuilder(); captionStringBuilder = new StringBuilder();
pendingCaptionLists = new TreeSet<>(); pendingCaptionLists = new TreeSet<>();
} }
@ -97,7 +97,7 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
inputStreamEnded = false; inputStreamEnded = false;
repeatableControl = null; repeatableControl = null;
pendingCaptionLists.clear(); pendingCaptionLists.clear();
clearPendingSample(); clearPendingBuffer();
captionRowCount = DEFAULT_CAPTIONS_ROW_COUNT; captionRowCount = DEFAULT_CAPTIONS_ROW_COUNT;
setCaptionMode(CC_MODE_UNKNOWN); setCaptionMode(CC_MODE_UNKNOWN);
invokeRenderer(null); invokeRenderer(null);
@ -106,17 +106,20 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
@Override @Override
protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady) protected void render(long positionUs, long elapsedRealtimeUs, boolean sourceIsReady)
throws ExoPlaybackException { throws ExoPlaybackException {
if (isSamplePending()) { if (isBufferPending()) {
maybeParsePendingSample(positionUs); maybeParsePendingBuffer(positionUs);
} }
int result = inputStreamEnded ? TrackStream.END_OF_STREAM : TrackStream.SAMPLE_READ; while (!isBufferPending() && !inputStreamEnded) {
while (!isSamplePending() && result == TrackStream.SAMPLE_READ) { int result = readSource(formatHolder, buffer);
result = readSource(formatHolder, sampleHolder); if (result == TrackStream.BUFFER_READ) {
if (result == TrackStream.SAMPLE_READ) { if (buffer.isEndOfStream()) {
maybeParsePendingSample(positionUs); inputStreamEnded = true;
} else if (result == TrackStream.END_OF_STREAM) { } else {
inputStreamEnded = true; 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) { private void maybeParsePendingBuffer(long positionUs) {
if (sampleHolder.timeUs > positionUs + MAX_SAMPLE_READAHEAD_US) { if (buffer.timeUs > positionUs + MAX_BUFFER_READAHEAD_US) {
// We're too early to parse the sample. // We're too early to parse the buffer.
return; return;
} }
ClosedCaptionList holder = eia608Parser.parse(sampleHolder); ClosedCaptionList holder = eia608Parser.parse(buffer);
clearPendingSample(); clearPendingBuffer();
if (holder != null) { if (holder != null) {
pendingCaptionLists.add(holder); pendingCaptionLists.add(holder);
} }
@ -338,13 +341,13 @@ public final class Eia608TrackRenderer extends SampleSourceTrackRenderer impleme
return captionStringBuilder.substring(0, endIndex - startIndex); return captionStringBuilder.substring(0, endIndex - startIndex);
} }
private void clearPendingSample() { private void clearPendingBuffer() {
sampleHolder.clear(); buffer.clear();
sampleHolder.timeUs = C.UNKNOWN_TIME_US; buffer.timeUs = C.UNKNOWN_TIME_US;
} }
private boolean isSamplePending() { private boolean isBufferPending() {
return sampleHolder.timeUs != C.UNKNOWN_TIME_US; return buffer.timeUs != C.UNKNOWN_TIME_US;
} }
} }

View File

@ -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() { 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() { 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() { public final boolean isKeyFrame() {
return getFlag(C.SAMPLE_FLAG_SYNC); return getFlag(C.BUFFER_FLAG_KEY_FRAME);
} }
/** /**
* Replaces this buffer's flags with {@code flags}. * 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. * constants.
*/ */
public final void setFlags(int flags) { public final void setFlags(int flags) {
@ -66,7 +66,7 @@ public abstract class Buffer {
* Adds the {@code flag} to this buffer's flags. * 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 * @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) { public final void addFlag(int flag) {
flags |= flag; flags |= flag;

View File

@ -16,7 +16,7 @@
package com.google.android.exoplayer.util.extensions; package com.google.android.exoplayer.util.extensions;
import com.google.android.exoplayer.C; 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 com.google.android.exoplayer.util.Assertions;
import java.util.LinkedList; import java.util.LinkedList;
@ -24,7 +24,7 @@ import java.util.LinkedList;
/** /**
* Base class for {@link Decoder}s that use their own decode thread. * 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> { 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()) { if (inputBuffer.isEndOfStream()) {
outputBuffer.addFlag(C.SAMPLE_FLAG_END_OF_STREAM); outputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
} else { } else {
if (inputBuffer.isDecodeOnly()) { if (inputBuffer.isDecodeOnly()) {
outputBuffer.addFlag(C.SAMPLE_FLAG_DECODE_ONLY); outputBuffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY);
} }
exception = decode(inputBuffer, outputBuffer); exception = decode(inputBuffer, outputBuffer);
if (exception != null) { if (exception != null) {
@ -276,7 +276,7 @@ public abstract class SimpleDecoder<I extends SampleHolder, O extends OutputBuff
* *
* @param inputBuffer The buffer to decode. * @param inputBuffer The buffer to decode.
* @param outputBuffer The output buffer to store decoded data. The flag * @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 * {@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. * after this method returns, any output will not be presented.
* @return A decoder exception if an error occurred, or null if decoding was successful. * @return A decoder exception if an error occurred, or null if decoding was successful.