mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
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:
parent
86ef571644
commit
03a041c452
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user