Skip to content

Commit

Permalink
Work around non-empty EoS buffers with timestamp 0
Browse files Browse the repository at this point in the history
Issue: #5045

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=220237752
  • Loading branch information
andrewlewis authored and ojw28 committed Nov 6, 2018
1 parent e347239 commit 3e35b6d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
9 changes: 6 additions & 3 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@
* Fix issue where the buffered position was not updated correctly when
transitioning between periods
([#4899](https://github.com/google/ExoPlayer/issues/4899)).
* Fix issue where a `NullPointerException` is thrown when removing an unprepared
media source from a `ConcatenatingMediaSource` with the `useLazyPreparation`
option enabled ([#4986](https://github.com/google/ExoPlayer/issues/4986)).
* Work around an issue where a non-empty end-of-stream audio buffer would be
output with timestamp zero, causing the player position to jump backwards
([#5045](https://github.com/google/ExoPlayer/issues/5045)).
* Suppress a spurious assertion failure on some Samsung devices
([#4532](https://github.com/google/ExoPlayer/issues/4532)).
* Suppress spurious "references unknown class member" shrinking warning
([#4890](https://github.com/google/ExoPlayer/issues/4890)).
* Fix issue where a `NullPointerException` is thrown when removing an unprepared
media source from a `ConcatenatingMediaSource` with the `useLazyPreparation`
option enabled ([#4986](https://github.com/google/ExoPlayer/issues/4986)).
* Swap recommended order for google() and jcenter() in gradle config
([#4997](https://github.com/google/ExoPlayer/issues/4997)).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.media.MediaFormat;
import android.media.audiofx.Virtualizer;
import android.os.Handler;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
Expand Down Expand Up @@ -86,6 +87,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private int codecMaxInputSize;
private boolean passthroughEnabled;
private boolean codecNeedsDiscardChannelsWorkaround;
private boolean codecNeedsEosBufferTimestampWorkaround;
private android.media.MediaFormat passthroughMediaFormat;
private @C.Encoding int pcmEncoding;
private int channelCount;
Expand Down Expand Up @@ -345,6 +347,7 @@ protected void configureCodec(
float codecOperatingRate) {
codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats());
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecInfo.name);
passthroughEnabled = codecInfo.passthrough;
String codecMimeType = codecInfo.mimeType == null ? MimeTypes.AUDIO_RAW : codecInfo.mimeType;
MediaFormat mediaFormat =
Expand Down Expand Up @@ -583,9 +586,9 @@ protected void onQueueInputBuffer(DecoderInputBuffer buffer) {
lastInputTimeUs = Math.max(buffer.timeUs, lastInputTimeUs);
}

@CallSuper
@Override
protected void onProcessedOutputBuffer(long presentationTimeUs) {
super.onProcessedOutputBuffer(presentationTimeUs);
while (pendingStreamChangeCount != 0 && presentationTimeUs >= pendingStreamChangeTimesUs[0]) {
audioSink.handleDiscontinuity();
pendingStreamChangeCount--;
Expand All @@ -610,6 +613,13 @@ protected boolean processOutputBuffer(
boolean shouldSkip,
Format format)
throws ExoPlaybackException {
if (codecNeedsEosBufferTimestampWorkaround
&& bufferPresentationTimeUs == 0
&& (bufferFlags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0
&& lastInputTimeUs != C.TIME_UNSET) {
bufferPresentationTimeUs = lastInputTimeUs;
}

if (passthroughEnabled && (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
// Discard output buffers from the passthrough (raw) decoder containing codec specific data.
codec.releaseOutputBuffer(bufferIndex, false);
Expand Down Expand Up @@ -777,6 +787,24 @@ private static boolean codecNeedsDiscardChannelsWorkaround(String codecName) {
|| 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
Expand Down

0 comments on commit 3e35b6d

Please sign in to comment.