From 841c5477d182a83b5b58529fbeef725f56db1747 Mon Sep 17 00:00:00 2001 From: tianyifeng Date: Thu, 16 Mar 2023 15:56:59 +0000 Subject: [PATCH] Add `release` method to Renderer and AudioSink * Add `release` method to Renderer and AudioSink interfaces. * Call the `release` method for renderers when the ExoPlayer is going to be released. PiperOrigin-RevId: 517135677 --- RELEASENOTES.md | 2 ++ .../androidx/media3/exoplayer/BaseRenderer.java | 15 +++++++++++++++ .../media3/exoplayer/ExoPlayerImplInternal.java | 7 +++++++ .../java/androidx/media3/exoplayer/Renderer.java | 7 +++++++ .../media3/exoplayer/audio/AudioSink.java | 3 +++ .../exoplayer/audio/MediaCodecAudioRenderer.java | 5 +++++ 6 files changed, 39 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b7eaac93d9..7b749abf29 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -17,6 +17,8 @@ ([#10847](https://github.com/google/ExoPlayer/issues/10847)). * Encapsulate Opus frames in Ogg packets in direct playbacks (offload). * Extrapolate current position during sleep with offload scheduling. + * Add `Renderer.release()` and `AudioSink.release()` for releasing the + resources at the end of player's lifecycle. * DRM: * Reduce the visibility of several internal-only methods on `DefaultDrmSession` that aren't expected to be called from outside the 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 db410d3a8d..50effc32de 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/BaseRenderer.java @@ -197,6 +197,12 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { onReset(); } + @Override + public final void release() { + Assertions.checkState(state == STATE_DISABLED); + onRelease(); + } + // RendererCapabilities implementation. @Override @@ -303,6 +309,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { // Do nothing. } + /** + * Called when the renderer is released. + * + *

The default implementation is a no-op. + */ + protected void onRelease() { + // Do nothing. + } + // Methods to be called by subclasses. /** diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java index aa950ecda3..62dffd768a 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayerImplInternal.java @@ -1410,6 +1410,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /* resetPosition= */ false, /* releaseMediaSourceList= */ true, /* resetError= */ false); + releaseRenderers(); loadControl.onReleased(); setState(Player.STATE_IDLE); if (internalPlaybackThread != null) { @@ -2546,6 +2547,12 @@ import java.util.concurrent.atomic.AtomicBoolean; } } + private void releaseRenderers() { + for (Renderer renderer : renderers) { + renderer.release(); + } + } + private void handleLoadingMediaPeriodChanged(boolean loadingTrackSelectionChanged) { MediaPeriodHolder loadingMediaPeriodHolder = queue.getLoadingPeriod(); MediaPeriodId loadingMediaPeriodId = 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 6d39bb1d64..6fe54fccdb 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java @@ -520,4 +520,11 @@ public interface Renderer extends PlayerMessage.Target { * #STATE_DISABLED}. */ void reset(); + + /** + * Releases the renderer. + * + *

The renderer must not be used after calling this method. + */ + default void release() {} } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioSink.java index 20f95192db..f73f9635cc 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioSink.java @@ -485,4 +485,7 @@ public interface AudioSink { /** Resets the sink, releasing any resources that it currently holds. */ void reset(); + + /** Releases the audio sink. */ + default void release() {} } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java index 2f63b80cf8..eb74f06c42 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java @@ -627,6 +627,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media } } + @Override + protected void onRelease() { + audioSink.release(); + } + @Override public boolean isEnded() { return super.isEnded() && audioSink.isEnded();