mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Fix transformer stuck forever
When the decoder output buffer was partially read, a call to Codec.getOutputBuffer() was returning the same buffer, but with the position reset to 0. The reason was that, in Codec.maybeDequeueAndSetOutputBuffer(), mediaCodec.getOutputBuffer() was called with the same buffer index (L350 in old rev), even though there was already a buffer available (outputBufferIndex >=0). This change avoids calling mediaCodec.getOutputBuffer() if the previous buffer has not been released. #minor-release PiperOrigin-RevId: 424612197
This commit is contained in:
parent
8123ef5d71
commit
8ec18086f2
@ -111,6 +111,7 @@
|
||||
during a transformation.
|
||||
* Add `TransformationRequest` for specifying the transformation options.
|
||||
* Allow multiple listeners to be registered.
|
||||
* Fix Transformer being stuck when the codec output is partially read.
|
||||
* MediaSession extension:
|
||||
* Remove deprecated call to `onStop(/* reset= */ true)` and provide an
|
||||
opt-out flag for apps that don't want to clear the playlist on stop.
|
||||
|
@ -261,7 +261,7 @@ public final class Codec {
|
||||
@Nullable
|
||||
public Format getOutputFormat() throws TransformationException {
|
||||
// The format is updated when dequeueing a 'special' buffer index, so attempt to dequeue now.
|
||||
maybeDequeueOutputBuffer();
|
||||
maybeDequeueOutputBuffer(/* setOutputBuffer= */ false);
|
||||
return outputFormat;
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ public final class Codec {
|
||||
*/
|
||||
@Nullable
|
||||
public ByteBuffer getOutputBuffer() throws TransformationException {
|
||||
return maybeDequeueAndSetOutputBuffer() ? outputBuffer : null;
|
||||
return maybeDequeueOutputBuffer(/* setOutputBuffer= */ true) ? outputBuffer : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,7 +282,7 @@ public final class Codec {
|
||||
*/
|
||||
@Nullable
|
||||
public BufferInfo getOutputBufferInfo() throws TransformationException {
|
||||
return maybeDequeueOutputBuffer() ? outputBufferInfo : null;
|
||||
return maybeDequeueOutputBuffer(/* setOutputBuffer= */ false) ? outputBufferInfo : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,33 +334,15 @@ public final class Codec {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries obtaining an output buffer and sets {@link #outputBuffer} to the obtained output buffer.
|
||||
* Attempts to dequeue an output buffer if there is no output buffer pending. Does nothing
|
||||
* otherwise.
|
||||
*
|
||||
* @return {@code true} if a buffer is successfully obtained, {@code false} otherwise.
|
||||
* @param setOutputBuffer Whether to read the bytes of the dequeued output buffer and copy them
|
||||
* into {@link #outputBuffer}.
|
||||
* @return Whether there is an output buffer available.
|
||||
* @throws TransformationException If the underlying {@link MediaCodec} encounters a problem.
|
||||
*/
|
||||
private boolean maybeDequeueAndSetOutputBuffer() throws TransformationException {
|
||||
if (!maybeDequeueOutputBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
outputBuffer = checkNotNull(mediaCodec.getOutputBuffer(outputBufferIndex));
|
||||
} catch (RuntimeException e) {
|
||||
throw createTransformationException(e);
|
||||
}
|
||||
outputBuffer.position(outputBufferInfo.offset);
|
||||
outputBuffer.limit(outputBufferInfo.offset + outputBufferInfo.size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is already an output buffer pending. Otherwise attempts to dequeue an
|
||||
* output buffer and returns whether there is a new output buffer.
|
||||
*
|
||||
* @throws TransformationException If the underlying {@link MediaCodec} encounters a problem.
|
||||
*/
|
||||
private boolean maybeDequeueOutputBuffer() throws TransformationException {
|
||||
private boolean maybeDequeueOutputBuffer(boolean setOutputBuffer) throws TransformationException {
|
||||
if (outputBufferIndex >= 0) {
|
||||
return true;
|
||||
}
|
||||
@ -391,6 +373,16 @@ public final class Codec {
|
||||
releaseOutputBuffer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setOutputBuffer) {
|
||||
try {
|
||||
outputBuffer = checkNotNull(mediaCodec.getOutputBuffer(outputBufferIndex));
|
||||
} catch (RuntimeException e) {
|
||||
throw createTransformationException(e);
|
||||
}
|
||||
outputBuffer.position(outputBufferInfo.offset);
|
||||
outputBuffer.limit(outputBufferInfo.offset + outputBufferInfo.size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user