Skip to content

Add Player.setAudioPresentation API #2549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions libraries/common/src/main/java/androidx/media3/common/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;

import android.media.AudioPresentation;
import android.os.Bundle;
import android.os.Looper;
import android.view.Surface;
Expand Down Expand Up @@ -554,6 +555,7 @@ public static final class Builder {
COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
COMMAND_SET_AUDIO_ATTRIBUTES,
COMMAND_SET_AUDIO_PRESENTATION,
COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT,
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
Expand Down Expand Up @@ -1685,6 +1687,7 @@ default void onMetadata(Metadata metadata) {}
* <li>{@link #COMMAND_ADJUST_DEVICE_VOLUME}
* <li>{@link #COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS}
* <li>{@link #COMMAND_SET_AUDIO_ATTRIBUTES}
* <li>{@link #COMMAND_SET_AUDIO_PRESENTATION}
* <li>{@link #COMMAND_SET_VIDEO_SURFACE}
* <li>{@link #COMMAND_GET_TEXT}
* <li>{@link #COMMAND_SET_TRACK_SELECTION_PARAMETERS}
Expand Down Expand Up @@ -1732,6 +1735,7 @@ default void onMetadata(Metadata metadata) {}
COMMAND_ADJUST_DEVICE_VOLUME,
COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS,
COMMAND_SET_AUDIO_ATTRIBUTES,
COMMAND_SET_AUDIO_PRESENTATION,
COMMAND_SET_VIDEO_SURFACE,
COMMAND_GET_TEXT,
COMMAND_SET_TRACK_SELECTION_PARAMETERS,
Expand Down Expand Up @@ -2092,6 +2096,14 @@ default void onMetadata(Metadata metadata) {}
*/
int COMMAND_SET_AUDIO_ATTRIBUTES = 35;

/**
* Command to set the player's audio presentation.
*
* <p>The {@link #setAudioPresentation(AudioPresentation presentation)} method must only
* be called if this command is {@linkplain #isCommandAvailable(int) available}.
*/
int COMMAND_SET_AUDIO_PRESENTATION = 36;

/**
* Command to set and clear the surface on which to render the video.
*
Expand Down Expand Up @@ -3508,4 +3520,18 @@ default void onMetadata(Metadata metadata) {}
* @param handleAudioFocus True if the player should handle audio focus, false otherwise.
*/
void setAudioAttributes(AudioAttributes audioAttributes, boolean handleAudioFocus);

/**
* Sets the {@link AudioPresentation} to be selected in the audio renderer on an active audio
* track. This audio presentation will be decoded by the supported audio decoders.
*
* <p>This method is supported only for direct/offload playback modes and on devices running a
* build platform API version 29 onwards.
*
* <p>This method must only be called if {@link #COMMAND_SET_AUDIO_PRESENTATION} is {@linkplain
* #getAvailableCommands() available}.
*
* @param presentation The audio presentation to select.
*/
default void setAudioPresentation(AudioPresentation presentation) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Util.castNonNull;
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUDIO_ATTRIBUTES;
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUDIO_PRESENTATION;
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUDIO_SESSION_ID;
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUX_EFFECT_INFO;
import static androidx.media3.exoplayer.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
Expand All @@ -45,6 +46,7 @@
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.media.AudioDeviceInfo;
import android.media.AudioPresentation;
import android.media.MediaFormat;
import android.os.Handler;
import android.os.Looper;
Expand All @@ -53,6 +55,7 @@
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.media3.common.AudioAttributes;
Expand Down Expand Up @@ -1944,6 +1947,12 @@ public void setImageOutput(@Nullable ImageOutput imageOutput) {
sendRendererMessage(TRACK_TYPE_IMAGE, MSG_SET_IMAGE_OUTPUT, imageOutput);
}

@Override
public void setAudioPresentation(AudioPresentation audioPresentation) {
verifyApplicationThread();
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_AUDIO_PRESENTATION, audioPresentation);
}

@SuppressWarnings("deprecation") // Calling deprecated methods.
/* package */ void setThrowsWhenUsingWrongThread(boolean throwsWhenUsingWrongThread) {
this.throwsWhenUsingWrongThread = throwsWhenUsingWrongThread;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static java.lang.annotation.ElementType.TYPE_USE;

import android.media.AudioPresentation;
import android.media.MediaCodec;
import android.view.Surface;
import androidx.annotation.IntDef;
Expand Down Expand Up @@ -186,8 +187,9 @@ interface WakeupListener {
* #MSG_SET_AUX_EFFECT_INFO}, {@link #MSG_SET_VIDEO_FRAME_METADATA_LISTENER}, {@link
* #MSG_SET_CAMERA_MOTION_LISTENER}, {@link #MSG_SET_SKIP_SILENCE_ENABLED}, {@link
* #MSG_SET_AUDIO_SESSION_ID}, {@link #MSG_SET_WAKEUP_LISTENER}, {@link #MSG_SET_VIDEO_EFFECTS},
* {@link #MSG_SET_VIDEO_OUTPUT_RESOLUTION} or {@link #MSG_SET_IMAGE_OUTPUT}. May also be an
* app-defined value (see {@link #MSG_CUSTOM_BASE}).
* {@link #MSG_SET_VIDEO_OUTPUT_RESOLUTION}, {@link #MSG_SET_IMAGE_OUTPUT} or
* {@link #MSG_SET_AUDIO_PRESENTATION}. May also be an app-defined value
* (see {@link #MSG_CUSTOM_BASE}).
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
Expand All @@ -211,7 +213,8 @@ interface WakeupListener {
MSG_SET_IMAGE_OUTPUT,
MSG_SET_PRIORITY,
MSG_TRANSFER_RESOURCES,
MSG_SET_SCRUBBING_MODE
MSG_SET_SCRUBBING_MODE,
MSG_SET_AUDIO_PRESENTATION
})
public @interface MessageType {}

Expand Down Expand Up @@ -363,6 +366,13 @@ interface WakeupListener {
*/
int MSG_SET_SCRUBBING_MODE = 18;

/**
* The type of message that can be passed to an audio renderer to set a desired audio
* presentation. The message object should be an {@link AudioPresentation} instance that will
* configure the underlying audio track.
*/
int MSG_SET_AUDIO_PRESENTATION = 19;

/**
* Applications or extensions may define custom {@code MSG_*} constants that can be passed to
* renderers. These custom constants must be greater than or equal to this value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ interface Listener {
/**
* Level of renderer support for audio offload.
*
* <p>Speed change and gapless transition support with audio offload is represented by the bit
* mask flags {@link #AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED} and {@link
* #AUDIO_OFFLOAD_GAPLESS_SUPPORTED} respectively. If neither feature is supported then the value
* will be either {@link #AUDIO_OFFLOAD_SUPPORTED} or {@link #AUDIO_OFFLOAD_NOT_SUPPORTED}.
* <p>Set presentation, speed change and gapless transition support with audio offload is
* represented by the bit mask flags {@link #AUDIO_OFFLOAD_SET_PRESENTATION_SUPPORTED},
* {@link #AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED} and {@link #AUDIO_OFFLOAD_GAPLESS_SUPPORTED}
* respectively. If neither feature is supported then the value will be either
* {@link #AUDIO_OFFLOAD_SUPPORTED} or {@link #AUDIO_OFFLOAD_NOT_SUPPORTED}.
*
* <p>For non-audio renderers, the level of support is always {@link
* #AUDIO_OFFLOAD_NOT_SUPPORTED}.
Expand All @@ -157,6 +158,7 @@ interface Listener {
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@IntDef({
AUDIO_OFFLOAD_SET_PRESENTATION_SUPPORTED,
AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED,
AUDIO_OFFLOAD_GAPLESS_SUPPORTED,
AUDIO_OFFLOAD_SUPPORTED,
Expand All @@ -165,7 +167,10 @@ interface Listener {
@interface AudioOffloadSupport {}

/** A mask to apply to {@link Capabilities} to obtain {@link AudioOffloadSupport} only. */
int AUDIO_OFFLOAD_SUPPORT_MASK = 0b111 << 9;
int AUDIO_OFFLOAD_SUPPORT_MASK = 0b1111 << 9;

/** The renderer supports audio offload and set presentation with this format. */
int AUDIO_OFFLOAD_SET_PRESENTATION_SUPPORTED = 0b1000 << 9;

/** The renderer supports audio offload and speed changes with this format. */
int AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED = 0b100 << 9;
Expand Down Expand Up @@ -215,9 +220,10 @@ interface Listener {
* <li>{@link AudioOffloadSupport}: The level of offload support. Value will have the flag
* {@link #AUDIO_OFFLOAD_SUPPORTED} or be {@link #AUDIO_OFFLOAD_NOT_SUPPORTED}. In addition,
* if it is {@link #AUDIO_OFFLOAD_SUPPORTED}, then one can check for {@link
* #AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED} and {@link #AUDIO_OFFLOAD_GAPLESS_SUPPORTED}.
* These represent speed change and gapless transition support with audio offload
* respectively.
* #AUDIO_OFFLOAD_SET_PRESENTATION_SUPPORTED}, {@link #AUDIO_OFFLOAD_SPEED_CHANGE_SUPPORTED}
* and {@link #AUDIO_OFFLOAD_GAPLESS_SUPPORTED}.
* These represent set presentation, speed change and gapless transition support with audio
* offload respectively.
* </ul>
*/
@Documented
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,16 @@ public static final class Builder {
/** Whether playback of the format is supported with speed changes. */
private boolean isSpeedChangeSupported;

/** Whether playback of the format is supported with audio presentation selection. */
private boolean isSetPresentationSupported;

public Builder() {}

public Builder(AudioOffloadSupport audioOffloadSupport) {
isFormatSupported = audioOffloadSupport.isFormatSupported;
isGaplessSupported = audioOffloadSupport.isGaplessSupported;
isSpeedChangeSupported = audioOffloadSupport.isSpeedChangeSupported;
isSetPresentationSupported = audioOffloadSupport.isSetPresentationSupported;
}

/**
Expand Down Expand Up @@ -79,6 +83,17 @@ public Builder setIsSpeedChangeSupported(boolean isSpeedChangeSupported) {
return this;
}

/**
* Sets whether the format allows selection of different audio presentations during playback.
*
* <p>Default is {@code false}.
*/
@CanIgnoreReturnValue
public Builder setIsPresentationSelectionSupported(boolean isSetPresentationSupported) {
this.isSetPresentationSupported = isSetPresentationSupported;
return this;
}

/**
* Builds the {@link AudioOffloadSupport}.
*
Expand All @@ -103,10 +118,14 @@ public AudioOffloadSupport build() {
/** Whether playback of the format is supported with speed changes. */
public final boolean isSpeedChangeSupported;

/** Whether the format allows selection of different audio presentations during playback. */
public final boolean isSetPresentationSupported;

private AudioOffloadSupport(AudioOffloadSupport.Builder builder) {
this.isFormatSupported = builder.isFormatSupported;
this.isGaplessSupported = builder.isGaplessSupported;
this.isSpeedChangeSupported = builder.isSpeedChangeSupported;
this.isSetPresentationSupported = builder.isSetPresentationSupported;
}

/** Creates a new {@link Builder}, copying the initial values from this instance. */
Expand All @@ -125,14 +144,16 @@ public boolean equals(@Nullable Object obj) {
AudioOffloadSupport other = (AudioOffloadSupport) obj;
return isFormatSupported == other.isFormatSupported
&& isGaplessSupported == other.isGaplessSupported
&& isSpeedChangeSupported == other.isSpeedChangeSupported;
&& isSpeedChangeSupported == other.isSpeedChangeSupported
&& isSetPresentationSupported == other.isSetPresentationSupported;
}

@Override
public int hashCode() {
int hashCode = (isFormatSupported ? 1 : 0) << 2;
hashCode += (isGaplessSupported ? 1 : 0) << 1;
hashCode += (isSpeedChangeSupported ? 1 : 0);
int hashCode = (isFormatSupported ? 1 : 0) << 3;
hashCode += (isGaplessSupported ? 1 : 0) << 2;
hashCode += (isSpeedChangeSupported ? 1 : 0) << 1;
hashCode += (isSetPresentationSupported ? 1 : 0);
return hashCode;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static java.lang.annotation.ElementType.TYPE_USE;

import android.media.AudioDeviceInfo;
import android.media.AudioPresentation;
import android.media.AudioTrack;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -643,6 +644,15 @@ default void setOffloadMode(@OffloadMode int offloadMode) {}
@RequiresApi(29)
default void setOffloadDelayPadding(int delayInFrames, int paddingInFrames) {}

/**
* Sets the presentation of an audio program, delivered by Next Generation Audio streams.
* Also requires platform API version 29 onwards.
*
* @param presentation The audio presentation to set.
*/
@RequiresApi(29)
default void setPresentation(AudioPresentation presentation) {}

/**
* Sets the playback volume.
*
Expand Down
Loading