From a49b625cc585970843f27410b614c6470924e7e5 Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 29 Apr 2024 08:15:03 -0700 Subject: [PATCH] Add renderer message to update priority This can be used to set the new codec importance values. PiperOrigin-RevId: 629073176 --- .../androidx/media3/exoplayer/Renderer.java | 10 +++++- .../audio/MediaCodecAudioRenderer.java | 31 +++++++++++++++---- .../video/MediaCodecVideoRenderer.java | 30 ++++++++++++++---- 3 files changed, 58 insertions(+), 13 deletions(-) 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 e61b897ebb..215d043d04 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/Renderer.java @@ -116,7 +116,8 @@ public interface Renderer extends PlayerMessage.Target { MSG_SET_WAKEUP_LISTENER, MSG_SET_VIDEO_EFFECTS, MSG_SET_VIDEO_OUTPUT_RESOLUTION, - MSG_SET_IMAGE_OUTPUT + MSG_SET_IMAGE_OUTPUT, + MSG_SET_PRIORITY }) public @interface MessageType {} @@ -250,6 +251,13 @@ public interface Renderer extends PlayerMessage.Target { */ int MSG_SET_IMAGE_OUTPUT = 15; + /** + * The type of message that can be passed to a renderer to set its priority. The message payload + * should be an {@link Integer} instance for the priority of the renderer. See {@code C.PRIORITY_} + * constants for predefined values. + */ + int MSG_SET_PRIORITY = 16; + /** * 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. 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 c4468563d8..b9b21f98f9 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 @@ -28,6 +28,7 @@ import android.media.AudioFormat; import android.media.MediaCodec; import android.media.MediaCrypto; import android.media.MediaFormat; +import android.os.Bundle; import android.os.Handler; import androidx.annotation.CallSuper; import androidx.annotation.DoNotInline; @@ -121,6 +122,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media @Nullable private WakeupListener wakeupListener; private boolean hasPendingReportedSkippedSilence; + private int rendererPriority; /** * @param context A context. @@ -259,6 +261,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media context = context.getApplicationContext(); this.context = context; this.audioSink = audioSink; + rendererPriority = C.PRIORITY_PLAYBACK; eventDispatcher = new EventDispatcher(eventHandler, eventListener); audioSink.setListener(new AudioSinkListener()); } @@ -822,11 +825,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media case MSG_SET_WAKEUP_LISTENER: this.wakeupListener = (WakeupListener) message; break; - case MSG_SET_CAMERA_MOTION_LISTENER: - case MSG_SET_CHANGE_FRAME_RATE_STRATEGY: - case MSG_SET_SCALING_MODE: - case MSG_SET_VIDEO_FRAME_METADATA_LISTENER: - case MSG_SET_VIDEO_OUTPUT: + case MSG_SET_PRIORITY: + rendererPriority = (int) checkNotNull(message); + updateCodecImportance(); + break; default: super.handleMessage(messageType, message); break; @@ -938,10 +940,27 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media if (Util.SDK_INT >= 32) { mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99); } - + if (Util.SDK_INT >= 35) { + // TODO: b/333552477 - Use MediaFormat.KEY_IMPORTANCE once compileSdk >= 35 + mediaFormat.setInteger("importance", max(0, -rendererPriority)); + } return mediaFormat; } + private void updateCodecImportance() { + @Nullable MediaCodecAdapter codec = getCodec(); + if (codec == null) { + // If codec is null, then the importance will be set when initializing the codec. + return; + } + if (Util.SDK_INT >= 35) { + Bundle codecParameters = new Bundle(); + // TODO: b/333552477 - Use MediaFormat.KEY_IMPORTANCE once compileSdk >= 35 + codecParameters.putInt("importance", max(0, -rendererPriority)); + codec.setParameters(codecParameters); + } + } + private void updateCurrentPosition() { long newCurrentPositionUs = audioSink.getCurrentPositionUs(isEnded()); if (newCurrentPositionUs != AudioSink.CURRENT_POSITION_NOT_SET) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index d1fa900146..00554f91fa 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java @@ -169,6 +169,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer @Nullable private VideoSize reportedVideoSize; private boolean hasEffects; private boolean hasInitializedPlayback; + private int rendererPriority; private boolean tunneling; private int tunnelingAudioSessionId; @@ -413,6 +414,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer decodedVideoSize = VideoSize.UNKNOWN; tunnelingAudioSessionId = C.AUDIO_SESSION_ID_UNSET; reportedVideoSize = null; + rendererPriority = C.PRIORITY_PLAYBACK; } // FrameTimingEvaluator methods @@ -782,12 +784,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer videoSinkProvider.setOutputSurfaceInfo(displaySurface, checkNotNull(outputResolution)); } break; - case MSG_SET_AUDIO_ATTRIBUTES: - case MSG_SET_AUX_EFFECT_INFO: - case MSG_SET_CAMERA_MOTION_LISTENER: - case MSG_SET_SKIP_SILENCE_ENABLED: - case MSG_SET_VOLUME: - case MSG_SET_WAKEUP_LISTENER: + case MSG_SET_PRIORITY: + rendererPriority = (int) checkNotNull(message); + updateCodecImportance(); + break; default: super.handleMessage(messageType, message); } @@ -1722,6 +1722,20 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer } } + private void updateCodecImportance() { + @Nullable MediaCodecAdapter codec = getCodec(); + if (codec == null) { + // If codec is null, then the importance will be set when initializing the codec. + return; + } + if (Util.SDK_INT >= 35) { + Bundle codecParameters = new Bundle(); + // TODO: b/333552477 - Use MediaFormat.KEY_IMPORTANCE once compileSdk >= 35 + codecParameters.putInt("importance", max(0, -rendererPriority)); + codec.setParameters(codecParameters); + } + } + private void maybeNotifyRenderedFirstFrame() { if (videoFrameReleaseControl.onFrameReleasedIsFirstFrame() && displaySurface != null) { notifyRenderedFirstFrame(); @@ -1852,6 +1866,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer if (tunnelingAudioSessionId != C.AUDIO_SESSION_ID_UNSET) { configureTunnelingV21(mediaFormat, tunnelingAudioSessionId); } + if (Util.SDK_INT >= 35) { + // TODO: b/333552477 - Use MediaFormat.KEY_IMPORTANCE once compileSdk >= 35 + mediaFormat.setInteger("importance", max(0, -rendererPriority)); + } return mediaFormat; }