From 656fc0b0ca4b2ba5269227848a5da9294d4854f5 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Wed, 3 Dec 2014 18:26:48 +0000 Subject: [PATCH] Make sure SmoothStreaming manifest durations are -1 for Live. Plus start to properly document the SmoothStreaming package. Note that where the documentation is a little vague, this is because the original SmoothStreaming documentation is equally vague! --- .../java/com/google/android/exoplayer/C.java | 5 ++ .../exoplayer/FrameworkSampleSource.java | 6 +- .../google/android/exoplayer/TrackInfo.java | 12 ++++ .../android/exoplayer/TrackRenderer.java | 4 +- .../chunk/SingleSampleChunkSource.java | 4 +- .../SmoothStreamingManifest.java | 58 +++++++++++++++++-- 6 files changed, 79 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/C.java b/library/src/main/java/com/google/android/exoplayer/C.java index f0f2a57fec..b852676bd7 100644 --- a/library/src/main/java/com/google/android/exoplayer/C.java +++ b/library/src/main/java/com/google/android/exoplayer/C.java @@ -20,6 +20,11 @@ package com.google.android.exoplayer; */ public final class C { + /** + * Represents an unknown microsecond time or duration. + */ + public static final long UNKNOWN_TIME_US = -1; + /** * Represents an unbounded length of data. */ diff --git a/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java b/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java index 0fc39b0e1a..716ef7dafb 100644 --- a/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/FrameworkSampleSource.java @@ -71,10 +71,10 @@ public final class FrameworkSampleSource implements SampleSource { trackInfos = new TrackInfo[trackStates.length]; for (int i = 0; i < trackStates.length; i++) { android.media.MediaFormat format = extractor.getTrackFormat(i); - long duration = format.containsKey(android.media.MediaFormat.KEY_DURATION) ? - format.getLong(android.media.MediaFormat.KEY_DURATION) : TrackRenderer.UNKNOWN_TIME_US; + long durationUs = format.containsKey(android.media.MediaFormat.KEY_DURATION) ? + format.getLong(android.media.MediaFormat.KEY_DURATION) : C.UNKNOWN_TIME_US; String mime = format.getString(android.media.MediaFormat.KEY_MIME); - trackInfos[i] = new TrackInfo(mime, duration); + trackInfos[i] = new TrackInfo(mime, durationUs); } prepared = true; } diff --git a/library/src/main/java/com/google/android/exoplayer/TrackInfo.java b/library/src/main/java/com/google/android/exoplayer/TrackInfo.java index e6c1b0c977..72487a0cdf 100644 --- a/library/src/main/java/com/google/android/exoplayer/TrackInfo.java +++ b/library/src/main/java/com/google/android/exoplayer/TrackInfo.java @@ -20,9 +20,21 @@ package com.google.android.exoplayer; */ public final class TrackInfo { + /** + * The mime type. + */ public final String mimeType; + + /** + * The duration in microseconds, or {@link C#UNKNOWN_TIME_US} if the duration is unknown. + */ public final long durationUs; + /** + * @param mimeType The mime type. + * @param durationUs The duration in microseconds, or {@link C#UNKNOWN_TIME_US} if the duration + * is unknown. + */ public TrackInfo(String mimeType, long durationUs) { this.mimeType = mimeType; this.durationUs = durationUs; diff --git a/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java index 66e20291f7..cf4f8f13fc 100644 --- a/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/TrackRenderer.java @@ -67,9 +67,9 @@ public abstract class TrackRenderer implements ExoPlayerComponent { protected static final int STATE_STARTED = 3; /** - * Represents an unknown time or duration. + * Represents an unknown time or duration. Equal to {@link C#UNKNOWN_TIME_US}. */ - public static final long UNKNOWN_TIME_US = -1; + public static final long UNKNOWN_TIME_US = C.UNKNOWN_TIME_US; // -1 /** * Represents a time or duration that should match the duration of the longest track whose * duration is known. diff --git a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java index ffb90eaefd..71a50241f4 100644 --- a/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java +++ b/library/src/main/java/com/google/android/exoplayer/chunk/SingleSampleChunkSource.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer.chunk; +import com.google.android.exoplayer.C; import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.TrackInfo; import com.google.android.exoplayer.upstream.DataSource; @@ -42,7 +43,8 @@ public class SingleSampleChunkSource implements ChunkSource { * @param dataSource A {@link DataSource} suitable for loading the sample data. * @param dataSpec Defines the location of the sample. * @param format The format of the sample. - * @param durationUs The duration of the sample in microseconds. + * @param durationUs The duration of the sample in microseconds, or {@link C#UNKNOWN_TIME_US} if + * the duration is unknown. * @param mediaFormat The sample media format. May be null. */ public SingleSampleChunkSource(DataSource dataSource, DataSpec dataSpec, Format format, diff --git a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java index 7b45aed9cc..8e4a0cada0 100644 --- a/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java +++ b/library/src/main/java/com/google/android/exoplayer/smoothstreaming/SmoothStreamingManifest.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer.smoothstreaming; +import com.google.android.exoplayer.C; import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Util; @@ -33,28 +34,77 @@ public class SmoothStreamingManifest { private static final long MICROS_PER_SECOND = 1000000L; + /** + * The client manifest major version. + */ public final int majorVersion; + + /** + * The client manifest minor version. + */ public final int minorVersion; - public final long timescale; + + /** + * The number of fragments in a lookahead, or -1 if the lookahead is unspecified. + */ public final int lookAheadCount; + + /** + * True if the manifest describes a live presentation still in progress. False otherwise. + */ public final boolean isLive; + + /** + * Content protection information, or null if the content is not protected. + */ public final ProtectionElement protectionElement; + + /** + * The contained stream elements. + */ public final StreamElement[] streamElements; + + /** + * The overall presentation duration of the media in microseconds, or {@link C#UNKNOWN_TIME_US} + * if the duration is unknown. + */ public final long durationUs; + + /** + * The length of the trailing window for a live broadcast in microseconds, or + * {@link C#UNKNOWN_TIME_US} if the stream is not live or if the window length is unspecified. + */ public final long dvrWindowLengthUs; + /** + * @param majorVersion The client manifest major version. + * @param minorVersion The client manifest minor version. + * @param timescale The timescale of the media as the number of units that pass in one second. + * @param duration The overall presentation duration in units of the timescale attribute, or 0 + * if the duration is unknown. + * @param dvrWindowLength The length of the trailing window in units of the timescale attribute, + * or 0 if this attribute is unspecified or not applicable. + * @param lookAheadCount The number of fragments in a lookahead, or -1 if this attribute is + * unspecified or not applicable. + * @param isLive True if the manifest describes a live presentation still in progress. False + * otherwise. + * @param protectionElement Content protection information, or null if the content is not + * protected. + * @param streamElements The contained stream elements. + */ public SmoothStreamingManifest(int majorVersion, int minorVersion, long timescale, long duration, long dvrWindowLength, int lookAheadCount, boolean isLive, ProtectionElement protectionElement, StreamElement[] streamElements) { this.majorVersion = majorVersion; this.minorVersion = minorVersion; - this.timescale = timescale; this.lookAheadCount = lookAheadCount; this.isLive = isLive; this.protectionElement = protectionElement; this.streamElements = streamElements; - dvrWindowLengthUs = Util.scaleLargeTimestamp(dvrWindowLength, MICROS_PER_SECOND, timescale); - durationUs = Util.scaleLargeTimestamp(duration, MICROS_PER_SECOND, timescale); + dvrWindowLengthUs = dvrWindowLength == 0 ? C.UNKNOWN_TIME_US + : Util.scaleLargeTimestamp(dvrWindowLength, MICROS_PER_SECOND, timescale); + durationUs = duration == 0 ? C.UNKNOWN_TIME_US + : Util.scaleLargeTimestamp(duration, MICROS_PER_SECOND, timescale); } /**