Deprecate Transformer.Builder.setTransformationRequest()
Usages will be removed in follow-up changes. PiperOrigin-RevId: 543654397
This commit is contained in:
parent
140c83ce7e
commit
f8491fc61f
@ -16,12 +16,18 @@
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -42,6 +48,7 @@ public final class Composition {
|
||||
private boolean forceAudioTrack;
|
||||
private boolean transmuxAudio;
|
||||
private boolean transmuxVideo;
|
||||
private @HdrMode int hdrMode;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
@ -96,8 +103,8 @@ public final class Composition {
|
||||
* the {@link Composition} export doesn't produce any audio.
|
||||
*
|
||||
* <p>The MIME type of the output's audio track can be set using {@link
|
||||
* TransformationRequest.Builder#setAudioMimeType(String)}. The sample rate and channel count
|
||||
* can be set by passing relevant {@link AudioProcessor} instances to the {@link Composition}.
|
||||
* Transformer.Builder#setAudioMimeType(String)}. The sample rate and channel count can be set
|
||||
* by passing relevant {@link AudioProcessor} instances to the {@link Composition}.
|
||||
*
|
||||
* <p>Forcing an audio track and {@linkplain #setTransmuxAudio(boolean) requesting audio
|
||||
* transmuxing} are not allowed together because generating silence requires transcoding.
|
||||
@ -163,12 +170,101 @@ public final class Composition {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link HdrMode} for HDR video input.
|
||||
*
|
||||
* <p>The default value is {@link #HDR_MODE_KEEP_HDR}.
|
||||
*
|
||||
* @param hdrMode The {@link HdrMode} used.
|
||||
* @return This builder.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setHdrMode(@HdrMode int hdrMode) {
|
||||
this.hdrMode = hdrMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds a {@link Composition} instance. */
|
||||
public Composition build() {
|
||||
return new Composition(sequences, effects, forceAudioTrack, transmuxAudio, transmuxVideo);
|
||||
return new Composition(
|
||||
sequences, effects, forceAudioTrack, transmuxAudio, transmuxVideo, hdrMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The strategy to use to transcode or edit High Dynamic Range (HDR) input video.
|
||||
*
|
||||
* <p>One of {@link #HDR_MODE_KEEP_HDR}, {@link #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC},
|
||||
* {@link #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL}, or {@link
|
||||
* #HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||
*
|
||||
* <p>Standard Dynamic Range (SDR) input video is unaffected by these settings.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(SOURCE)
|
||||
@Target(TYPE_USE)
|
||||
@IntDef({
|
||||
HDR_MODE_KEEP_HDR,
|
||||
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC,
|
||||
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL,
|
||||
HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR,
|
||||
})
|
||||
public @interface HdrMode {}
|
||||
|
||||
/**
|
||||
* Processes HDR input as HDR, to generate HDR output.
|
||||
*
|
||||
* <p>The HDR output format (ex. color transfer) will be the same as the HDR input format.
|
||||
*
|
||||
* <p>Supported on API 31+, by some device and HDR format combinations.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} will attempt to use {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}.
|
||||
*/
|
||||
public static final int HDR_MODE_KEEP_HDR = 0;
|
||||
|
||||
/**
|
||||
* Tone map HDR input to SDR before processing, to generate SDR output, using the {@link
|
||||
* android.media.MediaCodec} decoder tone-mapper.
|
||||
*
|
||||
* <p>Supported on API 31+, by some device and HDR format combinations. Tone-mapping is only
|
||||
* guaranteed to be supported on API 33+, on devices with HDR capture support.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} throws an {@link ExportException}.
|
||||
*/
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC = 1;
|
||||
|
||||
/**
|
||||
* Tone map HDR input to SDR before processing, to generate SDR output, using an OpenGL
|
||||
* tone-mapper.
|
||||
*
|
||||
* <p>Supported on API 29+.
|
||||
*
|
||||
* <p>This may exhibit mild differences from {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}, depending on the device's tone-mapping
|
||||
* implementation, but should have much wider support and have more consistent results across
|
||||
* devices.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} throws an {@link ExportException}.
|
||||
*/
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL = 2;
|
||||
|
||||
/**
|
||||
* Interpret HDR input as SDR, likely with a washed out look.
|
||||
*
|
||||
* <p>This is much more widely supported than {@link #HDR_MODE_KEEP_HDR} and {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}. However, as HDR transfer functions and
|
||||
* metadata will be ignored, contents will be displayed incorrectly, likely with a washed out
|
||||
* look.
|
||||
*
|
||||
* <p>Using this API may lead to codec errors before API 29.
|
||||
*
|
||||
* <p>Use of this flag may result in {@code ERROR_CODE_DECODING_FORMAT_UNSUPPORTED}.
|
||||
*
|
||||
* <p>This field is experimental, and will be renamed or removed in a future release.
|
||||
*/
|
||||
public static final int HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR = 3;
|
||||
|
||||
/**
|
||||
* The {@link EditedMediaItemSequence} instances to compose.
|
||||
*
|
||||
@ -200,12 +296,20 @@ public final class Composition {
|
||||
*/
|
||||
public final boolean transmuxVideo;
|
||||
|
||||
/**
|
||||
* The {@link HdrMode} specifying how to handle HDR input video.
|
||||
*
|
||||
* <p>For more information, see {@link Builder#setHdrMode(int)}.
|
||||
*/
|
||||
public final @HdrMode int hdrMode;
|
||||
|
||||
private Composition(
|
||||
List<EditedMediaItemSequence> sequences,
|
||||
Effects effects,
|
||||
boolean forceAudioTrack,
|
||||
boolean transmuxAudio,
|
||||
boolean transmuxVideo) {
|
||||
boolean transmuxVideo,
|
||||
@HdrMode int hdrMode) {
|
||||
checkArgument(
|
||||
!transmuxAudio || !forceAudioTrack,
|
||||
"Audio transmuxing and audio track forcing are not allowed together.");
|
||||
@ -214,5 +318,6 @@ public final class Composition {
|
||||
this.transmuxAudio = transmuxAudio;
|
||||
this.transmuxVideo = transmuxVideo;
|
||||
this.forceAudioTrack = forceAudioTrack;
|
||||
this.hdrMode = hdrMode;
|
||||
}
|
||||
}
|
||||
|
@ -35,15 +35,7 @@ import java.lang.annotation.Target;
|
||||
@UnstableApi
|
||||
public final class TransformationRequest {
|
||||
|
||||
/**
|
||||
* The strategy to use to transcode or edit High Dynamic Range (HDR) input video.
|
||||
*
|
||||
* <p>One of {@link #HDR_MODE_KEEP_HDR}, {@link #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC},
|
||||
* {@link #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL}, or {@link
|
||||
* #HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}.
|
||||
*
|
||||
* <p>Standard Dynamic Range (SDR) input video is unaffected by these settings.
|
||||
*/
|
||||
/** See {@link Composition.HdrMode}. */
|
||||
@Documented
|
||||
@Retention(SOURCE)
|
||||
@Target(TYPE_USE)
|
||||
@ -55,59 +47,20 @@ public final class TransformationRequest {
|
||||
})
|
||||
public @interface HdrMode {}
|
||||
|
||||
/**
|
||||
* Processes HDR input as HDR, to generate HDR output.
|
||||
*
|
||||
* <p>The HDR output format (ex. color transfer) will be the same as the HDR input format.
|
||||
*
|
||||
* <p>Supported on API 31+, by some device and HDR format combinations.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} will attempt to use {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}.
|
||||
*/
|
||||
public static final int HDR_MODE_KEEP_HDR = 0;
|
||||
/** See {@link Composition#HDR_MODE_KEEP_HDR}. */
|
||||
public static final int HDR_MODE_KEEP_HDR = Composition.HDR_MODE_KEEP_HDR;
|
||||
|
||||
/**
|
||||
* Tone map HDR input to SDR before processing, to generate SDR output, using the {@link
|
||||
* android.media.MediaCodec} decoder tone-mapper.
|
||||
*
|
||||
* <p>Supported on API 31+, by some device and HDR format combinations. Tone-mapping is only
|
||||
* guaranteed to be supported on API 33+, on devices with HDR capture support.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} throws an {@link ExportException}.
|
||||
*/
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC = 1;
|
||||
/** See {@link Composition#HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}. */
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC =
|
||||
Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;
|
||||
|
||||
/**
|
||||
* Tone map HDR input to SDR before processing, to generate SDR output, using an OpenGL
|
||||
* tone-mapper.
|
||||
*
|
||||
* <p>Supported on API 29+.
|
||||
*
|
||||
* <p>This may exhibit mild differences from {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}, depending on the device's tone-mapping
|
||||
* implementation, but should have much wider support and have more consistent results across
|
||||
* devices.
|
||||
*
|
||||
* <p>If not supported, {@link Transformer} throws an {@link ExportException}.
|
||||
*/
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL = 2;
|
||||
/** See {@link Composition#HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL}. */
|
||||
public static final int HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL =
|
||||
Composition.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
|
||||
|
||||
/**
|
||||
* Interpret HDR input as SDR, likely with a washed out look.
|
||||
*
|
||||
* <p>This is much more widely supported than {@link #HDR_MODE_KEEP_HDR} and {@link
|
||||
* #HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC}. However, as HDR transfer functions and
|
||||
* metadata will be ignored, contents will be displayed incorrectly, likely with a washed out
|
||||
* look.
|
||||
*
|
||||
* <p>Using this API may lead to codec errors before API 29.
|
||||
*
|
||||
* <p>Use of this flag may result in {@code ERROR_CODE_DECODING_FORMAT_UNSUPPORTED}.
|
||||
*
|
||||
* <p>This field is experimental, and will be renamed or removed in a future release.
|
||||
*/
|
||||
public static final int HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR = 3;
|
||||
/** See {@link Composition#HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR}. */
|
||||
public static final int HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR =
|
||||
Composition.HDR_MODE_EXPERIMENTAL_FORCE_INTERPRET_HDR_AS_SDR;
|
||||
|
||||
/** A builder for {@link TransformationRequest} instances. */
|
||||
public static final class Builder {
|
||||
|
@ -80,7 +80,9 @@ public final class Transformer {
|
||||
private final Context context;
|
||||
|
||||
// Optional fields.
|
||||
private TransformationRequest transformationRequest;
|
||||
private @MonotonicNonNull String audioMimeType;
|
||||
private @MonotonicNonNull String videoMimeType;
|
||||
private @MonotonicNonNull TransformationRequest transformationRequest;
|
||||
private ImmutableList<AudioProcessor> audioProcessors;
|
||||
private ImmutableList<Effect> videoEffects;
|
||||
private boolean removeAudio;
|
||||
@ -102,7 +104,6 @@ public final class Transformer {
|
||||
*/
|
||||
public Builder(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
transformationRequest = new TransformationRequest.Builder().build();
|
||||
audioProcessors = ImmutableList.of();
|
||||
videoEffects = ImmutableList.of();
|
||||
videoFrameProcessorFactory = new DefaultVideoFrameProcessor.Factory.Builder().build();
|
||||
@ -117,6 +118,8 @@ public final class Transformer {
|
||||
/** Creates a builder with the values of the provided {@link Transformer}. */
|
||||
private Builder(Transformer transformer) {
|
||||
this.context = transformer.context;
|
||||
this.audioMimeType = transformer.transformationRequest.audioMimeType;
|
||||
this.videoMimeType = transformer.transformationRequest.videoMimeType;
|
||||
this.transformationRequest = transformer.transformationRequest;
|
||||
this.audioProcessors = transformer.audioProcessors;
|
||||
this.videoEffects = transformer.videoEffects;
|
||||
@ -133,16 +136,72 @@ public final class Transformer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TransformationRequest} which configures the editing and transcoding options.
|
||||
* Sets the audio {@linkplain MimeTypes MIME type} of the output.
|
||||
*
|
||||
* <p>Actual applied values may differ, per device capabilities. {@link
|
||||
* Listener#onFallbackApplied(Composition, TransformationRequest, TransformationRequest)} will
|
||||
* be invoked with the actual applied values.
|
||||
* <p>If no audio MIME type is passed, the output audio MIME type is the same as the first
|
||||
* {@link MediaItem} in the {@link Composition}.
|
||||
*
|
||||
* @param transformationRequest The {@link TransformationRequest}.
|
||||
* <p>Supported MIME types are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link MimeTypes#AUDIO_AAC}
|
||||
* <li>{@link MimeTypes#AUDIO_AMR_NB}
|
||||
* <li>{@link MimeTypes#AUDIO_AMR_WB}
|
||||
* </ul>
|
||||
*
|
||||
* If the MIME type is not supported, {@link Transformer} will fallback to a supported MIME type
|
||||
* and {@link Listener#onFallbackApplied(Composition, TransformationRequest,
|
||||
* TransformationRequest)} will be invoked with the fallback value.
|
||||
*
|
||||
* @param audioMimeType The MIME type of the audio samples in the output.
|
||||
* @return This builder.
|
||||
* @throws IllegalArgumentException If the audio MIME type passed is not an audio {@linkplain
|
||||
* MimeTypes MIME type}.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setAudioMimeType(String audioMimeType) {
|
||||
checkArgument(MimeTypes.isAudio(audioMimeType), "Not an audio MIME type: " + audioMimeType);
|
||||
this.audioMimeType = audioMimeType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the video {@linkplain MimeTypes MIME type} of the output.
|
||||
*
|
||||
* <p>If no video MIME type is passed, the output video MIME type is the same as the first
|
||||
* {@link MediaItem} in the {@link Composition}.
|
||||
*
|
||||
* <p>Supported MIME types are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link MimeTypes#VIDEO_H263}
|
||||
* <li>{@link MimeTypes#VIDEO_H264}
|
||||
* <li>{@link MimeTypes#VIDEO_H265} from API level 24
|
||||
* <li>{@link MimeTypes#VIDEO_MP4V}
|
||||
* </ul>
|
||||
*
|
||||
* If the MIME type is not supported, {@link Transformer} will fallback to a supported MIME type
|
||||
* and {@link Listener#onFallbackApplied(Composition, TransformationRequest,
|
||||
* TransformationRequest)} will be invoked with the fallback value.
|
||||
*
|
||||
* @param videoMimeType The MIME type of the video samples in the output.
|
||||
* @return This builder.
|
||||
* @throws IllegalArgumentException If the video MIME type passed is not a video {@linkplain
|
||||
* MimeTypes MIME type}.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setVideoMimeType(String videoMimeType) {
|
||||
checkArgument(MimeTypes.isVideo(videoMimeType), "Not a video MIME type: " + videoMimeType);
|
||||
this.videoMimeType = videoMimeType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #setAudioMimeType(String)}, {@link #setVideoMimeType(String)} and
|
||||
* {@link Composition.Builder#setHdrMode(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setTransformationRequest(TransformationRequest transformationRequest) {
|
||||
this.transformationRequest = transformationRequest;
|
||||
return this;
|
||||
@ -376,6 +435,17 @@ public final class Transformer {
|
||||
* type.
|
||||
*/
|
||||
public Transformer build() {
|
||||
TransformationRequest.Builder transformationRequestBuilder =
|
||||
transformationRequest == null
|
||||
? new TransformationRequest.Builder()
|
||||
: transformationRequest.buildUpon();
|
||||
if (audioMimeType != null) {
|
||||
transformationRequestBuilder.setAudioMimeType(audioMimeType);
|
||||
}
|
||||
if (videoMimeType != null) {
|
||||
transformationRequestBuilder.setVideoMimeType(videoMimeType);
|
||||
}
|
||||
transformationRequest = transformationRequestBuilder.build();
|
||||
if (transformationRequest.audioMimeType != null) {
|
||||
checkSampleMimeType(transformationRequest.audioMimeType);
|
||||
}
|
||||
@ -720,6 +790,11 @@ public final class Transformer {
|
||||
TransformerInternalListener transformerInternalListener =
|
||||
new TransformerInternalListener(composition);
|
||||
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
|
||||
TransformationRequest transformationRequest = this.transformationRequest;
|
||||
if (composition.hdrMode != Composition.HDR_MODE_KEEP_HDR) {
|
||||
transformationRequest =
|
||||
transformationRequest.buildUpon().setHdrMode(composition.hdrMode).build();
|
||||
}
|
||||
FallbackListener fallbackListener =
|
||||
new FallbackListener(composition, listeners, applicationHandler, transformationRequest);
|
||||
DebugTraceUtil.reset();
|
||||
|
Loading…
x
Reference in New Issue
Block a user