Expose AudioOffload track state.
Adds a new event to AudioOffloadListener to get the offload state of the track, which indicates when software decoding is taking place. PiperOrigin-RevId: 465264362
This commit is contained in:
parent
a10af8ecda
commit
7893531888
@ -11,6 +11,10 @@
|
|||||||
([#10057](https://github.com/google/ExoPlayer/issues/10057)).
|
([#10057](https://github.com/google/ExoPlayer/issues/10057)).
|
||||||
* Limit parallel download removals to 1 to avoid excessive thread creation
|
* Limit parallel download removals to 1 to avoid excessive thread creation
|
||||||
([#10458](https://github.com/google/ExoPlayer/issues/10458)).
|
([#10458](https://github.com/google/ExoPlayer/issues/10458)).
|
||||||
|
* Audio:
|
||||||
|
* Adds AudioOffloadListener.onExperimentalOffloadedPlayback for the
|
||||||
|
AudioTrack offload state.
|
||||||
|
([#134](https://github.com/androidx/media/issues/134)).
|
||||||
* Metadata:
|
* Metadata:
|
||||||
* `MetadataRenderer` can now be configured to render metadata as soon as
|
* `MetadataRenderer` can now be configured to render metadata as soon as
|
||||||
they are available. Create an instance with
|
they are available. Create an instance with
|
||||||
|
@ -435,6 +435,16 @@ public interface ExoPlayer extends Player {
|
|||||||
* <p>This method is experimental, and will be renamed or removed in a future release.
|
* <p>This method is experimental, and will be renamed or removed in a future release.
|
||||||
*/
|
*/
|
||||||
default void onExperimentalSleepingForOffloadChanged(boolean sleepingForOffload) {}
|
default void onExperimentalSleepingForOffloadChanged(boolean sleepingForOffload) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the value of {@link AudioTrack#isOffloadedPlayback} changes.
|
||||||
|
*
|
||||||
|
* <p>This should not be generally required to be acted upon. But when offload is critical for
|
||||||
|
* efficiency, or audio features (gapless, playback speed), this will let the app know.
|
||||||
|
*
|
||||||
|
* <p>This method is experimental, and will be renamed or removed in a future release.
|
||||||
|
*/
|
||||||
|
default void onExperimentalOffloadedPlayback(boolean offloadedPlayback) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,6 +50,7 @@ import androidx.media3.common.util.ConditionVariable;
|
|||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
|
import androidx.media3.exoplayer.ExoPlayer.AudioOffloadListener;
|
||||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||||
import androidx.media3.exoplayer.audio.AudioProcessor.UnhandledAudioFormatException;
|
import androidx.media3.exoplayer.audio.AudioProcessor.UnhandledAudioFormatException;
|
||||||
import androidx.media3.extractor.AacUtil;
|
import androidx.media3.extractor.AacUtil;
|
||||||
@ -274,6 +275,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
private boolean enableAudioTrackPlaybackParams;
|
private boolean enableAudioTrackPlaybackParams;
|
||||||
private int offloadMode;
|
private int offloadMode;
|
||||||
AudioTrackBufferSizeProvider audioTrackBufferSizeProvider;
|
AudioTrackBufferSizeProvider audioTrackBufferSizeProvider;
|
||||||
|
@Nullable AudioOffloadListener audioOffloadListener;
|
||||||
|
|
||||||
/** Creates a new builder. */
|
/** Creates a new builder. */
|
||||||
public Builder() {
|
public Builder() {
|
||||||
@ -379,6 +381,19 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an optional {@link AudioOffloadListener} to receive events relevant to offloaded
|
||||||
|
* playback.
|
||||||
|
*
|
||||||
|
* <p>The default value is null.
|
||||||
|
*/
|
||||||
|
@CanIgnoreReturnValue
|
||||||
|
public Builder setExperimentalAudioOffloadListener(
|
||||||
|
@Nullable AudioOffloadListener audioOffloadListener) {
|
||||||
|
this.audioOffloadListener = audioOffloadListener;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/** Builds the {@link DefaultAudioSink}. Must only be called once per Builder instance. */
|
/** Builds the {@link DefaultAudioSink}. Must only be called once per Builder instance. */
|
||||||
public DefaultAudioSink build() {
|
public DefaultAudioSink build() {
|
||||||
if (audioProcessorChain == null) {
|
if (audioProcessorChain == null) {
|
||||||
@ -509,6 +524,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
initializationExceptionPendingExceptionHolder;
|
initializationExceptionPendingExceptionHolder;
|
||||||
private final PendingExceptionHolder<WriteException> writeExceptionPendingExceptionHolder;
|
private final PendingExceptionHolder<WriteException> writeExceptionPendingExceptionHolder;
|
||||||
private final AudioTrackBufferSizeProvider audioTrackBufferSizeProvider;
|
private final AudioTrackBufferSizeProvider audioTrackBufferSizeProvider;
|
||||||
|
@Nullable private final AudioOffloadListener audioOffloadListener;
|
||||||
|
|
||||||
@Nullable private PlayerId playerId;
|
@Nullable private PlayerId playerId;
|
||||||
@Nullable private Listener listener;
|
@Nullable private Listener listener;
|
||||||
@ -669,6 +685,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS);
|
new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS);
|
||||||
writeExceptionPendingExceptionHolder =
|
writeExceptionPendingExceptionHolder =
|
||||||
new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS);
|
new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS);
|
||||||
|
audioOffloadListener = builder.audioOffloadListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioSink implementation.
|
// AudioSink implementation.
|
||||||
@ -1096,7 +1113,12 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
|
|
||||||
private AudioTrack buildAudioTrack(Configuration configuration) throws InitializationException {
|
private AudioTrack buildAudioTrack(Configuration configuration) throws InitializationException {
|
||||||
try {
|
try {
|
||||||
return configuration.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
|
AudioTrack audioTrack =
|
||||||
|
configuration.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
|
||||||
|
if (audioOffloadListener != null) {
|
||||||
|
audioOffloadListener.onExperimentalOffloadedPlayback(isOffloadedPlayback(audioTrack));
|
||||||
|
}
|
||||||
|
return audioTrack;
|
||||||
} catch (InitializationException e) {
|
} catch (InitializationException e) {
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onAudioSinkError(e);
|
listener.onAudioSinkError(e);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user