From afb1a93059794b432cf6fa9509a603ddb3b73fa4 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Wed, 22 Apr 2015 16:23:33 +0100 Subject: [PATCH] Refine ExtractorSampleSource retry. I was hoping not to avoid this, but in the case of a parsing failure during preparation we keep retrying forever! --- .../extractor/DefaultTrackOutput.java | 2 +- .../extractor/ExtractorSampleSource.java | 47 +++++++++++++------ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java b/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java index e8a30ca401..330f320d22 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/DefaultTrackOutput.java @@ -27,7 +27,7 @@ import java.io.IOException; * A {@link TrackOutput} that buffers extracted samples in a queue, and allows for consumption from * that queue. */ -public final class DefaultTrackOutput implements TrackOutput { +public class DefaultTrackOutput implements TrackOutput { private final RollingSampleBuffer rollingBuffer; private final SampleHolder sampleInfoHolder; diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java index 1107d71536..7a14a5a6d1 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java @@ -23,6 +23,7 @@ import com.google.android.exoplayer.SampleSource; import com.google.android.exoplayer.TrackInfo; import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.drm.DrmInitData; +import com.google.android.exoplayer.upstream.Allocator; import com.google.android.exoplayer.upstream.BufferPool; import com.google.android.exoplayer.upstream.DataSource; import com.google.android.exoplayer.upstream.DataSpec; @@ -58,7 +59,7 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa private final Extractor extractor; private final BufferPool bufferPool; private final int requestedBufferSize; - private final SparseArray sampleQueues; + private final SparseArray sampleQueues; private final int minLoadableRetryCount; private final boolean frameAccurateSeeking; private final Uri uri; @@ -93,6 +94,9 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa private long currentLoadableExceptionTimestamp; private boolean loadingFinished; + private int extractedSampleCount; + private int extractedSampleCountAtStartOfLoad; + /** * @param uri The {@link Uri} of the media stream. * @param dataSource A data source to read the media stream. @@ -125,7 +129,7 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa this.remainingReleaseCount = downstreamRendererCount; this.requestedBufferSize = requestedBufferSize; this.minLoadableRetryCount = minLoadableRetryCount; - sampleQueues = new SparseArray(); + sampleQueues = new SparseArray(); bufferPool = new BufferPool(BUFFER_FRAGMENT_LENGTH); pendingResetPositionUs = NO_RESET_PENDING; frameAccurateSeeking = true; @@ -228,7 +232,7 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa return NOTHING_READ; } - DefaultTrackOutput sampleQueue = sampleQueues.valueAt(track); + InternalTrackOutput sampleQueue = sampleQueues.valueAt(track); if (pendingMediaFormat[track]) { formatHolder.format = sampleQueue.getFormat(); formatHolder.drmInitData = drmInitData; @@ -335,7 +339,8 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa @Override public void onLoadError(Loadable ignored, IOException e) { currentLoadableException = e; - currentLoadableExceptionCount = loadable.madeProgress() ? 1 : currentLoadableExceptionCount + 1; + currentLoadableExceptionCount = extractedSampleCount > extractedSampleCountAtStartOfLoad ? 1 + : currentLoadableExceptionCount + 1; currentLoadableExceptionTimestamp = SystemClock.elapsedRealtime(); maybeStartLoading(); } @@ -344,9 +349,9 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa @Override public TrackOutput track(int id) { - DefaultTrackOutput sampleQueue = sampleQueues.get(id); + InternalTrackOutput sampleQueue = sampleQueues.get(id); if (sampleQueue == null) { - sampleQueue = new DefaultTrackOutput(bufferPool); + sampleQueue = new InternalTrackOutput(bufferPool); sampleQueues.put(id, sampleQueue); } return sampleQueue; @@ -427,6 +432,7 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa // We're playing a seekable on-demand stream. Resume the current loadable, which will // request data starting from the point it left off. } + extractedSampleCountAtStartOfLoad = extractedSampleCount; loader.startLoading(loadable, this); } return; @@ -445,6 +451,7 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa loadable = createLoadableFromPositionUs(pendingResetPositionUs); pendingResetPositionUs = NO_RESET_PENDING; } + extractedSampleCountAtStartOfLoad = extractedSampleCount; loader.startLoading(loadable, this); } @@ -521,6 +528,24 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa return Math.min((errorCount - 1) * 1000, 5000); } + /** + * Extension of {@link DefaultTrackOutput} that increments a shared counter of the total number + * of extracted samples. + */ + private class InternalTrackOutput extends DefaultTrackOutput { + + public InternalTrackOutput(Allocator allocator) { + super(allocator); + } + + @Override + public void sampleMetadata(long timeUs, int flags, int size, int offset, byte[] encryptionKey) { + super.sampleMetadata(timeUs, flags, size, offset, encryptionKey); + extractedSampleCount++; + } + + } + /** * Loads the media stream and extracts sample data from it. */ @@ -536,7 +561,6 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa private volatile boolean loadCanceled; private boolean pendingExtractorSeek; - private boolean madeProgress; public ExtractingLoadable(Uri uri, DataSource dataSource, Extractor extractor, BufferPool bufferPool, int bufferPoolSizeLimit, long position) { @@ -550,10 +574,6 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa pendingExtractorSeek = true; } - public boolean madeProgress() { - return madeProgress; - } - @Override public void cancelLoad() { loadCanceled = true; @@ -587,12 +607,9 @@ public class ExtractorSampleSource implements SampleSource, ExtractorOutput, Loa } } finally { if (result == Extractor.RESULT_SEEK) { - madeProgress |= true; result = Extractor.RESULT_CONTINUE; } else if (input != null) { - long newPosition = input.getPosition(); - madeProgress |= newPosition > positionHolder.position; - positionHolder.position = newPosition; + positionHolder.position = input.getPosition(); } dataSource.close(); }