Commit 656fc0b0 by Oliver Woodman

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!
parent 165562d8
...@@ -21,6 +21,11 @@ package com.google.android.exoplayer; ...@@ -21,6 +21,11 @@ package com.google.android.exoplayer;
public final class C { 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. * Represents an unbounded length of data.
*/ */
public static final int LENGTH_UNBOUNDED = -1; public static final int LENGTH_UNBOUNDED = -1;
......
...@@ -71,10 +71,10 @@ public final class FrameworkSampleSource implements SampleSource { ...@@ -71,10 +71,10 @@ public final class FrameworkSampleSource implements SampleSource {
trackInfos = new TrackInfo[trackStates.length]; trackInfos = new TrackInfo[trackStates.length];
for (int i = 0; i < trackStates.length; i++) { for (int i = 0; i < trackStates.length; i++) {
android.media.MediaFormat format = extractor.getTrackFormat(i); android.media.MediaFormat format = extractor.getTrackFormat(i);
long duration = format.containsKey(android.media.MediaFormat.KEY_DURATION) ? long durationUs = format.containsKey(android.media.MediaFormat.KEY_DURATION) ?
format.getLong(android.media.MediaFormat.KEY_DURATION) : TrackRenderer.UNKNOWN_TIME_US; format.getLong(android.media.MediaFormat.KEY_DURATION) : C.UNKNOWN_TIME_US;
String mime = format.getString(android.media.MediaFormat.KEY_MIME); String mime = format.getString(android.media.MediaFormat.KEY_MIME);
trackInfos[i] = new TrackInfo(mime, duration); trackInfos[i] = new TrackInfo(mime, durationUs);
} }
prepared = true; prepared = true;
} }
......
...@@ -20,9 +20,21 @@ package com.google.android.exoplayer; ...@@ -20,9 +20,21 @@ package com.google.android.exoplayer;
*/ */
public final class TrackInfo { public final class TrackInfo {
/**
* The mime type.
*/
public final String mimeType; public final String mimeType;
/**
* The duration in microseconds, or {@link C#UNKNOWN_TIME_US} if the duration is unknown.
*/
public final long durationUs; 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) { public TrackInfo(String mimeType, long durationUs) {
this.mimeType = mimeType; this.mimeType = mimeType;
this.durationUs = durationUs; this.durationUs = durationUs;
......
...@@ -67,9 +67,9 @@ public abstract class TrackRenderer implements ExoPlayerComponent { ...@@ -67,9 +67,9 @@ public abstract class TrackRenderer implements ExoPlayerComponent {
protected static final int STATE_STARTED = 3; 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 * Represents a time or duration that should match the duration of the longest track whose
* duration is known. * duration is known.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer.chunk; package com.google.android.exoplayer.chunk;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.MediaFormat; import com.google.android.exoplayer.MediaFormat;
import com.google.android.exoplayer.TrackInfo; import com.google.android.exoplayer.TrackInfo;
import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSource;
...@@ -42,7 +43,8 @@ public class SingleSampleChunkSource implements ChunkSource { ...@@ -42,7 +43,8 @@ public class SingleSampleChunkSource implements ChunkSource {
* @param dataSource A {@link DataSource} suitable for loading the sample data. * @param dataSource A {@link DataSource} suitable for loading the sample data.
* @param dataSpec Defines the location of the sample. * @param dataSpec Defines the location of the sample.
* @param format The format 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. * @param mediaFormat The sample media format. May be null.
*/ */
public SingleSampleChunkSource(DataSource dataSource, DataSpec dataSpec, Format format, public SingleSampleChunkSource(DataSource dataSource, DataSpec dataSpec, Format format,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer.smoothstreaming; 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.Assertions;
import com.google.android.exoplayer.util.Util; import com.google.android.exoplayer.util.Util;
...@@ -33,28 +34,77 @@ public class SmoothStreamingManifest { ...@@ -33,28 +34,77 @@ public class SmoothStreamingManifest {
private static final long MICROS_PER_SECOND = 1000000L; private static final long MICROS_PER_SECOND = 1000000L;
/**
* The client manifest major version.
*/
public final int majorVersion; public final int majorVersion;
/**
* The client manifest minor version.
*/
public final int minorVersion; 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; public final int lookAheadCount;
/**
* True if the manifest describes a live presentation still in progress. False otherwise.
*/
public final boolean isLive; public final boolean isLive;
/**
* Content protection information, or null if the content is not protected.
*/
public final ProtectionElement protectionElement; public final ProtectionElement protectionElement;
/**
* The contained stream elements.
*/
public final StreamElement[] streamElements; 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; 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; 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, public SmoothStreamingManifest(int majorVersion, int minorVersion, long timescale, long duration,
long dvrWindowLength, int lookAheadCount, boolean isLive, ProtectionElement protectionElement, long dvrWindowLength, int lookAheadCount, boolean isLive, ProtectionElement protectionElement,
StreamElement[] streamElements) { StreamElement[] streamElements) {
this.majorVersion = majorVersion; this.majorVersion = majorVersion;
this.minorVersion = minorVersion; this.minorVersion = minorVersion;
this.timescale = timescale;
this.lookAheadCount = lookAheadCount; this.lookAheadCount = lookAheadCount;
this.isLive = isLive; this.isLive = isLive;
this.protectionElement = protectionElement; this.protectionElement = protectionElement;
this.streamElements = streamElements; this.streamElements = streamElements;
dvrWindowLengthUs = Util.scaleLargeTimestamp(dvrWindowLength, MICROS_PER_SECOND, timescale); dvrWindowLengthUs = dvrWindowLength == 0 ? C.UNKNOWN_TIME_US
durationUs = Util.scaleLargeTimestamp(duration, MICROS_PER_SECOND, timescale); : Util.scaleLargeTimestamp(dvrWindowLength, MICROS_PER_SECOND, timescale);
durationUs = duration == 0 ? C.UNKNOWN_TIME_US
: Util.scaleLargeTimestamp(duration, MICROS_PER_SECOND, timescale);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment