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
03a1a3ee
authored
Aug 07, 2020
by
krocard
Committed by
kim-vde
Aug 07, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Temporary disable offload after failure
PiperOrigin-RevId: 325429029
parent
805cfb02
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
58 additions
and
11 deletions
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
View file @
03a1a3ee
...
@@ -336,6 +336,15 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -336,6 +336,15 @@ public final class DefaultAudioSink implements AudioSink {
private
AuxEffectInfo
auxEffectInfo
;
private
AuxEffectInfo
auxEffectInfo
;
private
boolean
tunneling
;
private
boolean
tunneling
;
private
long
lastFeedElapsedRealtimeMs
;
private
long
lastFeedElapsedRealtimeMs
;
/**
* Do not retrying offload if it just failed.
*
* <p>{@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,
* android.media.AudioAttributes)} does not guaranty that offload is available (eg: using {@link
* android.media.AudioPlaybackCaptureConfiguration}) will disable offload. As a result only try
* once per track/seek to play in offload mode.
*/
private
boolean
disableOffloadAfterFailureUntilNextConfiguration
;
/**
/**
* Creates a new default audio sink.
* Creates a new default audio sink.
...
@@ -459,7 +468,9 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -459,7 +468,9 @@ public final class DefaultAudioSink implements AudioSink {
// guaranteed to support.
// guaranteed to support.
return
SINK_FORMAT_SUPPORTED_WITH_TRANSCODING
;
return
SINK_FORMAT_SUPPORTED_WITH_TRANSCODING
;
}
}
if
(
enableOffload
&&
isOffloadedPlaybackSupported
(
format
,
audioAttributes
))
{
if
(
enableOffload
&&
!
disableOffloadAfterFailureUntilNextConfiguration
&&
isOffloadedPlaybackSupported
(
format
,
audioAttributes
))
{
return
SINK_FORMAT_SUPPORTED_DIRECTLY
;
return
SINK_FORMAT_SUPPORTED_DIRECTLY
;
}
}
if
(
isPassthroughPlaybackSupported
(
format
,
audioCapabilities
))
{
if
(
isPassthroughPlaybackSupported
(
format
,
audioCapabilities
))
{
...
@@ -566,6 +577,9 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -566,6 +577,9 @@ public final class DefaultAudioSink implements AudioSink {
throw
new
ConfigurationException
(
throw
new
ConfigurationException
(
"Invalid output channel config (mode="
+
outputMode
+
") for: "
+
inputFormat
);
"Invalid output channel config (mode="
+
outputMode
+
") for: "
+
inputFormat
);
}
}
disableOffloadAfterFailureUntilNextConfiguration
=
false
;
Configuration
pendingConfiguration
=
Configuration
pendingConfiguration
=
new
Configuration
(
new
Configuration
(
inputPcmFrameSize
,
inputPcmFrameSize
,
...
@@ -619,9 +633,7 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -619,9 +633,7 @@ public final class DefaultAudioSink implements AudioSink {
// initialization of the audio track to fail.
// initialization of the audio track to fail.
releasingConditionVariable
.
block
();
releasingConditionVariable
.
block
();
audioTrack
=
audioTrack
=
buildAudioTrack
();
Assertions
.
checkNotNull
(
configuration
)
.
buildAudioTrack
(
tunneling
,
audioAttributes
,
audioSessionId
);
if
(
isOffloadedPlayback
(
audioTrack
))
{
if
(
isOffloadedPlayback
(
audioTrack
))
{
registerStreamEventCallbackV29
(
audioTrack
);
registerStreamEventCallbackV29
(
audioTrack
);
audioTrack
.
setOffloadDelayPadding
(
configuration
.
trimStartFrames
,
configuration
.
trimEndFrames
);
audioTrack
.
setOffloadDelayPadding
(
configuration
.
trimStartFrames
,
configuration
.
trimEndFrames
);
...
@@ -813,6 +825,18 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -813,6 +825,18 @@ public final class DefaultAudioSink implements AudioSink {
return
false
;
return
false
;
}
}
private
AudioTrack
buildAudioTrack
()
throws
InitializationException
{
try
{
return
Assertions
.
checkNotNull
(
configuration
)
.
buildAudioTrack
(
tunneling
,
audioAttributes
,
audioSessionId
);
}
catch
(
InitializationException
e
)
{
if
(
configuration
.
outputModeIsOffload
())
{
disableOffloadAfterFailureUntilNextConfiguration
=
true
;
}
throw
e
;
}
}
@RequiresApi
(
29
)
@RequiresApi
(
29
)
private
void
registerStreamEventCallbackV29
(
AudioTrack
audioTrack
)
{
private
void
registerStreamEventCallbackV29
(
AudioTrack
audioTrack
)
{
if
(
offloadStreamEventCallbackV29
==
null
)
{
if
(
offloadStreamEventCallbackV29
==
null
)
{
...
@@ -898,6 +922,10 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -898,6 +922,10 @@ public final class DefaultAudioSink implements AudioSink {
lastFeedElapsedRealtimeMs
=
SystemClock
.
elapsedRealtime
();
lastFeedElapsedRealtimeMs
=
SystemClock
.
elapsedRealtime
();
if
(
bytesWritten
<
0
)
{
if
(
bytesWritten
<
0
)
{
boolean
isRecoverable
=
isAudioTrackDeadObject
(
bytesWritten
);
if
(
isRecoverable
&&
configuration
.
outputModeIsOffload
())
{
disableOffloadAfterFailureUntilNextConfiguration
=
true
;
}
throw
new
WriteException
(
bytesWritten
);
throw
new
WriteException
(
bytesWritten
);
}
}
...
@@ -932,6 +960,10 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -932,6 +960,10 @@ public final class DefaultAudioSink implements AudioSink {
}
}
}
}
private
static
boolean
isAudioTrackDeadObject
(
int
status
)
{
return
Util
.
SDK_INT
>=
24
&&
status
==
AudioTrack
.
ERROR_DEAD_OBJECT
;
}
private
boolean
drainToEndOfStream
()
throws
WriteException
{
private
boolean
drainToEndOfStream
()
throws
WriteException
{
boolean
audioProcessorNeedsEndOfStream
=
false
;
boolean
audioProcessorNeedsEndOfStream
=
false
;
if
(
drainingAudioProcessorIndex
==
C
.
INDEX_UNSET
)
{
if
(
drainingAudioProcessorIndex
==
C
.
INDEX_UNSET
)
{
...
@@ -1143,6 +1175,7 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -1143,6 +1175,7 @@ public final class DefaultAudioSink implements AudioSink {
}
}
audioSessionId
=
C
.
AUDIO_SESSION_ID_UNSET
;
audioSessionId
=
C
.
AUDIO_SESSION_ID_UNSET
;
playing
=
false
;
playing
=
false
;
disableOffloadAfterFailureUntilNextConfiguration
=
false
;
}
}
// Internal methods.
// Internal methods.
...
@@ -1771,12 +1804,11 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -1771,12 +1804,11 @@ public final class DefaultAudioSink implements AudioSink {
boolean
tunneling
,
AudioAttributes
audioAttributes
,
int
audioSessionId
)
boolean
tunneling
,
AudioAttributes
audioAttributes
,
int
audioSessionId
)
throws
InitializationException
{
throws
InitializationException
{
AudioTrack
audioTrack
;
AudioTrack
audioTrack
;
if
(
Util
.
SDK_INT
>=
29
)
{
try
{
audioTrack
=
createAudioTrackV29
(
tunneling
,
audioAttributes
,
audioSessionId
);
audioTrack
=
createAudioTrack
(
tunneling
,
audioAttributes
,
audioSessionId
);
}
else
if
(
Util
.
SDK_INT
>=
21
)
{
}
catch
(
UnsupportedOperationException
e
)
{
audioTrack
=
createAudioTrackV21
(
tunneling
,
audioAttributes
,
audioSessionId
);
throw
new
InitializationException
(
}
else
{
AudioTrack
.
STATE_UNINITIALIZED
,
outputSampleRate
,
outputChannelConfig
,
bufferSize
);
audioTrack
=
createAudioTrack
(
audioAttributes
,
audioSessionId
);
}
}
int
state
=
audioTrack
.
getState
();
int
state
=
audioTrack
.
getState
();
...
@@ -1792,6 +1824,17 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -1792,6 +1824,17 @@ public final class DefaultAudioSink implements AudioSink {
return
audioTrack
;
return
audioTrack
;
}
}
private
AudioTrack
createAudioTrack
(
boolean
tunneling
,
AudioAttributes
audioAttributes
,
int
audioSessionId
)
{
if
(
Util
.
SDK_INT
>=
29
)
{
return
createAudioTrackV29
(
tunneling
,
audioAttributes
,
audioSessionId
);
}
else
if
(
Util
.
SDK_INT
>=
21
)
{
return
createAudioTrackV21
(
tunneling
,
audioAttributes
,
audioSessionId
);
}
else
{
return
createAudioTrackV9
(
audioAttributes
,
audioSessionId
);
}
}
@RequiresApi
(
29
)
@RequiresApi
(
29
)
private
AudioTrack
createAudioTrackV29
(
private
AudioTrack
createAudioTrackV29
(
boolean
tunneling
,
AudioAttributes
audioAttributes
,
int
audioSessionId
)
{
boolean
tunneling
,
AudioAttributes
audioAttributes
,
int
audioSessionId
)
{
...
@@ -1820,7 +1863,7 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -1820,7 +1863,7 @@ public final class DefaultAudioSink implements AudioSink {
audioSessionId
);
audioSessionId
);
}
}
private
AudioTrack
createAudioTrack
(
AudioAttributes
audioAttributes
,
int
audioSessionId
)
{
private
AudioTrack
createAudioTrack
V9
(
AudioAttributes
audioAttributes
,
int
audioSessionId
)
{
int
streamType
=
Util
.
getStreamTypeForAudioUsage
(
audioAttributes
.
usage
);
int
streamType
=
Util
.
getStreamTypeForAudioUsage
(
audioAttributes
.
usage
);
if
(
audioSessionId
==
C
.
AUDIO_SESSION_ID_UNSET
)
{
if
(
audioSessionId
==
C
.
AUDIO_SESSION_ID_UNSET
)
{
return
new
AudioTrack
(
return
new
AudioTrack
(
...
@@ -1896,5 +1939,9 @@ public final class DefaultAudioSink implements AudioSink {
...
@@ -1896,5 +1939,9 @@ public final class DefaultAudioSink implements AudioSink {
.
setUsage
(
android
.
media
.
AudioAttributes
.
USAGE_MEDIA
)
.
setUsage
(
android
.
media
.
AudioAttributes
.
USAGE_MEDIA
)
.
build
();
.
build
();
}
}
public
boolean
outputModeIsOffload
()
{
return
outputMode
==
OUTPUT_MODE_OFFLOAD
;
}
}
}
}
}
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