diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/PerformanceTestListener.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/PerformanceTestListener.java new file mode 100644 index 0000000000..a89fbe0cfc --- /dev/null +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/PerformanceTestListener.java @@ -0,0 +1,107 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.transformer.mh.performance; + +import android.os.ConditionVariable; +import androidx.annotation.Nullable; +import androidx.media3.common.PlaybackException; +import androidx.media3.common.Player; +import androidx.media3.common.util.NullableType; +import androidx.media3.exoplayer.DecoderCounters; +import androidx.media3.exoplayer.analytics.AnalyticsListener; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +/** A listener for testing previewing performance. */ +/* package */ class PerformanceTestListener implements Player.Listener, AnalyticsListener { + + private final ConditionVariable playerReady; + private final ConditionVariable playerEnded; + private final AtomicReference<@NullableType PlaybackException> playbackException; + private final long testTimeoutMs; + private @MonotonicNonNull DecoderCounters decoderCounters; + + /** + * Creates a new instance. + * + * @param testTimeoutMs The timeout value in milliseconds for which {@link + * #waitUntilPlayerReady()} and {@link #waitUntilPlayerEnded()} waits. + */ + public PerformanceTestListener(long testTimeoutMs) { + playerReady = new ConditionVariable(); + playerEnded = new ConditionVariable(); + playbackException = new AtomicReference<>(); + this.testTimeoutMs = testTimeoutMs; + } + + /** Waits until the {@link Player player} is {@linkplain Player#STATE_READY ready}. */ + public void waitUntilPlayerReady() throws TimeoutException, PlaybackException { + waitOrThrow(playerReady); + } + + /** Waits until the {@link Player player} is {@linkplain Player#STATE_ENDED ended}. */ + public void waitUntilPlayerEnded() throws PlaybackException, TimeoutException { + waitOrThrow(playerEnded); + } + + /** + * Returns the {@link DecoderCounters} from {@link AnalyticsListener#onVideoEnabled(EventTime, + * DecoderCounters)}, {@code null} if not available. + */ + @Nullable + public DecoderCounters getDecoderCounters() { + return decoderCounters; + } + + // Player.Listener methods + + @Override + public void onPlaybackStateChanged(int playbackState) { + if (playbackState == Player.STATE_READY) { + playerReady.open(); + } else if (playbackState == Player.STATE_ENDED) { + playerEnded.open(); + } + } + + @Override + public void onPlayerError(PlaybackException error) { + playbackException.set(error); + playerReady.open(); + playerEnded.open(); + } + + // AnalyticsListener methods + + @Override + public void onVideoEnabled(EventTime eventTime, DecoderCounters decoderCounters) { + this.decoderCounters = decoderCounters; + } + + // Internal methods + + private void waitOrThrow(ConditionVariable conditionVariable) + throws TimeoutException, PlaybackException { + if (!conditionVariable.block(testTimeoutMs)) { + throw new TimeoutException(); + } + @Nullable PlaybackException playbackException = this.playbackException.get(); + if (playbackException != null) { + throw playbackException; + } + } +} diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/VideoEffectsPreviewPerformanceTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/VideoEffectsPreviewPerformanceTest.java index 15c67810ee..0f9beeeee4 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/VideoEffectsPreviewPerformanceTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/mh/performance/VideoEffectsPreviewPerformanceTest.java @@ -21,17 +21,12 @@ import static com.google.common.truth.Truth.assertThat; import android.app.Instrumentation; import android.graphics.SurfaceTexture; -import android.os.ConditionVariable; import android.os.SystemClock; import android.view.Surface; -import androidx.annotation.Nullable; import androidx.media3.common.MediaItem; import androidx.media3.common.PlaybackException; -import androidx.media3.common.Player; -import androidx.media3.common.util.NullableType; import androidx.media3.exoplayer.DecoderCounters; import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.analytics.AnalyticsListener; import androidx.media3.exoplayer.util.EventLogger; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -40,7 +35,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.junit.After; import org.junit.Test; @@ -72,7 +66,7 @@ public class VideoEffectsPreviewPerformanceTest { */ @Test public void exoplayerEffectsPreviewTest() throws PlaybackException, TimeoutException { - TestListener listener = new TestListener(); + PerformanceTestListener listener = new PerformanceTestListener(TEST_TIMEOUT_MS); instrumentation.runOnMainSync( () -> { player = new ExoPlayer.Builder(ApplicationProvider.getApplicationContext()).build(); @@ -106,7 +100,7 @@ public class VideoEffectsPreviewPerformanceTest { // Playback realtime should take 2 seconds, plus/minus error margin. assertThat(playbackDurationMs).isIn(Range.closed(1950L, 2050L)); - DecoderCounters decoderCounters = checkNotNull(listener.decoderCounters); + DecoderCounters decoderCounters = checkNotNull(listener.getDecoderCounters()); assertThat(decoderCounters.droppedBufferCount).isEqualTo(0); assertThat(decoderCounters.skippedInputBufferCount).isEqualTo(0); assertThat(decoderCounters.skippedOutputBufferCount).isEqualTo(0); @@ -121,63 +115,4 @@ public class VideoEffectsPreviewPerformanceTest { .build()) .build(); } - - private static class TestListener implements Player.Listener, AnalyticsListener { - private final ConditionVariable playerReady; - private final ConditionVariable playerEnded; - private final AtomicReference<@NullableType PlaybackException> playbackException; - private @MonotonicNonNull DecoderCounters decoderCounters; - - public TestListener() { - playerReady = new ConditionVariable(); - playerEnded = new ConditionVariable(); - playbackException = new AtomicReference<>(); - } - - public void waitUntilPlayerReady() throws TimeoutException, PlaybackException { - waitOrThrow(playerReady); - } - - public void waitUntilPlayerEnded() throws PlaybackException, TimeoutException { - waitOrThrow(playerEnded); - } - - // Player.Listener methods - - @Override - public void onPlaybackStateChanged(int playbackState) { - if (playbackState == Player.STATE_READY) { - playerReady.open(); - } else if (playbackState == Player.STATE_ENDED) { - playerEnded.open(); - } - } - - @Override - public void onPlayerError(PlaybackException error) { - playbackException.set(error); - playerReady.open(); - playerEnded.open(); - } - - // AnalyticsListener methods - - @Override - public void onVideoEnabled(EventTime eventTime, DecoderCounters decoderCounters) { - this.decoderCounters = decoderCounters; - } - - // Internal methods - - private void waitOrThrow(ConditionVariable conditionVariable) - throws TimeoutException, PlaybackException { - if (!conditionVariable.block(TEST_TIMEOUT_MS)) { - throw new TimeoutException(); - } - @Nullable PlaybackException playbackException = this.playbackException.get(); - if (playbackException != null) { - throw playbackException; - } - } - } }