Commit 5f0be427 by Oliver Woodman

Update HlsSampleSource + correctly propagate error from prepare.

Issue: #81
parent 60d162df
...@@ -64,7 +64,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -64,7 +64,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
private long downstreamPositionUs; private long downstreamPositionUs;
private long lastSeekPositionUs; private long lastSeekPositionUs;
private long pendingResetTime; private long pendingResetPositionUs;
private long lastPerformedBufferOperation; private long lastPerformedBufferOperation;
private Loader loader; private Loader loader;
...@@ -89,7 +89,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -89,7 +89,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
@Override @Override
public boolean prepare() { public boolean prepare() throws IOException {
if (prepared) { if (prepared) {
return true; return true;
} }
...@@ -116,6 +116,9 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -116,6 +116,9 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
prepared = true; prepared = true;
} }
if (!prepared && currentLoadableException != null) {
throw currentLoadableException;
}
return prepared; return prepared;
} }
...@@ -132,16 +135,16 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -132,16 +135,16 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
@Override @Override
public void enable(int track, long timeUs) { public void enable(int track, long positionUs) {
Assertions.checkState(prepared); Assertions.checkState(prepared);
Assertions.checkState(!trackEnabledStates[track]); Assertions.checkState(!trackEnabledStates[track]);
enabledTrackCount++; enabledTrackCount++;
trackEnabledStates[track] = true; trackEnabledStates[track] = true;
downstreamMediaFormats[track] = null; downstreamMediaFormats[track] = null;
if (enabledTrackCount == 1) { if (enabledTrackCount == 1) {
downstreamPositionUs = timeUs; downstreamPositionUs = positionUs;
lastSeekPositionUs = timeUs; lastSeekPositionUs = positionUs;
restartFrom(timeUs); restartFrom(positionUs);
} }
} }
...@@ -257,21 +260,21 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -257,21 +260,21 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
@Override @Override
public void seekToUs(long timeUs) { public void seekToUs(long positionUs) {
Assertions.checkState(prepared); Assertions.checkState(prepared);
Assertions.checkState(enabledTrackCount > 0); Assertions.checkState(enabledTrackCount > 0);
downstreamPositionUs = timeUs; downstreamPositionUs = positionUs;
lastSeekPositionUs = timeUs; lastSeekPositionUs = positionUs;
if (pendingResetTime == timeUs) { if (pendingResetPositionUs == positionUs) {
return; return;
} }
for (int i = 0; i < pendingDiscontinuities.length; i++) { for (int i = 0; i < pendingDiscontinuities.length; i++) {
pendingDiscontinuities[i] = true; pendingDiscontinuities[i] = true;
} }
TsChunk mediaChunk = getHlsChunk(timeUs); TsChunk mediaChunk = getHlsChunk(positionUs);
if (mediaChunk == null) { if (mediaChunk == null) {
restartFrom(timeUs); restartFrom(positionUs);
} else { } else {
pendingTimestampOffsetUpdate = true; pendingTimestampOffsetUpdate = true;
mediaChunk.reset(); mediaChunk.reset();
...@@ -280,13 +283,13 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -280,13 +283,13 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
} }
private TsChunk getHlsChunk(long timeUs) { private TsChunk getHlsChunk(long positionUs) {
Iterator<TsChunk> mediaChunkIterator = mediaChunks.iterator(); Iterator<TsChunk> mediaChunkIterator = mediaChunks.iterator();
while (mediaChunkIterator.hasNext()) { while (mediaChunkIterator.hasNext()) {
TsChunk mediaChunk = mediaChunkIterator.next(); TsChunk mediaChunk = mediaChunkIterator.next();
if (timeUs < mediaChunk.startTimeUs) { if (positionUs < mediaChunk.startTimeUs) {
return null; return null;
} else if (mediaChunk.isLastChunk() || timeUs < mediaChunk.endTimeUs) { } else if (mediaChunk.isLastChunk() || positionUs < mediaChunk.endTimeUs) {
return mediaChunk; return mediaChunk;
} }
} }
...@@ -298,7 +301,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -298,7 +301,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
Assertions.checkState(prepared); Assertions.checkState(prepared);
Assertions.checkState(enabledTrackCount > 0); Assertions.checkState(enabledTrackCount > 0);
if (isPendingReset()) { if (isPendingReset()) {
return pendingResetTime; return pendingResetPositionUs;
} }
TsChunk mediaChunk = mediaChunks.getLast(); TsChunk mediaChunk = mediaChunks.getLast();
HlsChunk currentLoadable = currentLoadableHolder.chunk; HlsChunk currentLoadable = currentLoadableHolder.chunk;
...@@ -357,7 +360,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -357,7 +360,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
clearCurrentLoadable(); clearCurrentLoadable();
if (enabledTrackCount > 0) { if (enabledTrackCount > 0) {
restartFrom(pendingResetTime); restartFrom(pendingResetPositionUs);
} else { } else {
clearHlsChunks(); clearHlsChunks();
loadControl.trimAllocator(); loadControl.trimAllocator();
...@@ -372,8 +375,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -372,8 +375,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
updateLoadControl(); updateLoadControl();
} }
private void restartFrom(long timeUs) { private void restartFrom(long positionUs) {
pendingResetTime = timeUs; pendingResetPositionUs = positionUs;
if (loader.isLoading()) { if (loader.isLoading()) {
loader.cancelLoading(); loader.cancelLoading();
} else { } else {
...@@ -395,21 +398,23 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -395,21 +398,23 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
private void updateLoadControl() { private void updateLoadControl() {
if (currentLoadableExceptionFatal) {
// We've failed, but we still need to update the control with our current state.
loadControl.update(this, downstreamPositionUs, -1, false, true);
return;
}
long loadPositionUs; long loadPositionUs;
if (isPendingReset()) { if (isPendingReset()) {
loadPositionUs = pendingResetTime; loadPositionUs = pendingResetPositionUs;
} else { } else {
TsChunk lastHlsChunk = mediaChunks.getLast(); TsChunk lastHlsChunk = mediaChunks.getLast();
loadPositionUs = lastHlsChunk.nextChunkIndex == -1 ? -1 : lastHlsChunk.endTimeUs; loadPositionUs = lastHlsChunk.nextChunkIndex == -1 ? -1 : lastHlsChunk.endTimeUs;
} }
boolean isBackedOff = currentLoadableException != null && !currentLoadableExceptionFatal; boolean isBackedOff = currentLoadableException != null;
boolean nextLoader = loadControl.update(this, downstreamPositionUs, loadPositionUs, boolean nextLoader = loadControl.update(this, downstreamPositionUs, loadPositionUs,
isBackedOff || loader.isLoading(), currentLoadableExceptionFatal); isBackedOff || loader.isLoading(), false);
if (currentLoadableExceptionFatal) {
return;
}
long now = SystemClock.elapsedRealtime(); long now = SystemClock.elapsedRealtime();
...@@ -425,8 +430,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -425,8 +430,8 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
if (currentLoadableHolder.chunk == null || now - lastPerformedBufferOperation > 1000) { if (currentLoadableHolder.chunk == null || now - lastPerformedBufferOperation > 1000) {
lastPerformedBufferOperation = now; lastPerformedBufferOperation = now;
currentLoadableHolder.queueSize = readOnlyHlsChunks.size(); currentLoadableHolder.queueSize = readOnlyHlsChunks.size();
chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetTime, downstreamPositionUs, chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetPositionUs,
currentLoadableHolder); downstreamPositionUs, currentLoadableHolder);
discardUpstreamHlsChunks(currentLoadableHolder.queueSize); discardUpstreamHlsChunks(currentLoadableHolder.queueSize);
} }
if (nextLoader) { if (nextLoader) {
...@@ -448,7 +453,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -448,7 +453,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
HlsChunk backedOffChunk = currentLoadableHolder.chunk; HlsChunk backedOffChunk = currentLoadableHolder.chunk;
if (!isTsChunk(backedOffChunk)) { if (!isTsChunk(backedOffChunk)) {
currentLoadableHolder.queueSize = readOnlyHlsChunks.size(); currentLoadableHolder.queueSize = readOnlyHlsChunks.size();
chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetTime, downstreamPositionUs, chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetPositionUs, downstreamPositionUs,
currentLoadableHolder); currentLoadableHolder);
discardUpstreamHlsChunks(currentLoadableHolder.queueSize); discardUpstreamHlsChunks(currentLoadableHolder.queueSize);
if (currentLoadableHolder.chunk == backedOffChunk) { if (currentLoadableHolder.chunk == backedOffChunk) {
...@@ -473,7 +478,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -473,7 +478,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
TsChunk removedChunk = mediaChunks.removeLast(); TsChunk removedChunk = mediaChunks.removeLast();
Assertions.checkState(backedOffChunk == removedChunk); Assertions.checkState(backedOffChunk == removedChunk);
currentLoadableHolder.queueSize = readOnlyHlsChunks.size(); currentLoadableHolder.queueSize = readOnlyHlsChunks.size();
chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetTime, downstreamPositionUs, chunkSource.getChunkOperation(readOnlyHlsChunks, pendingResetPositionUs, downstreamPositionUs,
currentLoadableHolder); currentLoadableHolder);
mediaChunks.add(removedChunk); mediaChunks.add(removedChunk);
...@@ -501,7 +506,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -501,7 +506,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
if (isPendingReset()) { if (isPendingReset()) {
pendingTimestampOffsetUpdate = true; pendingTimestampOffsetUpdate = true;
mediaChunk.reset(); mediaChunk.reset();
pendingResetTime = NO_RESET_PENDING; pendingResetPositionUs = NO_RESET_PENDING;
} }
mediaChunks.add(mediaChunk); mediaChunks.add(mediaChunk);
} }
...@@ -546,7 +551,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback { ...@@ -546,7 +551,7 @@ public class HlsSampleSource implements SampleSource, Loader.Callback {
} }
private boolean isPendingReset() { private boolean isPendingReset() {
return pendingResetTime != NO_RESET_PENDING; return pendingResetPositionUs != NO_RESET_PENDING;
} }
private long getRetryDelayMillis(long errorCount) { private long getRetryDelayMillis(long errorCount) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment