mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Workaround for vorbis EOS flush bug (23361053).
I'm assuming this will be fixed in API level 24.
This commit is contained in:
parent
879da81218
commit
8e9aadc5e5
1 changed files with 45 additions and 17 deletions
|
|
@ -192,7 +192,9 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
private DrmInitData drmInitData;
|
private DrmInitData drmInitData;
|
||||||
private MediaCodec codec;
|
private MediaCodec codec;
|
||||||
private boolean codecIsAdaptive;
|
private boolean codecIsAdaptive;
|
||||||
private boolean codecNeedsEndOfStreamWorkaround;
|
private boolean codecNeedsEosPropagationWorkaround;
|
||||||
|
private boolean codecNeedsEosFlushWorkaround;
|
||||||
|
private boolean codecReceivedEos;
|
||||||
private ByteBuffer[] inputBuffers;
|
private ByteBuffer[] inputBuffers;
|
||||||
private ByteBuffer[] outputBuffers;
|
private ByteBuffer[] outputBuffers;
|
||||||
private long codecHotswapTimeMs;
|
private long codecHotswapTimeMs;
|
||||||
|
|
@ -319,7 +321,8 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
|
|
||||||
String decoderName = decoderInfo.name;
|
String decoderName = decoderInfo.name;
|
||||||
codecIsAdaptive = decoderInfo.adaptive;
|
codecIsAdaptive = decoderInfo.adaptive;
|
||||||
codecNeedsEndOfStreamWorkaround = codecNeedsEndOfStreamWorkaround(decoderName);
|
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(decoderName);
|
||||||
|
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(decoderName);
|
||||||
try {
|
try {
|
||||||
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
|
long codecInitializingTimestamp = SystemClock.elapsedRealtime();
|
||||||
TraceUtil.beginSection("createByCodecName(" + decoderName + ")");
|
TraceUtil.beginSection("createByCodecName(" + decoderName + ")");
|
||||||
|
|
@ -395,7 +398,9 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
codecReconfigured = false;
|
codecReconfigured = false;
|
||||||
codecHasQueuedBuffers = false;
|
codecHasQueuedBuffers = false;
|
||||||
codecIsAdaptive = false;
|
codecIsAdaptive = false;
|
||||||
codecNeedsEndOfStreamWorkaround = false;
|
codecNeedsEosPropagationWorkaround = false;
|
||||||
|
codecNeedsEosFlushWorkaround = false;
|
||||||
|
codecReceivedEos = false;
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
|
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
|
||||||
codecReinitializationState = REINITIALIZATION_STATE_NONE;
|
codecReinitializationState = REINITIALIZATION_STATE_NONE;
|
||||||
codecCounters.codecReleaseCount++;
|
codecCounters.codecReleaseCount++;
|
||||||
|
|
@ -480,14 +485,19 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
waitingForFirstSyncFrame = true;
|
waitingForFirstSyncFrame = true;
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
decodeOnlyPresentationTimestamps.clear();
|
decodeOnlyPresentationTimestamps.clear();
|
||||||
// Workaround for framework bugs.
|
if (Util.SDK_INT < 18 || (codecNeedsEosFlushWorkaround && codecReceivedEos)) {
|
||||||
// See [Internal: b/8347958], [Internal: b/8578467], [Internal: b/8543366].
|
// Workaround framework bugs. See [Internal: b/8347958, b/8578467, b/8543366, b/23361053].
|
||||||
if (Util.SDK_INT >= 18 && codecReinitializationState == REINITIALIZATION_STATE_NONE) {
|
|
||||||
codec.flush();
|
|
||||||
codecHasQueuedBuffers = false;
|
|
||||||
} else {
|
|
||||||
releaseCodec();
|
releaseCodec();
|
||||||
maybeInitCodec();
|
maybeInitCodec();
|
||||||
|
} else if (codecReinitializationState != REINITIALIZATION_STATE_NONE) {
|
||||||
|
// We're already waiting to release and re-initialize the codec. Since we're now flushing,
|
||||||
|
// there's no need to wait any longer.
|
||||||
|
releaseCodec();
|
||||||
|
maybeInitCodec();
|
||||||
|
} else {
|
||||||
|
// We can flush and re-use the existing decoder.
|
||||||
|
codec.flush();
|
||||||
|
codecHasQueuedBuffers = false;
|
||||||
}
|
}
|
||||||
if (codecReconfigured && format != null) {
|
if (codecReconfigured && format != null) {
|
||||||
// Any reconfiguration data that we send shortly before the flush may be discarded. We
|
// Any reconfiguration data that we send shortly before the flush may be discarded. We
|
||||||
|
|
@ -524,9 +534,10 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
|
if (codecReinitializationState == REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM) {
|
||||||
// We need to re-initialize the codec. Send an end of stream signal to the existing codec so
|
// We need to re-initialize the codec. Send an end of stream signal to the existing codec so
|
||||||
// that it outputs any remaining buffers before we release it.
|
// that it outputs any remaining buffers before we release it.
|
||||||
if (codecNeedsEndOfStreamWorkaround) {
|
if (codecNeedsEosPropagationWorkaround) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else {
|
} else {
|
||||||
|
codecReceivedEos = true;
|
||||||
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -581,9 +592,10 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
}
|
}
|
||||||
inputStreamEnded = true;
|
inputStreamEnded = true;
|
||||||
try {
|
try {
|
||||||
if (codecNeedsEndOfStreamWorkaround) {
|
if (codecNeedsEosPropagationWorkaround) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else {
|
} else {
|
||||||
|
codecReceivedEos = true;
|
||||||
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
inputIndex = -1;
|
inputIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -781,7 +793,7 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
codecCounters.outputBuffersChangedCount++;
|
codecCounters.outputBuffersChangedCount++;
|
||||||
return true;
|
return true;
|
||||||
} else if (outputIndex < 0) {
|
} else if (outputIndex < 0) {
|
||||||
if (codecNeedsEndOfStreamWorkaround && (inputStreamEnded
|
if (codecNeedsEosPropagationWorkaround && (inputStreamEnded
|
||||||
|| codecReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM)) {
|
|| codecReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM)) {
|
||||||
processEndOfStream();
|
processEndOfStream();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -879,17 +891,18 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the decoder is known to handle {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM}
|
* Returns whether the decoder is known to handle the propagation of the
|
||||||
* incorrectly on the host device.
|
* {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} flag incorrectly on the host device.
|
||||||
* <p>
|
* <p>
|
||||||
* If true is returned, the renderer will work around the issue by approximating end of stream
|
* If true is returned, the renderer will work around the issue by approximating end of stream
|
||||||
* behavior without involvement of the underlying decoder.
|
* behavior without relying on the flag being propagated through to an output buffer by the
|
||||||
|
* underlying decoder.
|
||||||
*
|
*
|
||||||
* @param name The name of the decoder.
|
* @param name The name of the decoder.
|
||||||
* @return True if the decoder is known to handle {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM}
|
* @return True if the decoder is known to handle {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM}
|
||||||
* incorrectly on the host device. False otherwise.
|
* propagation incorrectly on the host device. False otherwise.
|
||||||
*/
|
*/
|
||||||
private static boolean codecNeedsEndOfStreamWorkaround(String name) {
|
private static boolean codecNeedsEosPropagationWorkaround(String name) {
|
||||||
return Util.SDK_INT <= 17
|
return Util.SDK_INT <= 17
|
||||||
&& "OMX.rk.video_decoder.avc".equals(name)
|
&& "OMX.rk.video_decoder.avc".equals(name)
|
||||||
&& ("ht7s3".equals(Util.DEVICE) // Tesco HUDL
|
&& ("ht7s3".equals(Util.DEVICE) // Tesco HUDL
|
||||||
|
|
@ -897,4 +910,19 @@ public abstract class MediaCodecTrackRenderer extends SampleSourceTrackRenderer
|
||||||
|| "rk31sdk".equals(Util.DEVICE)); // Rockchip rk31
|
|| "rk31sdk".equals(Util.DEVICE)); // Rockchip rk31
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the decoder is known to behave incorrectly if flushed after receiving an input
|
||||||
|
* buffer with {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} set.
|
||||||
|
* <p>
|
||||||
|
* If true is returned, the renderer will work around the issue by instantiating a new decoder
|
||||||
|
* when this case occurs.
|
||||||
|
*
|
||||||
|
* @param name The name of the decoder.
|
||||||
|
* @return True if the decoder is known to behave incorrectly if flushed after receiving an input
|
||||||
|
* buffer with {@link MediaCodec#BUFFER_FLAG_END_OF_STREAM} set. False otherwise.
|
||||||
|
*/
|
||||||
|
private static boolean codecNeedsEosFlushWorkaround(String name) {
|
||||||
|
return Util.SDK_INT <= 23 && "OMX.google.vorbis.decoder".equals(name);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue