mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Pass MuxerWrapper to the TransformerInternal
For pause/resume feature, same MuxerWrapper needs to be used across intermediate exports. So pass the MuxerWrapper from Transformer.java More specifically, when resume() is called 1. Create a MuxerWrapper and remux the previous video samples (Export 1). 2. User the same MuxerWrapper and start processing remaining video samples (Export 2). PiperOrigin-RevId: 561325867
This commit is contained in:
parent
cf3fd1f4dd
commit
b37e37aa3c
3 changed files with 29 additions and 21 deletions
|
|
@ -71,7 +71,6 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
||||||
private final String outputPath;
|
private final String outputPath;
|
||||||
private final Muxer.Factory muxerFactory;
|
private final Muxer.Factory muxerFactory;
|
||||||
private final Listener listener;
|
|
||||||
private final SparseArray<TrackInfo> trackTypeToInfo;
|
private final SparseArray<TrackInfo> trackTypeToInfo;
|
||||||
private final ScheduledExecutorService abortScheduledExecutorService;
|
private final ScheduledExecutorService abortScheduledExecutorService;
|
||||||
|
|
||||||
|
|
@ -80,6 +79,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
private @C.TrackType int previousTrackType;
|
private @C.TrackType int previousTrackType;
|
||||||
private long minTrackTimeUs;
|
private long minTrackTimeUs;
|
||||||
private long maxEndedTrackTimeUs;
|
private long maxEndedTrackTimeUs;
|
||||||
|
private @MonotonicNonNull Listener listener;
|
||||||
private @MonotonicNonNull ScheduledFuture<?> abortScheduledFuture;
|
private @MonotonicNonNull ScheduledFuture<?> abortScheduledFuture;
|
||||||
private boolean isAborted;
|
private boolean isAborted;
|
||||||
private @MonotonicNonNull Muxer muxer;
|
private @MonotonicNonNull Muxer muxer;
|
||||||
|
|
@ -87,16 +87,25 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
private volatile int additionalRotationDegrees;
|
private volatile int additionalRotationDegrees;
|
||||||
private volatile int trackCount;
|
private volatile int trackCount;
|
||||||
|
|
||||||
public MuxerWrapper(String outputPath, Muxer.Factory muxerFactory, Listener listener) {
|
/** Creates an instance. */
|
||||||
|
public MuxerWrapper(String outputPath, Muxer.Factory muxerFactory) {
|
||||||
this.outputPath = outputPath;
|
this.outputPath = outputPath;
|
||||||
this.muxerFactory = muxerFactory;
|
this.muxerFactory = muxerFactory;
|
||||||
this.listener = listener;
|
|
||||||
|
|
||||||
trackTypeToInfo = new SparseArray<>();
|
trackTypeToInfo = new SparseArray<>();
|
||||||
previousTrackType = C.TRACK_TYPE_NONE;
|
previousTrackType = C.TRACK_TYPE_NONE;
|
||||||
abortScheduledExecutorService = Util.newSingleThreadScheduledExecutor(TIMER_THREAD_NAME);
|
abortScheduledExecutorService = Util.newSingleThreadScheduledExecutor(TIMER_THREAD_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a {@link MuxerWrapper.Listener}.
|
||||||
|
*
|
||||||
|
* <p>The {@link MuxerWrapper.Listener} must be set before calling any other methods.
|
||||||
|
*/
|
||||||
|
public void setListener(Listener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the clockwise rotation to add to the {@linkplain #addTrackFormat(Format) video track's}
|
* Sets the clockwise rotation to add to the {@linkplain #addTrackFormat(Format) video track's}
|
||||||
* rotation, in degrees.
|
* rotation, in degrees.
|
||||||
|
|
@ -266,9 +275,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
|
|
||||||
TrackInfo trackInfo = trackTypeToInfo.get(trackType);
|
TrackInfo trackInfo = trackTypeToInfo.get(trackType);
|
||||||
maxEndedTrackTimeUs = max(maxEndedTrackTimeUs, trackInfo.timeUs);
|
maxEndedTrackTimeUs = max(maxEndedTrackTimeUs, trackInfo.timeUs);
|
||||||
|
Listener listener = checkNotNull(this.listener);
|
||||||
listener.onTrackEnded(
|
listener.onTrackEnded(
|
||||||
trackType, trackInfo.format, trackInfo.getAverageBitrate(), trackInfo.sampleCount);
|
trackType, trackInfo.format, trackInfo.getAverageBitrate(), trackInfo.sampleCount);
|
||||||
|
|
||||||
if (trackType == C.TRACK_TYPE_VIDEO) {
|
if (trackType == C.TRACK_TYPE_VIDEO) {
|
||||||
DebugTraceUtil.logEvent(DebugTraceUtil.EVENT_MUXER_TRACK_ENDED_VIDEO, trackInfo.timeUs);
|
DebugTraceUtil.logEvent(DebugTraceUtil.EVENT_MUXER_TRACK_ENDED_VIDEO, trackInfo.timeUs);
|
||||||
} else if (trackType == C.TRACK_TYPE_AUDIO) {
|
} else if (trackType == C.TRACK_TYPE_AUDIO) {
|
||||||
|
|
@ -345,14 +354,15 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isAborted = true;
|
isAborted = true;
|
||||||
listener.onError(
|
checkNotNull(listener)
|
||||||
ExportException.createForMuxer(
|
.onError(
|
||||||
new IllegalStateException(
|
ExportException.createForMuxer(
|
||||||
Util.formatInvariant(
|
new IllegalStateException(
|
||||||
MUXER_TIMEOUT_ERROR_FORMAT_STRING,
|
Util.formatInvariant(
|
||||||
maxDelayBetweenSamplesMs,
|
MUXER_TIMEOUT_ERROR_FORMAT_STRING,
|
||||||
DebugTraceUtil.generateTraceSummary())),
|
maxDelayBetweenSamplesMs,
|
||||||
ExportException.ERROR_CODE_MUXING_TIMEOUT));
|
DebugTraceUtil.generateTraceSummary())),
|
||||||
|
ExportException.ERROR_CODE_MUXING_TIMEOUT));
|
||||||
},
|
},
|
||||||
maxDelayBetweenSamplesMs,
|
maxDelayBetweenSamplesMs,
|
||||||
MILLISECONDS);
|
MILLISECONDS);
|
||||||
|
|
|
||||||
|
|
@ -837,6 +837,7 @@ public final class Transformer {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
checkState(transformerInternal == null, "There is already an export in progress.");
|
checkState(transformerInternal == null, "There is already an export in progress.");
|
||||||
|
|
||||||
|
MuxerWrapper muxerWrapper = new MuxerWrapper(path, muxerFactory);
|
||||||
TransformerInternalListener transformerInternalListener =
|
TransformerInternalListener transformerInternalListener =
|
||||||
new TransformerInternalListener(composition);
|
new TransformerInternalListener(composition);
|
||||||
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
|
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
|
||||||
|
|
@ -862,13 +863,12 @@ public final class Transformer {
|
||||||
new TransformerInternal(
|
new TransformerInternal(
|
||||||
context,
|
context,
|
||||||
composition,
|
composition,
|
||||||
path,
|
|
||||||
transformationRequest,
|
transformationRequest,
|
||||||
assetLoaderFactory,
|
assetLoaderFactory,
|
||||||
audioMixerFactory,
|
audioMixerFactory,
|
||||||
videoFrameProcessorFactory,
|
videoFrameProcessorFactory,
|
||||||
encoderFactory,
|
encoderFactory,
|
||||||
muxerFactory,
|
muxerWrapper,
|
||||||
transformerInternalListener,
|
transformerInternalListener,
|
||||||
fallbackListener,
|
fallbackListener,
|
||||||
applicationHandler,
|
applicationHandler,
|
||||||
|
|
|
||||||
|
|
@ -128,17 +128,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
private volatile boolean released;
|
private volatile boolean released;
|
||||||
|
|
||||||
// Warning suppression is needed to assign the MuxerWrapper with "this" as listener.
|
// Warning suppression is needed to assign the MuxerWrapper with "this" as listener.
|
||||||
@SuppressWarnings("assignment.type.incompatible")
|
@SuppressWarnings({"argument.type.incompatible"})
|
||||||
public TransformerInternal(
|
public TransformerInternal(
|
||||||
Context context,
|
Context context,
|
||||||
Composition composition,
|
Composition composition,
|
||||||
String outputPath,
|
|
||||||
TransformationRequest transformationRequest,
|
TransformationRequest transformationRequest,
|
||||||
AssetLoader.Factory assetLoaderFactory,
|
AssetLoader.Factory assetLoaderFactory,
|
||||||
AudioMixer.Factory audioMixerFactory,
|
AudioMixer.Factory audioMixerFactory,
|
||||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||||
Codec.EncoderFactory encoderFactory,
|
Codec.EncoderFactory encoderFactory,
|
||||||
Muxer.Factory muxerFactory,
|
MuxerWrapper muxerWrapper,
|
||||||
Listener listener,
|
Listener listener,
|
||||||
FallbackListener fallbackListener,
|
FallbackListener fallbackListener,
|
||||||
HandlerWrapper applicationHandler,
|
HandlerWrapper applicationHandler,
|
||||||
|
|
@ -150,6 +149,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
this.applicationHandler = applicationHandler;
|
this.applicationHandler = applicationHandler;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
|
this.muxerWrapper = muxerWrapper;
|
||||||
|
// It's safe to use "this" because we don't mux any data before exiting the constructor.
|
||||||
|
this.muxerWrapper.setListener(this);
|
||||||
internalHandlerThread = new HandlerThread("Transformer:Internal");
|
internalHandlerThread = new HandlerThread("Transformer:Internal");
|
||||||
internalHandlerThread.start();
|
internalHandlerThread.start();
|
||||||
sequenceAssetLoaders = new ArrayList<>();
|
sequenceAssetLoaders = new ArrayList<>();
|
||||||
|
|
@ -192,10 +194,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
HandlerWrapper internalHandler =
|
HandlerWrapper internalHandler =
|
||||||
clock.createHandler(internalLooper, /* callback= */ this::handleMessage);
|
clock.createHandler(internalLooper, /* callback= */ this::handleMessage);
|
||||||
this.internalHandler = internalHandler;
|
this.internalHandler = internalHandler;
|
||||||
// It's safe to use "this" because we don't mux any data before exiting the constructor.
|
|
||||||
@SuppressWarnings("nullness:argument.type.incompatible")
|
|
||||||
MuxerWrapper muxerWrapper = new MuxerWrapper(outputPath, muxerFactory, /* listener= */ this);
|
|
||||||
this.muxerWrapper = muxerWrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue