Remove ParcelFileDescriptor output from Transformer
ParcelFileDescriptor is quite specific and removing it allows to have less overloads of startTransformation. A follow-up CL will undeprecate the overload that takes a MediaItem. PiperOrigin-RevId: 505670321
This commit is contained in:
parent
4a942adbc6
commit
4a66ad5dd1
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.transformer;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -65,11 +64,6 @@ public final class DefaultMuxer implements Muxer {
|
||||
return new DefaultMuxer(muxerFactory.create(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Muxer create(ParcelFileDescriptor parcelFileDescriptor) throws MuxerException {
|
||||
return new DefaultMuxer(muxerFactory.create(parcelFileDescriptor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType) {
|
||||
return muxerFactory.getSupportedSampleMimeTypes(trackType);
|
||||
|
@ -24,9 +24,7 @@ import android.annotation.SuppressLint;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.MediaMuxer;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.SparseLongArray;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.MediaFormatUtil;
|
||||
@ -75,21 +73,6 @@ import java.nio.ByteBuffer;
|
||||
return new FrameworkMuxer(mediaMuxer, maxDelayBetweenSamplesMs, videoDurationMs);
|
||||
}
|
||||
|
||||
@RequiresApi(26)
|
||||
@Override
|
||||
public FrameworkMuxer create(ParcelFileDescriptor parcelFileDescriptor) throws MuxerException {
|
||||
MediaMuxer mediaMuxer;
|
||||
try {
|
||||
mediaMuxer =
|
||||
new MediaMuxer(
|
||||
parcelFileDescriptor.getFileDescriptor(),
|
||||
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
|
||||
} catch (IOException e) {
|
||||
throw new MuxerException("Error creating muxer", e);
|
||||
}
|
||||
return new FrameworkMuxer(mediaMuxer, maxDelayBetweenSamplesMs, videoDurationMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType) {
|
||||
if (trackType == C.TRACK_TYPE_VIDEO) {
|
||||
|
@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.transformer;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
@ -57,18 +56,6 @@ public interface Muxer {
|
||||
*/
|
||||
Muxer create(String path) throws MuxerException;
|
||||
|
||||
/**
|
||||
* Returns a new muxer writing to a file descriptor.
|
||||
*
|
||||
* @param parcelFileDescriptor A readable and writable {@link ParcelFileDescriptor} of the
|
||||
* output. The file referenced by this ParcelFileDescriptor should not be used before the
|
||||
* muxer is released. It is the responsibility of the caller to close the
|
||||
* ParcelFileDescriptor. This can be done after this method returns.
|
||||
* @throws IllegalArgumentException If the file descriptor is invalid.
|
||||
* @throws MuxerException If an error occurs opening the output file descriptor for writing.
|
||||
*/
|
||||
Muxer create(ParcelFileDescriptor parcelFileDescriptor) throws MuxerException;
|
||||
|
||||
/**
|
||||
* Returns the supported sample {@linkplain MimeTypes MIME types} for the given {@link
|
||||
* C.TrackType}.
|
||||
|
@ -23,7 +23,6 @@ import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.SparseArray;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -65,8 +64,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
*/
|
||||
private static final long MAX_TRACK_WRITE_AHEAD_US = Util.msToUs(500);
|
||||
|
||||
@Nullable private final String outputPath;
|
||||
@Nullable private final ParcelFileDescriptor outputParcelFileDescriptor;
|
||||
private final String outputPath;
|
||||
private final Muxer.Factory muxerFactory;
|
||||
private final Listener listener;
|
||||
private final SparseArray<TrackInfo> trackTypeToInfo;
|
||||
@ -82,17 +80,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
private boolean isAborted;
|
||||
private @MonotonicNonNull Muxer muxer;
|
||||
|
||||
public MuxerWrapper(
|
||||
@Nullable String outputPath,
|
||||
@Nullable ParcelFileDescriptor outputParcelFileDescriptor,
|
||||
Muxer.Factory muxerFactory,
|
||||
Listener listener) {
|
||||
if (outputPath == null && outputParcelFileDescriptor == null) {
|
||||
throw new NullPointerException("Both output path and ParcelFileDescriptor are null");
|
||||
}
|
||||
|
||||
public MuxerWrapper(String outputPath, Muxer.Factory muxerFactory, Listener listener) {
|
||||
this.outputPath = outputPath;
|
||||
this.outputParcelFileDescriptor = outputParcelFileDescriptor;
|
||||
this.muxerFactory = muxerFactory;
|
||||
this.listener = listener;
|
||||
|
||||
@ -302,25 +291,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
@EnsuresNonNull("muxer")
|
||||
private void ensureMuxerInitialized() throws Muxer.MuxerException {
|
||||
if (muxer == null) {
|
||||
if (outputPath != null) {
|
||||
muxer = muxerFactory.create(outputPath);
|
||||
} else {
|
||||
checkNotNull(outputParcelFileDescriptor);
|
||||
muxer = muxerFactory.create(outputParcelFileDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the current size in bytes of the output, or {@link C#LENGTH_UNSET} if unavailable. */
|
||||
private long getCurrentOutputSizeBytes() {
|
||||
long fileSize = C.LENGTH_UNSET;
|
||||
|
||||
if (outputPath != null) {
|
||||
fileSize = new File(outputPath).length();
|
||||
} else if (outputParcelFileDescriptor != null) {
|
||||
fileSize = outputParcelFileDescriptor.getStatSize();
|
||||
}
|
||||
|
||||
long fileSize = new File(outputPath).length();
|
||||
return fileSize > 0 ? fileSize : C.LENGTH_UNSET;
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,8 @@ import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
@ -149,8 +147,8 @@ public final class Transformer {
|
||||
|
||||
/**
|
||||
* @deprecated Set the {@linkplain AudioProcessor audio processors} in an {@link
|
||||
* EditedMediaItem}, and pass it to {@link #startTransformation(EditedMediaItem, String)} or
|
||||
* {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* EditedMediaItem}, and pass it to {@link #startTransformation(EditedMediaItem, String)}
|
||||
* instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -161,8 +159,7 @@ public final class Transformer {
|
||||
|
||||
/**
|
||||
* @deprecated Set the {@linkplain Effect video effects} in an {@link EditedMediaItem}, and pass
|
||||
* it to {@link #startTransformation(EditedMediaItem, String)} or {@link
|
||||
* #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* it to {@link #startTransformation(EditedMediaItem, String)} instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -174,7 +171,7 @@ public final class Transformer {
|
||||
/**
|
||||
* @deprecated Use {@link EditedMediaItem.Builder#setRemoveAudio(boolean)} to remove the audio
|
||||
* from the {@link EditedMediaItem} passed to {@link #startTransformation(EditedMediaItem,
|
||||
* String)} or {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* String)} instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -186,7 +183,7 @@ public final class Transformer {
|
||||
/**
|
||||
* @deprecated Use {@link EditedMediaItem.Builder#setRemoveVideo(boolean)} to remove the video
|
||||
* from the {@link EditedMediaItem} passed to {@link #startTransformation(EditedMediaItem,
|
||||
* String)} or {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* String)} instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -198,7 +195,7 @@ public final class Transformer {
|
||||
/**
|
||||
* @deprecated Use {@link EditedMediaItem.Builder#setFlattenForSlowMotion(boolean)} to flatten
|
||||
* the {@link EditedMediaItem} passed to {@link #startTransformation(EditedMediaItem,
|
||||
* String)} or {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* String)} instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -277,8 +274,7 @@ public final class Transformer {
|
||||
|
||||
/**
|
||||
* @deprecated Set the {@link FrameProcessor.Factory} in an {@link EditedMediaItem}, and pass it
|
||||
* to {@link #startTransformation(EditedMediaItem, String)} or {@link
|
||||
* #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
* to {@link #startTransformation(EditedMediaItem, String)} instead.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@Deprecated
|
||||
@ -671,42 +667,7 @@ public final class Transformer {
|
||||
* @throws IllegalStateException If a transformation is already in progress.
|
||||
*/
|
||||
public void startTransformation(EditedMediaItem editedMediaItem, String path) {
|
||||
startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an asynchronous operation to transform the given {@link MediaItem}.
|
||||
*
|
||||
* <p>The transformation state is notified through the {@linkplain Builder#addListener(Listener)
|
||||
* listener}.
|
||||
*
|
||||
* <p>Concurrent transformations on the same Transformer object are not allowed.
|
||||
*
|
||||
* <p>If no custom {@link Muxer.Factory} is specified, the output is an MP4 file.
|
||||
*
|
||||
* <p>The output can contain at most one video track and one audio track. Other track types are
|
||||
* ignored. For adaptive bitrate, if no custom {@link AssetLoader.Factory} is specified, the
|
||||
* highest bitrate video and audio streams are selected.
|
||||
*
|
||||
* <p>If encoding the output's video track is needed, the output frames' dimensions will be
|
||||
* swapped if the height is larger than the width. This is to improve compatibility among
|
||||
* different device encoders.
|
||||
*
|
||||
* @param editedMediaItem The {@link MediaItem} to transform, with the transformations to apply to
|
||||
* it.
|
||||
* @param parcelFileDescriptor A readable and writable {@link ParcelFileDescriptor} of the output.
|
||||
* The file referenced by this ParcelFileDescriptor should not be used before the
|
||||
* transformation is completed. It is the responsibility of the caller to close the
|
||||
* ParcelFileDescriptor. This can be done after this method returns.
|
||||
* @throws IllegalArgumentException If the file descriptor is invalid.
|
||||
* @throws IllegalArgumentException If the {@link MediaItem} is not supported.
|
||||
* @throws IllegalStateException If this method is called from the wrong thread.
|
||||
* @throws IllegalStateException If a transformation is already in progress.
|
||||
*/
|
||||
@RequiresApi(26)
|
||||
public void startTransformation(
|
||||
EditedMediaItem editedMediaItem, ParcelFileDescriptor parcelFileDescriptor) {
|
||||
startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor);
|
||||
startTransformationInternal(editedMediaItem, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -726,34 +687,10 @@ public final class Transformer {
|
||||
.setFlattenForSlowMotion(flattenForSlowMotion)
|
||||
.setEffects(new Effects(audioProcessors, videoEffects, frameProcessorFactory))
|
||||
.build();
|
||||
startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null);
|
||||
startTransformationInternal(editedMediaItem, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@RequiresApi(26)
|
||||
public void startTransformation(MediaItem mediaItem, ParcelFileDescriptor parcelFileDescriptor) {
|
||||
if (!mediaItem.clippingConfiguration.equals(MediaItem.ClippingConfiguration.UNSET)
|
||||
&& flattenForSlowMotion) {
|
||||
throw new IllegalArgumentException(
|
||||
"Clipping is not supported when slow motion flattening is requested");
|
||||
}
|
||||
EditedMediaItem editedMediaItem =
|
||||
new EditedMediaItem.Builder(mediaItem)
|
||||
.setRemoveAudio(removeAudio)
|
||||
.setRemoveVideo(removeVideo)
|
||||
.setFlattenForSlowMotion(flattenForSlowMotion)
|
||||
.setEffects(new Effects(audioProcessors, videoEffects, frameProcessorFactory))
|
||||
.build();
|
||||
startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor);
|
||||
}
|
||||
|
||||
private void startTransformationInternal(
|
||||
EditedMediaItem editedMediaItem,
|
||||
@Nullable String path,
|
||||
@Nullable ParcelFileDescriptor parcelFileDescriptor) {
|
||||
private void startTransformationInternal(EditedMediaItem editedMediaItem, String path) {
|
||||
verifyApplicationThread();
|
||||
if (transformerInternal != null) {
|
||||
throw new IllegalStateException("There is already a transformation in progress.");
|
||||
@ -769,7 +706,6 @@ public final class Transformer {
|
||||
context,
|
||||
editedMediaItem,
|
||||
path,
|
||||
parcelFileDescriptor,
|
||||
transformationRequest,
|
||||
generateSilentAudio,
|
||||
assetLoaderFactory,
|
||||
|
@ -28,7 +28,6 @@ import android.content.Context;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
@ -113,8 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
public TransformerInternal(
|
||||
Context context,
|
||||
EditedMediaItem editedMediaItem,
|
||||
@Nullable String outputPath,
|
||||
@Nullable ParcelFileDescriptor outputParcelFileDescriptor,
|
||||
String outputPath,
|
||||
TransformationRequest transformationRequest,
|
||||
boolean generateSilentAudio,
|
||||
AssetLoader.Factory assetLoaderFactory,
|
||||
@ -144,8 +142,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
.setFlattenVideoForSlowMotion(editedMediaItem.flattenForSlowMotion)
|
||||
.createAssetLoader(editedMediaItem.mediaItem, internalLooper, componentListener);
|
||||
samplePipelines = new ArrayList<>();
|
||||
muxerWrapper =
|
||||
new MuxerWrapper(outputPath, outputParcelFileDescriptor, muxerFactory, componentListener);
|
||||
muxerWrapper = new MuxerWrapper(outputPath, muxerFactory, componentListener);
|
||||
transformerConditionVariable = new ConditionVariable();
|
||||
transformationResultBuilder = new TransformationResult.Builder();
|
||||
// It's safe to use "this" because we don't send a message before exiting the constructor.
|
||||
|
@ -39,7 +39,6 @@ import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
@ -1140,12 +1139,6 @@ public final class TransformerEndToEndTest {
|
||||
return testMuxer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Muxer create(ParcelFileDescriptor parcelFileDescriptor) throws Muxer.MuxerException {
|
||||
testMuxer = new TestMuxer("FD:" + parcelFileDescriptor.getFd(), defaultMuxerFactory);
|
||||
return testMuxer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType) {
|
||||
return defaultMuxerFactory.getSupportedSampleMimeTypes(trackType);
|
||||
|
Loading…
x
Reference in New Issue
Block a user