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
This commit is contained in:
sheenachhabra 2024-03-25 03:37:54 -07:00 committed by Copybara-Service
parent d165af9a85
commit 483d2bb9e7
9 changed files with 74 additions and 13 deletions

View File

@ -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;

View File

@ -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;

View File

@ -70,9 +70,7 @@ import java.nio.ByteBuffer;
* </ul>
*/
@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}
*
* <p>Tracks can be added at any point before the muxer is closed, even after writing samples to
* other tracks.
*
* <p>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}
*
* <p>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}
*
* <p>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();
}

View File

@ -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<BufferInfo> writtenSamples;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */