Pass LoadErrorInfo to LoadErrorHandlingPolcy

Issue: #7309
PiperOrigin-RevId: 309749566
This commit is contained in:
aquilescanta 2020-05-04 16:36:55 +01:00 committed by Oliver Woodman
parent 862a6e4dd2
commit fff3f99f4a
8 changed files with 168 additions and 115 deletions

View File

@ -55,22 +55,28 @@ public final class MediaLoadData {
*/ */
public final long mediaEndTimeMs; public final long mediaEndTimeMs;
/** Creates an instance with the given {@link #dataType}. */
public MediaLoadData(int dataType) {
this(
dataType,
/* trackType= */ C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
/* trackSelectionReason= */ C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaStartTimeMs= */ C.TIME_UNSET,
/* mediaEndTimeMs= */ C.TIME_UNSET);
}
/** /**
* Creates media load data. * Creates media load data.
* *
* @param dataType One of the {@link C} {@code DATA_TYPE_*} constants defining the type of data. * @param dataType See {@link #dataType}.
* @param trackType One of the {@link C} {@code TRACK_TYPE_*} constants if the data corresponds to * @param trackType See {@link #trackType}.
* media of a specific type. {@link C#TRACK_TYPE_UNKNOWN} otherwise. * @param trackFormat See {@link #trackFormat}.
* @param trackFormat The format of the track to which the data belongs. Null if the data does not * @param trackSelectionReason See {@link #trackSelectionReason}.
* belong to a track. * @param trackSelectionData See {@link #trackSelectionData}.
* @param trackSelectionReason One of the {@link C} {@code SELECTION_REASON_*} constants if the * @param mediaStartTimeMs See {@link #mediaStartTimeMs}.
* data belongs to a track. {@link C#SELECTION_REASON_UNKNOWN} otherwise. * @param mediaEndTimeMs See {@link #mediaEndTimeMs}.
* @param trackSelectionData Optional data associated with the selection of the track to which the
* data belongs. Null if the data does not belong to a track.
* @param mediaStartTimeMs The start time of the media, or {@link C#TIME_UNSET} if the data does
* not belong to a specific media period.
* @param mediaEndTimeMs The end time of the media, or {@link C#TIME_UNSET} if the data does not
* belong to a specific media period or the end time is unknown.
*/ */
public MediaLoadData( public MediaLoadData(
int dataType, int dataType,

View File

@ -41,6 +41,7 @@ import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.Loader.Loadable; import com.google.android.exoplayer2.upstream.Loader.Loadable;
@ -620,9 +621,29 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
IOException error, IOException error,
int errorCount) { int errorCount) {
copyLengthFromLoader(loadable); copyLengthFromLoader(loadable);
StatsDataSource dataSource = loadable.dataSource;
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
dataSource.getBytesRead());
MediaLoadData mediaLoadData =
new MediaLoadData(
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaStartTimeMs= */ C.usToMs(loadable.seekTimeUs),
C.usToMs(durationUs));
LoadErrorAction loadErrorAction; LoadErrorAction loadErrorAction;
long retryDelayMs = long retryDelayMs =
loadErrorHandlingPolicy.getRetryDelayMsFor(dataType, loadDurationMs, error, errorCount); loadErrorHandlingPolicy.getRetryDelayMsFor(
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount));
if (retryDelayMs == C.TIME_UNSET) { if (retryDelayMs == C.TIME_UNSET) {
loadErrorAction = Loader.DONT_RETRY_FATAL; loadErrorAction = Loader.DONT_RETRY_FATAL;
} else /* the load should be retried */ { } else /* the load should be retried */ {
@ -634,17 +655,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
: Loader.DONT_RETRY; : Loader.DONT_RETRY;
} }
StatsDataSource dataSource = loadable.dataSource;
boolean wasCanceled = !loadErrorAction.isRetry(); boolean wasCanceled = !loadErrorAction.isRetry();
eventDispatcher.loadError( eventDispatcher.loadError(
new LoadEventInfo( loadEventInfo,
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
dataSource.getBytesRead()),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
/* trackFormat= */ null, /* trackFormat= */ null,

View File

@ -26,6 +26,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.Loader.Loadable; import com.google.android.exoplayer2.upstream.Loader.Loadable;
@ -271,9 +272,28 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
StatsDataSource dataSource = loadable.dataSource;
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
dataSource.getBytesRead());
MediaLoadData mediaLoadData =
new MediaLoadData(
C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN,
format,
C.SELECTION_REASON_UNKNOWN,
/* trackSelectionData= */ null,
/* mediaStartTimeMs= */ 0,
C.usToMs(durationUs));
long retryDelay = long retryDelay =
loadErrorHandlingPolicy.getRetryDelayMsFor( loadErrorHandlingPolicy.getRetryDelayMsFor(
C.DATA_TYPE_MEDIA, loadDurationMs, error, errorCount); new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount));
boolean errorCanBePropagated = boolean errorCanBePropagated =
retryDelay == C.TIME_UNSET retryDelay == C.TIME_UNSET
|| errorCount || errorCount
@ -289,17 +309,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelay) ? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelay)
: Loader.DONT_RETRY_FATAL; : Loader.DONT_RETRY_FATAL;
} }
StatsDataSource dataSource = loadable.dataSource;
boolean wasCanceled = !action.isRetry(); boolean wasCanceled = !action.isRetry();
eventDispatcher.loadError( eventDispatcher.loadError(
new LoadEventInfo( loadEventInfo,
loadable.loadTaskId,
loadable.dataSpec,
dataSource.getLastOpenedUri(),
dataSource.getLastResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
dataSource.getBytesRead()),
C.DATA_TYPE_MEDIA, C.DATA_TYPE_MEDIA,
C.TRACK_TYPE_UNKNOWN, C.TRACK_TYPE_UNKNOWN,
format, format,

View File

@ -25,12 +25,14 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.drm.DrmSession; import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.SampleQueue; import com.google.android.exoplayer2.source.SampleQueue;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.SequenceableLoader; import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -470,10 +472,30 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
int lastChunkIndex = mediaChunks.size() - 1; int lastChunkIndex = mediaChunks.size() - 1;
boolean cancelable = boolean cancelable =
bytesLoaded == 0 || !isMediaChunk || !haveReadFromMediaChunk(lastChunkIndex); bytesLoaded == 0 || !isMediaChunk || !haveReadFromMediaChunk(lastChunkIndex);
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
bytesLoaded);
MediaLoadData mediaLoadData =
new MediaLoadData(
loadable.type,
primaryTrackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
C.usToMs(loadable.startTimeUs),
C.usToMs(loadable.endTimeUs));
LoadErrorInfo loadErrorInfo =
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount);
long blacklistDurationMs = long blacklistDurationMs =
cancelable cancelable
? loadErrorHandlingPolicy.getBlacklistDurationMsFor( ? loadErrorHandlingPolicy.getBlacklistDurationMsFor(loadErrorInfo)
loadable.type, loadDurationMs, error, errorCount)
: C.TIME_UNSET; : C.TIME_UNSET;
@Nullable LoadErrorAction loadErrorAction = null; @Nullable LoadErrorAction loadErrorAction = null;
if (chunkSource.onChunkLoadError(loadable, cancelable, error, blacklistDurationMs)) { if (chunkSource.onChunkLoadError(loadable, cancelable, error, blacklistDurationMs)) {
@ -493,9 +515,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
if (loadErrorAction == null) { if (loadErrorAction == null) {
// The load was not cancelled. Either the load must be retried or the error propagated. // The load was not cancelled. Either the load must be retried or the error propagated.
long retryDelayMs = long retryDelayMs = loadErrorHandlingPolicy.getRetryDelayMsFor(loadErrorInfo);
loadErrorHandlingPolicy.getRetryDelayMsFor(
loadable.type, loadDurationMs, error, errorCount);
loadErrorAction = loadErrorAction =
retryDelayMs != C.TIME_UNSET retryDelayMs != C.TIME_UNSET
? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs) ? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs)
@ -504,14 +524,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
boolean canceled = !loadErrorAction.isRetry(); boolean canceled = !loadErrorAction.isRetry();
eventDispatcher.loadError( eventDispatcher.loadError(
new LoadEventInfo( loadEventInfo,
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
bytesLoaded),
loadable.type, loadable.type,
primaryTrackType, primaryTrackType,
loadable.trackFormat, loadable.trackFormat,

View File

@ -34,6 +34,7 @@ import com.google.android.exoplayer2.source.BaseMediaSource;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.DefaultCompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.DefaultCompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.MediaSourceEventListener;
@ -49,6 +50,7 @@ import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
@ -852,15 +854,7 @@ public final class DashMediaSource extends BaseMediaSource {
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
long retryDelayMs = LoadEventInfo loadEventInfo =
loadErrorHandlingPolicy.getRetryDelayMsFor(
C.DATA_TYPE_MANIFEST, loadDurationMs, error, errorCount);
LoadErrorAction loadErrorAction =
retryDelayMs == C.TIME_UNSET
? Loader.DONT_RETRY_FATAL
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
boolean wasCanceled = !loadErrorAction.isRetry();
manifestEventDispatcher.loadError(
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -868,10 +862,17 @@ public final class DashMediaSource extends BaseMediaSource {
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type, MediaLoadData mediaLoadData = new MediaLoadData(loadable.type);
error, LoadErrorInfo loadErrorInfo =
wasCanceled); new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount);
long retryDelayMs = loadErrorHandlingPolicy.getRetryDelayMsFor(loadErrorInfo);
LoadErrorAction loadErrorAction =
retryDelayMs == C.TIME_UNSET
? Loader.DONT_RETRY_FATAL
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
boolean wasCanceled = !loadErrorAction.isRetry();
manifestEventDispatcher.loadError(loadEventInfo, loadable.type, error, wasCanceled);
if (wasCanceled) { if (wasCanceled) {
loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId); loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);
} }

View File

@ -38,6 +38,7 @@ import com.google.android.exoplayer2.metadata.emsg.EventMessage;
import com.google.android.exoplayer2.metadata.emsg.EventMessageDecoder; import com.google.android.exoplayer2.metadata.emsg.EventMessageDecoder;
import com.google.android.exoplayer2.metadata.id3.PrivFrame; import com.google.android.exoplayer2.metadata.id3.PrivFrame;
import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.SampleQueue; import com.google.android.exoplayer2.source.SampleQueue;
import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener; import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener;
@ -51,6 +52,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.upstream.DataReader;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
@ -768,11 +770,28 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
long bytesLoaded = loadable.bytesLoaded(); long bytesLoaded = loadable.bytesLoaded();
boolean isMediaChunk = isMediaChunk(loadable); boolean isMediaChunk = isMediaChunk(loadable);
boolean blacklistSucceeded = false; boolean blacklistSucceeded = false;
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
bytesLoaded);
MediaLoadData mediaLoadData =
new MediaLoadData(
loadable.type,
trackType,
loadable.trackFormat,
loadable.trackSelectionReason,
loadable.trackSelectionData,
C.usToMs(loadable.startTimeUs),
C.usToMs(loadable.endTimeUs));
LoadErrorInfo loadErrorInfo =
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount);
LoadErrorAction loadErrorAction; LoadErrorAction loadErrorAction;
long blacklistDurationMs = loadErrorHandlingPolicy.getBlacklistDurationMsFor(loadErrorInfo);
long blacklistDurationMs =
loadErrorHandlingPolicy.getBlacklistDurationMsFor(
loadable.type, loadDurationMs, error, errorCount);
if (blacklistDurationMs != C.TIME_UNSET) { if (blacklistDurationMs != C.TIME_UNSET) {
blacklistSucceeded = chunkSource.maybeBlacklistTrack(loadable, blacklistDurationMs); blacklistSucceeded = chunkSource.maybeBlacklistTrack(loadable, blacklistDurationMs);
} }
@ -787,9 +806,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
} }
loadErrorAction = Loader.DONT_RETRY; loadErrorAction = Loader.DONT_RETRY;
} else /* did not blacklist */ { } else /* did not blacklist */ {
long retryDelayMs = long retryDelayMs = loadErrorHandlingPolicy.getRetryDelayMsFor(loadErrorInfo);
loadErrorHandlingPolicy.getRetryDelayMsFor(
loadable.type, loadDurationMs, error, errorCount);
loadErrorAction = loadErrorAction =
retryDelayMs != C.TIME_UNSET retryDelayMs != C.TIME_UNSET
? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs) ? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs)
@ -798,14 +815,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
boolean wasCanceled = !loadErrorAction.isRetry(); boolean wasCanceled = !loadErrorAction.isRetry();
eventDispatcher.loadError( eventDispatcher.loadError(
new LoadEventInfo( loadEventInfo,
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
bytesLoaded),
loadable.type, loadable.type,
trackType, trackType,
loadable.trackFormat, loadable.trackFormat,

View File

@ -22,12 +22,14 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory; import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
@ -281,11 +283,7 @@ public final class DefaultHlsPlaylistTracker
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
long retryDelayMs = LoadEventInfo loadEventInfo =
loadErrorHandlingPolicy.getRetryDelayMsFor(
loadable.type, loadDurationMs, error, errorCount);
boolean isFatal = retryDelayMs == C.TIME_UNSET;
eventDispatcher.loadError(
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -293,10 +291,13 @@ public final class DefaultHlsPlaylistTracker
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
C.DATA_TYPE_MANIFEST, MediaLoadData mediaLoadData = new MediaLoadData(loadable.type);
error, long retryDelayMs =
isFatal); loadErrorHandlingPolicy.getRetryDelayMsFor(
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount));
boolean isFatal = retryDelayMs == C.TIME_UNSET;
eventDispatcher.loadError(loadEventInfo, loadable.type, error, isFatal);
if (isFatal) { if (isFatal) {
loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId); loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);
} }
@ -576,11 +577,20 @@ public final class DefaultHlsPlaylistTracker
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded());
MediaLoadData mediaLoadData = new MediaLoadData(loadable.type);
LoadErrorInfo loadErrorInfo =
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount);
LoadErrorAction loadErrorAction; LoadErrorAction loadErrorAction;
long blacklistDurationMs = loadErrorHandlingPolicy.getBlacklistDurationMsFor(loadErrorInfo);
long blacklistDurationMs =
loadErrorHandlingPolicy.getBlacklistDurationMsFor(
loadable.type, loadDurationMs, error, errorCount);
boolean shouldBlacklist = blacklistDurationMs != C.TIME_UNSET; boolean shouldBlacklist = blacklistDurationMs != C.TIME_UNSET;
boolean blacklistingFailed = boolean blacklistingFailed =
@ -590,9 +600,7 @@ public final class DefaultHlsPlaylistTracker
} }
if (blacklistingFailed) { if (blacklistingFailed) {
long retryDelay = long retryDelay = loadErrorHandlingPolicy.getRetryDelayMsFor(loadErrorInfo);
loadErrorHandlingPolicy.getRetryDelayMsFor(
loadable.type, loadDurationMs, error, errorCount);
loadErrorAction = loadErrorAction =
retryDelay != C.TIME_UNSET retryDelay != C.TIME_UNSET
? Loader.createRetryAction(false, retryDelay) ? Loader.createRetryAction(false, retryDelay)
@ -602,18 +610,7 @@ public final class DefaultHlsPlaylistTracker
} }
boolean wasCanceled = !loadErrorAction.isRetry(); boolean wasCanceled = !loadErrorAction.isRetry();
eventDispatcher.loadError( eventDispatcher.loadError(loadEventInfo, loadable.type, error, wasCanceled);
new LoadEventInfo(
loadable.loadTaskId,
loadable.dataSpec,
loadable.getUri(),
loadable.getResponseHeaders(),
elapsedRealtimeMs,
loadDurationMs,
loadable.bytesLoaded()),
C.DATA_TYPE_MANIFEST,
error,
wasCanceled);
if (wasCanceled) { if (wasCanceled) {
loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId); loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);
} }

View File

@ -31,6 +31,7 @@ import com.google.android.exoplayer2.source.BaseMediaSource;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.DefaultCompositeSequenceableLoaderFactory; import com.google.android.exoplayer2.source.DefaultCompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.LoadEventInfo; import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.MediaSourceEventListener;
@ -46,6 +47,7 @@ import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction; import com.google.android.exoplayer2.upstream.Loader.LoadErrorAction;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
@ -664,15 +666,7 @@ public final class SsMediaSource extends BaseMediaSource
long loadDurationMs, long loadDurationMs,
IOException error, IOException error,
int errorCount) { int errorCount) {
long retryDelayMs = LoadEventInfo loadEventInfo =
loadErrorHandlingPolicy.getRetryDelayMsFor(
C.DATA_TYPE_MANIFEST, loadDurationMs, error, errorCount);
LoadErrorAction loadErrorAction =
retryDelayMs == C.TIME_UNSET
? Loader.DONT_RETRY_FATAL
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
boolean wasCanceled = !loadErrorAction.isRetry();
manifestEventDispatcher.loadError(
new LoadEventInfo( new LoadEventInfo(
loadable.loadTaskId, loadable.loadTaskId,
loadable.dataSpec, loadable.dataSpec,
@ -680,10 +674,17 @@ public final class SsMediaSource extends BaseMediaSource
loadable.getResponseHeaders(), loadable.getResponseHeaders(),
elapsedRealtimeMs, elapsedRealtimeMs,
loadDurationMs, loadDurationMs,
loadable.bytesLoaded()), loadable.bytesLoaded());
loadable.type, MediaLoadData mediaLoadData = new MediaLoadData(loadable.type);
error, long retryDelayMs =
wasCanceled); loadErrorHandlingPolicy.getRetryDelayMsFor(
new LoadErrorInfo(loadEventInfo, mediaLoadData, error, errorCount));
LoadErrorAction loadErrorAction =
retryDelayMs == C.TIME_UNSET
? Loader.DONT_RETRY_FATAL
: Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs);
boolean wasCanceled = !loadErrorAction.isRetry();
manifestEventDispatcher.loadError(loadEventInfo, loadable.type, error, wasCanceled);
if (wasCanceled) { if (wasCanceled) {
loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId); loadErrorHandlingPolicy.onLoadTaskConcluded(loadable.loadTaskId);
} }