Work around codec frame rate issues in Redmi Note 9 Pro
The decoder and encoder won't accept high values for frame rate, so avoid setting the key when configuring the decoder, and set a default value for the encoder (where the key is required). Also skip SSIM calculation for 4k, where the device lacks concurrent decoding support. PiperOrigin-RevId: 585604976
This commit is contained in:
parent
c650f05234
commit
8b38b34b9f
@ -158,8 +158,9 @@ public class ExportTest {
|
||||
.setEncoderFactory(new ForceEncodeEncoderFactory(context))
|
||||
.build();
|
||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_4K60_PORTRAIT_URI_STRING));
|
||||
boolean skipCalculateSsim = Util.SDK_INT < 30 && Util.DEVICE.equals("joyeuse");
|
||||
new TransformerAndroidTestRunner.Builder(context, transformer)
|
||||
.setRequestCalculateSsim(true)
|
||||
.setRequestCalculateSsim(!skipCalculateSsim)
|
||||
.setTimeoutSeconds(180)
|
||||
.build()
|
||||
.run(testId, mediaItem);
|
||||
|
@ -41,7 +41,6 @@ import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
|
||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
||||
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link Codec.DecoderFactory} that uses {@link MediaCodec} for decoding.
|
||||
@ -66,7 +65,6 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
|
||||
@Override
|
||||
public DefaultCodec createForAudioDecoding(Format format) throws ExportException {
|
||||
checkNotNull(format.sampleMimeType);
|
||||
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
||||
|
||||
String mediaCodecName;
|
||||
@ -98,8 +96,6 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
@Override
|
||||
public DefaultCodec createForVideoDecoding(
|
||||
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException {
|
||||
checkNotNull(format.sampleMimeType);
|
||||
|
||||
if (ColorInfo.isTransferHdr(format.colorInfo)) {
|
||||
if (requestSdrToneMapping
|
||||
&& (SDK_INT < 31
|
||||
@ -118,6 +114,9 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
throw createExportException(
|
||||
format, /* reason= */ "Decoding 8k is not supported on this device.");
|
||||
}
|
||||
if (deviceNeedsNoFrameRateWorkaround()) {
|
||||
format = format.buildUpon().setFrameRate(Format.NO_VALUE).build();
|
||||
}
|
||||
|
||||
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
||||
if (decoderSupportsKeyAllowFrameDrop) {
|
||||
@ -195,12 +194,16 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
return false;
|
||||
}
|
||||
|
||||
@RequiresNonNull("#1.sampleMimeType")
|
||||
private static boolean deviceNeedsNoFrameRateWorkaround() {
|
||||
// Redmi Note 9 Pro fails if KEY_FRAME_RATE is set too high (see b/278076311).
|
||||
return SDK_INT < 30 && Util.DEVICE.equals("joyeuse");
|
||||
}
|
||||
|
||||
private static ExportException createExportException(Format format, String reason) {
|
||||
return ExportException.createForCodec(
|
||||
new IllegalArgumentException(reason),
|
||||
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||
MimeTypes.isVideo(format.sampleMimeType),
|
||||
MimeTypes.isVideo(checkNotNull(format.sampleMimeType)),
|
||||
/* isDecoder= */ true,
|
||||
format);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||
import static androidx.media3.common.util.MediaFormatUtil.createMediaFormatFromFormat;
|
||||
import static androidx.media3.common.util.Util.SDK_INT;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.lang.Math.floor;
|
||||
import static java.lang.Math.round;
|
||||
@ -199,7 +200,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
*/
|
||||
@Override
|
||||
public DefaultCodec createForVideoEncoding(Format format) throws ExportException {
|
||||
if (format.frameRate == Format.NO_VALUE) {
|
||||
if (format.frameRate == Format.NO_VALUE || deviceNeedsDefaultFrameRateWorkaround()) {
|
||||
format = format.buildUpon().setFrameRate(DEFAULT_FRAME_RATE).build();
|
||||
}
|
||||
checkArgument(format.width != Format.NO_VALUE);
|
||||
@ -661,4 +662,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
/* isDecoder= */ false,
|
||||
format);
|
||||
}
|
||||
|
||||
private static boolean deviceNeedsDefaultFrameRateWorkaround() {
|
||||
// Redmi Note 9 Pro fails if KEY_FRAME_RATE is set too high (see b/278076311).
|
||||
return SDK_INT < 30 && Util.DEVICE.equals("joyeuse");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user