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
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
boolean supportsFormatDrm = supportsFormatDrm(format);
if (supportsFormatDrm
&& allowPassthrough(format.channelCount, mimeType)
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) {
if (supportsFormatDrm && usePassthrough(format.channelCount, mimeType)) {
return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
}
if ((MimeTypes.AUDIO_RAW.equals(mimeType)
@ -257,12 +255,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
if (mimeType == null) {
return Collections.emptyList();
}
if (allowPassthrough(format.channelCount, mimeType)) {
@Nullable
MediaCodecInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo();
if (passthroughDecoderInfo != null) {
return Collections.singletonList(passthroughDecoderInfo);
}
if (usePassthrough(format.channelCount, mimeType)) {
return Collections.singletonList(MediaCodecUtil.getPassthroughDecoderInfo());
}
List<MediaCodecInfo> decoderInfos =
mediaCodecSelector.getDecoderInfos(
@ -286,9 +280,12 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
* not known.
* @param mimeType The type of input media.
* @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) {
return getPassthroughEncoding(channelCount, mimeType) != C.ENCODING_INVALID;
protected boolean usePassthrough(int channelCount, String mimeType) throws DecoderQueryException {
return getPassthroughEncoding(channelCount, mimeType) != C.ENCODING_INVALID
&& MediaCodecUtil.getPassthroughDecoderInfo() != null;
}
@Override
@ -301,10 +298,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
codecMaxInputSize = getCodecMaxInputSize(codecInfo, format, getStreamFormats());
codecNeedsDiscardChannelsWorkaround = codecNeedsDiscardChannelsWorkaround(codecInfo.name);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecInfo.name);
passthroughEnabled = codecInfo.passthrough;
String codecMimeType = passthroughEnabled ? MimeTypes.AUDIO_RAW : codecInfo.codecMimeType;
passthroughEnabled =
MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType)
&& !MimeTypes.AUDIO_RAW.equals(format.sampleMimeType);
MediaFormat mediaFormat =
getMediaFormat(format, codecMimeType, codecMaxInputSize, codecOperatingRate);
getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
codec.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0);
if (passthroughEnabled) {
// 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;
/** The MIME type handled by the codec, or {@code null} if this is a passthrough codec. */
@Nullable public final String mimeType;
/** The MIME type handled by the codec. */
public final String mimeType;
/**
* The MIME type that the codec uses for media of type {@link #mimeType}, or {@code null} if this
* is a passthrough codec. Equal to {@link #mimeType} unless the codec is known to use a
* non-standard MIME type alias.
* The MIME type that the codec uses for media of type {@link #mimeType}. Equal to {@link
* #mimeType} unless the codec is known to use a 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
@ -90,9 +89,6 @@ public final class MediaCodecInfo {
*/
public final boolean secure;
/** Whether this instance describes a passthrough codec. */
public final boolean passthrough;
/**
* Whether the codec is hardware accelerated.
*
@ -122,26 +118,6 @@ public final class MediaCodecInfo {
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.
*
@ -173,7 +149,6 @@ public final class MediaCodecInfo {
mimeType,
codecMimeType,
capabilities,
/* passthrough= */ false,
hardwareAccelerated,
softwareOnly,
vendor,
@ -183,10 +158,9 @@ public final class MediaCodecInfo {
private MediaCodecInfo(
String name,
@Nullable String mimeType,
@Nullable String codecMimeType,
String mimeType,
String codecMimeType,
@Nullable CodecCapabilities capabilities,
boolean passthrough,
boolean hardwareAccelerated,
boolean softwareOnly,
boolean vendor,
@ -196,7 +170,6 @@ public final class MediaCodecInfo {
this.mimeType = mimeType;
this.codecMimeType = codecMimeType;
this.capabilities = capabilities;
this.passthrough = passthrough;
this.hardwareAccelerated = hardwareAccelerated;
this.softwareOnly = softwareOnly;
this.vendor = vendor;

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.mediacodec;
import android.media.MediaCodec;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import java.util.List;
@ -29,22 +28,7 @@ public interface MediaCodecSelector {
* Default implementation of {@link MediaCodecSelector}, which returns the preferred decoder for
* the given format.
*/
MediaCodecSelector DEFAULT =
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();
}
};
MediaCodecSelector DEFAULT = MediaCodecUtil::getDecoderInfos;
/**
* 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(
String mimeType, boolean requiresSecureDecoder, boolean requiresTunnelingDecoder)
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
public static MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
@Nullable
MediaCodecInfo decoderInfo =
getDecoderInfo(MimeTypes.AUDIO_RAW, /* secure= */ false, /* tunneling= */ false);
return decoderInfo == null ? null : MediaCodecInfo.newPassthroughInstance(decoderInfo.name);
return getDecoderInfo(MimeTypes.AUDIO_RAW, /* secure= */ false, /* tunneling= */ false);
}
/**