diff --git a/library/core/src/main/java/com/google/android/exoplayer2/C.java b/library/core/src/main/java/com/google/android/exoplayer2/C.java
index b09d570219..587dd50ea2 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/C.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/C.java
@@ -488,32 +488,24 @@ public final class C {
*/
public static final int RESULT_FORMAT_READ = -5;
- /**
- * A data type constant for data of unknown or unspecified type.
- */
+ /** A data type constant for data of unknown or unspecified type. */
public static final int DATA_TYPE_UNKNOWN = 0;
- /**
- * A data type constant for media, typically containing media samples.
- */
+ /** A data type constant for media, typically containing media samples. */
public static final int DATA_TYPE_MEDIA = 1;
- /**
- * A data type constant for media, typically containing only initialization data.
- */
+ /** A data type constant for media, typically containing only initialization data. */
public static final int DATA_TYPE_MEDIA_INITIALIZATION = 2;
- /**
- * A data type constant for drm or encryption data.
- */
+ /** A data type constant for drm or encryption data. */
public static final int DATA_TYPE_DRM = 3;
- /**
- * A data type constant for a manifest file.
- */
+ /** A data type constant for a manifest file. */
public static final int DATA_TYPE_MANIFEST = 4;
- /**
- * A data type constant for time synchronization data.
- */
+ /** A data type constant for time synchronization data. */
public static final int DATA_TYPE_TIME_SYNCHRONIZATION = 5;
/** A data type constant for ads loader data. */
public static final int DATA_TYPE_AD = 6;
+ /**
+ * A data type constant for progressive media live streams, typically containing media samples.
+ */
+ public static final int DATA_TYPE_MEDIA_LIVE_STREAM = 7;
/**
* Applications or extensions may define custom {@code DATA_TYPE_*} constants greater than or
* equal to this value.
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java
new file mode 100644
index 0000000000..1c78fb0969
--- /dev/null
+++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.exoplayer2.upstream;
+
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.ParserException;
+import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil;
+import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
+import java.io.IOException;
+
+/** Default implementation of {@link LoadErrorHandlingPolicy}. */
+public final class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy {
+
+ /** The default minimum number of times to retry loading data prior to propagating the error. */
+ public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
+
+ private final int minimumLoadableRetryCount;
+
+ /** Creates an instance that returns the default values. */
+ public DefaultLoadErrorHandlingPolicy() {
+ this(DEFAULT_MIN_LOADABLE_RETRY_COUNT);
+ }
+
+ /**
+ * Creates an instance with the given value for {@link #getMinimumLoadableRetryCount(int)}.
+ *
+ * @param minimumLoadableRetryCount See {@link #getMinimumLoadableRetryCount}.
+ */
+ public DefaultLoadErrorHandlingPolicy(int minimumLoadableRetryCount) {
+ this.minimumLoadableRetryCount = minimumLoadableRetryCount;
+ }
+
+ /**
+ * Blacklists resources whose load error was an {@link InvalidResponseCodeException} with response
+ * code HTTP 404 or 410. The duration of the blacklisting is {@link
+ * ChunkedTrackBlacklistUtil#DEFAULT_TRACK_BLACKLIST_MS}.
+ */
+ @Override
+ public long getBlacklistDurationMsFor(
+ int dataType, long loadDurationMs, IOException exception, int errorCount) {
+ if (exception instanceof InvalidResponseCodeException) {
+ int responseCode = ((InvalidResponseCodeException) exception).responseCode;
+ return responseCode == 404 // HTTP 404 Not Found.
+ || responseCode == 410 // HTTP 410 Gone.
+ ? ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS
+ : C.TIME_UNSET;
+ }
+ return C.TIME_UNSET;
+ }
+
+ /**
+ * Retries for any exception that is not a subclass of {@link ParserException}. The retry delay is
+ * calculated as {@code Math.min((errorCount - 1) * 1000, 5000)}.
+ */
+ @Override
+ public long getRetryDelayMsFor(
+ int dataType, long loadDurationMs, IOException exception, int errorCount) {
+ return exception instanceof ParserException
+ ? C.TIME_UNSET
+ : Math.min((errorCount - 1) * 1000, 5000);
+ }
+
+ /** Returns {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT}. */
+ @Override
+ public int getMinimumLoadableRetryCount(int dataType) {
+ return minimumLoadableRetryCount;
+ }
+}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java b/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java
index 8d6c0b9cf1..579169ad94 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java
@@ -16,9 +16,6 @@
package com.google.android.exoplayer2.upstream;
import com.google.android.exoplayer2.C;
-import com.google.android.exoplayer2.ParserException;
-import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil;
-import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
import com.google.android.exoplayer2.upstream.Loader.Callback;
import com.google.android.exoplayer2.upstream.Loader.Loadable;
import java.io.IOException;
@@ -29,74 +26,22 @@ import java.io.IOException;
*
Loader clients may blacklist a resource when a load error occurs. Blacklisting works around
* load errors by loading an alternative resource. Clients do not try blacklisting when a resource
* does not have an alternative. When a resource does have valid alternatives, {@link
- * #getBlacklistDurationMsFor(T, long, IOException, int)} defines whether the resource should be
+ * #getBlacklistDurationMsFor(int, long, IOException, int)} defines whether the resource should be
* blacklisted. Blacklisting will succeed if any of the alternatives is not in the black list.
*
- *
When blacklisting does not take place, {@link #getRetryDelayMsFor(T, long, IOException, int)}
- * defines whether the load is retried. Errors whose load is not retried are propagated. Load errors
- * whose load is retried are propagated according to {@link
- * #getMinimumLoadableRetryCount(Loadable)}.
- *
- * @param The type of the object being loaded.
+ * When blacklisting does not take place, {@link #getRetryDelayMsFor(int, long, IOException,
+ * int)} defines whether the load is retried. Errors whose load is not retried are propagated. Load
+ * errors whose load is retried are propagated according to {@link
+ * #getMinimumLoadableRetryCount(int)}.
*/
-public interface LoadErrorHandlingPolicy {
-
- /** The default minimum number of times to retry loading data prior to propagating the error. */
- int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
-
- /** Default implementation of {@link LoadErrorHandlingPolicy}. */
- LoadErrorHandlingPolicy DEFAULT =
- new LoadErrorHandlingPolicy() {
-
- /**
- * Blacklists resources whose load error was an {@link InvalidResponseCodeException} with
- * response code HTTP 404 or 410. The duration of the blacklisting is {@link
- * ChunkedTrackBlacklistUtil#DEFAULT_TRACK_BLACKLIST_MS}.
- */
- @Override
- public long getBlacklistDurationMsFor(
- Loadable loadable, long loadDurationMs, IOException exception, int errorCount) {
- if (exception instanceof InvalidResponseCodeException) {
- int responseCode = ((InvalidResponseCodeException) exception).responseCode;
- return responseCode == 404 // HTTP 404 Not Found.
- || responseCode == 410 // HTTP 410 Gone.
- ? ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS
- : C.TIME_UNSET;
- }
- return C.TIME_UNSET;
- }
-
- /**
- * Retries for any exception that is not a subclass of {@link ParserException}. The retry
- * delay is calculated as {@code Math.min((errorCount - 1) * 1000, 5000)}.
- */
- @Override
- public long getRetryDelayMsFor(
- Loadable loadable, long loadDurationMs, IOException exception, int errorCount) {
- return exception instanceof ParserException
- ? C.TIME_UNSET
- : Math.min((errorCount - 1) * 1000, 5000);
- }
-
- /** Returns {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT}. */
- @Override
- public int getMinimumLoadableRetryCount(Loadable loadable) {
- return DEFAULT_MIN_LOADABLE_RETRY_COUNT;
- }
- };
-
- /** Returns {@link #DEFAULT}. */
- static LoadErrorHandlingPolicy getDefault() {
- @SuppressWarnings("unchecked") // Safe contravariant cast.
- LoadErrorHandlingPolicy policy = (LoadErrorHandlingPolicy) DEFAULT;
- return policy;
- }
+public interface LoadErrorHandlingPolicy {
/**
* Returns the number of milliseconds for which a resource associated to a provided load error
* should be blacklisted, or {@link C#TIME_UNSET} if the resource should not be blacklisted.
*
- * @param loadable The loadable whose load failed.
+ * @param dataType One of the {@link C C.DATA_TYPE_*} constants indicating the type of data to
+ * load.
* @param loadDurationMs The duration in milliseconds of the load up to the point at which the
* error occurred, including any previous attempts.
* @param exception The load error.
@@ -105,7 +50,7 @@ public interface LoadErrorHandlingPolicy {
* not be blacklisted.
*/
long getBlacklistDurationMsFor(
- T loadable, long loadDurationMs, IOException exception, int errorCount);
+ int dataType, long loadDurationMs, IOException exception, int errorCount);
/**
* Returns the number of milliseconds to wait before attempting the load again, or {@link
@@ -115,7 +60,8 @@ public interface LoadErrorHandlingPolicy {
* for a specific event before retrying. However, the load is retried if and only if this method
* does not return {@link C#TIME_UNSET}.
*
- * @param loadable The loadable whose load failed.
+ * @param dataType One of the {@link C C.DATA_TYPE_*} constants indicating the type of data to
+ * load.
* @param loadDurationMs The duration in milliseconds of the load up to the point at which the
* error occurred, including any previous attempts.
* @param exception The load error.
@@ -123,16 +69,17 @@ public interface LoadErrorHandlingPolicy {
* @return The number of milliseconds to wait before attempting the load again, or {@link
* C#TIME_UNSET} if the error is fatal and should not be retried.
*/
- long getRetryDelayMsFor(T loadable, long loadDurationMs, IOException exception, int errorCount);
+ long getRetryDelayMsFor(int dataType, long loadDurationMs, IOException exception, int errorCount);
/**
* Returns the minimum number of times to retry a load in the case of a load error, before
* propagating the error.
*
- * @param loadable The loadable to load.
+ * @param dataType One of the {@link C C.DATA_TYPE_*} constants indicating the type of data to
+ * load.
* @return The minimum number of times to retry a load in the case of a load error, before
* propagating the error.
* @see Loader#startLoading(Loadable, Callback, int)
*/
- int getMinimumLoadableRetryCount(T loadable);
+ int getMinimumLoadableRetryCount(int dataType);
}
diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java
index 295ebfb518..3879c62650 100644
--- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java
+++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java
@@ -30,7 +30,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-/** Unit tests for {@link LoadErrorHandlingPolicy#DEFAULT}. */
+/** Unit tests for {@link DefaultLoadErrorHandlingPolicy}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultLoadErrorHandlingPolicyTest {
@@ -90,12 +90,13 @@ public final class DefaultLoadErrorHandlingPolicyTest {
}
private static long getDefaultPolicyBlacklistOutputFor(IOException exception) {
- return LoadErrorHandlingPolicy.DEFAULT.getBlacklistDurationMsFor(
- DUMMY_LOADABLE, /* loadDurationMs= */ 1000, exception, /* errorCount= */ 1);
+ return new DefaultLoadErrorHandlingPolicy()
+ .getBlacklistDurationMsFor(
+ C.DATA_TYPE_MEDIA, /* loadDurationMs= */ 1000, exception, /* errorCount= */ 1);
}
private static long getDefaultPolicyRetryDelayOutputFor(IOException exception, int errorCount) {
- return LoadErrorHandlingPolicy.DEFAULT.getRetryDelayMsFor(
- DUMMY_LOADABLE, /* loadDurationMs= */ 1000, exception, errorCount);
+ return new DefaultLoadErrorHandlingPolicy()
+ .getRetryDelayMsFor(C.DATA_TYPE_MEDIA, /* loadDurationMs= */ 1000, exception, errorCount);
}
}
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
index 1beb7e2e5a..c8cf8151c5 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
@@ -27,7 +27,6 @@ import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
-import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
@@ -56,8 +55,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
private final HlsPlaylistTracker playlistTracker;
private final HlsDataSourceFactory dataSourceFactory;
private final @Nullable TransferListener mediaTransferListener;
- private final LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy;
- private final int minLoadableRetryCount;
+ private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final EventDispatcher eventDispatcher;
private final Allocator allocator;
private final IdentityHashMap streamWrapperIndices;
@@ -82,8 +80,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
* and keys.
* @param mediaTransferListener The transfer listener to inform of any media data transfers. May
* be null if no listener is available.
- * @param chunkLoadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy} for chunk loads.
- * @param minLoadableRetryCount The minimum number of times to retry if a loading error occurs.
+ * @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}.
* @param eventDispatcher A dispatcher to notify of events.
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
* @param compositeSequenceableLoaderFactory A factory to create composite {@link
@@ -95,8 +92,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
HlsPlaylistTracker playlistTracker,
HlsDataSourceFactory dataSourceFactory,
@Nullable TransferListener mediaTransferListener,
- LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy,
- int minLoadableRetryCount,
+ LoadErrorHandlingPolicy loadErrorHandlingPolicy,
EventDispatcher eventDispatcher,
Allocator allocator,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
@@ -105,8 +101,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
this.playlistTracker = playlistTracker;
this.dataSourceFactory = dataSourceFactory;
this.mediaTransferListener = mediaTransferListener;
- this.chunkLoadErrorHandlingPolicy = chunkLoadErrorHandlingPolicy;
- this.minLoadableRetryCount = minLoadableRetryCount;
+ this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
this.eventDispatcher = eventDispatcher;
this.allocator = allocator;
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
@@ -532,8 +527,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
allocator,
positionUs,
muxedAudioFormat,
- chunkLoadErrorHandlingPolicy,
- minLoadableRetryCount,
+ loadErrorHandlingPolicy,
eventDispatcher);
}
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java
index 112071f1f2..6efa9728e9 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java
@@ -32,7 +32,6 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispat
import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
-import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.hls.playlist.DefaultHlsPlaylistTracker;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
@@ -40,6 +39,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
+import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.upstream.TransferListener;
@@ -64,8 +64,7 @@ public final class HlsMediaSource extends BaseMediaSource
private @Nullable ParsingLoadable.Parser playlistParser;
private @Nullable HlsPlaylistTracker playlistTracker;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
- private LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy;
- private int minLoadableRetryCount;
+ private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private boolean allowChunklessPreparation;
private boolean isCreateCalled;
private @Nullable Object tag;
@@ -90,8 +89,7 @@ public final class HlsMediaSource extends BaseMediaSource
public Factory(HlsDataSourceFactory hlsDataSourceFactory) {
this.hlsDataSourceFactory = Assertions.checkNotNull(hlsDataSourceFactory);
extractorFactory = HlsExtractorFactory.DEFAULT;
- chunkLoadErrorHandlingPolicy = LoadErrorHandlingPolicy.getDefault();
- minLoadableRetryCount = DEFAULT_MIN_LOADABLE_RETRY_COUNT;
+ loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
}
@@ -126,31 +124,41 @@ public final class HlsMediaSource extends BaseMediaSource
}
/**
- * Sets the {@link LoadErrorHandlingPolicy} for chunk loads. The default value is {@link
- * LoadErrorHandlingPolicy#DEFAULT}.
+ * Sets the {@link LoadErrorHandlingPolicy}. The default value is created by calling {@link
+ * DefaultLoadErrorHandlingPolicy()}.
*
- * @param chunkLoadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy} for chunk loads.
+ * Calling this method overrides any calls to {@link #setMinLoadableRetryCount(int)}.
+ *
+ *
If {@link #setPlaylistTracker} is not called on this builder, {@code
+ * loadErrorHandlingPolicy} is used for creating the used {@link DefaultHlsPlaylistTracker}.
+ *
+ * @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}.
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/
- public Factory setChunkLoadErrorHandlingPolicy(
- LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy) {
+ public Factory setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
Assertions.checkState(!isCreateCalled);
- this.chunkLoadErrorHandlingPolicy = chunkLoadErrorHandlingPolicy;
+ this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
return this;
}
/**
* Sets the minimum number of times to retry if a loading error occurs. The default value is
- * {@link #DEFAULT_MIN_LOADABLE_RETRY_COUNT}.
+ * {@link DefaultLoadErrorHandlingPolicy#DEFAULT_MIN_LOADABLE_RETRY_COUNT}.
+ *
+ * Calling this method is equivalent to calling {@link #setLoadErrorHandlingPolicy} with
+ * {@link DefaultLoadErrorHandlingPolicy(int)
+ * DefaultLoadErrorHandlingPolicy(minLoadableRetryCount)}
*
* @param minLoadableRetryCount The minimum number of times to retry if a loading error occurs.
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
+ * @deprecated Use {@link #setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy)} instead.
*/
+ @Deprecated
public Factory setMinLoadableRetryCount(int minLoadableRetryCount) {
Assertions.checkState(!isCreateCalled);
- this.minLoadableRetryCount = minLoadableRetryCount;
+ this.loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy(minLoadableRetryCount);
return this;
}
@@ -234,8 +242,7 @@ public final class HlsMediaSource extends BaseMediaSource
playlistTracker =
new DefaultHlsPlaylistTracker(
hlsDataSourceFactory,
- LoadErrorHandlingPolicy.getDefault(),
- minLoadableRetryCount,
+ loadErrorHandlingPolicy,
playlistParser != null ? playlistParser : new HlsPlaylistParser());
}
return new HlsMediaSource(
@@ -243,8 +250,7 @@ public final class HlsMediaSource extends BaseMediaSource
hlsDataSourceFactory,
extractorFactory,
compositeSequenceableLoaderFactory,
- chunkLoadErrorHandlingPolicy,
- minLoadableRetryCount,
+ loadErrorHandlingPolicy,
playlistTracker,
allowChunklessPreparation,
tag);
@@ -270,19 +276,14 @@ public final class HlsMediaSource extends BaseMediaSource
public int[] getSupportedTypes() {
return new int[] {C.TYPE_HLS};
}
- }
- /**
- * The default minimum number of times to retry loading data prior to failing.
- */
- public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
+ }
private final HlsExtractorFactory extractorFactory;
private final Uri manifestUri;
private final HlsDataSourceFactory dataSourceFactory;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
- private final LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy;
- private final int minLoadableRetryCount;
+ private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final boolean allowChunklessPreparation;
private final HlsPlaylistTracker playlistTracker;
private final @Nullable Object tag;
@@ -304,7 +305,11 @@ public final class HlsMediaSource extends BaseMediaSource
DataSource.Factory dataSourceFactory,
Handler eventHandler,
MediaSourceEventListener eventListener) {
- this(manifestUri, dataSourceFactory, DEFAULT_MIN_LOADABLE_RETRY_COUNT, eventHandler,
+ this(
+ manifestUri,
+ dataSourceFactory,
+ DefaultLoadErrorHandlingPolicy.DEFAULT_MIN_LOADABLE_RETRY_COUNT,
+ eventHandler,
eventListener);
}
@@ -363,12 +368,10 @@ public final class HlsMediaSource extends BaseMediaSource
dataSourceFactory,
extractorFactory,
new DefaultCompositeSequenceableLoaderFactory(),
- LoadErrorHandlingPolicy.getDefault(),
- minLoadableRetryCount,
+ new DefaultLoadErrorHandlingPolicy(minLoadableRetryCount),
new DefaultHlsPlaylistTracker(
dataSourceFactory,
- LoadErrorHandlingPolicy.getDefault(),
- minLoadableRetryCount,
+ new DefaultLoadErrorHandlingPolicy(minLoadableRetryCount),
playlistParser),
/* allowChunklessPreparation= */ false,
/* tag= */ null);
@@ -382,8 +385,7 @@ public final class HlsMediaSource extends BaseMediaSource
HlsDataSourceFactory dataSourceFactory,
HlsExtractorFactory extractorFactory,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
- LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy,
- int minLoadableRetryCount,
+ LoadErrorHandlingPolicy loadErrorHandlingPolicy,
HlsPlaylistTracker playlistTracker,
boolean allowChunklessPreparation,
@Nullable Object tag) {
@@ -391,8 +393,7 @@ public final class HlsMediaSource extends BaseMediaSource
this.dataSourceFactory = dataSourceFactory;
this.extractorFactory = extractorFactory;
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
- this.chunkLoadErrorHandlingPolicy = chunkLoadErrorHandlingPolicy;
- this.minLoadableRetryCount = minLoadableRetryCount;
+ this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
this.playlistTracker = playlistTracker;
this.allowChunklessPreparation = allowChunklessPreparation;
this.tag = tag;
@@ -422,8 +423,7 @@ public final class HlsMediaSource extends BaseMediaSource
playlistTracker,
dataSourceFactory,
mediaTransferListener,
- chunkLoadErrorHandlingPolicy,
- minLoadableRetryCount,
+ loadErrorHandlingPolicy,
eventDispatcher,
allocator,
compositeSequenceableLoaderFactory,
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
index 73114f43c0..7061e3e738 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
@@ -85,8 +85,7 @@ import java.util.List;
private final HlsChunkSource chunkSource;
private final Allocator allocator;
private final Format muxedAudioFormat;
- private final LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy;
- private final int minLoadableRetryCount;
+ private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final Loader loader;
private final EventDispatcher eventDispatcher;
private final HlsChunkSource.HlsChunkHolder nextChunkHolder;
@@ -141,9 +140,7 @@ import java.util.List;
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
* @param positionUs The position from which to start loading media.
* @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the master playlist.
- * @param chunkLoadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy} for chunk loads.
- * @param minLoadableRetryCount The minimum number of times that the source should retry a load
- * before propagating an error.
+ * @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}.
* @param eventDispatcher A dispatcher to notify of events.
*/
public HlsSampleStreamWrapper(
@@ -153,16 +150,14 @@ import java.util.List;
Allocator allocator,
long positionUs,
Format muxedAudioFormat,
- LoadErrorHandlingPolicy chunkLoadErrorHandlingPolicy,
- int minLoadableRetryCount,
+ LoadErrorHandlingPolicy loadErrorHandlingPolicy,
EventDispatcher eventDispatcher) {
this.trackType = trackType;
this.callback = callback;
this.chunkSource = chunkSource;
this.allocator = allocator;
this.muxedAudioFormat = muxedAudioFormat;
- this.chunkLoadErrorHandlingPolicy = chunkLoadErrorHandlingPolicy;
- this.minLoadableRetryCount = minLoadableRetryCount;
+ this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
this.eventDispatcher = eventDispatcher;
loader = new Loader("Loader:HlsSampleStreamWrapper");
nextChunkHolder = new HlsChunkSource.HlsChunkHolder();
@@ -571,7 +566,9 @@ import java.util.List;
mediaChunks.add(mediaChunk);
upstreamTrackFormat = mediaChunk.trackFormat;
}
- long elapsedRealtimeMs = loader.startLoading(loadable, this, minLoadableRetryCount);
+ long elapsedRealtimeMs =
+ loader.startLoading(
+ loadable, this, loadErrorHandlingPolicy.getMinimumLoadableRetryCount(loadable.type));
eventDispatcher.loadStarted(
loadable.dataSpec,
loadable.dataSpec.uri,
@@ -654,8 +651,8 @@ import java.util.List;
if (!isMediaChunk || bytesLoaded == 0) {
long blacklistDurationMs =
- chunkLoadErrorHandlingPolicy.getBlacklistDurationMsFor(
- loadable, loadDurationMs, error, errorCount);
+ loadErrorHandlingPolicy.getBlacklistDurationMsFor(
+ loadable.type, loadDurationMs, error, errorCount);
if (blacklistDurationMs != C.TIME_UNSET) {
blacklistSucceeded = chunkSource.maybeBlacklistTrack(loadable, blacklistDurationMs);
}
@@ -672,8 +669,8 @@ import java.util.List;
loadErrorAction = Loader.DONT_RETRY;
} else /* did not blacklist */ {
long retryDelayMs =
- chunkLoadErrorHandlingPolicy.getRetryDelayMsFor(
- loadable, loadDurationMs, error, errorCount);
+ loadErrorHandlingPolicy.getRetryDelayMsFor(
+ loadable.type, loadDurationMs, error, errorCount);
loadErrorAction =
retryDelayMs != C.TIME_UNSET
? Loader.createRetryAction(/* resetErrorCount= */ false, retryDelayMs)
diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
index 099002a109..5cf3765b71 100644
--- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
+++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
@@ -49,9 +49,7 @@ public final class DefaultHlsPlaylistTracker
private final HlsDataSourceFactory dataSourceFactory;
private final ParsingLoadable.Parser playlistParser;
- private final LoadErrorHandlingPolicy>
- playlistLoadErrorHandlingPolicy;
- private final int minRetryCount;
+ private final LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private final IdentityHashMap playlistBundles;
private final List listeners;
@@ -67,21 +65,16 @@ public final class DefaultHlsPlaylistTracker
/**
* @param dataSourceFactory A factory for {@link DataSource} instances.
- * @param playlistLoadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy} for playlist loads.
- * @param minRetryCount The minimum number of times loads must be retried before {@link
- * #maybeThrowPlaylistRefreshError(HlsUrl)} and {@link
- * #maybeThrowPrimaryPlaylistRefreshError()} propagate any loading errors.
+ * @param loadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy}.
* @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists.
*/
public DefaultHlsPlaylistTracker(
HlsDataSourceFactory dataSourceFactory,
- LoadErrorHandlingPolicy> playlistLoadErrorHandlingPolicy,
- int minRetryCount,
+ LoadErrorHandlingPolicy loadErrorHandlingPolicy,
ParsingLoadable.Parser playlistParser) {
this.dataSourceFactory = dataSourceFactory;
- this.minRetryCount = minRetryCount;
this.playlistParser = playlistParser;
- this.playlistLoadErrorHandlingPolicy = playlistLoadErrorHandlingPolicy;
+ this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
listeners = new ArrayList<>();
playlistBundles = new IdentityHashMap<>();
initialStartTimeUs = C.TIME_UNSET;
@@ -106,7 +99,10 @@ public final class DefaultHlsPlaylistTracker
Assertions.checkState(initialPlaylistLoader == null);
initialPlaylistLoader = new Loader("DefaultHlsPlaylistTracker:MasterPlaylist");
long elapsedRealtime =
- initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount);
+ initialPlaylistLoader.startLoading(
+ masterPlaylistLoadable,
+ this,
+ loadErrorHandlingPolicy.getMinimumLoadableRetryCount(masterPlaylistLoadable.type));
eventDispatcher.loadStarted(
masterPlaylistLoadable.dataSpec,
masterPlaylistLoadable.dataSpec.uri,
@@ -248,8 +244,8 @@ public final class DefaultHlsPlaylistTracker
IOException error,
int errorCount) {
long retryDelayMs =
- playlistLoadErrorHandlingPolicy.getRetryDelayMsFor(
- loadable, loadDurationMs, error, errorCount);
+ loadErrorHandlingPolicy.getRetryDelayMsFor(
+ loadable.type, loadDurationMs, error, errorCount);
boolean isFatal = retryDelayMs == C.TIME_UNSET;
eventDispatcher.loadError(
loadable.dataSpec,
@@ -515,8 +511,8 @@ public final class DefaultHlsPlaylistTracker
LoadErrorAction loadErrorAction;
long blacklistDurationMs =
- playlistLoadErrorHandlingPolicy.getBlacklistDurationMsFor(
- loadable, loadDurationMs, error, errorCount);
+ loadErrorHandlingPolicy.getBlacklistDurationMsFor(
+ loadable.type, loadDurationMs, error, errorCount);
boolean shouldBlacklist = blacklistDurationMs != C.TIME_UNSET;
boolean blacklistingFailed =
@@ -527,8 +523,8 @@ public final class DefaultHlsPlaylistTracker
if (blacklistingFailed) {
long retryDelay =
- playlistLoadErrorHandlingPolicy.getRetryDelayMsFor(
- loadable, loadDurationMs, error, errorCount);
+ loadErrorHandlingPolicy.getRetryDelayMsFor(
+ loadable.type, loadDurationMs, error, errorCount);
loadErrorAction =
retryDelay != C.TIME_UNSET
? Loader.createRetryAction(false, retryDelay)
@@ -562,7 +558,10 @@ public final class DefaultHlsPlaylistTracker
private void loadPlaylistImmediately() {
long elapsedRealtime =
- mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
+ mediaPlaylistLoader.startLoading(
+ mediaPlaylistLoadable,
+ this,
+ loadErrorHandlingPolicy.getMinimumLoadableRetryCount(mediaPlaylistLoadable.type));
eventDispatcher.loadStarted(
mediaPlaylistLoadable.dataSpec,
mediaPlaylistLoadable.dataSpec.uri,