Class MediaCodecRenderer

    • Field Detail

      • CODEC_OPERATING_RATE_UNSET

        protected static final float CODEC_OPERATING_RATE_UNSET
        Indicates no codec operating rate should be set.
        See Also:
        Constant Field Values
    • Constructor Detail

      • MediaCodecRenderer

        public MediaCodecRenderer​(int trackType,
                                  MediaCodecAdapter.Factory codecAdapterFactory,
                                  MediaCodecSelector mediaCodecSelector,
                                  boolean enableDecoderFallback,
                                  float assumedMinimumCodecOperatingRate)
        Parameters:
        trackType - The track type that the renderer handles. One of the C.TRACK_TYPE_* constants defined in C.
        mediaCodecSelector - A decoder selector.
        enableDecoderFallback - Whether to enable fallback to lower-priority decoders if decoder initialization fails. This may result in using a decoder that is less efficient or slower than the primary decoder.
        assumedMinimumCodecOperatingRate - A codec operating rate that all codecs instantiated by this renderer are assumed to meet implicitly (i.e. without the operating rate being set explicitly using MediaFormat.KEY_OPERATING_RATE).
    • Method Detail

      • setRenderTimeLimitMs

        public void setRenderTimeLimitMs​(long renderTimeLimitMs)
        Set a limit on the time a single render(long, long) call can spend draining and filling the decoder.

        This method should be called right after creating an instance of this class.

        Parameters:
        renderTimeLimitMs - The render time limit in milliseconds, or C.TIME_UNSET for no limit.
      • experimentalSetAsynchronousBufferQueueingEnabled

        public void experimentalSetAsynchronousBufferQueueingEnabled​(boolean enabled)
        Enables asynchronous input buffer queueing.

        Operates the underlying MediaCodec in asynchronous mode and submits input buffers from a separate thread to unblock the playback thread.

        This method is experimental, and will be renamed or removed in a future release. It should only be called before the renderer is used.

      • experimentalSetForceAsyncQueueingSynchronizationWorkaround

        public void experimentalSetForceAsyncQueueingSynchronizationWorkaround​(boolean enabled)
        Enables the asynchronous queueing synchronization workaround.

        When enabled, the queueing threads for MediaCodec instance will synchronize on a shared lock when submitting buffers to the respective MediaCodec.

        This method is experimental, and will be renamed or removed in a future release. It should only be called before the renderer is used.

      • experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled

        public void experimentalSetSynchronizeCodecInteractionsWithQueueingEnabled​(boolean enabled)
        Enables synchronizing codec interactions with asynchronous buffer queueing.

        When enabled, codec interactions will wait until all input buffers pending for asynchronous queueing are submitted to the MediaCodec first. This method is effective only if asynchronous buffer queueing is enabled.

        This method is experimental, and will be renamed or removed in a future release. It should only be called before the renderer is used.

      • shouldUseBypass

        protected boolean shouldUseBypass​(Format format)
        Returns whether buffers in the input format can be processed without a codec.

        This method is only called if the content is not DRM protected, because if the content is DRM protected use of bypass is never possible.

        Parameters:
        format - The input Format.
        Returns:
        Whether playback bypassing MediaCodec is supported.
      • shouldInitCodec

        protected boolean shouldInitCodec​(MediaCodecInfo codecInfo)
      • getCodecNeedsEosPropagation

        protected boolean getCodecNeedsEosPropagation()
        Returns whether the codec needs the renderer to propagate the end-of-stream signal directly, rather than by using an end-of-stream buffer queued to the codec.
      • setPendingPlaybackException

        protected final void setPendingPlaybackException​(ExoPlaybackException exception)
        Sets an exception to be re-thrown by render.
        Parameters:
        exception - The exception.
      • getCodecOutputMediaFormat

        @Nullable
        protected final MediaFormat getCodecOutputMediaFormat()
      • getCodecInfo

        @Nullable
        protected final MediaCodecInfo getCodecInfo()
      • onEnabled

        protected void onEnabled​(boolean joining,
                                 boolean mayRenderStartOfStream)
                          throws ExoPlaybackException
        Description copied from class: BaseRenderer
        Called when the renderer is enabled.

        The default implementation is a no-op.

        Overrides:
        onEnabled in class BaseRenderer
        Parameters:
        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.
        Throws:
        ExoPlaybackException - If an error occurs.
      • onPositionReset

        protected void onPositionReset​(long positionUs,
                                       boolean joining)
                                throws ExoPlaybackException
        Description copied from class: BaseRenderer
        Called when the position is reset. This occurs when the renderer is enabled after 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.

        Overrides:
        onPositionReset in class BaseRenderer
        Parameters:
        positionUs - The new playback position in microseconds.
        joining - Whether this renderer is being enabled to join an ongoing playback.
        Throws:
        ExoPlaybackException - If an error occurs.
      • setPlaybackSpeed

        public void setPlaybackSpeed​(float currentPlaybackSpeed,
                                     float targetPlaybackSpeed)
                              throws ExoPlaybackException
        Description copied from interface: Renderer
        Indicates the playback speed to this renderer.

        The default implementation is a no-op.

        Parameters:
        currentPlaybackSpeed - The factor by which playback is currently sped up.
        targetPlaybackSpeed - The target factor by which playback should be sped up. This may be different from currentPlaybackSpeed, for example, if the speed is temporarily adjusted for live playback.
        Throws:
        ExoPlaybackException - If an error occurs handling the playback speed.
      • onDisabled

        protected void onDisabled()
        Description copied from class: BaseRenderer
        Called when the renderer is disabled.

        The default implementation is a no-op.

        Overrides:
        onDisabled in class BaseRenderer
      • onReset

        protected void onReset()
        Description copied from class: BaseRenderer
        Called when the renderer is reset.

        The default implementation is a no-op.

        Overrides:
        onReset in class BaseRenderer
      • releaseCodec

        protected void releaseCodec()
      • onStarted

        protected void onStarted()
        Description copied from class: BaseRenderer
        Called when the renderer is started.

        The default implementation is a no-op.

        Overrides:
        onStarted in class BaseRenderer
      • onStopped

        protected void onStopped()
        Description copied from class: BaseRenderer
        Called when the renderer is stopped.

        The default implementation is a no-op.

        Overrides:
        onStopped in class BaseRenderer
      • flushOrReinitializeCodec

        protected final boolean flushOrReinitializeCodec()
                                                  throws ExoPlaybackException
        Flushes the codec. If flushing is not possible, the codec will be released and re-instantiated. This method is a no-op if the codec is null.

        The implementation of this method calls flushOrReleaseCodec(), and maybeInitCodecOrBypass() if the codec needs to be re-instantiated.

        Returns:
        Whether the codec was released and reinitialized, rather than being flushed.
        Throws:
        ExoPlaybackException - If an error occurs re-instantiating the codec.
      • flushOrReleaseCodec

        protected boolean flushOrReleaseCodec()
        Flushes the codec. If flushing is not possible, the codec will be released. This method is a no-op if the codec is null.
        Returns:
        Whether the codec was released.
      • resetCodecStateForFlush

        @CallSuper
        protected void resetCodecStateForFlush()
        Resets the renderer internal state after a codec flush.
      • resetCodecStateForRelease

        @CallSuper
        protected void resetCodecStateForRelease()
        Resets the renderer internal state after a codec release.

        Note that this only needs to reset state variables that are changed in addition to those already changed in resetCodecStateForFlush().

      • onCodecInitialized

        protected void onCodecInitialized​(String name,
                                          long initializedTimestampMs,
                                          long initializationDurationMs)
        Called when a MediaCodec has been created and configured.

        The default implementation is a no-op.

        Parameters:
        name - The name of the codec that was initialized.
        initializedTimestampMs - SystemClock.elapsedRealtime() when initialization finished.
        initializationDurationMs - The time taken to initialize the codec in milliseconds.
      • onCodecReleased

        protected void onCodecReleased​(String name)
        Called when a MediaCodec has been released.

        The default implementation is a no-op.

        Parameters:
        name - The name of the codec that was released.
      • onCodecError

        protected void onCodecError​(Exception codecError)
        Called when a codec error has occurred.

        The default implementation is a no-op.

        Parameters:
        codecError - The error.
      • onOutputFormatChanged

        protected void onOutputFormatChanged​(Format format,
                                             @Nullable
                                             MediaFormat mediaFormat)
                                      throws ExoPlaybackException
        Called when one of the output formats changes.

        The default implementation is a no-op.

        Parameters:
        format - The input Format to which future output now corresponds. If the renderer is in bypass mode, this is also the output format.
        mediaFormat - The codec output MediaFormat, or null if the renderer is in bypass mode.
        Throws:
        ExoPlaybackException - Thrown if an error occurs configuring the output.
      • handleInputBufferSupplementalData

        protected void handleInputBufferSupplementalData​(DecoderInputBuffer buffer)
                                                  throws ExoPlaybackException
        Handles supplemental data associated with an input buffer.

        The default implementation is a no-op.

        Parameters:
        buffer - The input buffer that is about to be queued.
        Throws:
        ExoPlaybackException - Thrown if an error occurs handling supplemental data.
      • onQueueInputBuffer

        protected void onQueueInputBuffer​(DecoderInputBuffer buffer)
                                   throws ExoPlaybackException
        Called immediately before an input buffer is queued into the codec.

        The default implementation is a no-op.

        Parameters:
        buffer - The buffer to be queued.
        Throws:
        ExoPlaybackException - Thrown if an error occurs handling the input buffer.
      • onProcessedOutputBuffer

        @CallSuper
        protected void onProcessedOutputBuffer​(long presentationTimeUs)
        Called when an output buffer is successfully processed.
        Parameters:
        presentationTimeUs - The timestamp associated with the output buffer.
      • onProcessedStreamChange

        protected void onProcessedStreamChange()
        Called after the last output buffer before a stream change has been processed.
      • canReuseCodec

        protected DecoderReuseEvaluation canReuseCodec​(MediaCodecInfo codecInfo,
                                                       Format oldFormat,
                                                       Format newFormat)
        Evaluates whether the existing MediaCodec can be kept for a new Format, and if it can whether it requires reconfiguration.

        The default implementation does not allow decoder reuse.

        Parameters:
        codecInfo - A MediaCodecInfo describing the decoder.
        oldFormat - The Format for which the existing instance is configured.
        newFormat - The new Format.
        Returns:
        The result of the evaluation.
      • isEnded

        public boolean isEnded()
        Description copied from interface: Renderer
        Whether the renderer is ready for the 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.

        Returns:
        Whether the renderer is ready for the player to transition to the ended state.
      • isReady

        public boolean isReady()
        Description copied from interface: Renderer
        Whether the renderer is able to immediately render media from the current position.

        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.

        Returns:
        Whether the renderer is ready to render media.
      • getCodecOperatingRate

        protected float getCodecOperatingRate()
        Returns the operating rate used by the current codec
      • getCodecOperatingRateV23

        protected float getCodecOperatingRateV23​(float targetPlaybackSpeed,
                                                 Format format,
                                                 Format[] streamFormats)
        Returns the MediaFormat.KEY_OPERATING_RATE value for a given playback speed, current Format and set of possible stream formats.

        The default implementation returns CODEC_OPERATING_RATE_UNSET.

        Parameters:
        targetPlaybackSpeed - The target factor by which playback should be sped up. This may be different from the current playback speed, for example, if the speed is temporarily adjusted for live playback.
        format - The Format for which the codec is being configured.
        streamFormats - The possible stream formats.
        Returns:
        The codec operating rate, or CODEC_OPERATING_RATE_UNSET if no codec operating rate should be set.
      • updateCodecOperatingRate

        protected final boolean updateCodecOperatingRate()
                                                  throws ExoPlaybackException
        Updates the codec operating rate, or triggers codec release and re-initialization if a previously set operating rate needs to be cleared.
        Returns:
        False if codec release and re-initialization was triggered. True in all other cases.
        Throws:
        ExoPlaybackException - If an error occurs releasing or initializing a codec.
      • processOutputBuffer

        protected abstract boolean processOutputBuffer​(long positionUs,
                                                       long elapsedRealtimeUs,
                                                       @Nullable
                                                       MediaCodecAdapter codec,
                                                       @Nullable
                                                       ByteBuffer buffer,
                                                       int bufferIndex,
                                                       int bufferFlags,
                                                       int sampleCount,
                                                       long bufferPresentationTimeUs,
                                                       boolean isDecodeOnlyBuffer,
                                                       boolean isLastBuffer,
                                                       Format format)
                                                throws ExoPlaybackException
        Processes an output media buffer.

        When a new ByteBuffer is passed to this method its position and limit delineate the data to be processed. The return value indicates whether the buffer was processed in full. If true is returned then the next call to this method will receive a new buffer to be processed. If false is returned then the same buffer will be passed to the next call. An implementation of this method is free to modify the buffer and can assume that the buffer will not be externally modified between successive calls. Hence an implementation can, for example, modify the buffer's position to keep track of how much of the data it has processed.

        Note that the first call to this method following a call to onPositionReset(long, boolean) will always receive a new ByteBuffer to be processed.

        Parameters:
        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.
        codec - The MediaCodecAdapter instance, or null in bypass mode were no codec is used.
        buffer - The output buffer to process, or null if the buffer data is not made available to the application layer (see MediaCodec.getOutputBuffer(int)). This buffer can only be null for video data. Note that the buffer data can still be rendered in this case by using the bufferIndex.
        bufferIndex - The index of the output buffer.
        bufferFlags - The flags attached to the output buffer.
        sampleCount - The number of samples extracted from the sample queue in the buffer. This allows handling multiple samples as a batch for efficiency.
        bufferPresentationTimeUs - The presentation time of the output buffer in microseconds.
        isDecodeOnlyBuffer - Whether the buffer was marked with C.BUFFER_FLAG_DECODE_ONLY by the source.
        isLastBuffer - Whether the buffer is known to contain the last sample of the current stream. This flag is set on a best effort basis, and any logic relying on it should degrade gracefully to handle cases where it's not set.
        format - The Format associated with the buffer.
        Returns:
        Whether the output buffer was fully processed (for example, rendered or skipped).
        Throws:
        ExoPlaybackException - If an error occurs processing the output buffer.
      • renderToEndOfStream

        protected void renderToEndOfStream()
                                    throws ExoPlaybackException
        Incrementally renders any remaining output.

        The default implementation is a no-op.

        Throws:
        ExoPlaybackException - Thrown if an error occurs rendering remaining output.
      • setPendingOutputEndOfStream

        protected final void setPendingOutputEndOfStream()
        Notifies the renderer that output end of stream is pending and should be handled on the next render.
      • supportsFormatDrm

        protected static boolean supportsFormatDrm​(Format format)
        Returns whether this renderer supports the given Format's DRM scheme.