mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add CodecDetails to ExportException
This will replace the existing free-form string in the error message PiperOrigin-RevId: 640954158
This commit is contained in:
parent
977fe6aef3
commit
ec0af5a7e0
@ -997,7 +997,7 @@ public class TransformerEndToEndTest {
|
|||||||
|
|
||||||
assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
|
assertThat(exception).hasCauseThat().isInstanceOf(IllegalArgumentException.class);
|
||||||
assertThat(exception.errorCode).isEqualTo(ExportException.ERROR_CODE_ENCODER_INIT_FAILED);
|
assertThat(exception.errorCode).isEqualTo(ExportException.ERROR_CODE_ENCODER_INIT_FAILED);
|
||||||
assertThat(exception).hasMessageThat().contains("video");
|
assertThat(exception.codecInfo.isVideo).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1813,9 +1813,8 @@ public class TransformerEndToEndTest {
|
|||||||
throw ExportException.createForCodec(
|
throw ExportException.createForCodec(
|
||||||
new IllegalArgumentException(),
|
new IllegalArgumentException(),
|
||||||
ExportException.ERROR_CODE_ENCODER_INIT_FAILED,
|
ExportException.ERROR_CODE_ENCODER_INIT_FAILED,
|
||||||
/* isVideo= */ true,
|
new ExportException.CodecInfo(
|
||||||
/* isDecoder= */ false,
|
format.toString(), /* isVideo= */ true, /* isDecoder= */ false, /* name= */ null));
|
||||||
format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -460,9 +460,10 @@ public final class DefaultCodec implements Codec {
|
|||||||
Exception cause,
|
Exception cause,
|
||||||
@ExportException.ErrorCode int errorCode,
|
@ExportException.ErrorCode int errorCode,
|
||||||
String mediaCodecName) {
|
String mediaCodecName) {
|
||||||
String codecDetails =
|
ExportException.CodecInfo codecInfo =
|
||||||
"mediaFormat=" + configurationMediaFormat + ", mediaCodecName=" + mediaCodecName;
|
new ExportException.CodecInfo(
|
||||||
return ExportException.createForCodec(cause, errorCode, isVideo, isDecoder, codecDetails);
|
configurationMediaFormat.toString(), isVideo, isDecoder, mediaCodecName);
|
||||||
|
return ExportException.createForCodec(cause, errorCode, codecInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Format convertToFormat(
|
private static Format convertToFormat(
|
||||||
|
@ -389,8 +389,10 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
return ExportException.createForCodec(
|
return ExportException.createForCodec(
|
||||||
new IllegalArgumentException(reason),
|
new IllegalArgumentException(reason),
|
||||||
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||||
|
new ExportException.CodecInfo(
|
||||||
|
format.toString(),
|
||||||
MimeTypes.isVideo(checkNotNull(format.sampleMimeType)),
|
MimeTypes.isVideo(checkNotNull(format.sampleMimeType)),
|
||||||
/* isDecoder= */ true,
|
/* isDecoder= */ true,
|
||||||
format);
|
/* name= */ null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,9 +711,11 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
return ExportException.createForCodec(
|
return ExportException.createForCodec(
|
||||||
new IllegalArgumentException(errorString),
|
new IllegalArgumentException(errorString),
|
||||||
ExportException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED,
|
ExportException.ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED,
|
||||||
|
new ExportException.CodecInfo(
|
||||||
|
format.toString(),
|
||||||
MimeTypes.isVideo(format.sampleMimeType),
|
MimeTypes.isVideo(format.sampleMimeType),
|
||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
format);
|
/* name= */ null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean deviceNeedsDefaultFrameRateWorkaround() {
|
private static boolean deviceNeedsDefaultFrameRateWorkaround() {
|
||||||
|
@ -17,6 +17,7 @@ package androidx.media3.transformer;
|
|||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
|
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;
|
||||||
@ -37,6 +38,46 @@ import java.lang.annotation.Target;
|
|||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class ExportException extends Exception {
|
public final class ExportException extends Exception {
|
||||||
|
|
||||||
|
/** The {@link Codec} details. */
|
||||||
|
public static final class CodecInfo {
|
||||||
|
/**
|
||||||
|
* A string describing the format used to configure the underlying codec, for example, the value
|
||||||
|
* returned by {@link Format#toString()} or {@link MediaFormat#toString()}.
|
||||||
|
*/
|
||||||
|
public final String configurationFormat;
|
||||||
|
|
||||||
|
/** Whether the {@link Codec} is configured for video. */
|
||||||
|
public final boolean isVideo;
|
||||||
|
|
||||||
|
/** Whether the {@link Codec} is used as a decoder. */
|
||||||
|
public final boolean isDecoder;
|
||||||
|
|
||||||
|
/** The {@link Codec} name, or {@code null} if the {@link Codec} is not yet initialized. */
|
||||||
|
@Nullable public final String name;
|
||||||
|
|
||||||
|
/** Creates an instance. */
|
||||||
|
public CodecInfo(
|
||||||
|
String configurationFormat, boolean isVideo, boolean isDecoder, @Nullable String name) {
|
||||||
|
this.configurationFormat = configurationFormat;
|
||||||
|
this.isVideo = isVideo;
|
||||||
|
this.isDecoder = isDecoder;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String type = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
||||||
|
return "CodecInfo{"
|
||||||
|
+ "type="
|
||||||
|
+ type
|
||||||
|
+ ", configurationFormat="
|
||||||
|
+ configurationFormat
|
||||||
|
+ ", name="
|
||||||
|
+ name
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes that identify causes of {@link Transformer} errors.
|
* Error codes that identify causes of {@link Transformer} errors.
|
||||||
*
|
*
|
||||||
@ -244,48 +285,14 @@ public final class ExportException extends Exception {
|
|||||||
/**
|
/**
|
||||||
* Creates an instance for a {@link Codec} related exception.
|
* Creates an instance for a {@link Codec} related exception.
|
||||||
*
|
*
|
||||||
* <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 errorCode See {@link #errorCode}.
|
* @param errorCode See {@link #errorCode}.
|
||||||
* @param isVideo Whether the {@link Codec} is configured for video.
|
* @param codecInfo The {@link CodecInfo}.
|
||||||
* @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 ExportException createForCodec(
|
public static ExportException createForCodec(
|
||||||
Throwable cause,
|
Throwable cause, @ErrorCode int errorCode, CodecInfo codecInfo) {
|
||||||
@ErrorCode int errorCode,
|
return new ExportException("Codec exception: " + codecInfo, cause, errorCode, codecInfo);
|
||||||
boolean isVideo,
|
|
||||||
boolean isDecoder,
|
|
||||||
Format format) {
|
|
||||||
String details = "format=" + format;
|
|
||||||
if (isVideo) {
|
|
||||||
details += ", colorInfo=" + format.colorInfo;
|
|
||||||
}
|
|
||||||
return createForCodec(cause, errorCode, isVideo, isDecoder, details);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance for a {@link Codec} related exception.
|
|
||||||
*
|
|
||||||
* @param cause The cause of the failure.
|
|
||||||
* @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 ExportException createForCodec(
|
|
||||||
Throwable cause,
|
|
||||||
@ErrorCode int errorCode,
|
|
||||||
boolean isVideo,
|
|
||||||
boolean isDecoder,
|
|
||||||
String details) {
|
|
||||||
String componentName = (isVideo ? "Video" : "Audio") + (isDecoder ? "Decoder" : "Encoder");
|
|
||||||
String errorMessage = componentName + " error: " + details;
|
|
||||||
return new ExportException(errorMessage, cause, errorCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -352,7 +359,13 @@ public final class ExportException extends Exception {
|
|||||||
public final long timestampMs;
|
public final long timestampMs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* The {@linkplain CodecInfo} for codec related exceptions, or {@code null} if the exception is
|
||||||
|
* not codec related.
|
||||||
|
*/
|
||||||
|
@Nullable public final CodecInfo codecInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance with {@code codecInfo} set to {@code null}.
|
||||||
*
|
*
|
||||||
* @param message See {@link #getMessage()}.
|
* @param message See {@link #getMessage()}.
|
||||||
* @param cause See {@link #getCause()}.
|
* @param cause See {@link #getCause()}.
|
||||||
@ -361,9 +374,27 @@ public final class ExportException extends Exception {
|
|||||||
*/
|
*/
|
||||||
private ExportException(
|
private ExportException(
|
||||||
@Nullable String message, @Nullable Throwable cause, @ErrorCode int errorCode) {
|
@Nullable String message, @Nullable Throwable cause, @ErrorCode int errorCode) {
|
||||||
|
this(message, cause, errorCode, /* codecInfo= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
|
* @param message See {@link #getMessage()}.
|
||||||
|
* @param cause See {@link #getCause()}.
|
||||||
|
* @param errorCode A number which identifies the cause of the error. May be one of the {@link
|
||||||
|
* ErrorCode ErrorCodes}.
|
||||||
|
* @param codecInfo The {@link CodecInfo}, or {@code null} if the exception is not codec related.
|
||||||
|
*/
|
||||||
|
private ExportException(
|
||||||
|
@Nullable String message,
|
||||||
|
@Nullable Throwable cause,
|
||||||
|
@ErrorCode int errorCode,
|
||||||
|
@Nullable CodecInfo codecInfo) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.errorCode = errorCode;
|
this.errorCode = errorCode;
|
||||||
this.timestampMs = Clock.DEFAULT.elapsedRealtime();
|
this.timestampMs = Clock.DEFAULT.elapsedRealtime();
|
||||||
|
this.codecInfo = codecInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,8 +208,7 @@ import java.util.List;
|
|||||||
return ExportException.createForCodec(
|
return ExportException.createForCodec(
|
||||||
new IllegalArgumentException(errorMessage),
|
new IllegalArgumentException(errorMessage),
|
||||||
errorCode,
|
errorCode,
|
||||||
isVideo,
|
new ExportException.CodecInfo(
|
||||||
/* isDecoder= */ false,
|
format.toString(), isVideo, /* isDecoder= */ false, /* name= */ null));
|
||||||
format);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user