mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
parent
93f9e6574c
commit
33c3d5140e
@ -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;
|
||||
@ -1302,7 +1301,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);
|
||||
@ -1390,21 +1388,39 @@ 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 findDecoderForFormat(format) != null && !deviceNeedsDisable8kWorkaround(format);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String findDecoderForFormat(Format format)
|
||||
throws MediaCodecUtil.DecoderQueryException {
|
||||
List<androidx.media3.exoplayer.mediacodec.MediaCodecInfo> decoderInfoList =
|
||||
MediaCodecUtil.getDecoderInfosSortedByFormatSupport(
|
||||
MediaCodecUtil.getDecoderInfosSoftMatch(
|
||||
MediaCodecSelector.DEFAULT,
|
||||
format,
|
||||
/* requiresSecureDecoder= */ false,
|
||||
/* requiresTunnelingDecoder= */ false),
|
||||
format);
|
||||
|
||||
for (int i = 0; i < decoderInfoList.size(); i++) {
|
||||
androidx.media3.exoplayer.mediacodec.MediaCodecInfo decoderInfo = decoderInfoList.get(i);
|
||||
// On some devices this method can return false even when the format can be decoded. For
|
||||
// example, Pixel 6a can decode an 8K video but this method returns false. The
|
||||
// DefaultDecoderFactory does not rely on this method rather it directly initialize the
|
||||
// decoder. See b/222095724#comment9.
|
||||
if (decoderInfo.isFormatSupported(format)) {
|
||||
return decoderInfo.name;
|
||||
}
|
||||
}
|
||||
return EncoderUtil.findCodecForFormat(mediaFormat, /* isDecoder= */ true) != null
|
||||
&& !deviceNeedsDisable8kWorkaround(format);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean deviceNeedsDisable8kWorkaround(Format format) {
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user