-
Notifications
You must be signed in to change notification settings - Fork 574
Dts direct passthrough support #335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b73d2cc
22b45b7
6823a29
c0e03f1
3b9d680
d01a93b
689451b
b069fb1
c984387
f47930e
abc46d4
753257e
b1ac768
924723d
53f35f4
773d3c5
6b4cf4d
905ad1c
cb29e8f
424b5d8
47b0726
5a6906a
d0cd2f5
c61f8d3
b9a53da
162f5e8
f69718e
9d147f2
ea32f11
48509df
fb34983
f301214
730cfec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,21 +48,19 @@ | |
@UnstableApi | ||
public final class AudioCapabilities { | ||
|
||
private static final int DEFAULT_MAX_CHANNEL_COUNT = 8; | ||
// TODO(internal b/283945513): Have separate default max channel counts in `AudioCapabilities` | ||
// for PCM and compressed audio. | ||
private static final int DEFAULT_MAX_CHANNEL_COUNT = 10; | ||
@VisibleForTesting /* package */ static final int DEFAULT_SAMPLE_RATE_HZ = 48_000; | ||
|
||
/** The minimum audio capabilities supported by all devices. */ | ||
public static final AudioCapabilities DEFAULT_AUDIO_CAPABILITIES = | ||
new AudioCapabilities(new int[] {AudioFormat.ENCODING_PCM_16BIT}, DEFAULT_MAX_CHANNEL_COUNT); | ||
|
||
/** Audio capabilities when the device specifies external surround sound. */ | ||
@SuppressWarnings("InlinedApi") | ||
private static final AudioCapabilities EXTERNAL_SURROUND_SOUND_CAPABILITIES = | ||
new AudioCapabilities( | ||
new int[] { | ||
AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_AC3, AudioFormat.ENCODING_E_AC3 | ||
}, | ||
DEFAULT_MAX_CHANNEL_COUNT); | ||
/** Encodings supported when the device specifies external surround sound. */ | ||
private static final ImmutableList<Integer> EXTERNAL_SURROUND_SOUND_ENCODINGS = | ||
ImmutableList.of( | ||
AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_AC3, AudioFormat.ENCODING_E_AC3); | ||
|
||
/** | ||
* All surround sound encodings that a device may be capable of playing mapped to a maximum | ||
|
@@ -73,6 +71,7 @@ public final class AudioCapabilities { | |
.put(C.ENCODING_AC3, 6) | ||
.put(C.ENCODING_AC4, 6) | ||
.put(C.ENCODING_DTS, 6) | ||
.put(C.ENCODING_DTS_UHD_P2, 10) | ||
.put(C.ENCODING_E_AC3_JOC, 6) | ||
.put(C.ENCODING_E_AC3, 8) | ||
.put(C.ENCODING_DTS_HD, 8) | ||
|
@@ -103,25 +102,39 @@ public static AudioCapabilities getCapabilities(Context context) { | |
if (Util.SDK_INT >= 23 && Api23.isBluetoothConnected(context)) { | ||
return DEFAULT_AUDIO_CAPABILITIES; | ||
} | ||
|
||
ImmutableSet.Builder<Integer> supportedEncodings = new ImmutableSet.Builder<>(); | ||
if (deviceMaySetExternalSurroundSoundGlobalSetting() | ||
&& Global.getInt(context.getContentResolver(), EXTERNAL_SURROUND_SOUND_KEY, 0) == 1) { | ||
return EXTERNAL_SURROUND_SOUND_CAPABILITIES; | ||
supportedEncodings.addAll(EXTERNAL_SURROUND_SOUND_ENCODINGS); | ||
} | ||
// AudioTrack.isDirectPlaybackSupported returns true for encodings that are supported for audio | ||
// offload, as well as for encodings we want to list for passthrough mode. Therefore we only use | ||
// it on TV and automotive devices, which generally shouldn't support audio offload for surround | ||
// encodings. | ||
if (Util.SDK_INT >= 29 && (Util.isTv(context) || Util.isAutomotive(context))) { | ||
supportedEncodings.addAll(Api29.getDirectPlaybackSupportedEncodings()); | ||
return new AudioCapabilities( | ||
Api29.getDirectPlaybackSupportedEncodings(), DEFAULT_MAX_CHANNEL_COUNT); | ||
Ints.toArray(supportedEncodings.build()), DEFAULT_MAX_CHANNEL_COUNT); | ||
} | ||
if (intent == null || intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 0) { | ||
return DEFAULT_AUDIO_CAPABILITIES; | ||
|
||
if (intent != null && intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 1) { | ||
@Nullable int[] encodingsFromExtra = intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS); | ||
if (encodingsFromExtra != null) { | ||
supportedEncodings.addAll(Ints.asList(encodingsFromExtra)); | ||
} | ||
return new AudioCapabilities( | ||
Ints.toArray(supportedEncodings.build()), | ||
intent.getIntExtra( | ||
AudioManager.EXTRA_MAX_CHANNEL_COUNT, /* defaultValue= */ DEFAULT_MAX_CHANNEL_COUNT)); | ||
} | ||
return new AudioCapabilities( | ||
intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS), | ||
intent.getIntExtra( | ||
AudioManager.EXTRA_MAX_CHANNEL_COUNT, /* defaultValue= */ DEFAULT_MAX_CHANNEL_COUNT)); | ||
|
||
ImmutableSet<Integer> supportedEncodingsSet = supportedEncodings.build(); | ||
if (!supportedEncodingsSet.isEmpty()) { | ||
return new AudioCapabilities( | ||
Ints.toArray(supportedEncodingsSet), /* maxChannelCount= */ DEFAULT_MAX_CHANNEL_COUNT); | ||
} | ||
return DEFAULT_AUDIO_CAPABILITIES; | ||
} | ||
|
||
/** | ||
|
@@ -203,7 +216,8 @@ public Pair<Integer, Integer> getEncodingAndChannelConfigForPassthrough(Format f | |
if (encoding == C.ENCODING_E_AC3_JOC && !supportsEncoding(C.ENCODING_E_AC3_JOC)) { | ||
// E-AC3 receivers support E-AC3 JOC streams (but decode only the base layer). | ||
encoding = C.ENCODING_E_AC3; | ||
} else if (encoding == C.ENCODING_DTS_HD && !supportsEncoding(C.ENCODING_DTS_HD)) { | ||
} else if ((encoding == C.ENCODING_DTS_HD && !supportsEncoding(C.ENCODING_DTS_HD)) | ||
|| (encoding == C.ENCODING_DTS_UHD_P2 && !supportsEncoding(C.ENCODING_DTS_UHD_P2))) { | ||
// DTS receivers support DTS-HD streams (but decode only the core layer). | ||
encoding = C.ENCODING_DTS; | ||
} | ||
|
@@ -220,7 +234,13 @@ public Pair<Integer, Integer> getEncodingAndChannelConfigForPassthrough(Format f | |
channelCount = getMaxSupportedChannelCountForPassthrough(encoding, sampleRate); | ||
} else { | ||
channelCount = format.channelCount; | ||
if (channelCount > maxChannelCount) { | ||
// Some DTS:X TVs reports ACTION_HDMI_AUDIO_PLUG.EXTRA_MAX_CHANNEL_COUNT as 8 | ||
// instead of 10. See https://github.com/androidx/media/issues/396 | ||
if (format.sampleMimeType.equals(MimeTypes.AUDIO_DTS_X)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cedricxperi We have two questions regarding this:
The reason I'm asking above questions is - either this is a device or even platform issue, if it is able to be fixed, how do you think if we just don't attempt to play DTS:X for those devices ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tianyif I do not have access to other device at the moment but it is reasonable to think that this would be reproduceable for all DTS:X TVs based on MTK platforms. It will take sometime for this issue to be fixed on the platform. Meanwhile, Xperi will have to go to each and every streaming service to tell them to add the above so that DTS:X can be played back. I think it is better to add this patch in the exoplayer code base so that everyone will be aware of it. When the issue get fixed on the platform (which could take a long time), we can remove this patch in another exoplayer contribution. Thanks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will keep this patch. Thanks! |
||
if (channelCount > 10) { | ||
return null; | ||
} | ||
} else if (channelCount > maxChannelCount) { | ||
return null; | ||
} | ||
} | ||
|
@@ -355,9 +375,13 @@ private static final class Api29 { | |
private Api29() {} | ||
|
||
@DoNotInline | ||
public static int[] getDirectPlaybackSupportedEncodings() { | ||
public static ImmutableList<Integer> getDirectPlaybackSupportedEncodings() { | ||
ImmutableList.Builder<Integer> supportedEncodingsListBuilder = ImmutableList.builder(); | ||
for (int encoding : ALL_SURROUND_ENCODINGS_AND_MAX_CHANNELS.keySet()) { | ||
// AudioFormat.ENCODING_DTS_UHD_P2 is supported from API 34. | ||
if (Util.SDK_INT < 34 && encoding == C.ENCODING_DTS_UHD_P2) { | ||
continue; | ||
} | ||
if (AudioTrack.isDirectPlaybackSupported( | ||
new AudioFormat.Builder() | ||
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO) | ||
|
@@ -369,7 +393,7 @@ public static int[] getDirectPlaybackSupportedEncodings() { | |
} | ||
} | ||
supportedEncodingsListBuilder.add(AudioFormat.ENCODING_PCM_16BIT); | ||
return Ints.toArray(supportedEncodingsListBuilder.build()); | ||
return supportedEncodingsListBuilder.build(); | ||
} | ||
|
||
/** | ||
|
Uh oh!
There was an error while loading. Please reload this page.