mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
Have seekTo return new position directly.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=125476407
This commit is contained in:
parent
e71cdb1bad
commit
f9fa54cd5d
8 changed files with 64 additions and 89 deletions
|
|
@ -377,8 +377,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
TraceUtil.beginSection("doSomeWork");
|
||||
|
||||
if (enabledRenderers.length > 0) {
|
||||
// Process reset if there is one, else update the position.
|
||||
if (!checkForSourceResetInternal()) {
|
||||
// Process a source discontinuity if there is one, else update the position.
|
||||
if (!checkForSourceDiscontinuityInternal()) {
|
||||
updatePositionUs();
|
||||
sampleSource = timeline.getSampleSource();
|
||||
}
|
||||
|
|
@ -442,21 +442,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
}
|
||||
}
|
||||
|
||||
private void seekToInternal(int sourceIndex, long positionMs) throws ExoPlaybackException {
|
||||
private void seekToInternal(int sourceIndex, long seekPositionMs) throws ExoPlaybackException {
|
||||
try {
|
||||
if (positionMs == (positionUs / 1000)) {
|
||||
if (seekPositionMs == (positionUs / 1000)) {
|
||||
// Seek is to the current position. Do nothing.
|
||||
return;
|
||||
}
|
||||
|
||||
long seekPositionUs = seekPositionMs * 1000;
|
||||
rebuffering = false;
|
||||
positionUs = positionMs * 1000;
|
||||
internalPositionUs = sourceOffsetUs + positionUs;
|
||||
standaloneMediaClock.stop();
|
||||
standaloneMediaClock.setPositionUs(internalPositionUs);
|
||||
sampleSource = timeline.seekTo(sourceIndex, positionUs);
|
||||
|
||||
sampleSource = timeline.seekToSource(sourceIndex);
|
||||
if (sampleSource == null) {
|
||||
// The source isn't prepared.
|
||||
setNewSourcePositionInternal(seekPositionUs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -464,9 +464,10 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
for (TrackRenderer renderer : enabledRenderers) {
|
||||
ensureStopped(renderer);
|
||||
}
|
||||
checkForSourceResetInternal();
|
||||
seekPositionUs = sampleSource.seekToUs(seekPositionUs);
|
||||
}
|
||||
|
||||
setNewSourcePositionInternal(seekPositionUs);
|
||||
resumeInternal();
|
||||
} finally {
|
||||
pendingSeekCount.decrementAndGet();
|
||||
|
|
@ -496,17 +497,22 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
|
||||
}
|
||||
|
||||
private boolean checkForSourceResetInternal() throws ExoPlaybackException {
|
||||
long resetPositionUs = sampleSource.readReset();
|
||||
if (resetPositionUs == C.UNSET_TIME_US) {
|
||||
private boolean checkForSourceDiscontinuityInternal() throws ExoPlaybackException {
|
||||
long newSourcePositionUs = sampleSource.readDiscontinuity();
|
||||
if (newSourcePositionUs == C.UNSET_TIME_US) {
|
||||
return false;
|
||||
}
|
||||
internalPositionUs = sourceOffsetUs + resetPositionUs;
|
||||
setNewSourcePositionInternal(newSourcePositionUs);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setNewSourcePositionInternal(long sourcePositionUs) throws ExoPlaybackException {
|
||||
positionUs = sourcePositionUs;
|
||||
internalPositionUs = sourceOffsetUs + sourcePositionUs;
|
||||
standaloneMediaClock.setPositionUs(internalPositionUs);
|
||||
for (TrackRenderer renderer : enabledRenderers) {
|
||||
renderer.reset(internalPositionUs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void stopInternal() {
|
||||
|
|
@ -672,8 +678,6 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
playingSourceEndPositionUs = C.UNSET_TIME_US;
|
||||
} else if (playingSource.nextSource != null && playingSource.nextSource.prepared) {
|
||||
readingSource = playingSource.nextSource;
|
||||
// Suppress reading a reset so that the transition can be seamless.
|
||||
readingSource.sampleSource.readReset();
|
||||
// Replace enabled renderers' TrackStreams if they will continue to be enabled when the
|
||||
// new source starts playing, so that the transition can be seamless.
|
||||
TrackSelectionArray newTrackSelections = readingSource.trackSelections;
|
||||
|
|
@ -711,7 +715,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
return playingSource.sampleSource;
|
||||
}
|
||||
|
||||
public SampleSource seekTo(int sourceIndex, long sourcePositionUs) throws ExoPlaybackException {
|
||||
public SampleSource seekToSource(int sourceIndex) throws ExoPlaybackException {
|
||||
// Clear the timeline, but keep the requested source if it is already prepared.
|
||||
Source source = playingSource;
|
||||
Source newPlayingSource = null;
|
||||
|
|
@ -729,10 +733,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
setPlayingSource(newPlayingSource, sourceOffsetUs);
|
||||
bufferingSource = playingSource;
|
||||
bufferingSourceOffsetUs = sourceOffsetUs;
|
||||
if (playingSource.hasEnabledTracks) {
|
||||
sampleSource.seekToUs(sourcePositionUs);
|
||||
}
|
||||
} else {
|
||||
// TODO[REFACTOR]: Presumably we need to disable the renderers somewhere in here?
|
||||
playingSource = null;
|
||||
readingSource = null;
|
||||
bufferingSource = null;
|
||||
|
|
|
|||
|
|
@ -124,17 +124,14 @@ public final class MultiSampleSource implements SampleSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
long resetPositionUs = C.UNSET_TIME_US;
|
||||
public long readDiscontinuity() {
|
||||
for (SampleSource source : enabledSources) {
|
||||
long childResetPositionUs = source.readReset();
|
||||
if (resetPositionUs == C.UNSET_TIME_US) {
|
||||
resetPositionUs = childResetPositionUs;
|
||||
} else if (childResetPositionUs != C.UNSET_TIME_US) {
|
||||
resetPositionUs = Math.min(resetPositionUs, childResetPositionUs);
|
||||
if (source.readDiscontinuity() != C.UNSET_TIME_US) {
|
||||
// Children are not allowed to report discontinuities.
|
||||
throw new IllegalStateException("Child reported discontinuity");
|
||||
}
|
||||
}
|
||||
return resetPositionUs;
|
||||
return C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -150,10 +147,15 @@ public final class MultiSampleSource implements SampleSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
for (SampleSource source : enabledSources) {
|
||||
source.seekToUs(positionUs);
|
||||
public long seekToUs(long positionUs) {
|
||||
positionUs = enabledSources[0].seekToUs(positionUs);
|
||||
for (int i = 1; i < enabledSources.length; i++) {
|
||||
// Additional sources must seek to the same position.
|
||||
if (enabledSources[i].seekToUs(positionUs) != positionUs) {
|
||||
throw new IllegalStateException("Children seeked to different positions");
|
||||
}
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -88,12 +88,15 @@ public interface SampleSource {
|
|||
void continueBuffering(long positionUs);
|
||||
|
||||
/**
|
||||
* Attempts to read a pending reset.
|
||||
* Attempts to read a discontinuity.
|
||||
* <p>
|
||||
* After this method has returned a value other than {@link C#UNSET_TIME_US}, all
|
||||
* {@link TrackStream}s provided by the source are guaranteed to start from a key frame.
|
||||
*
|
||||
* @return If a reset was read then the playback position in microseconds after the reset. Else
|
||||
* {@link C#UNSET_TIME_US}.
|
||||
* @return If a discontinuity was read then the playback position in microseconds after the
|
||||
* discontinuity. Else {@link C#UNSET_TIME_US}.
|
||||
*/
|
||||
long readReset();
|
||||
long readDiscontinuity();
|
||||
|
||||
/**
|
||||
* Returns an estimate of the position up to which data is buffered for the enabled tracks.
|
||||
|
|
@ -106,13 +109,17 @@ public interface SampleSource {
|
|||
long getBufferedPositionUs();
|
||||
|
||||
/**
|
||||
* Seeks to the specified position in microseconds.
|
||||
* Attempts to seek to the specified position in microseconds.
|
||||
* <p>
|
||||
* After this method has been called, all {@link TrackStream}s provided by the source are
|
||||
* guaranteed to start from a key frame.
|
||||
* <p>
|
||||
* This method should only be called when at least one track is selected.
|
||||
*
|
||||
* @param positionUs The seek position in microseconds.
|
||||
* @return The actual position to which the source was seeked, in microseconds.
|
||||
*/
|
||||
void seekToUs(long positionUs);
|
||||
long seekToUs(long positionUs);
|
||||
|
||||
/**
|
||||
* Releases the source.
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
|||
private final EventListener eventListener;
|
||||
private final int eventSourceId;
|
||||
|
||||
private long pendingResetPositionUs;
|
||||
private boolean loadingFinished;
|
||||
|
||||
private int streamState;
|
||||
|
|
@ -140,7 +139,6 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
|||
if (!newSelections.isEmpty()) {
|
||||
newStreams[0] = this;
|
||||
streamState = STREAM_STATE_SEND_FORMAT;
|
||||
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||
maybeStartLoading();
|
||||
}
|
||||
return newStreams;
|
||||
|
|
@ -157,11 +155,11 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
public long seekToUs(long positionUs) {
|
||||
if (streamState == STREAM_STATE_END_OF_STREAM) {
|
||||
pendingResetPositionUs = positionUs;
|
||||
streamState = STREAM_STATE_SEND_SAMPLE;
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -182,10 +180,8 @@ public final class SingleSampleSource implements SampleSource, TrackStream,
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
long resetPositionUs = pendingResetPositionUs;
|
||||
pendingResetPositionUs = C.UNSET_TIME_US;
|
||||
return resetPositionUs;
|
||||
public long readDiscontinuity() {
|
||||
return C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -92,8 +92,6 @@ public final class DashSampleSource implements SampleSource {
|
|||
private long elapsedRealtimeOffset;
|
||||
private TrackGroupArray trackGroups;
|
||||
private int[] trackGroupAdaptationSetIndices;
|
||||
private boolean pendingReset;
|
||||
private long lastSeekPositionUs;
|
||||
private ChunkTrackStream<DashChunkSource>[] trackStreams;
|
||||
|
||||
public DashSampleSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
|
||||
|
|
@ -184,14 +182,7 @@ public final class DashSampleSource implements SampleSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
if (pendingReset) {
|
||||
pendingReset = false;
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.setReadingEnabled(true);
|
||||
}
|
||||
return lastSeekPositionUs;
|
||||
}
|
||||
public long readDiscontinuity() {
|
||||
return C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
|
|
@ -208,13 +199,11 @@ public final class DashSampleSource implements SampleSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
lastSeekPositionUs = positionUs;
|
||||
pendingReset = true;
|
||||
public long seekToUs(long positionUs) {
|
||||
for (ChunkTrackStream<DashChunkSource> trackStream : trackStreams) {
|
||||
trackStream.setReadingEnabled(false);
|
||||
trackStream.seekToUs(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
public long readDiscontinuity() {
|
||||
if (notifyReset) {
|
||||
notifyReset = false;
|
||||
return lastSeekPositionUs;
|
||||
|
|
@ -410,7 +410,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
public long seekToUs(long positionUs) {
|
||||
// Treat all seeks into non-seekable media as being to t=0.
|
||||
positionUs = seekMap.isSeekable() ? positionUs : 0;
|
||||
lastSeekPositionUs = positionUs;
|
||||
|
|
@ -426,6 +426,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
|
|||
if (!seekInsideBuffer) {
|
||||
restartFrom(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -80,8 +80,6 @@ public final class HlsSampleSource implements SampleSource,
|
|||
private int[] selectedTrackCounts;
|
||||
private HlsTrackStreamWrapper[] trackStreamWrappers;
|
||||
private HlsTrackStreamWrapper[] enabledTrackStreamWrappers;
|
||||
private boolean pendingReset;
|
||||
private long lastSeekPositionUs;
|
||||
|
||||
public HlsSampleSource(Uri manifestUri, DataSourceFactory dataSourceFactory,
|
||||
BandwidthMeter bandwidthMeter, Handler eventHandler,
|
||||
|
|
@ -192,14 +190,7 @@ public final class HlsSampleSource implements SampleSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
if (pendingReset) {
|
||||
pendingReset = false;
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||
trackStreamWrapper.setReadingEnabled(true);
|
||||
}
|
||||
return lastSeekPositionUs;
|
||||
}
|
||||
public long readDiscontinuity() {
|
||||
return C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
|
|
@ -216,16 +207,14 @@ public final class HlsSampleSource implements SampleSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
public long seekToUs(long positionUs) {
|
||||
// Treat all seeks into non-seekable media as being to t=0.
|
||||
positionUs = isLive ? 0 : positionUs;
|
||||
lastSeekPositionUs = positionUs;
|
||||
pendingReset = true;
|
||||
timestampAdjusterProvider.reset();
|
||||
for (HlsTrackStreamWrapper trackStreamWrapper : enabledTrackStreamWrappers) {
|
||||
trackStreamWrapper.setReadingEnabled(false);
|
||||
trackStreamWrapper.restartFrom(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -81,8 +81,6 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
|||
private TrackEncryptionBox[] trackEncryptionBoxes;
|
||||
private TrackGroupArray trackGroups;
|
||||
private int[] trackGroupElementIndices;
|
||||
private boolean pendingReset;
|
||||
private long lastSeekPositionUs;
|
||||
|
||||
private ChunkTrackStream<SmoothStreamingChunkSource>[] trackStreams;
|
||||
|
||||
|
|
@ -171,14 +169,7 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public long readReset() {
|
||||
if (pendingReset) {
|
||||
pendingReset = false;
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.setReadingEnabled(true);
|
||||
}
|
||||
return lastSeekPositionUs;
|
||||
}
|
||||
public long readDiscontinuity() {
|
||||
return C.UNSET_TIME_US;
|
||||
}
|
||||
|
||||
|
|
@ -195,13 +186,11 @@ public final class SmoothStreamingSampleSource implements SampleSource,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
lastSeekPositionUs = positionUs;
|
||||
pendingReset = true;
|
||||
public long seekToUs(long positionUs) {
|
||||
for (ChunkTrackStream<SmoothStreamingChunkSource> trackStream : trackStreams) {
|
||||
trackStream.setReadingEnabled(false);
|
||||
trackStream.seekToUs(positionUs);
|
||||
}
|
||||
return positionUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in a new issue