Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
6dbc1eb1
authored
Jul 06, 2021
by
bachinger
Committed by
kim-vde
Jul 09, 2021
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Make customization of fallback selection more flexible
PiperOrigin-RevId: 383245932
parent
15c565c7
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
451 additions
and
106 deletions
library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java
library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java
library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSourceTest.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java
library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java
View file @
6dbc1eb1
...
...
@@ -383,7 +383,8 @@ public class DefaultDrmSessionManager implements DrmSessionManager {
multiSession
,
/* useDrmSessionsForClearContentTrackTypes= */
new
int
[
0
],
/* playClearSamplesWithoutKeys= */
false
,
new
DefaultLoadErrorHandlingPolicy
(
initialDrmRequestRetryCount
),
new
DefaultLoadErrorHandlingPolicy
(
initialDrmRequestRetryCount
,
/* locationExclusionEnabled= */
false
),
DEFAULT_SESSION_KEEPALIVE_MS
);
}
...
...
library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java
View file @
6dbc1eb1
...
...
@@ -15,10 +15,12 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
trackselection
;
import
android.os.SystemClock
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.source.TrackGroupArray
;
import
com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride
;
import
com.google.android.exoplayer2.trackselection.ExoTrackSelection.Definition
;
import
com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
org.checkerframework.checker.nullness.compatqual.NullableType
;
...
...
@@ -114,4 +116,29 @@ public final class TrackSelectionUtil {
}
return
false
;
}
/**
* Returns the {@link LoadErrorHandlingPolicy.FallbackOptions} with the tracks of the given {@link
* ExoTrackSelection} and with a single location option indicating that there are no alternative
* locations available.
*
* @param trackSelection The track selection to get the number of total and excluded tracks.
* @return The {@link LoadErrorHandlingPolicy.FallbackOptions} for the given track selection.
*/
public
static
LoadErrorHandlingPolicy
.
FallbackOptions
createFallbackOptions
(
ExoTrackSelection
trackSelection
)
{
long
nowMs
=
SystemClock
.
elapsedRealtime
();
int
numberOfTracks
=
trackSelection
.
length
();
int
numberOfExcludedTracks
=
0
;
for
(
int
i
=
0
;
i
<
numberOfTracks
;
i
++)
{
if
(
trackSelection
.
isBlacklisted
(
i
,
nowMs
))
{
numberOfExcludedTracks
++;
}
}
return
new
LoadErrorHandlingPolicy
.
FallbackOptions
(
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
numberOfTracks
,
numberOfExcludedTracks
);
}
}
library/core/src/main/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicy.java
View file @
6dbc1eb1
...
...
@@ -45,6 +45,7 @@ public class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy {
private
static
final
int
DEFAULT_BEHAVIOR_MIN_LOADABLE_RETRY_COUNT
=
-
1
;
private
final
int
minimumLoadableRetryCount
;
private
final
boolean
locationExclusionEnabled
;
/**
* Creates an instance with default behavior.
...
...
@@ -53,44 +54,72 @@ public class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy {
* #DEFAULT_MIN_LOADABLE_RETRY_COUNT_PROGRESSIVE_LIVE} for {@code dataType} {@link
* C#DATA_TYPE_MEDIA_PROGRESSIVE_LIVE}. For other {@code dataType} values, it will return {@link
* #DEFAULT_MIN_LOADABLE_RETRY_COUNT}.
*
* <p>Exclusion of both fallback types {@link #FALLBACK_TYPE_TRACK} and {@link
* #FALLBACK_TYPE_TRACK} is enabled by default.
*/
public
DefaultLoadErrorHandlingPolicy
()
{
this
(
DEFAULT_BEHAVIOR_MIN_LOADABLE_RETRY_COUNT
);
this
(
DEFAULT_BEHAVIOR_MIN_LOADABLE_RETRY_COUNT
,
/* locationExclusionEnabled= */
true
);
}
/** @deprecated Use {@link #DefaultLoadErrorHandlingPolicy(int, boolean)} instead. */
@Deprecated
public
DefaultLoadErrorHandlingPolicy
(
int
minimumLoadableRetryCount
)
{
this
(
minimumLoadableRetryCount
,
/* locationExclusionEnabled= */
true
);
}
/**
* Creates an instance with the given value for {@link #getMinimumLoadableRetryCount(int)}.
*
* @param minimumLoadableRetryCount See {@link #getMinimumLoadableRetryCount}.
* @param locationExclusionEnabled Whether location exclusion is enabled.
*/
public
DefaultLoadErrorHandlingPolicy
(
int
minimumLoadableRetryCount
)
{
public
DefaultLoadErrorHandlingPolicy
(
int
minimumLoadableRetryCount
,
boolean
locationExclusionEnabled
)
{
this
.
minimumLoadableRetryCount
=
minimumLoadableRetryCount
;
this
.
locationExclusionEnabled
=
locationExclusionEnabled
;
}
/**
* Returns the exclusion duration, given by {@link #DEFAULT_TRACK_EXCLUSION_MS} or {@link
* Returns the fallback selection.
*
* <p>The exclusion duration is given by {@link #DEFAULT_TRACK_EXCLUSION_MS} or {@link
* #DEFAULT_LOCATION_EXCLUSION_MS}, if the load error was an {@link InvalidResponseCodeException}
* with an HTTP response code indicating an unrecoverable error, or {@link C#TIME_UNSET}
* otherwise.
*
* <p>If alternative locations are advertised by the {@link
* LoadErrorHandlingPolicy.FallbackOptions}, {@link #FALLBACK_TYPE_LOCATION} is selected until all
* locations are excluded, {@link #FALLBACK_TYPE_TRACK} otherwise.
*/
@Override
public
long
getExclusionDurationMsFor
(
@FallbackType
int
fallbackType
,
LoadErrorInfo
loadErrorInfo
)
{
public
FallbackSelection
getFallbackSelectionFor
(
FallbackOptions
fallbackOptions
,
LoadErrorInfo
loadErrorInfo
)
{
@FallbackType
int
fallbackType
=
FALLBACK_TYPE_TRACK
;
boolean
fallbackAvailable
=
fallbackOptions
.
numberOfTracks
-
fallbackOptions
.
numberOfExcludedTracks
>
1
;
if
(
locationExclusionEnabled
&&
fallbackOptions
.
numberOfLocations
-
fallbackOptions
.
numberOfExcludedLocations
>
1
)
{
fallbackType
=
FALLBACK_TYPE_LOCATION
;
fallbackAvailable
=
true
;
}
long
exclusionDurationMs
=
C
.
TIME_UNSET
;
IOException
exception
=
loadErrorInfo
.
exception
;
if
(
exception
instanceof
InvalidResponseCodeException
)
{
if
(
fallbackAvailable
&&
exception
instanceof
InvalidResponseCodeException
)
{
int
responseCode
=
((
InvalidResponseCodeException
)
exception
).
responseCode
;
return
responseCode
==
403
// HTTP 403 Forbidden.
||
responseCode
==
404
// HTTP 404 Not Found.
||
responseCode
==
410
// HTTP 410 Gone.
||
responseCode
==
416
// HTTP 416 Range Not Satisfiable.
||
responseCode
==
500
// HTTP 500 Internal Server Error.
||
responseCode
==
503
// HTTP 503 Service Unavailable.
?
(
fallbackType
==
FALLBACK_TYPE_TRACK
?
DEFAULT_TRACK_EXCLUSION_MS
:
DEFAULT_LOCATION_EXCLUSION_MS
)
:
C
.
TIME_UNSET
;
exclusionDurationMs
=
responseCode
==
403
// HTTP 403 Forbidden.
||
responseCode
==
404
// HTTP 404 Not Found.
||
responseCode
==
410
// HTTP 410 Gone.
||
responseCode
==
416
// HTTP 416 Range Not Satisfiable.
||
responseCode
==
500
// HTTP 500 Internal Server Error.
||
responseCode
==
503
// HTTP 503 Service Unavailable.
?
(
fallbackType
==
FALLBACK_TYPE_TRACK
?
DEFAULT_TRACK_EXCLUSION_MS
:
DEFAULT_LOCATION_EXCLUSION_MS
)
:
C
.
TIME_UNSET
;
}
return
C
.
TIME_UNSET
;
return
new
FallbackSelection
(
fallbackType
,
exclusionDurationMs
)
;
}
/**
...
...
library/core/src/main/java/com/google/android/exoplayer2/upstream/LoadErrorHandlingPolicy.java
View file @
6dbc1eb1
...
...
@@ -30,11 +30,11 @@ import java.lang.annotation.RetentionPolicy;
* Defines how errors encountered by loaders are handled.
*
* <p>A loader that can choose between one of a number of resources can exclude a resource when a
* load error occurs. In this case, {@link #get
ExclusionDurationMsFor(int, LoadErrorInfo)} defines
*
whether the resource should be excluded for a given {@link FallbackType fallback type}, and if so
*
for how long. If the policy indicates that a resource should be excluded, the loader will exclude
*
it for the specified amount of time unless all of the alternatives for the given fallback type
* are already excluded.
* load error occurs. In this case, {@link #get
FallbackSelectionFor(FallbackOptions, LoadErrorInfo)}
*
defines whether the resource should be excluded for a given {@link FallbackType fallback type},
*
and if so for how long. If the policy indicates that a resource should be excluded, the loader
*
will exclude it for the specified amount of time unless all of the alternatives for the given
*
fallback type
are already excluded.
*
* <p>When exclusion does not take place, {@link #getRetryDelayMsFor(LoadErrorInfo)} defines whether
* the load is retried. An error that's not retried will always be propagated. An error that is
...
...
@@ -87,17 +87,65 @@ public interface LoadErrorHandlingPolicy {
}
}
/** Holds information about the available fallback options. */
final
class
FallbackOptions
{
/** The number of total available alternative locations. */
public
final
int
numberOfLocations
;
/** The number of locations that are already excluded. */
public
final
int
numberOfExcludedLocations
;
/** The number of total available tracks. */
public
final
int
numberOfTracks
;
/** The number of tracks that are already excluded. */
public
final
int
numberOfExcludedTracks
;
/** Creates an instance with the given values. */
public
FallbackOptions
(
int
numberOfLocations
,
int
numberOfExcludedLocations
,
int
numberOfTracks
,
int
numberOfExcludedTracks
)
{
this
.
numberOfLocations
=
numberOfLocations
;
this
.
numberOfExcludedLocations
=
numberOfExcludedLocations
;
this
.
numberOfTracks
=
numberOfTracks
;
this
.
numberOfExcludedTracks
=
numberOfExcludedTracks
;
}
}
/** The selection of a fallback option determining the fallback behaviour on load error. */
final
class
FallbackSelection
{
/** The {@link FallbackType fallback type} to use. */
@FallbackType
public
final
int
type
;
/**
* The exclusion duration of the {@link #type} in milliseconds, or {@link C#TIME_UNSET} to
* disable exclusion of any fallback type.
*/
public
final
long
exclusionDurationMs
;
/** Creates an instance with the given values. */
public
FallbackSelection
(
@FallbackType
int
type
,
long
exclusionDurationMs
)
{
this
.
type
=
type
;
this
.
exclusionDurationMs
=
exclusionDurationMs
;
}
}
/**
* Returns the number of milliseconds for which a resource associated to a provided load error
* should be excluded for a given {@link FallbackType fallback type}, or {@link C#TIME_UNSET} if
* the resource should not be excluded.
* Returns the {@link FallbackSelection fallback selection} that determines the exclusion
* behaviour on load error.
*
* <p>If {@link FallbackSelection#exclusionDurationMs} is {@link C#TIME_UNSET}, exclusion is
* disabled for any fallback type, regardless of the value of the {@link FallbackSelection#type
* selected fallback type}.
*
* <p>If {@link FallbackSelection#type} is of a type that is not advertised as available by the
* {@link FallbackOptions}, exclusion is disabled for any fallback type.
*
* @param fallback
Type The {@link FallbackType fallback type} used for exclusion
.
* @param fallback
Options The available fallback options
.
* @param loadErrorInfo A {@link LoadErrorInfo} holding information about the load error.
* @return The
exclusion duration in milliseconds, or {@link C#TIME_UNSET} if the resource should
*
not
be excluded.
* @return The
fallback selection indicating whether to apply exclusion, and if so for which type
*
and how long the resource should
be excluded.
*/
long
getExclusionDurationMsFor
(
@FallbackType
int
fallbackType
,
LoadErrorInfo
loadErrorInfo
);
FallbackSelection
getFallbackSelectionFor
(
FallbackOptions
fallbackOptions
,
LoadErrorInfo
loadErrorInfo
);
/**
* Returns the number of milliseconds to wait before attempting the load again, or {@link
...
...
library/core/src/test/java/com/google/android/exoplayer2/upstream/DefaultLoadErrorHandlingPolicyTest.java
View file @
6dbc1eb1
...
...
@@ -15,6 +15,11 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
upstream
;
import
static
com
.
google
.
android
.
exoplayer2
.
upstream
.
DefaultLoadErrorHandlingPolicy
.
DEFAULT_LOCATION_EXCLUSION_MS
;
import
static
com
.
google
.
android
.
exoplayer2
.
upstream
.
DefaultLoadErrorHandlingPolicy
.
DEFAULT_MIN_LOADABLE_RETRY_COUNT
;
import
static
com
.
google
.
android
.
exoplayer2
.
upstream
.
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
;
import
static
com
.
google
.
android
.
exoplayer2
.
upstream
.
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_LOCATION
;
import
static
com
.
google
.
android
.
exoplayer2
.
upstream
.
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
android.net.Uri
;
...
...
@@ -48,52 +53,214 @@ public final class DefaultLoadErrorHandlingPolicyTest {
new
MediaLoadData
(
/* dataType= */
C
.
DATA_TYPE_UNKNOWN
);
@Test
public
void
get
ExclusionDurationMs
For_responseCode403
()
{
public
void
get
FallbackSelection
For_responseCode403
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
403
,
"Forbidden"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
))
.
isEqualTo
(
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_LOCATION_EXCLUSION_MS
);
}
@Test
public
void
get
ExclusionDurationMs
For_responseCode404
()
{
public
void
get
FallbackSelection
For_responseCode404
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
404
,
"Not found"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
))
.
isEqualTo
(
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_LOCATION_EXCLUSION_MS
);
}
@Test
public
void
get
ExclusionDurationMs
For_responseCode410
()
{
public
void
get
FallbackSelection
For_responseCode410
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
410
,
"Gone"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
))
.
isEqualTo
(
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_LOCATION_EXCLUSION_MS
);
}
@Test
public
void
get
ExclusionDurationMs
For_responseCode500
()
{
public
void
get
FallbackSelection
For_responseCode500
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
500
,
"Internal server error"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
))
.
isEqualTo
(
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_LOCATION_EXCLUSION_MS
);
}
@Test
public
void
get
ExclusionDurationMs
For_responseCode503
()
{
public
void
get
FallbackSelection
For_responseCode503
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
503
,
"Service unavailable"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
))
.
isEqualTo
(
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_LOCATION_EXCLUSION_MS
);
}
@Test
public
void
get
ExclusionDurationMs
For_dontExcludeUnexpectedHttpCodes
()
{
public
void
get
FallbackSelection
For_dontExcludeUnexpectedHttpCodes
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
418
,
"I'm a teapot"
);
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
)).
isEqualTo
(
C
.
TIME_UNSET
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
).
isEqualTo
(
C
.
TIME_UNSET
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
).
isEqualTo
(
C
.
TIME_UNSET
);
}
@Test
public
void
get
ExclusionDurationMs
For_dontExcludeUnexpectedExceptions
()
{
public
void
get
FallbackSelection
For_dontExcludeUnexpectedExceptions
()
{
IOException
exception
=
new
IOException
();
assertThat
(
getDefaultPolicyTrackExclusionDurationMsFor
(
exception
)).
isEqualTo
(
C
.
TIME_UNSET
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
1
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
10
,
/* numberOfExcludedTracks= */
0
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
).
isEqualTo
(
C
.
TIME_UNSET
);
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
);
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_LOCATION
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
).
isEqualTo
(
C
.
TIME_UNSET
);
}
@Test
public
void
getFallbackSelectionFor_disabledLocationExclusion_useTrackExclusion
()
{
InvalidResponseCodeException
exception
=
buildInvalidResponseCodeException
(
404
,
"Not found"
);
LoadErrorHandlingPolicy
.
FallbackSelection
defaultPolicyFallbackSelection
=
getDefaultPolicyFallbackSelection
(
exception
,
/* numberOfLocations= */
2
,
/* numberOfExcludedLocations= */
0
,
/* numberOfTracks= */
4
,
/* numberOfExcludedTracks= */
1
,
new
DefaultLoadErrorHandlingPolicy
(
DEFAULT_MIN_LOADABLE_RETRY_COUNT
,
/* locationExclusionEnabled= */
false
));
assertThat
(
defaultPolicyFallbackSelection
.
type
).
isEqualTo
(
FALLBACK_TYPE_TRACK
);
assertThat
(
defaultPolicyFallbackSelection
.
exclusionDurationMs
)
.
isEqualTo
(
DEFAULT_TRACK_EXCLUSION_MS
);
}
@Test
...
...
@@ -112,15 +279,38 @@ public final class DefaultLoadErrorHandlingPolicyTest {
assertThat
(
getDefaultPolicyRetryDelayOutputFor
(
new
IOException
(),
9
)).
isEqualTo
(
5000
);
}
private
static
long
getDefaultPolicyTrackExclusionDurationMsFor
(
IOException
exception
)
{
private
static
LoadErrorHandlingPolicy
.
FallbackSelection
getDefaultPolicyFallbackSelection
(
IOException
exception
,
int
numberOfLocations
,
int
numberOfExcludedLocations
,
int
numberOfTracks
,
int
numberOfExcludedTracks
)
{
return
getDefaultPolicyFallbackSelection
(
exception
,
numberOfLocations
,
numberOfExcludedLocations
,
numberOfTracks
,
numberOfExcludedTracks
,
new
DefaultLoadErrorHandlingPolicy
());
}
private
static
LoadErrorHandlingPolicy
.
FallbackSelection
getDefaultPolicyFallbackSelection
(
IOException
exception
,
int
numberOfLocations
,
int
numberOfExcludedLocations
,
int
numberOfTracks
,
int
numberOfExcludedTracks
,
DefaultLoadErrorHandlingPolicy
defaultLoadErrorHandlingPolicy
)
{
LoadErrorInfo
loadErrorInfo
=
new
LoadErrorInfo
(
PLACEHOLDER_LOAD_EVENT_INFO
,
PLACEHOLDER_MEDIA_LOAD_DATA
,
exception
,
/* errorCount= */
1
);
return
new
DefaultLoadErrorHandlingPolicy
()
.
getExclusionDurationMsFor
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
LoadErrorHandlingPolicy
.
FallbackOptions
fallbackOptions
=
new
LoadErrorHandlingPolicy
.
FallbackOptions
(
numberOfLocations
,
numberOfExcludedLocations
,
numberOfTracks
,
numberOfExcludedTracks
);
return
defaultLoadErrorHandlingPolicy
.
getFallbackSelectionFor
(
fallbackOptions
,
loadErrorInfo
);
}
private
static
long
getDefaultPolicyRetryDelayOutputFor
(
IOException
exception
,
int
errorCount
)
{
...
...
library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSource.java
View file @
6dbc1eb1
...
...
@@ -15,6 +15,7 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
source
.
dash
;
import
static
com
.
google
.
android
.
exoplayer2
.
trackselection
.
TrackSelectionUtil
.
createFallbackOptions
;
import
static
java
.
lang
.
Math
.
max
;
import
static
java
.
lang
.
Math
.
min
;
...
...
@@ -482,11 +483,17 @@ public class DefaultDashChunkSource implements DashChunkSource {
}
}
}
long
exclusionDurationMs
=
loadErrorHandlingPolicy
.
getExclusionDurationMsFor
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
return
exclusionDurationMs
!=
C
.
TIME_UNSET
&&
trackSelection
.
blacklist
(
trackSelection
.
indexOf
(
chunk
.
trackFormat
),
exclusionDurationMs
);
LoadErrorHandlingPolicy
.
FallbackOptions
fallbackOptions
=
createFallbackOptions
(
trackSelection
);
if
(
fallbackOptions
.
numberOfTracks
-
fallbackOptions
.
numberOfExcludedTracks
<=
1
)
{
// No more alternative tracks remaining.
return
false
;
}
LoadErrorHandlingPolicy
.
FallbackSelection
fallbackSelection
=
loadErrorHandlingPolicy
.
getFallbackSelectionFor
(
fallbackOptions
,
loadErrorInfo
);
return
fallbackSelection
.
type
==
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
&&
fallbackSelection
.
exclusionDurationMs
!=
C
.
TIME_UNSET
&&
trackSelection
.
blacklist
(
trackSelection
.
indexOf
(
chunk
.
trackFormat
),
fallbackSelection
.
exclusionDurationMs
);
}
@Override
...
...
library/dash/src/test/java/com/google/android/exoplayer2/source/dash/DefaultDashChunkSourceTest.java
View file @
6dbc1eb1
...
...
@@ -150,11 +150,11 @@ public class DefaultDashChunkSourceTest {
DefaultLoadErrorHandlingPolicy
loadErrorHandlingPolicy
=
new
DefaultLoadErrorHandlingPolicy
()
{
@Override
public
long
getExclusionDurationMsFor
(
int
fallbackType
,
LoadErrorInfo
loadErrorInfo
)
{
// Try to exclude tracks only.
return
fallbackType
==
FALLBACK_TYPE_LOCATION
?
C
.
TIME_UNSET
:
super
.
getExclusionDurationMsFor
(
fallbackType
,
loadErrorInfo
);
public
FallbackSelection
getFallbackSelectionFor
(
FallbackOptions
fallbackOptions
,
LoadErrorInfo
loadErrorInfo
)
{
// Exclude tracks only.
return
new
FallbackSelection
(
FALLBACK_TYPE_TRACK
,
DefaultLoadErrorHandlingPolicy
.
DEFAULT_TRACK_EXCLUSION_MS
);
}
};
int
numberOfTracks
=
2
;
...
...
@@ -186,9 +186,10 @@ public class DefaultDashChunkSourceTest {
DefaultLoadErrorHandlingPolicy
loadErrorHandlingPolicy
=
new
DefaultLoadErrorHandlingPolicy
()
{
@Override
public
long
getExclusionDurationMsFor
(
int
fallbackType
,
LoadErrorInfo
loadErrorInfo
)
{
public
FallbackSelection
getFallbackSelectionFor
(
FallbackOptions
fallbackOptions
,
LoadErrorInfo
loadErrorInfo
)
{
// Never exclude, neither tracks nor locations.
return
C
.
TIME_UNSET
;
return
new
FallbackSelection
(
FALLBACK_TYPE_TRACK
,
C
.
TIME_UNSET
)
;
}
};
DashChunkSource
chunkSource
=
createDashChunkSource
(
/* numberOfTracks= */
2
);
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsChunkSource.java
View file @
6dbc1eb1
...
...
@@ -544,7 +544,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
seenExpectedPlaylistError
|=
playlistUrl
.
equals
(
expectedPlaylistUrl
);
return
exclusionDurationMs
==
C
.
TIME_UNSET
||
trackSelection
.
blacklist
(
trackSelectionIndex
,
exclusionDurationMs
);
||
(
trackSelection
.
blacklist
(
trackSelectionIndex
,
exclusionDurationMs
)
&&
playlistTracker
.
excludeMediaPlaylist
(
playlistUrl
,
exclusionDurationMs
));
}
/**
...
...
@@ -669,6 +670,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
return
Collections
.
unmodifiableList
(
segmentBases
);
}
/** Returns whether this chunk source obtains chunks for the playlist with the given url. */
public
boolean
obtainsChunksForPlaylist
(
Uri
playlistUrl
)
{
return
Util
.
contains
(
playlistUrls
,
playlistUrl
);
}
// Private methods.
/**
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaPeriod.java
View file @
6dbc1eb1
...
...
@@ -465,10 +465,11 @@ public final class HlsMediaPeriod
}
@Override
public
boolean
onPlaylistError
(
Uri
url
,
long
exclusionDurationMs
)
{
public
boolean
onPlaylistError
(
Uri
url
,
LoadErrorHandlingPolicy
.
LoadErrorInfo
loadErrorInfo
,
boolean
forceRetry
)
{
boolean
exclusionSucceeded
=
true
;
for
(
HlsSampleStreamWrapper
streamWrapper
:
sampleStreamWrappers
)
{
exclusionSucceeded
&=
streamWrapper
.
onPlaylistError
(
url
,
exclusionDurationMs
);
exclusionSucceeded
&=
streamWrapper
.
onPlaylistError
(
url
,
loadErrorInfo
,
forceRetry
);
}
callback
.
onContinueLoadingRequested
(
this
);
return
exclusionSucceeded
;
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java
View file @
6dbc1eb1
...
...
@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.hls;
import
static
com
.
google
.
android
.
exoplayer2
.
source
.
hls
.
HlsChunkSource
.
CHUNK_PUBLICATION_STATE_PUBLISHED
;
import
static
com
.
google
.
android
.
exoplayer2
.
source
.
hls
.
HlsChunkSource
.
CHUNK_PUBLICATION_STATE_REMOVED
;
import
static
com
.
google
.
android
.
exoplayer2
.
trackselection
.
TrackSelectionUtil
.
createFallbackOptions
;
import
static
java
.
lang
.
Math
.
max
;
import
static
java
.
lang
.
Math
.
min
;
...
...
@@ -554,7 +555,21 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
chunkSource
.
setIsTimestampMaster
(
isTimestampMaster
);
}
public
boolean
onPlaylistError
(
Uri
playlistUrl
,
long
exclusionDurationMs
)
{
public
boolean
onPlaylistError
(
Uri
playlistUrl
,
LoadErrorInfo
loadErrorInfo
,
boolean
forceRetry
)
{
if
(!
chunkSource
.
obtainsChunksForPlaylist
(
playlistUrl
))
{
// Return early if the chunk source doesn't deliver chunks for the failing playlist.
return
true
;
}
long
exclusionDurationMs
=
C
.
TIME_UNSET
;
if
(!
forceRetry
)
{
LoadErrorHandlingPolicy
.
FallbackSelection
fallbackSelection
=
loadErrorHandlingPolicy
.
getFallbackSelectionFor
(
createFallbackOptions
(
chunkSource
.
getTrackSelection
()),
loadErrorInfo
);
exclusionDurationMs
=
fallbackSelection
.
type
==
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
?
fallbackSelection
.
exclusionDurationMs
:
C
.
TIME_UNSET
;
}
return
chunkSource
.
onPlaylistError
(
playlistUrl
,
exclusionDurationMs
);
}
...
...
@@ -894,11 +909,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
LoadErrorInfo
loadErrorInfo
=
new
LoadErrorInfo
(
loadEventInfo
,
mediaLoadData
,
error
,
errorCount
);
LoadErrorAction
loadErrorAction
;
long
exclusionDurationMs
=
loadErrorHandlingPolicy
.
getExclusionDurationMsFor
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
if
(
exclusionDurationMs
!=
C
.
TIME_UNSET
)
{
exclusionSucceeded
=
chunkSource
.
maybeExcludeTrack
(
loadable
,
exclusionDurationMs
);
LoadErrorHandlingPolicy
.
FallbackSelection
fallbackSelection
=
loadErrorHandlingPolicy
.
getFallbackSelectionFor
(
createFallbackOptions
(
chunkSource
.
getTrackSelection
()),
loadErrorInfo
);
if
(
fallbackSelection
.
type
==
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
&&
fallbackSelection
.
exclusionDurationMs
!=
C
.
TIME_UNSET
)
{
exclusionSucceeded
=
chunkSource
.
maybeExcludeTrack
(
loadable
,
fallbackSelection
.
exclusionDurationMs
);
}
if
(
exclusionSucceeded
)
{
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java
View file @
6dbc1eb1
...
...
@@ -228,6 +228,15 @@ public final class DefaultHlsPlaylistTracker
return
isLive
;
}
@Override
public
boolean
excludeMediaPlaylist
(
Uri
playlistUrl
,
long
exclusionDurationMs
)
{
@Nullable
MediaPlaylistBundle
bundle
=
playlistBundles
.
get
(
playlistUrl
);
if
(
bundle
!=
null
)
{
return
!
bundle
.
excludePlaylist
(
exclusionDurationMs
);
}
return
false
;
}
// Loader.Callback implementation.
@Override
...
...
@@ -413,11 +422,13 @@ public final class DefaultHlsPlaylistTracker
}
}
private
boolean
notifyPlaylistError
(
Uri
playlistUrl
,
long
exclusionDurationMs
)
{
private
boolean
notifyPlaylistError
(
Uri
playlistUrl
,
LoadErrorInfo
loadErrorInfo
,
boolean
forceRetry
)
{
int
listenersSize
=
listeners
.
size
();
boolean
anyExclusionFailed
=
false
;
for
(
int
i
=
0
;
i
<
listenersSize
;
i
++)
{
anyExclusionFailed
|=
!
listeners
.
get
(
i
).
onPlaylistError
(
playlistUrl
,
exclusionDurationMs
);
anyExclusionFailed
|=
!
listeners
.
get
(
i
).
onPlaylistError
(
playlistUrl
,
loadErrorInfo
,
forceRetry
);
}
return
anyExclusionFailed
;
}
...
...
@@ -632,18 +643,9 @@ public final class DefaultHlsPlaylistTracker
MediaLoadData
mediaLoadData
=
new
MediaLoadData
(
loadable
.
type
);
LoadErrorInfo
loadErrorInfo
=
new
LoadErrorInfo
(
loadEventInfo
,
mediaLoadData
,
error
,
errorCount
);
LoadErrorAction
loadErrorAction
;
long
exclusionDurationMs
=
loadErrorHandlingPolicy
.
getExclusionDurationMsFor
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
boolean
shouldExclude
=
exclusionDurationMs
!=
C
.
TIME_UNSET
;
boolean
exclusionFailed
=
notifyPlaylistError
(
playlistUrl
,
exclusionDurationMs
)
||
!
shouldExclude
;
if
(
shouldExclude
)
{
exclusionFailed
|=
excludePlaylist
(
exclusionDurationMs
);
}
notifyPlaylistError
(
playlistUrl
,
loadErrorInfo
,
/* forceRetry= */
false
);
LoadErrorAction
loadErrorAction
;
if
(
exclusionFailed
)
{
long
retryDelay
=
loadErrorHandlingPolicy
.
getRetryDelayMsFor
(
loadErrorInfo
);
loadErrorAction
=
...
...
@@ -696,7 +698,7 @@ public final class DefaultHlsPlaylistTracker
long
elapsedRealtime
=
mediaPlaylistLoader
.
startLoading
(
mediaPlaylistLoadable
,
this
,
/* callback= */
this
,
loadErrorHandlingPolicy
.
getMinimumLoadableRetryCount
(
mediaPlaylistLoadable
.
type
));
eventDispatcher
.
loadStarted
(
new
LoadEventInfo
(
...
...
@@ -715,31 +717,31 @@ public final class DefaultHlsPlaylistTracker
lastSnapshotChangeMs
=
currentTimeMs
;
onPlaylistUpdated
(
playlistUrl
,
playlistSnapshot
);
}
else
if
(!
playlistSnapshot
.
hasEndTag
)
{
boolean
forceRetry
=
false
;
@Nullable
IOException
playlistError
=
null
;
if
(
loadedPlaylist
.
mediaSequence
+
loadedPlaylist
.
segments
.
size
()
<
playlistSnapshot
.
mediaSequence
)
{
// TODO: Allow customization of playlist resets handling.
// The media sequence jumped backwards. The server has probably reset. We do not try
// excluding in this case.
forceRetry
=
true
;
playlistError
=
new
PlaylistResetException
(
playlistUrl
);
notifyPlaylistError
(
playlistUrl
,
C
.
TIME_UNSET
);
}
else
if
(
currentTimeMs
-
lastSnapshotChangeMs
>
C
.
usToMs
(
playlistSnapshot
.
targetDurationUs
)
*
playlistStuckTargetDurationCoefficient
)
{
// TODO: Allow customization of stuck playlists handling.
playlistError
=
new
PlaylistStuckException
(
playlistUrl
);
LoadErrorInfo
loadErrorInfo
=
}
if
(
playlistError
!=
null
)
{
this
.
playlistError
=
playlistError
;
notifyPlaylistError
(
playlistUrl
,
new
LoadErrorInfo
(
loadEventInfo
,
new
MediaLoadData
(
C
.
DATA_TYPE_MANIFEST
),
playlistError
,
/* errorCount= */
1
);
long
exclusionDurationMs
=
loadErrorHandlingPolicy
.
getExclusionDurationMsFor
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
notifyPlaylistError
(
playlistUrl
,
exclusionDurationMs
);
if
(
exclusionDurationMs
!=
C
.
TIME_UNSET
)
{
excludePlaylist
(
exclusionDurationMs
);
}
/* errorCount= */
1
),
forceRetry
);
}
}
long
durationUntilNextLoadUs
=
0L
;
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java
View file @
6dbc1eb1
...
...
@@ -74,11 +74,12 @@ public interface HlsPlaylistTracker {
* Called if an error is encountered while loading a playlist.
*
* @param url The loaded url that caused the error.
* @param
exclusionDurationMs The duration for which the playlist should be excluded. Or {@link
*
C#TIME_UNSET} if the playlist should not be excluded
.
* @param
loadErrorInfo The load error info.
*
@param forceRetry Whether retry should be forced without considering exclusion
.
* @return True if excluding did not encounter errors. False otherwise.
*/
boolean
onPlaylistError
(
Uri
url
,
long
exclusionDurationMs
);
boolean
onPlaylistError
(
Uri
url
,
LoadErrorHandlingPolicy
.
LoadErrorInfo
loadErrorInfo
,
boolean
forceRetry
);
}
/** Thrown when a playlist is considered to be stuck due to a server side error. */
...
...
@@ -206,6 +207,15 @@ public interface HlsPlaylistTracker {
void
maybeThrowPlaylistRefreshError
(
Uri
url
)
throws
IOException
;
/**
* Excludes the given media playlist for the given duration, in milliseconds.
*
* @param playlistUrl The URL of the media playlist.
* @param exclusionDurationMs The duration for which to exclude the playlist.
* @return Whether exclusion was successful.
*/
boolean
excludeMediaPlaylist
(
Uri
playlistUrl
,
long
exclusionDurationMs
);
/**
* Requests a playlist refresh and removes it from the exclusion list.
*
* <p>The playlist tracker may choose to delay the playlist refresh. The request is discarded if a
...
...
library/smoothstreaming/src/main/java/com/google/android/exoplayer2/source/smoothstreaming/DefaultSsChunkSource.java
View file @
6dbc1eb1
...
...
@@ -15,6 +15,8 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
source
.
smoothstreaming
;
import
static
com
.
google
.
android
.
exoplayer2
.
trackselection
.
TrackSelectionUtil
.
createFallbackOptions
;
import
android.net.Uri
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
...
...
@@ -38,6 +40,7 @@ import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import
com.google.android.exoplayer2.upstream.DataSource
;
import
com.google.android.exoplayer2.upstream.DataSpec
;
import
com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy
;
import
com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.FallbackSelection
;
import
com.google.android.exoplayer2.upstream.LoaderErrorThrower
;
import
com.google.android.exoplayer2.upstream.TransferListener
;
import
com.google.android.exoplayer2.util.Assertions
;
...
...
@@ -287,12 +290,14 @@ public class DefaultSsChunkSource implements SsChunkSource {
boolean
cancelable
,
LoadErrorHandlingPolicy
.
LoadErrorInfo
loadErrorInfo
,
LoadErrorHandlingPolicy
loadErrorHandlingPolicy
)
{
long
exclusionDurationMs
=
loadErrorHandlingPolicy
.
get
ExclusionDurationMs
For
(
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
,
loadErrorInfo
);
FallbackSelection
fallbackSelection
=
loadErrorHandlingPolicy
.
get
FallbackSelection
For
(
createFallbackOptions
(
trackSelection
)
,
loadErrorInfo
);
return
cancelable
&&
exclusionDurationMs
!=
C
.
TIME_UNSET
&&
trackSelection
.
blacklist
(
trackSelection
.
indexOf
(
chunk
.
trackFormat
),
exclusionDurationMs
);
&&
fallbackSelection
.
type
==
LoadErrorHandlingPolicy
.
FALLBACK_TYPE_TRACK
&&
fallbackSelection
.
exclusionDurationMs
!=
C
.
TIME_UNSET
&&
trackSelection
.
blacklist
(
trackSelection
.
indexOf
(
chunk
.
trackFormat
),
fallbackSelection
.
exclusionDurationMs
);
}
@Override
...
...
testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java
View file @
6dbc1eb1
...
...
@@ -177,7 +177,8 @@ public class FakeAdaptiveMediaPeriod
positionUs
,
DrmSessionManager
.
DRM_UNSUPPORTED
,
new
DrmSessionEventListener
.
EventDispatcher
(),
new
DefaultLoadErrorHandlingPolicy
(
/* minimumLoadableRetryCount= */
3
),
new
DefaultLoadErrorHandlingPolicy
(
/* minimumLoadableRetryCount= */
3
,
/* locationExclusionEnabled= */
true
),
mediaSourceEventDispatcher
);
streams
[
i
]
=
sampleStream
;
sampleStreams
.
add
(
sampleStream
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment