mirror of
https://github.com/androidx/media.git
synced 2025-05-11 01:31:40 +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 {
|
||||
throw TransformationException.createForCodec(
|
||||
new IllegalArgumentException(),
|
||||
TransformationException.ERROR_CODE_ENCODER_INIT_FAILED,
|
||||
/* isVideo= */ true,
|
||||
/* isDecoder= */ false,
|
||||
format,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_ENCODER_INIT_FAILED);
|
||||
format);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,6 +44,7 @@ import com.google.android.exoplayer2.video.ColorInfo;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
@ -64,6 +65,8 @@ public final class DefaultCodec implements Codec {
|
||||
private final MediaCodec mediaCodec;
|
||||
@Nullable private final Surface inputSurface;
|
||||
private final int maxPendingFrameCount;
|
||||
private final boolean isDecoder;
|
||||
private final boolean isVideo;
|
||||
|
||||
private @MonotonicNonNull Format outputFormat;
|
||||
@Nullable private ByteBuffer outputBuffer;
|
||||
@ -96,17 +99,18 @@ public final class DefaultCodec implements Codec {
|
||||
throws TransformationException {
|
||||
this.configurationFormat = configurationFormat;
|
||||
this.configurationMediaFormat = configurationMediaFormat;
|
||||
this.isDecoder = isDecoder;
|
||||
isVideo = MimeTypes.isVideo(checkNotNull(configurationFormat.sampleMimeType));
|
||||
outputBufferInfo = new BufferInfo();
|
||||
inputBufferIndex = C.INDEX_UNSET;
|
||||
outputBufferIndex = C.INDEX_UNSET;
|
||||
|
||||
boolean isVideo = MimeTypes.isVideo(checkNotNull(configurationFormat.sampleMimeType));
|
||||
@Nullable MediaCodec mediaCodec = null;
|
||||
@Nullable Surface inputSurface = null;
|
||||
boolean requestedHdrToneMapping;
|
||||
boolean requestedHdrToneMapping =
|
||||
SDK_INT >= 29 && Api29.isSdrToneMappingEnabled(configurationMediaFormat);
|
||||
|
||||
try {
|
||||
requestedHdrToneMapping =
|
||||
SDK_INT >= 29 && Api29.isSdrToneMappingEnabled(configurationMediaFormat);
|
||||
mediaCodec = MediaCodec.createByCodecName(mediaCodecName);
|
||||
configureCodec(mediaCodec, configurationMediaFormat, isDecoder, outputSurface);
|
||||
if (SDK_INT >= 29 && requestedHdrToneMapping) {
|
||||
@ -129,8 +133,21 @@ public final class DefaultCodec implements Codec {
|
||||
mediaCodec.release();
|
||||
}
|
||||
|
||||
throw createInitializationTransformationException(
|
||||
e, configurationMediaFormat, isVideo, isDecoder, mediaCodecName);
|
||||
@TransformationException.ErrorCode int errorCode;
|
||||
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.inputSurface = inputSurface;
|
||||
@ -353,17 +370,24 @@ public final class DefaultCodec implements Codec {
|
||||
}
|
||||
|
||||
private TransformationException createTransformationException(Exception cause) {
|
||||
boolean isDecoder = !mediaCodec.getCodecInfo().isEncoder();
|
||||
boolean isVideo = MimeTypes.isVideo(configurationFormat.sampleMimeType);
|
||||
return TransformationException.createForCodec(
|
||||
return createTransformationException(
|
||||
cause,
|
||||
isVideo,
|
||||
isDecoder,
|
||||
configurationMediaFormat,
|
||||
getName(),
|
||||
isDecoder
|
||||
? 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(
|
||||
@ -379,37 +403,6 @@ public final class DefaultCodec implements Codec {
|
||||
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) {
|
||||
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
||||
int csdIndex = 0;
|
||||
|
@ -112,10 +112,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
private static TransformationException createTransformationException(Format format) {
|
||||
return TransformationException.createForCodec(
|
||||
new IllegalArgumentException("The requested decoding format is not supported."),
|
||||
TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||
MimeTypes.isVideo(format.sampleMimeType),
|
||||
/* isDecoder= */ true,
|
||||
format,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED);
|
||||
format);
|
||||
}
|
||||
}
|
||||
|
@ -676,10 +676,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
Format format, @TransformationException.ErrorCode int errorCode) {
|
||||
return TransformationException.createForCodec(
|
||||
new IllegalArgumentException("The requested encoding format is not supported."),
|
||||
errorCode,
|
||||
MimeTypes.isVideo(format.sampleMimeType),
|
||||
/* isDecoder= */ false,
|
||||
format,
|
||||
/* mediaCodecName= */ null,
|
||||
errorCode);
|
||||
format);
|
||||
}
|
||||
}
|
||||
|
@ -48,11 +48,10 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
||||
Format requestedEncoderFormat) {
|
||||
return TransformationException.createForCodec(
|
||||
new IllegalArgumentException("No MIME type is supported by both encoder and muxer."),
|
||||
TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED,
|
||||
MimeTypes.isVideo(requestedEncoderFormat.sampleMimeType),
|
||||
/* isDecoder= */ false,
|
||||
requestedEncoderFormat,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED);
|
||||
requestedEncoderFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,8 +17,6 @@ package com.google.android.exoplayer2.transformer;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaFormat;
|
||||
import android.os.SystemClock;
|
||||
import androidx.annotation.IntDef;
|
||||
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 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 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.
|
||||
*/
|
||||
public static TransformationException createForCodec(
|
||||
Throwable cause,
|
||||
@ErrorCode int errorCode,
|
||||
boolean isVideo,
|
||||
boolean isDecoder,
|
||||
MediaFormat mediaFormat,
|
||||
@Nullable String mediaCodecName,
|
||||
int errorCode) {
|
||||
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
||||
String errorMessage =
|
||||
componentName + ", mediaFormat=" + mediaFormat + ", mediaCodecName=" + mediaCodecName;
|
||||
return new TransformationException(errorMessage, cause, errorCode);
|
||||
Format format) {
|
||||
String details = "format=" + format;
|
||||
return createForCodec(cause, errorCode, isVideo, isDecoder, details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance for a decoder or encoder related exception.
|
||||
*
|
||||
* <p>Use this method before configuring the {@link Codec}, or when the {@link Codec} is not
|
||||
* configured with a {@link MediaFormat}.
|
||||
* Creates an instance for a {@link Codec} related exception.
|
||||
*
|
||||
* @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 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.
|
||||
*/
|
||||
public static TransformationException createForCodec(
|
||||
Throwable cause,
|
||||
@ErrorCode int errorCode,
|
||||
boolean isVideo,
|
||||
boolean isDecoder,
|
||||
Format format,
|
||||
@Nullable String mediaCodecName,
|
||||
int errorCode) {
|
||||
String details) {
|
||||
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
||||
String errorMessage =
|
||||
componentName + " error, format=" + format + ", mediaCodecName=" + mediaCodecName;
|
||||
String errorMessage = componentName + " error: " + details;
|
||||
return new TransformationException(errorMessage, cause, errorCode);
|
||||
}
|
||||
|
||||
|
@ -89,11 +89,10 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
if (SDK_INT < 29) {
|
||||
throw TransformationException.createForCodec(
|
||||
new IllegalArgumentException("Interpreting HDR video as SDR is not supported."),
|
||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED,
|
||||
/* isVideo= */ true,
|
||||
/* isDecoder= */ true,
|
||||
firstInputFormat,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED);
|
||||
firstInputFormat);
|
||||
}
|
||||
firstInputFormat =
|
||||
firstInputFormat.buildUpon().setColorInfo(ColorInfo.SDR_BT709_LIMITED).build();
|
||||
@ -102,21 +101,19 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
throw TransformationException.createForCodec(
|
||||
new IllegalArgumentException(
|
||||
"OpenGL-based HDR to SDR tone mapping is not supported."),
|
||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED,
|
||||
/* isVideo= */ true,
|
||||
/* isDecoder= */ true,
|
||||
firstInputFormat,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_HDR_DECODING_UNSUPPORTED);
|
||||
firstInputFormat);
|
||||
}
|
||||
isGlToneMapping = true;
|
||||
} else if (SDK_INT < 31 || deviceNeedsNoToneMappingWorkaround()) {
|
||||
throw TransformationException.createForCodec(
|
||||
new IllegalArgumentException("HDR editing and tone mapping is not supported."),
|
||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED,
|
||||
/* isVideo= */ true,
|
||||
/* isDecoder= */ false,
|
||||
firstInputFormat,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED);
|
||||
firstInputFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,11 +446,10 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
new IllegalStateException(
|
||||
"No MIME type supported by both encoder and muxer for requested HDR colorInfo: "
|
||||
+ requestedEncoderFormat.colorInfo),
|
||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED,
|
||||
/* isVideo= */ true,
|
||||
/* isDecoder= */ false,
|
||||
requestedEncoderFormat,
|
||||
/* mediaCodecName= */ null,
|
||||
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED);
|
||||
requestedEncoderFormat);
|
||||
} else {
|
||||
throw createNoSupportedMimeTypeException(requestedEncoderFormat);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user