S/PDIF+HDMI: DTS passthrough untested - ffmpeg's spdif muxer emits no IEC 61937 bursts #78

Open
opened 2026-08-30 18:43:30 +00:00 by tiagoagueda · 1 comment
Owner

Split out of #42, which is fixed and closed. This is not that bug.

What works

AC-3 passthrough works, confirmed by ear and by measurement: the receiver displays Dolby
Digital
, drain 47998 frames/s against 48000 expected, 180 s elapsed for a 179.9 s track, IEC 61937
carried with NONAUDIO=1.

What does not

DTS locks and then sounds wrong - the receiver displays DTS, and the audio is described as
filtered, as though the top end has been removed. It fails identically across every variable we
changed:

varied tried result
the FCTL.TXIM fix before and after unchanged
encoder ffmpeg dca, and a reference DTS stream copied without re-encoding unchanged
bitrate 1411.2 kbps (100% link use) and 768 kbps (50%) unchanged
rate 44.1 kHz and 48 kHz 48 kHz also played slow
carriage 32-bit expanded, and raw 16-bit IEC 61937 with TXIM=1 - the vendor's own configuration unchanged

Every transport measurement was exact in every case: correct carrier rate, correct drain rate,
elapsed time matching the source duration, NONAUDIO set, zero xruns.

What that leaves

Since AC-3 passes through the identical path, and DTS fails with two independent encoders
including a genuine reference stream, this is neither the S/PDIF driver nor the encoder.

⚠️ An assumption worth revisiting first. The ELD quoted early in #42 - LPCM / AC-3 / DTS, 8
channels - was read from card 0, the HDMI sink. It says nothing about whatever is connected to
the optical output. Its DTS capability was assumed and never checked. If the optical device
handles DTS poorly, or not at all, that alone explains everything here.

Also worth noting: the board's previous Android firmware reportedly showed DTS-over-optical
glitching - a different failure from this one, but it suggests DTS on this path has a history.

Suggested next steps, cheap first

  1. Establish what the optical receiver actually is and whether it decodes DTS from any other
    source. That is a five-minute check and may end the issue.
  2. If it does decode DTS elsewhere, compare the IEC 61937 burst framing ffmpeg produces against a
    known-good source - burst period and Pc data type are the obvious candidates.
  3. Only then look at the driver, and note there is nothing in the registers to look at: they read
    identically for working and broken streams (see 59-spdif-txim.md).

P4-later: AC-3 covers the practical passthrough case, and this is very likely not our bug.

Split out of #42, which is fixed and closed. This is not that bug. ## What works **AC-3 passthrough works**, confirmed by ear and by measurement: the receiver displays *Dolby Digital*, drain 47998 frames/s against 48000 expected, 180 s elapsed for a 179.9 s track, IEC 61937 carried with `NONAUDIO=1`. ## What does not **DTS locks and then sounds wrong** - the receiver displays *DTS*, and the audio is described as filtered, as though the top end has been removed. It fails identically across every variable we changed: | varied | tried | result | | --- | --- | --- | | the `FCTL.TXIM` fix | before and after | unchanged | | encoder | ffmpeg `dca`, and a **reference DTS stream** copied without re-encoding | unchanged | | bitrate | 1411.2 kbps (100% link use) and 768 kbps (50%) | unchanged | | rate | 44.1 kHz and 48 kHz | 48 kHz also played *slow* | | carriage | 32-bit expanded, and raw 16-bit IEC 61937 with `TXIM=1` - the vendor's own configuration | unchanged | Every transport measurement was exact in every case: correct carrier rate, correct drain rate, elapsed time matching the source duration, `NONAUDIO` set, zero xruns. ## What that leaves Since **AC-3 passes through the identical path**, and DTS fails with two independent encoders including a genuine reference stream, this is neither the S/PDIF driver nor the encoder. ⚠️ **An assumption worth revisiting first.** The ELD quoted early in #42 - LPCM / AC-3 / DTS, 8 channels - was read from **card 0, the HDMI sink**. It says nothing about whatever is connected to the *optical* output. Its DTS capability was assumed and never checked. If the optical device handles DTS poorly, or not at all, that alone explains everything here. Also worth noting: the board's previous Android firmware reportedly showed DTS-over-optical **glitching** - a different failure from this one, but it suggests DTS on this path has a history. ## Suggested next steps, cheap first 1. **Establish what the optical receiver actually is** and whether it decodes DTS from any other source. That is a five-minute check and may end the issue. 2. If it does decode DTS elsewhere, compare the IEC 61937 burst framing ffmpeg produces against a known-good source - burst period and `Pc` data type are the obvious candidates. 3. Only then look at the driver, and note there is nothing in the registers to look at: they read identically for working and broken streams (see `59-spdif-txim.md`). **P4-later**: AC-3 covers the practical passthrough case, and this is very likely not our bug.
Author
Owner

Cause found: the stream has no IEC 61937 burst preambles

Not the board, not either sink, not the DTS encoder. ffmpeg's -f spdif muxer never wrapped the
DTS frames in bursts.

Scanning the muxer's output for the IEC 61937 preamble finds nothing at all:

first 16 bytes:  fe 7f 01 80 ...          <- DTS sync word, immediately, at offset 0
Pa=0xF872 / Pb=0x4E1F : 0 occurrences in 400 KB, in either byte order
DTS frame spacing     : 2048 bytes = exactly 512 stereo frames

The payload is byte-swapped correctly and the frames are laid down on a perfect 512-frame period,
but there is no Pa/Pb sync, no Pc data type and no Pd length anywhere.

That explains every symptom precisely. A DTS decoder scanning for its own 7FFE8001 sync finds it,
on time, every 512 frames - so the receiver locks and displays "DTS". Without Pc/Pd it has
no burst framing, mis-assembles frame boundaries and loses the upper subbands, which is heard as a
low-pass. AC-3 was unaffected because ffmpeg's AC-3 path does emit proper bursts.

What eliminated everything else

suspect verdict how
the S/PDIF driver clean AC-3 passthrough works on it
the optical receiver clean HDMI shows the identical artifact
the HDMI path clean AC-3 passthrough works on it too
the DTS encoder clean a reference stream, copied with -c:a copy, fails identically
ffmpeg's spdif muxer cause no burst preambles in its output

Also varied without effect, for the record: the FCTL.TXIM fix (before and after), 1411.2 kbps
(100% link use) vs 768 kbps (50%), 44.1 kHz vs 48 kHz, and 32-bit-expanded vs raw 16-bit carriage.
Every transport measurement was exact in every case - correct carrier rate, correct drain rate,
elapsed matching source duration, NONAUDIO set, zero xruns.

Two capabilities confirmed on the way

  • S/PDIF AC-3 passthrough works (receiver displays Dolby Digital)
  • HDMI AC-3 passthrough works - new, and not previously known for this board. The HDMI IEC958
    control accepts the non-audio flag and carries a fuller channel status than the S/PDIF path
    (AES0=0x06 AES1=0x00 AES2=0x00 AES3=0x01, i.e. bitstream plus a 48 kHz rate field).

So this board does DTS passthrough as far as anyone has tested it - we simply never fed it a
correctly framed DTS stream.

To actually verify DTS

Produce a properly wrapped stream and replay. Options, cheapest first:

  1. A player that does passthrough natively (VLC/mpv with a passthrough-capable ALSA output), which
    builds the bursts itself rather than relying on the muxer.
  2. Check whether a newer ffmpeg fixes the DTS path in the spdif muxer - the AC-3 path clearly works,
    so this looks like a codec-specific gap rather than a broken muxer.
  3. Failing both, wrap it by hand: Pa=0xF872 Pb=0x4E1F Pc=11 (DTS Type I, 512 samples - which
    matches the 512-frame period measured above) and Pd = payload length in bits.

Reduced to P4-later and reframed: this is not a board defect, and the board is not blocked on
it. Detail in 59-spdif-txim.md.

## Cause found: the stream has no IEC 61937 burst preambles Not the board, not either sink, not the DTS encoder. **ffmpeg's `-f spdif` muxer never wrapped the DTS frames in bursts.** Scanning the muxer's output for the IEC 61937 preamble finds nothing at all: ``` first 16 bytes: fe 7f 01 80 ... <- DTS sync word, immediately, at offset 0 Pa=0xF872 / Pb=0x4E1F : 0 occurrences in 400 KB, in either byte order DTS frame spacing : 2048 bytes = exactly 512 stereo frames ``` The payload is byte-swapped correctly and the frames are laid down on a perfect 512-frame period, but there is no `Pa`/`Pb` sync, no `Pc` data type and no `Pd` length anywhere. That explains every symptom precisely. A DTS decoder scanning for its own `7FFE8001` sync finds it, on time, every 512 frames - so the receiver **locks and displays "DTS"**. Without `Pc`/`Pd` it has no burst framing, mis-assembles frame boundaries and loses the upper subbands, which is heard as a low-pass. AC-3 was unaffected because ffmpeg's AC-3 path does emit proper bursts. ## What eliminated everything else | suspect | verdict | how | |---|---|---| | the S/PDIF driver | clean | AC-3 passthrough works on it | | the optical receiver | clean | HDMI shows the identical artifact | | the HDMI path | clean | AC-3 passthrough works on it too | | the DTS encoder | clean | a reference stream, copied with `-c:a copy`, fails identically | | **ffmpeg's spdif muxer** | **cause** | no burst preambles in its output | Also varied without effect, for the record: the `FCTL.TXIM` fix (before and after), 1411.2 kbps (100% link use) vs 768 kbps (50%), 44.1 kHz vs 48 kHz, and 32-bit-expanded vs raw 16-bit carriage. Every transport measurement was exact in every case - correct carrier rate, correct drain rate, elapsed matching source duration, `NONAUDIO` set, zero xruns. ## Two capabilities confirmed on the way - **S/PDIF AC-3 passthrough works** (receiver displays *Dolby Digital*) - **HDMI AC-3 passthrough works** - new, and not previously known for this board. The HDMI IEC958 control accepts the non-audio flag and carries a fuller channel status than the S/PDIF path (`AES0=0x06 AES1=0x00 AES2=0x00 AES3=0x01`, i.e. bitstream plus a 48 kHz rate field). So this board does DTS passthrough as far as anyone has tested it - we simply never fed it a correctly framed DTS stream. ## To actually verify DTS Produce a properly wrapped stream and replay. Options, cheapest first: 1. A player that does passthrough natively (VLC/mpv with a passthrough-capable ALSA output), which builds the bursts itself rather than relying on the muxer. 2. Check whether a newer ffmpeg fixes the DTS path in the spdif muxer - the AC-3 path clearly works, so this looks like a codec-specific gap rather than a broken muxer. 3. Failing both, wrap it by hand: `Pa=0xF872 Pb=0x4E1F Pc=11` (DTS Type I, 512 samples - which matches the 512-frame period measured above) and `Pd` = payload length in bits. **Reduced to P4-later and reframed**: this is not a board defect, and the board is not blocked on it. Detail in `59-spdif-txim.md`.
tiagoagueda changed title from S/PDIF: DTS passthrough decodes but sounds filtered (AC-3 is fine) to S/PDIF+HDMI: DTS passthrough untested - ffmpeg's spdif muxer emits no IEC 61937 bursts 2026-08-30 18:55:22 +00:00
Sign in to join this conversation.
No description provided.