Commit 07e33a13 by christosts Committed by Andrew Lewis

Add getInputBuffer/getOutputBuffer in MediaCodecAdapter

PiperOrigin-RevId: 341016263
parent 1bcf1cf9
......@@ -30,6 +30,7 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
/**
* A {@link MediaCodecAdapter} that operates the underlying {@link MediaCodec} in asynchronous mode,
......@@ -123,6 +124,18 @@ import java.lang.annotation.RetentionPolicy;
}
@Override
@Nullable
public ByteBuffer getInputBuffer(int index) {
return codec.getInputBuffer(index);
}
@Override
@Nullable
public ByteBuffer getOutputBuffer(int index) {
return codec.getOutputBuffer(index);
}
@Override
public void flush() {
// The order of calls is important:
// First, flush the bufferEnqueuer to stop queueing input buffers.
......
......@@ -22,6 +22,7 @@ import android.media.MediaFormat;
import android.view.Surface;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.decoder.CryptoInfo;
import java.nio.ByteBuffer;
/**
* Abstracts {@link MediaCodec} operations.
......@@ -78,6 +79,22 @@ public interface MediaCodecAdapter {
MediaFormat getOutputFormat();
/**
* Returns a writable ByteBuffer object for a dequeued input buffer index.
*
* @see MediaCodec#getInputBuffer(int)
*/
@Nullable
ByteBuffer getInputBuffer(int index);
/**
* Returns a read-only ByteBuffer for a dequeued output buffer index.
*
* @see MediaCodec#getOutputBuffer(int)
*/
@Nullable
ByteBuffer getOutputBuffer(int index);
/**
* Submit an input buffer for decoding.
*
* <p>The {@code index} must be an input buffer index that has been obtained from a previous call
......
......@@ -327,8 +327,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean shouldSkipAdaptationWorkaroundOutputBuffer;
private boolean codecNeedsEosPropagation;
@Nullable private C2Mp3TimestampTracker c2Mp3TimestampTracker;
private ByteBuffer[] inputBuffers;
private ByteBuffer[] outputBuffers;
private long codecHotswapDeadlineMs;
private int inputIndex;
private int outputIndex;
......@@ -909,7 +907,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsEosPropagation = false;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
resetCodecBuffers();
mediaCryptoRequiresSecureDecoder = false;
}
......@@ -1072,13 +1069,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecAdapter.start();
TraceUtil.endSection();
codecInitializedTimestamp = SystemClock.elapsedRealtime();
getCodecBuffers(codec);
} catch (Exception e) {
if (codecAdapter != null) {
codecAdapter.shutdown();
}
if (codec != null) {
resetCodecBuffers();
codec.release();
}
throw e;
......@@ -1119,37 +1114,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|| SystemClock.elapsedRealtime() - renderStartTimeMs < renderTimeLimitMs;
}
private void getCodecBuffers(MediaCodec codec) {
if (Util.SDK_INT < 21) {
inputBuffers = codec.getInputBuffers();
outputBuffers = codec.getOutputBuffers();
}
}
private void resetCodecBuffers() {
if (Util.SDK_INT < 21) {
inputBuffers = null;
outputBuffers = null;
}
}
private ByteBuffer getInputBuffer(int inputIndex) {
if (Util.SDK_INT >= 21) {
return codec.getInputBuffer(inputIndex);
} else {
return inputBuffers[inputIndex];
}
}
@Nullable
private ByteBuffer getOutputBuffer(int outputIndex) {
if (Util.SDK_INT >= 21) {
return codec.getOutputBuffer(outputIndex);
} else {
return outputBuffers[outputIndex];
}
}
private boolean hasOutputBuffer() {
return outputIndex >= 0;
}
......@@ -1188,7 +1152,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (inputIndex < 0) {
return false;
}
buffer.data = getInputBuffer(inputIndex);
buffer.data = codecAdapter.getInputBuffer(inputIndex);
buffer.clear();
}
......@@ -1729,9 +1693,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED /* (-2) */) {
processOutputMediaFormatChanged();
return true;
} else if (outputIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED /* (-3) */) {
processOutputBuffersChanged();
return true;
}
/* MediaCodec.INFO_TRY_AGAIN_LATER (-1) or unknown negative return value */
if (codecNeedsEosPropagation
......@@ -1754,7 +1715,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
this.outputIndex = outputIndex;
outputBuffer = getOutputBuffer(outputIndex);
outputBuffer = codecAdapter.getOutputBuffer(outputIndex);
// The dequeued buffer is a media buffer. Do some initial setup.
// It will be processed by calling processOutputBuffer (possibly multiple times).
......@@ -1847,15 +1808,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
/**
* Processes a change in the output buffers.
*/
private void processOutputBuffersChanged() {
if (Util.SDK_INT < 21) {
outputBuffers = codec.getOutputBuffers();
}
}
/**
* Processes an output media buffer.
*
* <p>When a new {@link ByteBuffer} is passed to this method its position and limit delineate the
......
......@@ -16,12 +16,16 @@
package com.google.android.exoplayer2.mediacodec;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.media.MediaCodec;
import android.media.MediaCrypto;
import android.media.MediaFormat;
import android.view.Surface;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.decoder.CryptoInfo;
import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer;
/**
* A {@link MediaCodecAdapter} that operates the underlying {@link MediaCodec} in synchronous mode.
......@@ -29,6 +33,8 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
/* package */ final class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
private final MediaCodec codec;
@Nullable private ByteBuffer[] inputByteBuffers;
@Nullable private ByteBuffer[] outputByteBuffers;
public SynchronousMediaCodecAdapter(MediaCodec mediaCodec) {
this.codec = mediaCodec;
......@@ -46,6 +52,10 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
@Override
public void start() {
codec.start();
if (Util.SDK_INT < 21) {
inputByteBuffers = codec.getInputBuffers();
outputByteBuffers = codec.getOutputBuffers();
}
}
@Override
......@@ -55,7 +65,15 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
@Override
public int dequeueOutputBufferIndex(MediaCodec.BufferInfo bufferInfo) {
return codec.dequeueOutputBuffer(bufferInfo, 0);
int index;
do {
index = codec.dequeueOutputBuffer(bufferInfo, 0);
if (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED && Util.SDK_INT < 21) {
outputByteBuffers = codec.getOutputBuffers();
}
} while (index == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED);
return index;
}
@Override
......@@ -64,6 +82,26 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
}
@Override
@Nullable
public ByteBuffer getInputBuffer(int index) {
if (Util.SDK_INT >= 21) {
return codec.getInputBuffer(index);
} else {
return castNonNull(inputByteBuffers)[index];
}
}
@Override
@Nullable
public ByteBuffer getOutputBuffer(int index) {
if (Util.SDK_INT >= 21) {
return codec.getOutputBuffer(index);
} else {
return castNonNull(outputByteBuffers)[index];
}
}
@Override
public void queueInputBuffer(
int index, int offset, int size, long presentationTimeUs, int flags) {
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
......@@ -82,7 +120,10 @@ import com.google.android.exoplayer2.decoder.CryptoInfo;
}
@Override
public void shutdown() {}
public void shutdown() {
inputByteBuffers = null;
outputByteBuffers = null;
}
@Override
public MediaCodec getCodec() {
......
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