From 483d2bb9e7fd8e67ddb7b97e09b29a506adc8175 Mon Sep 17 00:00:00 2001 From: sheenachhabra Date: Mon, 25 Mar 2024 03:37:54 -0700 Subject: [PATCH] Add Muxer interface in muxer module The immediate plan is to replace `Transformer Muxer interface` with this one. It was not straight forward to move/change `Transformer Muxer interface` hence this intermediate step. The follow up CL will also remove fragmented MP4 related code from `Mp4Muxer` and move it into `FragmentedMp4Muxer implements Muxer`. PiperOrigin-RevId: 618789265 --- .../androidx/media3/muxer/BasicMp4Writer.java | 2 +- .../media3/muxer/FragmentedMp4Writer.java | 2 +- .../java/androidx/media3/muxer/Mp4Muxer.java | 28 +++++++++--- .../java/androidx/media3/muxer/Mp4Writer.java | 4 +- .../java/androidx/media3/muxer/Muxer.java | 44 +++++++++++++++++++ .../media3/muxer/Mp4MuxerEndToEndTest.java | 2 +- .../media3/muxer/Mp4MuxerMetadataTest.java | 2 +- .../media3/transformer/InAppMuxer.java | 2 +- .../androidx/media3/transformer/Muxer.java | 1 + 9 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 libraries/muxer/src/main/java/androidx/media3/muxer/Muxer.java diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/BasicMp4Writer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/BasicMp4Writer.java index 895934e9e4..47c12fa0cd 100644 --- a/libraries/muxer/src/main/java/androidx/media3/muxer/BasicMp4Writer.java +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/BasicMp4Writer.java @@ -25,7 +25,7 @@ import static java.lang.Math.min; import android.media.MediaCodec.BufferInfo; import androidx.media3.common.Format; import androidx.media3.common.util.Util; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import com.google.common.collect.Range; import java.io.FileOutputStream; import java.io.IOException; diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/FragmentedMp4Writer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/FragmentedMp4Writer.java index 26de72528f..36c9bd8fb2 100644 --- a/libraries/muxer/src/main/java/androidx/media3/muxer/FragmentedMp4Writer.java +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/FragmentedMp4Writer.java @@ -32,7 +32,7 @@ import android.media.MediaCodec.BufferInfo; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; import androidx.media3.common.util.Util; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import com.google.common.collect.ImmutableList; import java.io.FileOutputStream; import java.io.IOException; diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java index f9e0ca3db0..76d3d893a4 100644 --- a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Muxer.java @@ -70,9 +70,7 @@ import java.nio.ByteBuffer; * */ @UnstableApi -public final class Mp4Muxer { - /** A token representing an added track. */ - public interface TrackToken {} +public final class Mp4Muxer implements Muxer { /** Behavior for the last sample duration. */ @Documented @@ -223,6 +221,22 @@ public final class Mp4Muxer { || metadata instanceof XmpData; } + /** + * {@inheritDoc} + * + *

Tracks can be added at any point before the muxer is closed, even after writing samples to + * other tracks. + * + *

The order of tracks remains same in which they are added. + * + * @param format The {@link Format} for the track. + * @return A unique {@link TrackToken}. It should be used in {@link #writeSampleData}. + */ + @Override + public TrackToken addTrack(Format format) { + return addTrack(/* sortKey= */ 1, format); + } + /** * Adds a track of the given media format. * @@ -242,7 +256,7 @@ public final class Mp4Muxer { } /** - * Writes encoded sample data. + * {@inheritDoc} * *

The samples are cached and are written in batches so the caller must not change/release the * {@link ByteBuffer} and the {@link BufferInfo} after calling this method. @@ -254,13 +268,14 @@ public final class Mp4Muxer { * @param bufferInfo The {@link BufferInfo} related to this sample. * @throws IOException If there is any error while writing data to the disk. */ + @Override public void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo) throws IOException { mp4Writer.writeSampleData(trackToken, byteBuffer, bufferInfo); } /** - * Adds metadata for the output file. + * {@inheritDoc} * *

List of supported {@linkplain Metadata.Entry metadata entries}: * @@ -277,12 +292,13 @@ public final class Mp4Muxer { * @param metadata The {@linkplain Metadata.Entry metadata}. An {@link IllegalArgumentException} * is throw if the {@linkplain Metadata.Entry metadata} is not supported. */ + @Override public void addMetadata(Metadata.Entry metadata) { checkArgument(isMetadataSupported(metadata), "Unsupported metadata"); metadataCollector.addMetadata(metadata); } - /** Closes the MP4 file. */ + @Override public void close() throws IOException { mp4Writer.close(); } diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Writer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Writer.java index e20eef2c7a..9b0c1091cd 100644 --- a/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Writer.java +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Mp4Writer.java @@ -22,7 +22,7 @@ import android.media.MediaCodec.BufferInfo; import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import com.google.common.collect.ImmutableList; import java.io.IOException; import java.nio.ByteBuffer; @@ -41,7 +41,7 @@ import java.util.List; void close() throws IOException; - class Track implements Mp4Muxer.TrackToken, Mp4MoovStructure.TrackMetadataProvider { + class Track implements TrackToken, Mp4MoovStructure.TrackMetadataProvider { public final Format format; public final int sortKey; public final List writtenSamples; diff --git a/libraries/muxer/src/main/java/androidx/media3/muxer/Muxer.java b/libraries/muxer/src/main/java/androidx/media3/muxer/Muxer.java new file mode 100644 index 0000000000..eede55f85d --- /dev/null +++ b/libraries/muxer/src/main/java/androidx/media3/muxer/Muxer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 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 + * + * http://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.muxer; + +import android.media.MediaCodec; +import androidx.media3.common.Format; +import androidx.media3.common.Metadata; +import androidx.media3.common.util.UnstableApi; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** The muxer for producing media container files. */ +@UnstableApi +public interface Muxer { + /** A token representing an added track. */ + interface TrackToken {} + + /** Adds a track of the given media format. */ + TrackToken addTrack(Format format); + + /** Writes encoded sample data. */ + void writeSampleData( + TrackToken trackToken, ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo) + throws IOException; + + /** Adds metadata for the output file. */ + void addMetadata(Metadata.Entry metadata); + + /** Closes the file. */ + void close() throws IOException; +} diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java index 55cca99ff2..e4c18d0578 100644 --- a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java +++ b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerEndToEndTest.java @@ -31,7 +31,7 @@ import androidx.media3.container.Mp4OrientationData; import androidx.media3.container.Mp4TimestampData; import androidx.media3.container.XmpData; import androidx.media3.extractor.mp4.Mp4Extractor; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import androidx.media3.test.utils.DumpFileAsserts; import androidx.media3.test.utils.DumpableMp4Box; import androidx.media3.test.utils.FakeExtractorOutput; diff --git a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java index 6ceb64bdeb..70e40a6720 100644 --- a/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java +++ b/libraries/muxer/src/test/java/androidx/media3/muxer/Mp4MuxerMetadataTest.java @@ -32,7 +32,7 @@ import androidx.media3.container.Mp4TimestampData; import androidx.media3.container.XmpData; import androidx.media3.extractor.mp4.Mp4Extractor; import androidx.media3.extractor.text.DefaultSubtitleParserFactory; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import androidx.media3.test.utils.DumpFileAsserts; import androidx.media3.test.utils.DumpableMp4Box; import androidx.media3.test.utils.FakeExtractorOutput; diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java index 5ded6bd4a3..6b27e605fb 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/InAppMuxer.java @@ -26,7 +26,7 @@ import androidx.media3.common.MimeTypes; import androidx.media3.common.util.UnstableApi; import androidx.media3.container.Mp4OrientationData; import androidx.media3.muxer.Mp4Muxer; -import androidx.media3.muxer.Mp4Muxer.TrackToken; +import androidx.media3.muxer.Muxer.TrackToken; import com.google.common.collect.ImmutableList; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.FileNotFoundException; diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Muxer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Muxer.java index 6953862cfa..f2ffce0e58 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/Muxer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Muxer.java @@ -33,6 +33,7 @@ import java.nio.ByteBuffer; * finish writing to the output and return any resources to the system. */ @UnstableApi +// TODO: b/330695864 - Replace with the Muxer interface from the Muxer module. public interface Muxer { /** Thrown when a muxing failure occurs. */