Add dependency on nullness annotations and add missing annotations for DASH.
This includes only the (hopefully) non-debatable changes for the DASH module and all needed changes for call into the core library. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=195097791
This commit is contained in:
parent
c466fabb1c
commit
7799e8fd5e
@ -2,6 +2,7 @@
|
||||
|
||||
### dev-v2 (not yet released) ###
|
||||
|
||||
* Added dependency on checkerframework annotations for static code analysis.
|
||||
* Optimize seeking in FMP4 by enabling seeking to the nearest sync sample within
|
||||
a fragment. This benefits standalone FMP4 playbacks, DASH and SmoothStreaming.
|
||||
* Moved initial bitrate estimate from `AdaptiveTrackSelection` to
|
||||
|
@ -31,6 +31,7 @@ project.ext {
|
||||
junitVersion = '4.12'
|
||||
truthVersion = '0.39'
|
||||
robolectricVersion = '3.7.1'
|
||||
checkerframeworkVersion = '2.5.0'
|
||||
modulePrefix = ':'
|
||||
if (gradle.ext.has('exoplayerModulePrefix')) {
|
||||
modulePrefix += gradle.ext.exoplayerModulePrefix
|
||||
|
@ -46,6 +46,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
|
||||
implementation 'org.checkerframework:checker-qual:' + checkerframeworkVersion
|
||||
androidTestImplementation 'com.google.dexmaker:dexmaker:' + dexmakerVersion
|
||||
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
|
||||
androidTestImplementation 'com.google.truth:truth:' + truthVersion
|
||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
@ -43,29 +44,21 @@ public final class Format implements Parcelable {
|
||||
*/
|
||||
public static final long OFFSET_SAMPLE_RELATIVE = Long.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* An identifier for the format, or null if unknown or not applicable.
|
||||
*/
|
||||
public final String id;
|
||||
/** An identifier for the format, or null if unknown or not applicable. */
|
||||
public final @Nullable String id;
|
||||
/**
|
||||
* The average bandwidth in bits per second, or {@link #NO_VALUE} if unknown or not applicable.
|
||||
*/
|
||||
public final int bitrate;
|
||||
/**
|
||||
* Codecs of the format as described in RFC 6381, or null if unknown or not applicable.
|
||||
*/
|
||||
public final String codecs;
|
||||
/**
|
||||
* Metadata, or null if unknown or not applicable.
|
||||
*/
|
||||
public final Metadata metadata;
|
||||
/** Codecs of the format as described in RFC 6381, or null if unknown or not applicable. */
|
||||
public final @Nullable String codecs;
|
||||
/** Metadata, or null if unknown or not applicable. */
|
||||
public final @Nullable Metadata metadata;
|
||||
|
||||
// Container specific.
|
||||
|
||||
/**
|
||||
* The mime type of the container, or null if unknown or not applicable.
|
||||
*/
|
||||
public final String containerMimeType;
|
||||
/** The mime type of the container, or null if unknown or not applicable. */
|
||||
public final @Nullable String containerMimeType;
|
||||
|
||||
// Elementary stream specific.
|
||||
|
||||
@ -73,7 +66,7 @@ public final class Format implements Parcelable {
|
||||
* The mime type of the elementary stream (i.e. the individual samples), or null if unknown or not
|
||||
* applicable.
|
||||
*/
|
||||
public final String sampleMimeType;
|
||||
public final @Nullable String sampleMimeType;
|
||||
/**
|
||||
* The maximum size of a buffer of data (typically one sample), or {@link #NO_VALUE} if unknown or
|
||||
* not applicable.
|
||||
@ -84,10 +77,8 @@ public final class Format implements Parcelable {
|
||||
* if initialization data is not required.
|
||||
*/
|
||||
public final List<byte[]> initializationData;
|
||||
/**
|
||||
* DRM initialization data if the stream is protected, or null otherwise.
|
||||
*/
|
||||
public final DrmInitData drmInitData;
|
||||
/** DRM initialization data if the stream is protected, or null otherwise. */
|
||||
public final @Nullable DrmInitData drmInitData;
|
||||
|
||||
// Video specific.
|
||||
|
||||
@ -117,14 +108,10 @@ public final class Format implements Parcelable {
|
||||
*/
|
||||
@C.StereoMode
|
||||
public final int stereoMode;
|
||||
/**
|
||||
* The projection data for 360/VR video, or null if not applicable.
|
||||
*/
|
||||
public final byte[] projectionData;
|
||||
/**
|
||||
* The color metadata associated with the video, helps with accurate color reproduction.
|
||||
*/
|
||||
public final ColorInfo colorInfo;
|
||||
/** The projection data for 360/VR video, or null if not applicable. */
|
||||
public final @Nullable byte[] projectionData;
|
||||
/** The color metadata associated with the video, helps with accurate color reproduction. */
|
||||
public final @Nullable ColorInfo colorInfo;
|
||||
|
||||
// Audio specific.
|
||||
|
||||
@ -171,10 +158,8 @@ public final class Format implements Parcelable {
|
||||
@C.SelectionFlags
|
||||
public final int selectionFlags;
|
||||
|
||||
/**
|
||||
* The language, or null if unknown or not applicable.
|
||||
*/
|
||||
public final String language;
|
||||
/** The language, or null if unknown or not applicable. */
|
||||
public final @Nullable String language;
|
||||
|
||||
/**
|
||||
* The Accessibility channel, or {@link #NO_VALUE} if not known or applicable.
|
||||
@ -186,36 +171,72 @@ public final class Format implements Parcelable {
|
||||
|
||||
// Video.
|
||||
|
||||
public static Format createVideoContainerFormat(String id, String containerMimeType,
|
||||
String sampleMimeType, String codecs, int bitrate, int width, int height,
|
||||
float frameRate, List<byte[]> initializationData, @C.SelectionFlags int selectionFlags) {
|
||||
public static Format createVideoContainerFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
String sampleMimeType,
|
||||
String codecs,
|
||||
int bitrate,
|
||||
int width,
|
||||
int height,
|
||||
float frameRate,
|
||||
List<byte[]> initializationData,
|
||||
@C.SelectionFlags int selectionFlags) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, width,
|
||||
height, frameRate, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, selectionFlags, null, NO_VALUE, OFFSET_SAMPLE_RELATIVE,
|
||||
initializationData, null, null);
|
||||
}
|
||||
|
||||
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int width, int height, float frameRate,
|
||||
List<byte[]> initializationData, DrmInitData drmInitData) {
|
||||
public static Format createVideoSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int width,
|
||||
int height,
|
||||
float frameRate,
|
||||
List<byte[]> initializationData,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return createVideoSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||
height, frameRate, initializationData, NO_VALUE, NO_VALUE, drmInitData);
|
||||
}
|
||||
|
||||
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int width, int height, float frameRate,
|
||||
List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio,
|
||||
DrmInitData drmInitData) {
|
||||
public static Format createVideoSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int width,
|
||||
int height,
|
||||
float frameRate,
|
||||
List<byte[]> initializationData,
|
||||
int rotationDegrees,
|
||||
float pixelWidthHeightRatio,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return createVideoSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||
height, frameRate, initializationData, rotationDegrees, pixelWidthHeightRatio, null,
|
||||
NO_VALUE, null, drmInitData);
|
||||
}
|
||||
|
||||
public static Format createVideoSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int width, int height, float frameRate,
|
||||
List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio,
|
||||
byte[] projectionData, @C.StereoMode int stereoMode, ColorInfo colorInfo,
|
||||
DrmInitData drmInitData) {
|
||||
public static Format createVideoSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int width,
|
||||
int height,
|
||||
float frameRate,
|
||||
List<byte[]> initializationData,
|
||||
int rotationDegrees,
|
||||
float pixelWidthHeightRatio,
|
||||
byte[] projectionData,
|
||||
@C.StereoMode int stereoMode,
|
||||
@Nullable ColorInfo colorInfo,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, width, height,
|
||||
frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
||||
colorInfo, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, 0, null, NO_VALUE,
|
||||
@ -224,37 +245,73 @@ public final class Format implements Parcelable {
|
||||
|
||||
// Audio.
|
||||
|
||||
public static Format createAudioContainerFormat(String id, String containerMimeType,
|
||||
String sampleMimeType, String codecs, int bitrate, int channelCount, int sampleRate,
|
||||
List<byte[]> initializationData, @C.SelectionFlags int selectionFlags, String language) {
|
||||
public static Format createAudioContainerFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int channelCount,
|
||||
int sampleRate,
|
||||
List<byte[]> initializationData,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, channelCount, sampleRate,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE,
|
||||
initializationData, null, null);
|
||||
}
|
||||
|
||||
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int channelCount, int sampleRate,
|
||||
List<byte[]> initializationData, DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags, String language) {
|
||||
public static Format createAudioSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int channelCount,
|
||||
int sampleRate,
|
||||
List<byte[]> initializationData,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount,
|
||||
sampleRate, NO_VALUE, initializationData, drmInitData, selectionFlags, language);
|
||||
}
|
||||
|
||||
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int channelCount, int sampleRate,
|
||||
@C.PcmEncoding int pcmEncoding, List<byte[]> initializationData, DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags, String language) {
|
||||
public static Format createAudioSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int channelCount,
|
||||
int sampleRate,
|
||||
@C.PcmEncoding int pcmEncoding,
|
||||
List<byte[]> initializationData,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return createAudioSampleFormat(id, sampleMimeType, codecs, bitrate, maxInputSize, channelCount,
|
||||
sampleRate, pcmEncoding, NO_VALUE, NO_VALUE, initializationData, drmInitData,
|
||||
selectionFlags, language, null);
|
||||
}
|
||||
|
||||
public static Format createAudioSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int channelCount, int sampleRate,
|
||||
@C.PcmEncoding int pcmEncoding, int encoderDelay, int encoderPadding,
|
||||
List<byte[]> initializationData, DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags, String language, Metadata metadata) {
|
||||
public static Format createAudioSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int channelCount,
|
||||
int sampleRate,
|
||||
@C.PcmEncoding int pcmEncoding,
|
||||
int encoderDelay,
|
||||
int encoderPadding,
|
||||
List<byte[]> initializationData,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
@Nullable Metadata metadata) {
|
||||
return new Format(id, null, sampleMimeType, codecs, bitrate, maxInputSize, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, channelCount, sampleRate, pcmEncoding,
|
||||
encoderDelay, encoderPadding, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE,
|
||||
@ -263,50 +320,87 @@ public final class Format implements Parcelable {
|
||||
|
||||
// Text.
|
||||
|
||||
public static Format createTextContainerFormat(String id, String containerMimeType,
|
||||
String sampleMimeType, String codecs, int bitrate, @C.SelectionFlags int selectionFlags,
|
||||
String language) {
|
||||
public static Format createTextContainerFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return createTextContainerFormat(id, containerMimeType, sampleMimeType, codecs, bitrate,
|
||||
selectionFlags, language, NO_VALUE);
|
||||
}
|
||||
|
||||
public static Format createTextContainerFormat(String id, String containerMimeType,
|
||||
String sampleMimeType, String codecs, int bitrate, @C.SelectionFlags int selectionFlags,
|
||||
String language, int accessibilityChannel) {
|
||||
public static Format createTextContainerFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
int accessibilityChannel) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, selectionFlags, language, accessibilityChannel,
|
||||
OFFSET_SAMPLE_RELATIVE, null, null, null);
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(String id, String sampleMimeType,
|
||||
@C.SelectionFlags int selectionFlags, String language) {
|
||||
public static Format createTextSampleFormat(
|
||||
@Nullable String id,
|
||||
String sampleMimeType,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return createTextSampleFormat(id, sampleMimeType, selectionFlags, language, null);
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(String id, String sampleMimeType,
|
||||
@C.SelectionFlags int selectionFlags, String language, DrmInitData drmInitData) {
|
||||
public static Format createTextSampleFormat(
|
||||
@Nullable String id,
|
||||
String sampleMimeType,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return createTextSampleFormat(id, sampleMimeType, null, NO_VALUE, selectionFlags, language,
|
||||
NO_VALUE, drmInitData, OFFSET_SAMPLE_RELATIVE, Collections.<byte[]>emptyList());
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, @C.SelectionFlags int selectionFlags, String language, int accessibilityChannel,
|
||||
DrmInitData drmInitData) {
|
||||
public static Format createTextSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
int accessibilityChannel,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return createTextSampleFormat(id, sampleMimeType, codecs, bitrate, selectionFlags, language,
|
||||
accessibilityChannel, drmInitData, OFFSET_SAMPLE_RELATIVE, Collections.<byte[]>emptyList());
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, @C.SelectionFlags int selectionFlags, String language, DrmInitData drmInitData,
|
||||
public static Format createTextSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
long subsampleOffsetUs) {
|
||||
return createTextSampleFormat(id, sampleMimeType, codecs, bitrate, selectionFlags, language,
|
||||
NO_VALUE, drmInitData, subsampleOffsetUs, Collections.<byte[]>emptyList());
|
||||
}
|
||||
|
||||
public static Format createTextSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, @C.SelectionFlags int selectionFlags, String language,
|
||||
int accessibilityChannel, DrmInitData drmInitData, long subsampleOffsetUs,
|
||||
public static Format createTextSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
int accessibilityChannel,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
long subsampleOffsetUs,
|
||||
List<byte[]> initializationData) {
|
||||
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
@ -317,14 +411,14 @@ public final class Format implements Parcelable {
|
||||
// Image.
|
||||
|
||||
public static Format createImageSampleFormat(
|
||||
String id,
|
||||
String sampleMimeType,
|
||||
String codecs,
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
List<byte[]> initializationData,
|
||||
String language,
|
||||
DrmInitData drmInitData) {
|
||||
@Nullable String language,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return new Format(
|
||||
id,
|
||||
null,
|
||||
@ -356,36 +450,65 @@ public final class Format implements Parcelable {
|
||||
|
||||
// Generic.
|
||||
|
||||
public static Format createContainerFormat(String id, String containerMimeType,
|
||||
String sampleMimeType, String codecs, int bitrate, @C.SelectionFlags int selectionFlags,
|
||||
String language) {
|
||||
public static Format createContainerFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, selectionFlags, language, NO_VALUE, OFFSET_SAMPLE_RELATIVE, null, null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static Format createSampleFormat(String id, String sampleMimeType,
|
||||
long subsampleOffsetUs) {
|
||||
public static Format createSampleFormat(
|
||||
@Nullable String id, @Nullable String sampleMimeType, long subsampleOffsetUs) {
|
||||
return new Format(id, null, sampleMimeType, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, 0, null, NO_VALUE, subsampleOffsetUs, null, null, null);
|
||||
}
|
||||
|
||||
public static Format createSampleFormat(String id, String sampleMimeType, String codecs,
|
||||
int bitrate, DrmInitData drmInitData) {
|
||||
public static Format createSampleFormat(
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
@Nullable DrmInitData drmInitData) {
|
||||
return new Format(id, null, sampleMimeType, codecs, bitrate, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, NO_VALUE, NO_VALUE, null, NO_VALUE, null, NO_VALUE, NO_VALUE, NO_VALUE, NO_VALUE,
|
||||
NO_VALUE, 0, null, NO_VALUE, OFFSET_SAMPLE_RELATIVE, null, drmInitData, null);
|
||||
}
|
||||
|
||||
/* package */ Format(String id, String containerMimeType, String sampleMimeType, String codecs,
|
||||
int bitrate, int maxInputSize, int width, int height, float frameRate, int rotationDegrees,
|
||||
float pixelWidthHeightRatio, byte[] projectionData, @C.StereoMode int stereoMode,
|
||||
ColorInfo colorInfo, int channelCount, int sampleRate, @C.PcmEncoding int pcmEncoding,
|
||||
int encoderDelay, int encoderPadding, @C.SelectionFlags int selectionFlags, String language,
|
||||
int accessibilityChannel, long subsampleOffsetUs, List<byte[]> initializationData,
|
||||
DrmInitData drmInitData, Metadata metadata) {
|
||||
/* package */ Format(
|
||||
@Nullable String id,
|
||||
@Nullable String containerMimeType,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int maxInputSize,
|
||||
int width,
|
||||
int height,
|
||||
float frameRate,
|
||||
int rotationDegrees,
|
||||
float pixelWidthHeightRatio,
|
||||
@Nullable byte[] projectionData,
|
||||
@C.StereoMode int stereoMode,
|
||||
@Nullable ColorInfo colorInfo,
|
||||
int channelCount,
|
||||
int sampleRate,
|
||||
@C.PcmEncoding int pcmEncoding,
|
||||
int encoderDelay,
|
||||
int encoderPadding,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
@Nullable String language,
|
||||
int accessibilityChannel,
|
||||
long subsampleOffsetUs,
|
||||
@Nullable List<byte[]> initializationData,
|
||||
@Nullable DrmInitData drmInitData,
|
||||
@Nullable Metadata metadata) {
|
||||
this.id = id;
|
||||
this.containerMimeType = containerMimeType;
|
||||
this.sampleMimeType = sampleMimeType;
|
||||
@ -468,14 +591,14 @@ public final class Format implements Parcelable {
|
||||
}
|
||||
|
||||
public Format copyWithContainerInfo(
|
||||
String id,
|
||||
String sampleMimeType,
|
||||
String codecs,
|
||||
@Nullable String id,
|
||||
@Nullable String sampleMimeType,
|
||||
@Nullable String codecs,
|
||||
int bitrate,
|
||||
int width,
|
||||
int height,
|
||||
@C.SelectionFlags int selectionFlags,
|
||||
String language) {
|
||||
@Nullable String language) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||
height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
||||
colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
|
||||
@ -512,7 +635,7 @@ public final class Format implements Parcelable {
|
||||
drmInitData, metadata);
|
||||
}
|
||||
|
||||
public Format copyWithDrmInitData(DrmInitData drmInitData) {
|
||||
public Format copyWithDrmInitData(@Nullable DrmInitData drmInitData) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||
height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
||||
colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
|
||||
@ -520,7 +643,7 @@ public final class Format implements Parcelable {
|
||||
drmInitData, metadata);
|
||||
}
|
||||
|
||||
public Format copyWithMetadata(Metadata metadata) {
|
||||
public Format copyWithMetadata(@Nullable Metadata metadata) {
|
||||
return new Format(id, containerMimeType, sampleMimeType, codecs, bitrate, maxInputSize, width,
|
||||
height, frameRate, rotationDegrees, pixelWidthHeightRatio, projectionData, stereoMode,
|
||||
colorInfo, channelCount, sampleRate, pcmEncoding, encoderDelay, encoderPadding,
|
||||
@ -574,7 +697,7 @@ public final class Format implements Parcelable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
@ -121,11 +121,11 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
|
||||
// Workarounds.
|
||||
@Flags private final int flags;
|
||||
private final Track sideloadedTrack;
|
||||
private final @Nullable Track sideloadedTrack;
|
||||
|
||||
// Sideloaded data.
|
||||
private final List<Format> closedCaptionFormats;
|
||||
private final DrmInitData sideloadedDrmInitData;
|
||||
private final @Nullable DrmInitData sideloadedDrmInitData;
|
||||
|
||||
// Track-linked data bundle, accessible as a whole through trackID.
|
||||
private final SparseArray<TrackBundle> trackBundles;
|
||||
@ -136,7 +136,7 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
private final ParsableByteArray nalBuffer;
|
||||
|
||||
// Adjusts sample timestamps.
|
||||
private final TimestampAdjuster timestampAdjuster;
|
||||
private final @Nullable TimestampAdjuster timestampAdjuster;
|
||||
|
||||
// Parser state.
|
||||
private final ParsableByteArray atomHeader;
|
||||
@ -185,20 +185,23 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
* @param flags Flags that control the extractor's behavior.
|
||||
* @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed.
|
||||
*/
|
||||
public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster) {
|
||||
public FragmentedMp4Extractor(@Flags int flags, @Nullable TimestampAdjuster timestampAdjuster) {
|
||||
this(flags, timestampAdjuster, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flags Flags that control the extractor's behavior.
|
||||
* @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor
|
||||
* will not receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor will not
|
||||
* receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedDrmInitData The {@link DrmInitData} to use for encrypted tracks. If null, the
|
||||
* pssh boxes (if present) will be used.
|
||||
*/
|
||||
public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster,
|
||||
Track sideloadedTrack, DrmInitData sideloadedDrmInitData) {
|
||||
public FragmentedMp4Extractor(
|
||||
@Flags int flags,
|
||||
@Nullable TimestampAdjuster timestampAdjuster,
|
||||
@Nullable Track sideloadedTrack,
|
||||
@Nullable DrmInitData sideloadedDrmInitData) {
|
||||
this(flags, timestampAdjuster, sideloadedTrack, sideloadedDrmInitData,
|
||||
Collections.<Format>emptyList());
|
||||
}
|
||||
@ -206,15 +209,19 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
/**
|
||||
* @param flags Flags that control the extractor's behavior.
|
||||
* @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor
|
||||
* will not receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor will not
|
||||
* receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedDrmInitData The {@link DrmInitData} to use for encrypted tracks. If null, the
|
||||
* pssh boxes (if present) will be used.
|
||||
* @param closedCaptionFormats For tracks that contain SEI messages, the formats of the closed
|
||||
* caption channels to expose.
|
||||
*/
|
||||
public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster,
|
||||
Track sideloadedTrack, DrmInitData sideloadedDrmInitData, List<Format> closedCaptionFormats) {
|
||||
public FragmentedMp4Extractor(
|
||||
@Flags int flags,
|
||||
@Nullable TimestampAdjuster timestampAdjuster,
|
||||
@Nullable Track sideloadedTrack,
|
||||
@Nullable DrmInitData sideloadedDrmInitData,
|
||||
List<Format> closedCaptionFormats) {
|
||||
this(flags, timestampAdjuster, sideloadedTrack, sideloadedDrmInitData,
|
||||
closedCaptionFormats, null);
|
||||
}
|
||||
@ -222,8 +229,8 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
/**
|
||||
* @param flags Flags that control the extractor's behavior.
|
||||
* @param timestampAdjuster Adjusts sample timestamps. May be null if no adjustment is needed.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor
|
||||
* will not receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedTrack Sideloaded track information, in the case that the extractor will not
|
||||
* receive a moov box in the input data. Null if a moov box is expected.
|
||||
* @param sideloadedDrmInitData The {@link DrmInitData} to use for encrypted tracks. If null, the
|
||||
* pssh boxes (if present) will be used.
|
||||
* @param closedCaptionFormats For tracks that contain SEI messages, the formats of the closed
|
||||
@ -232,8 +239,12 @@ public final class FragmentedMp4Extractor implements Extractor {
|
||||
* targeting the player, even if {@link #FLAG_ENABLE_EMSG_TRACK} is not set. Null if special
|
||||
* handling of emsg messages for players is not required.
|
||||
*/
|
||||
public FragmentedMp4Extractor(@Flags int flags, TimestampAdjuster timestampAdjuster,
|
||||
Track sideloadedTrack, DrmInitData sideloadedDrmInitData, List<Format> closedCaptionFormats,
|
||||
public FragmentedMp4Extractor(
|
||||
@Flags int flags,
|
||||
@Nullable TimestampAdjuster timestampAdjuster,
|
||||
@Nullable Track sideloadedTrack,
|
||||
@Nullable DrmInitData sideloadedDrmInitData,
|
||||
List<Format> closedCaptionFormats,
|
||||
@Nullable TrackOutput additionalEmsgTrackOutput) {
|
||||
this.flags = flags | (sideloadedTrack != null ? FLAG_SIDELOADED : 0);
|
||||
this.timestampAdjuster = timestampAdjuster;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.mp4;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -36,7 +37,7 @@ public final class PsshAtomUtil {
|
||||
* @param data The scheme specific data.
|
||||
* @return The PSSH atom.
|
||||
*/
|
||||
public static byte[] buildPsshAtom(UUID systemId, byte[] data) {
|
||||
public static byte[] buildPsshAtom(UUID systemId, @Nullable byte[] data) {
|
||||
return buildPsshAtom(systemId, null, data);
|
||||
}
|
||||
|
||||
@ -48,7 +49,8 @@ public final class PsshAtomUtil {
|
||||
* @param data The scheme specific data.
|
||||
* @return The PSSH atom.
|
||||
*/
|
||||
public static byte[] buildPsshAtom(UUID systemId, UUID[] keyIds, byte[] data) {
|
||||
public static byte[] buildPsshAtom(
|
||||
UUID systemId, @Nullable UUID[] keyIds, @Nullable byte[] data) {
|
||||
boolean buildV1Atom = keyIds != null;
|
||||
int dataLength = data != null ? data.length : 0;
|
||||
int psshBoxLength = Atom.FULL_HEADER_SIZE + 16 /* SystemId */ + 4 /* DataSize */ + dataLength;
|
||||
@ -77,14 +79,14 @@ public final class PsshAtomUtil {
|
||||
|
||||
/**
|
||||
* Parses the UUID from a PSSH atom. Version 0 and 1 PSSH atoms are supported.
|
||||
* <p>
|
||||
* The UUID is only parsed if the data is a valid PSSH atom.
|
||||
*
|
||||
* <p>The UUID is only parsed if the data is a valid PSSH atom.
|
||||
*
|
||||
* @param atom The atom to parse.
|
||||
* @return The parsed UUID. Null if the input is not a valid PSSH atom, or if the PSSH atom has
|
||||
* an unsupported version.
|
||||
* @return The parsed UUID. Null if the input is not a valid PSSH atom, or if the PSSH atom has an
|
||||
* unsupported version.
|
||||
*/
|
||||
public static UUID parseUuid(byte[] atom) {
|
||||
public static @Nullable UUID parseUuid(byte[] atom) {
|
||||
PsshAtom parsedAtom = parsePsshAtom(atom);
|
||||
if (parsedAtom == null) {
|
||||
return null;
|
||||
@ -111,8 +113,8 @@ public final class PsshAtomUtil {
|
||||
|
||||
/**
|
||||
* Parses the scheme specific data from a PSSH atom. Version 0 and 1 PSSH atoms are supported.
|
||||
* <p>
|
||||
* The scheme specific data is only parsed if the data is a valid PSSH atom matching the given
|
||||
*
|
||||
* <p>The scheme specific data is only parsed if the data is a valid PSSH atom matching the given
|
||||
* UUID, or if the data is a valid PSSH atom of any type in the case that the passed UUID is null.
|
||||
*
|
||||
* @param atom The atom to parse.
|
||||
@ -120,7 +122,7 @@ public final class PsshAtomUtil {
|
||||
* @return The parsed scheme specific data. Null if the input is not a valid PSSH atom, or if the
|
||||
* PSSH atom has an unsupported version, or if the PSSH atom does not match the passed UUID.
|
||||
*/
|
||||
public static byte[] parseSchemeSpecificData(byte[] atom, UUID uuid) {
|
||||
public static @Nullable byte[] parseSchemeSpecificData(byte[] atom, UUID uuid) {
|
||||
PsshAtom parsedAtom = parsePsshAtom(atom);
|
||||
if (parsedAtom == null) {
|
||||
return null;
|
||||
@ -140,7 +142,7 @@ public final class PsshAtomUtil {
|
||||
* has an unsupported version.
|
||||
*/
|
||||
// TODO: Support parsing of the key ids for version 1 PSSH atoms.
|
||||
private static PsshAtom parsePsshAtom(byte[] atom) {
|
||||
private static @Nullable PsshAtom parsePsshAtom(byte[] atom) {
|
||||
ParsableByteArray atomData = new ParsableByteArray(atom);
|
||||
if (atomData.limit() < Atom.FULL_HEADER_SIZE + 16 /* UUID */ + 4 /* DataSize */) {
|
||||
// Data too short.
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.chunk;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
@ -51,7 +52,7 @@ public abstract class Chunk implements Loadable {
|
||||
* Optional data associated with the selection of the track to which this chunk belongs. Null if
|
||||
* the chunk does not belong to a track.
|
||||
*/
|
||||
public final Object trackSelectionData;
|
||||
public final @Nullable Object trackSelectionData;
|
||||
/**
|
||||
* The start time of the media contained by the chunk, or {@link C#TIME_UNSET} if the data
|
||||
* being loaded does not contain media samples.
|
||||
@ -75,8 +76,15 @@ public abstract class Chunk implements Loadable {
|
||||
* @param startTimeUs See {@link #startTimeUs}.
|
||||
* @param endTimeUs See {@link #endTimeUs}.
|
||||
*/
|
||||
public Chunk(DataSource dataSource, DataSpec dataSpec, int type, Format trackFormat,
|
||||
int trackSelectionReason, Object trackSelectionData, long startTimeUs, long endTimeUs) {
|
||||
public Chunk(
|
||||
DataSource dataSource,
|
||||
DataSpec dataSpec,
|
||||
int type,
|
||||
Format trackFormat,
|
||||
int trackSelectionReason,
|
||||
@Nullable Object trackSelectionData,
|
||||
long startTimeUs,
|
||||
long endTimeUs) {
|
||||
this.dataSource = Assertions.checkNotNull(dataSource);
|
||||
this.dataSpec = Assertions.checkNotNull(dataSpec);
|
||||
this.type = type;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.chunk;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||
@ -44,8 +45,12 @@ public final class InitializationChunk extends Chunk {
|
||||
* @param trackSelectionData See {@link #trackSelectionData}.
|
||||
* @param extractorWrapper A wrapped extractor to use for parsing the initialization data.
|
||||
*/
|
||||
public InitializationChunk(DataSource dataSource, DataSpec dataSpec, Format trackFormat,
|
||||
int trackSelectionReason, Object trackSelectionData,
|
||||
public InitializationChunk(
|
||||
DataSource dataSource,
|
||||
DataSpec dataSpec,
|
||||
Format trackFormat,
|
||||
int trackSelectionReason,
|
||||
@Nullable Object trackSelectionData,
|
||||
ChunkExtractorWrapper extractorWrapper) {
|
||||
super(dataSource, dataSpec, C.DATA_TYPE_MEDIA_INITIALIZATION, trackFormat, trackSelectionReason,
|
||||
trackSelectionData, C.TIME_UNSET, C.TIME_UNSET);
|
||||
|
@ -16,8 +16,10 @@
|
||||
package com.google.android.exoplayer2.util;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||
|
||||
/**
|
||||
* Provides methods for asserting the truth of expressions and properties.
|
||||
@ -102,7 +104,8 @@ public final class Assertions {
|
||||
* @return The non-null reference that was validated.
|
||||
* @throws NullPointerException If {@code reference} is null.
|
||||
*/
|
||||
public static <T> T checkNotNull(T reference) {
|
||||
@EnsuresNonNull({"#1"})
|
||||
public static <T> T checkNotNull(@Nullable T reference) {
|
||||
if (ExoPlayerLibraryInfo.ASSERTIONS_ENABLED && reference == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
@ -119,7 +122,8 @@ public final class Assertions {
|
||||
* @return The non-null reference that was validated.
|
||||
* @throws NullPointerException If {@code reference} is null.
|
||||
*/
|
||||
public static <T> T checkNotNull(T reference, Object errorMessage) {
|
||||
@EnsuresNonNull({"#1"})
|
||||
public static <T> T checkNotNull(@Nullable T reference, Object errorMessage) {
|
||||
if (ExoPlayerLibraryInfo.ASSERTIONS_ENABLED && reference == null) {
|
||||
throw new NullPointerException(String.valueOf(errorMessage));
|
||||
}
|
||||
@ -133,7 +137,8 @@ public final class Assertions {
|
||||
* @return The non-null, non-empty string that was validated.
|
||||
* @throws IllegalArgumentException If {@code string} is null or 0-length.
|
||||
*/
|
||||
public static String checkNotEmpty(String string) {
|
||||
@EnsuresNonNull({"#1"})
|
||||
public static String checkNotEmpty(@Nullable String string) {
|
||||
if (ExoPlayerLibraryInfo.ASSERTIONS_ENABLED && TextUtils.isEmpty(string)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@ -149,7 +154,8 @@ public final class Assertions {
|
||||
* @return The non-null, non-empty string that was validated.
|
||||
* @throws IllegalArgumentException If {@code string} is null or 0-length.
|
||||
*/
|
||||
public static String checkNotEmpty(String string, Object errorMessage) {
|
||||
@EnsuresNonNull({"#1"})
|
||||
public static String checkNotEmpty(@Nullable String string, Object errorMessage) {
|
||||
if (ExoPlayerLibraryInfo.ASSERTIONS_ENABLED && TextUtils.isEmpty(string)) {
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
}
|
||||
|
@ -134,14 +134,13 @@ public final class MimeTypes {
|
||||
return BASE_TYPE_APPLICATION.equals(getTopLevelType(mimeType));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Derives a video sample mimeType from a codecs attribute.
|
||||
*
|
||||
* @param codecs The codecs attribute.
|
||||
* @return The derived video mimeType, or null if it could not be derived.
|
||||
*/
|
||||
public static String getVideoMediaMimeType(String codecs) {
|
||||
public static @Nullable String getVideoMediaMimeType(@Nullable String codecs) {
|
||||
if (codecs == null) {
|
||||
return null;
|
||||
}
|
||||
@ -161,7 +160,7 @@ public final class MimeTypes {
|
||||
* @param codecs The codecs attribute.
|
||||
* @return The derived audio mimeType, or null if it could not be derived.
|
||||
*/
|
||||
public static String getAudioMediaMimeType(String codecs) {
|
||||
public static @Nullable String getAudioMediaMimeType(@Nullable String codecs) {
|
||||
if (codecs == null) {
|
||||
return null;
|
||||
}
|
||||
@ -181,7 +180,7 @@ public final class MimeTypes {
|
||||
* @param codec The codec identifier to derive.
|
||||
* @return The mimeType, or null if it could not be derived.
|
||||
*/
|
||||
public static String getMediaMimeType(String codec) {
|
||||
public static @Nullable String getMediaMimeType(@Nullable String codec) {
|
||||
if (codec == null) {
|
||||
return null;
|
||||
}
|
||||
@ -345,7 +344,7 @@ public final class MimeTypes {
|
||||
* @param mimeType The mimeType whose top-level type is required.
|
||||
* @return The top-level type, or null if the mimeType is null.
|
||||
*/
|
||||
private static String getTopLevelType(String mimeType) {
|
||||
private static @Nullable String getTopLevelType(@Nullable String mimeType) {
|
||||
if (mimeType == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
@ -190,7 +191,7 @@ public final class Util {
|
||||
* @param o2 The second object.
|
||||
* @return {@code o1 == null ? o2 == null : o1.equals(o2)}.
|
||||
*/
|
||||
public static boolean areEqual(Object o1, Object o2) {
|
||||
public static boolean areEqual(@Nullable Object o1, @Nullable Object o2) {
|
||||
return o1 == null ? o2 == null : o1.equals(o2);
|
||||
}
|
||||
|
||||
@ -224,6 +225,20 @@ public final class Util {
|
||||
list.subList(fromIndex, toIndex).clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies and optionally truncates an array. Prevents null array elements created by {@link
|
||||
* Arrays#copyOf(Object[], int)} by ensuring the new length does not exceed the current length.
|
||||
*
|
||||
* @param input The input array.
|
||||
* @param length The output array length. Must be less or equal to the length of the input array.
|
||||
* @return The copied array.
|
||||
*/
|
||||
@SuppressWarnings("nullness:assignment.type.incompatible")
|
||||
public static <T> T[] nullSafeArrayCopy(T[] input, int length) {
|
||||
Assertions.checkArgument(length <= input.length);
|
||||
return Arrays.copyOf(input, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new single threaded executor whose thread has the specified name.
|
||||
*
|
||||
|
@ -34,6 +34,8 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation project(modulePrefix + 'library-core')
|
||||
implementation 'org.checkerframework:checker-qual:' + checkerframeworkVersion
|
||||
implementation 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
|
||||
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
|
||||
testImplementation project(modulePrefix + 'testutils-robolectric')
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.source.dash;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
@ -65,7 +66,7 @@ public final class DashUtil {
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
|
||||
public static @Nullable DrmInitData loadDrmInitData(DataSource dataSource, Period period)
|
||||
throws IOException, InterruptedException {
|
||||
int primaryTrackType = C.TRACK_TYPE_VIDEO;
|
||||
Representation representation = getFirstRepresentation(period, primaryTrackType);
|
||||
@ -87,15 +88,16 @@ public final class DashUtil {
|
||||
* Loads initialization data for the {@code representation} and returns the sample {@link Format}.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param trackType The type of the representation. Typically one of the {@link
|
||||
* com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @return the sample {@link Format} of the given representation.
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
public static Format loadSampleFormat(DataSource dataSource, int trackType,
|
||||
Representation representation) throws IOException, InterruptedException {
|
||||
public static @Nullable Format loadSampleFormat(
|
||||
DataSource dataSource, int trackType, Representation representation)
|
||||
throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
|
||||
representation, false);
|
||||
return extractorWrapper == null ? null : extractorWrapper.getSampleFormats()[0];
|
||||
@ -106,28 +108,29 @@ public final class DashUtil {
|
||||
* ChunkIndex}.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param trackType The type of the representation. Typically one of the {@link
|
||||
* com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @return The {@link ChunkIndex} of the given representation, or null if no initialization or
|
||||
* index data exists.
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
public static ChunkIndex loadChunkIndex(DataSource dataSource, int trackType,
|
||||
Representation representation) throws IOException, InterruptedException {
|
||||
public static @Nullable ChunkIndex loadChunkIndex(
|
||||
DataSource dataSource, int trackType, Representation representation)
|
||||
throws IOException, InterruptedException {
|
||||
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
|
||||
representation, true);
|
||||
return extractorWrapper == null ? null : (ChunkIndex) extractorWrapper.getSeekMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads initialization data for the {@code representation} and optionally index data then
|
||||
* returns a {@link ChunkExtractorWrapper} which contains the output.
|
||||
* Loads initialization data for the {@code representation} and optionally index data then returns
|
||||
* a {@link ChunkExtractorWrapper} which contains the output.
|
||||
*
|
||||
* @param dataSource The source from which the data should be loaded.
|
||||
* @param trackType The type of the representation. Typically one of the
|
||||
* {@link com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param trackType The type of the representation. Typically one of the {@link
|
||||
* com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
|
||||
* @param representation The representation which initialization chunk belongs to.
|
||||
* @param loadIndex Whether to load index data too.
|
||||
* @return A {@link ChunkExtractorWrapper} for the {@code representation}, or null if no
|
||||
@ -135,8 +138,9 @@ public final class DashUtil {
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
* @throws InterruptedException Thrown if the thread was interrupted.
|
||||
*/
|
||||
private static ChunkExtractorWrapper loadInitializationData(DataSource dataSource, int trackType,
|
||||
Representation representation, boolean loadIndex) throws IOException, InterruptedException {
|
||||
private static @Nullable ChunkExtractorWrapper loadInitializationData(
|
||||
DataSource dataSource, int trackType, Representation representation, boolean loadIndex)
|
||||
throws IOException, InterruptedException {
|
||||
RangedUri initializationUri = representation.getInitializationUri();
|
||||
if (initializationUri == null) {
|
||||
return null;
|
||||
@ -181,7 +185,7 @@ public final class DashUtil {
|
||||
return new ChunkExtractorWrapper(extractor, trackType, format);
|
||||
}
|
||||
|
||||
private static Representation getFirstRepresentation(Period period, int type) {
|
||||
private static @Nullable Representation getFirstRepresentation(Period period, int type) {
|
||||
int index = period.getAdaptationSetIndex(type);
|
||||
if (index == C.INDEX_UNSET) {
|
||||
return null;
|
||||
|
@ -45,8 +45,10 @@ import java.io.IOException;
|
||||
|
||||
EventSampleStream(EventStream eventStream, Format upstreamFormat, boolean eventStreamUpdatable) {
|
||||
this.upstreamFormat = upstreamFormat;
|
||||
this.eventStream = eventStream;
|
||||
eventMessageEncoder = new EventMessageEncoder();
|
||||
pendingSeekPositionUs = C.TIME_UNSET;
|
||||
eventTimesUs = eventStream.presentationTimesUs;
|
||||
updateEventStream(eventStream, eventStreamUpdatable);
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||
* messages that generate DASH media source events.
|
||||
* @param allocator An {@link Allocator} from which allocations can be obtained.
|
||||
*/
|
||||
@SuppressWarnings("nullness")
|
||||
public PlayerEmsgHandler(
|
||||
DashManifest manifest, PlayerEmsgCallback playerEmsgCallback, Allocator allocator) {
|
||||
this.manifest = manifest;
|
||||
@ -237,11 +238,10 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||
// Internal methods.
|
||||
|
||||
private void handleManifestExpiredMessage(long eventTimeUs, long manifestPublishTimeMsInEmsg) {
|
||||
if (!manifestPublishTimeToExpiryTimeUs.containsKey(manifestPublishTimeMsInEmsg)) {
|
||||
Long previousExpiryTimeUs = manifestPublishTimeToExpiryTimeUs.get(manifestPublishTimeMsInEmsg);
|
||||
if (previousExpiryTimeUs == null) {
|
||||
manifestPublishTimeToExpiryTimeUs.put(manifestPublishTimeMsInEmsg, eventTimeUs);
|
||||
} else {
|
||||
long previousExpiryTimeUs =
|
||||
manifestPublishTimeToExpiryTimeUs.get(manifestPublishTimeMsInEmsg);
|
||||
if (previousExpiryTimeUs > eventTimeUs) {
|
||||
manifestPublishTimeToExpiryTimeUs.put(manifestPublishTimeMsInEmsg, eventTimeUs);
|
||||
}
|
||||
@ -253,10 +253,7 @@ public final class PlayerEmsgHandler implements Handler.Callback {
|
||||
notifySourceMediaPresentationEnded();
|
||||
}
|
||||
|
||||
private Map.Entry<Long, Long> ceilingExpiryEntryForPublishTime(long publishTimeMs) {
|
||||
if (manifestPublishTimeToExpiryTimeUs.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
private @Nullable Map.Entry<Long, Long> ceilingExpiryEntryForPublishTime(long publishTimeMs) {
|
||||
return manifestPublishTimeToExpiryTimeUs.ceilingEntry(publishTimeMs);
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ public final class Descriptor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.source.dash.manifest;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.util.UriUtil;
|
||||
|
||||
@ -46,7 +47,7 @@ public final class RangedUri {
|
||||
* @param length The length of the range, or {@link C#LENGTH_UNSET} to indicate that the range is
|
||||
* unbounded.
|
||||
*/
|
||||
public RangedUri(String referenceUri, long start, long length) {
|
||||
public RangedUri(@Nullable String referenceUri, long start, long length) {
|
||||
this.referenceUri = referenceUri == null ? "" : referenceUri;
|
||||
this.start = start;
|
||||
this.length = length;
|
||||
@ -74,18 +75,18 @@ public final class RangedUri {
|
||||
|
||||
/**
|
||||
* Attempts to merge this {@link RangedUri} with another and an optional common base uri.
|
||||
* <p>
|
||||
* A merge is successful if both instances define the same {@link Uri} after resolution with the
|
||||
* base uri, and if one starts the byte after the other ends, forming a contiguous region with
|
||||
*
|
||||
* <p>A merge is successful if both instances define the same {@link Uri} after resolution with
|
||||
* the base uri, and if one starts the byte after the other ends, forming a contiguous region with
|
||||
* no overlap.
|
||||
* <p>
|
||||
* If {@code other} is null then the merge is considered unsuccessful, and null is returned.
|
||||
*
|
||||
* <p>If {@code other} is null then the merge is considered unsuccessful, and null is returned.
|
||||
*
|
||||
* @param other The {@link RangedUri} to merge.
|
||||
* @param baseUri The optional base Uri.
|
||||
* @return The merged {@link RangedUri} if the merge was successful. Null otherwise.
|
||||
*/
|
||||
public RangedUri attemptMerge(RangedUri other, String baseUri) {
|
||||
public @Nullable RangedUri attemptMerge(@Nullable RangedUri other, String baseUri) {
|
||||
final String resolvedUri = resolveUriString(baseUri);
|
||||
if (other == null || !resolvedUri.equals(other.resolveUriString(baseUri))) {
|
||||
return null;
|
||||
@ -113,7 +114,7 @@ public final class RangedUri {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.dash.manifest;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Uniquely identifies a {@link Representation} in a {@link DashManifest}.
|
||||
@ -81,7 +82,7 @@ public final class RepresentationKey implements Parcelable, Comparable<Represent
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ public final class DashDownloader extends SegmentDownloader<DashManifest, Repres
|
||||
out.add(new Segment(startTimeUs, dataSpec));
|
||||
}
|
||||
|
||||
private static DashSegmentIndex getSegmentIndex(
|
||||
private static @Nullable DashSegmentIndex getSegmentIndex(
|
||||
DataSource dataSource, int trackType, Representation representation)
|
||||
throws IOException, InterruptedException {
|
||||
DashSegmentIndex index = representation.getIndex();
|
||||
|
Loading…
x
Reference in New Issue
Block a user