Use @IntDef where possible.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=133932812
This commit is contained in:
andrewlewis 2016-09-22 02:53:01 -07:00 committed by Oliver Woodman
parent e20d7034c7
commit 1546da899b
46 changed files with 459 additions and 212 deletions

View File

@ -316,15 +316,15 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension
: uri.getLastPathSegment()); : uri.getLastPathSegment());
switch (type) { switch (type) {
case Util.TYPE_SS: case C.TYPE_SS:
return new SsMediaSource(uri, buildDataSourceFactory(false), return new SsMediaSource(uri, buildDataSourceFactory(false),
new DefaultSsChunkSource.Factory(mediaDataSourceFactory), mainHandler, eventLogger); new DefaultSsChunkSource.Factory(mediaDataSourceFactory), mainHandler, eventLogger);
case Util.TYPE_DASH: case C.TYPE_DASH:
return new DashMediaSource(uri, buildDataSourceFactory(false), return new DashMediaSource(uri, buildDataSourceFactory(false),
new DefaultDashChunkSource.Factory(mediaDataSourceFactory), mainHandler, eventLogger); new DefaultDashChunkSource.Factory(mediaDataSourceFactory), mainHandler, eventLogger);
case Util.TYPE_HLS: case C.TYPE_HLS:
return new HlsMediaSource(uri, mediaDataSourceFactory, mainHandler, eventLogger); return new HlsMediaSource(uri, mediaDataSourceFactory, mainHandler, eventLogger);
case Util.TYPE_OTHER: case C.TYPE_OTHER:
return new ExtractorMediaSource(uri, mediaDataSourceFactory, new DefaultExtractorsFactory(), return new ExtractorMediaSource(uri, mediaDataSourceFactory, new DefaultExtractorsFactory(),
mainHandler, eventLogger); mainHandler, eventLogger);
default: { default: {

View File

@ -55,6 +55,7 @@ dependencies {
androidTestCompile 'com.google.dexmaker:dexmaker:1.2' androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2' androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'org.mockito:mockito-core:1.9.5' androidTestCompile 'org.mockito:mockito-core:1.9.5'
compile 'com.android.support:support-annotations:24.2.0'
} }
android.libraryVariants.all { variant -> android.libraryVariants.all { variant ->

View File

@ -17,8 +17,11 @@ package com.google.android.exoplayer2;
import android.media.AudioFormat; import android.media.AudioFormat;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.support.annotation.IntDef;
import android.view.Surface; import android.view.Surface;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.UUID; import java.util.UUID;
/** /**
@ -70,55 +73,79 @@ public final class C {
*/ */
public static final String UTF8_NAME = "UTF-8"; public static final String UTF8_NAME = "UTF-8";
/**
* Crypto modes for a codec.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({CRYPTO_MODE_UNENCRYPTED, CRYPTO_MODE_AES_CTR, CRYPTO_MODE_AES_CBC})
public @interface CryptoMode {}
/**
* @see MediaCodec#CRYPTO_MODE_UNENCRYPTED
*/
@SuppressWarnings("InlinedApi")
public static final int CRYPTO_MODE_UNENCRYPTED = MediaCodec.CRYPTO_MODE_UNENCRYPTED;
/** /**
* @see MediaCodec#CRYPTO_MODE_AES_CTR * @see MediaCodec#CRYPTO_MODE_AES_CTR
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static final int CRYPTO_MODE_AES_CTR = MediaCodec.CRYPTO_MODE_AES_CTR; public static final int CRYPTO_MODE_AES_CTR = MediaCodec.CRYPTO_MODE_AES_CTR;
/**
* @see MediaCodec#CRYPTO_MODE_AES_CBC
*/
@SuppressWarnings("InlinedApi")
public static final int CRYPTO_MODE_AES_CBC = MediaCodec.CRYPTO_MODE_AES_CBC;
/**
* Represents an audio encoding, or an invalid or unset value.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, ENCODING_INVALID, ENCODING_PCM_8BIT, ENCODING_PCM_16BIT,
ENCODING_PCM_24BIT, ENCODING_PCM_32BIT, ENCODING_AC3, ENCODING_E_AC3, ENCODING_DTS,
ENCODING_DTS_HD})
public @interface Encoding {}
/**
* Represents a PCM audio encoding, or an invalid or unset value.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, ENCODING_INVALID, ENCODING_PCM_8BIT, ENCODING_PCM_16BIT,
ENCODING_PCM_24BIT, ENCODING_PCM_32BIT})
public @interface PcmEncoding {}
/** /**
* @see AudioFormat#ENCODING_INVALID * @see AudioFormat#ENCODING_INVALID
*/ */
public static final int ENCODING_INVALID = AudioFormat.ENCODING_INVALID; public static final int ENCODING_INVALID = AudioFormat.ENCODING_INVALID;
/** /**
* @see AudioFormat#ENCODING_PCM_8BIT * @see AudioFormat#ENCODING_PCM_8BIT
*/ */
public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT; public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT;
/** /**
* @see AudioFormat#ENCODING_PCM_16BIT * @see AudioFormat#ENCODING_PCM_16BIT
*/ */
public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT; public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT;
/** /**
* PCM encoding with 24 bits per sample. * PCM encoding with 24 bits per sample.
*/ */
public static final int ENCODING_PCM_24BIT = 0x80000000; public static final int ENCODING_PCM_24BIT = 0x80000000;
/** /**
* PCM encoding with 32 bits per sample. * PCM encoding with 32 bits per sample.
*/ */
public static final int ENCODING_PCM_32BIT = 0x40000000; public static final int ENCODING_PCM_32BIT = 0x40000000;
/** /**
* @see AudioFormat#ENCODING_AC3 * @see AudioFormat#ENCODING_AC3
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3; public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
/** /**
* @see AudioFormat#ENCODING_E_AC3 * @see AudioFormat#ENCODING_E_AC3
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static final int ENCODING_E_AC3 = AudioFormat.ENCODING_E_AC3; public static final int ENCODING_E_AC3 = AudioFormat.ENCODING_E_AC3;
/** /**
* @see AudioFormat#ENCODING_DTS * @see AudioFormat#ENCODING_DTS
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static final int ENCODING_DTS = AudioFormat.ENCODING_DTS; public static final int ENCODING_DTS = AudioFormat.ENCODING_DTS;
/** /**
* @see AudioFormat#ENCODING_DTS_HD * @see AudioFormat#ENCODING_DTS_HD
*/ */
@ -132,48 +159,93 @@ public final class C {
public static final int CHANNEL_OUT_7POINT1_SURROUND = Util.SDK_INT < 23 public static final int CHANNEL_OUT_7POINT1_SURROUND = Util.SDK_INT < 23
? AudioFormat.CHANNEL_OUT_7POINT1 : AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; ? AudioFormat.CHANNEL_OUT_7POINT1 : AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
/**
* Flags which can apply to a buffer containing a media sample.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {BUFFER_FLAG_KEY_FRAME, BUFFER_FLAG_END_OF_STREAM,
BUFFER_FLAG_ENCRYPTED, BUFFER_FLAG_DECODE_ONLY})
public @interface BufferFlags {}
/** /**
* Indicates that a buffer holds a synchronization sample. * Indicates that a buffer holds a synchronization sample.
*/ */
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public static final int BUFFER_FLAG_KEY_FRAME = 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 BUFFER_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 buffer is (at least partially) encrypted. * Indicates that a buffer is (at least partially) encrypted.
*/ */
public static final int BUFFER_FLAG_ENCRYPTED = 0x40000000; public static final int BUFFER_FLAG_ENCRYPTED = 0x40000000;
/** /**
* Indicates that a buffer should be decoded but not rendered. * Indicates that a buffer should be decoded but not rendered.
*/ */
public static final int BUFFER_FLAG_DECODE_ONLY = 0x80000000; public static final int BUFFER_FLAG_DECODE_ONLY = 0x80000000;
/**
* Track selection flags.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {SELECTION_FLAG_DEFAULT, SELECTION_FLAG_FORCED,
SELECTION_FLAG_AUTOSELECT})
public @interface SelectionFlags {}
/**
* Indicates that the track should be selected if user preferences do not state otherwise.
*/
public static final int SELECTION_FLAG_DEFAULT = 1;
/**
* Indicates that the track must be displayed. Only applies to text tracks.
*/
public static final int SELECTION_FLAG_FORCED = 2;
/**
* Indicates that the player may choose to play the track in absence of an explicit user
* preference.
*/
public static final int SELECTION_FLAG_AUTOSELECT = 4;
/**
* Represents a streaming or other media type.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_DASH, TYPE_SS, TYPE_HLS, TYPE_OTHER})
public @interface ContentType {}
/**
* Value returned by {@link Util#inferContentType(String)} for DASH manifests.
*/
public static final int TYPE_DASH = 0;
/**
* Value returned by {@link Util#inferContentType(String)} for Smooth Streaming manifests.
*/
public static final int TYPE_SS = 1;
/**
* Value returned by {@link Util#inferContentType(String)} for HLS manifests.
*/
public static final int TYPE_HLS = 2;
/**
* Value returned by {@link Util#inferContentType(String)} for files other than DASH, HLS or
* Smooth Streaming manifests.
*/
public static final int TYPE_OTHER = 3;
/** /**
* 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.
*/ */
public static final int RESULT_END_OF_INPUT = -1; public static final int RESULT_END_OF_INPUT = -1;
/** /**
* A return value for methods where the length of parsed data exceeds the maximum length allowed. * A return value for methods where the length of parsed data exceeds the maximum length allowed.
*/ */
public static final int RESULT_MAX_LENGTH_EXCEEDED = -2; public static final int RESULT_MAX_LENGTH_EXCEEDED = -2;
/** /**
* A return value for methods where nothing was read. * A return value for methods where nothing was read.
*/ */
public static final int RESULT_NOTHING_READ = -3; public static final int RESULT_NOTHING_READ = -3;
/** /**
* A return value for methods where a buffer was read. * A return value for methods where a buffer was read.
*/ */
public static final int RESULT_BUFFER_READ = -4; public static final int RESULT_BUFFER_READ = -4;
/** /**
* A return value for methods where a format was read. * A return value for methods where a format was read.
*/ */
@ -183,32 +255,26 @@ public final class C {
* A data type constant for data of unknown or unspecified type. * A data type constant for data of unknown or unspecified type.
*/ */
public static final int DATA_TYPE_UNKNOWN = 0; public static final int DATA_TYPE_UNKNOWN = 0;
/** /**
* A data type constant for media, typically containing media samples. * A data type constant for media, typically containing media samples.
*/ */
public static final int DATA_TYPE_MEDIA = 1; public static final int DATA_TYPE_MEDIA = 1;
/** /**
* A data type constant for media, typically containing only initialization data. * A data type constant for media, typically containing only initialization data.
*/ */
public static final int DATA_TYPE_MEDIA_INITIALIZATION = 2; public static final int DATA_TYPE_MEDIA_INITIALIZATION = 2;
/** /**
* A data type constant for drm or encryption data. * A data type constant for drm or encryption data.
*/ */
public static final int DATA_TYPE_DRM = 3; public static final int DATA_TYPE_DRM = 3;
/** /**
* A data type constant for a manifest file. * A data type constant for a manifest file.
*/ */
public static final int DATA_TYPE_MANIFEST = 4; public static final int DATA_TYPE_MANIFEST = 4;
/** /**
* A data type constant for time synchronization data. * A data type constant for time synchronization data.
*/ */
public static final int DATA_TYPE_TIME_SYNCHRONIZATION = 5; public static final int DATA_TYPE_TIME_SYNCHRONIZATION = 5;
/** /**
* Applications or extensions may define custom {@code DATA_TYPE_*} constants greater than or * Applications or extensions may define custom {@code DATA_TYPE_*} constants greater than or
* equal to this value. * equal to this value.
@ -219,32 +285,26 @@ public final class C {
* A type constant for tracks of unknown type. * A type constant for tracks of unknown type.
*/ */
public static final int TRACK_TYPE_UNKNOWN = -1; public static final int TRACK_TYPE_UNKNOWN = -1;
/** /**
* A type constant for tracks of some default type, where the type itself is unknown. * A type constant for tracks of some default type, where the type itself is unknown.
*/ */
public static final int TRACK_TYPE_DEFAULT = 0; public static final int TRACK_TYPE_DEFAULT = 0;
/** /**
* A type constant for audio tracks. * A type constant for audio tracks.
*/ */
public static final int TRACK_TYPE_AUDIO = 1; public static final int TRACK_TYPE_AUDIO = 1;
/** /**
* A type constant for video tracks. * A type constant for video tracks.
*/ */
public static final int TRACK_TYPE_VIDEO = 2; public static final int TRACK_TYPE_VIDEO = 2;
/** /**
* A type constant for text tracks. * A type constant for text tracks.
*/ */
public static final int TRACK_TYPE_TEXT = 3; public static final int TRACK_TYPE_TEXT = 3;
/** /**
* A type constant for metadata tracks. * A type constant for metadata tracks.
*/ */
public static final int TRACK_TYPE_METADATA = 4; public static final int TRACK_TYPE_METADATA = 4;
/** /**
* Applications or extensions may define custom {@code TRACK_TYPE_*} constants greater than or * Applications or extensions may define custom {@code TRACK_TYPE_*} constants greater than or
* equal to this value. * equal to this value.
@ -255,27 +315,22 @@ public final class C {
* A selection reason constant for selections whose reasons are unknown or unspecified. * A selection reason constant for selections whose reasons are unknown or unspecified.
*/ */
public static final int SELECTION_REASON_UNKNOWN = 0; public static final int SELECTION_REASON_UNKNOWN = 0;
/** /**
* A selection reason constant for an initial track selection. * A selection reason constant for an initial track selection.
*/ */
public static final int SELECTION_REASON_INITIAL = 1; public static final int SELECTION_REASON_INITIAL = 1;
/** /**
* A selection reason constant for an manual (i.e. user initiated) track selection. * A selection reason constant for an manual (i.e. user initiated) track selection.
*/ */
public static final int SELECTION_REASON_MANUAL = 2; public static final int SELECTION_REASON_MANUAL = 2;
/** /**
* A selection reason constant for an adaptive track selection. * A selection reason constant for an adaptive track selection.
*/ */
public static final int SELECTION_REASON_ADAPTIVE = 3; public static final int SELECTION_REASON_ADAPTIVE = 3;
/** /**
* A selection reason constant for a trick play track selection. * A selection reason constant for a trick play track selection.
*/ */
public static final int SELECTION_REASON_TRICK_PLAY = 4; public static final int SELECTION_REASON_TRICK_PLAY = 4;
/** /**
* Applications or extensions may define custom {@code SELECTION_REASON_*} constants greater than * Applications or extensions may define custom {@code SELECTION_REASON_*} constants greater than
* or equal to this value. * or equal to this value.
@ -363,16 +418,20 @@ public final class C {
*/ */
public static final int MSG_CUSTOM_BASE = 10000; public static final int MSG_CUSTOM_BASE = 10000;
/**
* The stereo mode for 360/3D/VR videos.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, STEREO_MODE_MONO, STEREO_MODE_TOP_BOTTOM, STEREO_MODE_LEFT_RIGHT})
public @interface StereoMode {}
/** /**
* Indicates Monoscopic stereo layout, used with 360/3D/VR videos. * Indicates Monoscopic stereo layout, used with 360/3D/VR videos.
*/ */
public static final int STEREO_MODE_MONO = 0; public static final int STEREO_MODE_MONO = 0;
/** /**
* Indicates Top-Bottom stereo layout, used with 360/3D/VR videos. * Indicates Top-Bottom stereo layout, used with 360/3D/VR videos.
*/ */
public static final int STEREO_MODE_TOP_BOTTOM = 1; public static final int STEREO_MODE_TOP_BOTTOM = 1;
/** /**
* Indicates Left-Right stereo layout, used with 360/3D/VR videos. * Indicates Left-Right stereo layout, used with 360/3D/VR videos.
*/ */

View File

@ -15,15 +15,24 @@
*/ */
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Thrown when a non-recoverable playback failure occurs. * Thrown when a non-recoverable playback failure occurs.
*/ */
public final class ExoPlaybackException extends Exception { public final class ExoPlaybackException extends Exception {
/**
* The type of source that produced the error.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED})
public @interface Type {}
/** /**
* The error occurred loading data from a {@link MediaSource}. * The error occurred loading data from a {@link MediaSource}.
* <p> * <p>
@ -47,6 +56,7 @@ public final class ExoPlaybackException extends Exception {
* The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER} and * The type of the playback failure. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER} and
* {@link #TYPE_UNEXPECTED}. * {@link #TYPE_UNEXPECTED}.
*/ */
@Type
public final int type; public final int type;
/** /**
@ -85,7 +95,8 @@ public final class ExoPlaybackException extends Exception {
return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET); return new ExoPlaybackException(TYPE_UNEXPECTED, null, cause, C.INDEX_UNSET);
} }
private ExoPlaybackException(int type, String message, Throwable cause, int rendererIndex) { private ExoPlaybackException(@Type int type, String message, Throwable cause,
int rendererIndex) {
super(message, cause); super(message, cause);
this.type = type; this.type = type;
this.rendererIndex = rendererIndex; this.rendererIndex = rendererIndex;

View File

@ -39,20 +39,6 @@ public final class Format implements Parcelable {
*/ */
public static final int NO_VALUE = -1; public static final int NO_VALUE = -1;
/**
* Indicates that the track should be selected if user preferences do not state otherwise.
*/
public static final int SELECTION_FLAG_DEFAULT = 1;
/**
* Indicates that the track must be displayed. Only applies to text tracks.
*/
public static final int SELECTION_FLAG_FORCED = 2;
/**
* Indicates that the player may choose to play the track in absence of an explicit user
* preference.
*/
public static final int SELECTION_FLAG_AUTOSELECT = 4;
/** /**
* A value for {@link #subsampleOffsetUs} to indicate that subsample timestamps are relative to * A value for {@link #subsampleOffsetUs} to indicate that subsample timestamps are relative to
* the timestamps of their parent samples. * the timestamps of their parent samples.
@ -131,6 +117,7 @@ public final class Format implements Parcelable {
* modes are {@link C#STEREO_MODE_MONO}, {@link C#STEREO_MODE_TOP_BOTTOM}, {@link * modes are {@link C#STEREO_MODE_MONO}, {@link C#STEREO_MODE_TOP_BOTTOM}, {@link
* C#STEREO_MODE_LEFT_RIGHT}. * C#STEREO_MODE_LEFT_RIGHT}.
*/ */
@C.StereoMode
public final int stereoMode; public final int stereoMode;
/** /**
* The projection data for 360/VR video, or null if not applicable. * The projection data for 360/VR video, or null if not applicable.
@ -153,6 +140,7 @@ public final class Format implements Parcelable {
* {@link C#ENCODING_PCM_24BIT} and {@link C#ENCODING_PCM_32BIT}. Set to {@link #NO_VALUE} for * {@link C#ENCODING_PCM_24BIT} and {@link C#ENCODING_PCM_32BIT}. Set to {@link #NO_VALUE} for
* other media types. * other media types.
*/ */
@C.PcmEncoding
public final int pcmEncoding; public final int pcmEncoding;
/** /**
* The number of samples to trim from the start of the decoded audio stream. * The number of samples to trim from the start of the decoded audio stream.
@ -177,6 +165,7 @@ public final class Format implements Parcelable {
/** /**
* Track selection flags. * Track selection flags.
*/ */
@C.SelectionFlags
public final int selectionFlags; public final int selectionFlags;
/** /**
@ -218,7 +207,7 @@ public final class Format implements Parcelable {
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs, public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int width, int height, float frameRate, int bitrate, int maxInputSize, int width, int height, float frameRate,
List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio, List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio,
byte[] projectionData, int stereoMode, DrmInitData drmInitData) { byte[] projectionData, @C.StereoMode int stereoMode, DrmInitData drmInitData) {
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height, return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height,
frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, NO_VALUE, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, initializationData, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, OFFSET_SAMPLE_RELATIVE, initializationData,
@ -229,7 +218,7 @@ public final class Format implements Parcelable {
public static Format createAudioContainerFormat(String id, String containerMimeType, public static Format createAudioContainerFormat(String id, String containerMimeType,
String sampleMimeType, String codecs, int bitrate, int channelCount, int sampleRate, String sampleMimeType, String codecs, int bitrate, int channelCount, int sampleRate,
List<byte[]> initializationData, int selectionFlags, String language) { List<byte[]> initializationData, @C.SelectionFlags int selectionFlags, String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, NO_VALUE,
NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, initializationData, NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, initializationData,
@ -238,25 +227,26 @@ public final class Format implements Parcelable {
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs, public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int channelCount, int sampleRate, int bitrate, int maxInputSize, int channelCount, int sampleRate,
List<byte[]> initializationData, DrmInitData drmInitData, int selectionFlags, List<byte[]> initializationData, DrmInitData drmInitData,
String language) { @C.SelectionFlags int selectionFlags, String language) {
return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount, return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount,
sampleRate, NO_VALUE, initializationData, drmInitData, selectionFlags, language); sampleRate, NO_VALUE, initializationData, drmInitData, selectionFlags, language);
} }
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs, public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int channelCount, int sampleRate, int pcmEncoding, int bitrate, int maxInputSize, int channelCount, int sampleRate,
List<byte[]> initializationData, DrmInitData drmInitData, int selectionFlags, @C.PcmEncoding int pcmEncoding, List<byte[]> initializationData, DrmInitData drmInitData,
String language) { @C.SelectionFlags int selectionFlags, String language) {
return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount, return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount,
sampleRate, pcmEncoding, NO_VALUE, NO_VALUE, initializationData, drmInitData, sampleRate, pcmEncoding, NO_VALUE, NO_VALUE, initializationData, drmInitData,
selectionFlags, language); selectionFlags, language);
} }
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs, public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int channelCount, int sampleRate, int pcmEncoding, int bitrate, int maxInputSize, int channelCount, int sampleRate,
int encoderDelay, int encoderPadding, List<byte[]> initializationData, @C.PcmEncoding int pcmEncoding, int encoderDelay, int encoderPadding,
DrmInitData drmInitData, int selectionFlags, String language) { List<byte[]> initializationData, DrmInitData drmInitData,
@C.SelectionFlags int selectionFlags, String language) {
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, pcmEncoding, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, channelCount, sampleRate, pcmEncoding,
encoderDelay, encoderPadding, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, encoderDelay, encoderPadding, selectionFlags, language, OFFSET_SAMPLE_RELATIVE,
@ -266,20 +256,21 @@ public final class Format implements Parcelable {
// Text. // Text.
public static Format createTextContainerFormat(String id, String containerMimeType, public static Format createTextContainerFormat(String id, String containerMimeType,
String sampleMimeType, String codecs, int bitrate, int selectionFlags, String language) { String sampleMimeType, String codecs, int bitrate, @C.SelectionFlags int selectionFlags,
String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, null, null); NO_VALUE, NO_VALUE, selectionFlags, language, OFFSET_SAMPLE_RELATIVE, null, null);
} }
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs, public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int selectionFlags, String language, DrmInitData drmInitData) { int bitrate, @C.SelectionFlags int selectionFlags, String language, DrmInitData drmInitData) {
return createTextSampleFormat(id, sampleMimeType, codecs, bitrate, selectionFlags, language, return createTextSampleFormat(id, sampleMimeType, codecs, bitrate, selectionFlags, language,
drmInitData, OFFSET_SAMPLE_RELATIVE); drmInitData, OFFSET_SAMPLE_RELATIVE);
} }
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs, public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
int bitrate, int selectionFlags, String language, DrmInitData drmInitData, int bitrate, @C.SelectionFlags int selectionFlags, String language, DrmInitData drmInitData,
long subsampleOffsetUs) { long subsampleOffsetUs) {
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE, return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
@ -313,10 +304,10 @@ public final class Format implements Parcelable {
/* package */ Format(String id, String containerMimeType, String sampleMimeType, String codecs, /* package */ Format(String id, String containerMimeType, String sampleMimeType, String codecs,
int bitrate, int maxInputSize, int width, int height, float frameRate, int rotationDegrees, int bitrate, int maxInputSize, int width, int height, float frameRate, int rotationDegrees,
float pixelWidthHeightRatio, byte[] projectionData, int stereoMode, int channelCount, float pixelWidthHeightRatio, byte[] projectionData, @C.StereoMode int stereoMode,
int sampleRate, int pcmEncoding, int encoderDelay, int encoderPadding, int selectionFlags, int channelCount, int sampleRate, @C.PcmEncoding int pcmEncoding, int encoderDelay,
String language, long subsampleOffsetUs, List<byte[]> initializationData, int encoderPadding, @C.SelectionFlags int selectionFlags, String language,
DrmInitData drmInitData) { long subsampleOffsetUs, List<byte[]> initializationData, DrmInitData drmInitData) {
this.id = id; this.id = id;
this.containerMimeType = containerMimeType; this.containerMimeType = containerMimeType;
this.sampleMimeType = sampleMimeType; this.sampleMimeType = sampleMimeType;
@ -343,6 +334,7 @@ public final class Format implements Parcelable {
this.drmInitData = drmInitData; this.drmInitData = drmInitData;
} }
@SuppressWarnings("ResourceType")
/* package */ Format(Parcel in) { /* package */ Format(Parcel in) {
id = in.readString(); id = in.readString();
containerMimeType = in.readString(); containerMimeType = in.readString();
@ -389,7 +381,7 @@ public final class Format implements Parcelable {
} }
public Format copyWithContainerInfo(String id, int bitrate, int width, int height, public Format copyWithContainerInfo(String id, int bitrate, int width, int height,
int selectionFlags, String language) { @C.SelectionFlags int selectionFlags, String language) {
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize,
width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, width, height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData,
stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding, stereoMode, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
@ -402,7 +394,7 @@ public final class Format implements Parcelable {
String codecs = this.codecs == null ? manifestFormat.codecs : this.codecs; String codecs = this.codecs == null ? manifestFormat.codecs : this.codecs;
int bitrate = this.bitrate == NO_VALUE ? manifestFormat.bitrate : this.bitrate; int bitrate = this.bitrate == NO_VALUE ? manifestFormat.bitrate : this.bitrate;
float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate; float frameRate = this.frameRate == NO_VALUE ? manifestFormat.frameRate : this.frameRate;
int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags; @C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags;
String language = this.language == null ? manifestFormat.language : this.language; String language = this.language == null ? manifestFormat.language : this.language;
DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null) DrmInitData drmInitData = (preferManifestDrmInitData && manifestFormat.drmInitData != null)
|| this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData; || this.drmInitData == null ? manifestFormat.drmInitData : this.drmInitData;

View File

@ -208,7 +208,9 @@ public final class AudioTrack {
private android.media.AudioTrack audioTrack; private android.media.AudioTrack audioTrack;
private int sampleRate; private int sampleRate;
private int channelConfig; private int channelConfig;
@C.Encoding
private int sourceEncoding; private int sourceEncoding;
@C.Encoding
private int targetEncoding; private int targetEncoding;
private boolean passthrough; private boolean passthrough;
private int pcmFrameSize; private int pcmFrameSize;
@ -348,8 +350,8 @@ public final class AudioTrack {
* @param specifiedBufferSize A specific size for the playback buffer in bytes, or 0 to infer a * @param specifiedBufferSize A specific size for the playback buffer in bytes, or 0 to infer a
* suitable buffer size automatically. * suitable buffer size automatically.
*/ */
public void configure(String mimeType, int channelCount, int sampleRate, int pcmEncoding, public void configure(String mimeType, int channelCount, int sampleRate,
int specifiedBufferSize) { @C.PcmEncoding int pcmEncoding, int specifiedBufferSize) {
int channelConfig; int channelConfig;
switch (channelCount) { switch (channelCount) {
case 1: case 1:
@ -381,7 +383,7 @@ public final class AudioTrack {
} }
boolean passthrough = !MimeTypes.AUDIO_RAW.equals(mimeType); boolean passthrough = !MimeTypes.AUDIO_RAW.equals(mimeType);
int sourceEncoding; @C.Encoding int sourceEncoding;
if (passthrough) { if (passthrough) {
sourceEncoding = getEncodingForMimeType(mimeType); sourceEncoding = getEncodingForMimeType(mimeType);
} else if (pcmEncoding == C.ENCODING_PCM_8BIT || pcmEncoding == C.ENCODING_PCM_16BIT } else if (pcmEncoding == C.ENCODING_PCM_8BIT || pcmEncoding == C.ENCODING_PCM_16BIT
@ -470,7 +472,7 @@ public final class AudioTrack {
if (keepSessionIdAudioTrack == null) { if (keepSessionIdAudioTrack == null) {
int sampleRate = 4000; // Equal to private android.media.AudioTrack.MIN_SAMPLE_RATE. int sampleRate = 4000; // Equal to private android.media.AudioTrack.MIN_SAMPLE_RATE.
int channelConfig = AudioFormat.CHANNEL_OUT_MONO; int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
int encoding = C.ENCODING_PCM_16BIT; @C.PcmEncoding int encoding = C.ENCODING_PCM_16BIT;
int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback. int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback.
keepSessionIdAudioTrack = new android.media.AudioTrack(streamType, sampleRate, keepSessionIdAudioTrack = new android.media.AudioTrack(streamType, sampleRate,
channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, sessionId); channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, sessionId);
@ -962,7 +964,7 @@ public final class AudioTrack {
* @return The 16-bit PCM output. Different to the out parameter if null was passed, or if the * @return The 16-bit PCM output. Different to the out parameter if null was passed, or if the
* capacity was insufficient for the output. * capacity was insufficient for the output.
*/ */
private static ByteBuffer resampleTo16BitPcm(ByteBuffer buffer, int sourceEncoding, private static ByteBuffer resampleTo16BitPcm(ByteBuffer buffer, @C.PcmEncoding int sourceEncoding,
ByteBuffer out) { ByteBuffer out) {
int offset = buffer.position(); int offset = buffer.position();
int limit = buffer.limit(); int limit = buffer.limit();
@ -1023,6 +1025,7 @@ public final class AudioTrack {
return resampledBuffer; return resampledBuffer;
} }
@C.Encoding
private static int getEncodingForMimeType(String mimeType) { private static int getEncodingForMimeType(String mimeType) {
switch (mimeType) { switch (mimeType) {
case MimeTypes.AUDIO_AC3: case MimeTypes.AUDIO_AC3:
@ -1038,7 +1041,7 @@ public final class AudioTrack {
} }
} }
private static int getFramesPerEncodedSample(int encoding, ByteBuffer buffer) { private static int getFramesPerEncodedSample(@C.Encoding int encoding, ByteBuffer buffer) {
if (encoding == C.ENCODING_DTS || encoding == C.ENCODING_DTS_HD) { if (encoding == C.ENCODING_DTS || encoding == C.ENCODING_DTS_HD) {
return DtsUtil.parseDtsAudioSampleCount(buffer); return DtsUtil.parseDtsAudioSampleCount(buffer);
} else if (encoding == C.ENCODING_AC3) { } else if (encoding == C.ENCODING_AC3) {

View File

@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C;
*/ */
public abstract class Buffer { public abstract class Buffer {
@C.BufferFlags
private int flags; private int flags;
/** /**
@ -58,7 +59,7 @@ public abstract class Buffer {
* @param flags The flags to set, which should be a combination of the {@code C.BUFFER_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(@C.BufferFlags int flags) {
this.flags = flags; this.flags = flags;
} }
@ -68,7 +69,7 @@ public abstract class Buffer {
* @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.BUFFER_FLAG_*} constants. * {@code C.BUFFER_FLAG_*} constants.
*/ */
public final void addFlag(int flag) { public final void addFlag(@C.BufferFlags int flag) {
flags |= flag; flags |= flag;
} }
@ -77,7 +78,7 @@ public abstract class Buffer {
* *
* @param flag The flag to remove. * @param flag The flag to remove.
*/ */
public final void clearFlag(int flag) { public final void clearFlag(@C.BufferFlags int flag) {
flags &= ~flag; flags &= ~flag;
} }
@ -87,7 +88,7 @@ public abstract class Buffer {
* @param flag The flag to check. * @param flag The flag to check.
* @return Whether the flag is set. * @return Whether the flag is set.
*/ */
protected final boolean getFlag(int flag) { protected final boolean getFlag(@C.BufferFlags int flag) {
return (flags & flag) == flag; return (flags & flag) == flag;
} }

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.decoder; package com.google.android.exoplayer2.decoder;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
/** /**
@ -34,6 +35,7 @@ public final class CryptoInfo {
/** /**
* @see android.media.MediaCodec.CryptoInfo#mode * @see android.media.MediaCodec.CryptoInfo#mode
*/ */
@C.CryptoMode
public int mode; public int mode;
/** /**
* @see android.media.MediaCodec.CryptoInfo#numBytesOfClearData * @see android.media.MediaCodec.CryptoInfo#numBytesOfClearData
@ -58,7 +60,7 @@ public final class CryptoInfo {
* @see android.media.MediaCodec.CryptoInfo#set(int, int[], int[], byte[], byte[], int) * @see android.media.MediaCodec.CryptoInfo#set(int, int[], int[], byte[], byte[], int)
*/ */
public void set(int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData, public void set(int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData,
byte[] key, byte[] iv, int mode) { byte[] key, byte[] iv, @C.CryptoMode int mode) {
this.numSubSamples = numSubSamples; this.numSubSamples = numSubSamples;
this.numBytesOfClearData = numBytesOfClearData; this.numBytesOfClearData = numBytesOfClearData;
this.numBytesOfEncryptedData = numBytesOfEncryptedData; this.numBytesOfEncryptedData = numBytesOfEncryptedData;

View File

@ -15,7 +15,10 @@
*/ */
package com.google.android.exoplayer2.decoder; package com.google.android.exoplayer2.decoder;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
/** /**
@ -23,16 +26,21 @@ import java.nio.ByteBuffer;
*/ */
public class DecoderInputBuffer extends Buffer { public class DecoderInputBuffer extends Buffer {
/**
* The buffer replacement mode, which may disable replacement.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({BUFFER_REPLACEMENT_MODE_DISABLED, BUFFER_REPLACEMENT_MODE_NORMAL,
BUFFER_REPLACEMENT_MODE_DIRECT})
public @interface BufferReplacementMode {}
/** /**
* Disallows buffer replacement. * Disallows buffer replacement.
*/ */
public static final int BUFFER_REPLACEMENT_MODE_DISABLED = 0; public static final int BUFFER_REPLACEMENT_MODE_DISABLED = 0;
/** /**
* Allows buffer replacement using {@link ByteBuffer#allocate(int)}. * Allows buffer replacement using {@link ByteBuffer#allocate(int)}.
*/ */
public static final int BUFFER_REPLACEMENT_MODE_NORMAL = 1; public static final int BUFFER_REPLACEMENT_MODE_NORMAL = 1;
/** /**
* Allows buffer replacement using {@link ByteBuffer#allocateDirect(int)}. * Allows buffer replacement using {@link ByteBuffer#allocateDirect(int)}.
*/ */
@ -53,6 +61,7 @@ public class DecoderInputBuffer extends Buffer {
*/ */
public long timeUs; public long timeUs;
@BufferReplacementMode
private final int bufferReplacementMode; private final int bufferReplacementMode;
/** /**
@ -60,7 +69,7 @@ public class DecoderInputBuffer 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 DecoderInputBuffer(int bufferReplacementMode) { public DecoderInputBuffer(@BufferReplacementMode int bufferReplacementMode) {
this.cryptoInfo = new CryptoInfo(); this.cryptoInfo = new CryptoInfo();
this.bufferReplacementMode = bufferReplacementMode; this.bufferReplacementMode = bufferReplacementMode;
} }

View File

@ -16,6 +16,9 @@
package com.google.android.exoplayer2.drm; package com.google.android.exoplayer2.drm;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* A DRM session. * A DRM session.
@ -23,6 +26,12 @@ import android.annotation.TargetApi;
@TargetApi(16) @TargetApi(16)
public interface DrmSession<T extends ExoMediaCrypto> { public interface DrmSession<T extends ExoMediaCrypto> {
/**
* The state of the DRM session.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({STATE_ERROR, STATE_CLOSED, STATE_OPENING, STATE_OPENED, STATE_OPENED_WITH_KEYS})
@interface State {}
/** /**
* The session has encountered an error. {@link #getError()} can be used to retrieve the cause. * The session has encountered an error. {@link #getError()} can be used to retrieve the cause.
*/ */
@ -50,6 +59,7 @@ public interface DrmSession<T extends ExoMediaCrypto> {
* @return One of {@link #STATE_ERROR}, {@link #STATE_CLOSED}, {@link #STATE_OPENING}, * @return One of {@link #STATE_ERROR}, {@link #STATE_CLOSED}, {@link #STATE_OPENING},
* {@link #STATE_OPENED} and {@link #STATE_OPENED_WITH_KEYS}. * {@link #STATE_OPENED} and {@link #STATE_OPENED_WITH_KEYS}.
*/ */
@State
int getState(); int getState();
/** /**

View File

@ -87,6 +87,7 @@ public class StreamingDrmSessionManager<T extends ExoMediaCrypto> implements Drm
private int openCount; private int openCount;
private boolean provisioningInProgress; private boolean provisioningInProgress;
@DrmSession.State
private int state; private int state;
private T mediaCrypto; private T mediaCrypto;
private Exception lastException; private Exception lastException;
@ -291,6 +292,7 @@ public class StreamingDrmSessionManager<T extends ExoMediaCrypto> implements Drm
// DrmSession implementation. // DrmSession implementation.
@Override @Override
@DrmSession.State
public final int getState() { public final int getState() {
return state; return state;
} }

View File

@ -15,11 +15,21 @@
*/ */
package com.google.android.exoplayer2.drm; package com.google.android.exoplayer2.drm;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Thrown when the requested DRM scheme is not supported. * Thrown when the requested DRM scheme is not supported.
*/ */
public final class UnsupportedDrmException extends Exception { public final class UnsupportedDrmException extends Exception {
/**
* The reason for the exception.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({REASON_UNSUPPORTED_SCHEME, REASON_INSTANTIATION_ERROR})
public @interface Reason {}
/** /**
* The requested DRM scheme is unsupported by the device. * The requested DRM scheme is unsupported by the device.
*/ */
@ -33,12 +43,13 @@ public final class UnsupportedDrmException extends Exception {
/** /**
* Either {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}. * Either {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}.
*/ */
@Reason
public final int reason; public final int reason;
/** /**
* @param reason {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}. * @param reason {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}.
*/ */
public UnsupportedDrmException(int reason) { public UnsupportedDrmException(@Reason int reason) {
this.reason = reason; this.reason = reason;
} }
@ -46,7 +57,7 @@ public final class UnsupportedDrmException extends Exception {
* @param reason {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}. * @param reason {@link #REASON_UNSUPPORTED_SCHEME} or {@link #REASON_INSTANTIATION_ERROR}.
* @param cause The cause of this exception. * @param cause The cause of this exception.
*/ */
public UnsupportedDrmException(int reason, Exception cause) { public UnsupportedDrmException(@Reason int reason, Exception cause) {
super(cause); super(cause);
this.reason = reason; this.reason = reason;
} }

View File

@ -496,7 +496,8 @@ public final class DefaultTrackOutput implements TrackOutput {
} }
@Override @Override
public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) {
if (!startWriteOperation()) { if (!startWriteOperation()) {
infoQueue.commitSampleTimestamp(timeUs); infoQueue.commitSampleTimestamp(timeUs);
return; return;
@ -836,8 +837,8 @@ public final class DefaultTrackOutput implements TrackOutput {
} }
} }
public synchronized void commitSample(long timeUs, int sampleFlags, long offset, int size, public synchronized void commitSample(long timeUs, @C.BufferFlags int sampleFlags, long offset,
byte[] encryptionKey) { int size, byte[] encryptionKey) {
Assertions.checkState(!upstreamFormatRequired); Assertions.checkState(!upstreamFormatRequired);
commitSampleTimestamp(timeUs); commitSampleTimestamp(timeUs);
timesUs[relativeWriteIndex] = timeUs; timesUs[relativeWriteIndex] = timeUs;

View File

@ -50,7 +50,8 @@ public final class DummyTrackOutput implements TrackOutput {
} }
@Override @Override
public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) {
// Do nothing. // Do nothing.
} }

View File

@ -72,6 +72,7 @@ public interface TrackOutput {
* whose metadata is being passed. * whose metadata is being passed.
* @param encryptionKey The encryption key associated with the sample. May be null. * @param encryptionKey The encryption key associated with the sample. May be null.
*/ */
void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey); void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey);
} }

View File

@ -264,6 +264,7 @@ public final class MatroskaExtractor implements Extractor {
private int[] blockLacingSampleSizes; private int[] blockLacingSampleSizes;
private int blockTrackNumber; private int blockTrackNumber;
private int blockTrackNumberLength; private int blockTrackNumberLength;
@C.BufferFlags
private int blockFlags; private int blockFlags;
// Sample reading state. // Sample reading state.
@ -1314,7 +1315,7 @@ public final class MatroskaExtractor implements Extractor {
public void initializeOutput(ExtractorOutput output, int trackId) throws ParserException { public void initializeOutput(ExtractorOutput output, int trackId) throws ParserException {
String mimeType; String mimeType;
int maxInputSize = Format.NO_VALUE; int maxInputSize = Format.NO_VALUE;
int pcmEncoding = Format.NO_VALUE; @C.PcmEncoding int pcmEncoding = Format.NO_VALUE;
List<byte[]> initializationData = null; List<byte[]> initializationData = null;
switch (codecId) { switch (codecId) {
case CODEC_ID_VP8: case CODEC_ID_VP8:
@ -1429,9 +1430,9 @@ public final class MatroskaExtractor implements Extractor {
} }
Format format; Format format;
int selectionFlags = 0; @C.SelectionFlags int selectionFlags = 0;
selectionFlags |= flagDefault ? Format.SELECTION_FLAG_DEFAULT : 0; selectionFlags |= flagDefault ? C.SELECTION_FLAG_DEFAULT : 0;
selectionFlags |= flagForced ? Format.SELECTION_FLAG_FORCED : 0; selectionFlags |= flagForced ? C.SELECTION_FLAG_FORCED : 0;
// TODO: Consider reading the name elements of the tracks and, if present, incorporating them // TODO: Consider reading the name elements of the tracks and, if present, incorporating them
// into the trackId passed when creating the formats. // into the trackId passed when creating the formats.
if (MimeTypes.isAudio(mimeType)) { if (MimeTypes.isAudio(mimeType)) {

View File

@ -665,6 +665,7 @@ import java.util.List;
List<byte[]> initializationData = null; List<byte[]> initializationData = null;
String mimeType = null; String mimeType = null;
byte[] projectionData = null; byte[] projectionData = null;
@C.StereoMode
int stereoMode = Format.NO_VALUE; int stereoMode = Format.NO_VALUE;
while (childPosition - position < size) { while (childPosition - position < size) {
parent.setPosition(childPosition); parent.setPosition(childPosition);
@ -889,7 +890,7 @@ import java.util.List;
if (out.format == null && mimeType != null) { if (out.format == null && mimeType != null) {
// TODO: Determine the correct PCM encoding. // TODO: Determine the correct PCM encoding.
int pcmEncoding = @C.PcmEncoding int pcmEncoding =
MimeTypes.AUDIO_RAW.equals(mimeType) ? C.ENCODING_PCM_16BIT : Format.NO_VALUE; MimeTypes.AUDIO_RAW.equals(mimeType) ? C.ENCODING_PCM_16BIT : Format.NO_VALUE;
out.format = Format.createAudioSampleFormat(Integer.toString(trackId), mimeType, null, out.format = Format.createAudioSampleFormat(Integer.toString(trackId), mimeType, null,
Format.NO_VALUE, Format.NO_VALUE, channelCount, sampleRate, pcmEncoding, Format.NO_VALUE, Format.NO_VALUE, channelCount, sampleRate, pcmEncoding,
@ -1169,6 +1170,7 @@ import java.util.List;
public Format format; public Format format;
public int nalUnitLengthFieldLength; public int nalUnitLengthFieldLength;
@Track.Transformation
public int requiredSampleTransformation; public int requiredSampleTransformation;
public StsdData(int numberOfEntries) { public StsdData(int numberOfEntries) {

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import android.support.annotation.IntDef;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
@ -38,6 +39,8 @@ import com.google.android.exoplayer2.util.NalUnitUtil;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -64,6 +67,13 @@ public final class FragmentedMp4Extractor implements Extractor {
private static final String TAG = "FragmentedMp4Extractor"; private static final String TAG = "FragmentedMp4Extractor";
private static final int SAMPLE_GROUP_TYPE_seig = Util.getIntegerCodeForString("seig"); private static final int SAMPLE_GROUP_TYPE_seig = Util.getIntegerCodeForString("seig");
/**
* Flags controlling the behavior of the extractor.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME,
FLAG_WORKAROUND_IGNORE_TFDT_BOX, FLAG_SIDELOADED})
public @interface Flags {}
/** /**
* Flag to work around an issue in some video streams where every frame is marked as a sync frame. * Flag to work around an issue in some video streams where every frame is marked as a sync frame.
* The workaround overrides the sync frame flags in the stream, forcing them to false except for * The workaround overrides the sync frame flags in the stream, forcing them to false except for
@ -72,12 +82,10 @@ public final class FragmentedMp4Extractor implements Extractor {
* This flag does nothing if the stream is not a video stream. * This flag does nothing if the stream is not a video stream.
*/ */
public static final int FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME = 1; public static final int FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME = 1;
/** /**
* Flag to ignore any tfdt boxes in the stream. * Flag to ignore any tfdt boxes in the stream.
*/ */
public static final int FLAG_WORKAROUND_IGNORE_TFDT_BOX = 2; public static final int FLAG_WORKAROUND_IGNORE_TFDT_BOX = 2;
/** /**
* Flag to indicate that the {@link Track} was sideloaded, instead of being declared by the MP4 * Flag to indicate that the {@link Track} was sideloaded, instead of being declared by the MP4
* container. * container.
@ -95,6 +103,7 @@ public final class FragmentedMp4Extractor implements Extractor {
private static final int STATE_READING_SAMPLE_CONTINUE = 4; private static final int STATE_READING_SAMPLE_CONTINUE = 4;
// Workarounds. // Workarounds.
@Flags
private final int flags; private final int flags;
private final Track sideloadedTrack; private final Track sideloadedTrack;
@ -135,18 +144,18 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
/** /**
* @param flags Flags to allow parsing of faulty streams. * @param flags Flags that control the extractor's behavior.
*/ */
public FragmentedMp4Extractor(int flags) { public FragmentedMp4Extractor(@Flags int flags) {
this(flags, null); this(flags, null);
} }
/** /**
* @param flags Flags to allow parsing of faulty streams. * @param flags Flags that control the extractor's behavior.
* @param sideloadedTrack Sideloaded track information, in the case that the extractor * @param sideloadedTrack Sideloaded track information, in the case that the extractor
* will not receive a moov box in the input data. * will not receive a moov box in the input data.
*/ */
public FragmentedMp4Extractor(int flags, Track sideloadedTrack) { public FragmentedMp4Extractor(@Flags int flags, Track sideloadedTrack) {
this.sideloadedTrack = sideloadedTrack; this.sideloadedTrack = sideloadedTrack;
this.flags = flags | (sideloadedTrack != null ? FLAG_SIDELOADED : 0); this.flags = flags | (sideloadedTrack != null ? FLAG_SIDELOADED : 0);
atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE); atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
@ -422,7 +431,7 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray, private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
int flags, byte[] extendedTypeScratch) throws ParserException { @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
int moofContainerChildrenSize = moof.containerChildren.size(); int moofContainerChildrenSize = moof.containerChildren.size();
for (int i = 0; i < moofContainerChildrenSize; i++) { for (int i = 0; i < moofContainerChildrenSize; i++) {
Atom.ContainerAtom child = moof.containerChildren.get(i); Atom.ContainerAtom child = moof.containerChildren.get(i);
@ -437,7 +446,7 @@ public final class FragmentedMp4Extractor implements Extractor {
* Parses a traf atom (defined in 14496-12). * Parses a traf atom (defined in 14496-12).
*/ */
private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray, private static void parseTraf(ContainerAtom traf, SparseArray<TrackBundle> trackBundleArray,
int flags, byte[] extendedTypeScratch) throws ParserException { @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd); LeafAtom tfhd = traf.getLeafAtomOfType(Atom.TYPE_tfhd);
TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags); TrackBundle trackBundle = parseTfhd(tfhd.data, trackBundleArray, flags);
if (trackBundle == null) { if (trackBundle == null) {
@ -488,7 +497,7 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime, private static void parseTruns(ContainerAtom traf, TrackBundle trackBundle, long decodeTime,
int flags) { @Flags int flags) {
int trunCount = 0; int trunCount = 0;
int totalSampleCount = 0; int totalSampleCount = 0;
List<LeafAtom> leafChildren = traf.leafChildren; List<LeafAtom> leafChildren = traf.leafChildren;
@ -643,8 +652,8 @@ public final class FragmentedMp4Extractor implements Extractor {
* @param trun The trun atom to decode. * @param trun The trun atom to decode.
* @return The starting position of samples for the next run. * @return The starting position of samples for the next run.
*/ */
private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime, int flags, private static int parseTrun(TrackBundle trackBundle, int index, long decodeTime,
ParsableByteArray trun, int trackRunStart) { @Flags int flags, ParsableByteArray trun, int trackRunStart) {
trun.setPosition(Atom.HEADER_SIZE); trun.setPosition(Atom.HEADER_SIZE);
int fullAtom = trun.readInt(); int fullAtom = trun.readInt();
int atomFlags = Atom.parseFullAtomFlags(fullAtom); int atomFlags = Atom.parseFullAtomFlags(fullAtom);
@ -994,7 +1003,7 @@ public final class FragmentedMp4Extractor implements Extractor {
} }
long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L; long sampleTimeUs = fragment.getSamplePresentationTime(sampleIndex) * 1000L;
int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0) @C.BufferFlags int sampleFlags = (fragment.definesEncryptionData ? C.BUFFER_FLAG_ENCRYPTED : 0)
| (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0); | (fragment.sampleIsSyncFrameTable[sampleIndex] ? C.BUFFER_FLAG_KEY_FRAME : 0);
int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex; int sampleDescriptionIndex = fragment.header.sampleDescriptionIndex;
byte[] encryptionKey = null; byte[] encryptionKey = null;

View File

@ -15,14 +15,23 @@
*/ */
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Encapsulates information describing an MP4 track. * Encapsulates information describing an MP4 track.
*/ */
public final class Track { public final class Track {
/**
* The transformation to apply to samples in the track, if any.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TRANSFORMATION_NONE, TRANSFORMATION_CEA608_CDAT})
public @interface Transformation {}
/** /**
* A no-op sample transformation. * A no-op sample transformation.
*/ */
@ -66,6 +75,7 @@ public final class Track {
* One of {@code TRANSFORMATION_*}. Defines the transformation to apply before outputting each * One of {@code TRANSFORMATION_*}. Defines the transformation to apply before outputting each
* sample. * sample.
*/ */
@Transformation
public final int sampleTransformation; public final int sampleTransformation;
/** /**
@ -90,7 +100,7 @@ public final class Track {
public final int nalUnitLengthFieldLength; public final int nalUnitLengthFieldLength;
public Track(int id, int type, long timescale, long movieTimescale, long durationUs, public Track(int id, int type, long timescale, long movieTimescale, long durationUs,
Format format, int sampleTransformation, Format format, @Transformation int sampleTransformation,
TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength, TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength,
long[] editListDurations, long[] editListMediaTimes) { long[] editListDurations, long[] editListMediaTimes) {
this.id = id; this.id = id;

View File

@ -49,7 +49,8 @@ import com.google.android.exoplayer2.util.Util;
*/ */
public final int[] flags; public final int[] flags;
TrackSampleTable(long[] offsets, int[] sizes, int maximumSize, long[] timestampsUs, int[] flags) { public TrackSampleTable(long[] offsets, int[] sizes, int maximumSize, long[] timestampsUs,
int[] flags) {
Assertions.checkArgument(sizes.length == timestampsUs.length); Assertions.checkArgument(sizes.length == timestampsUs.length);
Assertions.checkArgument(offsets.length == timestampsUs.length); Assertions.checkArgument(offsets.length == timestampsUs.length);
Assertions.checkArgument(flags.length == timestampsUs.length); Assertions.checkArgument(flags.length == timestampsUs.length);

View File

@ -128,7 +128,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.BUFFER_FLAG_KEY_FRAME : 0; @C.BufferFlags 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

@ -420,7 +420,7 @@ import java.util.List;
} }
private void outputSample(int offset) { private void outputSample(int offset) {
int flags = sampleIsKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0; @C.BufferFlags 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

@ -471,7 +471,7 @@ import java.util.Collections;
} }
private void outputSample(int offset) { private void outputSample(int offset) {
int flags = sampleIsKeyframe ? C.BUFFER_FLAG_KEY_FRAME : 0; @C.BufferFlags 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

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.ts; package com.google.android.exoplayer2.extractor.ts;
import android.support.annotation.IntDef;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
@ -32,6 +33,8 @@ import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Facilitates the extraction of data from the MPEG-2 TS container format. * Facilitates the extraction of data from the MPEG-2 TS container format.
@ -50,6 +53,13 @@ public final class TsExtractor implements Extractor {
}; };
/**
* Flags controlling what workarounds are enabled for the extractor.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {WORKAROUND_ALLOW_NON_IDR_KEYFRAMES, WORKAROUND_IGNORE_AAC_STREAM,
WORKAROUND_IGNORE_H264_STREAM, WORKAROUND_DETECT_ACCESS_UNITS, WORKAROUND_MAP_BY_TYPE})
public @interface WorkaroundFlags {}
public static final int WORKAROUND_ALLOW_NON_IDR_KEYFRAMES = 1; public static final int WORKAROUND_ALLOW_NON_IDR_KEYFRAMES = 1;
public static final int WORKAROUND_IGNORE_AAC_STREAM = 2; public static final int WORKAROUND_IGNORE_AAC_STREAM = 2;
public static final int WORKAROUND_IGNORE_H264_STREAM = 4; public static final int WORKAROUND_IGNORE_H264_STREAM = 4;
@ -83,6 +93,7 @@ public final class TsExtractor implements Extractor {
private static final int BUFFER_SIZE = TS_PACKET_SIZE * BUFFER_PACKET_COUNT; private static final int BUFFER_SIZE = TS_PACKET_SIZE * BUFFER_PACKET_COUNT;
private final TimestampAdjuster timestampAdjuster; private final TimestampAdjuster timestampAdjuster;
@WorkaroundFlags
private final int workaroundFlags; private final int workaroundFlags;
private final ParsableByteArray tsPacketBuffer; private final ParsableByteArray tsPacketBuffer;
private final ParsableBitArray tsScratch; private final ParsableBitArray tsScratch;
@ -103,7 +114,7 @@ public final class TsExtractor implements Extractor {
this(timestampAdjuster, 0); this(timestampAdjuster, 0);
} }
public TsExtractor(TimestampAdjuster timestampAdjuster, int workaroundFlags) { public TsExtractor(TimestampAdjuster timestampAdjuster, @WorkaroundFlags int workaroundFlags) {
this.timestampAdjuster = timestampAdjuster; this.timestampAdjuster = timestampAdjuster;
this.workaroundFlags = workaroundFlags; this.workaroundFlags = workaroundFlags;
tsPacketBuffer = new ParsableByteArray(BUFFER_SIZE); tsPacketBuffer = new ParsableByteArray(BUFFER_SIZE);

View File

@ -31,6 +31,7 @@ import com.google.android.exoplayer2.C;
/** Bits per sample for the audio data. */ /** Bits per sample for the audio data. */
private final int bitsPerSample; private final int bitsPerSample;
/** The PCM encoding */ /** The PCM encoding */
@C.PcmEncoding
private final int encoding; private final int encoding;
/** Offset to the start of sample data. */ /** Offset to the start of sample data. */
@ -39,7 +40,7 @@ import com.google.android.exoplayer2.C;
private long dataSize; private long dataSize;
public WavHeader(int numChannels, int sampleRateHz, int averageBytesPerSecond, int blockAlignment, public WavHeader(int numChannels, int sampleRateHz, int averageBytesPerSecond, int blockAlignment,
int bitsPerSample, int encoding) { int bitsPerSample, @C.PcmEncoding int encoding) {
this.numChannels = numChannels; this.numChannels = numChannels;
this.sampleRateHz = sampleRateHz; this.sampleRateHz = sampleRateHz;
this.averageBytesPerSecond = averageBytesPerSecond; this.averageBytesPerSecond = averageBytesPerSecond;
@ -99,6 +100,7 @@ import com.google.android.exoplayer2.C;
} }
/** Returns the PCM encoding. **/ /** Returns the PCM encoding. **/
@C.PcmEncoding
public int getEncoding() { public int getEncoding() {
return encoding; return encoding;
} }

View File

@ -87,7 +87,7 @@ import java.io.IOException;
+ blockAlignment); + blockAlignment);
} }
int encoding = Util.getPcmEncoding(bitsPerSample); @C.PcmEncoding int encoding = Util.getPcmEncoding(bitsPerSample);
if (encoding == C.ENCODING_INVALID) { if (encoding == C.ENCODING_INVALID) {
Log.e(TAG, "Unsupported WAV bit depth: " + bitsPerSample); Log.e(TAG, "Unsupported WAV bit depth: " + bitsPerSample);
return null; return null;

View File

@ -293,7 +293,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
MediaCrypto mediaCrypto = null; MediaCrypto mediaCrypto = null;
boolean drmSessionRequiresSecureDecoder = false; boolean drmSessionRequiresSecureDecoder = false;
if (drmSession != null) { if (drmSession != null) {
int drmSessionState = drmSession.getState(); @DrmSession.State int drmSessionState = drmSession.getState();
if (drmSessionState == DrmSession.STATE_ERROR) { if (drmSessionState == DrmSession.STATE_ERROR) {
throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex()); throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
} else if (drmSessionState == DrmSession.STATE_OPENED } else if (drmSessionState == DrmSession.STATE_OPENED
@ -682,7 +682,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (drmSession == null) { if (drmSession == null) {
return false; return false;
} }
int drmSessionState = drmSession.getState(); @DrmSession.State int drmSessionState = drmSession.getState();
if (drmSessionState == DrmSession.STATE_ERROR) { if (drmSessionState == DrmSession.STATE_ERROR) {
throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex()); throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
} }

View File

@ -15,11 +15,14 @@
*/ */
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod.Callback; import com.google.android.exoplayer2.source.MediaPeriod.Callback;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -36,11 +39,16 @@ public final class MergingMediaSource implements MediaSource {
*/ */
public static final class IllegalMergeException extends IOException { public static final class IllegalMergeException extends IOException {
/**
* The reason the merge failed.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({REASON_WINDOWS_ARE_DYNAMIC, REASON_PERIOD_COUNT_MISMATCH})
public @interface Reason {}
/** /**
* The merge failed because one of the sources being merged has a dynamic window. * The merge failed because one of the sources being merged has a dynamic window.
*/ */
public static final int REASON_WINDOWS_ARE_DYNAMIC = 0; public static final int REASON_WINDOWS_ARE_DYNAMIC = 0;
/** /**
* The merge failed because the sources have different period counts. * The merge failed because the sources have different period counts.
*/ */
@ -50,13 +58,14 @@ public final class MergingMediaSource implements MediaSource {
* The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and * The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and
* {@link #REASON_PERIOD_COUNT_MISMATCH}. * {@link #REASON_PERIOD_COUNT_MISMATCH}.
*/ */
@Reason
public final int reason; public final int reason;
/** /**
* @param reason The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and * @param reason The reason the merge failed. One of {@link #REASON_WINDOWS_ARE_DYNAMIC} and
* {@link #REASON_PERIOD_COUNT_MISMATCH}. * {@link #REASON_PERIOD_COUNT_MISMATCH}.
*/ */
public IllegalMergeException(int reason) { public IllegalMergeException(@Reason int reason) {
this.reason = reason; this.reason = reason;
} }

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.source.chunk; package com.google.android.exoplayer2.source.chunk;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
@ -150,7 +151,8 @@ public final class ChunkExtractorWrapper implements ExtractorOutput, TrackOutput
} }
@Override @Override
public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) {
trackOutput.sampleMetadata(timeUs, flags, size, offset, encryptionKey); trackOutput.sampleMetadata(timeUs, flags, size, offset, encryptionKey);
} }

View File

@ -111,7 +111,8 @@ public final class InitializationChunk extends Chunk implements SingleTrackMetad
} }
@Override @Override
public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) {
throw new IllegalStateException("Unexpected sample data in initialization chunk"); throw new IllegalStateException("Unexpected sample data in initialization chunk");
} }

View File

@ -355,7 +355,7 @@ import java.util.Locale;
timestampAdjuster = timestampAdjusterProvider.getAdjuster(segment.discontinuitySequenceNumber, timestampAdjuster = timestampAdjusterProvider.getAdjuster(segment.discontinuitySequenceNumber,
startTimeUs); startTimeUs);
// This flag ensures the change of pid between streams does not affect the sample queues. // This flag ensures the change of pid between streams does not affect the sample queues.
int workaroundFlags = TsExtractor.WORKAROUND_MAP_BY_TYPE; @TsExtractor.WorkaroundFlags int workaroundFlags = TsExtractor.WORKAROUND_MAP_BY_TYPE;
String codecs = variants[newVariantIndex].format.codecs; String codecs = variants[newVariantIndex].format.codecs;
if (!TextUtils.isEmpty(codecs)) { if (!TextUtils.isEmpty(codecs)) {
// Sometimes AAC and H264 streams are declared in TS chunks even though they don't really // Sometimes AAC and H264 streams are declared in TS chunks even though they don't really

View File

@ -15,18 +15,29 @@
*/ */
package com.google.android.exoplayer2.source.hls.playlist; package com.google.android.exoplayer2.source.hls.playlist;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Represents an HLS playlist. * Represents an HLS playlist.
*/ */
public abstract class HlsPlaylist { public abstract class HlsPlaylist {
/**
* The type of playlist.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_MASTER, TYPE_MEDIA})
public @interface Type {}
public static final int TYPE_MASTER = 0; public static final int TYPE_MASTER = 0;
public static final int TYPE_MEDIA = 1; public static final int TYPE_MEDIA = 1;
public final String baseUri; public final String baseUri;
@Type
public final int type; public final int type;
protected HlsPlaylist(String baseUri, int type) { protected HlsPlaylist(String baseUri, @Type int type) {
this.baseUri = baseUri; this.baseUri = baseUri;
this.type = type; this.type = type;
} }

View File

@ -62,7 +62,6 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final String BOOLEAN_TRUE = "YES"; private static final String BOOLEAN_TRUE = "YES";
private static final String BOOLEAN_FALSE = "NO"; private static final String BOOLEAN_FALSE = "NO";
private static final Pattern REGEX_GROUP_ID = Pattern.compile("GROUP-ID=\"(.+?)\""); private static final Pattern REGEX_GROUP_ID = Pattern.compile("GROUP-ID=\"(.+?)\"");
private static final Pattern REGEX_VIDEO = Pattern.compile("VIDEO=\"(.+?)\""); private static final Pattern REGEX_VIDEO = Pattern.compile("VIDEO=\"(.+?)\"");
private static final Pattern REGEX_AUDIO = Pattern.compile("AUDIO=\"(.+?)\""); private static final Pattern REGEX_AUDIO = Pattern.compile("AUDIO=\"(.+?)\"");
@ -138,7 +137,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
while (iterator.hasNext()) { while (iterator.hasNext()) {
line = iterator.next(); line = iterator.next();
if (line.startsWith(TAG_MEDIA)) { if (line.startsWith(TAG_MEDIA)) {
int selectionFlags = parseSelectionFlags(line); @C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
String uri = parseOptionalStringAttr(line, REGEX_URI); String uri = parseOptionalStringAttr(line, REGEX_URI);
String name = parseStringAttr(line, REGEX_NAME); String name = parseStringAttr(line, REGEX_NAME);
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE); String language = parseOptionalStringAttr(line, REGEX_LANGUAGE);
@ -200,11 +199,11 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
muxedCaptionFormat); muxedCaptionFormat);
} }
@C.SelectionFlags
private static int parseSelectionFlags(String line) { private static int parseSelectionFlags(String line) {
return (parseBooleanAttribute(line, REGEX_DEFAULT, false) ? Format.SELECTION_FLAG_DEFAULT : 0) return (parseBooleanAttribute(line, REGEX_DEFAULT, false) ? C.SELECTION_FLAG_DEFAULT : 0)
| (parseBooleanAttribute(line, REGEX_FORCED, false) ? Format.SELECTION_FLAG_FORCED : 0) | (parseBooleanAttribute(line, REGEX_FORCED, false) ? C.SELECTION_FLAG_FORCED : 0)
| (parseBooleanAttribute(line, REGEX_AUTOSELECT, false) ? Format.SELECTION_FLAG_AUTOSELECT | (parseBooleanAttribute(line, REGEX_AUTOSELECT, false) ? C.SELECTION_FLAG_AUTOSELECT : 0);
: 0);
} }
private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String baseUri) private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String baseUri)

View File

@ -18,35 +18,41 @@ package com.google.android.exoplayer2.text;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.support.annotation.IntDef;
import android.view.accessibility.CaptioningManager; import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle; import android.view.accessibility.CaptioningManager.CaptionStyle;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* A compatibility wrapper for {@link CaptionStyle}. * A compatibility wrapper for {@link CaptionStyle}.
*/ */
public final class CaptionStyleCompat { public final class CaptionStyleCompat {
/**
* The type of edge, which may be none.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({EDGE_TYPE_NONE, EDGE_TYPE_OUTLINE, EDGE_TYPE_DROP_SHADOW, EDGE_TYPE_RAISED,
EDGE_TYPE_DEPRESSED})
public @interface EdgeType {}
/** /**
* Edge type value specifying no character edges. * Edge type value specifying no character edges.
*/ */
public static final int EDGE_TYPE_NONE = 0; public static final int EDGE_TYPE_NONE = 0;
/** /**
* Edge type value specifying uniformly outlined character edges. * Edge type value specifying uniformly outlined character edges.
*/ */
public static final int EDGE_TYPE_OUTLINE = 1; public static final int EDGE_TYPE_OUTLINE = 1;
/** /**
* Edge type value specifying drop-shadowed character edges. * Edge type value specifying drop-shadowed character edges.
*/ */
public static final int EDGE_TYPE_DROP_SHADOW = 2; public static final int EDGE_TYPE_DROP_SHADOW = 2;
/** /**
* Edge type value specifying raised bevel character edges. * Edge type value specifying raised bevel character edges.
*/ */
public static final int EDGE_TYPE_RAISED = 3; public static final int EDGE_TYPE_RAISED = 3;
/** /**
* Edge type value specifying depressed bevel character edges. * Edge type value specifying depressed bevel character edges.
*/ */
@ -88,6 +94,7 @@ public final class CaptionStyleCompat {
* <li>{@link #EDGE_TYPE_DEPRESSED} * <li>{@link #EDGE_TYPE_DEPRESSED}
* </ul> * </ul>
*/ */
@EdgeType
public final int edgeType; public final int edgeType;
/** /**
@ -126,8 +133,8 @@ public final class CaptionStyleCompat {
* @param edgeColor See {@link #edgeColor}. * @param edgeColor See {@link #edgeColor}.
* @param typeface See {@link #typeface}. * @param typeface See {@link #typeface}.
*/ */
public CaptionStyleCompat(int foregroundColor, int backgroundColor, int windowColor, int edgeType, public CaptionStyleCompat(int foregroundColor, int backgroundColor, int windowColor,
int edgeColor, Typeface typeface) { @EdgeType int edgeType, int edgeColor, Typeface typeface) {
this.foregroundColor = foregroundColor; this.foregroundColor = foregroundColor;
this.backgroundColor = backgroundColor; this.backgroundColor = backgroundColor;
this.windowColor = windowColor; this.windowColor = windowColor;
@ -137,6 +144,7 @@ public final class CaptionStyleCompat {
} }
@TargetApi(19) @TargetApi(19)
@SuppressWarnings("ResourceType")
private static CaptionStyleCompat createFromCaptionStyleV19( private static CaptionStyleCompat createFromCaptionStyleV19(
CaptioningManager.CaptionStyle captionStyle) { CaptioningManager.CaptionStyle captionStyle) {
return new CaptionStyleCompat( return new CaptionStyleCompat(
@ -145,6 +153,7 @@ public final class CaptionStyleCompat {
} }
@TargetApi(21) @TargetApi(21)
@SuppressWarnings("ResourceType")
private static CaptionStyleCompat createFromCaptionStyleV21( private static CaptionStyleCompat createFromCaptionStyleV21(
CaptioningManager.CaptionStyle captionStyle) { CaptioningManager.CaptionStyle captionStyle) {
return new CaptionStyleCompat( return new CaptionStyleCompat(

View File

@ -15,7 +15,10 @@
*/ */
package com.google.android.exoplayer2.text; package com.google.android.exoplayer2.text;
import android.support.annotation.IntDef;
import android.text.Layout.Alignment; import android.text.Layout.Alignment;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Contains information about a specific cue, including textual content and formatting data. * Contains information about a specific cue, including textual content and formatting data.
@ -26,6 +29,13 @@ public class Cue {
* An unset position or width. * An unset position or width.
*/ */
public static final float DIMEN_UNSET = Float.MIN_VALUE; public static final float DIMEN_UNSET = Float.MIN_VALUE;
/**
* The type of anchor, which may be unset.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_UNSET, ANCHOR_TYPE_START, ANCHOR_TYPE_MIDDLE, ANCHOR_TYPE_END})
public @interface AnchorType {}
/** /**
* An unset anchor or line type value. * An unset anchor or line type value.
*/ */
@ -44,6 +54,13 @@ public class Cue {
* box. * box.
*/ */
public static final int ANCHOR_TYPE_END = 2; public static final int ANCHOR_TYPE_END = 2;
/**
* The type of line, which may be unset.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_UNSET, LINE_TYPE_FRACTION, LINE_TYPE_NUMBER})
public @interface LineType {}
/** /**
* Value for {@link #lineType} when {@link #line} is a fractional position. * Value for {@link #lineType} when {@link #line} is a fractional position.
*/ */
@ -83,6 +100,7 @@ public class Cue {
* -1). For horizontal text the size of the first line of the cue is its height, and the start * -1). For horizontal text the size of the first line of the cue is its height, and the start
* and end of the viewport are the top and bottom respectively. * and end of the viewport are the top and bottom respectively.
*/ */
@LineType
public final int lineType; public final int lineType;
/** /**
* The cue box anchor positioned by {@link #line}. One of {@link #ANCHOR_TYPE_START}, * The cue box anchor positioned by {@link #line}. One of {@link #ANCHOR_TYPE_START},
@ -92,6 +110,7 @@ public class Cue {
* and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box * and {@link #ANCHOR_TYPE_END} correspond to the top, middle and bottom of the cue box
* respectively. * respectively.
*/ */
@AnchorType
public final int lineAnchor; public final int lineAnchor;
/** /**
* The fractional position of the {@link #positionAnchor} of the cue box within the viewport in * The fractional position of the {@link #positionAnchor} of the cue box within the viewport in
@ -110,6 +129,7 @@ public class Cue {
* and {@link #ANCHOR_TYPE_END} correspond to the left, middle and right of the cue box * and {@link #ANCHOR_TYPE_END} correspond to the left, middle and right of the cue box
* respectively. * respectively.
*/ */
@AnchorType
public final int positionAnchor; public final int positionAnchor;
/** /**
* The size of the cue box in the writing direction specified as a fraction of the viewport size * The size of the cue box in the writing direction specified as a fraction of the viewport size
@ -137,8 +157,8 @@ public class Cue {
* @param positionAnchor See {@link #positionAnchor}. * @param positionAnchor See {@link #positionAnchor}.
* @param size See {@link #size}. * @param size See {@link #size}.
*/ */
public Cue(CharSequence text, Alignment textAlignment, float line, int lineType, int lineAnchor, public Cue(CharSequence text, Alignment textAlignment, float line, @LineType int lineType,
float position, int positionAnchor, float size) { @AnchorType int lineAnchor, float position, @AnchorType int positionAnchor, float size) {
this.text = text; this.text = text;
this.textAlignment = textAlignment; this.textAlignment = textAlignment;
this.line = line; this.line = line;

View File

@ -24,6 +24,7 @@ import com.google.android.exoplayer2.text.Cue;
public final float position; public final float position;
public final float line; public final float line;
@Cue.LineType
public final int lineType; public final int lineType;
public final float width; public final float width;
@ -31,7 +32,7 @@ import com.google.android.exoplayer2.text.Cue;
this(Cue.DIMEN_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET); this(Cue.DIMEN_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET);
} }
public TtmlRegion(float position, float line, int lineType, float width) { public TtmlRegion(float position, float line, @Cue.LineType int lineType, float width) {
this.position = position; this.position = position;
this.line = line; this.line = line;
this.lineType = lineType; this.lineType = lineType;

View File

@ -16,8 +16,11 @@
package com.google.android.exoplayer2.text.ttml; package com.google.android.exoplayer2.text.ttml;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.support.annotation.IntDef;
import android.text.Layout; import android.text.Layout;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* Style object of a <code>TtmlNode</code> * Style object of a <code>TtmlNode</code>
@ -26,15 +29,25 @@ import com.google.android.exoplayer2.util.Assertions;
public static final int UNSPECIFIED = -1; public static final int UNSPECIFIED = -1;
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {UNSPECIFIED, STYLE_NORMAL, STYLE_BOLD, STYLE_ITALIC,
STYLE_BOLD_ITALIC})
public @interface StyleFlags {}
public static final int STYLE_NORMAL = Typeface.NORMAL; public static final int STYLE_NORMAL = Typeface.NORMAL;
public static final int STYLE_BOLD = Typeface.BOLD; public static final int STYLE_BOLD = Typeface.BOLD;
public static final int STYLE_ITALIC = Typeface.ITALIC; public static final int STYLE_ITALIC = Typeface.ITALIC;
public static final int STYLE_BOLD_ITALIC = Typeface.BOLD_ITALIC; public static final int STYLE_BOLD_ITALIC = Typeface.BOLD_ITALIC;
@Retention(RetentionPolicy.SOURCE)
@IntDef({UNSPECIFIED, FONT_SIZE_UNIT_PIXEL, FONT_SIZE_UNIT_EM, FONT_SIZE_UNIT_PERCENT})
public @interface FontSizeUnit {}
public static final int FONT_SIZE_UNIT_PIXEL = 1; public static final int FONT_SIZE_UNIT_PIXEL = 1;
public static final int FONT_SIZE_UNIT_EM = 2; public static final int FONT_SIZE_UNIT_EM = 2;
public static final int FONT_SIZE_UNIT_PERCENT = 3; public static final int FONT_SIZE_UNIT_PERCENT = 3;
@Retention(RetentionPolicy.SOURCE)
@IntDef({UNSPECIFIED, OFF, ON})
private @interface OptionalBoolean {}
private static final int OFF = 0; private static final int OFF = 0;
private static final int ON = 1; private static final int ON = 1;
@ -43,10 +56,15 @@ import com.google.android.exoplayer2.util.Assertions;
private boolean hasFontColor; private boolean hasFontColor;
private int backgroundColor; private int backgroundColor;
private boolean hasBackgroundColor; private boolean hasBackgroundColor;
@OptionalBoolean
private int linethrough; private int linethrough;
@OptionalBoolean
private int underline; private int underline;
@OptionalBoolean
private int bold; private int bold;
@OptionalBoolean
private int italic; private int italic;
@FontSizeUnit
private int fontSizeUnit; private int fontSizeUnit;
private float fontSize; private float fontSize;
private String id; private String id;
@ -67,12 +85,13 @@ import com.google.android.exoplayer2.util.Assertions;
* @return {@link #UNSPECIFIED}, {@link #STYLE_NORMAL}, {@link #STYLE_BOLD}, {@link #STYLE_BOLD} * @return {@link #UNSPECIFIED}, {@link #STYLE_NORMAL}, {@link #STYLE_BOLD}, {@link #STYLE_BOLD}
* or {@link #STYLE_BOLD_ITALIC}. * or {@link #STYLE_BOLD_ITALIC}.
*/ */
@StyleFlags
public int getStyle() { public int getStyle() {
if (bold == UNSPECIFIED && italic == UNSPECIFIED) { if (bold == UNSPECIFIED && italic == UNSPECIFIED) {
return UNSPECIFIED; return UNSPECIFIED;
} }
return (bold != UNSPECIFIED ? bold : STYLE_NORMAL) return (bold == ON ? STYLE_BOLD : STYLE_NORMAL)
| (italic != UNSPECIFIED ? italic : STYLE_NORMAL); | (italic == ON ? STYLE_ITALIC : STYLE_NORMAL);
} }
public boolean isLinethrough() { public boolean isLinethrough() {
@ -95,6 +114,18 @@ import com.google.android.exoplayer2.util.Assertions;
return this; return this;
} }
public TtmlStyle setBold(boolean bold) {
Assertions.checkState(inheritableStyle == null);
this.bold = bold ? ON : OFF;
return this;
}
public TtmlStyle setItalic(boolean italic) {
Assertions.checkState(inheritableStyle == null);
this.italic = italic ? ON : OFF;
return this;
}
public String getFontFamily() { public String getFontFamily() {
return fontFamily; return fontFamily;
} }
@ -140,18 +171,6 @@ import com.google.android.exoplayer2.util.Assertions;
return hasBackgroundColor; return hasBackgroundColor;
} }
public TtmlStyle setBold(boolean isBold) {
Assertions.checkState(inheritableStyle == null);
bold = isBold ? STYLE_BOLD : STYLE_NORMAL;
return this;
}
public TtmlStyle setItalic(boolean isItalic) {
Assertions.checkState(inheritableStyle == null);
italic = isItalic ? STYLE_ITALIC : STYLE_NORMAL;
return this;
}
/** /**
* Inherits from an ancestor style. Properties like <i>tts:backgroundColor</i> which * Inherits from an ancestor style. Properties like <i>tts:backgroundColor</i> which
* are not inheritable are not inherited as well as properties which are already set locally * are not inheritable are not inherited as well as properties which are already set locally
@ -236,6 +255,7 @@ import com.google.android.exoplayer2.util.Assertions;
return this; return this;
} }
@FontSizeUnit
public int getFontSizeUnit() { public int getFontSizeUnit() {
return fontSizeUnit; return fontSizeUnit;
} }

View File

@ -16,8 +16,11 @@
package com.google.android.exoplayer2.text.webvtt; package com.google.android.exoplayer2.text.webvtt;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.support.annotation.IntDef;
import android.text.Layout; import android.text.Layout;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -32,15 +35,25 @@ import java.util.List;
public static final int UNSPECIFIED = -1; public static final int UNSPECIFIED = -1;
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {UNSPECIFIED, STYLE_NORMAL, STYLE_BOLD, STYLE_ITALIC,
STYLE_BOLD_ITALIC})
public @interface StyleFlags {}
public static final int STYLE_NORMAL = Typeface.NORMAL; public static final int STYLE_NORMAL = Typeface.NORMAL;
public static final int STYLE_BOLD = Typeface.BOLD; public static final int STYLE_BOLD = Typeface.BOLD;
public static final int STYLE_ITALIC = Typeface.ITALIC; public static final int STYLE_ITALIC = Typeface.ITALIC;
public static final int STYLE_BOLD_ITALIC = Typeface.BOLD_ITALIC; public static final int STYLE_BOLD_ITALIC = Typeface.BOLD_ITALIC;
@Retention(RetentionPolicy.SOURCE)
@IntDef({UNSPECIFIED, FONT_SIZE_UNIT_PIXEL, FONT_SIZE_UNIT_EM, FONT_SIZE_UNIT_PERCENT})
public @interface FontSizeUnit {}
public static final int FONT_SIZE_UNIT_PIXEL = 1; public static final int FONT_SIZE_UNIT_PIXEL = 1;
public static final int FONT_SIZE_UNIT_EM = 2; public static final int FONT_SIZE_UNIT_EM = 2;
public static final int FONT_SIZE_UNIT_PERCENT = 3; public static final int FONT_SIZE_UNIT_PERCENT = 3;
@Retention(RetentionPolicy.SOURCE)
@IntDef({UNSPECIFIED, OFF, ON})
private @interface OptionalBoolean {}
private static final int OFF = 0; private static final int OFF = 0;
private static final int ON = 1; private static final int ON = 1;
@ -56,10 +69,15 @@ import java.util.List;
private boolean hasFontColor; private boolean hasFontColor;
private int backgroundColor; private int backgroundColor;
private boolean hasBackgroundColor; private boolean hasBackgroundColor;
@OptionalBoolean
private int linethrough; private int linethrough;
@OptionalBoolean
private int underline; private int underline;
@OptionalBoolean
private int bold; private int bold;
@OptionalBoolean
private int italic; private int italic;
@FontSizeUnit
private int fontSizeUnit; private int fontSizeUnit;
private float fontSize; private float fontSize;
private Layout.Alignment textAlign; private Layout.Alignment textAlign;
@ -144,12 +162,13 @@ import java.util.List;
* @return {@link #UNSPECIFIED}, {@link #STYLE_NORMAL}, {@link #STYLE_BOLD}, {@link #STYLE_BOLD} * @return {@link #UNSPECIFIED}, {@link #STYLE_NORMAL}, {@link #STYLE_BOLD}, {@link #STYLE_BOLD}
* or {@link #STYLE_BOLD_ITALIC}. * or {@link #STYLE_BOLD_ITALIC}.
*/ */
@StyleFlags
public int getStyle() { public int getStyle() {
if (bold == UNSPECIFIED && italic == UNSPECIFIED) { if (bold == UNSPECIFIED && italic == UNSPECIFIED) {
return UNSPECIFIED; return UNSPECIFIED;
} }
return (bold != UNSPECIFIED ? bold : STYLE_NORMAL) return (bold == ON ? STYLE_BOLD : STYLE_NORMAL)
| (italic != UNSPECIFIED ? italic : STYLE_NORMAL); | (italic == ON ? STYLE_ITALIC : STYLE_NORMAL);
} }
public boolean isLinethrough() { public boolean isLinethrough() {
@ -169,6 +188,15 @@ import java.util.List;
this.underline = underline ? ON : OFF; this.underline = underline ? ON : OFF;
return this; return this;
} }
public WebvttCssStyle setBold(boolean bold) {
this.bold = bold ? ON : OFF;
return this;
}
public WebvttCssStyle setItalic(boolean italic) {
this.italic = italic ? ON : OFF;
return this;
}
public String getFontFamily() { public String getFontFamily() {
return fontFamily; return fontFamily;
@ -213,16 +241,6 @@ import java.util.List;
return hasBackgroundColor; return hasBackgroundColor;
} }
public WebvttCssStyle setBold(boolean isBold) {
bold = isBold ? STYLE_BOLD : STYLE_NORMAL;
return this;
}
public WebvttCssStyle setItalic(boolean isItalic) {
italic = isItalic ? STYLE_ITALIC : STYLE_NORMAL;
return this;
}
public Layout.Alignment getTextAlign() { public Layout.Alignment getTextAlign() {
return textAlign; return textAlign;
} }
@ -242,6 +260,7 @@ import java.util.List;
return this; return this;
} }
@FontSizeUnit
public int getFontSizeUnit() { public int getFontSizeUnit() {
return fontSizeUnit; return fontSizeUnit;
} }

View File

@ -37,8 +37,9 @@ import com.google.android.exoplayer2.text.Cue;
Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET); Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET);
} }
public WebvttCue(long startTime, long endTime, CharSequence text, Alignment textAlignment, public WebvttCue(long startTime, long endTime, CharSequence text, Alignment textAlignment,
float line, int lineType, int lineAnchor, float position, int positionAnchor, float width) { float line, @Cue.LineType int lineType, @Cue.AnchorType int lineAnchor, float position,
@Cue.AnchorType int positionAnchor, float width) {
super(text, textAlignment, line, lineType, lineAnchor, position, positionAnchor, width); super(text, textAlignment, line, lineType, lineAnchor, position, positionAnchor, width);
this.startTime = startTime; this.startTime = startTime;
this.endTime = endTime; this.endTime = endTime;

View File

@ -442,7 +442,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex])) { if (isSupported(trackFormatSupport[trackIndex])) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & Format.SELECTION_FLAG_DEFAULT) != 0; boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
int trackScore; int trackScore;
if (formatHasLanguage(format, preferredAudioLanguage)) { if (formatHasLanguage(format, preferredAudioLanguage)) {
if (isDefault) { if (isDefault) {
@ -480,8 +480,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex])) { if (isSupported(trackFormatSupport[trackIndex])) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & Format.SELECTION_FLAG_DEFAULT) != 0; boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
boolean isForced = (format.selectionFlags & Format.SELECTION_FLAG_FORCED) != 0; boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore; int trackScore;
if (formatHasLanguage(format, preferredTextLanguage)) { if (formatHasLanguage(format, preferredTextLanguage)) {
if (isDefault) { if (isDefault) {
@ -530,7 +530,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex])) { if (isSupported(trackFormatSupport[trackIndex])) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & Format.SELECTION_FLAG_DEFAULT) != 0; boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
int trackScore = isDefault ? 2 : 1; int trackScore = isDefault ? 2 : 1;
if (trackScore > selectedTrackScore) { if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup; selectedGroup = trackGroup;

View File

@ -66,9 +66,12 @@ import com.google.android.exoplayer2.util.Util;
private CharSequence cueText; private CharSequence cueText;
private Alignment cueTextAlignment; private Alignment cueTextAlignment;
private float cueLine; private float cueLine;
@Cue.LineType
private int cueLineType; private int cueLineType;
@Cue.AnchorType
private int cueLineAnchor; private int cueLineAnchor;
private float cuePosition; private float cuePosition;
@Cue.AnchorType
private int cuePositionAnchor; private int cuePositionAnchor;
private float cueSize; private float cueSize;
private boolean applyEmbeddedStyles; private boolean applyEmbeddedStyles;
@ -76,6 +79,7 @@ import com.google.android.exoplayer2.util.Util;
private int backgroundColor; private int backgroundColor;
private int windowColor; private int windowColor;
private int edgeColor; private int edgeColor;
@CaptionStyleCompat.EdgeType
private int edgeType; private int edgeType;
private float textSizePx; private float textSizePx;
private float bottomPaddingFraction; private float bottomPaddingFraction;

View File

@ -16,8 +16,11 @@
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.IntDef;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -25,6 +28,12 @@ import java.util.Arrays;
*/ */
public final class DataSpec { public final class DataSpec {
/**
* The flags that apply to any request for data.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {FLAG_ALLOW_GZIP})
public @interface Flags {}
/** /**
* Permits an underlying network stack to request that the server use gzip compression. * Permits an underlying network stack to request that the server use gzip compression.
* <p> * <p>
@ -69,6 +78,7 @@ public final class DataSpec {
/** /**
* Request flags. Currently {@link #FLAG_ALLOW_GZIP} is the only supported flag. * Request flags. Currently {@link #FLAG_ALLOW_GZIP} is the only supported flag.
*/ */
@Flags
public final int flags; public final int flags;
/** /**
@ -86,7 +96,7 @@ public final class DataSpec {
* @param uri {@link #uri}. * @param uri {@link #uri}.
* @param flags {@link #flags}. * @param flags {@link #flags}.
*/ */
public DataSpec(Uri uri, int flags) { public DataSpec(Uri uri, @Flags int flags) {
this(uri, 0, C.LENGTH_UNSET, null, flags); this(uri, 0, C.LENGTH_UNSET, null, flags);
} }
@ -111,7 +121,7 @@ public final class DataSpec {
* @param key {@link #key}. * @param key {@link #key}.
* @param flags {@link #flags}. * @param flags {@link #flags}.
*/ */
public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key, int flags) { public DataSpec(Uri uri, long absoluteStreamPosition, long length, String key, @Flags int flags) {
this(uri, absoluteStreamPosition, absoluteStreamPosition, length, key, flags); this(uri, absoluteStreamPosition, absoluteStreamPosition, length, key, flags);
} }
@ -127,7 +137,7 @@ public final class DataSpec {
* @param flags {@link #flags}. * @param flags {@link #flags}.
*/ */
public DataSpec(Uri uri, long absoluteStreamPosition, long position, long length, String key, public DataSpec(Uri uri, long absoluteStreamPosition, long position, long length, String key,
int flags) { @Flags int flags) {
this(uri, null, absoluteStreamPosition, position, length, key, flags); this(uri, null, absoluteStreamPosition, position, length, key, flags);
} }
@ -144,7 +154,7 @@ public final class DataSpec {
* @param flags {@link #flags}. * @param flags {@link #flags}.
*/ */
public DataSpec(Uri uri, byte[] postBody, long absoluteStreamPosition, long position, long length, public DataSpec(Uri uri, byte[] postBody, long absoluteStreamPosition, long position, long length,
String key, int flags) { String key, @Flags int flags) {
Assertions.checkArgument(absoluteStreamPosition >= 0); Assertions.checkArgument(absoluteStreamPosition >= 0);
Assertions.checkArgument(position >= 0); Assertions.checkArgument(position >= 0);
Assertions.checkArgument(length > 0 || length == C.LENGTH_UNSET); Assertions.checkArgument(length > 0 || length == C.LENGTH_UNSET);

View File

@ -15,10 +15,13 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import android.support.annotation.IntDef;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.exoplayer2.util.Predicate; import com.google.android.exoplayer2.util.Predicate;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -57,10 +60,14 @@ public interface HttpDataSource extends DataSource {
*/ */
class HttpDataSourceException extends IOException { class HttpDataSourceException extends IOException {
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_OPEN, TYPE_READ, TYPE_CLOSE})
public @interface Type {}
public static final int TYPE_OPEN = 1; public static final int TYPE_OPEN = 1;
public static final int TYPE_READ = 2; public static final int TYPE_READ = 2;
public static final int TYPE_CLOSE = 3; public static final int TYPE_CLOSE = 3;
@Type
public final int type; public final int type;
/** /**
@ -68,25 +75,26 @@ public interface HttpDataSource extends DataSource {
*/ */
public final DataSpec dataSpec; public final DataSpec dataSpec;
public HttpDataSourceException(DataSpec dataSpec, int type) { public HttpDataSourceException(DataSpec dataSpec, @Type int type) {
super(); super();
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.type = type; this.type = type;
} }
public HttpDataSourceException(String message, DataSpec dataSpec, int type) { public HttpDataSourceException(String message, DataSpec dataSpec, @Type int type) {
super(message); super(message);
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.type = type; this.type = type;
} }
public HttpDataSourceException(IOException cause, DataSpec dataSpec, int type) { public HttpDataSourceException(IOException cause, DataSpec dataSpec, @Type int type) {
super(cause); super(cause);
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.type = type; this.type = type;
} }
public HttpDataSourceException(String message, IOException cause, DataSpec dataSpec, int type) { public HttpDataSourceException(String message, IOException cause, DataSpec dataSpec,
@Type int type) {
super(message, cause); super(message, cause);
this.dataSpec = dataSpec; this.dataSpec = dataSpec;
this.type = type; this.type = type;

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.IntDef;
import android.util.Log; import android.util.Log;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSink; import com.google.android.exoplayer2.upstream.DataSink;
@ -27,6 +28,8 @@ import com.google.android.exoplayer2.upstream.TeeDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSink.CacheDataSinkException; import com.google.android.exoplayer2.upstream.cache.CacheDataSink.CacheDataSinkException;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** /**
* A {@link DataSource} that reads and writes a {@link Cache}. Requests are fulfilled from the cache * A {@link DataSource} that reads and writes a {@link Cache}. Requests are fulfilled from the cache
@ -43,6 +46,13 @@ public final class CacheDataSource implements DataSource {
*/ */
public static final long DEFAULT_MAX_CACHE_FILE_SIZE = 2 * 1024 * 1024; public static final long DEFAULT_MAX_CACHE_FILE_SIZE = 2 * 1024 * 1024;
/**
* Flags controlling the cache's behavior.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {FLAG_BLOCK_ON_CACHE, FLAG_IGNORE_CACHE_ON_ERROR,
FLAG_CACHE_UNBOUNDED_REQUESTS})
public @interface Flags {}
/** /**
* A flag indicating whether we will block reads if the cache key is locked. If this flag is * A flag indicating whether we will block reads if the cache key is locked. If this flag is
* set, then we will read from upstream if the cache key is locked. * set, then we will read from upstream if the cache key is locked.
@ -106,7 +116,7 @@ public final class CacheDataSource implements DataSource {
* Constructs an instance with default {@link DataSource} and {@link DataSink} instances for * Constructs an instance with default {@link DataSource} and {@link DataSink} instances for
* reading and writing the cache and with {@link #DEFAULT_MAX_CACHE_FILE_SIZE}. * reading and writing the cache and with {@link #DEFAULT_MAX_CACHE_FILE_SIZE}.
*/ */
public CacheDataSource(Cache cache, DataSource upstream, int flags) { public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags) {
this(cache, upstream, flags, DEFAULT_MAX_CACHE_FILE_SIZE); this(cache, upstream, flags, DEFAULT_MAX_CACHE_FILE_SIZE);
} }
@ -123,7 +133,8 @@ public final class CacheDataSource implements DataSource {
* exceeds this value, then the data will be fragmented into multiple cache files. The * exceeds this value, then the data will be fragmented into multiple cache files. The
* finer-grained this is the finer-grained the eviction policy can be. * finer-grained this is the finer-grained the eviction policy can be.
*/ */
public CacheDataSource(Cache cache, DataSource upstream, int flags, long maxCacheFileSize) { public CacheDataSource(Cache cache, DataSource upstream, @Flags int flags,
long maxCacheFileSize) {
this(cache, upstream, new FileDataSource(), new CacheDataSink(cache, maxCacheFileSize), this(cache, upstream, new FileDataSource(), new CacheDataSink(cache, maxCacheFileSize),
flags, null); flags, null);
} }
@ -142,7 +153,7 @@ public final class CacheDataSource implements DataSource {
* @param eventListener An optional {@link EventListener} to receive events. * @param eventListener An optional {@link EventListener} to receive events.
*/ */
public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource, public CacheDataSource(Cache cache, DataSource upstream, DataSource cacheReadDataSource,
DataSink cacheWriteDataSink, int flags, EventListener eventListener) { DataSink cacheWriteDataSink, @Flags int flags, EventListener eventListener) {
this.cache = cache; this.cache = cache;
this.cacheReadDataSource = cacheReadDataSource; this.cacheReadDataSource = cacheReadDataSource;
this.blockOnCache = (flags & FLAG_BLOCK_ON_CACHE) != 0; this.blockOnCache = (flags & FLAG_BLOCK_ON_CACHE) != 0;

View File

@ -88,27 +88,6 @@ public final class Util {
*/ */
public static final String MODEL = Build.MODEL; public static final String MODEL = Build.MODEL;
/**
* Value returned by {@link #inferContentType(String)} for DASH manifests.
*/
public static final int TYPE_DASH = 0;
/**
* Value returned by {@link #inferContentType(String)} for Smooth Streaming manifests.
*/
public static final int TYPE_SS = 1;
/**
* Value returned by {@link #inferContentType(String)} for HLS manifests.
*/
public static final int TYPE_HLS = 2;
/**
* Value returned by {@link #inferContentType(String)} for files other than DASH, HLS or Smooth
* Streaming manifests.
*/
public static final int TYPE_OTHER = 3;
private static final String TAG = "Util"; private static final String TAG = "Util";
private static final Pattern XS_DATE_TIME_PATTERN = Pattern.compile( private static final Pattern XS_DATE_TIME_PATTERN = Pattern.compile(
"(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)[Tt]" "(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)[Tt]"
@ -712,6 +691,7 @@ public final class Util {
* {@link C#ENCODING_PCM_32BIT}. If the bit depth is unsupported then * {@link C#ENCODING_PCM_32BIT}. If the bit depth is unsupported then
* {@link C#ENCODING_INVALID} is returned. * {@link C#ENCODING_INVALID} is returned.
*/ */
@C.PcmEncoding
public static int getPcmEncoding(int bitDepth) { public static int getPcmEncoding(int bitDepth) {
switch (bitDepth) { switch (bitDepth) {
case 8: case 8:
@ -731,19 +711,20 @@ public final class Util {
* Makes a best guess to infer the type from a file name. * Makes a best guess to infer the type from a file name.
* *
* @param fileName Name of the file. It can include the path of the file. * @param fileName Name of the file. It can include the path of the file.
* @return One of {@link #TYPE_DASH}, {@link #TYPE_SS}, {@link #TYPE_HLS} or {@link #TYPE_OTHER}. * @return The content type.
*/ */
@C.ContentType
public static int inferContentType(String fileName) { public static int inferContentType(String fileName) {
if (fileName == null) { if (fileName == null) {
return TYPE_OTHER; return C.TYPE_OTHER;
} else if (fileName.endsWith(".mpd")) { } else if (fileName.endsWith(".mpd")) {
return TYPE_DASH; return C.TYPE_DASH;
} else if (fileName.endsWith(".ism") || fileName.endsWith(".isml")) { } else if (fileName.endsWith(".ism") || fileName.endsWith(".isml")) {
return TYPE_SS; return C.TYPE_SS;
} else if (fileName.endsWith(".m3u8")) { } else if (fileName.endsWith(".m3u8")) {
return TYPE_HLS; return C.TYPE_HLS;
} else { } else {
return TYPE_OTHER; return C.TYPE_OTHER;
} }
} }

View File

@ -88,7 +88,8 @@ public final class FakeTrackOutput implements TrackOutput, Dumper.Dumpable {
} }
@Override @Override
public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { public void sampleMetadata(long timeUs, @C.BufferFlags int flags, int size, int offset,
byte[] encryptionKey) {
sampleTimesUs.add(timeUs); sampleTimesUs.add(timeUs);
sampleFlags.add(flags); sampleFlags.add(flags);
sampleStartOffsets.add(sampleData.length - offset - size); sampleStartOffsets.add(sampleData.length - offset - size);