Developer Console

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

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:

  1. ExoPlayer
  2. Custom Media Player Approach
  3. Other Supported Media Players
  4. Android Media Player

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:

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);
            }
        }
    }
};

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.

Test app for audio capabilities
The testing app can be used to find your device audio capabilities

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 is 1, Dolby audio is supported. If the value is 0, 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