Enable HLS sample queues as soon as possible.
Currently, the sample queues are lazily enabled when they are first read from. This causes problems when the player tries to discard buffer and the HlsSampleStreamWrapper assumes the sample queue is disabled even though it's actually enabled but hasn't been read from. This change moves setting the sample queue index of the sample stream back into HlsSampleStreamWrapper. It enables the sample queues at track selection if the queues are already built, or immediately after they have been built for chunkless preparation. Issue:#4241 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=197415741
This commit is contained in:
parent
e162d35689
commit
7b855e45e6
@ -22,6 +22,8 @@
|
||||
* HLS:
|
||||
* Fix playback of livestreams with EXT-X-PROGRAM-DATE-TIME tags
|
||||
([#4239](https://github.com/google/ExoPlayer/issues/4239)).
|
||||
* Fix playback of clipped streams starting from non-keyframe positions
|
||||
([#4241](https://github.com/google/ExoPlayer/issues/4241)).
|
||||
* Caption:
|
||||
* TTML:
|
||||
* Fix a styling issue when there are multiple regions displayed at the same
|
||||
|
@ -19,6 +19,7 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.FormatHolder;
|
||||
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@ -36,6 +37,11 @@ import java.io.IOException;
|
||||
sampleQueueIndex = HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_PENDING;
|
||||
}
|
||||
|
||||
public void bindSampleQueue() {
|
||||
Assertions.checkArgument(sampleQueueIndex == HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_PENDING);
|
||||
sampleQueueIndex = sampleStreamWrapper.bindSampleQueueToSampleStream(trackGroupIndex);
|
||||
}
|
||||
|
||||
public void unbindSampleQueue() {
|
||||
if (sampleQueueIndex != HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_PENDING) {
|
||||
sampleStreamWrapper.unbindSampleQueue(trackGroupIndex);
|
||||
@ -48,12 +54,11 @@ import java.io.IOException;
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return sampleQueueIndex == HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_NO_MAPPING_NON_FATAL
|
||||
|| (maybeMapToSampleQueue() && sampleStreamWrapper.isReady(sampleQueueIndex));
|
||||
|| (hasValidSampleQueueIndex() && sampleStreamWrapper.isReady(sampleQueueIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowError() throws IOException {
|
||||
maybeMapToSampleQueue();
|
||||
if (sampleQueueIndex == HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_NO_MAPPING_FATAL) {
|
||||
throw new SampleQueueMappingException(
|
||||
sampleStreamWrapper.getTrackGroups().get(trackGroupIndex).getFormat(0).sampleMimeType);
|
||||
@ -63,22 +68,21 @@ import java.io.IOException;
|
||||
|
||||
@Override
|
||||
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
|
||||
return maybeMapToSampleQueue()
|
||||
return hasValidSampleQueueIndex()
|
||||
? sampleStreamWrapper.readData(sampleQueueIndex, formatHolder, buffer, requireFormat)
|
||||
: C.RESULT_NOTHING_READ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skipData(long positionUs) {
|
||||
return maybeMapToSampleQueue() ? sampleStreamWrapper.skipData(sampleQueueIndex, positionUs) : 0;
|
||||
return hasValidSampleQueueIndex()
|
||||
? sampleStreamWrapper.skipData(sampleQueueIndex, positionUs)
|
||||
: 0;
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private boolean maybeMapToSampleQueue() {
|
||||
if (sampleQueueIndex == HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_PENDING) {
|
||||
sampleQueueIndex = sampleStreamWrapper.bindSampleQueueToSampleStream(trackGroupIndex);
|
||||
}
|
||||
private boolean hasValidSampleQueueIndex() {
|
||||
return sampleQueueIndex != HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_PENDING
|
||||
&& sampleQueueIndex != HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_NO_MAPPING_NON_FATAL
|
||||
&& sampleQueueIndex != HlsSampleStreamWrapper.SAMPLE_QUEUE_INDEX_NO_MAPPING_FATAL;
|
||||
|
@ -102,6 +102,7 @@ import java.util.Arrays;
|
||||
private final Runnable maybeFinishPrepareRunnable;
|
||||
private final Runnable onTracksEndedRunnable;
|
||||
private final Handler handler;
|
||||
private final ArrayList<HlsSampleStream> hlsSampleStreams;
|
||||
|
||||
private SampleQueue[] sampleQueues;
|
||||
private int[] sampleQueueTrackIds;
|
||||
@ -166,6 +167,7 @@ import java.util.Arrays;
|
||||
sampleQueueIsAudioVideoFlags = new boolean[0];
|
||||
sampleQueuesEnabledStates = new boolean[0];
|
||||
mediaChunks = new ArrayList<>();
|
||||
hlsSampleStreams = new ArrayList<>();
|
||||
maybeFinishPrepareRunnable =
|
||||
new Runnable() {
|
||||
@Override
|
||||
@ -219,9 +221,6 @@ import java.util.Arrays;
|
||||
}
|
||||
|
||||
public int bindSampleQueueToSampleStream(int trackGroupIndex) {
|
||||
if (trackGroupToSampleQueueIndex == null) {
|
||||
return SAMPLE_QUEUE_INDEX_PENDING;
|
||||
}
|
||||
int sampleQueueIndex = trackGroupToSampleQueueIndex[trackGroupIndex];
|
||||
if (sampleQueueIndex == C.INDEX_UNSET) {
|
||||
return optionalTrackGroups.indexOf(trackGroups.get(trackGroupIndex)) == C.INDEX_UNSET
|
||||
@ -295,6 +294,9 @@ import java.util.Arrays;
|
||||
}
|
||||
streams[i] = new HlsSampleStream(this, trackGroupIndex);
|
||||
streamResetFlags[i] = true;
|
||||
if (trackGroupToSampleQueueIndex != null) {
|
||||
((HlsSampleStream) streams[i]).bindSampleQueue();
|
||||
}
|
||||
// If there's still a chance of avoiding a seek, try and seek within the sample queue.
|
||||
if (sampleQueuesBuilt && !seekRequired) {
|
||||
SampleQueue sampleQueue = sampleQueues[trackGroupToSampleQueueIndex[trackGroupIndex]];
|
||||
@ -360,6 +362,7 @@ import java.util.Arrays;
|
||||
}
|
||||
}
|
||||
|
||||
updateSampleStreams(streams);
|
||||
seenFirstTrackSelection = true;
|
||||
return seekRequired;
|
||||
}
|
||||
@ -411,6 +414,7 @@ import java.util.Arrays;
|
||||
loader.release(this);
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
released = true;
|
||||
hlsSampleStreams.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -750,6 +754,15 @@ import java.util.Arrays;
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void updateSampleStreams(SampleStream[] streams) {
|
||||
hlsSampleStreams.clear();
|
||||
for (SampleStream stream : streams) {
|
||||
if (stream != null) {
|
||||
hlsSampleStreams.add((HlsSampleStream) stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean finishedReadingChunk(HlsMediaChunk chunk) {
|
||||
int chunkUid = chunk.uid;
|
||||
int sampleQueueCount = sampleQueues.length;
|
||||
@ -807,6 +820,9 @@ import java.util.Arrays;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (HlsSampleStream sampleStream : hlsSampleStreams) {
|
||||
sampleStream.bindSampleQueue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source.hls;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.SampleQueue;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import java.io.IOException;
|
||||
@ -23,7 +24,7 @@ import java.io.IOException;
|
||||
public final class SampleQueueMappingException extends IOException {
|
||||
|
||||
/** @param mimeType The mime type of the track group whose mapping failed. */
|
||||
public SampleQueueMappingException(String mimeType) {
|
||||
public SampleQueueMappingException(@Nullable String mimeType) {
|
||||
super("Unable to bind a sample queue to TrackGroup with mime type " + mimeType + ".");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user