Use @IntDef where possible.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=133932812
This commit is contained in:
parent
e20d7034c7
commit
1546da899b
@ -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: {
|
||||||
|
@ -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 ->
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user