Fix SmoothStreaming Timeline

There were a few things wrong. Specifically the case in
the ref'd issue. Also, the timeline was being marked as
non-dynamic in the empty-but-live case (it should be
marked dynamic as segments may be added later).

Issue: #2760

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157103727
This commit is contained in:
olly 2017-05-25 06:52:39 -07:00 committed by Oliver Woodman
parent 22137f6215
commit 67cb7d8da5

View file

@ -287,39 +287,41 @@ public final class SsMediaSource implements MediaSource,
for (int i = 0; i < mediaPeriods.size(); i++) {
mediaPeriods.get(i).updateManifest(manifest);
}
long startTimeUs = Long.MAX_VALUE;
long endTimeUs = Long.MIN_VALUE;
for (StreamElement element : manifest.streamElements) {
if (element.chunkCount > 0) {
startTimeUs = Math.min(startTimeUs, element.getStartTimeUs(0));
endTimeUs = Math.max(endTimeUs, element.getStartTimeUs(element.chunkCount - 1)
+ element.getChunkDurationUs(element.chunkCount - 1));
}
}
Timeline timeline;
if (manifest.isLive) {
long startTimeUs = Long.MAX_VALUE;
long endTimeUs = Long.MIN_VALUE;
for (int i = 0; i < manifest.streamElements.length; i++) {
StreamElement element = manifest.streamElements[i];
if (element.chunkCount > 0) {
startTimeUs = Math.min(startTimeUs, element.getStartTimeUs(0));
endTimeUs = Math.max(endTimeUs, element.getStartTimeUs(element.chunkCount - 1)
+ element.getChunkDurationUs(element.chunkCount - 1));
}
if (startTimeUs == Long.MAX_VALUE) {
long periodDurationUs = manifest.isLive ? C.TIME_UNSET : 0;
timeline = new SinglePeriodTimeline(periodDurationUs, 0, 0, 0, true /* isSeekable */,
manifest.isLive /* isDynamic */);
} else if (manifest.isLive) {
if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) {
startTimeUs = Math.max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
}
if (startTimeUs == Long.MAX_VALUE) {
timeline = new SinglePeriodTimeline(C.TIME_UNSET, false);
} else {
if (manifest.dvrWindowLengthUs != C.TIME_UNSET
&& manifest.dvrWindowLengthUs > 0) {
startTimeUs = Math.max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
}
long durationUs = endTimeUs - startTimeUs;
long defaultStartPositionUs = durationUs - C.msToUs(livePresentationDelayMs);
if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
// The default start position is too close to the start of the live window. Set it to the
// minimum default start position provided the window is at least twice as big. Else set
// it to the middle of the window.
defaultStartPositionUs = Math.min(MIN_LIVE_DEFAULT_START_POSITION_US, durationUs / 2);
}
timeline = new SinglePeriodTimeline(C.TIME_UNSET, durationUs, startTimeUs,
defaultStartPositionUs, true /* isSeekable */, true /* isDynamic */);
long durationUs = endTimeUs - startTimeUs;
long defaultStartPositionUs = durationUs - C.msToUs(livePresentationDelayMs);
if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
// The default start position is too close to the start of the live window. Set it to the
// minimum default start position provided the window is at least twice as big. Else set
// it to the middle of the window.
defaultStartPositionUs = Math.min(MIN_LIVE_DEFAULT_START_POSITION_US, durationUs / 2);
}
timeline = new SinglePeriodTimeline(C.TIME_UNSET, durationUs, startTimeUs,
defaultStartPositionUs, true /* isSeekable */, true /* isDynamic */);
} else {
boolean isSeekable = manifest.durationUs != C.TIME_UNSET;
timeline = new SinglePeriodTimeline(manifest.durationUs, isSeekable);
long durationUs = manifest.durationUs != C.TIME_UNSET ? manifest.durationUs
: endTimeUs - startTimeUs;
timeline = new SinglePeriodTimeline(startTimeUs + durationUs, durationUs, startTimeUs, 0,
true /* isSeekable */, false /* isDynamic */);
}
sourceListener.onSourceInfoRefreshed(timeline, manifest);
}