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:
andrewlewis 2023-11-27 04:02:38 -08:00 committed by Copybara-Service
parent c650f05234
commit 8b38b34b9f
3 changed files with 18 additions and 8 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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");
}
}