Dolby Integration Guidelines (Fire TV)
This documentation provides integration guidelines for application developers who need to support Dolby audio content.
You can see the Dolby settings in Amazon Fire TV by going to Settings > Display & Sounds > Audio > Dolby Digital Output.
- Terms
- Four Ways to Play Dolby Audio
- Option 1: Use ExoPlayer
- Option 2: Custom Media Player Approach
- Option 3: Use Other Supported Media Players
- Option 4: Use Android Media Player
- Handling non-Dolby End-Points and Private Listening Modes
Terms
Note the following abbreviations used in this documentation:
- EAC3: Dolby Digital Plus (DDP)
- AC3: Dolby Digital (DD)
Four Ways to Play Dolby Audio
You can play Dolby (DD/DDP/Atmos) audio content in your app in four ways:
Option 1: Use ExoPlayer
ExoPlayer is a open source player supported by Google that supports playing Dolby audio stream.
Amazon has developed patches for Exoplayer to enable or enhance playback of Dolby audio content on variuos Amazon devices. These patches are open sourced here: exoplayer-amazon-port. (Note that each "amazon/rx.y.z" branch maps to ExoPlayer version x.y.z.)
Option 2: Custom Media Player Approach
Implement a custom player that uses AudioManager, AudioTrack, and MediaCodec APIs. This section specifies the use of AudioManager, AudioTrack, and MediaCodec APIs to play Dolby audio content as recommended by Android.
Detecting Dolby support
To more easily test your audio capabilities using the methods below, use the Testing App.
Method 1: EXTRA_ENCODINGS
Android L (API level 21) enhanced the ACTION_HDMI_AUDIO_PLUG intent in AudioManager to report the capabilities of HDMI sink devices. This intent will be broadcast whenever HDMI is plugged in to or unplugged from the device.
This intent also has a provision for apps to detect the capabilities of the connected endpoint (AVR or TV) via EXTRA_ENCODINGS present in the intent. The possible values are one of the ENCODING_XXXX values. For example:
- ENCODING_PCM_16BIT
- ENCODING_AC3
- ENCODING_E_AC3
- ENCODING_E_AC3_JOC (added in API level 28 - Fire OS 7 and above)
Apps can register a broadcast receiver to receive an ACTION_HDMI_AUDIO_PLUG intent and obtain information like EXTRA_ENCODINGS and the EXTRA_AUDIO_PLUG_STATE from the intent.
BroadcastReceiver mAudioHDMIPlugReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null) {
if (intent.getIntExtra(AudioManager.EXTRA_AUDIO_PLUG_STATE, 0) == 0) {
// Handle HDMI unplug state
} else {
// Handle EXTRA_ENCODINGS
int[] extraEncodings = intent.getIntArrayExtra(AudioManager.EXTRA_ENCODINGS);
}
}
}
};
- If HDMI is unplugged, return the minimum audio capabilities supported by all devices. Normally it should be AudioFormat.ENCODING_PCM_16BIT. See the official example from Exoplayer.
- If an HDMI sink device supports Dolby Atmos, there will be AudioFormat.ENCODING_E_AC3_JOC enum(18) in the EXTRA_ENCODINGS list.
Method 2: audio_platform_capabilities global settings
The audio_platform_capabilities global setting is an Amazon designed method to query sink capabilities in Fire OS. When the AudioService launches, audio_platform_capabilities will be initialized, stored in the global settings in JSON format, and updated when the sink capability changes.
Developers can query audio_platform_capabilities in the global settings in order to get the current audio endpoint capabilities by doing the following:
String audioCapJson = Settings.Global.getString(mContext.getContentResolver(), "audio_platform_capabilities");
To actively observe capability changes, developers can use ContentObserver, like this:
ContentResolver mContentResolver = mContext.getContentResolver();
Uri audioPlatformUri = Settings.Global.getUriFor("audio_platform_capabilities");
ContentObserver mAudioPlatformJsonObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
String audioCapJson = Settings.Global.getString(mContentResolver, "audio_platform_capabilities");
Log.d(TAG, "audio_platform_capabilities=" + audioCapJson);
}
};
mContentResolver.registerContentObserver(audioPlatformUri, false, mAudioPlatformJsonObserver);
The following is an example a JSON string for audio_platform_capabilities for a Dolby Atmos capable sink.
{
"audiocaps": {
"pcm" : {
"mixing" : true
},
"ddplus" : {
"mixing" : true
},
"atmos" : {
"enabled" : true
}
}
}
Developers can query audiocaps.atmos.enabled for the Dolby Atmos capability by doing this:
String audioCapJsonStr = Settings.Global.getString(mContext.getContentResolver(), "audio_platform_capabilities");
JSONObject mAudioCapJson = new JSONObject(audioCapJson).getJSONObject("audiocaps");
JSONObject mAtmosCapJson = mAudioCapJson.getJSONObject("atmos");
boolean atmosEnabled = mAtmosCapJson.getBoolean("enabled");
By looking at the audio_platform_capabilities global settings, developers do not need to differentiate between products, Fire OS versions, and different audio endpoints. In the future, we will provide more information, such as supported sample rate, in the audio_platform_capabilities settings.
Method 3: AudioDeviceInfo
Android API level 23 added an API getEncodings that can also query sink capabilities. It looks like this:
AudioManager audio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] devices = audio.getDevices(audio.GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo device : devices) {
Log.i(TAG, "Supported Encodings" + Arrays.toString(device.getEncodings()));
}
For example, if we're looking at a TYPE_HDMI device, the output encodings list may be:
[2, 4, 5, 6, 7, 8, 13]
Mapping encoding names from the Android Open Source Project (AOSP): [PCM 16 Bit, Dolby Digital, Dolby Digital Plus, Dolby Atmos in Dolby Digital Plus, DTS, DTS HD, IEC61937]
Recommendation
Fire OS 7 devices
Use Method 1: EXTRA_ENCODINGS to detect all capability changes including Dolby Atmos.
Fire OS 6 devices
Use Method 1: EXTRA_ENCODINGS to detect capability changes. When streaming Dolby Atmos content, use Method 2: audio_platform_capabilities global settings to check Atmos capability.
Testing App
This audio testing app will help you find all the information based on the detection methods listed above.
AudioTrack Overview
Android L added the support of ENCODING_AC3 and ENCODING_E_AC3 encoding formats to AudioFormat. Android P added support for ENCODING_E_AC3_JOC used for Atmos. If the AudioTrack is configured with Dolby encoding format, and if the connecting endpoint supports that encoding format, AudioTrack accepts the Dolby raw bitstream as input and passes the bitstream to the endpoint after IEC61937 packetization. AudioTrack supports only clear (not encrypted) input bitstream.
Additionally, the creation of AudioTrack fails if the encoding format is not supported by the connected endpoint.
Certain platforms transcode DDP bitstream to DD if the connected endpoint only supports DD.
MediaCodec Overview
AudioTrack does not support Dolby audio content that is encrypted with DRM keys. Hence, for an encrypted Dolby audio bitstream, it is mandatory to use MediaCodec APIs to decrypt the bitstream and then pass the decrypted bitstream to AudioTrack.
Android provides a generic raw audio decoder via MediaCodec interface named "OMX.google.raw.dec", which is essentially a no-op (no operation) copy decoder. If the bitstream is encrypted, it uses MediaCrypto APIs to decrypt the bitstream and outputs it. Apps must use this decoder to decrypt the encrypted Dolby bitstream and pass the clear Dolby bitstream to AudioTrack.
Optionally, a platform can support Dolby decoder via MediaCodec interface. This decoder decodes the Dolby audio bitstream to PCM. Applications can use findDecoderForFormat to detect the presence of a decoder that supports Dolby MIME type.
Option 3: Use Other Supported Media Players
You can use other supported media players for Amazon Fire TV, such as VisualOn or NexPlayer, to play Dolby audio content and DRM content. Refer to Media Players for further details.
Option 4: Use Android Media Player
Your app can use Android MediaPlayer to play Dolby content.
Note: Android MediaPlayer can only output stereo PCM content and cannot support passthrough playback.
Handling non-Dolby End-Points and Private Listening Modes
This section describes recommendations and best practices for Dolby audio content playback on the Amazon Fire TV family of devices when connected to a non-Dolby endpoint and private listening(Bluetooth). Following these guidelines will help you create the best user experience for Dolby audio content playback.
As described previously, Android L introduced a new API in AudioManager called ACTION_HDMI_AUDIO_PLUG intent. This intent allows apps to detect the capabilities of the connected endpoint (AVR or TV). This detection can be used to support Dolby audio content playback in various HDMI related scenarios.
When connecting to a non HDMI sink device such as a Bluetooth headset the recommendation is to recreate the AudioTrack and switch to non-Dolby audio content such as AAC. This option has the advantage of reduced bandwidth usage as compared to Dolby audio content.
However, if the app cannot select an alternative non-Dolby audio content and chooses to continue to stream Dolby audio, applications should use MediaCodec to switch codecs from passthrough(OMX.google.raw.dec) to the appropriate Dolby codec(OMX.dolby.ac3.decoder or OMX.dolby.eac3.decoder).
The MediaCodec decoder decodes the Dolby bitstream, down-mixes to stereo PCM.
The AudioTrack again needs to be recreated with the ENCODING_PCM_16BIT
audio format to render the PCM data.
Since the Dolby Decoder in all the platforms down-mixes multi-channel content to stereo, there is no real advantage in choosing Dolby audio content when the endpoint does not support DD or DDP.
- Q. For Fire TV Edition, how does an app detect the capabilities of the connected endpoint (such as ACTION_HDMI_AUDIO_PLUG as mentioned above)?
- By default, the speakers of Fire TV Edition support stereo output only, and hence apps can stream stereo content by default. Dolby passthrough however is supported and recommended when playback is on TV speakers.
When the TV is connected to a sound bar or AVR via Optical audio output or HDMI (based on the Dolby system settings set by the user on Fire TV Edition), an app can choose to stream surround sound in Dolby audio format. -
To support this, the app is required to read a Global setting
external_surround_sound_enabled
to decide if surround sound (AC3 and EAC3) is supported or not. If the value is1
, Dolby audio is supported. If the value is0
, the app can further use other means (such as ACTION_HDMI_AUDIO_PLUG to decide if surround sound is supported or not. Refer to this Exoplayer patch (Added support for Surround Sound detection for Optical out for reference. - Q. Which audio stream should be selected for playback when the connected endpoint supports DD but does not support DDP?
- Most Amazon devices have the capability to automatically transcode DDP content to DD and passthrough the content to the DD only sink device.
This assumes the Amazon device reports support for DD as well. In the event DD is not supported as described above an alternate non-Dolby audio track needs to be selected or the DDP content needs to be decoded to PCM.
Last updated: Feb 22, 2022