Use @IntDef for some more int-based enumerations

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=188853170
This commit is contained in:
andrewlewis 2018-03-13 03:54:48 -07:00 committed by Oliver Woodman
parent 4f56636328
commit 07f898d441
19 changed files with 298 additions and 230 deletions

View File

@ -15,21 +15,29 @@
*/
package com.google.android.exoplayer2;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.util.MediaClock;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Renders media read from a {@link SampleStream}.
*
* <p>Internally, a renderer's lifecycle is managed by the owning {@link ExoPlayer}. The renderer is
* transitioned through various states as the overall playback state changes. The valid state
* transitions are shown below, annotated with the methods that are called during each transition.
* transitioned through various states as the overall playback state and enabled tracks change. The
* valid state transitions are shown below, annotated with the methods that are called during each
* transition.
*
* <p align="center"><img src="doc-files/renderer-states.svg" alt="Renderer state transitions">
*/
public interface Renderer extends PlayerMessage.Target {
/** The renderer states. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({STATE_DISABLED, STATE_ENABLED, STATE_STARTED})
@interface State {}
/**
* The renderer is disabled.
*/
@ -80,8 +88,10 @@ public interface Renderer extends PlayerMessage.Target {
/**
* Returns the current state of the renderer.
*
* @return The current state (one of the {@code STATE_*} constants).
* @return The current state. One of {@link #STATE_DISABLED}, {@link #STATE_ENABLED} and {@link
* #STATE_STARTED}.
*/
@State
int getState();
/**

View File

@ -15,41 +15,35 @@
*/
package com.google.android.exoplayer2.audio;
import static com.google.android.exoplayer2.audio.Ac3Util.Ac3SyncFrameInfo.STREAM_TYPE_TYPE0;
import static com.google.android.exoplayer2.audio.Ac3Util.Ac3SyncFrameInfo.STREAM_TYPE_TYPE1;
import static com.google.android.exoplayer2.audio.Ac3Util.Ac3SyncFrameInfo.STREAM_TYPE_UNDEFINED;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.Ac3Util.SyncFrameInfo.StreamType;
import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
/** Utility methods for parsing Dolby TrueHD and (E-)AC3 syncframes. */
public final class Ac3Util {
/**
* Holds sample format information as presented by a syncframe header.
*/
public static final class Ac3SyncFrameInfo {
/** Holds sample format information as presented by a syncframe header. */
public static final class SyncFrameInfo {
/**
* Undefined AC3 stream type.
*/
/** AC3 stream types. See also ETSI TS 102 366 E.1.3.1.1. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({STREAM_TYPE_UNDEFINED, STREAM_TYPE_TYPE0, STREAM_TYPE_TYPE1, STREAM_TYPE_TYPE2})
public @interface StreamType {}
/** Undefined AC3 stream type. */
public static final int STREAM_TYPE_UNDEFINED = -1;
/**
* Type 0 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1.
*/
/** Type 0 AC3 stream type. */
public static final int STREAM_TYPE_TYPE0 = 0;
/**
* Type 1 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1.
*/
/** Type 1 AC3 stream type. */
public static final int STREAM_TYPE_TYPE1 = 1;
/**
* Type 2 AC3 stream type. See ETSI TS 102 366 E.1.3.1.1.
*/
/** Type 2 AC3 stream type. */
public static final int STREAM_TYPE_TYPE2 = 2;
/**
@ -58,10 +52,10 @@ public final class Ac3Util {
*/
public final String mimeType;
/**
* The type of the stream if {@link #mimeType} is {@link MimeTypes#AUDIO_E_AC3}, or
* {@link #STREAM_TYPE_UNDEFINED} otherwise.
* The type of the stream if {@link #mimeType} is {@link MimeTypes#AUDIO_E_AC3}, or {@link
* #STREAM_TYPE_UNDEFINED} otherwise.
*/
public final int streamType;
public final @StreamType int streamType;
/**
* The audio sampling rate in Hz.
*/
@ -79,8 +73,13 @@ public final class Ac3Util {
*/
public final int sampleCount;
private Ac3SyncFrameInfo(String mimeType, int streamType, int channelCount, int sampleRate,
int frameSize, int sampleCount) {
private SyncFrameInfo(
String mimeType,
@StreamType int streamType,
int channelCount,
int sampleRate,
int frameSize,
int sampleCount) {
this.mimeType = mimeType;
this.streamType = streamType;
this.channelCount = channelCount;
@ -212,13 +211,13 @@ public final class Ac3Util {
* @param data The data to parse, positioned at the start of the syncframe.
* @return The (E-)AC-3 format data parsed from the header.
*/
public static Ac3SyncFrameInfo parseAc3SyncframeInfo(ParsableBitArray data) {
public static SyncFrameInfo parseAc3SyncframeInfo(ParsableBitArray data) {
int initialPosition = data.getPosition();
data.skipBits(40);
boolean isEac3 = data.readBits(5) == 16;
data.setPosition(initialPosition);
String mimeType;
int streamType = STREAM_TYPE_UNDEFINED;
@StreamType int streamType = SyncFrameInfo.STREAM_TYPE_UNDEFINED;
int sampleRate;
int acmod;
int frameSize;
@ -228,7 +227,20 @@ public final class Ac3Util {
if (isEac3) {
// Syntax from ETSI TS 102 366 V1.2.1 subsections E.1.2.1 and E.1.2.2.
data.skipBits(16); // syncword
streamType = data.readBits(2);
switch (data.readBits(2)) { // strmtyp
case 0:
streamType = SyncFrameInfo.STREAM_TYPE_TYPE0;
break;
case 1:
streamType = SyncFrameInfo.STREAM_TYPE_TYPE1;
break;
case 2:
streamType = SyncFrameInfo.STREAM_TYPE_TYPE2;
break;
default:
streamType = SyncFrameInfo.STREAM_TYPE_UNDEFINED;
break;
}
data.skipBits(3); // substreamid
frameSize = (data.readBits(11) + 1) * 2;
int fscod = data.readBits(2);
@ -257,7 +269,7 @@ public final class Ac3Util {
data.skipBits(8); // compr2
}
}
if (streamType == STREAM_TYPE_TYPE1 && data.readBit()) { // chanmape
if (streamType == SyncFrameInfo.STREAM_TYPE_TYPE1 && data.readBit()) { // chanmape
data.skipBits(16); // chanmap
}
if (data.readBit()) { // mixmdate
@ -273,7 +285,7 @@ public final class Ac3Util {
if (lfeon && data.readBit()) { // lfemixlevcode
data.skipBits(5); // lfemixlevcod
}
if (streamType == STREAM_TYPE_TYPE0) {
if (streamType == SyncFrameInfo.STREAM_TYPE_TYPE0) {
if (data.readBit()) { // pgmscle
data.skipBits(6); //pgmscl
}
@ -375,10 +387,11 @@ public final class Ac3Util {
data.skipBit(); // sourcefscod
}
}
if (streamType == 0 && numblkscod != 3) {
if (streamType == SyncFrameInfo.STREAM_TYPE_TYPE0 && numblkscod != 3) {
data.skipBit(); // convsync
}
if (streamType == 2 && (numblkscod == 3 || data.readBit())) { // blkid
if (streamType == SyncFrameInfo.STREAM_TYPE_TYPE2
&& (numblkscod == 3 || data.readBit())) { // blkid
data.skipBits(6); // frmsizecod
}
mimeType = MimeTypes.AUDIO_E_AC3;
@ -410,8 +423,8 @@ public final class Ac3Util {
lfeon = data.readBit();
channelCount = CHANNEL_COUNT_BY_ACMOD[acmod] + (lfeon ? 1 : 0);
}
return new Ac3SyncFrameInfo(mimeType, streamType, channelCount, sampleRate, frameSize,
sampleCount);
return new SyncFrameInfo(
mimeType, streamType, channelCount, sampleRate, frameSize, sampleCount);
}
/**

View File

@ -80,6 +80,10 @@ public final class DefaultAudioSink implements AudioSink {
*/
private static final int BUFFER_MULTIPLICATION_FACTOR = 4;
/** {@link AudioTrack} playback states. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, PLAYSTATE_PLAYING})
private @interface PlayState {}
/**
* @see AudioTrack#PLAYSTATE_STOPPED
*/
@ -965,8 +969,7 @@ public final class DefaultAudioSink implements AudioSink {
startMediaTimeState = START_NOT_SET;
latencyUs = 0;
resetSyncParams();
int playState = audioTrack.getPlayState();
if (playState == PLAYSTATE_PLAYING) {
if (audioTrack.getPlayState() == PLAYSTATE_PLAYING) {
audioTrack.pause();
}
// AudioTrack.release can take some time, so we call it on a background thread.
@ -1426,8 +1429,8 @@ public final class DefaultAudioSink implements AudioSink {
return Math.min(endPlaybackHeadPosition, stopPlaybackHeadPosition + framesSinceStop);
}
int state = audioTrack.getPlayState();
if (state == PLAYSTATE_STOPPED) {
@PlayState int playState = audioTrack.getPlayState();
if (playState == PLAYSTATE_STOPPED) {
// The audio track hasn't been started.
return 0;
}
@ -1437,15 +1440,16 @@ public final class DefaultAudioSink implements AudioSink {
// Work around an issue with passthrough/direct AudioTracks on platform API versions 21/22
// where the playback head position jumps back to zero on paused passthrough/direct audio
// tracks. See [Internal: b/19187573].
if (state == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
if (playState == PLAYSTATE_PAUSED && rawPlaybackHeadPosition == 0) {
passthroughWorkaroundPauseOffset = lastRawPlaybackHeadPosition;
}
rawPlaybackHeadPosition += passthroughWorkaroundPauseOffset;
}
if (Util.SDK_INT <= 28) {
if (rawPlaybackHeadPosition == 0 && lastRawPlaybackHeadPosition > 0
&& state == PLAYSTATE_PLAYING) {
if (rawPlaybackHeadPosition == 0
&& lastRawPlaybackHeadPosition > 0
&& playState == PLAYSTATE_PLAYING) {
// If connecting a Bluetooth audio device fails, the AudioTrack may be left in a state
// where its Java API is in the playing state, but the native track is stopped. When this
// happens the playback head position gets stuck at zero. In this case, return the old

View File

@ -15,12 +15,15 @@
*/
package com.google.android.exoplayer2.extractor.mkv;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.util.Assertions;
import java.io.EOFException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Stack;
/**
@ -28,6 +31,10 @@ import java.util.Stack;
*/
/* package */ final class DefaultEbmlReader implements EbmlReader {
@Retention(RetentionPolicy.SOURCE)
@IntDef({ELEMENT_STATE_READ_ID, ELEMENT_STATE_READ_CONTENT_SIZE, ELEMENT_STATE_READ_CONTENT})
private @interface ElementState {}
private static final int ELEMENT_STATE_READ_ID = 0;
private static final int ELEMENT_STATE_READ_CONTENT_SIZE = 1;
private static final int ELEMENT_STATE_READ_CONTENT = 2;
@ -44,7 +51,7 @@ import java.util.Stack;
private final VarintReader varintReader = new VarintReader();
private EbmlReaderOutput output;
private int elementState;
private @ElementState int elementState;
private int elementId;
private long elementContentSize;
@ -88,23 +95,23 @@ import java.util.Stack;
elementState = ELEMENT_STATE_READ_CONTENT;
}
int type = output.getElementType(elementId);
@EbmlReaderOutput.ElementType int type = output.getElementType(elementId);
switch (type) {
case TYPE_MASTER:
case EbmlReaderOutput.TYPE_MASTER:
long elementContentPosition = input.getPosition();
long elementEndPosition = elementContentPosition + elementContentSize;
masterElementsStack.add(new MasterElement(elementId, elementEndPosition));
output.startMasterElement(elementId, elementContentPosition, elementContentSize);
elementState = ELEMENT_STATE_READ_ID;
return true;
case TYPE_UNSIGNED_INT:
case EbmlReaderOutput.TYPE_UNSIGNED_INT:
if (elementContentSize > MAX_INTEGER_ELEMENT_SIZE_BYTES) {
throw new ParserException("Invalid integer size: " + elementContentSize);
}
output.integerElement(elementId, readInteger(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID;
return true;
case TYPE_FLOAT:
case EbmlReaderOutput.TYPE_FLOAT:
if (elementContentSize != VALID_FLOAT32_ELEMENT_SIZE_BYTES
&& elementContentSize != VALID_FLOAT64_ELEMENT_SIZE_BYTES) {
throw new ParserException("Invalid float size: " + elementContentSize);
@ -112,18 +119,18 @@ import java.util.Stack;
output.floatElement(elementId, readFloat(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID;
return true;
case TYPE_STRING:
case EbmlReaderOutput.TYPE_STRING:
if (elementContentSize > Integer.MAX_VALUE) {
throw new ParserException("String element size: " + elementContentSize);
}
output.stringElement(elementId, readString(input, (int) elementContentSize));
elementState = ELEMENT_STATE_READ_ID;
return true;
case TYPE_BINARY:
case EbmlReaderOutput.TYPE_BINARY:
output.binaryElement(elementId, (int) elementContentSize, input);
elementState = ELEMENT_STATE_READ_ID;
return true;
case TYPE_UNKNOWN:
case EbmlReaderOutput.TYPE_UNKNOWN:
input.skipFully((int) elementContentSize);
elementState = ELEMENT_STATE_READ_ID;
break;

View File

@ -28,31 +28,6 @@ import java.io.IOException;
*/
/* package */ interface EbmlReader {
/**
* Type for unknown elements.
*/
int TYPE_UNKNOWN = 0;
/**
* Type for elements that contain child elements.
*/
int TYPE_MASTER = 1;
/**
* Type for integer value elements of up to 8 bytes.
*/
int TYPE_UNSIGNED_INT = 2;
/**
* Type for string elements.
*/
int TYPE_STRING = 3;
/**
* Type for binary elements.
*/
int TYPE_BINARY = 4;
/**
* Type for IEEE floating point value elements of either 4 or 8 bytes.
*/
int TYPE_FLOAT = 5;
/**
* Initializes the extractor with an {@link EbmlReaderOutput}.
*

View File

@ -15,24 +15,46 @@
*/
package com.google.android.exoplayer2.extractor.mkv;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Defines EBML element IDs/types and reacts to events.
*/
/* package */ interface EbmlReaderOutput {
/** EBML element types. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_UNKNOWN, TYPE_MASTER, TYPE_UNSIGNED_INT, TYPE_STRING, TYPE_BINARY, TYPE_FLOAT})
@interface ElementType {}
/** Type for unknown elements. */
int TYPE_UNKNOWN = 0;
/** Type for elements that contain child elements. */
int TYPE_MASTER = 1;
/** Type for integer value elements of up to 8 bytes. */
int TYPE_UNSIGNED_INT = 2;
/** Type for string elements. */
int TYPE_STRING = 3;
/** Type for binary elements. */
int TYPE_BINARY = 4;
/** Type for IEEE floating point value elements of either 4 or 8 bytes. */
int TYPE_FLOAT = 5;
/**
* Maps an element ID to a corresponding type.
* <p>
* If {@link EbmlReader#TYPE_UNKNOWN} is returned then the element is skipped. Note that all
* children of a skipped element are also skipped.
*
* <p>If {@link #TYPE_UNKNOWN} is returned then the element is skipped. Note that all children of
* a skipped element are also skipped.
*
* @param id The element ID to map.
* @return One of the {@code TYPE_} constants defined in {@link EbmlReader}.
* @return One of {@link #TYPE_UNKNOWN}, {@link #TYPE_MASTER}, {@link #TYPE_UNSIGNED_INT}, {@link
* #TYPE_STRING}, {@link #TYPE_BINARY} and {@link #TYPE_FLOAT}.
*/
@ElementType
int getElementType(int id);
/**

View File

@ -448,100 +448,6 @@ public final class MatroskaExtractor implements Extractor {
return Extractor.RESULT_CONTINUE;
}
/* package */ int getElementType(int id) {
switch (id) {
case ID_EBML:
case ID_SEGMENT:
case ID_SEEK_HEAD:
case ID_SEEK:
case ID_INFO:
case ID_CLUSTER:
case ID_TRACKS:
case ID_TRACK_ENTRY:
case ID_AUDIO:
case ID_VIDEO:
case ID_CONTENT_ENCODINGS:
case ID_CONTENT_ENCODING:
case ID_CONTENT_COMPRESSION:
case ID_CONTENT_ENCRYPTION:
case ID_CONTENT_ENCRYPTION_AES_SETTINGS:
case ID_CUES:
case ID_CUE_POINT:
case ID_CUE_TRACK_POSITIONS:
case ID_BLOCK_GROUP:
case ID_PROJECTION:
case ID_COLOUR:
case ID_MASTERING_METADATA:
return EbmlReader.TYPE_MASTER;
case ID_EBML_READ_VERSION:
case ID_DOC_TYPE_READ_VERSION:
case ID_SEEK_POSITION:
case ID_TIMECODE_SCALE:
case ID_TIME_CODE:
case ID_BLOCK_DURATION:
case ID_PIXEL_WIDTH:
case ID_PIXEL_HEIGHT:
case ID_DISPLAY_WIDTH:
case ID_DISPLAY_HEIGHT:
case ID_DISPLAY_UNIT:
case ID_TRACK_NUMBER:
case ID_TRACK_TYPE:
case ID_FLAG_DEFAULT:
case ID_FLAG_FORCED:
case ID_DEFAULT_DURATION:
case ID_CODEC_DELAY:
case ID_SEEK_PRE_ROLL:
case ID_CHANNELS:
case ID_AUDIO_BIT_DEPTH:
case ID_CONTENT_ENCODING_ORDER:
case ID_CONTENT_ENCODING_SCOPE:
case ID_CONTENT_COMPRESSION_ALGORITHM:
case ID_CONTENT_ENCRYPTION_ALGORITHM:
case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE:
case ID_CUE_TIME:
case ID_CUE_CLUSTER_POSITION:
case ID_REFERENCE_BLOCK:
case ID_STEREO_MODE:
case ID_COLOUR_RANGE:
case ID_COLOUR_TRANSFER:
case ID_COLOUR_PRIMARIES:
case ID_MAX_CLL:
case ID_MAX_FALL:
return EbmlReader.TYPE_UNSIGNED_INT;
case ID_DOC_TYPE:
case ID_CODEC_ID:
case ID_LANGUAGE:
return EbmlReader.TYPE_STRING;
case ID_SEEK_ID:
case ID_CONTENT_COMPRESSION_SETTINGS:
case ID_CONTENT_ENCRYPTION_KEY_ID:
case ID_SIMPLE_BLOCK:
case ID_BLOCK:
case ID_CODEC_PRIVATE:
case ID_PROJECTION_PRIVATE:
return EbmlReader.TYPE_BINARY;
case ID_DURATION:
case ID_SAMPLING_FREQUENCY:
case ID_PRIMARY_R_CHROMATICITY_X:
case ID_PRIMARY_R_CHROMATICITY_Y:
case ID_PRIMARY_G_CHROMATICITY_X:
case ID_PRIMARY_G_CHROMATICITY_Y:
case ID_PRIMARY_B_CHROMATICITY_X:
case ID_PRIMARY_B_CHROMATICITY_Y:
case ID_WHITE_POINT_CHROMATICITY_X:
case ID_WHITE_POINT_CHROMATICITY_Y:
case ID_LUMNINANCE_MAX:
case ID_LUMNINANCE_MIN:
return EbmlReader.TYPE_FLOAT;
default:
return EbmlReader.TYPE_UNKNOWN;
}
}
/* package */ boolean isLevel1Element(int id) {
return id == ID_SEGMENT_INFO || id == ID_CLUSTER || id == ID_CUES || id == ID_TRACKS;
}
/* package */ void startMasterElement(int id, long contentPosition, long contentSize)
throws ParserException {
switch (id) {
@ -1501,12 +1407,98 @@ public final class MatroskaExtractor implements Extractor {
@Override
public int getElementType(int id) {
return MatroskaExtractor.this.getElementType(id);
switch (id) {
case ID_EBML:
case ID_SEGMENT:
case ID_SEEK_HEAD:
case ID_SEEK:
case ID_INFO:
case ID_CLUSTER:
case ID_TRACKS:
case ID_TRACK_ENTRY:
case ID_AUDIO:
case ID_VIDEO:
case ID_CONTENT_ENCODINGS:
case ID_CONTENT_ENCODING:
case ID_CONTENT_COMPRESSION:
case ID_CONTENT_ENCRYPTION:
case ID_CONTENT_ENCRYPTION_AES_SETTINGS:
case ID_CUES:
case ID_CUE_POINT:
case ID_CUE_TRACK_POSITIONS:
case ID_BLOCK_GROUP:
case ID_PROJECTION:
case ID_COLOUR:
case ID_MASTERING_METADATA:
return TYPE_MASTER;
case ID_EBML_READ_VERSION:
case ID_DOC_TYPE_READ_VERSION:
case ID_SEEK_POSITION:
case ID_TIMECODE_SCALE:
case ID_TIME_CODE:
case ID_BLOCK_DURATION:
case ID_PIXEL_WIDTH:
case ID_PIXEL_HEIGHT:
case ID_DISPLAY_WIDTH:
case ID_DISPLAY_HEIGHT:
case ID_DISPLAY_UNIT:
case ID_TRACK_NUMBER:
case ID_TRACK_TYPE:
case ID_FLAG_DEFAULT:
case ID_FLAG_FORCED:
case ID_DEFAULT_DURATION:
case ID_CODEC_DELAY:
case ID_SEEK_PRE_ROLL:
case ID_CHANNELS:
case ID_AUDIO_BIT_DEPTH:
case ID_CONTENT_ENCODING_ORDER:
case ID_CONTENT_ENCODING_SCOPE:
case ID_CONTENT_COMPRESSION_ALGORITHM:
case ID_CONTENT_ENCRYPTION_ALGORITHM:
case ID_CONTENT_ENCRYPTION_AES_SETTINGS_CIPHER_MODE:
case ID_CUE_TIME:
case ID_CUE_CLUSTER_POSITION:
case ID_REFERENCE_BLOCK:
case ID_STEREO_MODE:
case ID_COLOUR_RANGE:
case ID_COLOUR_TRANSFER:
case ID_COLOUR_PRIMARIES:
case ID_MAX_CLL:
case ID_MAX_FALL:
return TYPE_UNSIGNED_INT;
case ID_DOC_TYPE:
case ID_CODEC_ID:
case ID_LANGUAGE:
return TYPE_STRING;
case ID_SEEK_ID:
case ID_CONTENT_COMPRESSION_SETTINGS:
case ID_CONTENT_ENCRYPTION_KEY_ID:
case ID_SIMPLE_BLOCK:
case ID_BLOCK:
case ID_CODEC_PRIVATE:
case ID_PROJECTION_PRIVATE:
return TYPE_BINARY;
case ID_DURATION:
case ID_SAMPLING_FREQUENCY:
case ID_PRIMARY_R_CHROMATICITY_X:
case ID_PRIMARY_R_CHROMATICITY_Y:
case ID_PRIMARY_G_CHROMATICITY_X:
case ID_PRIMARY_G_CHROMATICITY_Y:
case ID_PRIMARY_B_CHROMATICITY_X:
case ID_PRIMARY_B_CHROMATICITY_Y:
case ID_WHITE_POINT_CHROMATICITY_X:
case ID_WHITE_POINT_CHROMATICITY_Y:
case ID_LUMNINANCE_MAX:
case ID_LUMNINANCE_MIN:
return TYPE_FLOAT;
default:
return TYPE_UNKNOWN;
}
}
@Override
public boolean isLevel1Element(int id) {
return MatroskaExtractor.this.isLevel1Element(id);
return id == ID_SEGMENT_INFO || id == ID_CLUSTER || id == ID_CUES || id == ID_TRACKS;
}
@Override

View File

@ -19,6 +19,7 @@ import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.audio.Ac3Util;
import com.google.android.exoplayer2.audio.Ac3Util.SyncFrameInfo;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
@ -187,7 +188,7 @@ public final class Ac3Reader implements ElementaryStreamReader {
@SuppressWarnings("ReferenceEquality")
private void parseHeader() {
headerScratchBits.setPosition(0);
Ac3Util.Ac3SyncFrameInfo frameInfo = Ac3Util.parseAc3SyncframeInfo(headerScratchBits);
SyncFrameInfo frameInfo = Ac3Util.parseAc3SyncframeInfo(headerScratchBits);
if (format == null || frameInfo.channelCount != format.channelCount
|| frameInfo.sampleRate != format.sampleRate
|| frameInfo.mimeType != format.sampleMimeType) {

View File

@ -524,8 +524,8 @@ import java.util.Arrays;
}
@Override
public int onLoadError(ExtractingLoadable loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ExtractingLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
boolean isErrorFatal = isLoadableExceptionFatal(error);
eventDispatcher.loadError(
loadable.dataSpec,

View File

@ -221,8 +221,8 @@ import java.util.Arrays;
}
@Override
public int onLoadError(SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs,
IOException error) {
public @Loader.RetryAction int onLoadError(
SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
errorCount++;
boolean cancel = treatLoadErrorsAsEndOfStream && errorCount >= minLoadableRetryCount;
eventDispatcher.loadError(

View File

@ -409,8 +409,8 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
}
@Override
public int onLoadError(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs,
IOException error) {
public @Loader.RetryAction int onLoadError(
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
long bytesLoaded = loadable.bytesLoaded();
boolean isMediaChunk = isMediaChunk(loadable);
int lastChunkIndex = mediaChunks.size() - 1;

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.trackselection;
import android.content.Context;
import android.support.annotation.IntDef;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.google.android.exoplayer2.C;
@ -27,6 +28,8 @@ import com.google.android.exoplayer2.RendererConfiguration;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -81,22 +84,25 @@ public abstract class MappingTrackSelector extends TrackSelector {
*/
public static final class MappedTrackInfo {
/**
* The renderer does not have any associated tracks.
*/
/** Levels of renderer support. Higher numerical values indicate higher levels of support. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
RENDERER_SUPPORT_NO_TRACKS,
RENDERER_SUPPORT_UNSUPPORTED_TRACKS,
RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS,
RENDERER_SUPPORT_PLAYABLE_TRACKS
})
@interface RendererSupport {}
/** The renderer does not have any associated tracks. */
public static final int RENDERER_SUPPORT_NO_TRACKS = 0;
/**
* The renderer has associated tracks, but all are of unsupported types.
*/
/** The renderer has associated tracks, but all are of unsupported types. */
public static final int RENDERER_SUPPORT_UNSUPPORTED_TRACKS = 1;
/**
* The renderer has associated tracks and at least one is of a supported type, but all of the
* tracks whose types are supported exceed the renderer's capabilities.
*/
public static final int RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS = 2;
/**
* The renderer has associated tracks and can play at least one of them.
*/
/** The renderer has associated tracks and can play at least one of them. */
public static final int RENDERER_SUPPORT_PLAYABLE_TRACKS = 3;
/**
@ -145,11 +151,11 @@ public abstract class MappingTrackSelector extends TrackSelector {
* Returns the extent to which a renderer can play the tracks in the track groups mapped to it.
*
* @param rendererIndex The renderer index.
* @return One of {@link #RENDERER_SUPPORT_PLAYABLE_TRACKS},
* {@link #RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS},
* {@link #RENDERER_SUPPORT_UNSUPPORTED_TRACKS} and {@link #RENDERER_SUPPORT_NO_TRACKS}.
* @return One of {@link #RENDERER_SUPPORT_PLAYABLE_TRACKS}, {@link
* #RENDERER_SUPPORT_EXCEEDS_CAPABILITIES_TRACKS}, {@link
* #RENDERER_SUPPORT_UNSUPPORTED_TRACKS} and {@link #RENDERER_SUPPORT_NO_TRACKS}.
*/
public int getRendererSupport(int rendererIndex) {
public @RendererSupport int getRendererSupport(int rendererIndex) {
int bestRendererSupport = RENDERER_SUPPORT_NO_TRACKS;
int[][] rendererFormatSupport = formatSupport[rendererIndex];
for (int i = 0; i < rendererFormatSupport.length; i++) {

View File

@ -20,12 +20,15 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.ExecutorService;
/**
@ -104,20 +107,20 @@ public final class Loader implements LoaderErrorThrower {
/**
* Called when a load encounters an error.
* <p>
* Note: There is guaranteed to be a memory barrier between {@link Loadable#load()} exiting and
* this callback being called.
*
* <p>Note: There is guaranteed to be a memory barrier between {@link Loadable#load()} exiting
* and this callback being called.
*
* @param loadable The loadable whose load has encountered an error.
* @param elapsedRealtimeMs {@link SystemClock#elapsedRealtime} when the error occurred.
* @param loadDurationMs The duration of the load up to the point at which the error occurred.
* @param error The load error.
* @return The desired retry action. One of {@link Loader#RETRY},
* {@link Loader#RETRY_RESET_ERROR_COUNT}, {@link Loader#DONT_RETRY} and
* {@link Loader#DONT_RETRY_FATAL}.
* @return The desired retry action. One of {@link Loader#RETRY}, {@link
* Loader#RETRY_RESET_ERROR_COUNT}, {@link Loader#DONT_RETRY} and {@link
* Loader#DONT_RETRY_FATAL}.
*/
@RetryAction
int onLoadError(T loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error);
}
/**
@ -132,6 +135,11 @@ public final class Loader implements LoaderErrorThrower {
}
/** Actions that can be taken in response to a load error. */
@Retention(RetentionPolicy.SOURCE)
@IntDef({RETRY, RETRY_RESET_ERROR_COUNT, DONT_RETRY, DONT_RETRY_FATAL})
public @interface RetryAction {}
public static final int RETRY = 0;
public static final int RETRY_RESET_ERROR_COUNT = 1;
public static final int DONT_RETRY = 2;

View File

@ -375,7 +375,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// We only need to update the codec if the surface has changed.
if (this.surface != surface) {
this.surface = surface;
int state = getState();
@State int state = getState();
if (state == STATE_ENABLED || state == STATE_STARTED) {
MediaCodec codec = getCodec();
if (Util.SDK_INT >= 23 && codec != null && surface != null

View File

@ -174,22 +174,22 @@ public class DefaultEbmlReaderTest {
private final List<String> events = new ArrayList<>();
@Override
public int getElementType(int id) {
public @ElementType int getElementType(int id) {
switch (id) {
case ID_EBML:
case ID_SEGMENT:
return EbmlReader.TYPE_MASTER;
return TYPE_MASTER;
case ID_EBML_READ_VERSION:
case ID_DOC_TYPE_READ_VERSION:
return EbmlReader.TYPE_UNSIGNED_INT;
return TYPE_UNSIGNED_INT;
case ID_DOC_TYPE:
return EbmlReader.TYPE_STRING;
return TYPE_STRING;
case ID_SIMPLE_BLOCK:
return EbmlReader.TYPE_BINARY;
return TYPE_BINARY;
case ID_DURATION:
return EbmlReader.TYPE_FLOAT;
return TYPE_FLOAT;
default:
return EbmlReader.TYPE_UNKNOWN;
return TYPE_UNKNOWN;
}
}

View File

@ -692,8 +692,12 @@ public final class DashMediaSource extends BaseMediaSource {
}
}
/* package */ int onManifestLoadError(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs, IOException error) {
/* package */ @Loader.RetryAction
int onManifestLoadError(
ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
boolean isFatal = error instanceof ParserException;
manifestEventDispatcher.loadError(
loadable.dataSpec,
@ -717,8 +721,12 @@ public final class DashMediaSource extends BaseMediaSource {
onUtcTimestampResolved(loadable.getResult() - elapsedRealtimeMs);
}
/* package */ int onUtcTimestampLoadError(ParsingLoadable<Long> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
/* package */ @Loader.RetryAction
int onUtcTimestampLoadError(
ParsingLoadable<Long> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
manifestEventDispatcher.loadError(
loadable.dataSpec,
loadable.type,
@ -1114,8 +1122,11 @@ public final class DashMediaSource extends BaseMediaSource {
}
@Override
public int onLoadError(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
return onManifestLoadError(loadable, elapsedRealtimeMs, loadDurationMs, error);
}
@ -1136,8 +1147,11 @@ public final class DashMediaSource extends BaseMediaSource {
}
@Override
public int onLoadError(ParsingLoadable<Long> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ParsingLoadable<Long> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
return onUtcTimestampLoadError(loadable, elapsedRealtimeMs, loadDurationMs, error);
}

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.hls;
import android.os.Handler;
import android.support.annotation.IntDef;
import android.util.Log;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
@ -43,6 +44,8 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
@ -73,6 +76,10 @@ import java.util.Arrays;
private static final String TAG = "HlsSampleStreamWrapper";
@Retention(RetentionPolicy.SOURCE)
@IntDef({PRIMARY_TYPE_NONE, PRIMARY_TYPE_TEXT, PRIMARY_TYPE_AUDIO, PRIMARY_TYPE_VIDEO})
private @interface PrimaryTrackType {}
private static final int PRIMARY_TYPE_NONE = 0;
private static final int PRIMARY_TYPE_TEXT = 1;
private static final int PRIMARY_TYPE_AUDIO = 2;
@ -583,8 +590,8 @@ import java.util.Arrays;
}
@Override
public int onLoadError(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs,
IOException error) {
public @Loader.RetryAction int onLoadError(
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, IOException error) {
long bytesLoaded = loadable.bytesLoaded();
boolean isMediaChunk = isMediaChunk(loadable);
boolean cancelable = !isMediaChunk || bytesLoaded == 0;
@ -826,12 +833,12 @@ import java.util.Arrays;
private void buildTracks() {
// Iterate through the extractor tracks to discover the "primary" track type, and the index
// of the single track of this type.
int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
@PrimaryTrackType int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
int primaryExtractorTrackIndex = C.INDEX_UNSET;
int extractorTrackCount = sampleQueues.length;
for (int i = 0; i < extractorTrackCount; i++) {
String sampleMimeType = sampleQueues[i].getUpstreamFormat().sampleMimeType;
int trackType;
@PrimaryTrackType int trackType;
if (MimeTypes.isVideo(sampleMimeType)) {
trackType = PRIMARY_TYPE_VIDEO;
} else if (MimeTypes.isAudio(sampleMimeType)) {

View File

@ -320,8 +320,11 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
}
@Override
public int onLoadError(ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ParsingLoadable<HlsPlaylist> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError(loadable.dataSpec, C.DATA_TYPE_MANIFEST, elapsedRealtimeMs,
loadDurationMs, loadable.bytesLoaded(), error, isFatal);
@ -554,8 +557,11 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
}
@Override
public int onLoadError(ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ParsingLoadable<HlsPlaylist> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError(loadable.dataSpec, C.DATA_TYPE_MANIFEST, elapsedRealtimeMs,
loadDurationMs, loadable.bytesLoaded(), error, isFatal);

View File

@ -518,8 +518,11 @@ public final class SsMediaSource extends BaseMediaSource
}
@Override
public int onLoadError(ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) {
public @Loader.RetryAction int onLoadError(
ParsingLoadable<SsManifest> loadable,
long elapsedRealtimeMs,
long loadDurationMs,
IOException error) {
boolean isFatal = error instanceof ParserException;
manifestEventDispatcher.loadError(
loadable.dataSpec,