Skip to content

HLS (fMP4) Exoplayer v2.17.1 DTS Digital Surround Passthrough Issue #10204

Closed

Description

@cedricxperi

ExoPlayer Version

2.17.1

Devices that reproduce the issue

Nvidia Shield TV Pro

Devices that do not reproduce the issue

None

Reproducible in the demo app?

Yes

Reproduction steps

Playback a HLS (fMP4) DTS Digital Surround audio stream on Nvidia Shield TV Pro (connected to an AVR via HDMI) running v2.17.1 Exoplayer demo app.
The DTS bitstream should be passthrough to the AVR for decoding. This works in earlier versions of Exoplayer, E.g. v2.14.1. In v2.17.1 the playback fails.

Expected result

The DTS bitstream should be passthrough to the AVR for decoding.

Actual result

Playback Fails.

Diagnosis

In Exoplayer, there is a variable  allowChunklessPreparation in HLSMediaPeriod.java which determines whether chunkless preparation (for HLS-fMp4 streams) is allowed. If chunkless preparation is allowed, the attributes of the Codec (such as channelCount) will not be determined by downloading a segment and parsing the Moov box (AtomParsers.parseAudioSampleEntry()). Instead, it will be trying to read these attributes from the Multivariant HLS playlist. Details on Multivariant playlist is here: https://developer.apple.com/documentation/http_live_streaming/example_playlists_for_http_live_streaming/creating_a_multivariant_playlist

When Exoplayer is deciding whether to passthrough the bitstream, it calls DefaultAudioSink().isPassthroughPlaybackSupported(), which will return false when channelCount of the stream is unknown.

When allowChunklessPreparation is set to true, it depends on the HLS manifests (See HlsPlaylistParser::parseMultivariantPlaylist(), HLSMediaPeriod::deriveAudioFormat()) to provide information on the CODECS.  However, in the test streams used, "channelCount" is not part of the information provide by the HLS Multivariant playlist. This resulted in the channelCount not being defined and DefaultAudioSink().isPassthroughPlaybackSupported() will return false causing the Digital Surround bitstream passthrough to fail.

When allowChunklessPreparation is set to false, channelCount will be read by parsing the Moov box (AtomParsers.parseAudioSampleEntry()) during the setup stage. A subsequent call to DefaultAudioSink().isPassthroughPlaybackSupported() will then return true and passthrough is possible.

In Exoplayer v2.14.1, allowChunklessPreparation in HLSMediaPeriod.java was not set explicitly and it defaults to false. Therefore passthrough works.

In Exoplayer v2.17.1, allowChunklessPreparation in HLSMediaPeriod.java was initialised to true. This caused passthrough to fail for the reasons mentioned earlier (channelCount undefined).

Solution

In order to overcome this issue, It is recommended in Exoplayer v2.17.X to initialise allowChunklessPreparation to false in the constructor of HLSMediaSource.Factory. This will allow HLS-fMP4 with DTS Digital Surround to passthrough successfully.

Media

Test media will be emailed to [email protected]

Bug Report

  • You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

Activity

  1. self-assigned this
    on Apr 20, 2022
  2. christosts commented on Apr 20, 2022

    @christosts
    Contributor

    @andrewlewis do you now if we can make a safe guess on the number of channels if the information is missing from Format for those audio formats for which the player does audio passthrough? In this issue it's DTS, but I think the same problem may apply for the other audio encodings too. With HLS chunkless preparation, we cannot know the channel count from the playlist., hence Format.channelCount is not set.

    For example, could DefaultAudioSink do something similar as in the ENCODING_E_AC3_JOC case (link)?

  3. andrewlewis commented on Apr 20, 2022

    @andrewlewis
    Collaborator

    If this is for plain DTS it looks like it only goes up to 5.1 so we could conservatively check for 6 channel output capability. That should be safe in the sense that there can't be more channels in the stream when it loads. For HDMI audio capabilities we get a max channel count so that probably means that fewer channels than the max are always supported.

  4. cedricxperi commented on Apr 27, 2022

    @cedricxperi
    ContributorAuthor

    Hi @andrewlewis @christosts ,

    Picking up on your suggestions, how about something like below in DefaultAudioSink.getEncodingAndChannelConfigForPassthrough(). I have tested that the below works for passing through DTS Digital surround on Nvidia Shield TV Pro. Thanks.

    if (encoding == C.ENCODING_E_AC3_JOC) {
    // E-AC3 JOC is object based so the format channel count is arbitrary. From API 29 we can get
    // the channel count for this encoding, but before then there is no way to query it so we
    // assume 6 channel audio is supported.
    if (Util.SDK_INT >= 29) {
    // Default to 48 kHz if the format doesn't have a sample rate (for example, for chunkless
    // HLS preparation). See [Internal: b/222127949].
    int sampleRate = format.sampleRate != NO_VALUE ? format.sampleRate : 48000;
    channelCount =
    getMaxSupportedChannelCountForPassthroughV29(C.ENCODING_E_AC3_JOC, sampleRate);
    if (channelCount == 0) {
    Log.w(TAG, "E-AC3 JOC encoding supported but no channel count supported");
    return null;
    }
    } else {
    channelCount = 6;
    }
    } else if (encoding == C.ENCODING_DTS) {
    channelCount = format.channelCount;
    if (channelCount == NO_VALUE){
    channelCount = 6;
    }
    } else {

    channelCount = format.channelCount;
    if (channelCount > audioCapabilities.getMaxChannelCount()) {
    return null;
    }
    }

  5. christosts commented on May 9, 2022

    @christosts
    Contributor

    Yes, we will add a fix along those lines - we are planning to have the fix included in the release.

  6. cedricxperi commented on May 9, 2022

    @cedricxperi
    ContributorAuthor

    @christosts That's great. Thanks a lot.

  7. christosts commented on Jun 8, 2022

    @christosts
    Contributor

    The upcoming 2.18 release will have a fix for this. The issue will be updated with a link to the commit once the dev branch is updated. The submitted fix covers not only DTS but other surround formats for which the player does audio passthrough playback and were affected by HLS chunkless preparation.

    Thank you for bringing this issue to our attention and sharing test content. I will close this issue for now, feel free to re-open is the fix did not resolve your problem.

  8. locked and limited conversation to collaborators on Aug 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions