From 8833a2930c0f6a7f43dd27787b72fd6d2c866ce5 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Mon, 27 Nov 2017 01:43:34 -0800 Subject: [PATCH] Take into account the playback speed for loading Update the default AdaptiveTrackSelection and DefaultLoadControl to use playback speed information. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=176989168 --- .../exoplayer2/DefaultLoadControl.java | 5 +++++ .../AdaptiveTrackSelection.java | 22 ++++++++++++++----- .../google/android/exoplayer2/util/Util.java | 13 +++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java index bfafd409f3..d329f6584b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java @@ -172,6 +172,11 @@ public class DefaultLoadControl implements LoadControl { @Override public boolean shouldStartPlayback(long bufferedDurationUs, float playbackSpeed, boolean rebuffering) { + if (bufferedDurationUs >= minBufferUs) { + // It's possible that we're not loading, so allow playback to start unconditionally. + return true; + } + bufferedDurationUs = Util.getPlayoutDurationForMediaDuration(bufferedDurationUs, playbackSpeed); long minBufferDurationUs = rebuffering ? bufferForPlaybackAfterRebufferUs : bufferForPlaybackUs; return minBufferDurationUs <= 0 || bufferedDurationUs >= minBufferDurationUs; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java index f9eddab286..ba45b2b186 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java @@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.upstream.BandwidthMeter; +import com.google.android.exoplayer2.util.Util; import java.util.List; /** @@ -139,6 +140,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { private final float bandwidthFraction; private final float bufferedFractionToLiveEdgeForQualityIncrease; + private float playbackSpeed; private int selectedIndex; private int reason; @@ -196,10 +198,16 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { this.bandwidthFraction = bandwidthFraction; this.bufferedFractionToLiveEdgeForQualityIncrease = bufferedFractionToLiveEdgeForQualityIncrease; + playbackSpeed = 1f; selectedIndex = determineIdealSelectedIndex(Long.MIN_VALUE); reason = C.SELECTION_REASON_INITIAL; } + @Override + public void onPlaybackSpeed(float playbackSpeed) { + this.playbackSpeed = playbackSpeed; + } + @Override public void updateSelectedTrack(long playbackPositionUs, long bufferedDurationUs, long availableDurationUs) { @@ -254,8 +262,10 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { return 0; } int queueSize = queue.size(); - long bufferedDurationUs = queue.get(queueSize - 1).endTimeUs - playbackPositionUs; - if (bufferedDurationUs < minDurationToRetainAfterDiscardUs) { + long mediaBufferedDurationUs = queue.get(queueSize - 1).endTimeUs - playbackPositionUs; + long playoutBufferedDurationUs = + Util.getPlayoutDurationForMediaDuration(mediaBufferedDurationUs, playbackSpeed); + if (playoutBufferedDurationUs < minDurationToRetainAfterDiscardUs) { return queueSize; } int idealSelectedIndex = determineIdealSelectedIndex(SystemClock.elapsedRealtime()); @@ -266,8 +276,10 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { for (int i = 0; i < queueSize; i++) { MediaChunk chunk = queue.get(i); Format format = chunk.trackFormat; - long durationBeforeThisChunkUs = chunk.startTimeUs - playbackPositionUs; - if (durationBeforeThisChunkUs >= minDurationToRetainAfterDiscardUs + long mediaDurationBeforeThisChunkUs = chunk.startTimeUs - playbackPositionUs; + long playoutDurationBeforeThisChunkUs = + Util.getPlayoutDurationForMediaDuration(mediaDurationBeforeThisChunkUs, playbackSpeed); + if (playoutDurationBeforeThisChunkUs >= minDurationToRetainAfterDiscardUs && format.bitrate < idealFormat.bitrate && format.height != Format.NO_VALUE && format.height < 720 && format.width != Format.NO_VALUE && format.width < 1280 @@ -292,7 +304,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { for (int i = 0; i < length; i++) { if (nowMs == Long.MIN_VALUE || !isBlacklisted(i, nowMs)) { Format format = getFormat(i); - if (format.bitrate <= effectiveBitrate) { + if (Math.round(format.bitrate * playbackSpeed) <= effectiveBitrate) { return i; } else { lowestBitrateNonBlacklistedIndex = i; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java index b5a897dc16..881da0868f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java @@ -697,6 +697,19 @@ public final class Util { return Math.round((double) playoutDuration * speed); } + /** + * Returns the playout duration of {@code mediaDuration} of media. + * + * @param mediaDuration The duration to scale. + * @return The scaled duration, in the same units as {@code mediaDuration}. + */ + public static long getPlayoutDurationForMediaDuration(long mediaDuration, float speed) { + if (speed == 1f) { + return mediaDuration; + } + return Math.round((double) mediaDuration / speed); + } + /** * Converts a list of integers to a primitive array. *