google / ExoPlayer

An extensible media player for Android
Apache License 2.0
21.63k stars 6k forks source link

Detect DTS-HD in Matroska #6225

Open andrewlewis opened 4 years ago

andrewlewis commented 4 years ago

[REQUIRED] Use case description

Support DTS-HD passthrough with audio contained in the Matroska container. See #2147 for more context.

Proposed solution

As the container does not explicitly signal DTS-HD vs DTS, we need to inspect the first audio access unit to determine if the audio is in DTS-HD format. See https://github.com/google/ExoPlayer/issues/2147#issuecomment-464041620 for more details.

Alternatives considered

We could add a flag to allow apps to force the extractor to advertise DTS-HD instead of DTS, but it seems preferable to have the extractor determine the media type correctly based on the media, without external information.

cncb-gh commented 3 years ago

Does this change in 2.14.0 have anything to do with this?

Allow fall back from DTS-HD to DTS when playing via passthrough.

andrewlewis commented 3 years ago

292700e93beb9cf0d635948817b00f1b0ae4d4fd doesn't directly address this (MatroskaExtractor still doesn't create a DTS-HD track).

moneytoo commented 2 years ago

The remaining piece to submit this workaround would be having a way to identify that the track is DTS-HD by looking at the start of the first sample. If someone on this thread knows what's needed to distinguish the two formats based on one access unit, please leave a comment and we can get this fixed.

Seems like this is the magic other tools use to detect HD.

FFmpeg:

#define DCA_HD_MARKER     0x64582025

mp4parser:

sync == 0x64582025 // DTS_SYNCWORD_SUBSTREAM
moneytoo commented 2 years ago

General DTS-HD detection is really only about presence of DTS extension substream sync word (0x64582025). We need to have access to up to 16383 + 4 bytes of data (max frame size + sync word of the second frame). We already have DtsUtil.getDtsFrameSize() helper for navigation to that second frame.

I'm already doing that in MatroskaExtractor.writeSampleData() to update mime type using track.output.format(). Is there any other/better place for detection? While the bitstream output is properly marked as DTS-HD and played correctly, the track details in track selectors are not updated.

I'm receiving feedback that this solution works properly for users with various DTS-HD content (Master Audio, High Resolution Audio). (I would send a PR but cause I'm only a hobby dev, my patch is really sloppy.)

However when using this, I encountered an issue resulting in no audio playback at all. Somehow this doesn't work when I use Geniatech ATV-598Max (somewhat obscure, but Google certified Android TV 7.1 device) and ONKYO TX-NR509. Setting DTS-HD mime type break playback while DTS mime type works. However VLC can output playable DTS-HD on the same hardware just fine. (I will do more testing when I will have access to different box) Could this be because VLC possibly uses IEC 61937 instead (just guessing)?

cncb-gh commented 1 year ago

Any progress here?