Fix DASH module API nullability issues and add package-level non-null-by-default

PiperOrigin-RevId: 262123595
This commit is contained in:
tonihei 2019-08-07 14:36:57 +01:00 committed by Oliver Woodman
parent 79e962c55a
commit 074b6f8ebd
15 changed files with 228 additions and 126 deletions

View file

@ -41,6 +41,7 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
implementation 'androidx.annotation:annotation:1.1.0'
testImplementation project(modulePrefix + 'testutils-robolectric')
}

View file

@ -60,6 +60,7 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** A DASH {@link MediaPeriod}. */
/* package */ final class DashMediaPeriod
@ -245,8 +246,12 @@ import java.util.regex.Pattern;
}
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
public long selectTracks(
@NullableType TrackSelection[] selections,
boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams,
boolean[] streamResetFlags,
long positionUs) {
int[] streamIndexToTrackGroupIndex = getStreamIndexToTrackGroupIndex(selections);
releaseDisabledStreams(selections, mayRetainStreamFlags, streams);
releaseOrphanEmbeddedStreams(selections, streams, streamIndexToTrackGroupIndex);

View file

@ -130,7 +130,7 @@ public final class DashMediaSource extends BaseMediaSource {
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/
public Factory setTag(Object tag) {
public Factory setTag(@Nullable Object tag) {
Assertions.checkState(!isCreateCalled);
this.tag = tag;
return this;
@ -430,8 +430,8 @@ public final class DashMediaSource extends BaseMediaSource {
public DashMediaSource(
DashManifest manifest,
DashChunkSource.Factory chunkSourceFactory,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifest,
chunkSourceFactory,
@ -455,8 +455,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashManifest manifest,
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifest,
/* manifestUri= */ null,
@ -492,8 +492,8 @@ public final class DashMediaSource extends BaseMediaSource {
Uri manifestUri,
DataSource.Factory manifestDataSourceFactory,
DashChunkSource.Factory chunkSourceFactory,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifestUri,
manifestDataSourceFactory,
@ -529,8 +529,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
long livePresentationDelayMs,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
manifestUri,
manifestDataSourceFactory,
@ -569,8 +569,8 @@ public final class DashMediaSource extends BaseMediaSource {
DashChunkSource.Factory chunkSourceFactory,
int minLoadableRetryCount,
long livePresentationDelayMs,
Handler eventHandler,
MediaSourceEventListener eventListener) {
@Nullable Handler eventHandler,
@Nullable MediaSourceEventListener eventListener) {
this(
/* manifest= */ null,
manifestUri,
@ -591,10 +591,10 @@ public final class DashMediaSource extends BaseMediaSource {
}
private DashMediaSource(
DashManifest manifest,
Uri manifestUri,
DataSource.Factory manifestDataSourceFactory,
ParsingLoadable.Parser<? extends DashManifest> manifestParser,
@Nullable DashManifest manifest,
@Nullable Uri manifestUri,
@Nullable DataSource.Factory manifestDataSourceFactory,
@Nullable ParsingLoadable.Parser<? extends DashManifest> manifestParser,
DashChunkSource.Factory chunkSourceFactory,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
DrmSessionManager<?> drmSessionManager,

View file

@ -66,7 +66,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable DrmInitData loadDrmInitData(DataSource dataSource, Period period)
@Nullable
public static DrmInitData loadDrmInitData(DataSource dataSource, Period period)
throws IOException, InterruptedException {
int primaryTrackType = C.TRACK_TYPE_VIDEO;
Representation representation = getFirstRepresentation(period, primaryTrackType);
@ -95,7 +96,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable Format loadSampleFormat(
@Nullable
public static Format loadSampleFormat(
DataSource dataSource, int trackType, Representation representation)
throws IOException, InterruptedException {
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
@ -116,7 +118,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
public static @Nullable ChunkIndex loadChunkIndex(
@Nullable
public static ChunkIndex loadChunkIndex(
DataSource dataSource, int trackType, Representation representation)
throws IOException, InterruptedException {
ChunkExtractorWrapper extractorWrapper = loadInitializationData(dataSource, trackType,
@ -138,7 +141,8 @@ public final class DashUtil {
* @throws IOException Thrown when there is an error while loading.
* @throws InterruptedException Thrown if the thread was interrupted.
*/
private static @Nullable ChunkExtractorWrapper loadInitializationData(
@Nullable
private static ChunkExtractorWrapper loadInitializationData(
DataSource dataSource, int trackType, Representation representation, boolean loadIndex)
throws IOException, InterruptedException {
RangedUri initializationUri = representation.getInitializationUri();
@ -187,7 +191,8 @@ public final class DashUtil {
return new ChunkExtractorWrapper(extractor, trackType, format);
}
private static @Nullable Representation getFirstRepresentation(Period period, int type) {
@Nullable
private static Representation getFirstRepresentation(Period period, int type) {
int index = period.getAdaptationSetIndex(type);
if (index == C.INDEX_UNSET) {
return null;
@ -197,5 +202,4 @@ public final class DashUtil {
}
private DashUtil() {}
}

View file

@ -67,7 +67,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
private final int maxSegmentsPerLoad;
public Factory(DataSource.Factory dataSourceFactory) {
this(dataSourceFactory, 1);
this(dataSourceFactory, /* maxSegmentsPerLoad= */ 1);
}
public Factory(DataSource.Factory dataSourceFactory, int maxSegmentsPerLoad) {
@ -633,7 +633,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
Representation representation,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
TrackOutput playerEmsgTrackOutput) {
@Nullable TrackOutput playerEmsgTrackOutput) {
this(
periodDurationUs,
representation,
@ -787,7 +787,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
Representation representation,
boolean enableEventMessageTrack,
List<Format> closedCaptionFormats,
TrackOutput playerEmsgTrackOutput) {
@Nullable TrackOutput playerEmsgTrackOutput) {
String containerMimeType = representation.format.containerMimeType;
if (mimeTypeIsRawText(containerMimeType)) {
return null;

View file

@ -80,12 +80,10 @@ public class DashManifest implements FilterableManifest<DashManifest> {
* The {@link UtcTimingElement}, or null if not present. Defined in DVB A168:7/2016, Section
* 4.7.2.
*/
public final UtcTimingElement utcTiming;
@Nullable public final UtcTimingElement utcTiming;
/**
* The location of this manifest.
*/
public final Uri location;
/** The location of this manifest, or null if not present. */
@Nullable public final Uri location;
/** The {@link ProgramInformation}, or null if not present. */
@Nullable public final ProgramInformation programInformation;
@ -106,8 +104,8 @@ public class DashManifest implements FilterableManifest<DashManifest> {
long timeShiftBufferDepthMs,
long suggestedPresentationDelayMs,
long publishTimeMs,
UtcTimingElement utcTiming,
Uri location,
@Nullable UtcTimingElement utcTiming,
@Nullable Uri location,
List<Period> periods) {
this(
availabilityStartTimeMs,
@ -134,8 +132,8 @@ public class DashManifest implements FilterableManifest<DashManifest> {
long suggestedPresentationDelayMs,
long publishTimeMs,
@Nullable ProgramInformation programInformation,
UtcTimingElement utcTiming,
Uri location,
@Nullable UtcTimingElement utcTiming,
@Nullable Uri location,
List<Period> periods) {
this.availabilityStartTimeMs = availabilityStartTimeMs;
this.durationMs = durationMs;

View file

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri;
import androidx.annotation.Nullable;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Pair;
@ -47,6 +48,7 @@ import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.xml.sax.helpers.DefaultHandler;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@ -189,9 +191,9 @@ public class DashManifestParser extends DefaultHandler
long timeShiftBufferDepthMs,
long suggestedPresentationDelayMs,
long publishTimeMs,
ProgramInformation programInformation,
UtcTimingElement utcTiming,
Uri location,
@Nullable ProgramInformation programInformation,
@Nullable UtcTimingElement utcTiming,
@Nullable Uri location,
List<Period> periods) {
return new DashManifest(
availabilityStartTime,
@ -259,8 +261,9 @@ public class DashManifestParser extends DefaultHandler
// AdaptationSet parsing.
protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
SegmentBase segmentBase) throws XmlPullParserException, IOException {
protected AdaptationSet parseAdaptationSet(
XmlPullParser xpp, String baseUrl, @Nullable SegmentBase segmentBase)
throws XmlPullParserException, IOException {
int id = parseInt(xpp, "id", AdaptationSet.ID_UNSET);
int contentType = parseContentType(xpp);
@ -394,8 +397,8 @@ public class DashManifestParser extends DefaultHandler
* @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
* Either or both may be null, depending on the ContentProtection element being parsed.
*/
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
throws XmlPullParserException, IOException {
protected Pair<@NullableType String, @NullableType SchemeData> parseContentProtection(
XmlPullParser xpp) throws XmlPullParserException, IOException {
String schemeType = null;
String licenseServerUrl = null;
byte[] data = null;
@ -477,19 +480,19 @@ public class DashManifestParser extends DefaultHandler
protected RepresentationInfo parseRepresentation(
XmlPullParser xpp,
String baseUrl,
String label,
String adaptationSetMimeType,
String adaptationSetCodecs,
@Nullable String label,
@Nullable String adaptationSetMimeType,
@Nullable String adaptationSetCodecs,
int adaptationSetWidth,
int adaptationSetHeight,
float adaptationSetFrameRate,
int adaptationSetAudioChannels,
int adaptationSetAudioSamplingRate,
String adaptationSetLanguage,
@Nullable String adaptationSetLanguage,
List<Descriptor> adaptationSetRoleDescriptors,
List<Descriptor> adaptationSetAccessibilityDescriptors,
List<Descriptor> adaptationSetSupplementalProperties,
SegmentBase segmentBase)
@Nullable SegmentBase segmentBase)
throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
@ -564,19 +567,19 @@ public class DashManifestParser extends DefaultHandler
}
protected Format buildFormat(
String id,
String label,
String containerMimeType,
@Nullable String id,
@Nullable String label,
@Nullable String containerMimeType,
int width,
int height,
float frameRate,
int audioChannels,
int audioSamplingRate,
int bitrate,
String language,
@Nullable String language,
List<Descriptor> roleDescriptors,
List<Descriptor> accessibilityDescriptors,
String codecs,
@Nullable String codecs,
List<Descriptor> supplementalProperties) {
String sampleMimeType = getSampleMimeType(containerMimeType, codecs);
@C.SelectionFlags int selectionFlags = parseSelectionFlagsFromRoleDescriptors(roleDescriptors);
@ -650,7 +653,7 @@ public class DashManifestParser extends DefaultHandler
protected Representation buildRepresentation(
RepresentationInfo representationInfo,
String extraDrmSchemeType,
@Nullable String extraDrmSchemeType,
ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format;
@ -675,7 +678,8 @@ public class DashManifestParser extends DefaultHandler
// SegmentBase, SegmentList and SegmentTemplate parsing.
protected SingleSegmentBase parseSegmentBase(XmlPullParser xpp, SingleSegmentBase parent)
protected SingleSegmentBase parseSegmentBase(
XmlPullParser xpp, @Nullable SingleSegmentBase parent)
throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
@ -711,7 +715,7 @@ public class DashManifestParser extends DefaultHandler
indexLength);
}
protected SegmentList parseSegmentList(XmlPullParser xpp, SegmentList parent)
protected SegmentList parseSegmentList(XmlPullParser xpp, @Nullable SegmentList parent)
throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
@ -756,15 +760,15 @@ public class DashManifestParser extends DefaultHandler
long presentationTimeOffset,
long startNumber,
long duration,
List<SegmentTimelineElement> timeline,
List<RangedUri> segments) {
@Nullable List<SegmentTimelineElement> timeline,
@Nullable List<RangedUri> segments) {
return new SegmentList(initialization, timescale, presentationTimeOffset,
startNumber, duration, timeline, segments);
}
protected SegmentTemplate parseSegmentTemplate(
XmlPullParser xpp,
SegmentTemplate parent,
@Nullable SegmentTemplate parent,
List<Descriptor> adaptationSetSupplementalProperties)
throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
@ -819,8 +823,8 @@ public class DashManifestParser extends DefaultHandler
long endNumber,
long duration,
List<SegmentTimelineElement> timeline,
UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate) {
@Nullable UrlTemplate initializationTemplate,
@Nullable UrlTemplate mediaTemplate) {
return new SegmentTemplate(
initialization,
timescale,
@ -1008,8 +1012,9 @@ public class DashManifestParser extends DefaultHandler
return new SegmentTimelineElement(elapsedTime, duration);
}
protected UrlTemplate parseUrlTemplate(XmlPullParser xpp, String name,
UrlTemplate defaultValue) {
@Nullable
protected UrlTemplate parseUrlTemplate(
XmlPullParser xpp, String name, @Nullable UrlTemplate defaultValue) {
String valueString = xpp.getAttributeValue(null, name);
if (valueString != null) {
return UrlTemplate.compile(valueString);
@ -1126,7 +1131,7 @@ public class DashManifestParser extends DefaultHandler
}
@C.RoleFlags
protected int parseDashRoleSchemeValue(String value) {
protected int parseDashRoleSchemeValue(@Nullable String value) {
if (value == null) {
return 0;
}
@ -1159,7 +1164,7 @@ public class DashManifestParser extends DefaultHandler
}
@C.RoleFlags
protected int parseTvaAudioPurposeCsValue(String value) {
protected int parseTvaAudioPurposeCsValue(@Nullable String value) {
if (value == null) {
return 0;
}
@ -1230,7 +1235,9 @@ public class DashManifestParser extends DefaultHandler
* @param codecs The codecs attribute.
* @return The derived sample mimeType, or null if it could not be derived.
*/
private static String getSampleMimeType(String containerMimeType, String codecs) {
@Nullable
private static String getSampleMimeType(
@Nullable String containerMimeType, @Nullable String codecs) {
if (MimeTypes.isAudio(containerMimeType)) {
return MimeTypes.getAudioMediaMimeType(codecs);
} else if (MimeTypes.isVideo(containerMimeType)) {
@ -1264,7 +1271,7 @@ public class DashManifestParser extends DefaultHandler
* @param mimeType The mimeType.
* @return Whether the mimeType is a text sample mimeType.
*/
private static boolean mimeTypeIsRawText(String mimeType) {
private static boolean mimeTypeIsRawText(@Nullable String mimeType) {
return MimeTypes.isText(mimeType)
|| MimeTypes.APPLICATION_TTML.equals(mimeType)
|| MimeTypes.APPLICATION_MP4VTT.equals(mimeType)
@ -1273,16 +1280,18 @@ public class DashManifestParser extends DefaultHandler
}
/**
* Checks two languages for consistency, returning the consistent language, or throwing an
* {@link IllegalStateException} if the languages are inconsistent.
* <p>
* Two languages are consistent if they are equal, or if one is null.
* Checks two languages for consistency, returning the consistent language, or throwing an {@link
* IllegalStateException} if the languages are inconsistent.
*
* <p>Two languages are consistent if they are equal, or if one is null.
*
* @param firstLanguage The first language.
* @param secondLanguage The second language.
* @return The consistent language.
*/
private static String checkLanguageConsistency(String firstLanguage, String secondLanguage) {
@Nullable
private static String checkLanguageConsistency(
@Nullable String firstLanguage, @Nullable String secondLanguage) {
if (firstLanguage == null) {
return secondLanguage;
} else if (secondLanguage == null) {
@ -1485,14 +1494,19 @@ public class DashManifestParser extends DefaultHandler
public final Format format;
public final String baseUrl;
public final SegmentBase segmentBase;
public final String drmSchemeType;
@Nullable public final String drmSchemeType;
public final ArrayList<SchemeData> drmSchemeDatas;
public final ArrayList<Descriptor> inbandEventStreams;
public final long revisionId;
public RepresentationInfo(Format format, String baseUrl, SegmentBase segmentBase,
String drmSchemeType, ArrayList<SchemeData> drmSchemeDatas,
ArrayList<Descriptor> inbandEventStreams, long revisionId) {
public RepresentationInfo(
Format format,
String baseUrl,
SegmentBase segmentBase,
@Nullable String drmSchemeType,
ArrayList<SchemeData> drmSchemeDatas,
ArrayList<Descriptor> inbandEventStreams,
long revisionId) {
this.format = format;
this.baseUrl = baseUrl;
this.segmentBase = segmentBase;

View file

@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Util;
@ -24,10 +23,8 @@ import com.google.android.exoplayer2.util.Util;
*/
public final class Descriptor {
/**
* The scheme URI.
*/
@NonNull public final String schemeIdUri;
/** The scheme URI. */
public final String schemeIdUri;
/**
* The value, or null.
*/
@ -42,7 +39,7 @@ public final class Descriptor {
* @param value The value, or null.
* @param id The identifier, or null.
*/
public Descriptor(@NonNull String schemeIdUri, @Nullable String value, @Nullable String id) {
public Descriptor(String schemeIdUri, @Nullable String value, @Nullable String id) {
this.schemeIdUri = schemeIdUri;
this.value = value;
this.id = id;
@ -63,10 +60,9 @@ public final class Descriptor {
@Override
public int hashCode() {
int result = (schemeIdUri != null ? schemeIdUri.hashCode() : 0);
int result = schemeIdUri.hashCode();
result = 31 * result + (value != null ? value.hashCode() : 0);
result = 31 * result + (id != null ? id.hashCode() : 0);
return result;
}
}

View file

@ -21,22 +21,26 @@ import com.google.android.exoplayer2.util.Util;
/** A parsed program information element. */
public class ProgramInformation {
/** The title for the media presentation. */
public final String title;
@Nullable public final String title;
/** Information about the original source of the media presentation. */
public final String source;
@Nullable public final String source;
/** A copyright statement for the media presentation. */
public final String copyright;
@Nullable public final String copyright;
/** A URL that provides more information about the media presentation. */
public final String moreInformationURL;
@Nullable public final String moreInformationURL;
/** Declares the language code(s) for this ProgramInformation. */
public final String lang;
@Nullable public final String lang;
public ProgramInformation(
String title, String source, String copyright, String moreInformationURL, String lang) {
@Nullable String title,
@Nullable String source,
@Nullable String copyright,
@Nullable String moreInformationURL,
@Nullable String lang) {
this.title = title;
this.source = source;
this.copyright = copyright;

View file

@ -83,7 +83,7 @@ public final class RangedUri {
* <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.
* @param baseUri The base Uri.
* @return The merged {@link RangedUri} if the merge was successful. Null otherwise.
*/
@Nullable

View file

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
@ -53,9 +54,7 @@ public abstract class Representation {
* The offset of the presentation timestamps in the media stream relative to media time.
*/
public final long presentationTimeOffsetUs;
/**
* The in-band event streams in the representation. Never null, but may be empty.
*/
/** The in-band event streams in the representation. May be empty. */
public final List<Descriptor> inbandEventStreams;
private final RangedUri initializationUri;
@ -71,7 +70,7 @@ public abstract class Representation {
*/
public static Representation newInstance(
long revisionId, Format format, String baseUrl, SegmentBase segmentBase) {
return newInstance(revisionId, format, baseUrl, segmentBase, null);
return newInstance(revisionId, format, baseUrl, segmentBase, /* inbandEventStreams= */ null);
}
/**
@ -89,8 +88,9 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
return newInstance(revisionId, format, baseUrl, segmentBase, inbandEventStreams, null);
@Nullable List<Descriptor> inbandEventStreams) {
return newInstance(
revisionId, format, baseUrl, segmentBase, inbandEventStreams, /* cacheKey= */ null);
}
/**
@ -110,8 +110,8 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams,
String cacheKey) {
@Nullable List<Descriptor> inbandEventStreams,
@Nullable String cacheKey) {
if (segmentBase instanceof SingleSegmentBase) {
return new SingleSegmentRepresentation(
revisionId,
@ -135,7 +135,7 @@ public abstract class Representation {
Format format,
String baseUrl,
SegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
@Nullable List<Descriptor> inbandEventStreams) {
this.revisionId = revisionId;
this.format = format;
this.baseUrl = baseUrl;
@ -151,6 +151,7 @@ public abstract class Representation {
* Returns a {@link RangedUri} defining the location of the representation's initialization data,
* or null if no initialization data exists.
*/
@Nullable
public RangedUri getInitializationUri() {
return initializationUri;
}
@ -159,14 +160,15 @@ public abstract class Representation {
* Returns a {@link RangedUri} defining the location of the representation's segment index, or
* null if the representation provides an index directly.
*/
@Nullable
public abstract RangedUri getIndexUri();
/**
* Returns an index if the representation provides one directly, or null otherwise.
*/
/** Returns an index if the representation provides one directly, or null otherwise. */
@Nullable
public abstract DashSegmentIndex getIndex();
/** Returns a cache key for the representation if set, or null. */
@Nullable
public abstract String getCacheKey();
/**
@ -184,9 +186,9 @@ public abstract class Representation {
*/
public final long contentLength;
private final String cacheKey;
private final RangedUri indexUri;
private final SingleSegmentIndex segmentIndex;
@Nullable private final String cacheKey;
@Nullable private final RangedUri indexUri;
@Nullable private final SingleSegmentIndex segmentIndex;
/**
* @param revisionId Identifies the revision of the content.
@ -209,7 +211,7 @@ public abstract class Representation {
long indexStart,
long indexEnd,
List<Descriptor> inbandEventStreams,
String cacheKey,
@Nullable String cacheKey,
long contentLength) {
RangedUri rangedUri = new RangedUri(null, initializationStart,
initializationEnd - initializationStart + 1);
@ -233,8 +235,8 @@ public abstract class Representation {
Format format,
String baseUrl,
SingleSegmentBase segmentBase,
List<Descriptor> inbandEventStreams,
String cacheKey,
@Nullable List<Descriptor> inbandEventStreams,
@Nullable String cacheKey,
long contentLength) {
super(revisionId, format, baseUrl, segmentBase, inbandEventStreams);
this.uri = Uri.parse(baseUrl);
@ -248,16 +250,19 @@ public abstract class Representation {
}
@Override
@Nullable
public RangedUri getIndexUri() {
return indexUri;
}
@Override
@Nullable
public DashSegmentIndex getIndex() {
return segmentIndex;
}
@Override
@Nullable
public String getCacheKey() {
return cacheKey;
}
@ -284,12 +289,13 @@ public abstract class Representation {
Format format,
String baseUrl,
MultiSegmentBase segmentBase,
List<Descriptor> inbandEventStreams) {
@Nullable List<Descriptor> inbandEventStreams) {
super(revisionId, format, baseUrl, segmentBase, inbandEventStreams);
this.segmentBase = segmentBase;
}
@Override
@Nullable
public RangedUri getIndexUri() {
return null;
}
@ -300,6 +306,7 @@ public abstract class Representation {
}
@Override
@Nullable
public String getCacheKey() {
return null;
}

View file

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
import com.google.android.exoplayer2.util.Util;
@ -25,7 +26,7 @@ import java.util.List;
*/
public abstract class SegmentBase {
/* package */ final RangedUri initialization;
/* package */ @Nullable final RangedUri initialization;
/* package */ final long timescale;
/* package */ final long presentationTimeOffset;
@ -36,7 +37,8 @@ public abstract class SegmentBase {
* @param presentationTimeOffset The presentation time offset. The value in seconds is the
* division of this value and {@code timescale}.
*/
public SegmentBase(RangedUri initialization, long timescale, long presentationTimeOffset) {
public SegmentBase(
@Nullable RangedUri initialization, long timescale, long presentationTimeOffset) {
this.initialization = initialization;
this.timescale = timescale;
this.presentationTimeOffset = presentationTimeOffset;
@ -49,6 +51,7 @@ public abstract class SegmentBase {
* @param representation The {@link Representation} for which initialization data is required.
* @return A {@link RangedUri} defining the location of the initialization data, or null.
*/
@Nullable
public RangedUri getInitialization(Representation representation) {
return initialization;
}
@ -77,19 +80,31 @@ public abstract class SegmentBase {
* @param indexStart The byte offset of the index data in the segment.
* @param indexLength The length of the index data in bytes.
*/
public SingleSegmentBase(RangedUri initialization, long timescale, long presentationTimeOffset,
long indexStart, long indexLength) {
public SingleSegmentBase(
@Nullable RangedUri initialization,
long timescale,
long presentationTimeOffset,
long indexStart,
long indexLength) {
super(initialization, timescale, presentationTimeOffset);
this.indexStart = indexStart;
this.indexLength = indexLength;
}
public SingleSegmentBase() {
this(null, 1, 0, 0, 0);
this(
/* initialization= */ null,
/* timescale= */ 1,
/* presentationTimeOffset= */ 0,
/* indexStart= */ 0,
/* indexLength= */ 0);
}
@Nullable
public RangedUri getIndex() {
return indexLength <= 0 ? null : new RangedUri(null, indexStart, indexLength);
return indexLength <= 0
? null
: new RangedUri(/* referenceUri= */ null, indexStart, indexLength);
}
}
@ -101,7 +116,7 @@ public abstract class SegmentBase {
/* package */ final long startNumber;
/* package */ final long duration;
/* package */ final List<SegmentTimelineElement> segmentTimeline;
/* package */ @Nullable final List<SegmentTimelineElement> segmentTimeline;
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
@ -118,12 +133,12 @@ public abstract class SegmentBase {
* parameter.
*/
public MultiSegmentBase(
RangedUri initialization,
@Nullable RangedUri initialization,
long timescale,
long presentationTimeOffset,
long startNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline) {
@Nullable List<SegmentTimelineElement> segmentTimeline) {
super(initialization, timescale, presentationTimeOffset);
this.startNumber = startNumber;
this.duration = duration;
@ -223,7 +238,7 @@ public abstract class SegmentBase {
*/
public static class SegmentList extends MultiSegmentBase {
/* package */ final List<RangedUri> mediaSegments;
/* package */ @Nullable final List<RangedUri> mediaSegments;
/**
* @param initialization A {@link RangedUri} corresponding to initialization data, if such data
@ -246,8 +261,8 @@ public abstract class SegmentBase {
long presentationTimeOffset,
long startNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline,
List<RangedUri> mediaSegments) {
@Nullable List<SegmentTimelineElement> segmentTimeline,
@Nullable List<RangedUri> mediaSegments) {
super(initialization, timescale, presentationTimeOffset, startNumber, duration,
segmentTimeline);
this.mediaSegments = mediaSegments;
@ -275,8 +290,8 @@ public abstract class SegmentBase {
*/
public static class SegmentTemplate extends MultiSegmentBase {
/* package */ final UrlTemplate initializationTemplate;
/* package */ final UrlTemplate mediaTemplate;
/* package */ @Nullable final UrlTemplate initializationTemplate;
/* package */ @Nullable final UrlTemplate mediaTemplate;
/* package */ final long endNumber;
/**
@ -308,9 +323,9 @@ public abstract class SegmentBase {
long startNumber,
long endNumber,
long duration,
List<SegmentTimelineElement> segmentTimeline,
UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate) {
@Nullable List<SegmentTimelineElement> segmentTimeline,
@Nullable UrlTemplate initializationTemplate,
@Nullable UrlTemplate mediaTemplate) {
super(
initialization,
timescale,
@ -324,6 +339,7 @@ public abstract class SegmentBase {
}
@Override
@Nullable
public RangedUri getInitialization(Representation representation) {
if (initializationTemplate != null) {
String urlString = initializationTemplate.buildUri(representation.format.id, 0,

View file

@ -0,0 +1,19 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.util.NonNullApi;

View file

@ -0,0 +1,19 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash.offline;
import com.google.android.exoplayer2.util.NonNullApi;

View file

@ -0,0 +1,19 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@NonNullApi
package com.google.android.exoplayer2.source.dash;
import com.google.android.exoplayer2.util.NonNullApi;