Use same decoder selection logic is test as in DefaultDecoderFactory

The decoder selection logic in DefaultDecoderFactory is more mature
and can find alternative decoders.

PiperOrigin-RevId: 711378121
This commit is contained in:
sheenachhabra 2025-01-02 03:47:27 -08:00 committed by Copybara-Service
parent 969c50d60f
commit 9cc4532f84
2 changed files with 19 additions and 47 deletions

View File

@ -35,10 +35,8 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.media.Image;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.ColorInfo;
@ -49,7 +47,6 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.GlRect;
import androidx.media3.common.util.GlUtil;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util;
import androidx.media3.effect.ByteBufferGlEffect;
@ -58,6 +55,7 @@ import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlShaderProgram;
import androidx.media3.effect.PassthroughShaderProgram;
import androidx.media3.effect.ScaleAndRotateTransformation;
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
import androidx.media3.muxer.Muxer;
import androidx.media3.test.utils.BitmapPixelTestUtil;
@ -69,6 +67,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -1295,7 +1294,6 @@ public final class AndroidTestUtil {
@Nullable Format outputFormat,
boolean isPortraitEncodingEnabled)
throws IOException, JSONException, MediaCodecUtil.DecoderQueryException {
// TODO(b/278657595): Make this capability check match the default codec factory selection code.
boolean canDecode = inputFormat == null || canDecode(inputFormat);
boolean canEncode = outputFormat == null || canEncode(outputFormat, isPortraitEncodingEnabled);
@ -1347,21 +1345,28 @@ public final class AndroidTestUtil {
return SDK_INT > 24 ? new DefaultMuxer.Factory() : new InAppMuxer.Factory.Builder().build();
}
private static boolean canDecode(Format format) {
private static boolean canDecode(Format format) throws MediaCodecUtil.DecoderQueryException {
if (MimeTypes.isImage(format.sampleMimeType)) {
return Util.isBitmapFactorySupportedMimeType(format.sampleMimeType);
}
// Check decoding capability in the same way as the default decoder factory.
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
@Nullable
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
if (codecProfileAndLevel != null) {
MediaFormatUtil.maybeSetInteger(
mediaFormat, MediaFormat.KEY_PROFILE, codecProfileAndLevel.first);
}
return EncoderUtil.findCodecForFormat(mediaFormat, /* isDecoder= */ true) != null
&& !deviceNeedsDisable8kWorkaround(format);
return findDecoderForFormat(format) != null && !deviceNeedsDisable8kWorkaround(format);
}
@Nullable
private static String findDecoderForFormat(Format format)
throws MediaCodecUtil.DecoderQueryException {
List<androidx.media3.exoplayer.mediacodec.MediaCodecInfo> mediaCodecInfoList =
MediaCodecUtil.getDecoderInfosSortedByFormatSupport(
MediaCodecUtil.getDecoderInfosSoftMatch(
MediaCodecSelector.DEFAULT,
format,
/* requiresSecureDecoder= */ false,
/* requiresTunnelingDecoder= */ false),
format);
return mediaCodecInfoList.isEmpty() ? null : mediaCodecInfoList.get(0).name;
}
private static boolean deviceNeedsDisable8kWorkaround(Format format) {

View File

@ -24,7 +24,6 @@ import android.media.CamcorderProfile;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.util.Pair;
import android.util.Range;
import android.util.Size;
@ -37,7 +36,6 @@ import androidx.media3.common.C.ColorTransfer;
import androidx.media3.common.ColorInfo;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.MediaFormatUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.base.Ascii;
@ -327,37 +325,6 @@ public final class EncoderUtil {
return maxSupportedLevel;
}
/**
* Finds a {@link MediaCodec} that supports the {@link MediaFormat}, or {@code null} if none is
* found.
*/
@Nullable
public static String findCodecForFormat(MediaFormat format, boolean isDecoder) {
MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
// Format must not include KEY_FRAME_RATE on API21.
// https://developer.android.com/reference/android/media/MediaCodecList#findDecoderForFormat(android.media.MediaFormat)
float frameRate = Format.NO_VALUE;
if (Util.SDK_INT == 21 && format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
try {
frameRate = format.getFloat(MediaFormat.KEY_FRAME_RATE);
} catch (ClassCastException e) {
frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
}
// Clears the frame rate field.
format.setString(MediaFormat.KEY_FRAME_RATE, null);
}
String mediaCodecName =
isDecoder
? mediaCodecList.findDecoderForFormat(format)
: mediaCodecList.findEncoderForFormat(format);
if (Util.SDK_INT == 21) {
MediaFormatUtil.maybeSetInteger(format, MediaFormat.KEY_FRAME_RATE, round(frameRate));
}
return mediaCodecName;
}
/** Returns the range of supported bitrates for the given {@linkplain MimeTypes MIME type}. */
public static Range<Integer> getSupportedBitrateRange(
MediaCodecInfo encoderInfo, String mimeType) {