MediaCodecAdapter supports queueing input buffers
Add queueInputBuffer() and queueSecureInputBuffer() in MediaCodecAdapter. PiperOrigin-RevId: 290720307
This commit is contained in:
parent
cf3939838b
commit
665092e4be
@ -63,6 +63,18 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||||||
codecStartRunnable.run();
|
codecStartRunnable.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueInputBuffer(
|
||||||
|
int index, int offset, int size, long presentationTimeUs, int flags) {
|
||||||
|
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueSecureInputBuffer(
|
||||||
|
int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) {
|
||||||
|
codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int dequeueInputBufferIndex() {
|
public int dequeueInputBufferIndex() {
|
||||||
if (flushing) {
|
if (flushing) {
|
||||||
|
@ -33,8 +33,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* A {@link MediaCodecAdapter} that operates the underlying {@link MediaCodec} in asynchronous mode
|
* A {@link MediaCodecAdapter} that operates the underlying {@link MediaCodec} in asynchronous mode
|
||||||
* and routes {@link MediaCodec.Callback} callbacks on a dedicated Thread that is managed
|
* and routes {@link MediaCodec.Callback} callbacks on a dedicated Thread that is managed
|
||||||
* internally.
|
* internally.
|
||||||
*
|
|
||||||
* <p>After creating an instance, you need to call {@link #start()} to start the internal Thread.
|
|
||||||
*/
|
*/
|
||||||
@RequiresApi(23)
|
@RequiresApi(23)
|
||||||
/* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback
|
/* package */ final class DedicatedThreadAsyncMediaCodecAdapter extends MediaCodec.Callback
|
||||||
@ -88,6 +86,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
state = STATE_STARTED;
|
state = STATE_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueInputBuffer(
|
||||||
|
int index, int offset, int size, long presentationTimeUs, int flags) {
|
||||||
|
// This method does not need to be synchronized because it does not interact with the
|
||||||
|
// mediaCodecAsyncCallback.
|
||||||
|
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueSecureInputBuffer(
|
||||||
|
int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) {
|
||||||
|
// This method does not need to be synchronized because it does not interact with the
|
||||||
|
// mediaCodecAsyncCallback.
|
||||||
|
codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized int dequeueInputBufferIndex() {
|
public synchronized int dequeueInputBufferIndex() {
|
||||||
if (isFlushing()) {
|
if (isFlushing()) {
|
||||||
|
@ -65,6 +65,27 @@ import android.media.MediaFormat;
|
|||||||
*/
|
*/
|
||||||
MediaFormat getOutputFormat();
|
MediaFormat getOutputFormat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit an input buffer for decoding.
|
||||||
|
*
|
||||||
|
* <p>The {@code index} must be an input buffer index that has been obtained from a previous call
|
||||||
|
* to {@link #dequeueInputBufferIndex()}.
|
||||||
|
*
|
||||||
|
* @see MediaCodec#queueInputBuffer
|
||||||
|
*/
|
||||||
|
void queueInputBuffer(int index, int offset, int size, long presentationTimeUs, int flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit an input buffer that is potentially encrypted for decoding.
|
||||||
|
*
|
||||||
|
* <p>The {@code index} must be an input buffer index that has been obtained from a previous call
|
||||||
|
* to {@link #dequeueInputBufferIndex()}.
|
||||||
|
*
|
||||||
|
* @see MediaCodec#queueSecureInputBuffer
|
||||||
|
*/
|
||||||
|
void queueSecureInputBuffer(
|
||||||
|
int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes the {@code MediaCodecAdapter}.
|
* Flushes the {@code MediaCodecAdapter}.
|
||||||
*
|
*
|
||||||
|
@ -1136,7 +1136,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else {
|
} else {
|
||||||
codecReceivedEos = true;
|
codecReceivedEos = true;
|
||||||
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
codecAdapter.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
resetInputBuffer();
|
resetInputBuffer();
|
||||||
}
|
}
|
||||||
codecDrainState = DRAIN_STATE_WAIT_END_OF_STREAM;
|
codecDrainState = DRAIN_STATE_WAIT_END_OF_STREAM;
|
||||||
@ -1146,7 +1146,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
if (codecNeedsAdaptationWorkaroundBuffer) {
|
if (codecNeedsAdaptationWorkaroundBuffer) {
|
||||||
codecNeedsAdaptationWorkaroundBuffer = false;
|
codecNeedsAdaptationWorkaroundBuffer = false;
|
||||||
buffer.data.put(ADAPTATION_WORKAROUND_BUFFER);
|
buffer.data.put(ADAPTATION_WORKAROUND_BUFFER);
|
||||||
codec.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0);
|
codecAdapter.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0);
|
||||||
resetInputBuffer();
|
resetInputBuffer();
|
||||||
codecReceivedBuffers = true;
|
codecReceivedBuffers = true;
|
||||||
return true;
|
return true;
|
||||||
@ -1210,7 +1210,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else {
|
} else {
|
||||||
codecReceivedEos = true;
|
codecReceivedEos = true;
|
||||||
codec.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
codecAdapter.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
||||||
resetInputBuffer();
|
resetInputBuffer();
|
||||||
}
|
}
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
@ -1261,9 +1261,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
if (bufferEncrypted) {
|
if (bufferEncrypted) {
|
||||||
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer,
|
MediaCodec.CryptoInfo cryptoInfo = getFrameworkCryptoInfo(buffer,
|
||||||
adaptiveReconfigurationBytes);
|
adaptiveReconfigurationBytes);
|
||||||
codec.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0);
|
codecAdapter.queueSecureInputBuffer(inputIndex, 0, cryptoInfo, presentationTimeUs, 0);
|
||||||
} else {
|
} else {
|
||||||
codec.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0);
|
codecAdapter.queueInputBuffer(inputIndex, 0, buffer.data.limit(), presentationTimeUs, 0);
|
||||||
}
|
}
|
||||||
resetInputBuffer();
|
resetInputBuffer();
|
||||||
codecReceivedBuffers = true;
|
codecReceivedBuffers = true;
|
||||||
|
@ -46,8 +46,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* MediaCodec.Callback} methods will be accessed by the internal Thread. This class is
|
* MediaCodec.Callback} methods will be accessed by the internal Thread. This class is
|
||||||
* <strong>NOT</strong> generally thread-safe in the sense that its public methods cannot be called
|
* <strong>NOT</strong> generally thread-safe in the sense that its public methods cannot be called
|
||||||
* by any thread.
|
* by any thread.
|
||||||
*
|
|
||||||
* <p>After creating an instance, you need to call {@link #start()} to start the internal Thread.
|
|
||||||
*/
|
*/
|
||||||
@RequiresApi(23)
|
@RequiresApi(23)
|
||||||
/* package */ final class MultiLockAsyncMediaCodecAdapter extends MediaCodec.Callback
|
/* package */ final class MultiLockAsyncMediaCodecAdapter extends MediaCodec.Callback
|
||||||
@ -161,6 +159,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueInputBuffer(
|
||||||
|
int index, int offset, int size, long presentationTimeUs, int flags) {
|
||||||
|
// This method does not need to be synchronized because it is not interacting with
|
||||||
|
// MediaCodec.Callback and dequeueing buffers operations.
|
||||||
|
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueSecureInputBuffer(
|
||||||
|
int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) {
|
||||||
|
// This method does not need to be synchronized because it is not interacting with
|
||||||
|
// MediaCodec.Callback and dequeueing buffers operations.
|
||||||
|
codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
synchronized (objectStateLock) {
|
synchronized (objectStateLock) {
|
||||||
|
@ -50,6 +50,18 @@ import android.media.MediaFormat;
|
|||||||
return codec.getOutputFormat();
|
return codec.getOutputFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueInputBuffer(
|
||||||
|
int index, int offset, int size, long presentationTimeUs, int flags) {
|
||||||
|
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueSecureInputBuffer(
|
||||||
|
int index, int offset, MediaCodec.CryptoInfo info, long presentationTimeUs, int flags) {
|
||||||
|
codec.queueSecureInputBuffer(index, offset, info, presentationTimeUs, flags);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
codec.flush();
|
codec.flush();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user