Optimize HLS seeking.

I think the concept of a sparse track might need formalizing
in Format at some point. We should probably do a similar thing
with sparse tracks in ExtractorSampleSource as well. WDYT?

Issue: #551
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=120530195
This commit is contained in:
olly 2016-04-22 03:02:05 -07:00 committed by Oliver Woodman
parent b1de997388
commit 2b13165738
2 changed files with 23 additions and 3 deletions

View file

@ -567,7 +567,9 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu
// If we're not pending a reset, see if we can seek within the sample queues.
boolean seekInsideBuffer = !isPendingReset();
for (int i = 0; seekInsideBuffer && i < sampleQueues.length; i++) {
seekInsideBuffer = sampleQueues[i].skipToKeyframeBefore(positionUs);
if (trackEnabledStates[i]) {
seekInsideBuffer = sampleQueues[i].skipToKeyframeBefore(positionUs);
}
}
// If we failed to seek within the sample queues, we need to restart.
if (!seekInsideBuffer) {

View file

@ -532,8 +532,26 @@ public final class HlsSampleSource implements SampleSource, Loader.Callback {
lastSeekPositionUs = positionUs;
downstreamPositionUs = positionUs;
Arrays.fill(pendingResets, true);
chunkSource.seek();
restartFrom(positionUs);
boolean seekInsideBuffer = !isPendingReset();
// TODO[REFACTOR]: This will nearly always fail to seek inside all buffers due to sparse tracks
// such as ID3 (probably EIA608 too). We need a way to not care if we can't seek to the keyframe
// before for such tracks. For ID3 we probably explicitly don't want the keyframe before, even
// if we do have it, since it might be quite a long way behind the seek position. We probably
// only want to output ID3 buffers whose timestamps are greater than or equal to positionUs.
for (int i = 0; seekInsideBuffer && i < sampleQueues.length; i++) {
if (groupEnabledStates[i]) {
seekInsideBuffer = sampleQueues[i].skipToKeyframeBefore(positionUs);
}
}
if (seekInsideBuffer) {
while (mediaChunks.size() > 1 && mediaChunks.get(1).startTimeUs <= positionUs) {
mediaChunks.removeFirst();
}
} else {
// If we failed to seek within the sample queues, we need to restart.
chunkSource.seek();
restartFrom(positionUs);
}
}
private void discardSamplesForDisabledTracks() {