Support differentiating between DTS-HD and DTS Express in TS, MP4 and Matroska extractors#3147
Support differentiating between DTS-HD and DTS Express in TS, MP4 and Matroska extractors#3147nift4 wants to merge 9 commits intoandroidx:mainfrom
Conversation
The TS extractor already supports DTS Express which uses the same headers as DTS-HD, but it had two bugs that made it impratical to use with DTS-HD streams: * The mime type was hardcoded to DTS Express instead of reading from header. (Also, the DTS-HD sample actually is DTS Express.) * The core format was emitted before the extension substream is read in a typical DTS-HD stream, which contains interleaved core and extension samples. Meanwhile, a DTS Express stream consists of extension samples only. This interleaved stream should still be output with the format of the extension samples, that is, DTS-HD, as opposed to core format (DTS only). To test this, a DTS-HD MA sample borrowed from the Matroska samples in ExoPlayer and remuxed with ffmpeg is added. Issue: androidx#2487
|
Not enough. Please follow the ffmpeg implementation. |
|
@FongMi please can you elaborate a bit? |
|
@FongMi Well, I see that you did a lot of changes and most of them seem to address the same issue that we shouldn't emit core format but extension format instead (I solved it with the PatientTrackOutput wrapper and you added a new state and coreFormatPendingEmit instead). My fix is a bit subtle because it intercepts the format() call and waits until extension header is parsed before sending, allowing to overwrite the format which is cached. But it works and it's readable. I also see another issue which I didn't solve but you solved it, that we should wait for core frame after seeking instead of sending extension substream frame first - it makes sense and I'll add it to my patch. Is there any other problem I need to address? |
|
That should be all. I'll test the ISO file again after you finish. |
FFmpeg outputs DTS Express files with "DTS" codec ID, so we need to add it to the detection. That however is free because we must do the detection anyway for DTS-HD, and we can even reuse all the code needed for TS logic.
|
@FongMi It should be good now, let me know if it works. Thanks :) |
|
Users have reported that the playback quality of DTS-HD is not as good as my version, and that stuttering occurs. This may be because your Core+EXTSS is sent in segments, while mine is sent all at once. |
|
FongMi@6755c3e |
Should be fixed, please check again. Thanks for testing!
It's on my TODO list, but I will do it in a seperate PR when this is merged. This one is already quite big. |
|
@nift4 Users say it's still very laggy. Core Architectural Differencenick —
|
| Criterion | fongmi | nick |
|---|---|---|
| Data copies per frame | 1 (direct write) | 2 (buffered) |
| Per-frame heap allocation | None | ByteBuffer.wrap() each call |
ensureCapacity reallocation risk |
None | Yes (large frames) |
| DTS:X (XLL-X) auto-detection | Yes | No |
| Post-seek resync | skipExtssUntilCore (precise) |
waitingForResyncAfterSeek (basic) |
| GC pressure | Low | Higher |
Verdict
fongmi is faster, for three reasons:
-
Zero-copy: data is written directly to
TrackOutput, eliminating thePatientTrackOutputintermediate buffer and second memcpy. For large DTS-HD MA frames (potentially hundreds of KB each), this is significant. -
No per-frame heap allocation: nick allocates a new
ByteBufferwrapper on everysampleData()call, increasing GC pressure. -
Richer functionality: fongmi adds XLL-X scanning to auto-detect DTS:X object audio and properly upgrades the track format to
AUDIO_DTS_X, which nick lacks entirely.
nick's PatientTrackOutput is a cleaner abstraction conceptually, but the double-copy cost makes it a poor trade-off for a hot path that processes audio frames continuously.
|
Hi @FongMi, I ran my sample file through both versions of extractors and only difference I saw in result was average bitrate was set on mine. That's set from core header, I imagine it might cause buffer allocation to be too small, so I removed it. Can you re-test?
Also, I don't think that's the problem causing audible lags, but I changed it to only do that on the first frame (after seek). |
The TS extractor already supports DTS Express which uses the same headers as DTS-HD, but it had two bugs that made it impratical to use with DTS-HD streams:
Meanwhile, Matroska had the wrong mime type assignment for DTS Express codec id. Also, FFmpeg outputs DTS Express files with "DTS" codec ID instead of "DTS Express", so we need to add it to the detection logic anyway. That however is free because we must do the detection anyway for DTS-HD, and we can even reuse all the code needed for TS logic.
The MP4 sample description box doesn't contain information about whether a stream is DTS Express, so use the same detection approach for MP4.
Issue: #2487