From 7dee3aec511686d8c6bcd0da000ed5ce672537cc Mon Sep 17 00:00:00 2001 From: claincly Date: Wed, 30 Nov 2022 18:38:45 +0000 Subject: [PATCH] Add function to clear the cached list of encoders EncoderUtil using a static list to cache encoders means it's not possible to use a different set of encoders for different tests when running all robolectric tests together. PiperOrigin-RevId: 491959350 --- .../media3/transformer/EncoderUtil.java | 38 +++++++++++-------- .../DefaultEncoderFactoryTest.java | 9 +++++ .../media3/transformer/EncoderUtilTest.java | 9 +++++ .../transformer/TransformerEndToEndTest.java | 2 + .../transformer/VideoEncoderWrapperTest.java | 9 +++++ 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/EncoderUtil.java b/libraries/transformer/src/main/java/androidx/media3/transformer/EncoderUtil.java index 169a4cb3ac..a957873b0b 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/EncoderUtil.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/EncoderUtil.java @@ -16,7 +16,6 @@ package androidx.media3.transformer; -import static androidx.media3.common.util.Assertions.checkNotNull; import static java.lang.Math.max; import static java.lang.Math.round; @@ -29,8 +28,10 @@ import android.util.Pair; import android.util.Range; import android.util.Size; import androidx.annotation.DoNotInline; +import androidx.annotation.GuardedBy; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; +import androidx.annotation.VisibleForTesting; import androidx.media3.common.C; import androidx.media3.common.C.ColorTransfer; import androidx.media3.common.ColorInfo; @@ -40,10 +41,8 @@ import androidx.media3.common.util.MediaFormatUtil; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import com.google.common.base.Ascii; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.primitives.Ints; @@ -54,20 +53,29 @@ public final class EncoderUtil { /** A value to indicate the encoding level is not set. */ public static final int LEVEL_UNSET = Format.NO_VALUE; - private static final Supplier> - MIME_TYPE_TO_ENCODERS = Suppliers.memoize(EncoderUtil::populateEncoderInfos); + @GuardedBy("EncoderUtil.class") + private static final ArrayListMultimap mimeTypeToEncoders = + ArrayListMultimap.create(); /** * Returns a list of {@linkplain MediaCodecInfo encoders} that support the given {@code mimeType}, * or an empty list if there is none. */ - public static ImmutableList getSupportedEncoders(String mimeType) { - return checkNotNull(MIME_TYPE_TO_ENCODERS.get()).get(Ascii.toLowerCase(mimeType)); + public static synchronized ImmutableList getSupportedEncoders(String mimeType) { + maybePopulateEncoderInfo(); + return ImmutableList.copyOf(mimeTypeToEncoders.get(Ascii.toLowerCase(mimeType))); } /** Returns a list of video {@linkplain MimeTypes MIME types} that can be encoded. */ - public static ImmutableSet getSupportedVideoMimeTypes() { - return checkNotNull(MIME_TYPE_TO_ENCODERS.get()).keySet(); + public static synchronized ImmutableSet getSupportedVideoMimeTypes() { + maybePopulateEncoderInfo(); + return ImmutableSet.copyOf(mimeTypeToEncoders.keySet()); + } + + /** Clears the cached list of encoders. */ + @VisibleForTesting + public static synchronized void clearCachedEncoders() { + mimeTypeToEncoders.clear(); } /** @@ -433,9 +441,10 @@ public final class EncoderUtil { : alignment * Math.round((float) size / alignment); } - private static ImmutableListMultimap populateEncoderInfos() { - ImmutableListMultimap.Builder encoderInfosBuilder = - new ImmutableListMultimap.Builder<>(); + private static synchronized void maybePopulateEncoderInfo() { + if (!mimeTypeToEncoders.isEmpty()) { + return; + } MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); MediaCodecInfo[] allCodecInfos = mediaCodecList.getCodecInfos(); @@ -446,10 +455,9 @@ public final class EncoderUtil { } String[] supportedMimeTypes = mediaCodecInfo.getSupportedTypes(); for (String mimeType : supportedMimeTypes) { - encoderInfosBuilder.put(Ascii.toLowerCase(mimeType), mediaCodecInfo); + mimeTypeToEncoders.put(Ascii.toLowerCase(mimeType), mediaCodecInfo); } } - return encoderInfosBuilder.build(); } @RequiresApi(29) diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/DefaultEncoderFactoryTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/DefaultEncoderFactoryTest.java index c4d192f4a0..cb6d3dfb3d 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/DefaultEncoderFactoryTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/DefaultEncoderFactoryTest.java @@ -28,11 +28,13 @@ import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import org.robolectric.shadows.MediaCodecInfoBuilder; +import org.robolectric.shadows.ShadowMediaCodec; import org.robolectric.shadows.ShadowMediaCodecList; /** Unit test for {@link DefaultEncoderFactory}. */ @@ -45,6 +47,13 @@ public class DefaultEncoderFactoryTest { createShadowH264Encoder(); } + @After + public void tearDown() { + ShadowMediaCodec.clearCodecs(); + ShadowMediaCodecList.reset(); + EncoderUtil.clearCachedEncoders(); + } + private static void createShadowH264Encoder() { MediaFormat avcFormat = new MediaFormat(); avcFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC); diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/EncoderUtilTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/EncoderUtilTest.java index e844a7319c..91fadb79d8 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/EncoderUtilTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/EncoderUtilTest.java @@ -27,11 +27,13 @@ import androidx.media3.common.ColorInfo; import androidx.media3.common.MimeTypes; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import org.robolectric.shadows.MediaCodecInfoBuilder; +import org.robolectric.shadows.ShadowMediaCodec; import org.robolectric.shadows.ShadowMediaCodecList; /** Unit test for {@link EncoderUtil}. */ @@ -64,6 +66,13 @@ public class EncoderUtilTest { .build()); } + @After + public void tearDown() { + ShadowMediaCodecList.reset(); + ShadowMediaCodec.clearCodecs(); + EncoderUtil.clearCachedEncoders(); + } + @Test public void getSupportedResolution_withSupportedResolution_succeeds() { ImmutableList supportedEncoders = EncoderUtil.getSupportedEncoders(MIME_TYPE); diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java index 0e9c9d5d90..3a2be95566 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java @@ -898,6 +898,8 @@ public final class TransformerEndToEndTest { private static void removeEncodersAndDecoders() { ShadowMediaCodec.clearCodecs(); + ShadowMediaCodecList.reset(); + EncoderUtil.clearCachedEncoders(); } private static String getDumpFileName(String originalFileName) { diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/VideoEncoderWrapperTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/VideoEncoderWrapperTest.java index 551e3e91cb..93904d6043 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/VideoEncoderWrapperTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/VideoEncoderWrapperTest.java @@ -32,10 +32,12 @@ import androidx.media3.common.util.Clock; import androidx.media3.common.util.ListenerSet; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.common.collect.ImmutableList; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.shadows.MediaCodecInfoBuilder; +import org.robolectric.shadows.ShadowMediaCodec; import org.robolectric.shadows.ShadowMediaCodecList; /** Unit tests for {@link VideoTranscodingSamplePipeline.EncoderWrapper}. */ @@ -63,6 +65,13 @@ public final class VideoEncoderWrapperTest { createShadowH264Encoder(); } + @After + public void tearDown() { + ShadowMediaCodec.clearCodecs(); + ShadowMediaCodecList.reset(); + EncoderUtil.clearCachedEncoders(); + } + @Test public void getSurfaceInfo_landscape_leavesOrientationUnchanged() throws Exception { int inputWidth = 200;