From 39e572ad6d142a9899cd7036e07dffcb3eac892b Mon Sep 17 00:00:00 2001 From: claincly Date: Fri, 7 Jun 2024 05:56:46 -0700 Subject: [PATCH] Fix a concurrency issue that shader capacity is set off GL thread Also add test to cover transitions between BT709 and 601. PiperOrigin-RevId: 641224971 --- .../media3/effect/ExternalTextureManager.java | 7 +- .../src/test/assets/media/mp4/bt601.mp4 | Bin 0 -> 24814 bytes .../media3/transformer/AndroidTestUtil.java | 23 ++- .../TransformerMixedInputEndToEndTest.java | 167 ++++++++++++++++-- .../TransformerSequenceEffectTest.java | 22 +-- 5 files changed, 187 insertions(+), 32 deletions(-) create mode 100644 libraries/test_data/src/test/assets/media/mp4/bt601.mp4 diff --git a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java index c6ecd4ed98..e15d785b24 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java @@ -191,8 +191,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public void setSamplingGlShaderProgram(GlShaderProgram samplingGlShaderProgram) { checkState(samplingGlShaderProgram instanceof ExternalShaderProgram); - externalShaderProgramInputCapacity.set(0); - this.externalShaderProgram = (ExternalShaderProgram) samplingGlShaderProgram; + videoFrameProcessingTaskExecutor.submit( + () -> { + externalShaderProgramInputCapacity.set(0); + this.externalShaderProgram = (ExternalShaderProgram) samplingGlShaderProgram; + }); } @Override diff --git a/libraries/test_data/src/test/assets/media/mp4/bt601.mp4 b/libraries/test_data/src/test/assets/media/mp4/bt601.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..b0db8e591d93b57472dcb487e05d7b5248389c67 GIT binary patch literal 24814 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 X4T6r}KZ2l}MHk`U=Elyhpb!58!C++n literal 0 HcmV?d00001 diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/AndroidTestUtil.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/AndroidTestUtil.java index fe6732ce3e..f76ca3a504 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/AndroidTestUtil.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/AndroidTestUtil.java @@ -103,8 +103,8 @@ public final class AndroidTestUtil { // ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4 public static final int MP4_ASSET_FRAME_COUNT = 30; - public static final String BT601_ASSET_URI_STRING = "asset:///media/mp4/bt601.mov"; - public static final Format BT601_ASSET_FORMAT = + public static final String BT601_MOV_ASSET_URI_STRING = "asset:///media/mp4/bt601.mov"; + public static final Format BT601_MOV_ASSET_FORMAT = new Format.Builder() .setSampleMimeType(VIDEO_H264) .setWidth(640) @@ -119,6 +119,25 @@ public final class AndroidTestUtil { .setCodecs("avc1.4D001E") .build(); + public static final String BT601_MP4_ASSET_URI_STRING = "asset:///media/mp4/bt601.mp4"; + public static final Format BT601_MP4_ASSET_FORMAT = + new Format.Builder() + .setSampleMimeType(VIDEO_H264) + .setWidth(360) + .setHeight(240) + .setFrameRate(29.97f) + .setColorInfo( + new ColorInfo.Builder() + .setColorSpace(C.COLOR_SPACE_BT601) + .setColorRange(C.COLOR_RANGE_LIMITED) + .setColorTransfer(C.COLOR_TRANSFER_SDR) + .build()) + .setCodecs("avc1.42C00D") + .build(); + // Result of the following command for BT601_MP4_ASSET_URI_STRING + // ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames bt601.mp4 + public static final int BT601_MP4_ASSET_FRAME_COUNT = 30; + public static final String MP4_PORTRAIT_ASSET_URI_STRING = "asset:///media/mp4/sample_portrait.mp4"; public static final Format MP4_PORTRAIT_ASSET_FORMAT = diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerMixedInputEndToEndTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerMixedInputEndToEndTest.java index c5a643ad52..2c6ba0d108 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerMixedInputEndToEndTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerMixedInputEndToEndTest.java @@ -17,6 +17,9 @@ package androidx.media3.transformer; +import static androidx.media3.transformer.AndroidTestUtil.BT601_MP4_ASSET_FORMAT; +import static androidx.media3.transformer.AndroidTestUtil.BT601_MP4_ASSET_FRAME_COUNT; +import static androidx.media3.transformer.AndroidTestUtil.BT601_MP4_ASSET_URI_STRING; import static androidx.media3.transformer.AndroidTestUtil.JPG_ASSET_URI_STRING; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_FORMAT; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_FRAME_COUNT; @@ -28,7 +31,10 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.net.Uri; import androidx.media3.common.C; +import androidx.media3.common.ColorInfo; +import androidx.media3.common.Format; import androidx.media3.common.MediaItem; +import androidx.media3.common.MimeTypes; import androidx.media3.common.VideoFrameProcessor; import androidx.media3.effect.Presentation; import androidx.test.core.app.ApplicationProvider; @@ -51,6 +57,16 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class TransformerMixedInputEndToEndTest { + // Image by default are encoded in H265 and BT709 SDR. + private static final Format IMAGE_VIDEO_ENCODING_FORMAT = + new Format.Builder() + .setSampleMimeType(MimeTypes.VIDEO_H265) + .setFrameRate(30.f) + .setWidth(480) + .setHeight(360) + .setColorInfo(ColorInfo.SDR_BT709_LIMITED) + .build(); + private final Context context = ApplicationProvider.getApplicationContext(); @Rule public final TestName testName = new TestName(); @@ -65,7 +81,10 @@ public class TransformerMixedInputEndToEndTest { public void videoEditing_withImageThenVideoInputs_completesWithCorrectFrameCount() throws Exception { assumeFormatsSupported( - context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); + context, + testId, + /* inputFormat= */ MP4_ASSET_FORMAT, + /* outputFormat= */ IMAGE_VIDEO_ENCODING_FORMAT); Transformer transformer = new Transformer.Builder(context) .setEncoderFactory( @@ -116,10 +135,18 @@ public class TransformerMixedInputEndToEndTest { @Test public void - videoEditing_withComplexVideoAndImageInputsEndWithVideo_completesWithCorrectFrameCount() + videoEditing_withComplexMixedColorSpaceSdrVideoAndImageInputsEndWithVideo_completesWithCorrectFrameCount() throws Exception { assumeFormatsSupported( - context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); + context, + testId, + /* inputFormat= */ MP4_ASSET_FORMAT, + /* outputFormat= */ BT601_MP4_ASSET_FORMAT); + assumeFormatsSupported( + context, + testId, + /* inputFormat= */ BT601_MP4_ASSET_FORMAT, + /* outputFormat= */ BT601_MP4_ASSET_FORMAT); Transformer transformer = new Transformer.Builder(context) .setEncoderFactory( @@ -131,7 +158,9 @@ public class TransformerMixedInputEndToEndTest { createImageEditedMediaItem(PNG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); EditedMediaItem imageEditedMediaItem2 = createImageEditedMediaItem(JPG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); - EditedMediaItem videoEditedMediaItem = + EditedMediaItem bt601VideoEditedMediaItem = + createVideoEditedMediaItem(BT601_MP4_ASSET_URI_STRING, /* height= */ 360); + EditedMediaItem bt709VideoEditedMediaItem = createVideoEditedMediaItem(MP4_ASSET_URI_STRING, /* height= */ 360); ExportTestResult result = new TransformerAndroidTestRunner.Builder(context, transformer) @@ -139,25 +168,35 @@ public class TransformerMixedInputEndToEndTest { .run( testId, buildComposition( - videoEditedMediaItem, - videoEditedMediaItem, + bt601VideoEditedMediaItem, + bt709VideoEditedMediaItem, imageEditedMediaItem1, imageEditedMediaItem2, - videoEditedMediaItem, + bt709VideoEditedMediaItem, imageEditedMediaItem1, - videoEditedMediaItem)); + bt601VideoEditedMediaItem)); assertThat(result.exportResult.videoFrameCount) - .isEqualTo(3 * imageFrameCount + 4 * MP4_ASSET_FRAME_COUNT); + .isEqualTo( + 3 * imageFrameCount + 2 * MP4_ASSET_FRAME_COUNT + 2 * BT601_MP4_ASSET_FRAME_COUNT); assertThat(new File(result.filePath).length()).isGreaterThan(0); } @Test public void - videoEditing_withComplexVideoAndImageInputsEndWithImage_completesWithCorrectFrameCount() + videoEditing_withComplexMixedColorSpaceSdrVideoAndImageInputsEndWithImage_completesWithCorrectFrameCount() throws Exception { + assumeFormatsSupported( - context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); + context, + testId, + /* inputFormat= */ MP4_ASSET_FORMAT, + /* outputFormat= */ IMAGE_VIDEO_ENCODING_FORMAT); + assumeFormatsSupported( + context, + testId, + /* inputFormat= */ BT601_MP4_ASSET_FORMAT, + /* outputFormat= */ IMAGE_VIDEO_ENCODING_FORMAT); Transformer transformer = new Transformer.Builder(context) .setEncoderFactory( @@ -167,9 +206,9 @@ public class TransformerMixedInputEndToEndTest { int imageFrameCount = 34; EditedMediaItem imageEditedMediaItem = createImageEditedMediaItem(PNG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); - // Result of the following command: - // ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4 - EditedMediaItem videoEditedMediaItem = + EditedMediaItem bt601VideoEditedMediaItem = + createVideoEditedMediaItem(BT601_MP4_ASSET_URI_STRING, /* height= */ 480); + EditedMediaItem bt709VideoEditedMediaItem = createVideoEditedMediaItem(MP4_ASSET_URI_STRING, /* height= */ 480); ExportTestResult result = new TransformerAndroidTestRunner.Builder(context, transformer) @@ -178,15 +217,107 @@ public class TransformerMixedInputEndToEndTest { testId, buildComposition( imageEditedMediaItem, - videoEditedMediaItem, - videoEditedMediaItem, + bt709VideoEditedMediaItem, + bt601VideoEditedMediaItem, imageEditedMediaItem, imageEditedMediaItem, - videoEditedMediaItem, + bt601VideoEditedMediaItem, imageEditedMediaItem)); assertThat(result.exportResult.videoFrameCount) - .isEqualTo(4 * imageFrameCount + 3 * MP4_ASSET_FRAME_COUNT); + .isEqualTo(4 * imageFrameCount + MP4_ASSET_FRAME_COUNT + 2 * BT601_MP4_ASSET_FRAME_COUNT); + assertThat(new File(result.filePath).length()).isGreaterThan(0); + } + + @Test + public void + videoEditing_withComplexVideoAndImageInputsEndWithVideo_completesWithCorrectFrameCount() + throws Exception { + assumeFormatsSupported( + context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); + assumeFormatsSupported( + context, + testId, + /* inputFormat= */ BT601_MP4_ASSET_FORMAT, + /* outputFormat= */ MP4_ASSET_FORMAT); + Transformer transformer = + new Transformer.Builder(context) + .setEncoderFactory( + new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build()) + .build(); + + int imageFrameCount = 33; + EditedMediaItem imageEditedMediaItem1 = + createImageEditedMediaItem(PNG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); + EditedMediaItem imageEditedMediaItem2 = + createImageEditedMediaItem(JPG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); + EditedMediaItem videoEditedMediaItem1 = + createVideoEditedMediaItem(MP4_ASSET_URI_STRING, /* height= */ 360); + EditedMediaItem videoEditedMediaItem2 = + createVideoEditedMediaItem(BT601_MP4_ASSET_URI_STRING, /* height= */ 360); + ExportTestResult result = + new TransformerAndroidTestRunner.Builder(context, transformer) + .build() + .run( + testId, + buildComposition( + videoEditedMediaItem1, + videoEditedMediaItem2, + imageEditedMediaItem1, + imageEditedMediaItem2, + videoEditedMediaItem1, + imageEditedMediaItem1, + videoEditedMediaItem2)); + + assertThat(result.exportResult.videoFrameCount) + .isEqualTo( + 3 * imageFrameCount + 2 * MP4_ASSET_FRAME_COUNT + 2 * BT601_MP4_ASSET_FRAME_COUNT); + assertThat(new File(result.filePath).length()).isGreaterThan(0); + } + + @Test + public void + videoEditing_withComplexVideoAndImageInputsEndWithImage_completesWithCorrectFrameCount() + throws Exception { + assumeFormatsSupported( + context, + testId, + /* inputFormat= */ MP4_ASSET_FORMAT, + /* outputFormat= */ IMAGE_VIDEO_ENCODING_FORMAT); + assumeFormatsSupported( + context, + testId, + /* inputFormat= */ BT601_MP4_ASSET_FORMAT, + /* outputFormat= */ IMAGE_VIDEO_ENCODING_FORMAT); + Transformer transformer = + new Transformer.Builder(context) + .setEncoderFactory( + new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build()) + .build(); + + int imageFrameCount = 34; + EditedMediaItem imageEditedMediaItem = + createImageEditedMediaItem(PNG_ASSET_URI_STRING, /* frameCount= */ imageFrameCount); + EditedMediaItem videoEditedMediaItem1 = + createVideoEditedMediaItem(MP4_ASSET_URI_STRING, /* height= */ 480); + EditedMediaItem videoEditedMediaItem2 = + createVideoEditedMediaItem(BT601_MP4_ASSET_URI_STRING, /* height= */ 480); + ExportTestResult result = + new TransformerAndroidTestRunner.Builder(context, transformer) + .build() + .run( + testId, + buildComposition( + imageEditedMediaItem, + videoEditedMediaItem1, + videoEditedMediaItem2, + imageEditedMediaItem, + imageEditedMediaItem, + videoEditedMediaItem2, + imageEditedMediaItem)); + + assertThat(result.exportResult.videoFrameCount) + .isEqualTo(4 * imageFrameCount + MP4_ASSET_FRAME_COUNT + 2 * BT601_MP4_ASSET_FRAME_COUNT); assertThat(new File(result.filePath).length()).isGreaterThan(0); } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerSequenceEffectTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerSequenceEffectTest.java index 2392fd3ad0..4f401d888b 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerSequenceEffectTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerSequenceEffectTest.java @@ -21,8 +21,8 @@ import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Util.SDK_INT; import static androidx.media3.effect.DebugTraceUtil.EVENT_SURFACE_TEXTURE_TRANSFORM_FIX; import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap; -import static androidx.media3.transformer.AndroidTestUtil.BT601_ASSET_FORMAT; -import static androidx.media3.transformer.AndroidTestUtil.BT601_ASSET_URI_STRING; +import static androidx.media3.transformer.AndroidTestUtil.BT601_MOV_ASSET_FORMAT; +import static androidx.media3.transformer.AndroidTestUtil.BT601_MOV_ASSET_URI_STRING; import static androidx.media3.transformer.AndroidTestUtil.JPG_ASSET_URI_STRING; import static androidx.media3.transformer.AndroidTestUtil.JPG_PORTRAIT_ASSET_URI_STRING; import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_AV1_VIDEO_FORMAT; @@ -228,18 +228,20 @@ public final class TransformerSequenceEffectTest { assumeFormatsSupported( context, testId, - /* inputFormat= */ BT601_ASSET_FORMAT, - /* outputFormat= */ BT601_ASSET_FORMAT); + /* inputFormat= */ BT601_MOV_ASSET_FORMAT, + /* outputFormat= */ BT601_MOV_ASSET_FORMAT); List mediaCodecInfoList = MediaCodecSelector.DEFAULT.getDecoderInfos( - checkNotNull(BT601_ASSET_FORMAT.sampleMimeType), + checkNotNull(BT601_MOV_ASSET_FORMAT.sampleMimeType), /* requiresSecureDecoder= */ false, /* requiresTunnelingDecoder= */ false); Composition composition = createComposition( /* presentation= */ null, clippedVideo( - BT601_ASSET_URI_STRING, NO_EFFECT, /* endPositionMs= */ C.MILLIS_PER_SECOND / 4)); + BT601_MOV_ASSET_URI_STRING, + NO_EFFECT, + /* endPositionMs= */ C.MILLIS_PER_SECOND / 4)); boolean atLeastOneDecoderSucceeds = false; for (MediaCodecInfo mediaCodecInfo : mediaCodecInfoList) { @@ -556,12 +558,12 @@ public final class TransformerSequenceEffectTest { assumeFormatsSupported( context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); assumeFormatsSupported( - context, testId, /* inputFormat= */ BT601_ASSET_FORMAT, /* outputFormat= */ null); + context, testId, /* inputFormat= */ BT601_MOV_ASSET_FORMAT, /* outputFormat= */ null); Composition composition = createComposition( Presentation.createForHeight(EXPORT_HEIGHT), clippedVideo( - BT601_ASSET_URI_STRING, + BT601_MOV_ASSET_URI_STRING, ImmutableList.of(RgbFilter.createInvertedFilter()), SINGLE_30_FPS_VIDEO_FRAME_THRESHOLD_MS), clippedVideo(MP4_ASSET_URI_STRING, NO_EFFECT, SINGLE_30_FPS_VIDEO_FRAME_THRESHOLD_MS)); @@ -581,12 +583,12 @@ public final class TransformerSequenceEffectTest { assumeFormatsSupported( context, testId, /* inputFormat= */ MP4_ASSET_FORMAT, /* outputFormat= */ MP4_ASSET_FORMAT); assumeFormatsSupported( - context, testId, /* inputFormat= */ BT601_ASSET_FORMAT, /* outputFormat= */ null); + context, testId, /* inputFormat= */ BT601_MOV_ASSET_FORMAT, /* outputFormat= */ null); Composition composition = createComposition( Presentation.createForHeight(EXPORT_HEIGHT), clippedVideo( - BT601_ASSET_URI_STRING, + BT601_MOV_ASSET_URI_STRING, ImmutableList.of(RgbFilter.createInvertedFilter()), SINGLE_30_FPS_VIDEO_FRAME_THRESHOLD_MS), oneFrameFromImage(JPG_ASSET_URI_STRING, NO_EFFECT));