mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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:
parent
c7ca9fbe7d
commit
26f10effc2
@ -28,10 +28,12 @@ import static org.junit.Assert.assertThrows;
|
|||||||
import android.app.Instrumentation;
|
import android.app.Instrumentation;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.util.ConditionVariable;
|
import androidx.media3.common.util.ConditionVariable;
|
||||||
import androidx.media3.common.util.NullableType;
|
import androidx.media3.common.util.NullableType;
|
||||||
import androidx.media3.effect.Presentation;
|
import androidx.media3.effect.Presentation;
|
||||||
|
import androidx.media3.exoplayer.DecoderCounters;
|
||||||
import androidx.media3.exoplayer.ExoPlaybackException;
|
import androidx.media3.exoplayer.ExoPlaybackException;
|
||||||
import androidx.media3.transformer.ExperimentalFrameExtractor.Frame;
|
import androidx.media3.transformer.ExperimentalFrameExtractor.Frame;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
@ -106,6 +108,12 @@ public class FrameExtractorTest {
|
|||||||
|
|
||||||
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
|
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
|
||||||
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -128,6 +136,12 @@ public class FrameExtractorTest {
|
|||||||
|
|
||||||
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
|
assertThat(frame.presentationTimeMs).isEqualTo(8_531);
|
||||||
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -151,6 +165,12 @@ public class FrameExtractorTest {
|
|||||||
|
|
||||||
assertThat(frame.presentationTimeMs).isEqualTo(lastVideoFramePresentationTimeMs);
|
assertThat(frame.presentationTimeMs).isEqualTo(lastVideoFramePresentationTimeMs);
|
||||||
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
assertBitmapsAreSimilar(expectedBitmap, actualBitmap, PSNR_THRESHOLD);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -182,6 +202,14 @@ public class FrameExtractorTest {
|
|||||||
assertBitmapsAreSimilar(expectedBitmap, frame.bitmap, PSNR_THRESHOLD);
|
assertBitmapsAreSimilar(expectedBitmap, frame.bitmap, PSNR_THRESHOLD);
|
||||||
assertThat(frame.presentationTimeMs).isEqualTo(expectedFramePositionsMs.get(i));
|
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
|
@Test
|
||||||
@ -204,6 +232,12 @@ public class FrameExtractorTest {
|
|||||||
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(7_031);
|
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(7_031);
|
||||||
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(2_032);
|
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(2_032);
|
||||||
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_031);
|
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_031);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -230,6 +264,12 @@ public class FrameExtractorTest {
|
|||||||
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
|
assertThat(frame7.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
|
||||||
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(0);
|
assertThat(frame2.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(0);
|
||||||
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
|
assertThat(frame8.get(TIMEOUT_SECONDS, SECONDS).presentationTimeMs).isEqualTo(8_331);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -284,6 +324,12 @@ public class FrameExtractorTest {
|
|||||||
|
|
||||||
assertThat(throwableAtomicReference.get()).isNull();
|
assertThat(throwableAtomicReference.get()).isNull();
|
||||||
assertThat(frameAtomicReference.get().presentationTimeMs).isEqualTo(0);
|
assertThat(frameAtomicReference.get().presentationTimeMs).isEqualTo(0);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.renderedOutputBufferCount)
|
||||||
|
.isAtLeast(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -30,6 +30,7 @@ import android.opengl.GLES20;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
@ -43,6 +44,7 @@ import androidx.media3.effect.GlEffect;
|
|||||||
import androidx.media3.effect.GlShaderProgram;
|
import androidx.media3.effect.GlShaderProgram;
|
||||||
import androidx.media3.effect.MatrixTransformation;
|
import androidx.media3.effect.MatrixTransformation;
|
||||||
import androidx.media3.effect.PassthroughShaderProgram;
|
import androidx.media3.effect.PassthroughShaderProgram;
|
||||||
|
import androidx.media3.exoplayer.DecoderCounters;
|
||||||
import androidx.media3.exoplayer.ExoPlayer;
|
import androidx.media3.exoplayer.ExoPlayer;
|
||||||
import androidx.media3.exoplayer.SeekParameters;
|
import androidx.media3.exoplayer.SeekParameters;
|
||||||
import androidx.media3.exoplayer.analytics.AnalyticsListener;
|
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) {
|
private ImmutableList<Effect> buildVideoEffects(List<Effect> effects) {
|
||||||
ImmutableList.Builder<Effect> listBuilder = new ImmutableList.Builder<>();
|
ImmutableList.Builder<Effect> listBuilder = new ImmutableList.Builder<>();
|
||||||
listBuilder.addAll(effects);
|
listBuilder.addAll(effects);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user