Commit 1fb675e8 by olly Committed by Andrew Lewis

Move last-buffer timestamp fix to better location

PiperOrigin-RevId: 340915538
parent 477eae3c
...@@ -94,7 +94,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -94,7 +94,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private int codecMaxInputSize; private int codecMaxInputSize;
private boolean codecNeedsDiscardChannelsWorkaround; private boolean codecNeedsDiscardChannelsWorkaround;
private boolean codecNeedsEosBufferTimestampWorkaround;
/** Codec used for DRM decryption only in passthrough and offload. */ /** Codec used for DRM decryption only in passthrough and offload. */
@Nullable private Format decryptOnlyCodecFormat; @Nullable private Format decryptOnlyCodecFormat;
...@@ -318,7 +317,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -318,7 +317,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
float codecOperatingRate) { float codecOperatingRate) {
codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats()); codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats());
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name); codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecInfo.name);
MediaFormat mediaFormat = MediaFormat mediaFormat =
getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate); getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
codecAdapter.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0); codecAdapter.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0);
...@@ -571,13 +569,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -571,13 +569,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
Format format) Format format)
throws ExoPlaybackException { throws ExoPlaybackException {
checkNotNull(buffer); 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 if (decryptOnlyCodecFormat != null
&& (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { && (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
...@@ -782,24 +773,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -782,24 +773,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|| Util.DEVICE.startsWith("heroqlte")); || 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 { private final class AudioSinkListener implements AudioSink.Listener {
@Override @Override
......
...@@ -321,6 +321,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -321,6 +321,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean codecNeedsSosFlushWorkaround; private boolean codecNeedsSosFlushWorkaround;
private boolean codecNeedsEosFlushWorkaround; private boolean codecNeedsEosFlushWorkaround;
private boolean codecNeedsEosOutputExceptionWorkaround; private boolean codecNeedsEosOutputExceptionWorkaround;
private boolean codecNeedsEosBufferTimestampWorkaround;
private boolean codecNeedsMonoChannelCountWorkaround; private boolean codecNeedsMonoChannelCountWorkaround;
private boolean codecNeedsAdaptationWorkaroundBuffer; private boolean codecNeedsAdaptationWorkaroundBuffer;
private boolean shouldSkipAdaptationWorkaroundOutputBuffer; private boolean shouldSkipAdaptationWorkaroundOutputBuffer;
...@@ -898,6 +899,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -898,6 +899,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsSosFlushWorkaround = false; codecNeedsSosFlushWorkaround = false;
codecNeedsEosFlushWorkaround = false; codecNeedsEosFlushWorkaround = false;
codecNeedsEosOutputExceptionWorkaround = false; codecNeedsEosOutputExceptionWorkaround = false;
codecNeedsEosBufferTimestampWorkaround = false;
codecNeedsMonoChannelCountWorkaround = false; codecNeedsMonoChannelCountWorkaround = false;
codecNeedsEosPropagation = false; codecNeedsEosPropagation = false;
codecReconfigured = false; codecReconfigured = false;
...@@ -1089,6 +1091,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1089,6 +1091,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsSosFlushWorkaround = codecNeedsSosFlushWorkaround(codecName); codecNeedsSosFlushWorkaround = codecNeedsSosFlushWorkaround(codecName);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName); codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName); codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround = codecNeedsMonoChannelCountWorkaround =
codecNeedsMonoChannelCountWorkaround(codecName, codecInputFormat); codecNeedsMonoChannelCountWorkaround(codecName, codecInputFormat);
codecNeedsEosPropagation = codecNeedsEosPropagation =
...@@ -1746,6 +1749,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1746,6 +1749,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
outputBuffer.position(outputBufferInfo.offset); outputBuffer.position(outputBufferInfo.offset);
outputBuffer.limit(outputBufferInfo.offset + outputBufferInfo.size); 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); isDecodeOnlyOutputBuffer = isDecodeOnlyBuffer(outputBufferInfo.presentationTimeUs);
isLastOutputBuffer = isLastOutputBuffer =
lastBufferInStreamPresentationTimeUs == outputBufferInfo.presentationTimeUs; lastBufferInStreamPresentationTimeUs == outputBufferInfo.presentationTimeUs;
...@@ -1928,18 +1937,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1928,18 +1937,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
pendingOutputEndOfStream = true; 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 * Returns the offset that should be subtracted from {@code bufferPresentationTimeUs} in {@link
* #processOutputBuffer(long, long, MediaCodec, ByteBuffer, int, int, int, long, boolean, boolean, * #processOutputBuffer(long, long, MediaCodec, ByteBuffer, int, int, int, long, boolean, boolean,
...@@ -2273,6 +2270,23 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -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 * 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. * MediaCodec#BUFFER_FLAG_END_OF_STREAM} flag incorrectly on the host device.
* *
...@@ -2316,12 +2330,30 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -2316,12 +2330,30 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
/** /**
* Returns whether the decoder may throw an {@link IllegalStateException} from * Returns whether the decoder may output a non-empty buffer with timestamp 0 as the end of stream
* {@link MediaCodec#dequeueOutputBuffer(MediaCodec.BufferInfo, long)} or * buffer.
* {@link MediaCodec#releaseOutputBuffer(int, boolean)} after receiving an input *
* buffer with {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} set. * <p>See <a href="https://github.com/google/ExoPlayer/issues/5045">GitHub issue #5045</a>.
* <p> */
* See [Internal: b/17933838]. 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. * @param name The name of the decoder.
* @return True if the decoder may throw an exception after receiving an end-of-stream buffer. * @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 { ...@@ -2348,21 +2380,4 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return Util.SDK_INT <= 18 && format.channelCount == 1 return Util.SDK_INT <= 18 && format.channelCount == 1
&& "OMX.MTK.AUDIO.DECODER.MP3".equals(name); && "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);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment