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
1fb675e8
authored
Nov 05, 2020
by
olly
Committed by
Andrew Lewis
Nov 06, 2020
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Move last-buffer timestamp fix to better location
PiperOrigin-RevId: 340915538
parent
477eae3c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
50 additions
and
62 deletions
library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java
View file @
1fb675e8
...
...
@@ -94,7 +94,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private
int
codecMaxInputSize
;
private
boolean
codecNeedsDiscardChannelsWorkaround
;
private
boolean
codecNeedsEosBufferTimestampWorkaround
;
/** Codec used for DRM decryption only in passthrough and offload. */
@Nullable
private
Format
decryptOnlyCodecFormat
;
...
...
@@ -318,7 +317,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
float
codecOperatingRate
)
{
codecMaxInputSize
=
getCodecMaxInputSize
(
codecInfo
,
format
,
getStreamFormats
());
codecNeedsDiscardChannelsWorkaround
=
codecNeedsDiscardChannelsWorkaround
(
codecInfo
.
name
);
codecNeedsEosBufferTimestampWorkaround
=
codecNeedsEosBufferTimestampWorkaround
(
codecInfo
.
name
);
MediaFormat
mediaFormat
=
getMediaFormat
(
format
,
codecInfo
.
codecMimeType
,
codecMaxInputSize
,
codecOperatingRate
);
codecAdapter
.
configure
(
mediaFormat
,
/* surface= */
null
,
crypto
,
/* flags= */
0
);
...
...
@@ -571,13 +569,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
Format
format
)
throws
ExoPlaybackException
{
checkNotNull
(
buffer
);
if
(
codec
!=
null
&&
codecNeedsEosBufferTimestampWorkaround
&&
bufferPresentationTimeUs
==
0
&&
(
bufferFlags
&
MediaCodec
.
BUFFER_FLAG_END_OF_STREAM
)
!=
0
&&
getLargestQueuedPresentationTimeUs
()
!=
C
.
TIME_UNSET
)
{
bufferPresentationTimeUs
=
getLargestQueuedPresentationTimeUs
();
}
if
(
decryptOnlyCodecFormat
!=
null
&&
(
bufferFlags
&
MediaCodec
.
BUFFER_FLAG_CODEC_CONFIG
)
!=
0
)
{
...
...
@@ -782,24 +773,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
||
Util
.
DEVICE
.
startsWith
(
"heroqlte"
));
}
/**
* Returns whether the decoder may output a non-empty buffer with timestamp 0 as the end of stream
* buffer.
*
* <p>See <a href="https://github.com/google/ExoPlayer/issues/5045">GitHub issue #5045</a>.
*/
private
static
boolean
codecNeedsEosBufferTimestampWorkaround
(
String
codecName
)
{
return
Util
.
SDK_INT
<
21
&&
"OMX.SEC.mp3.dec"
.
equals
(
codecName
)
&&
"samsung"
.
equals
(
Util
.
MANUFACTURER
)
&&
(
Util
.
DEVICE
.
startsWith
(
"baffin"
)
||
Util
.
DEVICE
.
startsWith
(
"grand"
)
||
Util
.
DEVICE
.
startsWith
(
"fortuna"
)
||
Util
.
DEVICE
.
startsWith
(
"gprimelte"
)
||
Util
.
DEVICE
.
startsWith
(
"j2y18lte"
)
||
Util
.
DEVICE
.
startsWith
(
"ms01"
));
}
private
final
class
AudioSinkListener
implements
AudioSink
.
Listener
{
@Override
...
...
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
View file @
1fb675e8
...
...
@@ -321,6 +321,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private
boolean
codecNeedsSosFlushWorkaround
;
private
boolean
codecNeedsEosFlushWorkaround
;
private
boolean
codecNeedsEosOutputExceptionWorkaround
;
private
boolean
codecNeedsEosBufferTimestampWorkaround
;
private
boolean
codecNeedsMonoChannelCountWorkaround
;
private
boolean
codecNeedsAdaptationWorkaroundBuffer
;
private
boolean
shouldSkipAdaptationWorkaroundOutputBuffer
;
...
...
@@ -898,6 +899,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsSosFlushWorkaround
=
false
;
codecNeedsEosFlushWorkaround
=
false
;
codecNeedsEosOutputExceptionWorkaround
=
false
;
codecNeedsEosBufferTimestampWorkaround
=
false
;
codecNeedsMonoChannelCountWorkaround
=
false
;
codecNeedsEosPropagation
=
false
;
codecReconfigured
=
false
;
...
...
@@ -1089,6 +1091,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsSosFlushWorkaround
=
codecNeedsSosFlushWorkaround
(
codecName
);
codecNeedsEosFlushWorkaround
=
codecNeedsEosFlushWorkaround
(
codecName
);
codecNeedsEosOutputExceptionWorkaround
=
codecNeedsEosOutputExceptionWorkaround
(
codecName
);
codecNeedsEosBufferTimestampWorkaround
=
codecNeedsEosBufferTimestampWorkaround
(
codecName
);
codecNeedsMonoChannelCountWorkaround
=
codecNeedsMonoChannelCountWorkaround
(
codecName
,
codecInputFormat
);
codecNeedsEosPropagation
=
...
...
@@ -1746,6 +1749,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
outputBuffer
.
position
(
outputBufferInfo
.
offset
);
outputBuffer
.
limit
(
outputBufferInfo
.
offset
+
outputBufferInfo
.
size
);
}
if
(
codecNeedsEosBufferTimestampWorkaround
&&
outputBufferInfo
.
presentationTimeUs
==
0
&&
(
outputBufferInfo
.
flags
&
MediaCodec
.
BUFFER_FLAG_END_OF_STREAM
)
!=
0
&&
largestQueuedPresentationTimeUs
!=
C
.
TIME_UNSET
)
{
outputBufferInfo
.
presentationTimeUs
=
largestQueuedPresentationTimeUs
;
}
isDecodeOnlyOutputBuffer
=
isDecodeOnlyBuffer
(
outputBufferInfo
.
presentationTimeUs
);
isLastOutputBuffer
=
lastBufferInStreamPresentationTimeUs
==
outputBufferInfo
.
presentationTimeUs
;
...
...
@@ -1928,18 +1937,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
pendingOutputEndOfStream
=
true
;
}
/** Returns the largest queued input presentation time, in microseconds. */
protected
final
long
getLargestQueuedPresentationTimeUs
()
{
return
largestQueuedPresentationTimeUs
;
}
/**
* Returns the start position of the output {@link SampleStream}, in renderer time microseconds.
*/
protected
final
long
getOutputStreamStartPositionUs
()
{
return
outputStreamStartPositionUs
;
}
/**
* Returns the offset that should be subtracted from {@code bufferPresentationTimeUs} in {@link
* #processOutputBuffer(long, long, MediaCodec, ByteBuffer, int, int, int, long, boolean, boolean,
...
...
@@ -2273,6 +2270,23 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
/**
* Returns whether the decoder is known to behave incorrectly if flushed prior to having output a
* {@link MediaFormat}.
*
* <p>If true is returned, the renderer will work around the issue by instantiating a new decoder
* when this case occurs.
*
* <p>See [Internal: b/141097367].
*
* @param name The name of the decoder.
* @return True if the decoder is known to behave incorrectly if flushed prior to having output a
* {@link MediaFormat}. False otherwise.
*/
private
static
boolean
codecNeedsSosFlushWorkaround
(
String
name
)
{
return
Util
.
SDK_INT
==
29
&&
"c2.android.aac.decoder"
.
equals
(
name
);
}
/**
* Returns whether the decoder is known to handle the propagation of the {@link
* MediaCodec#BUFFER_FLAG_END_OF_STREAM} flag incorrectly on the host device.
*
...
...
@@ -2316,12 +2330,30 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
/**
* Returns whether the decoder may throw an {@link IllegalStateException} from
* {@link MediaCodec#dequeueOutputBuffer(MediaCodec.BufferInfo, long)} or
* {@link MediaCodec#releaseOutputBuffer(int, boolean)} after receiving an input
* buffer with {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} set.
* <p>
* See [Internal: b/17933838].
* Returns whether the decoder may output a non-empty buffer with timestamp 0 as the end of stream
* buffer.
*
* <p>See <a href="https://github.com/google/ExoPlayer/issues/5045">GitHub issue #5045</a>.
*/
private
static
boolean
codecNeedsEosBufferTimestampWorkaround
(
String
codecName
)
{
return
Util
.
SDK_INT
<
21
&&
"OMX.SEC.mp3.dec"
.
equals
(
codecName
)
&&
"samsung"
.
equals
(
Util
.
MANUFACTURER
)
&&
(
Util
.
DEVICE
.
startsWith
(
"baffin"
)
||
Util
.
DEVICE
.
startsWith
(
"grand"
)
||
Util
.
DEVICE
.
startsWith
(
"fortuna"
)
||
Util
.
DEVICE
.
startsWith
(
"gprimelte"
)
||
Util
.
DEVICE
.
startsWith
(
"j2y18lte"
)
||
Util
.
DEVICE
.
startsWith
(
"ms01"
));
}
/**
* Returns whether the decoder may throw an {@link IllegalStateException} from {@link
* MediaCodec#dequeueOutputBuffer(MediaCodec.BufferInfo, long)} or {@link
* MediaCodec#releaseOutputBuffer(int, boolean)} after receiving an input buffer with {@link
* MediaCodec#BUFFER_FLAG_END_OF_STREAM} set.
*
* <p>See [Internal: b/17933838].
*
* @param name The name of the decoder.
* @return True if the decoder may throw an exception after receiving an end-of-stream buffer.
...
...
@@ -2348,21 +2380,4 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return
Util
.
SDK_INT
<=
18
&&
format
.
channelCount
==
1
&&
"OMX.MTK.AUDIO.DECODER.MP3"
.
equals
(
name
);
}
/**
* Returns whether the decoder is known to behave incorrectly if flushed prior to having output a
* {@link MediaFormat}.
*
* <p>If true is returned, the renderer will work around the issue by instantiating a new decoder
* when this case occurs.
*
* <p>See [Internal: b/141097367].
*
* @param name The name of the decoder.
* @return True if the decoder is known to behave incorrectly if flushed prior to having output a
* {@link MediaFormat}. False otherwise.
*/
private
static
boolean
codecNeedsSosFlushWorkaround
(
String
name
)
{
return
Util
.
SDK_INT
==
29
&&
"c2.android.aac.decoder"
.
equals
(
name
);
}
}
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