Signal end of stream in SampleHolder flags.

Also use MediaCodec buffer flag constants instead of those on MediaExtractor.

This is in preparation for merging InputBuffer and SampleHolder.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117810136
This commit is contained in:
andrewlewis 2016-03-22 04:20:56 -07:00 committed by Oliver Woodman
parent 733f2ccd1c
commit fc716b5711
12 changed files with 54 additions and 42 deletions

View File

@ -17,7 +17,6 @@ package com.google.android.exoplayer;
import android.annotation.SuppressLint;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import junit.framework.TestCase;
@ -29,8 +28,8 @@ public class CTest extends TestCase {
@SuppressLint("InlinedApi")
public static final void testContants() {
// Sanity check that constant values match those defined by the platform.
assertEquals(MediaExtractor.SAMPLE_FLAG_SYNC, C.SAMPLE_FLAG_SYNC);
assertEquals(MediaExtractor.SAMPLE_FLAG_ENCRYPTED, C.SAMPLE_FLAG_ENCRYPTED);
assertEquals(MediaCodec.BUFFER_FLAG_KEY_FRAME, C.SAMPLE_FLAG_SYNC);
assertEquals(MediaCodec.BUFFER_FLAG_END_OF_STREAM, C.SAMPLE_FLAG_END_OF_STREAM);
assertEquals(MediaCodec.CRYPTO_MODE_AES_CTR, C.CRYPTO_MODE_AES_CTR);
}

View File

@ -19,7 +19,6 @@ import com.google.android.exoplayer.util.Util;
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaExtractor;
/**
* Defines constants that are generally useful throughout the library.
@ -89,21 +88,26 @@ public final class C {
? AudioFormat.CHANNEL_OUT_7POINT1 : AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
/**
* @see MediaExtractor#SAMPLE_FLAG_SYNC
* Indicates that a sample is a synchronization sample.
*/
@SuppressWarnings("InlinedApi")
public static final int SAMPLE_FLAG_SYNC = MediaExtractor.SAMPLE_FLAG_SYNC;
public static final int SAMPLE_FLAG_SYNC = MediaCodec.BUFFER_FLAG_KEY_FRAME;
/**
* @see MediaExtractor#SAMPLE_FLAG_ENCRYPTED
* Flag for empty buffers that signal that the end of the stream was reached.
*/
@SuppressWarnings("InlinedApi")
public static final int SAMPLE_FLAG_ENCRYPTED = MediaExtractor.SAMPLE_FLAG_ENCRYPTED;
public static final int SAMPLE_FLAG_END_OF_STREAM = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
/**
* Indicates that a sample is (at least partially) encrypted.
*/
public static final int SAMPLE_FLAG_ENCRYPTED = 0x40000000;
/**
* Indicates that a sample should be decoded but not rendered.
*/
public static final int SAMPLE_FLAG_DECODE_ONLY = 0x8000000;
public static final int SAMPLE_FLAG_DECODE_ONLY = 0x80000000;
/**
* A return value for methods where the end of an input was encountered.

View File

@ -56,8 +56,6 @@ import java.util.UUID;
@TargetApi(16)
public final class FrameworkSampleSource implements SampleSource {
private static final int ALLOWED_FLAGS_MASK = C.SAMPLE_FLAG_SYNC | C.SAMPLE_FLAG_ENCRYPTED;
private static final int TRACK_STATE_DISABLED = 0;
private static final int TRACK_STATE_ENABLED = 1;
private static final int TRACK_STATE_FORMAT_SENT = 2;
@ -196,6 +194,7 @@ public final class FrameworkSampleSource implements SampleSource {
return TrackStream.FORMAT_READ;
}
int extractorTrackIndex = extractor.getSampleTrackIndex();
sampleHolder.flags = 0;
if (extractorTrackIndex == track) {
if (sampleHolder.data != null) {
int offset = sampleHolder.data.position();
@ -205,15 +204,22 @@ public final class FrameworkSampleSource implements SampleSource {
sampleHolder.size = 0;
}
sampleHolder.timeUs = extractor.getSampleTime();
sampleHolder.flags = extractor.getSampleFlags() & ALLOWED_FLAGS_MASK;
if (sampleHolder.isEncrypted()) {
int flags = extractor.getSampleFlags();
if ((flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_SYNC;
}
if ((flags & MediaExtractor.SAMPLE_FLAG_ENCRYPTED) != 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_ENCRYPTED;
sampleHolder.cryptoInfo.setFromExtractorV16(extractor);
}
pendingSeekPositionUs = C.UNKNOWN_TIME_US;
extractor.advance();
return TrackStream.SAMPLE_READ;
} else if (extractorTrackIndex < 0) {
sampleHolder.flags |= C.SAMPLE_FLAG_END_OF_STREAM;
return TrackStream.END_OF_STREAM;
} else {
return extractorTrackIndex < 0 ? TrackStream.END_OF_STREAM : TrackStream.NOTHING_READ;
return TrackStream.NOTHING_READ;
}
}

View File

@ -50,8 +50,7 @@ public final class SampleHolder {
public int size;
/**
* Flags that accompany the sample. A combination of {@link C#SAMPLE_FLAG_SYNC},
* {@link C#SAMPLE_FLAG_ENCRYPTED} and {@link C#SAMPLE_FLAG_DECODE_ONLY}.
* Flags that accompany the sample. A combination of the {@code C.SAMPLE_FLAG_*} constants.
*/
public int flags;

View File

@ -67,7 +67,9 @@ public abstract class SampleSourceTrackRenderer extends TrackRenderer {
* @param formatHolder A {@link FormatHolder} object to populate in the case of a new format.
* @param sampleHolder A {@link SampleHolder} object to populate in the case of a new sample.
* If the caller requires the sample data then it must ensure that {@link SampleHolder#data}
* references a valid output buffer.
* 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}.

View File

@ -162,6 +162,7 @@ public final class SingleSampleSource implements SampleSource, TrackStream, Load
@Override
public int readData(FormatHolder formatHolder, SampleHolder sampleHolder) {
if (state == STATE_END_OF_STREAM) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM;
return END_OF_STREAM;
} else if (state == STATE_SEND_FORMAT) {
formatHolder.format = format;

View File

@ -77,7 +77,9 @@ public interface TrackStream {
* @param formatHolder A {@link FormatHolder} to populate in the case of a new format.
* @param sampleHolder A {@link SampleHolder} to populate in the case of a new sample. If the
* caller requires the sample data then it must ensure that {@link SampleHolder#data}
* references a valid output buffer.
* references a valid output buffer. If the end of the stream has been reached,
* {@link #END_OF_STREAM} will be returned and {@link C#SAMPLE_FLAG_END_OF_STREAM} will be set
* on the sample holder.
* @return The result, which can be {@link #END_OF_STREAM}, {@link #NOTHING_READ},
* {@link #FORMAT_READ} or {@link #SAMPLE_READ}.
*/

View File

@ -273,6 +273,7 @@ public class ChunkSampleSource implements SampleSource, TrackStream, Loader.Call
if (!haveSamples) {
if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM;
return END_OF_STREAM;
}
return NOTHING_READ;

View File

@ -460,6 +460,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
}
if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM;
return TrackStream.END_OF_STREAM;
}

View File

@ -337,6 +337,7 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
}
if (loadingFinished) {
sampleHolder.flags = C.SAMPLE_FLAG_END_OF_STREAM;
return TrackStream.END_OF_STREAM;
}

View File

@ -20,19 +20,6 @@ package com.google.android.exoplayer.util.extensions;
*/
public abstract class Buffer {
/**
* Flag for empty input/output buffers that signal that the end of the stream was reached.
*/
public static final int FLAG_END_OF_STREAM = 1;
/**
* Flag for non-empty input buffers which signals that the decoder must be reset before decoding.
*/
public static final int FLAG_RESET = 2;
/**
* Flag for non-empty input/output buffers that should only be decoded (not rendered).
*/
public static final int FLAG_DECODE_ONLY = 4;
private int flags;
public void reset() {

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer.util.extensions;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.util.Assertions;
import java.util.LinkedList;
@ -219,16 +220,23 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
flushDecodedOutputBuffer = false;
}
outputBuffer.reset();
if (inputBuffer.getFlag(C.SAMPLE_FLAG_END_OF_STREAM)) {
outputBuffer.setFlag(C.SAMPLE_FLAG_END_OF_STREAM);
} else {
if (inputBuffer.getFlag(C.SAMPLE_FLAG_DECODE_ONLY)) {
outputBuffer.setFlag(C.SAMPLE_FLAG_DECODE_ONLY);
}
exception = decode(inputBuffer, outputBuffer);
if (exception != null) {
// Memory barrier to ensure that the decoder exception is visible from the playback thread.
synchronized (lock) {}
return false;
}
}
boolean decodeOnly = outputBuffer.getFlag(Buffer.FLAG_DECODE_ONLY);
synchronized (lock) {
if (flushDecodedOutputBuffer || decodeOnly) {
if (flushDecodedOutputBuffer || outputBuffer.getFlag(C.SAMPLE_FLAG_DECODE_ONLY)) {
// If a flush occurred while decoding or the buffer was only for decoding (not presentation)
// then make the output buffer available again rather than queueing it to be consumed.
availableOutputBuffers[availableOutputBufferCount++] = outputBuffer;
@ -261,10 +269,11 @@ public abstract class SimpleDecoder<I extends InputBuffer, O extends OutputBuffe
* Decodes the {@code inputBuffer} and stores any decoded output in {@code outputBuffer}.
*
* @param inputBuffer The buffer to decode.
* @param outputBuffer The output buffer to store decoded data. If the flag
* {@link Buffer#FLAG_DECODE_ONLY} is set after this method returns, any output should not be
* presented.
* @return A decode exception if an error occurred, or null if the decode was successful.
* @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
* {@code inputBuffer}, but the decoder may set/unset the flag if required. If the flag is set
* after this method returns, any output will not be presented.
* @return A decoder exception if an error occurred, or null if decoding was successful.
*/
protected abstract E decode(I inputBuffer, O outputBuffer);