提交 ebfd5a7f 编写于 作者: O olly 提交者: Oliver Woodman

Don't discard embedded queues beyond primary queue.

ChunkSampleStream.seekToUs assumes that if we can seek within the
primary sample queue, we can also seek within the embedded queues.
This assumption can be violated fairly easily if discardBuffer is
called with toKeyframe=true, since this can cause samples to be
discarded from the embedded queues within the period for which a
seek in the primary sample queue will succeed. This change fixes
the issue.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=181965902
上级 7b534cd9
......@@ -186,6 +186,11 @@ import com.google.android.exoplayer2.util.Util;
return largestQueuedTimestampUs;
}
/** Returns the timestamp of the first sample, or {@link Long#MIN_VALUE} if the queue is empty. */
public synchronized long getFirstTimestampUs() {
return length == 0 ? Long.MIN_VALUE : timesUs[relativeFirstIndex];
}
/**
* Rewinds the read position to the first sample retained in the queue.
*/
......@@ -487,8 +492,7 @@ import com.google.android.exoplayer2.util.Util;
* Discards the specified number of samples.
*
* @param discardCount The number of samples to discard.
* @return The corresponding offset up to which data should be discarded, or
* {@link C#POSITION_UNSET} if no discarding of data is necessary.
* @return The corresponding offset up to which data should be discarded.
*/
private long discardSamples(int discardCount) {
largestDiscardedTimestampUs = Math.max(largestDiscardedTimestampUs,
......
......@@ -226,6 +226,11 @@ public final class SampleQueue implements TrackOutput {
return metadataQueue.getLargestQueuedTimestampUs();
}
/** Returns the timestamp of the first sample, or {@link Long#MIN_VALUE} if the queue is empty. */
public long getFirstTimestampUs() {
return metadataQueue.getFirstTimestampUs();
}
/**
* Rewinds the read position to the first sample in the queue.
*/
......
......@@ -120,11 +120,16 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
* the specified position, rather than any sample before or at that position.
*/
public void discardBuffer(long positionUs, boolean toKeyframe) {
int oldFirstIndex = primarySampleQueue.getFirstIndex();
primarySampleQueue.discardTo(positionUs, toKeyframe, true);
int newFirstIndex = primarySampleQueue.getFirstIndex();
if (newFirstIndex > oldFirstIndex) {
long discardToUs = primarySampleQueue.getFirstTimestampUs();
for (int i = 0; i < embeddedSampleQueues.length; i++) {
embeddedSampleQueues[i].discardTo(positionUs, toKeyframe, embeddedTracksSelected[i]);
embeddedSampleQueues[i].discardTo(discardToUs, toKeyframe, embeddedTracksSelected[i]);
}
discardDownstreamMediaChunks(newFirstIndex);
}
discardDownstreamMediaChunks(primarySampleQueue.getFirstIndex());
}
/**
......@@ -209,7 +214,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
boolean seekInsideBuffer = !isPendingReset() && (primarySampleQueue.advanceTo(positionUs, true,
positionUs < getNextLoadPositionUs()) != SampleQueue.ADVANCE_FAILED);
if (seekInsideBuffer) {
// We succeeded. Discard samples and corresponding chunks prior to the seek position.
// We succeeded. Advance the embedded sample queues to the seek position.
for (SampleQueue embeddedSampleQueue : embeddedSampleQueues) {
embeddedSampleQueue.rewind();
embeddedSampleQueue.advanceTo(positionUs, true, false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册