Fix SmoothStreamingManifest to handle large timestamps.
This commit is contained in:
parent
c4e1c3543c
commit
4fdd68facf
@ -77,7 +77,7 @@ public class SmoothStreamingChunkSource implements ChunkSource {
|
|||||||
public SmoothStreamingChunkSource(SmoothStreamingManifest manifest, int streamElementIndex,
|
public SmoothStreamingChunkSource(SmoothStreamingManifest manifest, int streamElementIndex,
|
||||||
int[] trackIndices, DataSource dataSource, FormatEvaluator formatEvaluator) {
|
int[] trackIndices, DataSource dataSource, FormatEvaluator formatEvaluator) {
|
||||||
this.streamElement = manifest.streamElements[streamElementIndex];
|
this.streamElement = manifest.streamElements[streamElementIndex];
|
||||||
this.trackInfo = new TrackInfo(streamElement.tracks[0].mimeType, manifest.getDurationUs());
|
this.trackInfo = new TrackInfo(streamElement.tracks[0].mimeType, manifest.durationUs);
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.formatEvaluator = formatEvaluator;
|
this.formatEvaluator = formatEvaluator;
|
||||||
this.evaluation = new Evaluation();
|
this.evaluation = new Evaluation();
|
||||||
|
@ -31,6 +31,8 @@ import java.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public class SmoothStreamingManifest {
|
public class SmoothStreamingManifest {
|
||||||
|
|
||||||
|
private static final long MICROS_PER_SECOND = 1000000L;
|
||||||
|
|
||||||
public final int majorVersion;
|
public final int majorVersion;
|
||||||
public final int minorVersion;
|
public final int minorVersion;
|
||||||
public final long timescale;
|
public final long timescale;
|
||||||
@ -38,9 +40,8 @@ public class SmoothStreamingManifest {
|
|||||||
public final boolean isLive;
|
public final boolean isLive;
|
||||||
public final ProtectionElement protectionElement;
|
public final ProtectionElement protectionElement;
|
||||||
public final StreamElement[] streamElements;
|
public final StreamElement[] streamElements;
|
||||||
|
public final long durationUs;
|
||||||
private final long duration;
|
public final long dvrWindowLengthUs;
|
||||||
private final long dvrWindowLength;
|
|
||||||
|
|
||||||
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,
|
||||||
@ -48,33 +49,23 @@ public class SmoothStreamingManifest {
|
|||||||
this.majorVersion = majorVersion;
|
this.majorVersion = majorVersion;
|
||||||
this.minorVersion = minorVersion;
|
this.minorVersion = minorVersion;
|
||||||
this.timescale = timescale;
|
this.timescale = timescale;
|
||||||
this.duration = duration;
|
|
||||||
this.dvrWindowLength = dvrWindowLength;
|
|
||||||
this.lookAheadCount = lookAheadCount;
|
this.lookAheadCount = lookAheadCount;
|
||||||
this.isLive = isLive;
|
this.isLive = isLive;
|
||||||
this.protectionElement = protectionElement;
|
this.protectionElement = protectionElement;
|
||||||
this.streamElements = streamElements;
|
this.streamElements = streamElements;
|
||||||
|
if (timescale >= MICROS_PER_SECOND && (timescale % MICROS_PER_SECOND) == 0) {
|
||||||
|
long divisionFactor = timescale / MICROS_PER_SECOND;
|
||||||
|
dvrWindowLengthUs = dvrWindowLength / divisionFactor;
|
||||||
|
durationUs = duration / divisionFactor;
|
||||||
|
} else if (timescale < MICROS_PER_SECOND && (MICROS_PER_SECOND % timescale) == 0) {
|
||||||
|
long multiplicationFactor = MICROS_PER_SECOND / timescale;
|
||||||
|
dvrWindowLengthUs = dvrWindowLength * multiplicationFactor;
|
||||||
|
durationUs = duration * multiplicationFactor;
|
||||||
|
} else {
|
||||||
|
double multiplicationFactor = (double) MICROS_PER_SECOND / timescale;
|
||||||
|
dvrWindowLengthUs = (long) (dvrWindowLength * multiplicationFactor);
|
||||||
|
durationUs = (long) (duration * multiplicationFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the duration of the media.
|
|
||||||
* <p>
|
|
||||||
* For a live presentation the duration may be an approximation of the eventual final duration,
|
|
||||||
* or 0 if an approximate duration is not known.
|
|
||||||
*
|
|
||||||
* @return The duration of the media in microseconds.
|
|
||||||
*/
|
|
||||||
public long getDurationUs() {
|
|
||||||
return (duration * 1000000L) / timescale;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the DVR window length, or 0 if no window length was specified.
|
|
||||||
*
|
|
||||||
* @return The duration of the DVR window in microseconds, or 0 if no window length was specified.
|
|
||||||
*/
|
|
||||||
public long getDvrWindowLengthUs() {
|
|
||||||
return (dvrWindowLength * 1000000L) / timescale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,7 +164,8 @@ public class SmoothStreamingManifest {
|
|||||||
private final String chunkTemplate;
|
private final String chunkTemplate;
|
||||||
|
|
||||||
private final List<Long> chunkStartTimes;
|
private final List<Long> chunkStartTimes;
|
||||||
private final long lastChunkDuration;
|
private final long[] chunkStartTimesUs;
|
||||||
|
private final long lastChunkDurationUs;
|
||||||
|
|
||||||
public StreamElement(Uri baseUri, String chunkTemplate, int type, String subType,
|
public StreamElement(Uri baseUri, String chunkTemplate, int type, String subType,
|
||||||
long timescale, String name, int qualityLevels, int maxWidth, int maxHeight,
|
long timescale, String name, int qualityLevels, int maxWidth, int maxHeight,
|
||||||
@ -194,7 +186,26 @@ public class SmoothStreamingManifest {
|
|||||||
this.tracks = tracks;
|
this.tracks = tracks;
|
||||||
this.chunkCount = chunkStartTimes.size();
|
this.chunkCount = chunkStartTimes.size();
|
||||||
this.chunkStartTimes = chunkStartTimes;
|
this.chunkStartTimes = chunkStartTimes;
|
||||||
this.lastChunkDuration = lastChunkDuration;
|
chunkStartTimesUs = new long[chunkStartTimes.size()];
|
||||||
|
if (timescale >= MICROS_PER_SECOND && (timescale % MICROS_PER_SECOND) == 0) {
|
||||||
|
long divisionFactor = timescale / MICROS_PER_SECOND;
|
||||||
|
for (int i = 0; i < chunkStartTimesUs.length; i++) {
|
||||||
|
chunkStartTimesUs[i] = chunkStartTimes.get(i) / divisionFactor;
|
||||||
|
}
|
||||||
|
lastChunkDurationUs = lastChunkDuration / divisionFactor;
|
||||||
|
} else if (timescale < MICROS_PER_SECOND && (MICROS_PER_SECOND % timescale) == 0) {
|
||||||
|
long multiplicationFactor = MICROS_PER_SECOND / timescale;
|
||||||
|
for (int i = 0; i < chunkStartTimesUs.length; i++) {
|
||||||
|
chunkStartTimesUs[i] = chunkStartTimes.get(i) * multiplicationFactor;
|
||||||
|
}
|
||||||
|
lastChunkDurationUs = lastChunkDuration * multiplicationFactor;
|
||||||
|
} else {
|
||||||
|
double multiplicationFactor = (double) MICROS_PER_SECOND / timescale;
|
||||||
|
for (int i = 0; i < chunkStartTimesUs.length; i++) {
|
||||||
|
chunkStartTimesUs[i] = (long) (chunkStartTimes.get(i) * multiplicationFactor);
|
||||||
|
}
|
||||||
|
lastChunkDurationUs = (long) (lastChunkDuration * multiplicationFactor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +215,7 @@ public class SmoothStreamingManifest {
|
|||||||
* @return The index of the corresponding chunk.
|
* @return The index of the corresponding chunk.
|
||||||
*/
|
*/
|
||||||
public int getChunkIndex(long timeUs) {
|
public int getChunkIndex(long timeUs) {
|
||||||
return Util.binarySearchFloor(chunkStartTimes, (timeUs * timescale) / 1000000L, true, true);
|
return Util.binarySearchFloor(chunkStartTimesUs, timeUs, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,7 +225,7 @@ public class SmoothStreamingManifest {
|
|||||||
* @return The start time of the chunk, in microseconds.
|
* @return The start time of the chunk, in microseconds.
|
||||||
*/
|
*/
|
||||||
public long getStartTimeUs(int chunkIndex) {
|
public long getStartTimeUs(int chunkIndex) {
|
||||||
return (chunkStartTimes.get(chunkIndex) * 1000000L) / timescale;
|
return chunkStartTimesUs[chunkIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -224,9 +235,8 @@ public class SmoothStreamingManifest {
|
|||||||
* @return The duration of the chunk, in microseconds.
|
* @return The duration of the chunk, in microseconds.
|
||||||
*/
|
*/
|
||||||
public long getChunkDurationUs(int chunkIndex) {
|
public long getChunkDurationUs(int chunkIndex) {
|
||||||
long chunkDuration = (chunkIndex == chunkCount - 1) ? lastChunkDuration
|
return (chunkIndex == chunkCount - 1) ? lastChunkDurationUs
|
||||||
: chunkStartTimes.get(chunkIndex + 1) - chunkStartTimes.get(chunkIndex);
|
: chunkStartTimesUs[chunkIndex + 1] - chunkStartTimesUs[chunkIndex];
|
||||||
return chunkDuration / timescale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user