Remove passthrough from MediaCodecInfo

Selection of a passthrough codec will rarely (if ever) need to be customized, so
remove this capability from MediaCodecInfo.

Applications can still customize whether passthrough is used by overriding
MediaCodecAudioRenderer.usePassthrough, which now also checks for a passthrough
codec.

#exo-offload

PiperOrigin-RevId: 303964682
This commit is contained in:
krocard 2020-03-31 15:55:40 +01:00 committed by Oliver Woodman
parent 918172cca7
commit 78c103e7ea
4 changed files with 21 additions and 78 deletions

View File

@ -217,9 +217,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@TunnelingSupport @TunnelingSupport
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED; int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
boolean supportsFormatDrm = supportsFormatDrm(format); boolean supportsFormatDrm = supportsFormatDrm(format);
if (supportsFormatDrm if (supportsFormatDrm && usePassthrough(format.channelCount, mimeType)) {
&& allowPassthrough(format.channelCount, mimeType)
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) {
return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport); return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
} }
if ((MimeTypes.AUDIO_RAW.equals(mimeType) if ((MimeTypes.AUDIO_RAW.equals(mimeType)
@ -257,12 +255,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
if (mimeType == null) { if (mimeType == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
if (allowPassthrough(format.channelCount, mimeType)) { if (usePassthrough(format.channelCount, mimeType)) {
@Nullable return Collections.singletonList(MediaCodecUtil.getPassthroughDecoderInfo());
MediaCodecInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo();
if (passthroughDecoderInfo != null) {
return Collections.singletonList(passthroughDecoderInfo);
}
} }
List<MediaCodecInfo> decoderInfos = List<MediaCodecInfo> decoderInfos =
mediaCodecSelector.getDecoderInfos( mediaCodecSelector.getDecoderInfos(
@ -286,9 +280,12 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
* not known. * not known.
* @param mimeType The type of input media. * @param mimeType The type of input media.
* @return Whether passthrough playback is supported. * @return Whether passthrough playback is supported.
* @throws DecoderQueryException If there was an error querying the available passthrough
* decoders.
*/ */
protected boolean allowPassthrough(int channelCount, String mimeType) { protected boolean usePassthrough(int channelCount, String mimeType) throws DecoderQueryException {
return getPassthroughEncoding(channelCount, mimeType) != C.ENCODING_INVALID; return getPassthroughEncoding(channelCount, mimeType) != C.ENCODING_INVALID
&& MediaCodecUtil.getPassthroughDecoderInfo() != null;
} }
@Override @Override
@ -301,10 +298,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats()); codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats());
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name); codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecInfo.name); codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecInfo.name);
passthroughEnabled = codecInfo.passthrough; passthroughEnabled =
String codecMimeType = passthroughEnabled ? MimeTypes.AUDIO_RAW : codecInfo.codecMimeType; MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType)
&& !MimeTypes.AUDIO_RAW.equals(format.sampleMimeType);
MediaFormat mediaFormat = MediaFormat mediaFormat =
getMediaFormat(format, codecMimeType, codecMaxInputSize, codecOperatingRate); getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
codec.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0); codec.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0);
if (passthroughEnabled) { if (passthroughEnabled) {
// Store the input MIME type if we're using the passthrough codec. // Store the input MIME type if we're using the passthrough codec.

View File

@ -50,15 +50,14 @@ public final class MediaCodecInfo {
*/ */
public final String name; public final String name;
/** The MIME type handled by the codec, or {@code null} if this is a passthrough codec. */ /** The MIME type handled by the codec. */
@Nullable public final String mimeType; public final String mimeType;
/** /**
* The MIME type that the codec uses for media of type {@link #mimeType}, or {@code null} if this * The MIME type that the codec uses for media of type {@link #mimeType}. Equal to {@link
* is a passthrough codec. Equal to {@link #mimeType} unless the codec is known to use a * #mimeType} unless the codec is known to use a non-standard MIME type alias.
* non-standard MIME type alias.
*/ */
@Nullable public final String codecMimeType; public final String codecMimeType;
/** /**
* The capabilities of the decoder, like the profiles/levels it supports, or {@code null} if not * The capabilities of the decoder, like the profiles/levels it supports, or {@code null} if not
@ -90,9 +89,6 @@ public final class MediaCodecInfo {
*/ */
public final boolean secure; public final boolean secure;
/** Whether this instance describes a passthrough codec. */
public final boolean passthrough;
/** /**
* Whether the codec is hardware accelerated. * Whether the codec is hardware accelerated.
* *
@ -122,26 +118,6 @@ public final class MediaCodecInfo {
private final boolean isVideo; private final boolean isVideo;
/**
* Creates an instance representing an audio passthrough decoder.
*
* @param name The name of the {@link MediaCodec}.
* @return The created instance.
*/
public static MediaCodecInfo newPassthroughInstance(String name) {
return new MediaCodecInfo(
name,
/* mimeType= */ null,
/* codecMimeType= */ null,
/* capabilities= */ null,
/* passthrough= */ true,
/* hardwareAccelerated= */ false,
/* softwareOnly= */ true,
/* vendor= */ false,
/* forceDisableAdaptive= */ false,
/* forceSecure= */ false);
}
/** /**
* Creates an instance. * Creates an instance.
* *
@ -173,7 +149,6 @@ public final class MediaCodecInfo {
mimeType, mimeType,
codecMimeType, codecMimeType,
capabilities, capabilities,
/* passthrough= */ false,
hardwareAccelerated, hardwareAccelerated,
softwareOnly, softwareOnly,
vendor, vendor,
@ -183,10 +158,9 @@ public final class MediaCodecInfo {
private MediaCodecInfo( private MediaCodecInfo(
String name, String name,
@Nullable String mimeType, String mimeType,
@Nullable String codecMimeType, String codecMimeType,
@Nullable CodecCapabilities capabilities, @Nullable CodecCapabilities capabilities,
boolean passthrough,
boolean hardwareAccelerated, boolean hardwareAccelerated,
boolean softwareOnly, boolean softwareOnly,
boolean vendor, boolean vendor,
@ -196,7 +170,6 @@ public final class MediaCodecInfo {
this.mimeType = mimeType; this.mimeType = mimeType;
this.codecMimeType = codecMimeType; this.codecMimeType = codecMimeType;
this.capabilities = capabilities; this.capabilities = capabilities;
this.passthrough = passthrough;
this.hardwareAccelerated = hardwareAccelerated; this.hardwareAccelerated = hardwareAccelerated;
this.softwareOnly = softwareOnly; this.softwareOnly = softwareOnly;
this.vendor = vendor; this.vendor = vendor;

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.mediacodec; package com.google.android.exoplayer2.mediacodec;
import android.media.MediaCodec; import android.media.MediaCodec;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import java.util.List; import java.util.List;
@ -29,22 +28,7 @@ public interface MediaCodecSelector {
* Default implementation of {@link MediaCodecSelector}, which returns the preferred decoder for * Default implementation of {@link MediaCodecSelector}, which returns the preferred decoder for
* the given format. * the given format.
*/ */
MediaCodecSelector DEFAULT = MediaCodecSelector DEFAULT = MediaCodecUtil::getDecoderInfos;
new MediaCodecSelector() {
@Override
public List<MediaCodecInfo> getDecoderInfos(
String mimeType, boolean requiresSecureDecoder, boolean requiresTunnelingDecoder)
throws DecoderQueryException {
return MediaCodecUtil.getDecoderInfos(
mimeType, requiresSecureDecoder, requiresTunnelingDecoder);
}
@Override
@Nullable
public MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
return MediaCodecUtil.getPassthroughDecoderInfo();
}
};
/** /**
* Returns a list of decoders that can decode media in the specified MIME type, in priority order. * Returns a list of decoders that can decode media in the specified MIME type, in priority order.
@ -59,13 +43,4 @@ public interface MediaCodecSelector {
List<MediaCodecInfo> getDecoderInfos( List<MediaCodecInfo> getDecoderInfos(
String mimeType, boolean requiresSecureDecoder, boolean requiresTunnelingDecoder) String mimeType, boolean requiresSecureDecoder, boolean requiresTunnelingDecoder)
throws DecoderQueryException; throws DecoderQueryException;
/**
* Selects a decoder to instantiate for audio passthrough.
*
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder exists.
* @throws DecoderQueryException Thrown if there was an error querying decoders.
*/
@Nullable
MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException;
} }

View File

@ -123,10 +123,7 @@ public final class MediaCodecUtil {
*/ */
@Nullable @Nullable
public static MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException { public static MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
@Nullable return getDecoderInfo(MimeTypes.AUDIO_RAW, /* secure= */ false, /* tunneling= */ false);
MediaCodecInfo decoderInfo =
getDecoderInfo(MimeTypes.AUDIO_RAW, /* secure= */ false, /* tunneling= */ false);
return decoderInfo == null ? null : MediaCodecInfo.newPassthroughInstance(decoderInfo.name);
} }
/** /**