Add LoadErrorHandlingPolicy cleanup callbacks

Implementors should use the new callbacks to
clean up any resources associated with the
corresponding LoadEventInfo ids.

PiperOrigin-RevId: 309198455
This commit is contained in:
aquilescanta 2020-04-30 11:57:48 +01:00 committed by Oliver Woodman
parent b0a59a6b62
commit c4f65eb84a
8 changed files with 99 additions and 50 deletions

View File

@ -553,7 +553,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
listener.onSourceInfoRefreshed(durationUs, isSeekable, isLive); listener.onSourceInfoRefreshed(durationUs, isSeekable, isLive);
} }
StatsDataSource dataSource = loadable.dataSource; StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -561,7 +561,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
dataSource.getLastResponseHeaders(), dataSource.getLastResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
dataSource.getBytesRead()), dataSource.getBytesRead());
loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
eventDispatcher.loadCompleted(
loadEventInfo,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,
@ -578,7 +581,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void onLoadCanceled( public void onLoadCanceled(
ExtractingLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { ExtractingLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
StatsDataSource dataSource = loadable.dataSource; StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -586,7 +589,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
dataSource.getLastResponseHeaders(), dataSource.getLastResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
dataSource.getBytesRead()), dataSource.getBytesRead());
loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(
loadEventInfo,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,

View File

@ -218,7 +218,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
sampleData = Assertions.checkNotNull(loadable.sampleData); sampleData = Assertions.checkNotNull(loadable.sampleData);
loadingFinished = true; loadingFinished = true;
StatsDataSource dataSource = loadable.dataSource; StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -226,7 +226,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
dataSource.getLastResponseHeaders(), dataSource.getLastResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
sampleSize), sampleSize);
loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
eventDispatcher.loadCompleted(
loadEventInfo,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
format, format,
@ -240,7 +243,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void onLoadCanceled( public void onLoadCanceled(
SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { SourceLoadable loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
StatsDataSource dataSource = loadable.dataSource; StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -248,7 +251,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
dataSource.getLastResponseHeaders(), dataSource.getLastResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
dataSource.getBytesRead()), dataSource.getBytesRead());
loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(
loadEventInfo,
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,

View File

@ -405,7 +405,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
@Override @Override
public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) {
chunkSource.onChunkLoadCompleted(loadable); chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -413,7 +413,10 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
eventDispatcher.loadCompleted(
loadEventInfo,
loadable.type, loadable.type,
primaryTrackType, primaryTrackType,
loadable.trackFormat, loadable.trackFormat,
@ -427,7 +430,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
@Override @Override
public void onLoadCanceled( public void onLoadCanceled(
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -435,7 +438,10 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(
loadEventInfo,
loadable.type, loadable.type,
primaryTrackType, primaryTrackType,
loadable.trackFormat, loadable.trackFormat,

View File

@ -136,6 +136,22 @@ public interface LoadErrorHandlingPolicy {
loadErrorInfo.errorCount); loadErrorInfo.errorCount);
} }
/**
* Called when the load associated with the given {@link LoadEventInfo} completes.
*
* <p>Implementations of this interface should avoid resource leaks by releasing resources
* associated to the given {@link LoadEventInfo#loadTaskId}.
*/
default void onLoadCompleted(LoadEventInfo loadEventInfo) {}
/**
* Called when the load associated with the given {@link LoadEventInfo} is canceled.
*
* <p>Implementations of this interface should avoid resource leaks by releasing resources
* associated to the given {@link LoadEventInfo#loadTaskId}.
*/
default void onLoadCanceled(LoadEventInfo loadEventInfo) {}
/** /**
* Returns the minimum number of times to retry a load in the case of a load error, before * Returns the minimum number of times to retry a load in the case of a load error, before
* propagating the error. * propagating the error.

View File

@ -754,7 +754,7 @@ public final class DashMediaSource extends BaseMediaSource {
/* package */ void onManifestLoadCompleted(ParsingLoadable<DashManifest> loadable, /* package */ void onManifestLoadCompleted(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -762,8 +762,9 @@ public final class DashMediaSource extends BaseMediaSource {
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type); loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
manifestEventDispatcher.loadCompleted(loadEventInfo, loadable.type);
DashManifest newManifest = loadable.getResult(); DashManifest newManifest = loadable.getResult();
int oldPeriodCount = manifest == null ? 0 : manifest.getPeriodCount(); int oldPeriodCount = manifest == null ? 0 : manifest.getPeriodCount();
@ -875,7 +876,7 @@ public final class DashMediaSource extends BaseMediaSource {
/* package */ void onUtcTimestampLoadCompleted(ParsingLoadable<Long> loadable, /* package */ void onUtcTimestampLoadCompleted(ParsingLoadable<Long> loadable,
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -883,8 +884,9 @@ public final class DashMediaSource extends BaseMediaSource {
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type); loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
manifestEventDispatcher.loadCompleted(loadEventInfo, loadable.type);
onUtcTimestampResolved(loadable.getResult() - elapsedRealtimeMs); onUtcTimestampResolved(loadable.getResult() - elapsedRealtimeMs);
} }
@ -911,7 +913,7 @@ public final class DashMediaSource extends BaseMediaSource {
/* package */ void onLoadCanceled(ParsingLoadable<?> loadable, long elapsedRealtimeMs, /* package */ void onLoadCanceled(ParsingLoadable<?> loadable, long elapsedRealtimeMs,
long loadDurationMs) { long loadDurationMs) {
manifestEventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -919,8 +921,9 @@ public final class DashMediaSource extends BaseMediaSource {
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type); loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
manifestEventDispatcher.loadCanceled(loadEventInfo, loadable.type);
} }
// Internal methods. // Internal methods.

View File

@ -702,7 +702,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override @Override
public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) { public void onLoadCompleted(Chunk loadable, long elapsedRealtimeMs, long loadDurationMs) {
chunkSource.onChunkLoadCompleted(loadable); chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -710,7 +710,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
eventDispatcher.loadCompleted(
loadEventInfo,
loadable.type, loadable.type,
trackType, trackType,
loadable.trackFormat, loadable.trackFormat,
@ -728,7 +731,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
@Override @Override
public void onLoadCanceled( public void onLoadCanceled(
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) { Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -736,7 +739,10 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(
loadEventInfo,
loadable.type, loadable.type,
trackType, trackType,
loadable.trackFormat, loadable.trackFormat,

View File

@ -242,7 +242,7 @@ public final class DefaultHlsPlaylistTracker
} else { } else {
primaryBundle.loadPlaylist(); primaryBundle.loadPlaylist();
} }
eventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -250,8 +250,9 @@ public final class DefaultHlsPlaylistTracker
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
C.DATA_TYPE_MANIFEST); loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST);
} }
@Override @Override
@ -260,7 +261,7 @@ public final class DefaultHlsPlaylistTracker
long elapsedRealtimeMs, long elapsedRealtimeMs,
long loadDurationMs, long loadDurationMs,
boolean released) { boolean released) {
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -268,8 +269,9 @@ public final class DefaultHlsPlaylistTracker
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
C.DATA_TYPE_MANIFEST); loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(loadEventInfo, C.DATA_TYPE_MANIFEST);
} }
@Override @Override
@ -525,18 +527,19 @@ public final class DefaultHlsPlaylistTracker
public void onLoadCompleted( public void onLoadCompleted(
ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs, long loadDurationMs) { ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs, long loadDurationMs) {
HlsPlaylist result = loadable.getResult(); HlsPlaylist result = loadable.getResult();
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded());
loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
if (result instanceof HlsMediaPlaylist) { if (result instanceof HlsMediaPlaylist) {
processLoadedPlaylist((HlsMediaPlaylist) result, loadDurationMs); processLoadedPlaylist((HlsMediaPlaylist) result, loadDurationMs);
eventDispatcher.loadCompleted( eventDispatcher.loadCompleted(loadEventInfo, C.DATA_TYPE_MANIFEST);
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded()),
C.DATA_TYPE_MANIFEST);
} else { } else {
playlistError = new ParserException("Loaded playlist has unexpected type."); playlistError = new ParserException("Loaded playlist has unexpected type.");
} }
@ -548,7 +551,7 @@ public final class DefaultHlsPlaylistTracker
long elapsedRealtimeMs, long elapsedRealtimeMs,
long loadDurationMs, long loadDurationMs,
boolean released) { boolean released) {
eventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -556,8 +559,9 @@ public final class DefaultHlsPlaylistTracker
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
C.DATA_TYPE_MANIFEST); loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
eventDispatcher.loadCanceled(loadEventInfo, C.DATA_TYPE_MANIFEST);
} }
@Override @Override

View File

@ -621,7 +621,7 @@ public final class SsMediaSource extends BaseMediaSource
@Override @Override
public void onLoadCompleted( public void onLoadCompleted(
ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs, long loadDurationMs) { ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -629,8 +629,9 @@ public final class SsMediaSource extends BaseMediaSource
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type); loadErrorHandlingPolicy.onLoadCompleted(loadEventInfo);
manifestEventDispatcher.loadCompleted(loadEventInfo, loadable.type);
manifest = loadable.getResult(); manifest = loadable.getResult();
manifestLoadStartTimestamp = elapsedRealtimeMs - loadDurationMs; manifestLoadStartTimestamp = elapsedRealtimeMs - loadDurationMs;
processManifest(); processManifest();
@ -643,7 +644,7 @@ public final class SsMediaSource extends BaseMediaSource
long elapsedRealtimeMs, long elapsedRealtimeMs,
long loadDurationMs, long loadDurationMs,
boolean released) { boolean released) {
manifestEventDispatcher.loadCanceled( LoadEventInfo loadEventInfo =
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -651,8 +652,9 @@ public final class SsMediaSource extends BaseMediaSource
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type); loadErrorHandlingPolicy.onLoadCanceled(loadEventInfo);
manifestEventDispatcher.loadCanceled(loadEventInfo, loadable.type);
} }
@Override @Override