From d69572eb650fca4298dfc75cc531b01979e696dd Mon Sep 17 00:00:00 2001 From: bachinger Date: Thu, 27 Feb 2020 15:21:52 +0000 Subject: [PATCH] notify AudioListener about changes of skipSilenceEnabled This change adds the callback onSkipSilenceEnabledChange to the AudioListener and calls it when changed by the user by calling setPlaybackParameters, or when changed internally by the DefaultAudioSink if the parameters are not applicable. It needs to be plumped through AudioSink, AudioRenderer to SEP which eventually calls the AudioListener. No changes to the Player interface so far. The getter of skipSilenceEnabled is added to SimpleExoPlayer for completeness, but not yet to the Player interface. The setter is not yet exposed, but implemented as a private method for implementation reasons. PiperOrigin-RevId: 297590291 --- .../android/exoplayer2/SimpleExoPlayer.java | 30 +++++++++++++++++++ .../analytics/AnalyticsCollector.java | 8 +++++ .../analytics/AnalyticsListener.java | 8 +++++ .../exoplayer2/audio/AudioListener.java | 7 +++++ .../audio/AudioRendererEventListener.java | 14 ++++++++- .../android/exoplayer2/audio/AudioSink.java | 6 ++++ .../exoplayer2/audio/DefaultAudioSink.java | 17 ++++------- .../audio/MediaCodecAudioRenderer.java | 25 +++++++++------- .../audio/SimpleDecoderAudioRenderer.java | 25 +++++++++------- .../android/exoplayer2/util/EventLogger.java | 5 ++++ 10 files changed, 112 insertions(+), 33 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java index 85d380309b..a91e22b124 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java @@ -334,6 +334,7 @@ public class SimpleExoPlayer extends BasePlayer private int audioSessionId; private AudioAttributes audioAttributes; private float audioVolume; + private boolean skipSilenceEnabled; private List currentCues; @Nullable private VideoFrameMetadataListener videoFrameMetadataListener; @Nullable private CameraMotionListener cameraMotionListener; @@ -929,6 +930,11 @@ public class SimpleExoPlayer extends BasePlayer } } + /** Returns whether skipping silences in the audio stream is enabled. */ + public boolean isSkipSilenceEnabled() { + return skipSilenceEnabled; + } + /** * Sets a listener to receive video events, removing all existing listeners. * @@ -1347,6 +1353,7 @@ public class SimpleExoPlayer extends BasePlayer @Override public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) { verifyApplicationThread(); + setSkipSilenceEnabled(playbackParameters != null && playbackParameters.skipSilence); player.setPlaybackParameters(playbackParameters); } @@ -1659,6 +1666,24 @@ public class SimpleExoPlayer extends BasePlayer : PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST; } + @SuppressWarnings("SuspiciousMethodCalls") + private void setSkipSilenceEnabled(boolean skipSilenceEnabled) { + if (this.skipSilenceEnabled == skipSilenceEnabled) { + return; + } + this.skipSilenceEnabled = skipSilenceEnabled; + for (AudioListener listener : audioListeners) { + // Prevent duplicate notification if a listener is both a AudioRendererEventListener and + // a AudioListener, as they have the same method signature. + if (!audioDebugListeners.contains(listener)) { + listener.onSkipSilenceEnabledChanged(skipSilenceEnabled); + } + } + for (AudioRendererEventListener listener : audioDebugListeners) { + listener.onSkipSilenceEnabledChanged(skipSilenceEnabled); + } + } + private final class ComponentListener implements VideoRendererEventListener, AudioRendererEventListener, @@ -1814,6 +1839,11 @@ public class SimpleExoPlayer extends BasePlayer audioSessionId = C.AUDIO_SESSION_ID_UNSET; } + @Override + public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { + setSkipSilenceEnabled(skipSilenceEnabled); + } + // TextOutput implementation @Override diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java index 90b35ad459..71a369e3ca 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsCollector.java @@ -220,6 +220,14 @@ public class AnalyticsCollector } } + @Override + public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { + EventTime eventTime = generateReadingMediaPeriodEventTime(); + for (AnalyticsListener listener : listeners) { + listener.onSkipSilenceEnabledChanged(eventTime, skipSilenceEnabled); + } + } + @Override public void onVolumeChanged(float audioVolume) { EventTime eventTime = generateReadingMediaPeriodEventTime(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java index a6173787f1..fbaa6a9781 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/analytics/AnalyticsListener.java @@ -450,6 +450,14 @@ public interface AnalyticsListener { default void onAudioUnderrun( EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {} + /** + * Called when skipping silences is enabled or disabled in the audio stream. + * + * @param eventTime The event time. + * @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled. + */ + default void onSkipSilenceEnabledChanged(EventTime eventTime, boolean skipSilenceEnabled) {} + /** * Called after video frames have been dropped. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioListener.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioListener.java index 8ce365b283..f208f602e1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioListener.java @@ -38,4 +38,11 @@ public interface AudioListener { * @param volume The new volume, with 0 being silence and 1 being unity gain. */ default void onVolumeChanged(float volume) {} + + /** + * Called when skipping silences is enabled or disabled in the audio stream. + * + * @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled. + */ + default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {} } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java index bf5822caf6..7cb05cfa0d 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioRendererEventListener.java @@ -85,8 +85,13 @@ public interface AudioRendererEventListener { default void onAudioDisabled(DecoderCounters counters) {} /** - * Dispatches events to a {@link AudioRendererEventListener}. + * Called when skipping silences is enabled or disabled in the audio stream. + * + * @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled. */ + default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {} + + /** Dispatches events to a {@link AudioRendererEventListener}. */ final class EventDispatcher { @Nullable private final Handler handler; @@ -170,5 +175,12 @@ public interface AudioRendererEventListener { handler.post(() -> castNonNull(listener).onAudioSessionId(audioSessionId)); } } + + /** Invokes {@link AudioRendererEventListener#onSkipSilenceEnabledChanged(boolean)}. */ + public void skipSilenceEnabledChanged(final boolean skipSilenceEnabled) { + if (handler != null) { + handler.post(() -> castNonNull(listener).onSkipSilenceEnabledChanged(skipSilenceEnabled)); + } + } } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java index c03ad0f4af..477b1fd1c1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java @@ -84,6 +84,12 @@ public interface AudioSink { */ void onUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs); + /** + * Called when skipping silences is enabled or disabled. + * + * @param skipSilenceEnabled Whether skipping silences is enabled. + */ + void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled); } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java index d4b2b9b874..3482cbe9b6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java @@ -884,9 +884,6 @@ public final class DefaultAudioSink implements AudioSink { @Override public void setPlaybackSpeed(float playbackSpeed) { - if (configuration != null && !configuration.canApplyPlaybackParameters) { - playbackSpeed = DEFAULT_PLAYBACK_SPEED; - } setPlaybackSpeedAndSkipSilence(playbackSpeed, getSkipSilenceEnabled()); } @@ -897,9 +894,6 @@ public final class DefaultAudioSink implements AudioSink { @Override public void setSkipSilenceEnabled(boolean skipSilenceEnabled) { - if (configuration != null && !configuration.canApplyPlaybackParameters) { - skipSilenceEnabled = DEFAULT_SKIP_SILENCE; - } setPlaybackSpeedAndSkipSilence(getPlaybackSpeed(), skipSilenceEnabled); } @@ -1080,10 +1074,6 @@ public final class DefaultAudioSink implements AudioSink { } private void setPlaybackSpeedAndSkipSilence(float playbackSpeed, boolean skipSilence) { - if (configuration != null && !configuration.canApplyPlaybackParameters) { - playbackSpeed = DEFAULT_PLAYBACK_SPEED; - skipSilence = DEFAULT_SKIP_SILENCE; - } MediaPositionParameters currentMediaPositionParameters = getMediaPositionParameters(); if (playbackSpeed != currentMediaPositionParameters.playbackSpeed || skipSilence != currentMediaPositionParameters.skipSilence) { @@ -1119,17 +1109,20 @@ public final class DefaultAudioSink implements AudioSink { configuration.canApplyPlaybackParameters ? audioProcessorChain.applyPlaybackSpeed(getPlaybackSpeed()) : DEFAULT_PLAYBACK_SPEED; - boolean skipSilence = + boolean skipSilenceEnabled = configuration.canApplyPlaybackParameters ? audioProcessorChain.applySkipSilenceEnabled(getSkipSilenceEnabled()) : DEFAULT_SKIP_SILENCE; mediaPositionParametersCheckpoints.add( new MediaPositionParameters( playbackSpeed, - skipSilence, + skipSilenceEnabled, /* mediaTimeUs= */ Math.max(0, presentationTimeUs), /* audioTrackPositionUs= */ configuration.framesToDurationUs(getWrittenFrames()))); setupAudioProcessors(); + if (listener != null) { + listener.onSkipSilenceEnabledChanged(skipSilenceEnabled); + } } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java index 8c496e4ffd..0448c60a5f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java @@ -469,24 +469,25 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media * order to spatialize the audio channels. For this use case, any {@link Virtualizer} instances * should be released in {@link #onDisabled()} (if not before). * - * @see AudioSink.Listener#onAudioSessionId(int) + *

See {@link AudioSink.Listener#onAudioSessionId(int)}. */ protected void onAudioSessionId(int audioSessionId) { // Do nothing. } - /** - * @see AudioSink.Listener#onPositionDiscontinuity() - */ + /** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */ protected void onAudioTrackPositionDiscontinuity() { // Do nothing. } - /** - * @see AudioSink.Listener#onUnderrun(int, long, long) - */ - protected void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, - long elapsedSinceLastFeedMs) { + /** See {@link AudioSink.Listener#onUnderrun(int, long, long)}. */ + protected void onAudioTrackUnderrun( + int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { + // Do nothing. + } + + /** See {@link AudioSink.Listener#onSkipSilenceEnabledChanged(boolean)}. */ + protected void onAudioTrackSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { // Do nothing. } @@ -843,6 +844,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs); } + @Override + public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { + eventDispatcher.skipSilenceEnabledChanged(skipSilenceEnabled); + onAudioTrackSkipSilenceEnabledChanged(skipSilenceEnabled); + } } - } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java index 7da3ac9c6e..ee812138fe 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java @@ -270,24 +270,25 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements * order to spatialize the audio channels. For this use case, any {@link Virtualizer} instances * should be released in {@link #onDisabled()} (if not before). * - * @see AudioSink.Listener#onAudioSessionId(int) + *

See {@link AudioSink.Listener#onAudioSessionId(int)}. */ protected void onAudioSessionId(int audioSessionId) { // Do nothing. } - /** - * @see AudioSink.Listener#onPositionDiscontinuity() - */ + /** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */ protected void onAudioTrackPositionDiscontinuity() { // Do nothing. } - /** - * @see AudioSink.Listener#onUnderrun(int, long, long) - */ - protected void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs, - long elapsedSinceLastFeedMs) { + /** See {@link AudioSink.Listener#onUnderrun(int, long, long)}. */ + protected void onAudioTrackUnderrun( + int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { + // Do nothing. + } + + /** See {@link AudioSink.Listener#onSkipSilenceEnabledChanged(boolean)}. */ + protected void onAudioTrackSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { // Do nothing. } @@ -693,6 +694,10 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs); } + @Override + public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) { + eventDispatcher.skipSilenceEnabledChanged(skipSilenceEnabled); + onAudioTrackSkipSilenceEnabledChanged(skipSilenceEnabled); + } } - } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java b/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java index 99dde4fabf..b2e15d69e4 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java @@ -319,6 +319,11 @@ public class EventLogger implements AnalyticsListener { + audioAttributes.allowedCapturePolicy); } + @Override + public void onSkipSilenceEnabledChanged(EventTime eventTime, boolean skipSilenceEnabled) { + logd(eventTime, "skipSilenceEnabled", Boolean.toString(skipSilenceEnabled)); + } + @Override public void onVolumeChanged(EventTime eventTime, float volume) { logd(eventTime, "volume", Float.toString(volume));