public class CustomVideoCodecRenderer
extends com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
MediaCodec
.
This renderer accepts the following messages sent via ExoPlayer#createMessage(Target)
on the playback thread:
C.MSG_SET_SURFACE
to set the output surface. The message payload
should be the target Surface
, or null.
C.MSG_SET_SCALING_MODE
to set the video scaling mode. The message
payload should be one of the integer scaling modes in C.VideoScalingMode
. Note that
the scaling mode only applies if the Surface
targeted by this renderer is owned by
a SurfaceView
.
Modifier and Type | Class and Description |
---|---|
protected static class |
CustomVideoCodecRenderer.CodecMaxValues |
decoderCounters, KEEP_CODEC_RESULT_NO, KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION, KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION
STATE_DISABLED, STATE_ENABLED, STATE_STARTED
ADAPTIVE_NOT_SEAMLESS, ADAPTIVE_NOT_SUPPORTED, ADAPTIVE_SEAMLESS, ADAPTIVE_SUPPORT_MASK, FORMAT_EXCEEDS_CAPABILITIES, FORMAT_HANDLED, FORMAT_SUPPORT_MASK, FORMAT_UNSUPPORTED_DRM, FORMAT_UNSUPPORTED_SUBTYPE, FORMAT_UNSUPPORTED_TYPE, TUNNELING_NOT_SUPPORTED, TUNNELING_SUPPORT_MASK, TUNNELING_SUPPORTED
Constructor and Description |
---|
CustomVideoCodecRenderer(android.content.Context context,
com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector) |
CustomVideoCodecRenderer(android.content.Context context,
com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs) |
CustomVideoCodecRenderer(android.content.Context context,
com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs,
com.google.android.exoplayer2.drm.DrmSessionManager<com.google.android.exoplayer2.drm.FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys,
android.os.Handler eventHandler,
com.google.android.exoplayer2.video.VideoRendererEventListener eventListener,
int maxDroppedFramesToNotify) |
CustomVideoCodecRenderer(android.content.Context context,
com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs,
android.os.Handler eventHandler,
com.google.android.exoplayer2.video.VideoRendererEventListener eventListener,
int maxDroppedFrameCountToNotify) |
Modifier and Type | Method and Description |
---|---|
protected int |
canKeepCodec(android.media.MediaCodec codec,
com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo,
com.google.android.exoplayer2.Format oldFormat,
com.google.android.exoplayer2.Format newFormat) |
protected void |
configureCodec(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo,
android.media.MediaCodec codec,
com.google.android.exoplayer2.Format format,
android.media.MediaCrypto crypto) |
protected void |
dropOutputBuffer(android.media.MediaCodec codec,
int index,
long presentationTimeUs)
Drops the output buffer with the specified index.
|
protected void |
flushCodec() |
protected CustomVideoCodecRenderer.CodecMaxValues |
getCodecMaxValues(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo,
com.google.android.exoplayer2.Format format,
com.google.android.exoplayer2.Format[] streamFormats)
Returns
CustomVideoCodecRenderer.CodecMaxValues suitable for configuring a codec for format in a way
that will allow possible adaptation to other compatible formats in streamFormats . |
protected android.media.MediaFormat |
getMediaFormat(com.google.android.exoplayer2.Format format,
CustomVideoCodecRenderer.CodecMaxValues codecMaxValues,
boolean deviceNeedsAutoFrcWorkaround,
int tunnelingAudioSessionId)
Returns the framework
MediaFormat that should be used to configure the decoder. |
void |
handleMessage(int messageType,
java.lang.Object message) |
boolean |
isReady() |
protected boolean |
maybeDropBuffersToKeyframe(android.media.MediaCodec codec,
int index,
long presentationTimeUs,
long positionUs)
Drops frames from the current output buffer to the next keyframe at or before the playback
position.
|
protected void |
onCodecInitialized(java.lang.String name,
long initializedTimestampMs,
long initializationDurationMs) |
protected void |
onDisabled() |
protected void |
onEnabled(boolean joining) |
protected void |
onInputFormatChanged(com.google.android.exoplayer2.Format newFormat) |
protected void |
onOutputFormatChanged(android.media.MediaCodec codec,
android.media.MediaFormat outputFormat) |
protected void |
onPositionReset(long positionUs,
boolean joining) |
protected void |
onProcessedOutputBuffer(long presentationTimeUs)
Called when an output buffer is successfully processed.
|
protected void |
onQueueInputBuffer(com.google.android.exoplayer2.decoder.DecoderInputBuffer buffer)
Called immediately before an input buffer is queued into the codec.
|
protected void |
onStarted() |
protected void |
onStopped() |
protected void |
onStreamChanged(com.google.android.exoplayer2.Format[] formats,
long offsetUs) |
protected boolean |
processOutputBuffer(long positionUs,
long elapsedRealtimeUs,
android.media.MediaCodec codec,
java.nio.ByteBuffer buffer,
int bufferIndex,
int bufferFlags,
long bufferPresentationTimeUs,
boolean shouldSkip) |
protected void |
releaseCodec() |
protected void |
renderOutputBuffer(android.media.MediaCodec codec,
int index,
long presentationTimeUs)
Renders the output buffer with the specified index.
|
protected void |
renderOutputBufferV21(android.media.MediaCodec codec,
int index,
long presentationTimeUs,
long releaseTimeNs)
Renders the output buffer with the specified index.
|
protected boolean |
shouldDropBuffersToKeyframe(long earlyUs,
long elapsedRealtimeUs)
Returns whether to drop all buffers from the buffer being processed to the keyframe at or after
the current playback position, if possible.
|
protected boolean |
shouldDropOutputBuffer(long earlyUs,
long elapsedRealtimeUs)
Returns whether the buffer being processed should be dropped.
|
protected boolean |
shouldForceRenderOutputBuffer(long earlyUs,
long elapsedSinceLastRenderUs)
Returns whether to force rendering an output buffer.
|
protected boolean |
shouldInitCodec(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo) |
protected void |
skipOutputBuffer(android.media.MediaCodec codec,
int index,
long presentationTimeUs)
Skips the output buffer with the specified index.
|
protected int |
supportsFormat(com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector,
com.google.android.exoplayer2.drm.DrmSessionManager<com.google.android.exoplayer2.drm.FrameworkMediaCrypto> drmSessionManager,
com.google.android.exoplayer2.Format format) |
protected void |
updateDroppedBufferCounters(int droppedBufferCount)
Updates decoder counters to reflect that
droppedBufferCount additional buffers were
dropped. |
getCodec, getCodecInfo, getDecoderInfo, getDequeueOutputBufferTimeoutUs, isEnded, maybeInitCodec, render, renderToEndOfStream, supportsFormat, supportsMixedMimeTypeAdaptation
disable, enable, getCapabilities, getConfiguration, getIndex, getMediaClock, getState, getStream, getStreamFormats, getTrackType, hasReadStreamToEnd, isCurrentStreamFinal, isSourceReady, maybeThrowStreamError, readSource, replaceStream, resetPosition, setCurrentStreamFinal, setIndex, skipSource, start, stop, supportsFormatDrm
public CustomVideoCodecRenderer(android.content.Context context, com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector)
context
- A context.mediaCodecSelector
- A decoder selector.public CustomVideoCodecRenderer(android.content.Context context, com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs)
context
- A context.mediaCodecSelector
- A decoder selector.allowedJoiningTimeMs
- The maximum duration in milliseconds for which this video renderer
can attempt to seamlessly join an ongoing playback.public CustomVideoCodecRenderer(android.content.Context context, com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs, @Nullable android.os.Handler eventHandler, @Nullable com.google.android.exoplayer2.video.VideoRendererEventListener eventListener, int maxDroppedFrameCountToNotify)
context
- A context.mediaCodecSelector
- A decoder selector.allowedJoiningTimeMs
- The maximum duration in milliseconds for which this video renderer
can attempt to seamlessly join an ongoing playback.eventHandler
- A handler to use when delivering events to eventListener
. May be
null if delivery of events is not required.eventListener
- A listener of events. May be null if delivery of events is not required.maxDroppedFrameCountToNotify
- The maximum number of frames that can be dropped between
invocations of VideoRendererEventListener.onDroppedFrames(int, long)
.public CustomVideoCodecRenderer(android.content.Context context, com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector, long allowedJoiningTimeMs, @Nullable com.google.android.exoplayer2.drm.DrmSessionManager<com.google.android.exoplayer2.drm.FrameworkMediaCrypto> drmSessionManager, boolean playClearSamplesWithoutKeys, @Nullable android.os.Handler eventHandler, @Nullable com.google.android.exoplayer2.video.VideoRendererEventListener eventListener, int maxDroppedFramesToNotify)
context
- A context.mediaCodecSelector
- A decoder selector.allowedJoiningTimeMs
- The maximum duration in milliseconds for which this video renderer
can attempt to seamlessly join an ongoing playback.drmSessionManager
- For use with encrypted content. May be null if support for encrypted
content is not required.playClearSamplesWithoutKeys
- Encrypted media may contain clear (un-encrypted) regions.
For example a media file may start with a short clear region so as to allow playback to
begin in parallel with key acquisition. This parameter specifies whether the renderer is
permitted to play clear regions of encrypted media files before drmSessionManager
has obtained the keys necessary to decrypt encrypted regions of the media.eventHandler
- A handler to use when delivering events to eventListener
. May be
null if delivery of events is not required.eventListener
- A listener of events. May be null if delivery of events is not required.maxDroppedFramesToNotify
- The maximum number of frames that can be dropped between
invocations of VideoRendererEventListener.onDroppedFrames(int, long)
.protected int supportsFormat(com.google.android.exoplayer2.mediacodec.MediaCodecSelector mediaCodecSelector, com.google.android.exoplayer2.drm.DrmSessionManager<com.google.android.exoplayer2.drm.FrameworkMediaCrypto> drmSessionManager, com.google.android.exoplayer2.Format format) throws com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
supportsFormat
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
protected void onEnabled(boolean joining) throws com.google.android.exoplayer2.ExoPlaybackException
onEnabled
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.ExoPlaybackException
protected void onStreamChanged(com.google.android.exoplayer2.Format[] formats, long offsetUs) throws com.google.android.exoplayer2.ExoPlaybackException
onStreamChanged
in class com.google.android.exoplayer2.BaseRenderer
com.google.android.exoplayer2.ExoPlaybackException
protected void onPositionReset(long positionUs, boolean joining) throws com.google.android.exoplayer2.ExoPlaybackException
onPositionReset
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.ExoPlaybackException
public boolean isReady()
isReady
in interface com.google.android.exoplayer2.Renderer
isReady
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected void onStarted()
onStarted
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected void onStopped()
onStopped
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected void onDisabled()
onDisabled
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
public void handleMessage(int messageType, java.lang.Object message) throws com.google.android.exoplayer2.ExoPlaybackException
handleMessage
in interface com.google.android.exoplayer2.PlayerMessage.Target
handleMessage
in class com.google.android.exoplayer2.BaseRenderer
com.google.android.exoplayer2.ExoPlaybackException
protected boolean shouldInitCodec(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo)
shouldInitCodec
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected void configureCodec(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo, android.media.MediaCodec codec, com.google.android.exoplayer2.Format format, android.media.MediaCrypto crypto) throws com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
configureCodec
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
protected int canKeepCodec(android.media.MediaCodec codec, com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo, com.google.android.exoplayer2.Format oldFormat, com.google.android.exoplayer2.Format newFormat)
canKeepCodec
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
@CallSuper protected void releaseCodec()
releaseCodec
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
@CallSuper protected void flushCodec() throws com.google.android.exoplayer2.ExoPlaybackException
flushCodec
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.ExoPlaybackException
protected void onCodecInitialized(java.lang.String name, long initializedTimestampMs, long initializationDurationMs)
onCodecInitialized
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected void onInputFormatChanged(com.google.android.exoplayer2.Format newFormat) throws com.google.android.exoplayer2.ExoPlaybackException
onInputFormatChanged
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.ExoPlaybackException
@CallSuper protected void onQueueInputBuffer(com.google.android.exoplayer2.decoder.DecoderInputBuffer buffer)
onQueueInputBuffer
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
buffer
- The buffer to be queued.protected void onOutputFormatChanged(android.media.MediaCodec codec, android.media.MediaFormat outputFormat)
onOutputFormatChanged
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
protected boolean processOutputBuffer(long positionUs, long elapsedRealtimeUs, android.media.MediaCodec codec, java.nio.ByteBuffer buffer, int bufferIndex, int bufferFlags, long bufferPresentationTimeUs, boolean shouldSkip) throws com.google.android.exoplayer2.ExoPlaybackException
processOutputBuffer
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
com.google.android.exoplayer2.ExoPlaybackException
@CallSuper protected void onProcessedOutputBuffer(long presentationTimeUs)
onProcessedOutputBuffer
in class com.google.android.exoplayer2.mediacodec.MediaCodecRenderer
presentationTimeUs
- The timestamp associated with the output buffer.protected boolean shouldDropOutputBuffer(long earlyUs, long elapsedRealtimeUs)
earlyUs
- The time until the buffer should be presented in microseconds. A negative value
indicates that the buffer is late.elapsedRealtimeUs
- SystemClock.elapsedRealtime()
in microseconds,
measured at the start of the current iteration of the rendering loop.protected boolean shouldDropBuffersToKeyframe(long earlyUs, long elapsedRealtimeUs)
earlyUs
- The time until the current buffer should be presented in microseconds. A
negative value indicates that the buffer is late.elapsedRealtimeUs
- SystemClock.elapsedRealtime()
in microseconds,
measured at the start of the current iteration of the rendering loop.protected boolean shouldForceRenderOutputBuffer(long earlyUs, long elapsedSinceLastRenderUs)
earlyUs
- The time until the current buffer should be presented in microseconds. A
negative value indicates that the buffer is late.elapsedSinceLastRenderUs
- The elapsed time since the last output buffer was rendered, in
microseconds.protected void skipOutputBuffer(android.media.MediaCodec codec, int index, long presentationTimeUs)
codec
- The codec that owns the output buffer.index
- The index of the output buffer to skip.presentationTimeUs
- The presentation time of the output buffer, in microseconds.protected void dropOutputBuffer(android.media.MediaCodec codec, int index, long presentationTimeUs)
codec
- The codec that owns the output buffer.index
- The index of the output buffer to drop.presentationTimeUs
- The presentation time of the output buffer, in microseconds.protected boolean maybeDropBuffersToKeyframe(android.media.MediaCodec codec, int index, long presentationTimeUs, long positionUs) throws com.google.android.exoplayer2.ExoPlaybackException
false
. Returns true
otherwise.codec
- The codec that owns the output buffer.index
- The index of the output buffer to drop.presentationTimeUs
- The presentation time of the output buffer, in microseconds.positionUs
- The current playback position, in microseconds.com.google.android.exoplayer2.ExoPlaybackException
- If an error occurs flushing the codec.protected void updateDroppedBufferCounters(int droppedBufferCount)
droppedBufferCount
additional buffers were
dropped.droppedBufferCount
- The number of additional dropped buffers.protected void renderOutputBuffer(android.media.MediaCodec codec, int index, long presentationTimeUs)
codec
- The codec that owns the output buffer.index
- The index of the output buffer to drop.presentationTimeUs
- The presentation time of the output buffer, in microseconds.protected void renderOutputBufferV21(android.media.MediaCodec codec, int index, long presentationTimeUs, long releaseTimeNs)
codec
- The codec that owns the output buffer.index
- The index of the output buffer to drop.presentationTimeUs
- The presentation time of the output buffer, in microseconds.releaseTimeNs
- The wallclock time at which the frame should be displayed, in nanoseconds.protected android.media.MediaFormat getMediaFormat(com.google.android.exoplayer2.Format format, CustomVideoCodecRenderer.CodecMaxValues codecMaxValues, boolean deviceNeedsAutoFrcWorkaround, int tunnelingAudioSessionId)
MediaFormat
that should be used to configure the decoder.format
- The format of media.codecMaxValues
- Codec max values that should be used when configuring the decoder.deviceNeedsAutoFrcWorkaround
- Whether the device is known to enable frame-rate conversion
logic that negatively impacts ExoPlayer.tunnelingAudioSessionId
- The audio session id to use for tunneling, or C.AUDIO_SESSION_ID_UNSET
if tunneling should not be enabled.MediaFormat
that should be used to configure the decoder.protected CustomVideoCodecRenderer.CodecMaxValues getCodecMaxValues(com.google.android.exoplayer2.mediacodec.MediaCodecInfo codecInfo, com.google.android.exoplayer2.Format format, com.google.android.exoplayer2.Format[] streamFormats) throws com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
CustomVideoCodecRenderer.CodecMaxValues
suitable for configuring a codec for format
in a way
that will allow possible adaptation to other compatible formats in streamFormats
.codecInfo
- Information about the MediaCodec
being configured.format
- The format for which the codec is being configured.streamFormats
- The possible stream formats.CustomVideoCodecRenderer.CodecMaxValues
.com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException
- If an error occurs querying codecInfo
.