mirror of
https://github.com/samsonjs/media.git
synced 2026-03-25 09:25:53 +00:00
Add performance test for composition previewing
PiperOrigin-RevId: 576509031
This commit is contained in:
parent
e91ce868ad
commit
3204da41fe
2 changed files with 109 additions and 67 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue