mirror of
https://github.com/androidx/media.git
synced 2025-05-12 01:59:50 +08:00
Refactor TransformationException.createForCodec
method overloads.
* Overload added `(cause, errorCode, isVideo, isDecoder, details)`, where `details` is a string of values to be added to the error message of the `TransformationException`. * Overload with `MediaFormat` and `mediaCodecName` moved to `DefaultCodec`, because all usages of that overload were from `DefaultCodec`, and this allows a simplified API because of internally stored values. * `mediaCodecName` removed from overload that takes a `Format`. * Reordered `createForCodec` parameters. PiperOrigin-RevId: 506895268
This commit is contained in:
parent
83074c0dcd
commit
937fcf9c4a
@ -154,11 +154,10 @@ public class TransformerEndToEndTest {
|
|||||||
public Codec createForVideoEncoding(Format format) throws TransformationException {
|
public Codec createForVideoEncoding(Format format) throws TransformationException {
|
||||||
throw TransformationException.createForCodec(
|
throw TransformationException.createForCodec(
|
||||||
new IllegalArgumentException(),
|
new IllegalArgumentException(),
|
||||||
|
TransformationException.ERROR_CODE_ENCODER_INIT_FAILED,
|
||||||
/* isVideo= */ true,
|
/* isVideo= */ true,
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
format,
|
format);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_ENCODER_INIT_FAILED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,6 +44,7 @@ import com.google.android.exoplayer2.video.ColorInfo;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
@ -64,6 +65,8 @@ public final class DefaultCodec implements Codec {
|
|||||||
private final MediaCodec mediaCodec;
|
private final MediaCodec mediaCodec;
|
||||||
@Nullable private final Surface inputSurface;
|
@Nullable private final Surface inputSurface;
|
||||||
private final int maxPendingFrameCount;
|
private final int maxPendingFrameCount;
|
||||||
|
private final boolean isDecoder;
|
||||||
|
private final boolean isVideo;
|
||||||
|
|
||||||
private @MonotonicNonNull Format outputFormat;
|
private @MonotonicNonNull Format outputFormat;
|
||||||
@Nullable private ByteBuffer outputBuffer;
|
@Nullable private ByteBuffer outputBuffer;
|
||||||
@ -96,17 +99,18 @@ public final class DefaultCodec implements Codec {
|
|||||||
throws TransformationException {
|
throws TransformationException {
|
||||||
this.configurationFormat = configurationFormat;
|
this.configurationFormat = configurationFormat;
|
||||||
this.configurationMediaFormat = configurationMediaFormat;
|
this.configurationMediaFormat = configurationMediaFormat;
|
||||||
|
this.isDecoder = isDecoder;
|
||||||
|
isVideo = MimeTypes.isVideo(checkNotNull(configurationFormat.sampleMimeType));
|
||||||
outputBufferInfo = new BufferInfo();
|
outputBufferInfo = new BufferInfo();
|
||||||
inputBufferIndex = C.INDEX_UNSET;
|
inputBufferIndex = C.INDEX_UNSET;
|
||||||
outputBufferIndex = C.INDEX_UNSET;
|
outputBufferIndex = C.INDEX_UNSET;
|
||||||
|
|
||||||
boolean isVideo = MimeTypes.isVideo(checkNotNull(configurationFormat.sampleMimeType));
|
|
||||||
@Nullable MediaCodec mediaCodec = null;
|
@Nullable MediaCodec mediaCodec = null;
|
||||||
@Nullable Surface inputSurface = null;
|
@Nullable Surface inputSurface = null;
|
||||||
boolean requestedHdrToneMapping;
|
boolean requestedHdrToneMapping =
|
||||||
|
SDK_INT >= 29 && Api29.isSdrToneMappingEnabled(configurationMediaFormat);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
requestedHdrToneMapping =
|
|
||||||
SDK_INT >= 29 && Api29.isSdrToneMappingEnabled(configurationMediaFormat);
|
|
||||||
mediaCodec = MediaCodec.createByCodecName(mediaCodecName);
|
mediaCodec = MediaCodec.createByCodecName(mediaCodecName);
|
||||||
configureCodec(mediaCodec, configurationMediaFormat, isDecoder, outputSurface);
|
configureCodec(mediaCodec, configurationMediaFormat, isDecoder, outputSurface);
|
||||||
if (SDK_INT >= 29 && requestedHdrToneMapping) {
|
if (SDK_INT >= 29 && requestedHdrToneMapping) {
|
||||||
@ -129,8 +133,21 @@ public final class DefaultCodec implements Codec {
|
|||||||
mediaCodec.release();
|
mediaCodec.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw createInitializationTransformationException(
|
@TransformationException.ErrorCode int errorCode;
|
||||||
e, configurationMediaFormat, isVideo, isDecoder, mediaCodecName);
|
if (e instanceof IOException || e instanceof MediaCodec.CodecException) {
|
||||||
|
errorCode =
|
||||||
|
isDecoder
|
||||||
|
? TransformationException.ERROR_CODE_DECODER_INIT_FAILED
|
||||||
|
: TransformationException.ERROR_CODE_ENCODER_INIT_FAILED;
|
||||||
|
} else if (e instanceof IllegalArgumentException) {
|
||||||
|
errorCode =
|
||||||
|
isDecoder
|
||||||
|
? TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED
|
||||||
|
: TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
errorCode = TransformationException.ERROR_CODE_FAILED_RUNTIME_CHECK;
|
||||||
|
}
|
||||||
|
throw createTransformationException(e, errorCode, mediaCodecName);
|
||||||
}
|
}
|
||||||
this.mediaCodec = mediaCodec;
|
this.mediaCodec = mediaCodec;
|
||||||
this.inputSurface = inputSurface;
|
this.inputSurface = inputSurface;
|
||||||
@ -353,17 +370,24 @@ public final class DefaultCodec implements Codec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TransformationException createTransformationException(Exception cause) {
|
private TransformationException createTransformationException(Exception cause) {
|
||||||
boolean isDecoder = !mediaCodec.getCodecInfo().isEncoder();
|
return createTransformationException(
|
||||||
boolean isVideo = MimeTypes.isVideo(configurationFormat.sampleMimeType);
|
|
||||||
return TransformationException.createForCodec(
|
|
||||||
cause,
|
cause,
|
||||||
isVideo,
|
|
||||||
isDecoder,
|
|
||||||
configurationMediaFormat,
|
|
||||||
getName(),
|
|
||||||
isDecoder
|
isDecoder
|
||||||
? TransformationException.ERROR_CODE_DECODING_FAILED
|
? TransformationException.ERROR_CODE_DECODING_FAILED
|
||||||
: TransformationException.ERROR_CODE_ENCODING_FAILED);
|
: TransformationException.ERROR_CODE_ENCODING_FAILED,
|
||||||
|
getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a {@link TransformationException} with specific {@link MediaCodec} details. */
|
||||||
|
private TransformationException createTransformationException(
|
||||||
|
@UnknownInitialization DefaultCodec this,
|
||||||
|
Exception cause,
|
||||||
|
@TransformationException.ErrorCode int errorCode,
|
||||||
|
String mediaCodecName) {
|
||||||
|
String codecDetails =
|
||||||
|
"mediaFormat=" + configurationMediaFormat + ", mediaCodecName=" + mediaCodecName;
|
||||||
|
return TransformationException.createForCodec(
|
||||||
|
cause, errorCode, isVideo, isDecoder, codecDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean areColorTransfersEqual(
|
private static boolean areColorTransfersEqual(
|
||||||
@ -379,37 +403,6 @@ public final class DefaultCodec implements Codec {
|
|||||||
return transfer1 == transfer2;
|
return transfer1 == transfer2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TransformationException createInitializationTransformationException(
|
|
||||||
Exception cause,
|
|
||||||
MediaFormat mediaFormat,
|
|
||||||
boolean isVideo,
|
|
||||||
boolean isDecoder,
|
|
||||||
@Nullable String mediaCodecName) {
|
|
||||||
if (cause instanceof IOException || cause instanceof MediaCodec.CodecException) {
|
|
||||||
return TransformationException.createForCodec(
|
|
||||||
cause,
|
|
||||||
isVideo,
|
|
||||||
isDecoder,
|
|
||||||
mediaFormat,
|
|
||||||
mediaCodecName,
|
|
||||||
isDecoder
|
|
||||||
? TransformationException.ERROR_CODE_DECODER_INIT_FAILED
|
|
||||||
: TransformationException.ERROR_CODE_ENCODER_INIT_FAILED);
|
|
||||||
}
|
|
||||||
if (cause instanceof IllegalArgumentException) {
|
|
||||||
return TransformationException.createForCodec(
|
|
||||||
cause,
|
|
||||||
isVideo,
|
|
||||||
isDecoder,
|
|
||||||
mediaFormat,
|
|
||||||
mediaCodecName,
|
|
||||||
isDecoder
|
|
||||||
? TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED
|
|
||||||
: TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED);
|
|
||||||
}
|
|
||||||
return TransformationException.createForUnexpected(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Format convertToFormat(MediaFormat mediaFormat) {
|
private static Format convertToFormat(MediaFormat mediaFormat) {
|
||||||
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
||||||
int csdIndex = 0;
|
int csdIndex = 0;
|
||||||
|
@ -112,10 +112,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
private static TransformationException createTransformationException(Format format) {
|
private static TransformationException createTransformationException(Format format) {
|
||||||
return TransformationException.createForCodec(
|
return TransformationException.createForCodec(
|
||||||
new IllegalArgumentException("The requested decoding format is not supported."),
|
new IllegalArgumentException("The requested decoding format is not supported."),
|
||||||
|
TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||||
MimeTypes.isVideo(format.sampleMimeType),
|
MimeTypes.isVideo(format.sampleMimeType),
|
||||||
/* isDecoder= */ true,
|
/* isDecoder= */ true,
|
||||||
format,
|
format);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -676,10 +676,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
Format format, @TransformationException.ErrorCode int errorCode) {
|
Format format, @TransformationException.ErrorCode int errorCode) {
|
||||||
return TransformationException.createForCodec(
|
return TransformationException.createForCodec(
|
||||||
new IllegalArgumentException("The requested encoding format is not supported."),
|
new IllegalArgumentException("The requested encoding format is not supported."),
|
||||||
|
errorCode,
|
||||||
MimeTypes.isVideo(format.sampleMimeType),
|
MimeTypes.isVideo(format.sampleMimeType),
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
format,
|
format);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
errorCode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,11 +48,10 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||||||
Format requestedEncoderFormat) {
|
Format requestedEncoderFormat) {
|
||||||
return TransformationException.createForCodec(
|
return TransformationException.createForCodec(
|
||||||
new IllegalArgumentException("No MIME type is supported by both encoder and muxer."),
|
new IllegalArgumentException("No MIME type is supported by both encoder and muxer."),
|
||||||
|
TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED,
|
||||||
MimeTypes.isVideo(requestedEncoderFormat.sampleMimeType),
|
MimeTypes.isVideo(requestedEncoderFormat.sampleMimeType),
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
requestedEncoderFormat,
|
requestedEncoderFormat);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,8 +17,6 @@ package com.google.android.exoplayer2.transformer;
|
|||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import android.media.MediaCodec;
|
|
||||||
import android.media.MediaFormat;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -219,56 +217,46 @@ public final class TransformationException extends Exception {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance for a decoder or encoder related exception.
|
* Creates an instance for a {@link Codec} related exception.
|
||||||
*
|
*
|
||||||
* <p>Use this method after the {@link MediaFormat} used to configure the {@link Codec} is known.
|
* <p>This method should be used when the {@code cause} occurs before the {@link Codec} is
|
||||||
|
* initialized.
|
||||||
*
|
*
|
||||||
* @param cause The cause of the failure.
|
* @param cause The cause of the failure.
|
||||||
* @param isVideo Whether the decoder or encoder is configured for video.
|
|
||||||
* @param isDecoder Whether the exception is created for a decoder.
|
|
||||||
* @param mediaFormat The {@link MediaFormat} used for configuring the underlying {@link
|
|
||||||
* MediaCodec}.
|
|
||||||
* @param mediaCodecName The name of the {@link MediaCodec} used, if known.
|
|
||||||
* @param errorCode See {@link #errorCode}.
|
* @param errorCode See {@link #errorCode}.
|
||||||
|
* @param isVideo Whether the {@link Codec} is configured for video.
|
||||||
|
* @param isDecoder Whether the exception is created for a decoder.
|
||||||
|
* @param format The {@link Format} used for configuring the {@link Codec}.
|
||||||
* @return The created instance.
|
* @return The created instance.
|
||||||
*/
|
*/
|
||||||
public static TransformationException createForCodec(
|
public static TransformationException createForCodec(
|
||||||
Throwable cause,
|
Throwable cause,
|
||||||
|
@ErrorCode int errorCode,
|
||||||
boolean isVideo,
|
boolean isVideo,
|
||||||
boolean isDecoder,
|
boolean isDecoder,
|
||||||
MediaFormat mediaFormat,
|
Format format) {
|
||||||
@Nullable String mediaCodecName,
|
String details = "format=" + format;
|
||||||
int errorCode) {
|
return createForCodec(cause, errorCode, isVideo, isDecoder, details);
|
||||||
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
|
||||||
String errorMessage =
|
|
||||||
componentName + ", mediaFormat=" + mediaFormat + ", mediaCodecName=" + mediaCodecName;
|
|
||||||
return new TransformationException(errorMessage, cause, errorCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance for a decoder or encoder related exception.
|
* Creates an instance for a {@link Codec} related exception.
|
||||||
*
|
|
||||||
* <p>Use this method before configuring the {@link Codec}, or when the {@link Codec} is not
|
|
||||||
* configured with a {@link MediaFormat}.
|
|
||||||
*
|
*
|
||||||
* @param cause The cause of the failure.
|
* @param cause The cause of the failure.
|
||||||
* @param isVideo Whether the decoder or encoder is configured for video.
|
|
||||||
* @param isDecoder Whether the exception is created for a decoder.
|
|
||||||
* @param format The {@link Format} used for configuring the {@link Codec}.
|
|
||||||
* @param mediaCodecName The name of the {@link MediaCodec} used, if known.
|
|
||||||
* @param errorCode See {@link #errorCode}.
|
* @param errorCode See {@link #errorCode}.
|
||||||
|
* @param isVideo Whether the {@link Codec} is configured for video.
|
||||||
|
* @param isDecoder Whether the exception is created for a decoder.
|
||||||
|
* @param details The details associated with this exception.
|
||||||
* @return The created instance.
|
* @return The created instance.
|
||||||
*/
|
*/
|
||||||
public static TransformationException createForCodec(
|
public static TransformationException createForCodec(
|
||||||
Throwable cause,
|
Throwable cause,
|
||||||
|
@ErrorCode int errorCode,
|
||||||
boolean isVideo,
|
boolean isVideo,
|
||||||
boolean isDecoder,
|
boolean isDecoder,
|
||||||
Format format,
|
String details) {
|
||||||
@Nullable String mediaCodecName,
|
|
||||||
int errorCode) {
|
|
||||||
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
||||||
String errorMessage =
|
String errorMessage = componentName + " error: " + details;
|
||||||
componentName + " error, format=" + format + ", mediaCodecName=" + mediaCodecName;
|
|
||||||
return new TransformationException(errorMessage, cause, errorCode);
|
return new TransformationException(errorMessage, cause, errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,11 +89,10 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
if (SDK_INT < 29) {
|
if (SDK_INT < 29) {
|
||||||
throw TransformationException.createForCodec(
|
throw TransformationException.createForCodec(
|
||||||
new IllegalArgumentException("Interpreting HDR video as SDR is not supported."),
|
new IllegalArgumentException("Interpreting HDR video as SDR is not supported."),
|
||||||
|
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED,
|
||||||
/* isVideo= */ true,
|
/* isVideo= */ true,
|
||||||
/* isDecoder= */ true,
|
/* isDecoder= */ true,
|
||||||
firstInputFormat,
|
firstInputFormat);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED);
|
|
||||||
}
|
}
|
||||||
firstInputFormat =
|
firstInputFormat =
|
||||||
firstInputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build();
|
firstInputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build();
|
||||||
@ -102,21 +101,19 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
throw TransformationException.createForCodec(
|
throw TransformationException.createForCodec(
|
||||||
new IllegalArgumentException(
|
new IllegalArgumentException(
|
||||||
"OpenGL-based HDR to SDR tone mapping is not supported."),
|
"OpenGL-based HDR to SDR tone mapping is not supported."),
|
||||||
|
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED,
|
||||||
/* isVideo= */ true,
|
/* isVideo= */ true,
|
||||||
/* isDecoder= */ true,
|
/* isDecoder= */ true,
|
||||||
firstInputFormat,
|
firstInputFormat);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED);
|
|
||||||
}
|
}
|
||||||
isGlToneMapping = true;
|
isGlToneMapping = true;
|
||||||
} else if (SDK_INT < 31 || deviceNeedsNoToneMappingWorkaround()) {
|
} else if (SDK_INT < 31 || deviceNeedsNoToneMappingWorkaround()) {
|
||||||
throw TransformationException.createForCodec(
|
throw TransformationException.createForCodec(
|
||||||
new IllegalArgumentException("HDR editing and tone mapping is not supported."),
|
new IllegalArgumentException("HDR editing and tone mapping is not supported."),
|
||||||
|
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED,
|
||||||
/* isVideo= */ true,
|
/* isVideo= */ true,
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
firstInputFormat,
|
firstInputFormat);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,11 +446,10 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
new IllegalStateException(
|
new IllegalStateException(
|
||||||
"No MIME type supported by both encoder and muxer for requested HDR colorInfo: "
|
"No MIME type supported by both encoder and muxer for requested HDR colorInfo: "
|
||||||
+ requestedEncoderFormat.colorInfo),
|
+ requestedEncoderFormat.colorInfo),
|
||||||
|
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED,
|
||||||
/* isVideo= */ true,
|
/* isVideo= */ true,
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
requestedEncoderFormat,
|
requestedEncoderFormat);
|
||||||
/* mediaCodecName= */ null,
|
|
||||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED);
|
|
||||||
} else {
|
} else {
|
||||||
throw createNoSupportedMimeTypeException(requestedEncoderFormat);
|
throw createNoSupportedMimeTypeException(requestedEncoderFormat);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user