mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
parent
7ecaebe3d6
commit
750baf2c05
2 changed files with 47 additions and 19 deletions
|
|
@ -35,8 +35,10 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.Bitmap.Config;
|
import android.graphics.Bitmap.Config;
|
||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
|
import android.media.MediaFormat;
|
||||||
import android.opengl.EGLContext;
|
import android.opengl.EGLContext;
|
||||||
import android.opengl.EGLDisplay;
|
import android.opengl.EGLDisplay;
|
||||||
|
import android.util.Pair;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.ColorInfo;
|
import androidx.media3.common.ColorInfo;
|
||||||
|
|
@ -47,6 +49,7 @@ import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.GlRect;
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
|
import androidx.media3.common.util.MediaFormatUtil;
|
||||||
import androidx.media3.common.util.Size;
|
import androidx.media3.common.util.Size;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.ByteBufferGlEffect;
|
import androidx.media3.effect.ByteBufferGlEffect;
|
||||||
|
|
@ -55,7 +58,6 @@ import androidx.media3.effect.GlEffect;
|
||||||
import androidx.media3.effect.GlShaderProgram;
|
import androidx.media3.effect.GlShaderProgram;
|
||||||
import androidx.media3.effect.PassthroughShaderProgram;
|
import androidx.media3.effect.PassthroughShaderProgram;
|
||||||
import androidx.media3.effect.ScaleAndRotateTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
||||||
import androidx.media3.muxer.Muxer;
|
import androidx.media3.muxer.Muxer;
|
||||||
import androidx.media3.test.utils.BitmapPixelTestUtil;
|
import androidx.media3.test.utils.BitmapPixelTestUtil;
|
||||||
|
|
@ -67,7 +69,6 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
@ -1294,6 +1295,7 @@ public final class AndroidTestUtil {
|
||||||
@Nullable Format outputFormat,
|
@Nullable Format outputFormat,
|
||||||
boolean isPortraitEncodingEnabled)
|
boolean isPortraitEncodingEnabled)
|
||||||
throws IOException, JSONException, MediaCodecUtil.DecoderQueryException {
|
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 canDecode = inputFormat == null || canDecode(inputFormat);
|
||||||
|
|
||||||
boolean canEncode = outputFormat == null || canEncode(outputFormat, isPortraitEncodingEnabled);
|
boolean canEncode = outputFormat == null || canEncode(outputFormat, isPortraitEncodingEnabled);
|
||||||
|
|
@ -1345,28 +1347,21 @@ public final class AndroidTestUtil {
|
||||||
return SDK_INT > 24 ? new DefaultMuxer.Factory() : new InAppMuxer.Factory.Builder().build();
|
return SDK_INT > 24 ? new DefaultMuxer.Factory() : new InAppMuxer.Factory.Builder().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean canDecode(Format format) throws MediaCodecUtil.DecoderQueryException {
|
private static boolean canDecode(Format format) {
|
||||||
if (MimeTypes.isImage(format.sampleMimeType)) {
|
if (MimeTypes.isImage(format.sampleMimeType)) {
|
||||||
return Util.isBitmapFactorySupportedMimeType(format.sampleMimeType);
|
return Util.isBitmapFactorySupportedMimeType(format.sampleMimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check decoding capability in the same way as the default decoder factory.
|
// Check decoding capability in the same way as the default decoder factory.
|
||||||
return findDecoderForFormat(format) != null && !deviceNeedsDisable8kWorkaround(format);
|
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
|
||||||
}
|
@Nullable
|
||||||
|
Pair<Integer, Integer> codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format);
|
||||||
@Nullable
|
if (codecProfileAndLevel != null) {
|
||||||
private static String findDecoderForFormat(Format format)
|
MediaFormatUtil.maybeSetInteger(
|
||||||
throws MediaCodecUtil.DecoderQueryException {
|
mediaFormat, MediaFormat.KEY_PROFILE, codecProfileAndLevel.first);
|
||||||
List<androidx.media3.exoplayer.mediacodec.MediaCodecInfo> mediaCodecInfoList =
|
}
|
||||||
MediaCodecUtil.getDecoderInfosSortedByFormatSupport(
|
return EncoderUtil.findCodecForFormat(mediaFormat, /* isDecoder= */ true) != null
|
||||||
MediaCodecUtil.getDecoderInfosSoftMatch(
|
&& !deviceNeedsDisable8kWorkaround(format);
|
||||||
MediaCodecSelector.DEFAULT,
|
|
||||||
format,
|
|
||||||
/* requiresSecureDecoder= */ false,
|
|
||||||
/* requiresTunnelingDecoder= */ false),
|
|
||||||
format);
|
|
||||||
|
|
||||||
return mediaCodecInfoList.isEmpty() ? null : mediaCodecInfoList.get(0).name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean deviceNeedsDisable8kWorkaround(Format format) {
|
private static boolean deviceNeedsDisable8kWorkaround(Format format) {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import android.media.CamcorderProfile;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
import android.media.MediaCodecList;
|
import android.media.MediaCodecList;
|
||||||
|
import android.media.MediaFormat;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Range;
|
import android.util.Range;
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
|
|
@ -36,6 +37,7 @@ import androidx.media3.common.C.ColorTransfer;
|
||||||
import androidx.media3.common.ColorInfo;
|
import androidx.media3.common.ColorInfo;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
|
import androidx.media3.common.util.MediaFormatUtil;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import com.google.common.base.Ascii;
|
import com.google.common.base.Ascii;
|
||||||
|
|
@ -325,6 +327,37 @@ public final class EncoderUtil {
|
||||||
return maxSupportedLevel;
|
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}. */
|
/** Returns the range of supported bitrates for the given {@linkplain MimeTypes MIME type}. */
|
||||||
public static Range<Integer> getSupportedBitrateRange(
|
public static Range<Integer> getSupportedBitrateRange(
|
||||||
MediaCodecInfo encoderInfo, String mimeType) {
|
MediaCodecInfo encoderInfo, String mimeType) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue