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))
|
.setEncoderFactory(new ForceEncodeEncoderFactory(context))
|
||||||
.build();
|
.build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_4K60_PORTRAIT_URI_STRING));
|
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)
|
new TransformerAndroidTestRunner.Builder(context, transformer)
|
||||||
.setRequestCalculateSsim(true)
|
.setRequestCalculateSsim(!skipCalculateSsim)
|
||||||
.setTimeoutSeconds(180)
|
.setTimeoutSeconds(180)
|
||||||
.build()
|
.build()
|
||||||
.run(testId, mediaItem);
|
.run(testId, mediaItem);
|
||||||
|
@ -41,7 +41,6 @@ import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
|
|||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of {@link Codec.DecoderFactory} that uses {@link MediaCodec} for decoding.
|
* Default implementation of {@link Codec.DecoderFactory} that uses {@link MediaCodec} for decoding.
|
||||||
@ -66,7 +65,6 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DefaultCodec createForAudioDecoding(Format format) throws ExportException {
|
public DefaultCodec createForAudioDecoding(Format format) throws ExportException {
|
||||||
checkNotNull(format.sampleMimeType);
|
|
||||||
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
||||||
|
|
||||||
String mediaCodecName;
|
String mediaCodecName;
|
||||||
@ -98,8 +96,6 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
@Override
|
@Override
|
||||||
public DefaultCodec createForVideoDecoding(
|
public DefaultCodec createForVideoDecoding(
|
||||||
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException {
|
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException {
|
||||||
checkNotNull(format.sampleMimeType);
|
|
||||||
|
|
||||||
if (ColorInfo.isTransferHdr(format.colorInfo)) {
|
if (ColorInfo.isTransferHdr(format.colorInfo)) {
|
||||||
if (requestSdrToneMapping
|
if (requestSdrToneMapping
|
||||||
&& (SDK_INT < 31
|
&& (SDK_INT < 31
|
||||||
@ -118,6 +114,9 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
throw createExportException(
|
throw createExportException(
|
||||||
format, /* reason= */ "Decoding 8k is not supported on this device.");
|
format, /* reason= */ "Decoding 8k is not supported on this device.");
|
||||||
}
|
}
|
||||||
|
if (deviceNeedsNoFrameRateWorkaround()) {
|
||||||
|
format = format.buildUpon().setFrameRate(Format.NO_VALUE).build();
|
||||||
|
}
|
||||||
|
|
||||||
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
||||||
if (decoderSupportsKeyAllowFrameDrop) {
|
if (decoderSupportsKeyAllowFrameDrop) {
|
||||||
@ -195,12 +194,16 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
|||||||
return false;
|
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) {
|
private static ExportException createExportException(Format format, String reason) {
|
||||||
return ExportException.createForCodec(
|
return ExportException.createForCodec(
|
||||||
new IllegalArgumentException(reason),
|
new IllegalArgumentException(reason),
|
||||||
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
ExportException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED,
|
||||||
MimeTypes.isVideo(format.sampleMimeType),
|
MimeTypes.isVideo(checkNotNull(format.sampleMimeType)),
|
||||||
/* isDecoder= */ true,
|
/* isDecoder= */ true,
|
||||||
format);
|
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.checkState;
|
||||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||||
import static androidx.media3.common.util.MediaFormatUtil.createMediaFormatFromFormat;
|
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.abs;
|
||||||
import static java.lang.Math.floor;
|
import static java.lang.Math.floor;
|
||||||
import static java.lang.Math.round;
|
import static java.lang.Math.round;
|
||||||
@ -199,7 +200,7 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public DefaultCodec createForVideoEncoding(Format format) throws ExportException {
|
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();
|
format = format.buildUpon().setFrameRate(DEFAULT_FRAME_RATE).build();
|
||||||
}
|
}
|
||||||
checkArgument(format.width != Format.NO_VALUE);
|
checkArgument(format.width != Format.NO_VALUE);
|
||||||
@ -661,4 +662,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
|||||||
/* isDecoder= */ false,
|
/* isDecoder= */ false,
|
||||||
format);
|
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