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