From 6109a0eb624dfc8d4153e85f67556b6b3c38b9cc Mon Sep 17 00:00:00 2001 From: tianyifeng Date: Thu, 16 Mar 2023 16:33:43 +0000 Subject: [PATCH] Intercept audio capabilities change in `DefaultAudioSink` PiperOrigin-RevId: 517144710 --- RELEASENOTES.md | 5 ++ .../exoplayer/DefaultRenderersFactory.java | 4 +- .../exoplayer/audio/DefaultAudioSink.java | 52 ++++++++++++++++--- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 7b749abf29..1f8301cce8 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -19,6 +19,11 @@ * 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. + * Listen to audio capabilities changes in `DefaultAudioSink`. Add a + required parameter `context` in the constructor of `DefaultAudioSink`, + with which the `DefaultAudioSink` will register as the listener to the + `AudioCapabilitiesReceiver` and update its `audioCapabilities` property + when informed with a capabilities change. * 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/DefaultRenderersFactory.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultRenderersFactory.java index 02a77a96e4..f3443e1307 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultRenderersFactory.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultRenderersFactory.java @@ -26,7 +26,6 @@ import androidx.annotation.IntDef; import androidx.annotation.Nullable; import androidx.media3.common.util.Log; import androidx.media3.common.util.UnstableApi; -import androidx.media3.exoplayer.audio.AudioCapabilities; import androidx.media3.exoplayer.audio.AudioRendererEventListener; import androidx.media3.exoplayer.audio.AudioSink; import androidx.media3.exoplayer.audio.DefaultAudioSink; @@ -649,8 +648,7 @@ public class DefaultRenderersFactory implements RenderersFactory { boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams, boolean enableOffload) { - return new DefaultAudioSink.Builder() - .setAudioCapabilities(AudioCapabilities.getCapabilities(context)) + return new DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode( diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index ae2a4b27d7..bf5828560d 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -24,6 +24,7 @@ import static java.lang.Math.min; import static java.lang.annotation.ElementType.TYPE_USE; import android.annotation.SuppressLint; +import android.content.Context; import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioManager; @@ -227,6 +228,7 @@ public final class DefaultAudioSink implements AudioSink { /** A builder to create {@link DefaultAudioSink} instances. */ public static final class Builder { + @Nullable private final Context context; private AudioCapabilities audioCapabilities; @Nullable private androidx.media3.common.audio.AudioProcessorChain audioProcessorChain; private boolean enableFloatOutput; @@ -235,19 +237,34 @@ public final class DefaultAudioSink implements AudioSink { AudioTrackBufferSizeProvider audioTrackBufferSizeProvider; @Nullable AudioOffloadListener audioOffloadListener; - /** Creates a new builder. */ + /** + * @deprecated Use {@link #Builder(Context)} instead. + */ + @Deprecated public Builder() { + this(/* context= */ null); + } + + /** + * Creates a new builder. + * + * @param context The {@link Context}. + */ + public Builder(@Nullable Context context) { + this.context = context; audioCapabilities = DEFAULT_AUDIO_CAPABILITIES; offloadMode = OFFLOAD_MODE_DISABLED; audioTrackBufferSizeProvider = AudioTrackBufferSizeProvider.DEFAULT; } /** - * Sets audio capabilities for playback on this device. May be {@code null} if the default - * capabilities (no encoded audio passthrough support) should be assumed. - * - *

Default is {@link AudioCapabilities#DEFAULT_AUDIO_CAPABILITIES}. + * @deprecated The {@linkplain AudioCapabilities audio capabilities} set to the {@linkplain + * Builder builder} will be effective for the {@link DefaultAudioSink} only in the absence + * of {@linkplain Context context}. If the {@code Context} is {@code null} and the {@code + * audioCapabilities} is not set to the {@code Builder}, the default capabilities (no + * encoded audio passthrough support) should be assumed. */ + @Deprecated @CanIgnoreReturnValue public Builder setAudioCapabilities(AudioCapabilities audioCapabilities) { checkNotNull(audioCapabilities); @@ -483,6 +500,7 @@ public final class DefaultAudioSink implements AudioSink { private final PendingExceptionHolder writeExceptionPendingExceptionHolder; private final AudioTrackBufferSizeProvider audioTrackBufferSizeProvider; @Nullable private final AudioOffloadListener audioOffloadListener; + @Nullable private final AudioCapabilitiesReceiver audioCapabilitiesReceiver; @Nullable private PlayerId playerId; @Nullable private Listener listener; @@ -532,7 +550,14 @@ public final class DefaultAudioSink implements AudioSink { @RequiresNonNull("#1.audioProcessorChain") private DefaultAudioSink(Builder builder) { - audioCapabilities = builder.audioCapabilities; + audioCapabilitiesReceiver = + builder.context != null + ? new AudioCapabilitiesReceiver(builder.context, this::onAudioCapabilitiesChanged) + : null; + audioCapabilities = + audioCapabilitiesReceiver != null + ? audioCapabilitiesReceiver.register() + : builder.audioCapabilities; audioProcessorChain = builder.audioProcessorChain; enableFloatOutput = Util.SDK_INT >= 21 && builder.enableFloatOutput; preferAudioTrackPlaybackParams = Util.SDK_INT >= 23 && builder.enableAudioTrackPlaybackParams; @@ -1431,6 +1456,21 @@ public final class DefaultAudioSink implements AudioSink { offloadDisabledUntilNextConfiguration = false; } + @Override + public void release() { + if (audioCapabilitiesReceiver != null) { + audioCapabilitiesReceiver.unregister(); + } + } + + // AudioCapabilitiesReceiver.Listener implementation. + + public void onAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) { + if (!audioCapabilities.equals(this.audioCapabilities)) { + this.audioCapabilities = audioCapabilities; + } + } + // Internal methods. private void resetSinkStateForFlush() {