mirror of
https://github.com/androidx/media.git
synced 2025-05-03 21:57:46 +08:00
Use "Passthrough" terminology only for non-offload direct playback
The term "passthrough" was heavily overloaded. For clarity, split most of its usage to different terms: * codec "bypass": no MediaCodec is used * "direct playback": no decoding occurs (but decryption may or may not) * "decrypt only codec": a MediaCodec used only to decrypt, not decode * "offload": playback to an offload AudioTrack. * "passthrough" is now only used in the sense of playing encoded audio * to a non offload AudioTrack. PiperOrigin-RevId: 324984612
This commit is contained in:
parent
6e11d32092
commit
d2e50e40dc
@ -90,7 +90,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
private int codecMaxInputSize;
|
||||
private boolean codecNeedsDiscardChannelsWorkaround;
|
||||
private boolean codecNeedsEosBufferTimestampWorkaround;
|
||||
@Nullable private Format codecPassthroughFormat;
|
||||
/** Codec used for DRM decryption only in passthrough and offload. */
|
||||
@Nullable private Format decryptOnlyCodecFormat;
|
||||
|
||||
private long currentPositionUs;
|
||||
private boolean allowFirstBufferPositionDiscontinuity;
|
||||
private boolean allowPositionDiscontinuity;
|
||||
@ -214,11 +216,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
boolean formatHasDrm = format.exoMediaCryptoType != null;
|
||||
boolean supportsFormatDrm = supportsFormatDrm(format);
|
||||
// In passthrough mode, if the format needs decryption then we need to use a passthrough
|
||||
// decoder. Else we don't don't need a decoder at all.
|
||||
// In direct mode, if the format has DRM then we need to use a decoder that only decrypts.
|
||||
// Else we don't don't need a decoder at all.
|
||||
if (supportsFormatDrm
|
||||
&& usePassthrough(format)
|
||||
&& (!formatHasDrm || MediaCodecUtil.getPassthroughDecoderInfo() != null)) {
|
||||
&& isDirectPlaybackSupported(format)
|
||||
&& (!formatHasDrm || MediaCodecUtil.getDecryptOnlyDecoderInfo() != null)) {
|
||||
return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
|
||||
}
|
||||
// If the input is PCM then it will be passed directly to the sink. Hence the sink must support
|
||||
@ -260,8 +262,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
if (mimeType == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (usePassthrough(format)) {
|
||||
@Nullable MediaCodecInfo codecInfo = MediaCodecUtil.getPassthroughDecoderInfo();
|
||||
if (isDirectPlaybackSupported(format)) {
|
||||
// The format is supported directly, so a codec is only needed for decryption.
|
||||
@Nullable MediaCodecInfo codecInfo = MediaCodecUtil.getDecryptOnlyDecoderInfo();
|
||||
if (codecInfo != null) {
|
||||
return Collections.singletonList(codecInfo);
|
||||
}
|
||||
@ -282,13 +285,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean usePassthrough(Format format) {
|
||||
@Nullable String mimeType = format.sampleMimeType;
|
||||
if (MimeTypes.AUDIO_RAW.equals(mimeType)) {
|
||||
// PCM passthrough is not yet supported.
|
||||
return false;
|
||||
}
|
||||
return audioSink.supportsFormat(format);
|
||||
protected boolean shouldUseBypass(Format format) {
|
||||
return isDirectPlaybackSupported(format);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -304,11 +302,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
MediaFormat mediaFormat =
|
||||
getMediaFormat(format, codecInfo.codecMimeType, codecMaxInputSize, codecOperatingRate);
|
||||
codecAdapter.configure(mediaFormat, /* surface= */ null, crypto, /* flags= */ 0);
|
||||
// Store the input MIME type if we're using the passthrough codec.
|
||||
boolean codecPassthroughEnabled =
|
||||
// Store the input MIME type if we're only using the codec for decryption.
|
||||
boolean decryptOnlyCodecEnabled =
|
||||
MimeTypes.AUDIO_RAW.equals(codecInfo.mimeType)
|
||||
&& !MimeTypes.AUDIO_RAW.equals(format.sampleMimeType);
|
||||
codecPassthroughFormat = codecPassthroughEnabled ? format : null;
|
||||
decryptOnlyCodecFormat = decryptOnlyCodecEnabled ? format : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -386,9 +384,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
throws ExoPlaybackException {
|
||||
Format audioSinkInputFormat;
|
||||
@Nullable int[] channelMap = null;
|
||||
if (codecPassthroughFormat != null) { // Raw codec passthrough
|
||||
audioSinkInputFormat = codecPassthroughFormat;
|
||||
} else if (getCodec() == null) { // Codec bypass passthrough
|
||||
if (decryptOnlyCodecFormat != null) { // Direct playback with a codec for decryption.
|
||||
audioSinkInputFormat = decryptOnlyCodecFormat;
|
||||
} else if (getCodec() == null) { // Direct playback with codec bypass.
|
||||
audioSinkInputFormat = format;
|
||||
} else {
|
||||
@C.PcmEncoding int pcmEncoding;
|
||||
@ -578,7 +576,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
bufferPresentationTimeUs = getLargestQueuedPresentationTimeUs();
|
||||
}
|
||||
|
||||
if (codecPassthroughFormat != null
|
||||
if (decryptOnlyCodecFormat != null
|
||||
&& (bufferFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
|
||||
// Discard output buffers from the passthrough (raw) decoder containing codec specific data.
|
||||
checkNotNull(codec).releaseOutputBuffer(bufferIndex, false);
|
||||
@ -677,6 +675,16 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
return maxInputSize;
|
||||
}
|
||||
|
||||
/** Returns if the format can be played as is to the audio sink. */
|
||||
private boolean isDirectPlaybackSupported(Format format) {
|
||||
@Nullable String mimeType = format.sampleMimeType;
|
||||
if (MimeTypes.AUDIO_RAW.equals(mimeType)) {
|
||||
// Decoding bypass for PCM is not yet supported.
|
||||
return false;
|
||||
}
|
||||
return audioSink.supportsFormat(format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a maximum input buffer size for a given {@link Format}.
|
||||
*
|
||||
|
@ -537,7 +537,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sourceDrmSession == null && usePassthrough(inputFormat)) {
|
||||
if (sourceDrmSession == null && shouldUseBypass(inputFormat)) {
|
||||
initBypass(inputFormat);
|
||||
return;
|
||||
}
|
||||
@ -588,12 +588,15 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether encoded passthrough should be used for playing back the input format.
|
||||
* Returns whether buffers in the input format can be processed without a codec.
|
||||
*
|
||||
* <p>This method is only called if the content is not DRM protected, because if the content is
|
||||
* DRM protected use of bypass is never possible.
|
||||
*
|
||||
* @param format The input {@link Format}.
|
||||
* @return Whether passthrough playback is supported.
|
||||
* @return Whether playback bypassing {@link MediaCodec} is supported.
|
||||
*/
|
||||
protected boolean usePassthrough(Format format) {
|
||||
protected boolean shouldUseBypass(Format format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -106,13 +106,13 @@ public final class MediaCodecUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about a decoder suitable for audio passthrough.
|
||||
* Returns information about a decoder that will only decrypt data, without decoding it.
|
||||
*
|
||||
* @return A {@link MediaCodecInfo} describing the decoder, or null if no suitable decoder exists.
|
||||
* @throws DecoderQueryException If there was an error querying the available decoders.
|
||||
*/
|
||||
@Nullable
|
||||
public static MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
|
||||
public static MediaCodecInfo getDecryptOnlyDecoderInfo() throws DecoderQueryException {
|
||||
return getDecoderInfo(MimeTypes.AUDIO_RAW, /* secure= */ false, /* tunneling= */ false);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user