PlayerMessage.Target
, Renderer
, RendererCapabilities
Libgav1VideoRenderer
, LibvpxVideoRenderer
public abstract class DecoderVideoRenderer extends BaseRenderer
Decoder
.
This renderer accepts the following messages sent via ExoPlayer.createMessage(Target)
on the playback thread:
Renderer.MSG_SET_SURFACE
to set the output surface. The message payload
should be the target Surface
, or null.
Renderer.MSG_SET_VIDEO_DECODER_OUTPUT_BUFFER_RENDERER
to set the output
buffer renderer. The message payload should be the target VideoDecoderOutputBufferRenderer
, or null.
Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER
to set a listener for
metadata associated with frames being rendered. The message payload should be the VideoFrameMetadataListener
, or null.
Renderer.State, Renderer.VideoScalingMode, Renderer.WakeupListener
RendererCapabilities.AdaptiveSupport, RendererCapabilities.Capabilities, RendererCapabilities.FormatSupport, RendererCapabilities.TunnelingSupport
Modifier and Type | Field | Description |
---|---|---|
protected DecoderCounters |
decoderCounters |
Decoder event counters used for debugging purposes.
|
MSG_CUSTOM_BASE, MSG_SET_AUDIO_ATTRIBUTES, MSG_SET_AUDIO_SESSION_ID, MSG_SET_AUX_EFFECT_INFO, MSG_SET_CAMERA_MOTION_LISTENER, MSG_SET_SCALING_MODE, MSG_SET_SKIP_SILENCE_ENABLED, MSG_SET_SURFACE, MSG_SET_VIDEO_DECODER_OUTPUT_BUFFER_RENDERER, MSG_SET_VIDEO_FRAME_METADATA_LISTENER, MSG_SET_VOLUME, MSG_SET_WAKEUP_LISTENER, STATE_DISABLED, STATE_ENABLED, STATE_STARTED, VIDEO_SCALING_MODE_DEFAULT, VIDEO_SCALING_MODE_SCALE_TO_FIT, VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
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
Modifier | Constructor | Description |
---|---|---|
protected |
DecoderVideoRenderer(long allowedJoiningTimeMs,
Handler eventHandler,
VideoRendererEventListener eventListener,
int maxDroppedFramesToNotify) |
Modifier and Type | Method | Description |
---|---|---|
protected boolean |
canKeepCodec(Format oldFormat,
Format newFormat) |
Returns whether the existing decoder can be kept for a new format.
|
protected abstract Decoder<VideoDecoderInputBuffer,? extends VideoDecoderOutputBuffer,? extends DecoderException> |
createDecoder(Format format,
ExoMediaCrypto mediaCrypto) |
Creates a decoder for the given format.
|
protected void |
dropOutputBuffer(VideoDecoderOutputBuffer outputBuffer) |
Drops the specified output buffer and releases it.
|
protected void |
flushDecoder() |
Flushes the decoder.
|
void |
handleMessage(int messageType,
Object message) |
Handles a message delivered to the target.
|
boolean |
isEnded() |
Whether the renderer is ready for the
ExoPlayer instance to transition to Player.STATE_ENDED . |
boolean |
isReady() |
Whether the renderer is able to immediately render media from the current position.
|
protected boolean |
maybeDropBuffersToKeyframe(long positionUs) |
Drops frames from the current output buffer to the next keyframe at or before the playback
position.
|
protected void |
onDecoderInitialized(String name,
long initializedTimestampMs,
long initializationDurationMs) |
Called when a decoder has been created and configured.
|
protected void |
onDisabled() |
Called when the renderer is disabled.
|
protected void |
onEnabled(boolean joining,
boolean mayRenderStartOfStream) |
Called when the renderer is enabled.
|
protected void |
onInputFormatChanged(FormatHolder formatHolder) |
Called when a new format is read from the upstream source.
|
protected void |
onPositionReset(long positionUs,
boolean joining) |
Called when the position is reset.
|
protected void |
onProcessedOutputBuffer(long presentationTimeUs) |
Called when an output buffer is successfully processed.
|
protected void |
onQueueInputBuffer(VideoDecoderInputBuffer buffer) |
Called immediately before an input buffer is queued into the decoder.
|
protected void |
onStarted() |
Called when the renderer is started.
|
protected void |
onStopped() |
Called when the renderer is stopped.
|
protected void |
onStreamChanged(Format[] formats,
long startPositionUs,
long offsetUs) |
Called when the renderer's stream has changed.
|
protected void |
releaseDecoder() |
Releases the decoder.
|
void |
render(long positionUs,
long elapsedRealtimeUs) |
Incrementally renders the
SampleStream . |
protected void |
renderOutputBuffer(VideoDecoderOutputBuffer outputBuffer,
long presentationTimeUs,
Format outputFormat) |
Renders the specified output buffer.
|
protected abstract void |
renderOutputBufferToSurface(VideoDecoderOutputBuffer outputBuffer,
Surface surface) |
Renders the specified output buffer to the passed surface.
|
protected abstract void |
setDecoderOutputMode(int outputMode) |
Sets output mode of the decoder.
|
protected void |
setOutputBufferRenderer(VideoDecoderOutputBufferRenderer outputBufferRenderer) |
Sets output buffer renderer.
|
protected void |
setOutputSurface(Surface surface) |
Sets output surface.
|
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 void |
skipOutputBuffer(VideoDecoderOutputBuffer outputBuffer) |
Skips the specified output buffer and releases it.
|
protected void |
updateDroppedBufferCounters(int droppedBufferCount) |
Updates decoder counters to reflect that
droppedBufferCount additional buffers were
dropped. |
createRendererException, disable, enable, getCapabilities, getConfiguration, getFormatHolder, getIndex, getLastResetPositionUs, getMediaClock, getReadingPositionUs, getState, getStream, getStreamFormats, getTrackType, hasReadStreamToEnd, isCurrentStreamFinal, isSourceReady, maybeThrowStreamError, onReset, readSource, replaceStream, reset, resetPosition, setCurrentStreamFinal, setIndex, skipSource, start, stop, supportsMixedMimeTypeAdaptation
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getName, setOperatingRate
getName, supportsFormat
protected DecoderCounters decoderCounters
protected DecoderVideoRenderer(long allowedJoiningTimeMs, @Nullable Handler eventHandler, @Nullable VideoRendererEventListener eventListener, int maxDroppedFramesToNotify)
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.maxDroppedFramesToNotify
- The maximum number of frames that can be dropped between
invocations of VideoRendererEventListener.onDroppedFrames(int, long)
.public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException
Renderer
SampleStream
.
If the renderer is in the Renderer.STATE_ENABLED
state then each call to this method will do
work toward being ready to render the SampleStream
when the renderer is started. If the
renderer is in the Renderer.STATE_STARTED
state then calls to this method will render the
SampleStream
in sync with the specified media positions.
The renderer may also render the very start of the media at the current position (e.g. the
first frame of a video stream) while still in the Renderer.STATE_ENABLED
state, unless it's the
initial start of the media after calling Renderer.enable(RendererConfiguration, Format[],
SampleStream, long, boolean, boolean, long, long)
with mayRenderStartOfStream
set to
false
.
This method should return quickly, and should not block if the renderer is unable to make useful progress.
This method may be called when the renderer is in the following states: Renderer.STATE_ENABLED
, Renderer.STATE_STARTED
.
positionUs
- The current media time in microseconds, measured at the start of the current
iteration of the rendering loop.elapsedRealtimeUs
- SystemClock.elapsedRealtime()
in microseconds,
measured at the start of the current iteration of the rendering loop.ExoPlaybackException
- If an error occurs.public boolean isEnded()
Renderer
ExoPlayer
instance to transition to Player.STATE_ENDED
. The player will make this transition as soon as true
is returned
by all of its renderers.
This method may be called when the renderer is in the following states: Renderer.STATE_ENABLED
, Renderer.STATE_STARTED
.
public boolean isReady()
Renderer
If the renderer is in the Renderer.STATE_STARTED
state then returning true indicates that the
renderer has everything that it needs to continue playback. Returning false indicates that
the player should pause until the renderer is ready.
If the renderer is in the Renderer.STATE_ENABLED
state then returning true indicates that the
renderer is ready for playback to be started. Returning false indicates that it is not.
This method may be called when the renderer is in the following states:
Renderer.STATE_ENABLED
, Renderer.STATE_STARTED
.
public void handleMessage(int messageType, @Nullable Object message) throws ExoPlaybackException
PlayerMessage.Target
handleMessage
in interface PlayerMessage.Target
handleMessage
in class BaseRenderer
messageType
- The message type.message
- The message payload.ExoPlaybackException
- If an error occurred whilst handling the message. Should only be
thrown by targets that handle messages on the playback thread.protected void onEnabled(boolean joining, boolean mayRenderStartOfStream) throws ExoPlaybackException
BaseRenderer
The default implementation is a no-op.
onEnabled
in class BaseRenderer
joining
- Whether this renderer is being enabled to join an ongoing playback.mayRenderStartOfStream
- Whether this renderer is allowed to render the start of the
stream even if the state is not Renderer.STATE_STARTED
yet.ExoPlaybackException
- If an error occurs.protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException
BaseRenderer
BaseRenderer.onStreamChanged(Format[], long, long)
has been called, and also when a position discontinuity
is encountered.
After a position reset, the renderer's SampleStream
is guaranteed to provide samples
starting from a key frame.
The default implementation is a no-op.
onPositionReset
in class BaseRenderer
positionUs
- The new playback position in microseconds.joining
- Whether this renderer is being enabled to join an ongoing playback.ExoPlaybackException
- If an error occurs.protected void onStarted()
BaseRenderer
The default implementation is a no-op.
onStarted
in class BaseRenderer
protected void onStopped()
BaseRenderer
The default implementation is a no-op.
onStopped
in class BaseRenderer
protected void onDisabled()
BaseRenderer
The default implementation is a no-op.
onDisabled
in class BaseRenderer
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) throws ExoPlaybackException
BaseRenderer
BaseRenderer.onEnabled(boolean, boolean)
has been called, and also when the stream has been
replaced whilst the renderer is enabled or started.
The default implementation is a no-op.
onStreamChanged
in class BaseRenderer
formats
- The enabled formats.startPositionUs
- The start position of the new stream in renderer time (microseconds).offsetUs
- The offset that will be added to the timestamps of buffers read via BaseRenderer.readSource(FormatHolder, DecoderInputBuffer, boolean)
so that decoder input buffers have
monotonically increasing timestamps.ExoPlaybackException
- If an error occurs.@CallSuper protected void onDecoderInitialized(String name, long initializedTimestampMs, long initializationDurationMs)
The default implementation is a no-op.
name
- The name of the decoder that was initialized.initializedTimestampMs
- SystemClock.elapsedRealtime()
when initialization
finished.initializationDurationMs
- The time taken to initialize the decoder, in milliseconds.@CallSuper protected void flushDecoder() throws ExoPlaybackException
ExoPlaybackException
- If an error occurs reinitializing a decoder.@CallSuper protected void releaseDecoder()
@CallSuper protected void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException
formatHolder
- A FormatHolder
that holds the new Format
.ExoPlaybackException
- If an error occurs (re-)initializing the decoder.protected void onQueueInputBuffer(VideoDecoderInputBuffer buffer)
The default implementation is a no-op.
buffer
- The buffer that will be queued.@CallSuper protected void onProcessedOutputBuffer(long presentationTimeUs)
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(VideoDecoderOutputBuffer outputBuffer)
outputBuffer
- The output buffer to skip.protected void dropOutputBuffer(VideoDecoderOutputBuffer outputBuffer)
outputBuffer
- The output buffer to drop.protected boolean maybeDropBuffersToKeyframe(long positionUs) throws ExoPlaybackException
false
. Returns true
otherwise.positionUs
- The current playback position, in microseconds.ExoPlaybackException
- If an error occurs flushing the decoder.protected void updateDroppedBufferCounters(int droppedBufferCount)
droppedBufferCount
additional buffers were
dropped.droppedBufferCount
- The number of additional dropped buffers.protected abstract Decoder<VideoDecoderInputBuffer,? extends VideoDecoderOutputBuffer,? extends DecoderException> createDecoder(Format format, @Nullable ExoMediaCrypto mediaCrypto) throws DecoderException
format
- The format for which a decoder is required.mediaCrypto
- The ExoMediaCrypto
object required for decoding encrypted content.
May be null and can be ignored if decoder does not handle encrypted content.DecoderException
- If an error occurred creating a suitable decoder.protected void renderOutputBuffer(VideoDecoderOutputBuffer outputBuffer, long presentationTimeUs, Format outputFormat) throws DecoderException
The implementation of this method takes ownership of the output buffer and is responsible
for calling VideoDecoderOutputBuffer.release()
either immediately or in the future.
outputBuffer
- VideoDecoderOutputBuffer
to render.presentationTimeUs
- Presentation time in microseconds.outputFormat
- Output Format
.DecoderException
- If an error occurs when rendering the output buffer.protected abstract void renderOutputBufferToSurface(VideoDecoderOutputBuffer outputBuffer, Surface surface) throws DecoderException
The implementation of this method takes ownership of the output buffer and is responsible
for calling VideoDecoderOutputBuffer.release()
either immediately or in the future.
outputBuffer
- VideoDecoderOutputBuffer
to render.surface
- Output Surface
.DecoderException
- If an error occurs when rendering the output buffer.protected final void setOutputSurface(@Nullable Surface surface)
surface
- Surface.protected final void setOutputBufferRenderer(@Nullable VideoDecoderOutputBufferRenderer outputBufferRenderer)
outputBufferRenderer
- Output buffer renderer.protected abstract void setDecoderOutputMode(@VideoOutputMode int outputMode)
outputMode
- Output mode.