Add loadTaskId to LoadEventInfo

To be used by the LoadErrorHandlingPolicy.

PiperOrigin-RevId: 308657905
This commit is contained in:
aquilescanta 2020-04-27 19:08:18 +01:00 committed by Oliver Woodman
parent 0ba397cd4e
commit b5112492be
13 changed files with 84 additions and 32 deletions

View File

@ -34,6 +34,8 @@ public final class LoadEventInfo {
return idSource.getAndIncrement();
}
/** Identifies the load task to which this event corresponds. */
public final long loadTaskId;
/** Defines the requested data. */
public final DataSpec dataSpec;
/**
@ -52,11 +54,13 @@ public final class LoadEventInfo {
public final long bytesLoaded;
/**
* Equivalent to {@link #LoadEventInfo(DataSpec, Uri, Map, long, long, long)
* LoadEventInfo(dataSpec, dataSpec.uri, Collections.emptyMap(), elapsedRealtimeMs, 0, 0)}.
* Equivalent to {@link #LoadEventInfo(long, DataSpec, Uri, Map, long, long, long)
* LoadEventInfo(loadTaskId, dataSpec, dataSpec.uri, Collections.emptyMap(), elapsedRealtimeMs, 0,
* 0)}.
*/
public LoadEventInfo(DataSpec dataSpec, long elapsedRealtimeMs) {
public LoadEventInfo(long loadTaskId, DataSpec dataSpec, long elapsedRealtimeMs) {
this(
loadTaskId,
dataSpec,
dataSpec.uri,
Collections.emptyMap(),
@ -68,25 +72,23 @@ public final class LoadEventInfo {
/**
* Creates load event info.
*
* @param dataSpec Defines the requested data.
* @param uri The {@link Uri} from which data is being read. The uri must be identical to the one
* in {@code dataSpec.uri} unless redirection has occurred. If redirection has occurred, this
* is the uri after redirection.
* @param responseHeaders The response headers associated with the load, or an empty map if
* unavailable.
* @param elapsedRealtimeMs The value of {@link SystemClock#elapsedRealtime} at the time of the
* load event.
* @param loadDurationMs The duration of the load up to the event time.
* @param bytesLoaded The number of bytes that were loaded up to the event time. For compressed
* network responses, this is the decompressed size.
* @param loadTaskId See {@link #loadTaskId}.
* @param dataSpec See {@link #dataSpec}.
* @param uri See {@link #uri}.
* @param responseHeaders See {@link #responseHeaders}.
* @param elapsedRealtimeMs See {@link #elapsedRealtimeMs}.
* @param loadDurationMs See {@link #loadDurationMs}.
* @param bytesLoaded See {@link #bytesLoaded}.
*/
public LoadEventInfo(
long loadTaskId,
DataSpec dataSpec,
Uri uri,
Map<String, List<String>> responseHeaders,
long elapsedRealtimeMs,
long loadDurationMs,
long bytesLoaded) {
this.loadTaskId = loadTaskId;
this.dataSpec = dataSpec;
this.uri = uri;
this.responseHeaders = responseHeaders;

View File

@ -555,6 +555,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -579,6 +580,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -628,6 +630,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -789,7 +792,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(dataType));
DataSpec dataSpec = loadable.dataSpec;
eventDispatcher.loadStarted(
new LoadEventInfo(dataSpec, elapsedRealtimeMs),
new LoadEventInfo(loadable.loadTaskId, dataSpec, elapsedRealtimeMs),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -928,6 +931,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Loads the media stream and extracts sample data from it. */
/* package */ final class ExtractingLoadable implements Loadable, IcyDataSource.Listener {
private final long loadTaskId;
private final Uri uri;
private final StatsDataSource dataSource;
private final ProgressiveMediaExtractor progressiveMediaExtractor;
@ -959,6 +963,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
this.positionHolder = new PositionHolder();
this.pendingExtractorSeek = true;
this.length = C.LENGTH_UNSET;
loadTaskId = LoadEventInfo.getNewId();
dataSpec = buildDataSpec(/* position= */ 0);
}

View File

@ -154,13 +154,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (transferListener != null) {
dataSource.addTransferListener(transferListener);
}
SourceLoadable loadable = new SourceLoadable(dataSpec, dataSource);
long elapsedRealtimeMs =
loader.startLoading(
new SourceLoadable(dataSpec, dataSource),
loadable,
/* callback= */ this,
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(C.DATA_TYPE_MEDIA));
eventDispatcher.loadStarted(
new LoadEventInfo(dataSpec, elapsedRealtimeMs),
new LoadEventInfo(loadable.loadTaskId, dataSpec, elapsedRealtimeMs),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
@ -219,6 +220,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -240,6 +242,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -283,6 +286,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
StatsDataSource dataSource = loadable.dataSource;
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
@ -382,6 +386,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* package */ static final class SourceLoadable implements Loadable {
public final long loadTaskId;
public final DataSpec dataSpec;
private final StatsDataSource dataSource;
@ -389,6 +394,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Nullable private byte[] sampleData;
public SourceLoadable(DataSpec dataSpec, DataSource dataSource) {
this.loadTaskId = LoadEventInfo.getNewId();
this.dataSpec = dataSpec;
this.dataSource = new StatsDataSource(dataSource);
}

View File

@ -355,7 +355,10 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
}
createEventDispatcher(/* mediaPeriodId= */ null)
.loadError(
new LoadEventInfo(dataSpec, /* elapsedRealtimeMs= */ SystemClock.elapsedRealtime()),
new LoadEventInfo(
LoadEventInfo.getNewId(),
dataSpec,
/* elapsedRealtimeMs= */ SystemClock.elapsedRealtime()),
C.DATA_TYPE_AD,
error,
/* wasCanceled= */ true);
@ -379,7 +382,9 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
createEventDispatcher(mediaPeriodId)
.loadError(
new LoadEventInfo(
new DataSpec(adUri), /* elapsedRealtimeMs= */ SystemClock.elapsedRealtime()),
LoadEventInfo.getNewId(),
new DataSpec(adUri),
/* elapsedRealtimeMs= */ SystemClock.elapsedRealtime()),
C.DATA_TYPE_AD,
AdLoadException.createForAd(exception),
/* wasCanceled= */ true);

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
@ -33,9 +34,9 @@ import java.util.Map;
*/
public abstract class Chunk implements Loadable {
/**
* The {@link DataSpec} that defines the data to be loaded.
*/
/** Identifies the load task for this loadable. */
public final long loadTaskId;
/** The {@link DataSpec} that defines the data to be loaded. */
public final DataSpec dataSpec;
/**
* The type of the chunk. One of the {@code DATA_TYPE_*} constants defined in {@link C}. For
@ -95,6 +96,7 @@ public abstract class Chunk implements Loadable {
this.trackSelectionData = trackSelectionData;
this.startTimeUs = startTimeUs;
this.endTimeUs = endTimeUs;
loadTaskId = LoadEventInfo.getNewId();
}
/**

View File

@ -407,6 +407,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -428,6 +429,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -497,6 +499,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
boolean canceled = !loadErrorAction.isRetry();
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -568,7 +571,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
loader.startLoading(
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
new LoadEventInfo(loadable.dataSpec, elapsedRealtimeMs),
new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, elapsedRealtimeMs),
loadable.type,
primaryTrackType,
loadable.trackFormat,

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
@ -87,9 +88,9 @@ public final class ParsingLoadable<T> implements Loadable {
return Assertions.checkNotNull(loadable.getResult());
}
/**
* The {@link DataSpec} that defines the data to be loaded.
*/
/** Identifies the load task for this loadable. */
public final long loadTaskId;
/** The {@link DataSpec} that defines the data to be loaded. */
public final DataSpec dataSpec;
/**
* The type of the data. One of the {@code DATA_TYPE_*} constants defined in {@link C}. For
@ -128,6 +129,7 @@ public final class ParsingLoadable<T> implements Loadable {
this.dataSpec = dataSpec;
this.type = type;
this.parser = parser;
loadTaskId = LoadEventInfo.getNewId();
}
/** Returns the loaded object, or null if an object has not been loaded. */

View File

@ -756,6 +756,7 @@ public final class DashMediaSource extends BaseMediaSource {
long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -859,6 +860,7 @@ public final class DashMediaSource extends BaseMediaSource {
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
manifestEventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -875,6 +877,7 @@ public final class DashMediaSource extends BaseMediaSource {
long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -892,6 +895,7 @@ public final class DashMediaSource extends BaseMediaSource {
IOException error) {
manifestEventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -909,6 +913,7 @@ public final class DashMediaSource extends BaseMediaSource {
long loadDurationMs) {
manifestEventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -1129,7 +1134,8 @@ public final class DashMediaSource extends BaseMediaSource {
Loader.Callback<ParsingLoadable<T>> callback, int minRetryCount) {
long elapsedRealtimeMs = loader.startLoading(loadable, callback, minRetryCount);
manifestEventDispatcher.loadStarted(
new LoadEventInfo(loadable.dataSpec, elapsedRealtimeMs), loadable.type);
new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, elapsedRealtimeMs),
loadable.type);
}
private static final class PeriodSeekInfo {

View File

@ -676,7 +676,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
loader.startLoading(
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
new LoadEventInfo(loadable.dataSpec, elapsedRealtimeMs),
new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, elapsedRealtimeMs),
loadable.type,
trackType,
loadable.trackFormat,
@ -704,6 +704,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
chunkSource.onChunkLoadCompleted(loadable);
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -729,6 +730,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
Chunk loadable, long elapsedRealtimeMs, long loadDurationMs, boolean released) {
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -790,6 +792,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),

View File

@ -136,7 +136,8 @@ public final class DefaultHlsPlaylistTracker
this,
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(masterPlaylistLoadable.type));
eventDispatcher.loadStarted(
new LoadEventInfo(masterPlaylistLoadable.dataSpec, elapsedRealtime),
new LoadEventInfo(
masterPlaylistLoadable.loadTaskId, masterPlaylistLoadable.dataSpec, elapsedRealtime),
masterPlaylistLoadable.type);
}
@ -243,6 +244,7 @@ public final class DefaultHlsPlaylistTracker
}
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -260,6 +262,7 @@ public final class DefaultHlsPlaylistTracker
boolean released) {
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -282,6 +285,7 @@ public final class DefaultHlsPlaylistTracker
boolean isFatal = retryDelayMs == C.TIME_UNSET;
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -525,6 +529,7 @@ public final class DefaultHlsPlaylistTracker
processLoadedPlaylist((HlsMediaPlaylist) result, loadDurationMs);
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -545,6 +550,7 @@ public final class DefaultHlsPlaylistTracker
boolean released) {
eventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -588,6 +594,7 @@ public final class DefaultHlsPlaylistTracker
eventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -618,7 +625,8 @@ public final class DefaultHlsPlaylistTracker
this,
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(mediaPlaylistLoadable.type));
eventDispatcher.loadStarted(
new LoadEventInfo(mediaPlaylistLoadable.dataSpec, elapsedRealtime),
new LoadEventInfo(
mediaPlaylistLoadable.loadTaskId, mediaPlaylistLoadable.dataSpec, elapsedRealtime),
mediaPlaylistLoadable.type);
}

View File

@ -623,6 +623,7 @@ public final class SsMediaSource extends BaseMediaSource
ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs, long loadDurationMs) {
manifestEventDispatcher.loadCompleted(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -644,6 +645,7 @@ public final class SsMediaSource extends BaseMediaSource
boolean released) {
manifestEventDispatcher.loadCanceled(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -669,6 +671,7 @@ public final class SsMediaSource extends BaseMediaSource
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
manifestEventDispatcher.loadError(
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
@ -772,7 +775,8 @@ public final class SsMediaSource extends BaseMediaSource
manifestLoader.startLoading(
loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
manifestEventDispatcher.loadStarted(
new LoadEventInfo(loadable.dataSpec, elapsedRealtimeMs), loadable.type);
new LoadEventInfo(loadable.loadTaskId, loadable.dataSpec, elapsedRealtimeMs),
loadable.type);
}
}

View File

@ -50,6 +50,7 @@ public class FakeMediaPeriod implements MediaPeriod {
private final TrackGroupArray trackGroupArray;
private final List<SampleStream> sampleStreams;
private final EventDispatcher eventDispatcher;
private final long fakePreparationLoadTaskId;
@Nullable private Handler playerHandler;
@Nullable private Callback prepareCallback;
@ -82,6 +83,7 @@ public class FakeMediaPeriod implements MediaPeriod {
this.deferOnPrepared = deferOnPrepared;
discontinuityPositionUs = C.TIME_UNSET;
sampleStreams = new ArrayList<>();
fakePreparationLoadTaskId = LoadEventInfo.getNewId();
eventDispatcher.mediaPeriodCreated();
}
@ -122,7 +124,7 @@ public class FakeMediaPeriod implements MediaPeriod {
@Override
public synchronized void prepare(Callback callback, long positionUs) {
eventDispatcher.loadStarted(
new LoadEventInfo(FAKE_DATA_SPEC, SystemClock.elapsedRealtime()),
new LoadEventInfo(fakePreparationLoadTaskId, FAKE_DATA_SPEC, SystemClock.elapsedRealtime()),
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
@ -274,6 +276,7 @@ public class FakeMediaPeriod implements MediaPeriod {
Util.castNonNull(prepareCallback).onPrepared(this);
eventDispatcher.loadCompleted(
new LoadEventInfo(
fakePreparationLoadTaskId,
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),

View File

@ -261,8 +261,10 @@ public class FakeMediaSource extends BaseMediaSource {
/* mediaEndTimeMs = */ C.TIME_UNSET);
long elapsedRealTimeMs = SystemClock.elapsedRealtime();
EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null);
long loadTaskId = LoadEventInfo.getNewId();
eventDispatcher.loadStarted(
new LoadEventInfo(
loadTaskId,
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),
@ -272,6 +274,7 @@ public class FakeMediaSource extends BaseMediaSource {
mediaLoadData);
eventDispatcher.loadCompleted(
new LoadEventInfo(
loadTaskId,
FAKE_DATA_SPEC,
FAKE_DATA_SPEC.uri,
/* responseHeaders= */ Collections.emptyMap(),