Commit e2f0fd76 by christosts Committed by Marc Baechinger

DefaultTrackSelector: Constrain audio channel count

The track selector will select multi-channel formats when those can be
spatialized, otherwise the selector will prefer stereo/mono audio
tracks. When the device supports audio spatialization (Android 12L+),
the DefaultTrackSelector will monitor for changes in the platform
Spatializer and trigger a new track selection upon a
Spatializer change event.

Devices with a `television` UI mode are excluded from audio channel
count constraints.

#minor-release

PiperOrigin-RevId: 453957269
parent 9221eeb2
...@@ -39,6 +39,24 @@ ...@@ -39,6 +39,24 @@
`DefaultTrackSelector.Parameters.buildUpon` to return `DefaultTrackSelector.Parameters.buildUpon` to return
`DefaultTrackSelector.Parameters.Builder` instead of the deprecated `DefaultTrackSelector.Parameters.Builder` instead of the deprecated
`DefaultTrackSelector.ParametersBuilder`. `DefaultTrackSelector.ParametersBuilder`.
* Add
`DefaultTrackSelector.Parameters.constrainAudioChannelCountToDeviceCapabilities`.
which is enabled by default. When enabled, the `DefaultTrackSelector`
will prefer audio tracks whose channel count does not exceed the device
output capabilities. On handheld devices, the `DefaultTrackSelector`
will prefer stereo/mono over multichannel audio formats, unless the
multichannel format can be
[Spatialized](https://developer.android.com/reference/android/media/Spatializer)
(Android 12L+) or is a Dolby surround sound format. In addition, on
devices that support audio spatialization, the `DefaultTrackSelector`
will monitor for changes in the
[Spatializer properties](https://developer.android.com/reference/android/media/Spatializer.OnSpatializerStateChangedListener)
and trigger a new track selection upon these. Devices with a
`television`
[UI mode](https://developer.android.com/guide/topics/resources/providing-resources#UiModeQualifier)
are excluded from these constraints and the format with the highest
channel count will be preferred. To enable this feature, the
`DefaultTrackSelector` instance must be constructed with a `Context`.
* Video: * Video:
* Rename `DummySurface` to `PlaceholderSurface`. * Rename `DummySurface` to `PlaceholderSurface`.
* Add AV1 support to the `MediaCodecVideoRenderer.getCodecMaxInputSize`. * Add AV1 support to the `MediaCodecVideoRenderer.getCodecMaxInputSize`.
...@@ -171,6 +189,8 @@ ...@@ -171,6 +189,8 @@
`DEFAULT_TRACK_SELECTOR_PARAMETERS` constants. Use `DEFAULT_TRACK_SELECTOR_PARAMETERS` constants. Use
`getDefaultTrackSelectorParameters(Context)` instead when possible, and `getDefaultTrackSelectorParameters(Context)` instead when possible, and
`DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_CONTEXT` otherwise. `DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_CONTEXT` otherwise.
* Remove constructor `DefaultTrackSelector(ExoTrackSelection.Factory)`.
Use `DefaultTrackSelector(Context, ExoTrackSelection.Factory)` instead.
### 1.0.0-alpha03 (2022-03-14) ### 1.0.0-alpha03 (2022-03-14)
......
...@@ -380,6 +380,7 @@ import java.util.concurrent.TimeoutException; ...@@ -380,6 +380,7 @@ import java.util.concurrent.TimeoutException;
deviceInfo = createDeviceInfo(streamVolumeManager); deviceInfo = createDeviceInfo(streamVolumeManager);
videoSize = VideoSize.UNKNOWN; videoSize = VideoSize.UNKNOWN;
trackSelector.setAudioAttributes(audioAttributes);
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
sendRendererMessage(TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId); sendRendererMessage(TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, audioAttributes); sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_ATTRIBUTES, audioAttributes);
...@@ -1375,6 +1376,7 @@ import java.util.concurrent.TimeoutException; ...@@ -1375,6 +1376,7 @@ import java.util.concurrent.TimeoutException;
} }
audioFocusManager.setAudioAttributes(handleAudioFocus ? newAudioAttributes : null); audioFocusManager.setAudioAttributes(handleAudioFocus ? newAudioAttributes : null);
trackSelector.setAudioAttributes(newAudioAttributes);
boolean playWhenReady = getPlayWhenReady(); boolean playWhenReady = getPlayWhenReady();
@AudioFocusManager.PlayerCommand @AudioFocusManager.PlayerCommand
int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState()); int playerCommand = audioFocusManager.updateAudioFocus(playWhenReady, getPlaybackState());
......
...@@ -110,6 +110,7 @@ public final class DownloadHelper { ...@@ -110,6 +110,7 @@ public final class DownloadHelper {
DefaultTrackSelector.Parameters.DEFAULT_WITHOUT_CONTEXT DefaultTrackSelector.Parameters.DEFAULT_WITHOUT_CONTEXT
.buildUpon() .buildUpon()
.setForceHighestSupportedBitrate(true) .setForceHighestSupportedBitrate(true)
.setConstrainAudioChannelCountToDeviceCapabilities(false)
.build(); .build();
/** Returns the default parameters used for track selection for downloading. */ /** Returns the default parameters used for track selection for downloading. */
...@@ -117,6 +118,7 @@ public final class DownloadHelper { ...@@ -117,6 +118,7 @@ public final class DownloadHelper {
return DefaultTrackSelector.Parameters.getDefaults(context) return DefaultTrackSelector.Parameters.getDefaults(context)
.buildUpon() .buildUpon()
.setForceHighestSupportedBitrate(true) .setForceHighestSupportedBitrate(true)
.setConstrainAudioChannelCountToDeviceCapabilities(false)
.build(); .build();
} }
......
...@@ -17,7 +17,9 @@ package androidx.media3.exoplayer.trackselection; ...@@ -17,7 +17,9 @@ package androidx.media3.exoplayer.trackselection;
import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Assertions.checkStateNotNull;
import androidx.annotation.CallSuper;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.common.Timeline; import androidx.media3.common.Timeline;
import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.TrackSelectionParameters;
...@@ -112,7 +114,8 @@ public abstract class TrackSelector { ...@@ -112,7 +114,8 @@ public abstract class TrackSelector {
* it has previously made are no longer valid. * it has previously made are no longer valid.
* @param bandwidthMeter A bandwidth meter which can be used by track selections to select tracks. * @param bandwidthMeter A bandwidth meter which can be used by track selections to select tracks.
*/ */
public final void init(InvalidationListener listener, BandwidthMeter bandwidthMeter) { @CallSuper
public void init(InvalidationListener listener, BandwidthMeter bandwidthMeter) {
this.listener = listener; this.listener = listener;
this.bandwidthMeter = bandwidthMeter; this.bandwidthMeter = bandwidthMeter;
} }
...@@ -121,9 +124,10 @@ public abstract class TrackSelector { ...@@ -121,9 +124,10 @@ public abstract class TrackSelector {
* Called by the player to release the selector. The selector cannot be used until {@link * Called by the player to release the selector. The selector cannot be used until {@link
* #init(InvalidationListener, BandwidthMeter)} is called again. * #init(InvalidationListener, BandwidthMeter)} is called again.
*/ */
public final void release() { @CallSuper
this.listener = null; public void release() {
this.bandwidthMeter = null; listener = null;
bandwidthMeter = null;
} }
/** /**
...@@ -178,6 +182,11 @@ public abstract class TrackSelector { ...@@ -178,6 +182,11 @@ public abstract class TrackSelector {
return false; return false;
} }
/** Called by the player to set the {@link AudioAttributes} that will be used for playback. */
public void setAudioAttributes(AudioAttributes audioAttributes) {
// Default implementation is no-op.
}
/** /**
* Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously * Calls {@link InvalidationListener#onTrackSelectionsInvalidated()} to invalidate all previously
* generated track selections. * generated track selections.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment