Expose ability to get adjusted seek position from MediaPeriod

Issue: #2882

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=178606133
This commit is contained in:
olly 2017-12-11 05:31:54 -08:00 committed by Oliver Woodman
parent 8c7fe8a258
commit 2e3667eeff
12 changed files with 104 additions and 8 deletions

View File

@ -660,10 +660,18 @@ import java.io.IOException;
periodPositionUs = 0; periodPositionUs = 0;
} }
try { try {
if (periodId.equals(playbackInfo.periodId) if (periodId.equals(playbackInfo.periodId)) {
&& ((periodPositionUs / 1000) == (playbackInfo.positionUs / 1000))) { long adjustedPeriodPositionUs = periodPositionUs;
// Seek position equals the current position. Do nothing. if (playingPeriodHolder != null) {
return; adjustedPeriodPositionUs =
playingPeriodHolder.mediaPeriod.getAdjustedSeekPositionUs(
adjustedPeriodPositionUs, SeekParameters.DEFAULT);
}
if ((adjustedPeriodPositionUs / 1000) == (playbackInfo.positionUs / 1000)) {
// Seek will be performed to the current position. Do nothing.
periodPositionUs = playbackInfo.positionUs;
return;
}
} }
long newPeriodPositionUs = seekToPeriodPosition(periodId, periodPositionUs); long newPeriodPositionUs = seekToPeriodPosition(periodId, periodPositionUs);
seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs; seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs;

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -170,6 +171,12 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
return seekUs - startUs; return seekUs - startUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return mediaPeriod.getAdjustedSeekPositionUs(
positionUs + startUs, adjustSeekParameters(positionUs + startUs, seekParameters));
}
@Override @Override
public long getNextLoadPositionUs() { public long getNextLoadPositionUs() {
long nextLoadPositionUs = mediaPeriod.getNextLoadPositionUs(); long nextLoadPositionUs = mediaPeriod.getNextLoadPositionUs();
@ -202,6 +209,20 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
return pendingInitialDiscontinuityPositionUs != C.TIME_UNSET; return pendingInitialDiscontinuityPositionUs != C.TIME_UNSET;
} }
private SeekParameters adjustSeekParameters(long positionUs, SeekParameters seekParameters) {
long toleranceBeforeMs = Math.min(positionUs - startUs, seekParameters.toleranceBeforeUs);
long toleranceAfterMs =
endUs == C.TIME_END_OF_SOURCE
? seekParameters.toleranceAfterUs
: Math.min(endUs - positionUs, seekParameters.toleranceAfterUs);
if (toleranceBeforeMs == seekParameters.toleranceBeforeUs
&& toleranceAfterMs == seekParameters.toleranceAfterUs) {
return seekParameters;
} else {
return new SeekParameters(toleranceBeforeMs, toleranceAfterMs);
}
}
private static boolean shouldKeepInitialDiscontinuity(long startUs, TrackSelection[] selections) { private static boolean shouldKeepInitialDiscontinuity(long startUs, TrackSelection[] selections) {
// If the clipping start position is non-zero, the clipping sample streams will adjust // If the clipping start position is non-zero, the clipping sample streams will adjust
// timestamps on buffers they read from the unclipped sample streams. These adjusted buffer // timestamps on buffers they read from the unclipped sample streams. These adjusted buffer

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
@ -114,6 +115,11 @@ public final class DeferredMediaPeriod implements MediaPeriod, MediaPeriod.Callb
return mediaPeriod.seekToUs(positionUs); return mediaPeriod.seekToUs(positionUs);
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return mediaPeriod.getAdjustedSeekPositionUs(positionUs, seekParameters);
}
@Override @Override
public long getNextLoadPositionUs() { public long getNextLoadPositionUs() {
return mediaPeriod.getNextLoadPositionUs(); return mediaPeriod.getNextLoadPositionUs();

View File

@ -21,6 +21,7 @@ import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.extractor.DefaultExtractorInput; import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
@ -369,6 +370,12 @@ import java.util.Arrays;
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
// Treat all seeks into non-seekable media as being to t=0.
return seekMap.isSeekable() ? positionUs : 0;
}
// SampleStream methods. // SampleStream methods.
/* package */ boolean isReady(int track) { /* package */ boolean isReady(int track) {

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import java.io.IOException; import java.io.IOException;
@ -149,6 +150,19 @@ public interface MediaPeriod extends SequenceableLoader {
*/ */
long seekToUs(long positionUs); long seekToUs(long positionUs);
/**
* Returns the position to which a seek will be performed, given the specified seek position and
* {@link SeekParameters}.
*
* <p>This method should only be called after the period has been prepared.
*
* @param positionUs The seek position in microseconds.
* @param seekParameters Parameters that control how the seek is performed. Implementations may
* apply seek parameters on a best effort basis.
* @return The actual position to which a seek will be performed, in microseconds.
*/
long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters);
// SequenceableLoader interface. Overridden to provide more specific documentation. // SequenceableLoader interface. Overridden to provide more specific documentation.
/** /**

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
@ -192,6 +193,11 @@ import java.util.IdentityHashMap;
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return enabledPeriods[0].getAdjustedSeekPositionUs(positionUs, seekParameters);
}
// MediaPeriod.Callback implementation // MediaPeriod.Callback implementation
@Override @Override

View File

@ -20,6 +20,7 @@ import android.os.Handler;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.source.SingleSampleMediaSource.EventListener; import com.google.android.exoplayer2.source.SingleSampleMediaSource.EventListener;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
@ -153,11 +154,16 @@ import java.util.Arrays;
@Override @Override
public long seekToUs(long positionUs) { public long seekToUs(long positionUs) {
for (int i = 0; i < sampleStreams.size(); i++) { for (int i = 0; i < sampleStreams.size(); i++) {
sampleStreams.get(i).seekToUs(positionUs); sampleStreams.get(i).reset();
} }
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
}
// Loader.Callback implementation. // Loader.Callback implementation.
@Override @Override
@ -208,7 +214,7 @@ import java.util.Arrays;
private int streamState; private int streamState;
public void seekToUs(long positionUs) { public void reset() {
if (streamState == STREAM_STATE_END_OF_STREAM) { if (streamState == STREAM_STATE_END_OF_STREAM) {
streamState = STREAM_STATE_SEND_SAMPLE; streamState = STREAM_STATE_SEND_SAMPLE;
} }

View File

@ -20,6 +20,7 @@ import android.util.Pair;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.EmptySampleStream; import com.google.android.exoplayer2.source.EmptySampleStream;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
@ -306,6 +307,11 @@ import java.util.Map;
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
}
// SequenceableLoader.Callback implementation. // SequenceableLoader.Callback implementation.
@Override @Override

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.hls;
import android.os.Handler; import android.os.Handler;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
@ -244,6 +245,11 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
}
// HlsSampleStreamWrapper.Callback implementation. // HlsSampleStreamWrapper.Callback implementation.
@Override @Override

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.smoothstreaming;
import android.util.Base64; import android.util.Base64;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox; import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
@ -182,6 +183,11 @@ import java.util.ArrayList;
return positionUs; return positionUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
}
// SequenceableLoader.Callback implementation // SequenceableLoader.Callback implementation
@Override @Override

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.testutil;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
@ -176,6 +177,11 @@ public class FakeMediaPeriod implements MediaPeriod {
return positionUs + seekOffsetUs; return positionUs + seekOffsetUs;
} }
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
}
@Override @Override
public long getNextLoadPositionUs() { public long getNextLoadPositionUs() {
Assert.assertTrue(prepared); Assert.assertTrue(prepared);

View File

@ -422,8 +422,12 @@ public class FakeSimpleExoPlayer extends SimpleExoPlayer {
SampleStream[] sampleStreams = new SampleStream[renderers.length]; SampleStream[] sampleStreams = new SampleStream[renderers.length];
boolean[] mayRetainStreamFlags = new boolean[renderers.length]; boolean[] mayRetainStreamFlags = new boolean[renderers.length];
Arrays.fill(mayRetainStreamFlags, true); Arrays.fill(mayRetainStreamFlags, true);
mediaPeriod.selectTracks(selectorResult.selections.getAll(), mayRetainStreamFlags, mediaPeriod.selectTracks(
sampleStreams, new boolean[renderers.length], 0); selectorResult.selections.getAll(),
mayRetainStreamFlags,
sampleStreams,
new boolean[renderers.length],
/* positionUs = */ 0);
eventListenerHandler.post(new Runnable() { eventListenerHandler.post(new Runnable() {
@Override @Override
public void run() { public void run() {