From e8778d77faf1ec03272655be8568d71a7fb16543 Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 10 Jul 2024 07:21:37 -0700 Subject: [PATCH] Document Renderer and BaseRenderer in more detail PiperOrigin-RevId: 651008509 --- .../media3/exoplayer/BaseRenderer.java | 26 +++++- .../androidx/media3/exoplayer/Renderer.java | 84 +++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java index 5404a20545..5fc84bd1aa 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java @@ -39,7 +39,31 @@ import androidx.media3.exoplayer.source.SampleStream.ReadFlags; import java.io.IOException; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -/** An abstract base class suitable for most {@link Renderer} implementations. */ +/** + * An abstract base class suitable for most {@link Renderer} implementations. + * + *

It converts many of the state transitions explained in {@link Renderer} docs to protected + * callbacks and provides utilities to access current state values without tracking them manually: + * + *

+ */ @UnstableApi public abstract class BaseRenderer implements Renderer, RendererCapabilities { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java index 368d81c929..388fe1ad98 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java @@ -58,6 +58,90 @@ import java.util.List; *

Renderer state transitions + * + *

Format support

+ * + * The player will select a renderer based on the {@link RendererCapabilities} returned from {@link + * #getCapabilities()}. If the capabilities indicate support for a {@link Format}, the renderer is + * expected to handle {@link SampleStream} instances containing samples of this {@link Format}. + * + *

Resource management

+ * + *

Renderers should acquire resources like codecs when entering {@link #STATE_ENABLED} for the + * first time. As the renderer may transition quickly to and from {@link #STATE_DISABLED}, it is + * recommended to hold onto resources even when entering {@link #STATE_DISABLED}. The player will + * explicitly call {@link #reset()} if the renderer is no longer needed, at which point any acquired + * limited resources should be released. + * + *

Configuration changes

+ * + *

As renderers are created once in the lifetime of a player, they may need to be re-configured + * later based on user settings or other environmental changes. This is generally done by handling + * {@linkplain PlayerMessage player messages} in {@link #handleMessage}. There are many predefined + * common reconfigurations in {@link MessageType}, but custom renderers can add their own handling + * as needed. + * + *

Reading and rendering samples

+ * + *

The renderer receives a {@link SampleStream} to read from when {@linkplain #enable enabled}. + * When seamlessly transitioning from one item to another, the renderer may get new {@link + * SampleStream} instances via {@link #replaceStream}. Note that {@link #replaceStream} may be + * called as soon as the {@linkplain C#BUFFER_FLAG_END_OF_STREAM end-of-stream signal} has been read + * from the current {@link SampleStream} to allow reading new samples as early as possible. At this + * point, the renderer may still be processing samples from the previous stream(s). Once the current + * stream has been {@linkplain #setCurrentStreamFinal() marked as final}, no further calls to {@link + * #replaceStream} are allowed to happen without first {@link #disable disabling} the renderer + * again. + * + *

The player will regularly call {@link #render} to let the renderer make progress. Once the + * renderer has prepared its internal pipeline to handle continuous playback progress, it should + * report itself as {@link #isReady()}. The player will only transition the renderer to {@link + * #STATE_STARTED} if it reports itself as ready. If the renderer is blocked from making progress, + * it should return {@code false} from {@link #isReady()}, which will result in a {@link #stop()} + * operation back to {@link #STATE_ENABLED}. + * + *

As long as it is in {@link #STATE_STARTED}, the renderer is expected to actively output the + * data it is processing in line with the current playback position passed to {@link #render}. The + * only exception is the very first sample (for example the first video frame), that is allowed to + * be output in {@link #STATE_ENABLED} if the {@code mayRenderStartOfStream} flag was set in {@link + * #enable} or later set via {@link #enableMayRenderStartOfStream()}. + * + *

Once the renderer finished all processing it needs to do (that is, no further call to {@link + * #render} is needed) and the current stream is {@linkplain #isCurrentStreamFinal() final}, it + * should report itself as {@link #isEnded()}. + * + *

Timestamps and offsets

+ * + *

The renderer deals with potentially multiple consecutive input streams and has to handle + * position updates and stream transitions. This means there are multiple types of timestamps and + * offsets relevant in the context of this class: + * + *

*/ @UnstableApi public interface Renderer extends PlayerMessage.Target {