Skip to content

Commit

Permalink
Work around codec frame rate issues in Redmi Note 9 Pro
Browse files Browse the repository at this point in the history
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
  • Loading branch information
andrewlewis authored and copybara-github committed Nov 27, 2023
1 parent c650f05 commit 8b38b34
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,9 @@ public void export4K60() throws Exception {
.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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
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.
Expand All @@ -66,7 +65,6 @@ public DefaultDecoderFactory(Context context) {

@Override
public DefaultCodec createForAudioDecoding(Format format) throws ExportException {
checkNotNull(format.sampleMimeType);
MediaFormat mediaFormat = createMediaFormatFromFormat(format);

String mediaCodecName;
Expand Down Expand Up @@ -98,8 +96,6 @@ public DefaultCodec createForAudioDecoding(Format format) throws ExportException
@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
Expand All @@ -118,6 +114,9 @@ public DefaultCodec createForVideoDecoding(
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) {
Expand Down Expand Up @@ -195,12 +194,16 @@ private static boolean deviceNeedsDisableToneMappingWorkaround(
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
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;
Expand Down Expand Up @@ -199,7 +200,7 @@ public DefaultCodec createForAudioEncoding(Format format) throws ExportException
*/
@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);
Expand Down Expand Up @@ -661,4 +662,9 @@ private static ExportException createExportException(Format format, String error
/* 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");
}
}

0 comments on commit 8b38b34

Please sign in to comment.