mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Update HlsSampleSource + correctly propagate error from prepare.
Issue: #81
This commit is contained in:
parent
60d162df18
commit
5f0be427a4
1 changed files with 37 additions and 32 deletions
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue