mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Make TransformerTranscodingVideoRenderer support API < 23
PiperOrigin-RevId: 393100075
This commit is contained in:
parent
c90d4fd371
commit
f574ec952a
@ -118,7 +118,8 @@ import java.nio.ByteBuffer;
|
|||||||
configuration.mediaFormat,
|
configuration.mediaFormat,
|
||||||
configuration.surface,
|
configuration.surface,
|
||||||
configuration.crypto,
|
configuration.crypto,
|
||||||
configuration.flags);
|
configuration.flags,
|
||||||
|
configuration.createInputSurface);
|
||||||
return codecAdapter;
|
return codecAdapter;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (codecAdapter != null) {
|
if (codecAdapter != null) {
|
||||||
@ -146,6 +147,7 @@ import java.nio.ByteBuffer;
|
|||||||
private final boolean synchronizeCodecInteractionsWithQueueing;
|
private final boolean synchronizeCodecInteractionsWithQueueing;
|
||||||
private boolean codecReleased;
|
private boolean codecReleased;
|
||||||
@State private int state;
|
@State private int state;
|
||||||
|
@Nullable private Surface inputSurface;
|
||||||
|
|
||||||
private AsynchronousMediaCodecAdapter(
|
private AsynchronousMediaCodecAdapter(
|
||||||
MediaCodec codec,
|
MediaCodec codec,
|
||||||
@ -166,11 +168,15 @@ import java.nio.ByteBuffer;
|
|||||||
@Nullable MediaFormat mediaFormat,
|
@Nullable MediaFormat mediaFormat,
|
||||||
@Nullable Surface surface,
|
@Nullable Surface surface,
|
||||||
@Nullable MediaCrypto crypto,
|
@Nullable MediaCrypto crypto,
|
||||||
int flags) {
|
int flags,
|
||||||
|
boolean createInputSurface) {
|
||||||
asynchronousMediaCodecCallback.initialize(codec);
|
asynchronousMediaCodecCallback.initialize(codec);
|
||||||
TraceUtil.beginSection("configureCodec");
|
TraceUtil.beginSection("configureCodec");
|
||||||
codec.configure(mediaFormat, surface, crypto, flags);
|
codec.configure(mediaFormat, surface, crypto, flags);
|
||||||
TraceUtil.endSection();
|
TraceUtil.endSection();
|
||||||
|
if (createInputSurface) {
|
||||||
|
inputSurface = codec.createInputSurface();
|
||||||
|
}
|
||||||
bufferEnqueuer.start();
|
bufferEnqueuer.start();
|
||||||
TraceUtil.beginSection("startCodec");
|
TraceUtil.beginSection("startCodec");
|
||||||
codec.start();
|
codec.start();
|
||||||
@ -226,6 +232,12 @@ import java.nio.ByteBuffer;
|
|||||||
return codec.getInputBuffer(index);
|
return codec.getInputBuffer(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public Surface getInputSurface() {
|
||||||
|
return inputSurface;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ByteBuffer getOutputBuffer(int index) {
|
public ByteBuffer getOutputBuffer(int index) {
|
||||||
@ -253,6 +265,9 @@ import java.nio.ByteBuffer;
|
|||||||
}
|
}
|
||||||
state = STATE_SHUT_DOWN;
|
state = STATE_SHUT_DOWN;
|
||||||
} finally {
|
} finally {
|
||||||
|
if (inputSurface != null) {
|
||||||
|
inputSurface.release();
|
||||||
|
}
|
||||||
if (!codecReleased) {
|
if (!codecReleased) {
|
||||||
codec.release();
|
codec.release();
|
||||||
codecReleased = true;
|
codecReleased = true;
|
||||||
|
@ -45,10 +45,7 @@ public interface MediaCodecAdapter {
|
|||||||
public final MediaFormat mediaFormat;
|
public final MediaFormat mediaFormat;
|
||||||
/** The {@link Format} for which the codec is being configured. */
|
/** The {@link Format} for which the codec is being configured. */
|
||||||
public final Format format;
|
public final Format format;
|
||||||
/**
|
/** For video decoding, the output where the object will render the decoded frames. */
|
||||||
* For video decoding, the output where the object will render the decoded frames; for video
|
|
||||||
* encoding, this is the input surface from which the decoded frames are retrieved.
|
|
||||||
*/
|
|
||||||
@Nullable public final Surface surface;
|
@Nullable public final Surface surface;
|
||||||
/** For DRM protected playbacks, a {@link MediaCrypto} to use for decryption. */
|
/** For DRM protected playbacks, a {@link MediaCrypto} to use for decryption. */
|
||||||
@Nullable public final MediaCrypto crypto;
|
@Nullable public final MediaCrypto crypto;
|
||||||
@ -58,6 +55,11 @@ public interface MediaCodecAdapter {
|
|||||||
* @see MediaCodec#configure
|
* @see MediaCodec#configure
|
||||||
*/
|
*/
|
||||||
public final int flags;
|
public final int flags;
|
||||||
|
/**
|
||||||
|
* Whether to request a {@link Surface} and use it as to the input to an encoder. This can only
|
||||||
|
* be set to {@code true} on API 18+.
|
||||||
|
*/
|
||||||
|
public final boolean createInputSurface;
|
||||||
|
|
||||||
public Configuration(
|
public Configuration(
|
||||||
MediaCodecInfo codecInfo,
|
MediaCodecInfo codecInfo,
|
||||||
@ -66,12 +68,24 @@ public interface MediaCodecAdapter {
|
|||||||
@Nullable Surface surface,
|
@Nullable Surface surface,
|
||||||
@Nullable MediaCrypto crypto,
|
@Nullable MediaCrypto crypto,
|
||||||
int flags) {
|
int flags) {
|
||||||
|
this(codecInfo, mediaFormat, format, surface, crypto, flags, /* createInputSurface= */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Configuration(
|
||||||
|
MediaCodecInfo codecInfo,
|
||||||
|
MediaFormat mediaFormat,
|
||||||
|
Format format,
|
||||||
|
@Nullable Surface surface,
|
||||||
|
@Nullable MediaCrypto crypto,
|
||||||
|
int flags,
|
||||||
|
boolean createInputSurface) {
|
||||||
this.codecInfo = codecInfo;
|
this.codecInfo = codecInfo;
|
||||||
this.mediaFormat = mediaFormat;
|
this.mediaFormat = mediaFormat;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.surface = surface;
|
this.surface = surface;
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
|
this.createInputSurface = createInputSurface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +143,14 @@ public interface MediaCodecAdapter {
|
|||||||
@Nullable
|
@Nullable
|
||||||
ByteBuffer getInputBuffer(int index);
|
ByteBuffer getInputBuffer(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the input {@link Surface}, or null if the input is not a surface.
|
||||||
|
*
|
||||||
|
* @see MediaCodec#createInputSurface()
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Surface getInputSurface();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a read-only ByteBuffer for a dequeued output buffer index.
|
* Returns a read-only ByteBuffer for a dequeued output buffer index.
|
||||||
*
|
*
|
||||||
|
@ -21,7 +21,6 @@ import static com.google.android.exoplayer2.util.Util.castNonNull;
|
|||||||
|
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
@ -47,31 +46,34 @@ public class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
|
|||||||
@RequiresApi(16)
|
@RequiresApi(16)
|
||||||
public MediaCodecAdapter createAdapter(Configuration configuration) throws IOException {
|
public MediaCodecAdapter createAdapter(Configuration configuration) throws IOException {
|
||||||
@Nullable MediaCodec codec = null;
|
@Nullable MediaCodec codec = null;
|
||||||
boolean isEncoder = configuration.flags == MediaCodec.CONFIGURE_FLAG_ENCODE;
|
@Nullable Surface inputSurface = null;
|
||||||
@Nullable Surface decoderOutputSurface = isEncoder ? null : configuration.surface;
|
|
||||||
try {
|
try {
|
||||||
codec = createCodec(configuration);
|
codec = createCodec(configuration);
|
||||||
TraceUtil.beginSection("configureCodec");
|
TraceUtil.beginSection("configureCodec");
|
||||||
codec.configure(
|
codec.configure(
|
||||||
configuration.mediaFormat,
|
configuration.mediaFormat,
|
||||||
decoderOutputSurface,
|
configuration.surface,
|
||||||
configuration.crypto,
|
configuration.crypto,
|
||||||
configuration.flags);
|
configuration.flags);
|
||||||
TraceUtil.endSection();
|
TraceUtil.endSection();
|
||||||
if (isEncoder && configuration.surface != null) {
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (configuration.createInputSurface) {
|
||||||
Api23.setCodecInputSurface(codec, configuration.surface);
|
if (Util.SDK_INT >= 18) {
|
||||||
|
inputSurface = Api18.createCodecInputSurface(codec);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Encoding from a surface is only supported on API 23 and up");
|
"Encoding from a surface is only supported on API 18 and up.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceUtil.beginSection("startCodec");
|
TraceUtil.beginSection("startCodec");
|
||||||
codec.start();
|
codec.start();
|
||||||
TraceUtil.endSection();
|
TraceUtil.endSection();
|
||||||
return new SynchronousMediaCodecAdapter(codec);
|
return new SynchronousMediaCodecAdapter(codec, inputSurface);
|
||||||
} catch (IOException | RuntimeException e) {
|
} catch (IOException | RuntimeException e) {
|
||||||
|
if (inputSurface != null) {
|
||||||
|
inputSurface.release();
|
||||||
|
}
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
codec.release();
|
codec.release();
|
||||||
}
|
}
|
||||||
@ -91,11 +93,13 @@ public class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final MediaCodec codec;
|
private final MediaCodec codec;
|
||||||
|
@Nullable private final Surface inputSurface;
|
||||||
@Nullable private ByteBuffer[] inputByteBuffers;
|
@Nullable private ByteBuffer[] inputByteBuffers;
|
||||||
@Nullable private ByteBuffer[] outputByteBuffers;
|
@Nullable private ByteBuffer[] outputByteBuffers;
|
||||||
|
|
||||||
private SynchronousMediaCodecAdapter(MediaCodec mediaCodec) {
|
private SynchronousMediaCodecAdapter(MediaCodec mediaCodec, @Nullable Surface inputSurface) {
|
||||||
this.codec = mediaCodec;
|
this.codec = mediaCodec;
|
||||||
|
this.inputSurface = inputSurface;
|
||||||
if (Util.SDK_INT < 21) {
|
if (Util.SDK_INT < 21) {
|
||||||
inputByteBuffers = codec.getInputBuffers();
|
inputByteBuffers = codec.getInputBuffers();
|
||||||
outputByteBuffers = codec.getOutputBuffers();
|
outputByteBuffers = codec.getOutputBuffers();
|
||||||
@ -140,6 +144,12 @@ public class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public Surface getInputSurface() {
|
||||||
|
return inputSurface;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ByteBuffer getOutputBuffer(int index) {
|
public ByteBuffer getOutputBuffer(int index) {
|
||||||
@ -183,6 +193,9 @@ public class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
|
|||||||
public void release() {
|
public void release() {
|
||||||
inputByteBuffers = null;
|
inputByteBuffers = null;
|
||||||
outputByteBuffers = null;
|
outputByteBuffers = null;
|
||||||
|
if (inputSurface != null) {
|
||||||
|
inputSurface.release();
|
||||||
|
}
|
||||||
codec.release();
|
codec.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,11 +226,11 @@ public class SynchronousMediaCodecAdapter implements MediaCodecAdapter {
|
|||||||
codec.setVideoScalingMode(scalingMode);
|
codec.setVideoScalingMode(scalingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(23)
|
@RequiresApi(18)
|
||||||
private static final class Api23 {
|
private static final class Api18 {
|
||||||
@DoNotInline
|
@DoNotInline
|
||||||
public static void setCodecInputSurface(MediaCodec codec, Surface surface) {
|
public static Surface createCodecInputSurface(MediaCodec codec) {
|
||||||
codec.setInputSurface(surface);
|
return codec.createInputSurface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* through {@link MediaCodecAdapter}. This is done by simplifying the calls needed to queue and
|
* through {@link MediaCodecAdapter}. This is done by simplifying the calls needed to queue and
|
||||||
* dequeue buffers, removing the need to track buffer indices and codec events.
|
* dequeue buffers, removing the need to track buffer indices and codec events.
|
||||||
*/
|
*/
|
||||||
|
@RequiresApi(18)
|
||||||
/* package */ final class MediaCodecAdapterWrapper {
|
/* package */ final class MediaCodecAdapterWrapper {
|
||||||
|
|
||||||
// MediaCodec decoders always output 16 bit PCM, unless configured to output PCM float.
|
// MediaCodec decoders always output 16 bit PCM, unless configured to output PCM float.
|
||||||
@ -142,7 +143,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* @return A configured and started decoder wrapper.
|
* @return A configured and started decoder wrapper.
|
||||||
* @throws IOException If the underlying codec cannot be created.
|
* @throws IOException If the underlying codec cannot be created.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(23)
|
|
||||||
public static MediaCodecAdapterWrapper createForVideoDecoding(Format format, Surface surface)
|
public static MediaCodecAdapterWrapper createForVideoDecoding(Format format, Surface surface)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@Nullable MediaCodecAdapter adapter = null;
|
@Nullable MediaCodecAdapter adapter = null;
|
||||||
@ -163,7 +163,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
surface,
|
surface,
|
||||||
/* crypto= */ null,
|
/* crypto= */ null,
|
||||||
/* flags= */ 0));
|
/* flags= */ 0));
|
||||||
adapter.setOutputSurface(surface);
|
|
||||||
return new MediaCodecAdapterWrapper(adapter);
|
return new MediaCodecAdapterWrapper(adapter);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
@ -217,13 +216,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
*
|
*
|
||||||
* @param format The {@link Format} (of the output data) used to determine the underlying {@link
|
* @param format The {@link Format} (of the output data) used to determine the underlying {@link
|
||||||
* MediaCodec} and its configuration values.
|
* MediaCodec} and its configuration values.
|
||||||
* @param surface The {@link Surface} from which the encoder obtains the frame input.
|
|
||||||
* @return A configured and started encoder wrapper.
|
* @return A configured and started encoder wrapper.
|
||||||
* @throws IOException If the underlying codec cannot be created.
|
* @throws IOException If the underlying codec cannot be created.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(18)
|
public static MediaCodecAdapterWrapper createForVideoEncoding(Format format) throws IOException {
|
||||||
public static MediaCodecAdapterWrapper createForVideoEncoding(Format format, Surface surface)
|
|
||||||
throws IOException {
|
|
||||||
@Nullable MediaCodecAdapter adapter = null;
|
@Nullable MediaCodecAdapter adapter = null;
|
||||||
try {
|
try {
|
||||||
MediaFormat mediaFormat =
|
MediaFormat mediaFormat =
|
||||||
@ -242,9 +238,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
createPlaceholderMediaCodecInfo(),
|
createPlaceholderMediaCodecInfo(),
|
||||||
mediaFormat,
|
mediaFormat,
|
||||||
format,
|
format,
|
||||||
surface,
|
/* surface= */ null,
|
||||||
/* crypto= */ null,
|
/* crypto= */ null,
|
||||||
MediaCodec.CONFIGURE_FLAG_ENCODE));
|
MediaCodec.CONFIGURE_FLAG_ENCODE,
|
||||||
|
/* createInputSurface= */ true));
|
||||||
return new MediaCodecAdapterWrapper(adapter);
|
return new MediaCodecAdapterWrapper(adapter);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
@ -261,6 +258,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
outputBufferIndex = C.INDEX_UNSET;
|
outputBufferIndex = C.INDEX_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the input {@link Surface}, or null if the input is not a surface. */
|
||||||
|
@Nullable
|
||||||
|
public Surface getInputSurface() {
|
||||||
|
return codec.getInputSurface();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dequeues a writable input buffer, if available.
|
* Dequeues a writable input buffer, if available.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +19,6 @@ package com.google.android.exoplayer2.transformer;
|
|||||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||||
|
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.view.Surface;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
@ -32,7 +31,7 @@ import com.google.android.exoplayer2.source.SampleStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@RequiresApi(23)
|
@RequiresApi(18)
|
||||||
/* package */ final class TransformerTranscodingVideoRenderer extends TransformerBaseRenderer {
|
/* package */ final class TransformerTranscodingVideoRenderer extends TransformerBaseRenderer {
|
||||||
|
|
||||||
private static final String TAG = "TransformerTranscodingVideoRenderer";
|
private static final String TAG = "TransformerTranscodingVideoRenderer";
|
||||||
@ -41,8 +40,6 @@ import java.nio.ByteBuffer;
|
|||||||
/** The format the encoder is configured to output, may differ from the actual output format. */
|
/** The format the encoder is configured to output, may differ from the actual output format. */
|
||||||
private final Format encoderConfigurationOutputFormat;
|
private final Format encoderConfigurationOutputFormat;
|
||||||
|
|
||||||
private final Surface surface;
|
|
||||||
|
|
||||||
@Nullable private MediaCodecAdapterWrapper decoder;
|
@Nullable private MediaCodecAdapterWrapper decoder;
|
||||||
@Nullable private MediaCodecAdapterWrapper encoder;
|
@Nullable private MediaCodecAdapterWrapper encoder;
|
||||||
/** Whether encoder's actual output format is obtained. */
|
/** Whether encoder's actual output format is obtained. */
|
||||||
@ -58,7 +55,6 @@ import java.nio.ByteBuffer;
|
|||||||
super(C.TRACK_TYPE_VIDEO, muxerWrapper, mediaClock, transformation);
|
super(C.TRACK_TYPE_VIDEO, muxerWrapper, mediaClock, transformation);
|
||||||
|
|
||||||
decoderInputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
|
decoderInputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
|
||||||
surface = MediaCodec.createPersistentInputSurface();
|
|
||||||
this.encoderConfigurationOutputFormat = encoderConfigurationOutputFormat;
|
this.encoderConfigurationOutputFormat = encoderConfigurationOutputFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +89,6 @@ import java.nio.ByteBuffer;
|
|||||||
protected void onReset() {
|
protected void onReset() {
|
||||||
decoderInputBuffer.clear();
|
decoderInputBuffer.clear();
|
||||||
decoderInputBuffer.data = null;
|
decoderInputBuffer.data = null;
|
||||||
surface.release();
|
|
||||||
if (decoder != null) {
|
if (decoder != null) {
|
||||||
decoder.release();
|
decoder.release();
|
||||||
decoder = null;
|
decoder = null;
|
||||||
@ -121,8 +116,11 @@ import java.nio.ByteBuffer;
|
|||||||
}
|
}
|
||||||
|
|
||||||
Format inputFormat = checkNotNull(formatHolder.format);
|
Format inputFormat = checkNotNull(formatHolder.format);
|
||||||
|
MediaCodecAdapterWrapper encoder = checkNotNull(this.encoder);
|
||||||
try {
|
try {
|
||||||
decoder = MediaCodecAdapterWrapper.createForVideoDecoding(inputFormat, surface);
|
decoder =
|
||||||
|
MediaCodecAdapterWrapper.createForVideoDecoding(
|
||||||
|
inputFormat, checkNotNull(encoder.getInputSurface()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw createRendererException(
|
throw createRendererException(
|
||||||
e, formatHolder.format, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
|
e, formatHolder.format, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
|
||||||
@ -136,9 +134,7 @@ import java.nio.ByteBuffer;
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
encoder =
|
encoder = MediaCodecAdapterWrapper.createForVideoEncoding(encoderConfigurationOutputFormat);
|
||||||
MediaCodecAdapterWrapper.createForVideoEncoding(
|
|
||||||
encoderConfigurationOutputFormat, surface);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw createRendererException(
|
throw createRendererException(
|
||||||
// TODO(claincly): should be "ENCODER_INIT_FAILED"
|
// TODO(claincly): should be "ENCODER_INIT_FAILED"
|
||||||
|
@ -193,6 +193,12 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
|
|||||||
return inputBuffer;
|
return inputBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Surface getInputSurface() {
|
||||||
|
return delegate.getInputSurface();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer getOutputBuffer(int index) {
|
public ByteBuffer getOutputBuffer(int index) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user