Tweak live-streaming track selection logic.

Follow-up on the update to ABR logic in AdaptiveTrackSelection for live
streaming case:
- Do not reset liveEdgeTimeUs when user seek to a different position.
- For HlsChunkSource, for non-independent segments, currently the
bufferedDuration calculate will subtract previousChunk's duration. So to make
it work with live-streaming ABR logic, we subtract timeToLiveEdgeUs a similar
amount to compensate for that operation.
- Minor update to DefaultSSChunkSource, only perform TrackSelection when needed
(after checking necessary conditions).

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=169531275
This commit is contained in:
hoangtc 2017-03-07 05:42:33 +00:00 committed by Oliver Woodman
parent d71400d280
commit 324339b88f
3 changed files with 25 additions and 21 deletions

View File

@ -181,7 +181,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
long bufferedDurationUs = previous != null ? (previous.endTimeUs - playbackPositionUs) : 0;
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs, previous == null);
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
trackSelection.updateSelectedTrack(bufferedDurationUs, timeToLiveEdgeUs);
RepresentationHolder representationHolder =
@ -385,9 +385,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
}
private long resolveTimeToLiveEdgeUs(long playbackPositionUs, boolean isAfterPositionReset) {
boolean resolveTimeToLiveEdgePossible = manifest.dynamic
&& !isAfterPositionReset && liveEdgeTimeUs != C.TIME_UNSET;
private long resolveTimeToLiveEdgeUs(long playbackPositionUs) {
boolean resolveTimeToLiveEdgePossible = manifest.dynamic && liveEdgeTimeUs != C.TIME_UNSET;
return resolveTimeToLiveEdgePossible ? liveEdgeTimeUs - playbackPositionUs : C.TIME_UNSET;
}

View File

@ -209,14 +209,24 @@ import java.util.List;
int oldVariantIndex = previous == null ? C.INDEX_UNSET
: trackGroup.indexOf(previous.trackFormat);
expectedPlaylistUrl = null;
// Unless segments are known to be independent, switching variant will require downloading
// overlapping segments. Hence we use the start time of the previous chunk rather than its end
// time for this case.
long bufferedDurationUs = previous == null ? 0 : Math.max(0,
(independentSegments ? previous.endTimeUs : previous.startTimeUs) - playbackPositionUs);
long bufferedDurationUs = previous == null ? 0 : previous.endTimeUs - playbackPositionUs;
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
if (previous != null && !independentSegments) {
// Unless segments are known to be independent, switching variant will require downloading
// overlapping segments. Hence we will subtract previous chunk's duration from buffered
// duration.
// This may affect the live-streaming adaptive track selection logic, when we are comparing
// buffered duration to time to live edge to decide whether to switch. Therefore,
// we will subtract this same amount from timeToLiveEdgeUs as well.
long subtractedDurationUs = previous.getDurationUs();
bufferedDurationUs = Math.max(0, bufferedDurationUs - subtractedDurationUs);
if (timeToLiveEdgeUs != C.TIME_UNSET) {
timeToLiveEdgeUs = Math.max(0, timeToLiveEdgeUs - subtractedDurationUs);
}
}
// Select the variant.
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs, previous == null);
trackSelection.updateSelectedTrack(bufferedDurationUs, timeToLiveEdgeUs);
int selectedVariantIndex = trackSelection.getSelectedIndexInTrackGroup();
@ -365,9 +375,8 @@ import java.util.List;
// Private methods.
private long resolveTimeToLiveEdgeUs(long playbackPositionUs, boolean isAfterPositionReset) {
final boolean resolveTimeToLiveEdgePossible = !isAfterPositionReset
&& liveEdgeTimeUs != C.TIME_UNSET;
private long resolveTimeToLiveEdgeUs(long playbackPositionUs) {
final boolean resolveTimeToLiveEdgePossible = liveEdgeTimeUs != C.TIME_UNSET;
return resolveTimeToLiveEdgePossible ? liveEdgeTimeUs - playbackPositionUs : C.TIME_UNSET;
}

View File

@ -154,10 +154,6 @@ public class DefaultSsChunkSource implements SsChunkSource {
return;
}
long bufferedDurationUs = previous != null ? (previous.endTimeUs - playbackPositionUs) : 0;
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
trackSelection.updateSelectedTrack(bufferedDurationUs, timeToLiveEdgeUs);
StreamElement streamElement = manifest.streamElements[elementIndex];
if (streamElement.chunkCount == 0) {
// There aren't any chunks for us to load.
@ -183,6 +179,10 @@ public class DefaultSsChunkSource implements SsChunkSource {
return;
}
long bufferedDurationUs = previous != null ? (previous.endTimeUs - playbackPositionUs) : 0;
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
trackSelection.updateSelectedTrack(bufferedDurationUs, timeToLiveEdgeUs);
long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(chunkIndex);
int currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
@ -229,10 +229,6 @@ public class DefaultSsChunkSource implements SsChunkSource {
}
StreamElement currentElement = manifest.streamElements[elementIndex];
if (currentElement.chunkCount == 0) {
return C.TIME_UNSET;
}
int lastChunkIndex = currentElement.chunkCount - 1;
long lastChunkEndTimeUs = currentElement.getStartTimeUs(lastChunkIndex)
+ currentElement.getChunkDurationUs(lastChunkIndex);