Include channel count in capabilities check
Issue: #4690 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=220640737
This commit is contained in:
parent
b5beb32618
commit
d9462b9d2b
@ -1,5 +1,10 @@
|
||||
# Release notes #
|
||||
|
||||
### 2.9.2 ###
|
||||
|
||||
* Include channel count in audio capabilities check
|
||||
([#4690](https://github.com/google/ExoPlayer/issues/4690)).
|
||||
|
||||
### 2.9.1 ###
|
||||
|
||||
* Add convenience methods `Player.next`, `Player.previous`, `Player.hasNext`
|
||||
|
@ -145,12 +145,13 @@ public final class FfmpegAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||
}
|
||||
|
||||
private boolean isOutputSupported(Format inputFormat) {
|
||||
return shouldUseFloatOutput(inputFormat) || supportsOutputEncoding(C.ENCODING_PCM_16BIT);
|
||||
return shouldUseFloatOutput(inputFormat)
|
||||
|| supportsOutput(inputFormat.channelCount, C.ENCODING_PCM_16BIT);
|
||||
}
|
||||
|
||||
private boolean shouldUseFloatOutput(Format inputFormat) {
|
||||
Assertions.checkNotNull(inputFormat.sampleMimeType);
|
||||
if (!enableFloatOutput || !supportsOutputEncoding(C.ENCODING_PCM_FLOAT)) {
|
||||
if (!enableFloatOutput || !supportsOutput(inputFormat.channelCount, C.ENCODING_PCM_FLOAT)) {
|
||||
return false;
|
||||
}
|
||||
switch (inputFormat.sampleMimeType) {
|
||||
|
@ -53,7 +53,7 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||
if (!FlacLibrary.isAvailable()
|
||||
|| !MimeTypes.AUDIO_FLAC.equalsIgnoreCase(format.sampleMimeType)) {
|
||||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
} else if (!supportsOutputEncoding(C.ENCODING_PCM_16BIT)) {
|
||||
} else if (!supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
|
@ -78,7 +78,7 @@ public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
|
||||
if (!OpusLibrary.isAvailable()
|
||||
|| !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) {
|
||||
return FORMAT_UNSUPPORTED_TYPE;
|
||||
} else if (!supportsOutputEncoding(C.ENCODING_PCM_16BIT)) {
|
||||
} else if (!supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
} else if (!supportsFormatDrm(drmSessionManager, format.drmInitData)) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
|
@ -29,11 +29,11 @@ import java.util.Arrays;
|
||||
@TargetApi(21)
|
||||
public final class AudioCapabilities {
|
||||
|
||||
/**
|
||||
* The minimum audio capabilities supported by all devices.
|
||||
*/
|
||||
private static final int DEFAULT_MAX_CHANNEL_COUNT = 8;
|
||||
|
||||
/** The minimum audio capabilities supported by all devices. */
|
||||
public static final AudioCapabilities DEFAULT_AUDIO_CAPABILITIES =
|
||||
new AudioCapabilities(new int[] {AudioFormat.ENCODING_PCM_16BIT}, 2);
|
||||
new AudioCapabilities(new int[] {AudioFormat.ENCODING_PCM_16BIT}, DEFAULT_MAX_CHANNEL_COUNT);
|
||||
|
||||
/**
|
||||
* Returns the current audio capabilities for the device.
|
||||
@ -52,8 +52,10 @@ public final class AudioCapabilities {
|
||||
if (intent == null || intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 0) {
|
||||
return DEFAULT_AUDIO_CAPABILITIES;
|
||||
}
|
||||
return new AudioCapabilities(intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS),
|
||||
intent.getIntExtra(AudioManager.EXTRA_MAX_CHANNEL_COUNT, 0));
|
||||
return new AudioCapabilities(
|
||||
intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS),
|
||||
intent.getIntExtra(
|
||||
AudioManager.EXTRA_MAX_CHANNEL_COUNT, /* defaultValue= */ DEFAULT_MAX_CHANNEL_COUNT));
|
||||
}
|
||||
|
||||
private final int[] supportedEncodings;
|
||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.audio;
|
||||
import android.media.AudioTrack;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@ -165,12 +166,13 @@ public interface AudioSink {
|
||||
void setListener(Listener listener);
|
||||
|
||||
/**
|
||||
* Returns whether it's possible to play audio in the specified encoding.
|
||||
* Returns whether the sink supports the audio format.
|
||||
*
|
||||
* @param encoding The audio encoding.
|
||||
* @return Whether it's possible to play audio in the specified encoding.
|
||||
* @param channelCount The number of channels, or {@link Format#NO_VALUE} if not known.
|
||||
* @param encoding The audio encoding, or {@link Format#NO_VALUE} if not known.
|
||||
* @return Whether the sink supports the audio format.
|
||||
*/
|
||||
boolean isEncodingSupported(@C.Encoding int encoding);
|
||||
boolean supportsOutput(int channelCount, @C.Encoding int encoding);
|
||||
|
||||
/**
|
||||
* Returns the playback position in the stream starting at zero, in microseconds, or
|
||||
|
@ -377,14 +377,18 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEncodingSupported(@C.Encoding int encoding) {
|
||||
public boolean supportsOutput(int channelCount, @C.Encoding int encoding) {
|
||||
if (Util.isEncodingLinearPcm(encoding)) {
|
||||
// AudioTrack supports 16-bit integer PCM output in all platform API versions, and float
|
||||
// output from platform API version 21 only. Other integer PCM encodings are resampled by this
|
||||
// sink to 16-bit PCM.
|
||||
// sink to 16-bit PCM. We assume that the audio framework will downsample any number of
|
||||
// channels to the output device's required number of channels.
|
||||
return encoding != C.ENCODING_PCM_FLOAT || Util.SDK_INT >= 21;
|
||||
} else {
|
||||
return audioCapabilities != null && audioCapabilities.supportsEncoding(encoding);
|
||||
return audioCapabilities != null
|
||||
&& audioCapabilities.supportsEncoding(encoding)
|
||||
&& (channelCount == Format.NO_VALUE
|
||||
|| channelCount <= audioCapabilities.getMaxChannelCount());
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,7 +419,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
isInputPcm = Util.isEncodingLinearPcm(inputEncoding);
|
||||
shouldConvertHighResIntPcmToFloat =
|
||||
enableConvertHighResIntPcmToFloat
|
||||
&& isEncodingSupported(C.ENCODING_PCM_32BIT)
|
||||
&& supportsOutput(channelCount, C.ENCODING_PCM_32BIT)
|
||||
&& Util.isEncodingHighResolutionIntegerPcm(inputEncoding);
|
||||
if (isInputPcm) {
|
||||
pcmFrameSize = Util.getPcmFrameSize(inputEncoding, channelCount);
|
||||
|
@ -272,12 +272,14 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
|
||||
boolean supportsFormatDrm = supportsFormatDrm(drmSessionManager, format.drmInitData);
|
||||
if (supportsFormatDrm && allowPassthrough(mimeType)
|
||||
if (supportsFormatDrm
|
||||
&& allowPassthrough(format.channelCount, mimeType)
|
||||
&& mediaCodecSelector.getPassthroughDecoderInfo() != null) {
|
||||
return ADAPTIVE_NOT_SEAMLESS | tunnelingSupport | FORMAT_HANDLED;
|
||||
}
|
||||
if ((MimeTypes.AUDIO_RAW.equals(mimeType) && !audioSink.isEncodingSupported(format.pcmEncoding))
|
||||
|| !audioSink.isEncodingSupported(C.ENCODING_PCM_16BIT)) {
|
||||
if ((MimeTypes.AUDIO_RAW.equals(mimeType)
|
||||
&& !audioSink.supportsOutput(format.channelCount, format.pcmEncoding))
|
||||
|| !audioSink.supportsOutput(format.channelCount, C.ENCODING_PCM_16BIT)) {
|
||||
// Assume the decoder outputs 16-bit PCM, unless the input is raw.
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
}
|
||||
@ -316,7 +318,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
protected List<MediaCodecInfo> getDecoderInfos(
|
||||
MediaCodecSelector mediaCodecSelector, Format format, boolean requiresSecureDecoder)
|
||||
throws DecoderQueryException {
|
||||
if (allowPassthrough(format.sampleMimeType)) {
|
||||
if (allowPassthrough(format.channelCount, format.sampleMimeType)) {
|
||||
MediaCodecInfo passthroughDecoderInfo = mediaCodecSelector.getPassthroughDecoderInfo();
|
||||
if (passthroughDecoderInfo != null) {
|
||||
return Collections.singletonList(passthroughDecoderInfo);
|
||||
@ -330,12 +332,13 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
* This implementation returns true if the {@link AudioSink} indicates that encoded audio output
|
||||
* is supported.
|
||||
*
|
||||
* @param channelCount The number of channels in the input media, or {@link Format#NO_VALUE} if
|
||||
* not known.
|
||||
* @param mimeType The type of input media.
|
||||
* @return Whether passthrough playback is supported.
|
||||
*/
|
||||
protected boolean allowPassthrough(String mimeType) {
|
||||
@C.Encoding int encoding = MimeTypes.getEncoding(mimeType);
|
||||
return encoding != C.ENCODING_INVALID && audioSink.isEncodingSupported(encoding);
|
||||
protected boolean allowPassthrough(int channelCount, String mimeType) {
|
||||
return audioSink.supportsOutput(channelCount, MimeTypes.getEncoding(mimeType));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -249,13 +249,12 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
|
||||
DrmSessionManager<ExoMediaCrypto> drmSessionManager, Format format);
|
||||
|
||||
/**
|
||||
* Returns whether the audio sink can accept audio in the specified encoding.
|
||||
* Returns whether the sink supports the audio format.
|
||||
*
|
||||
* @param encoding The audio encoding.
|
||||
* @return Whether the audio sink can accept audio in the specified encoding.
|
||||
* @see AudioSink#supportsOutput(int, int)
|
||||
*/
|
||||
protected final boolean supportsOutputEncoding(@C.Encoding int encoding) {
|
||||
return audioSink.isEncodingSupported(encoding);
|
||||
protected final boolean supportsOutput(int channelCount, @C.Encoding int encoding) {
|
||||
return audioSink.supportsOutput(channelCount, encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user