Add frame extractor tests for decoder counters.

Right now, decoders produce an unspecified (but large)
number of frames. This will be resolved in a follow-up

PiperOrigin-RevId: 697945076
This commit is contained in:
dancho 2024-11-19 03:06:28 -08:00 committed by Copybara-Service
parent c7ca9fbe7d
commit 26f10effc2
2 changed files with 57 additions and 0 deletions

View File

@ -28,10 +28,12 @@ import static org.junit.Assert.assertThrows;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.NullableType;
import androidx.media3.effect.Presentation;
import androidx.media3.exoplayer.DecoderCounters;
import androidx.media3.exoplayer.ExoPlaybackException;
import androidx.media3.transformer.ExperimentalFrameExtractor.Frame;
import androidx.test.core.app.ApplicationProvider;
@ -106,6 +108,12 @@ public class FrameExtractorTest {
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(4);
}
@Test
@ -128,6 +136,12 @@ public class FrameExtractorTest {
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(4);
}
@Test
@ -151,6 +165,12 @@ public class FrameExtractorTest {
assertThat(frame.presentationTimeMs).isEqualTo(lastVideoFramePresentationTimeMs);
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(3);
}
@Test
@ -182,6 +202,14 @@ public class FrameExtractorTest {
assertBitmapsAreSimilar(expectedBitmap, frame.bitmap, PSNR_THRESHOLD);
assertThat(frame.presentationTimeMs).isEqualTo(expectedFramePositionsMs.get(i));
}
// TODO: b/350498258 - some decoders break right after extracting all the frames for this test.
// Fix and remove this hack.
@Nullable
DecoderCounters decoderCounters =
frameExtractor.getDecoderCounters().get(TIMEOUT_SECONDS, SECONDS);
if (decoderCounters != null) {
assertThat(decoderCounters.renderedOutputBufferCount).isAtLeast(7);
}
}
@Test
@ -204,6 +232,12 @@ public class FrameExtractorTest {
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(7_031);
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(2_032);
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_031);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(10);
}
@Test
@ -230,6 +264,12 @@ public class FrameExtractorTest {
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(0);
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(8);
}
@Test
@ -284,6 +324,12 @@ public class FrameExtractorTest {
assertThat(throwableAtomicReference.get()).isNull();
assertThat(frameAtomicReference.get().presentationTimeMs).isEqualTo(0);
assertThat(
frameExtractor
.getDecoderCounters()
.get(TIMEOUT_SECONDS, SECONDS)
.renderedOutputBufferCount)
.isAtLeast(1);
}
@Test

View File

@ -30,6 +30,7 @@ import android.opengl.GLES20;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.Effect;
import androidx.media3.common.GlObjectsProvider;
import androidx.media3.common.GlTextureInfo;
@ -43,6 +44,7 @@ import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlShaderProgram;
import androidx.media3.effect.MatrixTransformation;
import androidx.media3.effect.PassthroughShaderProgram;
import androidx.media3.exoplayer.DecoderCounters;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.SeekParameters;
import androidx.media3.exoplayer.analytics.AnalyticsListener;
@ -275,6 +277,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
}
@VisibleForTesting
/* package */ ListenableFuture<@NullableType DecoderCounters> getDecoderCounters() {
SettableFuture<@NullableType DecoderCounters> decoderCountersSettableFuture =
SettableFuture.create();
playerApplicationThreadHandler.post(
() -> decoderCountersSettableFuture.set(player.getVideoDecoderCounters()));
return decoderCountersSettableFuture;
}
private ImmutableList<Effect> buildVideoEffects(List<Effect> effects) {
ImmutableList.Builder<Effect> listBuilder = new ImmutableList.Builder<>();
listBuilder.addAll(effects);