Class MediaCodecVideoRenderer

    • Constructor Detail

      • MediaCodecVideoRenderer

        public MediaCodecVideoRenderer​(Context context,
                                       MediaCodecSelector mediaCodecSelector)
        Parameters:
        context - A context.
        mediaCodecSelector - A decoder selector.
      • MediaCodecVideoRenderer

        public MediaCodecVideoRenderer​(Context context,
                                       MediaCodecSelector mediaCodecSelector,
                                       long allowedJoiningTimeMs)
        Parameters:
        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.
      • MediaCodecVideoRenderer

        public MediaCodecVideoRenderer​(Context context,
                                       MediaCodecSelector mediaCodecSelector,
                                       long allowedJoiningTimeMs,
                                       @Nullable
                                       Handler eventHandler,
                                       @Nullable
                                       VideoRendererEventListener eventListener,
                                       int maxDroppedFramesToNotify)
        Parameters:
        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.
        maxDroppedFramesToNotify - The maximum number of frames that can be dropped between invocations of VideoRendererEventListener.onDroppedFrames(int, long).
      • MediaCodecVideoRenderer

        public MediaCodecVideoRenderer​(Context context,
                                       MediaCodecSelector mediaCodecSelector,
                                       long allowedJoiningTimeMs,
                                       boolean enableDecoderFallback,
                                       @Nullable
                                       Handler eventHandler,
                                       @Nullable
                                       VideoRendererEventListener eventListener,
                                       int maxDroppedFramesToNotify)
        Parameters:
        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.
        enableDecoderFallback - Whether to enable fallback to lower-priority decoders if decoder initialization fails. This may result in using a decoder that is slower/less efficient than the primary decoder.
        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).
      • MediaCodecVideoRenderer

        public MediaCodecVideoRenderer​(Context context,
                                       MediaCodecAdapter.Factory codecAdapterFactory,
                                       MediaCodecSelector mediaCodecSelector,
                                       long allowedJoiningTimeMs,
                                       boolean enableDecoderFallback,
                                       @Nullable
                                       Handler eventHandler,
                                       @Nullable
                                       VideoRendererEventListener eventListener,
                                       int maxDroppedFramesToNotify)
        Creates a new instance.
        Parameters:
        context - A context.
        codecAdapterFactory - The MediaCodecAdapter.Factory used to create MediaCodecAdapter instances.
        mediaCodecSelector - A decoder selector.
        allowedJoiningTimeMs - The maximum duration in milliseconds for which this video renderer can attempt to seamlessly join an ongoing playback.
        enableDecoderFallback - Whether to enable fallback to lower-priority decoders if decoder initialization fails. This may result in using a decoder that is slower/less efficient than the primary decoder.
        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).
    • Method Detail

      • getName

        public String getName()
        Description copied from interface: Renderer
        Returns the name of this renderer, for logging and debugging purposes. Should typically be the renderer's (un-obfuscated) class name.
        Returns:
        The name of this renderer.
      • 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 MediaCodecRenderer
        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 MediaCodecRenderer
        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.
      • 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.

        Specified by:
        isReady in interface Renderer
        Overrides:
        isReady in class MediaCodecRenderer
        Returns:
        Whether the renderer is ready to render media.
      • 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 MediaCodecRenderer
      • 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 MediaCodecRenderer
      • 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 MediaCodecRenderer
      • 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 MediaCodecRenderer
      • getCodecNeedsEosPropagation

        protected boolean getCodecNeedsEosPropagation()
        Description copied from class: MediaCodecRenderer
        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.
        Overrides:
        getCodecNeedsEosPropagation in class MediaCodecRenderer
      • 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.

        Specified by:
        setPlaybackSpeed in interface Renderer
        Overrides:
        setPlaybackSpeed in class MediaCodecRenderer
        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.
      • onCodecInitialized

        protected void onCodecInitialized​(String name,
                                          long initializedTimestampMs,
                                          long initializationDurationMs)
        Description copied from class: MediaCodecRenderer
        Called when a MediaCodec has been created and configured.

        The default implementation is a no-op.

        Overrides:
        onCodecInitialized in class MediaCodecRenderer
        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.
      • onCodecError

        protected void onCodecError​(Exception codecError)
        Description copied from class: MediaCodecRenderer
        Called when a codec error has occurred.

        The default implementation is a no-op.

        Overrides:
        onCodecError in class MediaCodecRenderer
        Parameters:
        codecError - The error.
      • onQueueInputBuffer

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

        In tunneling mode for pre Marshmallow, the buffer is treated as if immediately output.

        Overrides:
        onQueueInputBuffer in class MediaCodecRenderer
        Parameters:
        buffer - The buffer to be queued.
        Throws:
        ExoPlaybackException - Thrown if an error occurs handling the input buffer.
      • onOutputFormatChanged

        protected void onOutputFormatChanged​(Format format,
                                             @Nullable
                                             MediaFormat mediaFormat)
        Description copied from class: MediaCodecRenderer
        Called when one of the output formats changes.

        The default implementation is a no-op.

        Overrides:
        onOutputFormatChanged in class MediaCodecRenderer
        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.
      • processOutputBuffer

        protected 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
        Description copied from class: MediaCodecRenderer
        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 MediaCodecRenderer.onPositionReset(long, boolean) will always receive a new ByteBuffer to be processed.

        Specified by:
        processOutputBuffer in class MediaCodecRenderer
        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.
      • onProcessedTunneledBuffer

        protected void onProcessedTunneledBuffer​(long presentationTimeUs)
                                          throws ExoPlaybackException
        Called when a buffer was processed in tunneling mode.
        Throws:
        ExoPlaybackException
      • onProcessedOutputBuffer

        @CallSuper
        protected void onProcessedOutputBuffer​(long presentationTimeUs)
        Description copied from class: MediaCodecRenderer
        Called when an output buffer is successfully processed.
        Overrides:
        onProcessedOutputBuffer in class MediaCodecRenderer
        Parameters:
        presentationTimeUs - The timestamp associated with the output buffer.
      • shouldDropOutputBuffer

        protected boolean shouldDropOutputBuffer​(long earlyUs,
                                                 long elapsedRealtimeUs,
                                                 boolean isLastBuffer)
        Returns whether the buffer being processed should be dropped.
        Parameters:
        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.
        isLastBuffer - Whether the buffer is the last buffer in the current stream.
      • shouldDropBuffersToKeyframe

        protected boolean shouldDropBuffersToKeyframe​(long earlyUs,
                                                      long elapsedRealtimeUs,
                                                      boolean isLastBuffer)
        Returns whether to drop all buffers from the buffer being processed to the keyframe at or after the current playback position, if possible.
        Parameters:
        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.
        isLastBuffer - Whether the buffer is the last buffer in the current stream.
      • shouldForceRenderOutputBuffer

        protected boolean shouldForceRenderOutputBuffer​(long earlyUs,
                                                        long elapsedSinceLastRenderUs)
        Returns whether to force rendering an output buffer.
        Parameters:
        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.
        Returns:
        Returns whether to force rendering an output buffer.
      • skipOutputBuffer

        protected void skipOutputBuffer​(MediaCodecAdapter codec,
                                        int index,
                                        long presentationTimeUs)
        Skips the output buffer with the specified index.
        Parameters:
        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.
      • dropOutputBuffer

        protected void dropOutputBuffer​(MediaCodecAdapter codec,
                                        int index,
                                        long presentationTimeUs)
        Drops the output buffer with the specified index.
        Parameters:
        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.
      • maybeDropBuffersToKeyframe

        protected boolean maybeDropBuffersToKeyframe​(long positionUs,
                                                     boolean treatDroppedBuffersAsSkipped)
                                              throws ExoPlaybackException
        Drops frames from the current output buffer to the next keyframe at or before the playback position. If no such keyframe exists, as the playback position is inside the same group of pictures as the buffer being processed, returns false. Returns true otherwise.
        Parameters:
        positionUs - The current playback position, in microseconds.
        treatDroppedBuffersAsSkipped - Whether dropped buffers should be treated as intentionally skipped.
        Returns:
        Whether any buffers were dropped.
        Throws:
        ExoPlaybackException - If an error occurs flushing the codec.
      • updateDroppedBufferCounters

        protected void updateDroppedBufferCounters​(int droppedBufferCount)
        Updates local counters and DecoderCounters to reflect that droppedBufferCount additional buffers were dropped.
        Parameters:
        droppedBufferCount - The number of additional dropped buffers.
      • updateVideoFrameProcessingOffsetCounters

        protected void updateVideoFrameProcessingOffsetCounters​(long processingOffsetUs)
        Updates local counters and DecoderCounters with a new video frame processing offset.
        Parameters:
        processingOffsetUs - The video frame processing offset.
      • renderOutputBuffer

        protected void renderOutputBuffer​(MediaCodecAdapter codec,
                                          int index,
                                          long presentationTimeUs)
        Renders the output buffer with the specified index. This method is only called if the platform API version of the device is less than 21.
        Parameters:
        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.
      • renderOutputBufferV21

        @RequiresApi(21)
        protected void renderOutputBufferV21​(MediaCodecAdapter codec,
                                             int index,
                                             long presentationTimeUs,
                                             long releaseTimeNs)
        Renders the output buffer with the specified index. This method is only called if the platform API version of the device is 21 or later.
        Parameters:
        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.
      • setOutputSurfaceV23

        @RequiresApi(23)
        protected void setOutputSurfaceV23​(MediaCodecAdapter codec,
                                           Surface surface)
      • getMediaFormat

        protected MediaFormat getMediaFormat​(Format format,
                                             String codecMimeType,
                                             MediaCodecVideoRenderer.CodecMaxValues codecMaxValues,
                                             float codecOperatingRate,
                                             boolean deviceNeedsNoPostProcessWorkaround,
                                             int tunnelingAudioSessionId)
        Returns the framework MediaFormat that should be used to configure the decoder.
        Parameters:
        format - The Format of media.
        codecMimeType - The MIME type handled by the codec.
        codecMaxValues - Codec max values that should be used when configuring the decoder.
        codecOperatingRate - The codec operating rate, or MediaCodecRenderer.CODEC_OPERATING_RATE_UNSET if no codec operating rate should be set.
        deviceNeedsNoPostProcessWorkaround - Whether the device is known to do post processing by default that isn't compatible with ExoPlayer.
        tunnelingAudioSessionId - The audio session id to use for tunneling, or C.AUDIO_SESSION_ID_UNSET if tunneling should not be enabled.
        Returns:
        The framework MediaFormat that should be used to configure the decoder.
      • getMaxInputSize

        protected static int getMaxInputSize​(MediaCodecInfo codecInfo,
                                             Format format)
        Returns a maximum input buffer size for a given MediaCodec and Format.
        Parameters:
        codecInfo - Information about the MediaCodec being configured.
        format - The format.
        Returns:
        A maximum input buffer size in bytes, or Format.NO_VALUE if a maximum could not be determined.
      • codecNeedsSetOutputSurfaceWorkaround

        protected boolean codecNeedsSetOutputSurfaceWorkaround​(String name)
        Returns whether the codec is known to implement MediaCodec.setOutputSurface(Surface) incorrectly.

        If true is returned then we fall back to releasing and re-instantiating the codec instead.

        Parameters:
        name - The name of the codec.
        Returns:
        True if the device is known to implement MediaCodec.setOutputSurface(Surface) incorrectly.
      • getSurface

        protected Surface getSurface()