Move muxer closing logic from Mp4Writer to Mp4Muxer

PiperOrigin-RevId: 646134522
This commit is contained in:
sheenachhabra 2024-06-24 10:06:32 -07:00 committed by Copybara-Service
parent b026271c84
commit 327f728010
2 changed files with 49 additions and 21 deletions

View File

@ -24,6 +24,7 @@ import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.container.MdtaMetadataEntry;
import androidx.media3.container.Mp4LocationData;
@ -38,6 +39,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/**
* A muxer for creating an MP4 container file.
@ -176,6 +178,10 @@ public final class Mp4Muxer implements Muxer {
}
}
private static final String TAG = "Mp4Muxer";
private final FileOutputStream fileOutputStream;
private final FileChannel fileChannel;
private final MetadataCollector metadataCollector;
private final Mp4Writer mp4Writer;
@ -185,12 +191,14 @@ public final class Mp4Muxer implements Muxer {
AnnexBToAvccConverter annexBToAvccConverter,
boolean sampleCopyEnabled,
boolean attemptStreamableOutputEnabled) {
this.fileOutputStream = fileOutputStream;
this.fileChannel = fileOutputStream.getChannel();
metadataCollector = new MetadataCollector();
Mp4MoovStructure moovStructure =
new Mp4MoovStructure(metadataCollector, lastFrameDurationBehavior);
mp4Writer =
new Mp4Writer(
fileOutputStream,
fileChannel,
moovStructure,
annexBToAvccConverter,
sampleCopyEnabled,
@ -288,10 +296,32 @@ public final class Mp4Muxer implements Muxer {
@Override
public void close() throws MuxerException {
@Nullable MuxerException exception = null;
try {
mp4Writer.close();
mp4Writer.finishWritingSamples();
} catch (IOException e) {
throw new MuxerException("Failed to close the muxer", e);
exception = new MuxerException("Failed to finish writing samples", e);
}
try {
fileChannel.close();
} catch (IOException e) {
if (exception == null) {
exception = new MuxerException("Failed to close output channel", e);
} else {
Log.e(TAG, "Failed to close output channel", e);
}
}
try {
fileOutputStream.close();
} catch (IOException e) {
if (exception == null) {
exception = new MuxerException("Failed to close output stream", e);
} else {
Log.e(TAG, "Failed to close output stream", e);
}
}
if (exception != null) {
throw exception;
}
}
}

View File

@ -28,7 +28,6 @@ import androidx.media3.common.Format;
import androidx.media3.common.util.Util;
import androidx.media3.muxer.Muxer.TrackToken;
import com.google.common.collect.Range;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
@ -43,7 +42,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int DEFAULT_MOOV_BOX_SIZE_BYTES = 400_000;
private static final String FREE_BOX_TYPE = "free";
private final FileOutputStream outputStream;
private final FileChannel output;
private final Mp4MoovStructure moovGenerator;
private final AnnexBToAvccConverter annexBToAvccConverter;
@ -66,7 +64,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* Creates an instance.
*
* @param outputStream The {@link FileOutputStream} to write the data to.
* @param fileChannel The {@link FileChannel} to write the data to. The {@link FileChannel} can be
* closed after {@link #finishWritingSamples() finishing writing samples}.
* @param moovGenerator An {@link Mp4MoovStructure} instance to generate the moov box.
* @param annexBToAvccConverter The {@link AnnexBToAvccConverter} to be used to convert H.264 and
* H.265 NAL units from the Annex-B format (using start codes to delineate NAL units) to the
@ -75,13 +74,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
* @param attemptStreamableOutputEnabled Whether to attempt to write a streamable output.
*/
public Mp4Writer(
FileOutputStream outputStream,
FileChannel fileChannel,
Mp4MoovStructure moovGenerator,
AnnexBToAvccConverter annexBToAvccConverter,
boolean sampleCopyEnabled,
boolean attemptStreamableOutputEnabled) {
this.outputStream = outputStream;
this.output = outputStream.getChannel();
this.output = fileChannel;
this.moovGenerator = moovGenerator;
this.annexBToAvccConverter = annexBToAvccConverter;
this.sampleCopyEnabled = sampleCopyEnabled;
@ -105,8 +103,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
doInterleave();
}
public void close() throws IOException {
try {
/**
* Writes all the pending samples and the final moov box to the disk.
*
* <p>The output {@link FileChannel} can be closed after calling this method.
*/
public void finishWritingSamples() throws IOException {
for (int i = 0; i < tracks.size(); i++) {
flushPending(tracks.get(i));
}
@ -115,10 +117,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
if (hasWrittenSamples.get()) {
writeMoovAndTrim();
}
} finally {
output.close();
outputStream.close();
}
}
private void writeHeader() throws IOException {