From 3cf9c08dca1b16a84195aa5d01e134a4ea07bee4 Mon Sep 17 00:00:00 2001 From: michaelkatz Date: Wed, 20 Sep 2023 03:00:26 -0700 Subject: [PATCH] Create `AudioOffloadPreferences` class Move audio offload mode related interfaces and definitions from `TrackSelectionParameters` to a new `AudioOffloadModePreferences` class. PiperOrigin-RevId: 566905017 --- api.txt | 4 - .../common/TrackSelectionParameters.java | 334 +++++++++++++----- .../common/TrackSelectionParametersTest.java | 79 ++++- .../androidx/media3/exoplayer/ExoPlayer.java | 2 +- .../trackselection/DefaultTrackSelector.java | 41 ++- .../media3/exoplayer/ExoPlayerTest.java | 74 ++-- .../e2etest/OggOpusPlaybackTest.java | 13 +- .../DefaultTrackSelectorTest.java | 87 +++-- 8 files changed, 422 insertions(+), 212 deletions(-) diff --git a/api.txt b/api.txt index f454862972..ee652e26f9 100644 --- a/api.txt +++ b/api.txt @@ -1076,13 +1076,10 @@ package androidx.media3.common { method public static androidx.media3.common.TrackSelectionParameters fromBundle(android.os.Bundle); method public static androidx.media3.common.TrackSelectionParameters getDefaults(android.content.Context); method public android.os.Bundle toBundle(); - field public final int audioOffloadModePreference; field public final com.google.common.collect.ImmutableSet disabledTrackTypes; field public final boolean forceHighestSupportedBitrate; field public final boolean forceLowestBitrate; field @androidx.media3.common.C.SelectionFlags public final int ignoredTextSelectionFlags; - field public final boolean isGaplessSupportRequired; - field public final boolean isSpeedChangeSupportRequired; field public final int maxAudioBitrate; field public final int maxAudioChannelCount; field public final int maxVideoBitrate; @@ -1116,7 +1113,6 @@ package androidx.media3.common { method public androidx.media3.common.TrackSelectionParameters.Builder clearOverridesOfType(@androidx.media3.common.C.TrackType int); method public androidx.media3.common.TrackSelectionParameters.Builder clearVideoSizeConstraints(); method public androidx.media3.common.TrackSelectionParameters.Builder clearViewportSizeConstraints(); - method public androidx.media3.common.TrackSelectionParameters.Builder setAudioOffloadPreference(int, boolean, boolean); method public androidx.media3.common.TrackSelectionParameters.Builder setForceHighestSupportedBitrate(boolean); method public androidx.media3.common.TrackSelectionParameters.Builder setForceLowestBitrate(boolean); method public androidx.media3.common.TrackSelectionParameters.Builder setIgnoredTextSelectionFlags(@androidx.media3.common.C.SelectionFlags int); diff --git a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java index 3004654077..776fccd035 100644 --- a/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java +++ b/libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java @@ -19,6 +19,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.BundleableUtil.toBundleArrayList; import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.Context; import android.graphics.Point; @@ -38,7 +39,6 @@ import com.google.common.primitives.Ints; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Documented; import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.HashMap; import java.util.HashSet; @@ -71,41 +71,6 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNull; */ public class TrackSelectionParameters implements Bundleable { - /** - * The preference level for enabling audio offload on the audio sink. One of {@link - * #AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED}, {@link #AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED}, or - * {@link #AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED}. - */ - @UnstableApi - @Documented - @Retention(RetentionPolicy.SOURCE) - @Target(TYPE_USE) - @IntDef({ - AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED, - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED, - }) - public @interface AudioOffloadModePreference {} - - /** - * The track selector will only select tracks that with the renderer capabilities provide an audio - * offload compatible playback scenario. If it is impossible to create an offload-compatible track - * selection, then no tracks will be selected. - */ - @UnstableApi public static final int AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED = 2; - - /** - * The track selector will enable audio offload if the selected tracks and renderer capabilities - * are compatible. - */ - @UnstableApi public static final int AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED = 1; - - /** - * The track selector will disable audio offload on the audio sink. Track selection will not take - * into consideration whether or not a track is offload compatible. - */ - @UnstableApi public static final int AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED = 0; - /** * A builder for {@link TrackSelectionParameters}. See the {@link TrackSelectionParameters} * documentation for explanations of the parameters that can be configured using this builder. @@ -131,9 +96,7 @@ public class TrackSelectionParameters implements Bundleable { private int maxAudioChannelCount; private int maxAudioBitrate; private ImmutableList preferredAudioMimeTypes; - private @AudioOffloadModePreference int audioOffloadModePreference; - private boolean isGaplessSupportRequired; - private boolean isSpeedChangeSupportRequired; + private AudioOffloadPreferences audioOffloadPreferences; // Text private ImmutableList preferredTextLanguages; private @C.RoleFlags int preferredTextRoleFlags; @@ -168,9 +131,7 @@ public class TrackSelectionParameters implements Bundleable { maxAudioChannelCount = Integer.MAX_VALUE; maxAudioBitrate = Integer.MAX_VALUE; preferredAudioMimeTypes = ImmutableList.of(); - audioOffloadModePreference = AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED; - isGaplessSupportRequired = false; - isSpeedChangeSupportRequired = false; + audioOffloadPreferences = AudioOffloadPreferences.DEFAULT; // Text preferredTextLanguages = ImmutableList.of(); preferredTextRoleFlags = 0; @@ -246,6 +207,7 @@ public class TrackSelectionParameters implements Bundleable { preferredAudioMimeTypes = ImmutableList.copyOf( firstNonNull(bundle.getStringArray(FIELD_PREFERRED_AUDIO_MIME_TYPES), new String[0])); + audioOffloadPreferences = getAudioOffloadPreferencesFromBundle(bundle); // Text preferredTextLanguages = normalizeLanguageCodes( @@ -261,17 +223,7 @@ public class TrackSelectionParameters implements Bundleable { bundle.getBoolean( FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE, DEFAULT_WITHOUT_CONTEXT.selectUndeterminedTextLanguage); - audioOffloadModePreference = - bundle.getInt( - FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, - DEFAULT_WITHOUT_CONTEXT.audioOffloadModePreference); - isGaplessSupportRequired = - bundle.getBoolean( - FIELD_IS_GAPLESS_SUPPORT_REQUIRED, DEFAULT_WITHOUT_CONTEXT.isGaplessSupportRequired); - isSpeedChangeSupportRequired = - bundle.getBoolean( - FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, - DEFAULT_WITHOUT_CONTEXT.isSpeedChangeSupportRequired); + // General forceLowestBitrate = bundle.getBoolean(FIELD_FORCE_LOWEST_BITRATE, DEFAULT_WITHOUT_CONTEXT.forceLowestBitrate); @@ -298,11 +250,32 @@ public class TrackSelectionParameters implements Bundleable { } } + private static AudioOffloadPreferences getAudioOffloadPreferencesFromBundle(Bundle bundle) { + Bundle audioOffloadPreferencesBundle = bundle.getBundle(FIELD_AUDIO_OFFLOAD_PREFERENCES); + return (audioOffloadPreferencesBundle != null) + ? AudioOffloadPreferences.fromBundle(audioOffloadPreferencesBundle) + : new AudioOffloadPreferences.Builder() + .setAudioOffloadMode( + bundle.getInt( + FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, + AudioOffloadPreferences.DEFAULT.audioOffloadMode)) + .setIsGaplessSupportRequired( + bundle.getBoolean( + FIELD_IS_GAPLESS_SUPPORT_REQUIRED, + AudioOffloadPreferences.DEFAULT.isGaplessSupportRequired)) + .setIsSpeedChangeSupportRequired( + bundle.getBoolean( + FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, + AudioOffloadPreferences.DEFAULT.isSpeedChangeSupportRequired)) + .build(); + } + /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ @EnsuresNonNull({ "preferredVideoMimeTypes", "preferredAudioLanguages", "preferredAudioMimeTypes", + "audioOffloadPreferences", "preferredTextLanguages", "overrides", "disabledTrackTypes", @@ -328,9 +301,7 @@ public class TrackSelectionParameters implements Bundleable { maxAudioChannelCount = parameters.maxAudioChannelCount; maxAudioBitrate = parameters.maxAudioBitrate; preferredAudioMimeTypes = parameters.preferredAudioMimeTypes; - audioOffloadModePreference = parameters.audioOffloadModePreference; - isGaplessSupportRequired = parameters.isGaplessSupportRequired; - isSpeedChangeSupportRequired = parameters.isSpeedChangeSupportRequired; + audioOffloadPreferences = parameters.audioOffloadPreferences; // Text preferredTextLanguages = parameters.preferredTextLanguages; preferredTextRoleFlags = parameters.preferredTextRoleFlags; @@ -625,21 +596,11 @@ public class TrackSelectionParameters implements Bundleable { * Sets the audio offload mode preferences. This includes whether to enable/disable offload as * well as to set requirements like if the device must support gapless transitions or speed * change during offload. - * - *

If {@code isGaplessSupportRequired}, then audio offload will be enabled only if the device - * supports gapless transitions during offload or the selected audio is not gapless. - * - *

If {@code isSpeedChangeSupportRequired}, then audio offload will be enabled only if the - * device supports changing playback speed during offload. */ + @UnstableApi @CanIgnoreReturnValue - public Builder setAudioOffloadPreference( - @AudioOffloadModePreference int audioOffloadModePreference, - boolean isGaplessSupportRequired, - boolean isSpeedChangeSupportRequired) { - this.audioOffloadModePreference = audioOffloadModePreference; - this.isGaplessSupportRequired = isGaplessSupportRequired; - this.isSpeedChangeSupportRequired = isSpeedChangeSupportRequired; + public Builder setAudioOffloadPreferences(AudioOffloadPreferences audioOffloadPreferences) { + this.audioOffloadPreferences = audioOffloadPreferences; return this; } @@ -871,6 +832,199 @@ public class TrackSelectionParameters implements Bundleable { } } + /** Preferences and constraints for enabling audio offload. */ + @UnstableApi + public static final class AudioOffloadPreferences implements Bundleable { + + /** + * The preference level for enabling audio offload on the audio sink. One of {@link + * #AUDIO_OFFLOAD_MODE_REQUIRED}, {@link #AUDIO_OFFLOAD_MODE_ENABLED}, or {@link + * #AUDIO_OFFLOAD_MODE_DISABLED}. + */ + @Documented + @Retention(SOURCE) + @Target(TYPE_USE) + @IntDef({ + AUDIO_OFFLOAD_MODE_REQUIRED, + AUDIO_OFFLOAD_MODE_ENABLED, + AUDIO_OFFLOAD_MODE_DISABLED, + }) + public @interface AudioOffloadMode {} + + /** + * The track selector will only select tracks that with the renderer capabilities provide an + * audio offload compatible playback scenario. If it is impossible to create an + * offload-compatible track selection, then no tracks will be selected. + */ + public static final int AUDIO_OFFLOAD_MODE_REQUIRED = 2; + + /** + * The track selector will enable audio offload if the selected tracks and renderer capabilities + * are compatible. + */ + public static final int AUDIO_OFFLOAD_MODE_ENABLED = 1; + + /** + * The track selector will disable audio offload on the audio sink. Track selection will not + * take into consideration whether or not a track is offload compatible. + */ + public static final int AUDIO_OFFLOAD_MODE_DISABLED = 0; + + /** + * A builder for {@link AudioOffloadPreferences}. See the {@link AudioOffloadPreferences} + * documentation for explanations of the parameters that can be configured using this builder. + */ + public static final class Builder { + private @AudioOffloadMode int audioOffloadMode; + private boolean isGaplessSupportRequired; + private boolean isSpeedChangeSupportRequired; + + public Builder() { + this.audioOffloadMode = AUDIO_OFFLOAD_MODE_DISABLED; + this.isGaplessSupportRequired = false; + this.isSpeedChangeSupportRequired = false; + } + + /** + * Sets the audio offload mode preferences. For instance if the preferred mode is + * enabled/disabled or if offload is required for playback. Default value is {@link + * #AUDIO_OFFLOAD_MODE_DISABLED}. + * + * @param audioOffloadMode for enabling/disabling offload. One of {@link + * #AUDIO_OFFLOAD_MODE_REQUIRED}, {@link #AUDIO_OFFLOAD_MODE_ENABLED}, or {@link + * #AUDIO_OFFLOAD_MODE_DISABLED}. + * @return This builder. + */ + @CanIgnoreReturnValue + public Builder setAudioOffloadMode(@AudioOffloadMode int audioOffloadMode) { + this.audioOffloadMode = audioOffloadMode; + return this; + } + + /** + * Sets a constraint on audio offload enablement. If {@code true} then audio offload will be + * enabled only if the device supports gapless transitions during offload or the selected + * audio is not gapless. Default value is {@code false}. + * + * @param isGaplessSupportRequired for playing gapless audio offloaded. + * @return This builder. + */ + @CanIgnoreReturnValue + public Builder setIsGaplessSupportRequired(boolean isGaplessSupportRequired) { + this.isGaplessSupportRequired = isGaplessSupportRequired; + return this; + } + + /** + * Sets a constraint on audio offload enablement. If {@code true}, then audio offload will be + * enabled only if the device supports changing playback speed during offload. Default value + * is {@code false}. + * + * @param isSpeedChangeSupportRequired for playing audio offloaded. + * @return This builder. + */ + @CanIgnoreReturnValue + public Builder setIsSpeedChangeSupportRequired(boolean isSpeedChangeSupportRequired) { + this.isSpeedChangeSupportRequired = isSpeedChangeSupportRequired; + return this; + } + + /** Builds a {@link TrackSelectionParameters} instance with the selected values. */ + public AudioOffloadPreferences build() { + return new AudioOffloadPreferences(this); + } + } + + /** Returns an instance configured with default values. */ + public static final AudioOffloadPreferences DEFAULT = + new AudioOffloadPreferences.Builder().build(); + + /** The preferred offload mode setting for audio playback. */ + public final @AudioOffloadMode int audioOffloadMode; + + /** + * A constraint on enabling offload. If {@code true}, then audio offload will be enabled only if + * the device supports gapless transitions during offload or the selected audio is not gapless. + */ + public final boolean isGaplessSupportRequired; + + /** + * A constraint on enabling offload. If {@code true}, then audio offload will be enabled only if + * the device supports changing playback speed during offload. + */ + public final boolean isSpeedChangeSupportRequired; + + private AudioOffloadPreferences(Builder builder) { + this.audioOffloadMode = builder.audioOffloadMode; + this.isGaplessSupportRequired = builder.isGaplessSupportRequired; + this.isSpeedChangeSupportRequired = builder.isSpeedChangeSupportRequired; + } + + /** + * Creates a new {@link AudioOffloadPreferences.Builder}, copying the initial values from this + * instance. + */ + public AudioOffloadPreferences.Builder buildUpon() { + return new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(audioOffloadMode) + .setIsGaplessSupportRequired(isGaplessSupportRequired) + .setIsSpeedChangeSupportRequired(isSpeedChangeSupportRequired); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + AudioOffloadPreferences other = (AudioOffloadPreferences) obj; + return audioOffloadMode == other.audioOffloadMode + && isGaplessSupportRequired == other.isGaplessSupportRequired + && isSpeedChangeSupportRequired == other.isSpeedChangeSupportRequired; + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + audioOffloadMode; + result = 31 * result + (isGaplessSupportRequired ? 1 : 0); + result = 31 * result + (isSpeedChangeSupportRequired ? 1 : 0); + return result; + } + + // Bundleable implementation + + private static final String FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE = Util.intToStringMaxRadix(1); + private static final String FIELD_IS_GAPLESS_SUPPORT_REQUIRED = Util.intToStringMaxRadix(2); + private static final String FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED = + Util.intToStringMaxRadix(3); + + @Override + public Bundle toBundle() { + Bundle bundle = new Bundle(); + bundle.putInt(FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, audioOffloadMode); + bundle.putBoolean(FIELD_IS_GAPLESS_SUPPORT_REQUIRED, isGaplessSupportRequired); + bundle.putBoolean(FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, isSpeedChangeSupportRequired); + return bundle; + } + + /** Construct an instance from a {@link Bundle} produced by {@link #toBundle()}. */ + public static AudioOffloadPreferences fromBundle(Bundle bundle) { + return new AudioOffloadPreferences.Builder() + .setAudioOffloadMode( + bundle.getInt(FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, DEFAULT.audioOffloadMode)) + .setIsGaplessSupportRequired( + bundle.getBoolean( + FIELD_IS_GAPLESS_SUPPORT_REQUIRED, DEFAULT.isGaplessSupportRequired)) + .setIsSpeedChangeSupportRequired( + bundle.getBoolean( + FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, DEFAULT.isSpeedChangeSupportRequired)) + .build(); + } + } + /** * An instance with default values, except those obtained from the {@link Context}. * @@ -1015,23 +1169,10 @@ public class TrackSelectionParameters implements Bundleable { public final ImmutableList preferredAudioMimeTypes; /** - * The preferred offload mode setting for audio playback. The default is {@link - * #AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED}. + * The preferred offload mode settings for audio playback. The default is {@link + * AudioOffloadPreferences#DEFAULT}. */ - public final @AudioOffloadModePreference int audioOffloadModePreference; - - /** - * A constraint on enabling offload. If {@code isGaplessSupportRequired}, then audio offload will - * be enabled only if the device supports gapless transitions during offload or the selected audio - * is not gapless. - */ - public final boolean isGaplessSupportRequired; - - /** - * A constraint on enabling offload. If {@code isSpeedChangeSupportRequired}, then audio offload - * will be enabled only if the device supports changing playback speed during offload. - */ - public final boolean isSpeedChangeSupportRequired; + @UnstableApi public final AudioOffloadPreferences audioOffloadPreferences; // Text /** @@ -1108,9 +1249,7 @@ public class TrackSelectionParameters implements Bundleable { this.maxAudioChannelCount = builder.maxAudioChannelCount; this.maxAudioBitrate = builder.maxAudioBitrate; this.preferredAudioMimeTypes = builder.preferredAudioMimeTypes; - this.audioOffloadModePreference = builder.audioOffloadModePreference; - this.isGaplessSupportRequired = builder.isGaplessSupportRequired; - this.isSpeedChangeSupportRequired = builder.isSpeedChangeSupportRequired; + this.audioOffloadPreferences = builder.audioOffloadPreferences; // Text this.preferredTextLanguages = builder.preferredTextLanguages; this.preferredTextRoleFlags = builder.preferredTextRoleFlags; @@ -1158,9 +1297,7 @@ public class TrackSelectionParameters implements Bundleable { && maxAudioChannelCount == other.maxAudioChannelCount && maxAudioBitrate == other.maxAudioBitrate && preferredAudioMimeTypes.equals(other.preferredAudioMimeTypes) - && audioOffloadModePreference == other.audioOffloadModePreference - && isGaplessSupportRequired == other.isGaplessSupportRequired - && isSpeedChangeSupportRequired == other.isSpeedChangeSupportRequired + && audioOffloadPreferences.equals(other.audioOffloadPreferences) // Text && preferredTextLanguages.equals(other.preferredTextLanguages) && preferredTextRoleFlags == other.preferredTextRoleFlags @@ -1196,9 +1333,7 @@ public class TrackSelectionParameters implements Bundleable { result = 31 * result + maxAudioChannelCount; result = 31 * result + maxAudioBitrate; result = 31 * result + preferredAudioMimeTypes.hashCode(); - result = 31 * result + audioOffloadModePreference; - result = 31 * result + (isGaplessSupportRequired ? 1 : 0); - result = 31 * result + (isSpeedChangeSupportRequired ? 1 : 0); + result = 31 * result + audioOffloadPreferences.hashCode(); // Text result = 31 * result + preferredTextLanguages.hashCode(); result = 31 * result + preferredTextRoleFlags; @@ -1243,6 +1378,7 @@ public class TrackSelectionParameters implements Bundleable { private static final String FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE = Util.intToStringMaxRadix(27); private static final String FIELD_IS_GAPLESS_SUPPORT_REQUIRED = Util.intToStringMaxRadix(28); private static final String FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED = Util.intToStringMaxRadix(29); + private static final String FIELD_AUDIO_OFFLOAD_PREFERENCES = Util.intToStringMaxRadix(30); /** * Defines a minimum field ID value for subclasses to use when implementing {@link #toBundle()} @@ -1287,9 +1423,13 @@ public class TrackSelectionParameters implements Bundleable { bundle.putInt(FIELD_PREFERRED_TEXT_ROLE_FLAGS, preferredTextRoleFlags); bundle.putInt(FIELD_IGNORED_TEXT_SELECTION_FLAGS, ignoredTextSelectionFlags); bundle.putBoolean(FIELD_SELECT_UNDETERMINED_TEXT_LANGUAGE, selectUndeterminedTextLanguage); - bundle.putInt(FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, audioOffloadModePreference); - bundle.putBoolean(FIELD_IS_GAPLESS_SUPPORT_REQUIRED, isGaplessSupportRequired); - bundle.putBoolean(FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, isSpeedChangeSupportRequired); + bundle.putInt(FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE, audioOffloadPreferences.audioOffloadMode); + bundle.putBoolean( + FIELD_IS_GAPLESS_SUPPORT_REQUIRED, audioOffloadPreferences.isGaplessSupportRequired); + bundle.putBoolean( + FIELD_IS_SPEED_CHANGE_SUPPORT_REQUIRED, + audioOffloadPreferences.isSpeedChangeSupportRequired); + bundle.putBundle(FIELD_AUDIO_OFFLOAD_PREFERENCES, audioOffloadPreferences.toBundle()); // General bundle.putBoolean(FIELD_FORCE_LOWEST_BITRATE, forceLowestBitrate); bundle.putBoolean(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE, forceHighestSupportedBitrate); diff --git a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java index 35d9dc164c..ea2416a654 100644 --- a/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java @@ -15,9 +15,14 @@ */ package androidx.media3.common; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_DISABLED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.google.common.truth.Truth.assertThat; +import android.os.Bundle; +import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences; +import androidx.media3.common.util.Util; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; import org.junit.Test; @@ -29,6 +34,9 @@ public final class TrackSelectionParametersTest { private static final TrackGroup AAC_TRACK_GROUP = new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()); + private static final String BUNDLE_FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE = + Util.intToStringMaxRadix(27); + private static final String BUNDLE_FIELD_AUDIO_OFFLOAD_PREFERENCES = Util.intToStringMaxRadix(30); @Test public void defaultValue_withoutChange_isAsExpected() { @@ -52,10 +60,10 @@ public final class TrackSelectionParametersTest { assertThat(parameters.preferredAudioRoleFlags).isEqualTo(0); assertThat(parameters.maxAudioChannelCount).isEqualTo(Integer.MAX_VALUE); assertThat(parameters.maxAudioBitrate).isEqualTo(Integer.MAX_VALUE); - assertThat(parameters.audioOffloadModePreference) - .isEqualTo(TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED); - assertThat(parameters.isGaplessSupportRequired).isFalse(); - assertThat(parameters.isSpeedChangeSupportRequired).isFalse(); + assertThat(parameters.audioOffloadPreferences.audioOffloadMode) + .isEqualTo(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_DISABLED); + assertThat(parameters.audioOffloadPreferences.isGaplessSupportRequired).isFalse(); + assertThat(parameters.audioOffloadPreferences.isSpeedChangeSupportRequired).isFalse(); // Text assertThat(parameters.preferredAudioMimeTypes).isEmpty(); assertThat(parameters.preferredTextLanguages).isEmpty(); @@ -100,10 +108,11 @@ public final class TrackSelectionParametersTest { .setMaxAudioChannelCount(10) .setMaxAudioBitrate(11) .setPreferredAudioMimeTypes(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3) - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ true) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .setIsSpeedChangeSupportRequired(true) + .build()) // Text .setPreferredTextLanguages("de", "en") .setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION) @@ -148,10 +157,10 @@ public final class TrackSelectionParametersTest { assertThat(parameters.preferredAudioMimeTypes) .containsExactly(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3) .inOrder(); - assertThat(parameters.audioOffloadModePreference) - .isEqualTo(TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED); - assertThat(parameters.isGaplessSupportRequired).isFalse(); - assertThat(parameters.isSpeedChangeSupportRequired).isTrue(); + assertThat(parameters.audioOffloadPreferences.audioOffloadMode) + .isEqualTo(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED); + assertThat(parameters.audioOffloadPreferences.isGaplessSupportRequired).isFalse(); + assertThat(parameters.audioOffloadPreferences.isSpeedChangeSupportRequired).isTrue(); // Text assertThat(parameters.preferredTextLanguages).containsExactly("de", "en").inOrder(); assertThat(parameters.preferredTextRoleFlags).isEqualTo(C.ROLE_FLAG_CAPTION); @@ -220,6 +229,29 @@ public final class TrackSelectionParametersTest { .containsExactly(override.mediaTrackGroup, override); } + @Test + public void roundTripViaBundle_withLegacyPreferenceFields_yieldsEqualInstance() { + TrackSelectionParameters trackSelectionParameters = + new TrackSelectionParameters.Builder(getApplicationContext()) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .build()) + .build(); + Bundle bundle = trackSelectionParameters.toBundle(); + // By removing AudioOffloadPreferences, bundle is a model of one initially created without + // AudioOffloadPreferences but containing AudioOffloadPreferences sub-fields(ex: + // isGaplessSupportRequired). Prod system should not be removing fields from the bundle. + bundle.remove(BUNDLE_FIELD_AUDIO_OFFLOAD_PREFERENCES); + + TrackSelectionParameters trackSelectionParametersfromBundle = + TrackSelectionParameters.fromBundle(bundle); + + assertThat(bundle.containsKey(BUNDLE_FIELD_AUDIO_OFFLOAD_MODE_PREFERENCE)).isTrue(); + assertThat(trackSelectionParametersfromBundle).isEqualTo(trackSelectionParameters); + } + @Test public void addOverride_onDifferentGroups_addsOverride() { TrackSelectionOverride override1 = @@ -307,6 +339,29 @@ public final class TrackSelectionParametersTest { .containsExactly(override1.mediaTrackGroup, override1); } + @Test + public void audioOffloadPreferences_checkDefault_allFieldsAreDisabledOrFalse() { + AudioOffloadPreferences audioOffloadPreferences = AudioOffloadPreferences.DEFAULT; + + assertThat(audioOffloadPreferences.audioOffloadMode).isEqualTo(AUDIO_OFFLOAD_MODE_DISABLED); + assertThat(audioOffloadPreferences.isGaplessSupportRequired).isFalse(); + assertThat(audioOffloadPreferences.isSpeedChangeSupportRequired).isFalse(); + } + + @Test + public void audioOffloadPreferences_buildUponWithIndividualSetters_equalsToOriginal() { + AudioOffloadPreferences audioOffloadPreferences = + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build(); + + AudioOffloadPreferences copy = audioOffloadPreferences.buildUpon().build(); + + assertThat(copy).isEqualTo(audioOffloadPreferences); + } + private static TrackGroup newTrackGroupWithIds(int... ids) { Format[] formats = new Format[ids.length]; for (int i = 0; i < ids.length; i++) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java index 0942c5df3a..4839178677 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlayer.java @@ -1801,7 +1801,7 @@ public interface ExoPlayer extends Player { * *

    *
  • Audio offload rendering is enabled through {@link - * TrackSelectionParameters.Builder#setAudioOffloadPreference}. + * TrackSelectionParameters.Builder#setAudioOffloadPreferences}. *
  • An audio track is playing in a format that the device supports offloading (for example, * MP3 or AAC). *
  • The {@link AudioSink} is playing with an offload {@link AudioTrack}. diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java index 7d3ff55245..53bc7deda5 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelector.java @@ -15,8 +15,8 @@ */ package androidx.media3.exoplayer.trackselection; -import static androidx.media3.common.TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED; -import static androidx.media3.common.TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_DISABLED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED; import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Util.castNonNull; import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_GAPLESS_SUPPORTED; @@ -53,6 +53,7 @@ import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; +import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.BundleableUtil; import androidx.media3.common.util.Log; @@ -463,12 +464,9 @@ public class DefaultTrackSelector extends MappingTrackSelector @CanIgnoreReturnValue @Override - public ParametersBuilder setAudioOffloadPreference( - @TrackSelectionParameters.AudioOffloadModePreference int audioOffloadModePreference, - boolean isGaplessSupportRequired, - boolean isSpeedChangeSupportRequired) { - delegate.setAudioOffloadPreference( - audioOffloadModePreference, isGaplessSupportRequired, isSpeedChangeSupportRequired); + public ParametersBuilder setAudioOffloadPreferences( + AudioOffloadPreferences audioOffloadPreferences) { + delegate.setAudioOffloadPreferences(audioOffloadPreferences); return this; } @@ -2507,7 +2505,7 @@ public class DefaultTrackSelector extends MappingTrackSelector } // Configure audio renderer to use offload if appropriate. - if (parameters.audioOffloadModePreference != AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED) { + if (parameters.audioOffloadPreferences.audioOffloadMode != AUDIO_OFFLOAD_MODE_DISABLED) { maybeConfigureRendererForOffload( parameters, mappedTrackInfo, @@ -2529,9 +2527,10 @@ public class DefaultTrackSelector extends MappingTrackSelector *

    The implementation should not account for overrides and disabled flags. Track selections * generated by this method will be overridden to account for these properties. * - *

    If selection parameters include {@link Parameters#audioOffloadModePreference} with {@link - * TrackSelectionParameters#AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED}, then only audio tracks will - * be selected. If no audio track is supported in offload, then no track will be selected. + *

    If selection parameters include {@link Parameters#audioOffloadPreferences} with {@link + * AudioOffloadPreferences#audioOffloadMode} set to {@link + * AudioOffloadPreferences#AUDIO_OFFLOAD_MODE_REQUIRED} then only audio tracks will be selected. + * If no audio track is supported in offload, then no track will be selected. * * @param mappedTrackInfo Mapped track information. * @param rendererFormatSupports The {@link Capabilities} for each mapped track, indexed by @@ -2623,7 +2622,7 @@ public class DefaultTrackSelector extends MappingTrackSelector @AdaptiveSupport int[] mixedMimeTypeSupports, Parameters params) throws ExoPlaybackException { - if (params.audioOffloadModePreference == AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED) { + if (params.audioOffloadPreferences.audioOffloadMode == AUDIO_OFFLOAD_MODE_REQUIRED) { return null; } return selectTracksForType( @@ -2741,7 +2740,7 @@ public class DefaultTrackSelector extends MappingTrackSelector Parameters params, @Nullable String selectedAudioLanguage) throws ExoPlaybackException { - if (params.audioOffloadModePreference == AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED) { + if (params.audioOffloadPreferences.audioOffloadMode == AUDIO_OFFLOAD_MODE_REQUIRED) { return null; } return selectTracksForType( @@ -2772,7 +2771,7 @@ public class DefaultTrackSelector extends MappingTrackSelector protected ExoTrackSelection.Definition selectOtherTrack( int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) throws ExoPlaybackException { - if (params.audioOffloadModePreference == AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED) { + if (params.audioOffloadPreferences.audioOffloadMode == AUDIO_OFFLOAD_MODE_REQUIRED) { return null; } @Nullable TrackGroup selectedGroup = null; @@ -3077,7 +3076,7 @@ public class DefaultTrackSelector extends MappingTrackSelector // Check whether we can enable offload. To enable offload we require exactly one audio track // and a renderer with support matching the requirements set by // setAudioOffloadPreference. There also cannot be other non-audio renderers with their own - // selected tracks. + // selected tracks unless the selection parameters say audio-only is not required. int audioRendererIndex = C.INDEX_UNSET; int audioRenderersSupportingOffload = 0; boolean hasNonAudioRendererWithSelectedTracks = false; @@ -3106,7 +3105,7 @@ public class DefaultTrackSelector extends MappingTrackSelector if (!hasNonAudioRendererWithSelectedTracks && audioRenderersSupportingOffload == 1) { RendererConfiguration offloadRendererConfiguration = new RendererConfiguration( - parameters.isGaplessSupportRequired + parameters.audioOffloadPreferences.isGaplessSupportRequired ? AudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED : AudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_NOT_REQUIRED, /* tunneling= */ rendererConfigurations[audioRendererIndex] != null @@ -3128,14 +3127,14 @@ public class DefaultTrackSelector extends MappingTrackSelector if (RendererCapabilities.getAudioOffloadSupport(formatSupport) == AUDIO_OFFLOAD_NOT_SUPPORTED) { return false; } - if (parameters.isSpeedChangeSupportRequired + if (parameters.audioOffloadPreferences.isSpeedChangeSupportRequired && (RendererCapabilities.getAudioOffloadSupport(formatSupport) & AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED) == 0) { return false; } // TODO(b/235883373): Add check for OPUS where gapless info is in initialization data - if (parameters.isGaplessSupportRequired) { + if (parameters.audioOffloadPreferences.isGaplessSupportRequired) { boolean isGapless = format.encoderDelay != 0 || format.encoderPadding != 0; boolean isGaplessSupported = (RendererCapabilities.getAudioOffloadSupport(formatSupport) @@ -3751,7 +3750,7 @@ public class DefaultTrackSelector extends MappingTrackSelector if (!isWithinConstraints && !parameters.exceedAudioConstraintsIfNecessary) { return SELECTION_ELIGIBILITY_NO; } - if (params.audioOffloadModePreference == AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED + if (params.audioOffloadPreferences.audioOffloadMode == AUDIO_OFFLOAD_MODE_REQUIRED && !rendererSupportsOffload(params, rendererSupport, format)) { return SELECTION_ELIGIBILITY_NO; } @@ -3761,7 +3760,7 @@ public class DefaultTrackSelector extends MappingTrackSelector && !parameters.forceHighestSupportedBitrate && !parameters.forceLowestBitrate && (parameters.allowMultipleAdaptiveSelections || !hasMappedVideoTracks) - && params.audioOffloadModePreference != AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED + && params.audioOffloadPreferences.audioOffloadMode != AUDIO_OFFLOAD_MODE_REQUIRED ? SELECTION_ELIGIBILITY_ADAPTIVE : SELECTION_ELIGIBILITY_FIXED; } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java index 1376a2254d..0b3a2b0b7e 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/ExoPlayerTest.java @@ -122,7 +122,7 @@ import androidx.media3.common.Player.PositionInfo; import androidx.media3.common.Timeline; import androidx.media3.common.Timeline.Window; import androidx.media3.common.TrackGroup; -import androidx.media3.common.TrackSelectionParameters; +import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences; import androidx.media3.common.Tracks; import androidx.media3.common.VideoSize; import androidx.media3.common.util.Assertions; @@ -10210,10 +10210,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10241,10 +10241,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ true); @@ -10266,10 +10266,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10292,10 +10292,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10305,10 +10305,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_DISABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_DISABLED) + .build()) .build()); runUntilSleepingForOffload(player, /* expectedSleepForOffload= */ false); @@ -10328,10 +10328,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10359,10 +10359,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10393,10 +10393,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); @@ -10428,10 +10428,10 @@ public final class ExoPlayerTest { player .getTrackSelectionParameters() .buildUpon() - .setAudioOffloadPreference( - TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED) + .build()) .build()); player.prepare(); player.play(); diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/OggOpusPlaybackTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/OggOpusPlaybackTest.java index 718e6653a8..a9ac6d46ec 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/OggOpusPlaybackTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/e2etest/OggOpusPlaybackTest.java @@ -15,13 +15,14 @@ */ package androidx.media3.exoplayer.e2etest; -import static androidx.media3.common.TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED; import android.content.Context; import androidx.annotation.Nullable; import androidx.media3.common.Format; import androidx.media3.common.MediaItem; import androidx.media3.common.Player; +import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences; import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.audio.AudioOffloadSupport; @@ -61,10 +62,12 @@ public class OggOpusPlaybackTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(false) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); ExoPlayer player = new ExoPlayer.Builder(applicationContext, offloadRenderersFactory) diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java index bd213ffda4..dabd6d0941 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/trackselection/DefaultTrackSelectorTest.java @@ -19,8 +19,8 @@ import static androidx.media3.common.C.FORMAT_EXCEEDS_CAPABILITIES; import static androidx.media3.common.C.FORMAT_HANDLED; import static androidx.media3.common.C.FORMAT_UNSUPPORTED_SUBTYPE; import static androidx.media3.common.C.FORMAT_UNSUPPORTED_TYPE; -import static androidx.media3.common.TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED; -import static androidx.media3.common.TrackSelectionParameters.AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED; +import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED; import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_NOT_SEAMLESS; import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_GAPLESS_SUPPORTED; import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_SUPPORTED; @@ -51,6 +51,7 @@ import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; +import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences; import androidx.media3.common.Tracks; import androidx.media3.common.util.HandlerWrapper; import androidx.media3.common.util.Util; @@ -2329,10 +2330,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); RendererCapabilities capabilitiesOffloadSupport = new FakeRendererCapabilities( @@ -2365,10 +2368,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); RendererCapabilities capabilitiesOffloadSupport = new FakeRendererCapabilities( @@ -2402,10 +2407,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_REQUIRED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); RendererCapabilities capabilitiesOffloadSupport = new FakeRendererCapabilities( @@ -2438,10 +2445,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(false) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); RendererCapabilities audioCapabilities = new FakeRendererCapabilities( @@ -2475,10 +2484,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED, - /* isGaplessSupportRequired= */ false, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_REQUIRED) + .setIsGaplessSupportRequired(false) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); RendererCapabilities audioCapabilities = new FakeRendererCapabilities( @@ -2517,10 +2528,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); // Offload playback without gapless transitions is supported RendererCapabilities capabilitiesOffloadSupport = @@ -2559,12 +2572,14 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_ENABLED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_ENABLED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); - // Offload playback without gapless transitions is supported + // Offload playback with gapless transitions is supported RendererCapabilities capabilitiesOffloadSupport = new FakeRendererCapabilities( C.TRACK_TYPE_AUDIO, @@ -2598,10 +2613,12 @@ public final class DefaultTrackSelectorTest { trackSelector.setParameters( trackSelector .buildUponParameters() - .setAudioOffloadPreference( - AUDIO_OFFLOAD_MODE_PREFERENCE_REQUIRED, - /* isGaplessSupportRequired= */ true, - /* isSpeedChangeSupportRequired= */ false) + .setAudioOffloadPreferences( + new AudioOffloadPreferences.Builder() + .setAudioOffloadMode(AUDIO_OFFLOAD_MODE_REQUIRED) + .setIsGaplessSupportRequired(true) + .setIsSpeedChangeSupportRequired(false) + .build()) .build()); // Offload playback without gapless transitions is supported RendererCapabilities capabilitiesOffloadSupport =