Pass BufferInfo in writeSampleData() method in Transformer/Muxer.java

This is to eventually replace Transformer/Muxer.java with Muxer/Muxer.java

PiperOrigin-RevId: 627043808
This commit is contained in:
sheenachhabra 2024-04-22 08:20:59 -07:00 committed by Copybara-Service
parent 86ef571644
commit 03a041c452
8 changed files with 46 additions and 45 deletions

View File

@ -15,7 +15,7 @@
*/
package androidx.media3.muxer;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi;
@ -32,8 +32,7 @@ public interface Muxer {
TrackToken addTrack(Format format);
/** Writes encoded sample data. */
void writeSampleData(
TrackToken trackToken, ByteBuffer byteBuffer, MediaCodec.BufferInfo bufferInfo)
void writeSampleData(TrackToken trackToken, ByteBuffer byteBuffer, BufferInfo bufferInfo)
throws IOException;
/** Adds {@linkplain Metadata.Entry metadata} about the output file. */

View File

@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.content.Context;
import android.media.MediaCodec.BufferInfo;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Effect;
@ -449,18 +450,17 @@ public class TransformerPauseResumeTest {
}
@Override
public void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException {
if (trackToken == videoTrackToken
&& presentationTimeUs >= DEFAULT_PRESENTATION_TIME_US_TO_BLOCK_FRAME) {
&& bufferInfo.presentationTimeUs >= DEFAULT_PRESENTATION_TIME_US_TO_BLOCK_FRAME) {
if (!notifiedListener) {
listener.onFrameBlocked();
notifiedListener = true;
}
return;
}
wrappedMuxer.writeSampleData(trackToken, data, presentationTimeUs, flags);
wrappedMuxer.writeSampleData(trackToken, data, bufferInfo);
}
@Override

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.transformer;
import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
@ -70,10 +71,9 @@ public final class DefaultMuxer implements Muxer {
}
@Override
public void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException {
muxer.writeSampleData(trackToken, data, presentationTimeUs, flags);
muxer.writeSampleData(trackToken, data, bufferInfo);
}
@Override

View File

@ -21,7 +21,7 @@ import static androidx.media3.common.util.Util.SDK_INT;
import static androidx.media3.common.util.Util.castNonNull;
import android.annotation.SuppressLint;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import androidx.annotation.Nullable;
@ -80,7 +80,6 @@ import java.util.Map;
private final MediaMuxer mediaMuxer;
private final long videoDurationUs;
private final MediaCodec.BufferInfo bufferInfo;
private final Map<TrackToken, Long> trackTokenToLastPresentationTimeUs;
private final Map<TrackToken, Long> trackTokenToPresentationTimeOffsetUs;
@ -92,7 +91,6 @@ import java.util.Map;
private FrameworkMuxer(MediaMuxer mediaMuxer, long videoDurationMs) {
this.mediaMuxer = mediaMuxer;
this.videoDurationUs = Util.msToUs(videoDurationMs);
bufferInfo = new MediaCodec.BufferInfo();
trackTokenToLastPresentationTimeUs = new HashMap<>();
trackTokenToPresentationTimeOffsetUs = new HashMap<>();
}
@ -133,10 +131,9 @@ import java.util.Map;
}
@Override
public void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException {
long presentationTimeUs = bufferInfo.presentationTimeUs;
if (videoDurationUs != C.TIME_UNSET
&& trackToken == videoTrackToken
&& presentationTimeUs > videoDurationUs) {
@ -149,14 +146,10 @@ import java.util.Map;
startMuxer();
}
int offset = data.position();
int size = data.limit() - offset;
long presentationTimeOffsetUs =
trackTokenToPresentationTimeOffsetUs.getOrDefault(trackToken, 0L);
presentationTimeUs += presentationTimeOffsetUs;
bufferInfo.set(offset, size, presentationTimeUs, TransformerUtil.getMediaCodecFlags(flags));
long lastSamplePresentationTimeUs =
trackTokenToLastPresentationTimeUs.getOrDefault(trackToken, 0L);
// writeSampleData blocks on old API versions, so check here to avoid calling the method.
@ -176,13 +169,17 @@ import java.util.Map;
+ " < "
+ lastSamplePresentationTimeUs
+ ") unsupported when using negative PTS workaround");
bufferInfo.set(bufferInfo.offset, bufferInfo.size, presentationTimeUs, bufferInfo.flags);
try {
checkState(trackToken instanceof TrackTokenImpl);
mediaMuxer.writeSampleData(((TrackTokenImpl) trackToken).trackIndex, data, bufferInfo);
} catch (RuntimeException e) {
throw new MuxerException(
"Failed to write sample for presentationTimeUs=" + presentationTimeUs + ", size=" + size,
"Failed to write sample for presentationTimeUs="
+ presentationTimeUs
+ ", size="
+ bufferInfo.size,
e);
}
}
@ -208,11 +205,13 @@ import java.util.Map;
}
if (videoDurationUs != C.TIME_UNSET && videoTrackToken != null) {
writeSampleData(
videoTrackToken,
ByteBuffer.allocateDirect(0),
BufferInfo bufferInfo = new BufferInfo();
bufferInfo.set(
/* newOffset= */ 0,
/* newSize= */ 0,
videoDurationUs,
C.BUFFER_FLAG_END_OF_STREAM);
TransformerUtil.getMediaCodecFlags(C.BUFFER_FLAG_END_OF_STREAM));
writeSampleData(checkNotNull(videoTrackToken), ByteBuffer.allocateDirect(0), bufferInfo);
}
isStarted = false;

View File

@ -159,14 +159,12 @@ public final class InAppMuxer implements Muxer {
private final androidx.media3.muxer.Muxer muxer;
private final @Nullable MetadataProvider metadataProvider;
private final BufferInfo bufferInfo;
private final Set<Metadata.Entry> metadataEntries;
private InAppMuxer(
androidx.media3.muxer.Muxer muxer, @Nullable MetadataProvider metadataProvider) {
this.muxer = muxer;
this.metadataProvider = metadataProvider;
bufferInfo = new BufferInfo();
metadataEntries = new LinkedHashSet<>();
}
@ -180,19 +178,17 @@ public final class InAppMuxer implements Muxer {
}
@Override
public void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException {
int size = data.remaining();
bufferInfo.set(
data.position(), size, presentationTimeUs, TransformerUtil.getMediaCodecFlags(flags));
try {
muxer.writeSampleData(trackToken, data, bufferInfo);
} catch (IOException e) {
throw new MuxerException(
"Failed to write sample for presentationTimeUs=" + presentationTimeUs + ", size=" + size,
"Failed to write sample for presentationTimeUs="
+ bufferInfo.presentationTimeUs
+ ", size="
+ bufferInfo.size,
e);
}
}

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.transformer;
import android.media.MediaCodec.BufferInfo;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.Metadata;
@ -84,13 +85,10 @@ public interface Muxer {
* @param trackToken The {@link TrackToken} of the track, previously returned by {@link
* #addTrack(Format)}.
* @param data A buffer containing the sample data to write to the container.
* @param presentationTimeUs The presentation time of the sample in microseconds.
* @param flags The {@link C.BufferFlags} associated with the data. Only {@link
* C#BUFFER_FLAG_KEY_FRAME} and {@link C#BUFFER_FLAG_END_OF_STREAM} are supported.
* @param bufferInfo The {@link BufferInfo} of the sample.
* @throws MuxerException If the muxer fails to write the sample.
*/
void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException;
/** Adds {@linkplain Metadata.Entry metadata} about the output file. */

View File

@ -28,6 +28,7 @@ import static java.lang.Math.max;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.media.MediaCodec.BufferInfo;
import android.util.SparseArray;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
@ -147,6 +148,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final ScheduledExecutorService abortScheduledExecutorService;
private final @MonotonicNonNull Format appendVideoFormat;
private final long maxDelayBetweenSamplesMs;
private final BufferInfo bufferInfo;
private boolean isReady;
private boolean isEnded;
@ -206,6 +208,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
previousTrackType = C.TRACK_TYPE_NONE;
firstVideoPresentationTimeUs = C.TIME_UNSET;
abortScheduledExecutorService = Util.newSingleThreadScheduledExecutor(TIMER_THREAD_NAME);
bufferInfo = new BufferInfo();
}
/**
@ -552,8 +555,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
resetAbortTimer();
checkStateNotNull(muxer);
muxer.writeSampleData(
trackInfo.trackToken, data, presentationTimeUs, isKeyFrame ? C.BUFFER_FLAG_KEY_FRAME : 0);
bufferInfo.set(
data.position(),
data.remaining(),
presentationTimeUs,
TransformerUtil.getMediaCodecFlags(isKeyFrame ? C.BUFFER_FLAG_KEY_FRAME : 0));
muxer.writeSampleData(trackInfo.trackToken, data, bufferInfo);
if (trackType == C.TRACK_TYPE_VIDEO) {
DebugTraceUtil.logEvent(DebugTraceUtil.EVENT_MUXER_WRITE_SAMPLE_VIDEO, presentationTimeUs);
} else if (trackType == C.TRACK_TYPE_AUDIO) {

View File

@ -19,6 +19,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.transformer.TransformerUtil.getProcessedTrackType;
import android.media.MediaCodec.BufferInfo;
import android.util.SparseArray;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
@ -122,15 +123,16 @@ public final class CapturingMuxer implements Muxer, Dumpable {
}
@Override
public void writeSampleData(
TrackToken trackToken, ByteBuffer data, long presentationTimeUs, @C.BufferFlags int flags)
public void writeSampleData(TrackToken trackToken, ByteBuffer data, BufferInfo bufferInfo)
throws MuxerException {
@C.TrackType int trackType = checkNotNull(trackTokenToType.get(trackToken));
dumpableStreamByTrackType
.get(trackType)
.addSample(
data, (flags & C.BUFFER_FLAG_KEY_FRAME) == C.BUFFER_FLAG_KEY_FRAME, presentationTimeUs);
wrappedMuxer.writeSampleData(trackToken, data, presentationTimeUs, flags);
data,
(bufferInfo.flags & C.BUFFER_FLAG_KEY_FRAME) == C.BUFFER_FLAG_KEY_FRAME,
bufferInfo.presentationTimeUs);
wrappedMuxer.writeSampleData(trackToken, data, bufferInfo);
}
@Override