From cb0394b9cf469b5ac0092ab178dd8763f2a11566 Mon Sep 17 00:00:00 2001 From: WeiChungChang Date: Thu, 12 Jan 2017 10:49:37 +0800 Subject: [PATCH 1/2] 'improve_far_seek_of_chunkSampleStream' --- .../extractor/DefaultTrackOutput.java | 22 +++++++++++++--- .../source/chunk/ChunkSampleStream.java | 25 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java index 44756a507e..807160fd96 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java @@ -225,6 +225,22 @@ public final class DefaultTrackOutput implements TrackOutput { return infoQueue.getLargestQueuedTimestampUs(); } + /** + * Attempts to skip to the keyframe before the specified time, if it's present in the buffer. + * + * @param timeUs The seek time. + * @param skipToLastKey Skip to last key regardless the seek time is out of range . + * @return Whether the skip was successful. + */ + public boolean skipToKeyframeBefore(long timeUs, boolean skipToLastKey) { + long nextOffset = infoQueue.skipToKeyframeBefore(timeUs, skipToLastKey); + if (nextOffset == C.POSITION_UNSET) { + return false; + } + dropDownstreamTo(nextOffset); + return true; + } + /** * Attempts to skip to the keyframe before the specified time, if it's present in the buffer. * @@ -232,7 +248,7 @@ public final class DefaultTrackOutput implements TrackOutput { * @return Whether the skip was successful. */ public boolean skipToKeyframeBefore(long timeUs) { - long nextOffset = infoQueue.skipToKeyframeBefore(timeUs); + long nextOffset = infoQueue.skipToKeyframeBefore(timeUs, false); if (nextOffset == C.POSITION_UNSET) { return false; } @@ -781,12 +797,12 @@ public final class DefaultTrackOutput implements TrackOutput { * @return The offset of the keyframe's data if the keyframe was present. * {@link C#POSITION_UNSET} otherwise. */ - public synchronized long skipToKeyframeBefore(long timeUs) { + public synchronized long skipToKeyframeBefore(long timeUs, boolean skipToLastKey) { if (queueSize == 0 || timeUs < timesUs[relativeReadIndex]) { return C.POSITION_UNSET; } - if (timeUs > largestQueuedTimestampUs) { + if (timeUs > largestQueuedTimestampUs && !skipToLastKey) { return C.POSITION_UNSET; } diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 6de7c6ec01..812ac9a0be 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -114,6 +114,20 @@ public class ChunkSampleStream implements SampleStream, S } } + /** + * Check if the input position locates within the chunk we are downloading now. + * + * @param positionUs The target position in microseconds. + * @return Whether the input position locates within the chunk we are downloading now. + */ + public boolean isWithinLastChunk(long positionUs) { + if (isPendingReset() || loadingFinished) { + return false; + } else { + return ((positionUs >= getCurrentLoadPositionUs()) && (positionUs < getNextLoadPositionUs())); + } + } + /** * Seeks to the specified position in microseconds. * @@ -122,7 +136,8 @@ public class ChunkSampleStream implements SampleStream, S public void seekToUs(long positionUs) { lastSeekPositionUs = positionUs; // If we're not pending a reset, see if we can seek within the sample queue. - boolean seekInsideBuffer = !isPendingReset() && sampleQueue.skipToKeyframeBefore(positionUs); + boolean seekInsideBuffer = !isPendingReset() && + sampleQueue.skipToKeyframeBefore(positionUs, isWithinLastChunk(positionUs)); if (seekInsideBuffer) { // We succeeded. All we need to do is discard any chunks that we've moved past. while (mediaChunks.size() > 1 @@ -284,6 +299,14 @@ public class ChunkSampleStream implements SampleStream, S return true; } + public long getCurrentLoadPositionUs() { + if (isPendingReset()) { + return pendingResetPositionUs; + } else { + return loadingFinished ? C.TIME_END_OF_SOURCE : mediaChunks.getLast().startTimeUs; + } + } + @Override public long getNextLoadPositionUs() { if (isPendingReset()) { From 2214a4c152fab862c928875f8265e77676d3652b Mon Sep 17 00:00:00 2001 From: WeiChungChang Date: Sat, 14 Jan 2017 10:22:27 +0800 Subject: [PATCH 2/2] 'refine_to_make_flow_simpler' --- .../extractor/DefaultTrackOutput.java | 7 +----- .../source/chunk/ChunkSampleStream.java | 24 +------------------ 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java index 807160fd96..bd9076bd5d 100644 --- a/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer2/extractor/DefaultTrackOutput.java @@ -248,12 +248,7 @@ public final class DefaultTrackOutput implements TrackOutput { * @return Whether the skip was successful. */ public boolean skipToKeyframeBefore(long timeUs) { - long nextOffset = infoQueue.skipToKeyframeBefore(timeUs, false); - if (nextOffset == C.POSITION_UNSET) { - return false; - } - dropDownstreamTo(nextOffset); - return true; + return infoQueue.skipToKeyframeBefore(timeUs, false); } /** diff --git a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java index 812ac9a0be..189fcc96f4 100644 --- a/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java +++ b/library/src/main/java/com/google/android/exoplayer2/source/chunk/ChunkSampleStream.java @@ -114,20 +114,6 @@ public class ChunkSampleStream implements SampleStream, S } } - /** - * Check if the input position locates within the chunk we are downloading now. - * - * @param positionUs The target position in microseconds. - * @return Whether the input position locates within the chunk we are downloading now. - */ - public boolean isWithinLastChunk(long positionUs) { - if (isPendingReset() || loadingFinished) { - return false; - } else { - return ((positionUs >= getCurrentLoadPositionUs()) && (positionUs < getNextLoadPositionUs())); - } - } - /** * Seeks to the specified position in microseconds. * @@ -137,7 +123,7 @@ public class ChunkSampleStream implements SampleStream, S lastSeekPositionUs = positionUs; // If we're not pending a reset, see if we can seek within the sample queue. boolean seekInsideBuffer = !isPendingReset() && - sampleQueue.skipToKeyframeBefore(positionUs, isWithinLastChunk(positionUs)); + sampleQueue.skipToKeyframeBefore(positionUs, (positionUs < getNextLoadPositionUs())); if (seekInsideBuffer) { // We succeeded. All we need to do is discard any chunks that we've moved past. while (mediaChunks.size() > 1 @@ -299,14 +285,6 @@ public class ChunkSampleStream implements SampleStream, S return true; } - public long getCurrentLoadPositionUs() { - if (isPendingReset()) { - return pendingResetPositionUs; - } else { - return loadingFinished ? C.TIME_END_OF_SOURCE : mediaChunks.getLast().startTimeUs; - } - } - @Override public long getNextLoadPositionUs() { if (isPendingReset()) {