mirror of
https://github.com/samsonjs/media.git
synced 2026-04-17 13:15:47 +00:00
Ensure we always seek after selecting a track.
Some extractor implementations underneath MediaExtractor require a seekTo call after tracks are selected to ensure samples are read from the correct position. De-duplicating logic was preventing this from happening in some cases, causing issues like: https://github.com/google/ExoPlayer/issues/301 Note that seeking all tracks a side effect of track selection sucks if you already have one or more tracks selected, because it introduces discontinuities to the already selected tracks. However, in general, it *is* necessary to specify the position for the track being selected, because the underlying extractor doesn't have enough information to know where to start reading from. It can't determine this based on the read positions of the already selected tracks, because the samples in these tracks might be very sparse with respect to time. I think a more optimal fix would be to change the SampleExtractor interface to receive the current position as an argument to selectTrack. For our own extractors, we'd seek the newly selected track to that position, whilst the already enabled tracks would be left in their current positions (if possible). For FrameworkSampleExtractor we'd still have no choice but to call seekTo on the extractor to seek all of the tracks. This solution ends up being more complex though, because: - The SampleExtractor then needs a way of telling DefaultSampleSource which tracks were actually seeked, so that the pendingDiscontinuities flags can be set correctly. - It's a weird API that requires the "current playback position to seek only the track being enabled" So it may not be worth it! I think this fix is definitely good for now, in any case. Issue: #301
This commit is contained in:
parent
cc7a15b79b
commit
b03c5c5753
1 changed files with 16 additions and 12 deletions
|
|
@ -88,7 +88,7 @@ public final class DefaultSampleSource implements SampleSource {
|
|||
Assertions.checkState(trackStates[track] == TRACK_STATE_DISABLED);
|
||||
trackStates[track] = TRACK_STATE_ENABLED;
|
||||
sampleExtractor.selectTrack(track);
|
||||
seekToUs(positionUs);
|
||||
seekToUsInternal(positionUs, positionUs != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -131,17 +131,7 @@ public final class DefaultSampleSource implements SampleSource {
|
|||
@Override
|
||||
public void seekToUs(long positionUs) {
|
||||
Assertions.checkState(prepared);
|
||||
if (seekPositionUs != positionUs) {
|
||||
// Avoid duplicate calls to the underlying extractor's seek method in the case that there
|
||||
// have been no interleaving calls to readSample.
|
||||
seekPositionUs = positionUs;
|
||||
sampleExtractor.seekTo(positionUs);
|
||||
for (int i = 0; i < trackStates.length; ++i) {
|
||||
if (trackStates[i] != TRACK_STATE_DISABLED) {
|
||||
pendingDiscontinuities[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
seekToUsInternal(positionUs, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -158,4 +148,18 @@ public final class DefaultSampleSource implements SampleSource {
|
|||
}
|
||||
}
|
||||
|
||||
private void seekToUsInternal(long positionUs, boolean force) {
|
||||
// Unless forced, avoid duplicate calls to the underlying extractor's seek method in the case
|
||||
// that there have been no interleaving calls to readSample.
|
||||
if (force || seekPositionUs != positionUs) {
|
||||
seekPositionUs = positionUs;
|
||||
sampleExtractor.seekTo(positionUs);
|
||||
for (int i = 0; i < trackStates.length; ++i) {
|
||||
if (trackStates[i] != TRACK_STATE_DISABLED) {
|
||||
pendingDiscontinuities[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue