Skip to content

3.7.0 - dec3 keeps a dependent substream's channels and JOC

Latest

Choose a tag to compare

@superuser404notfound superuser404notfound released this 09 Oct 04:23

Same n8.1.3 FFmpeg, dav1d, zimg and libzvbi as 3.6.0. One new local patch: the mp4 muxer's dec3 box describes a Dolby Digital Plus track whose height channels and Atmos objects live in a dependent substream.

What it fixes

A Blu-ray style DD+ Atmos track (an AC-3 core syncframe followed by an E-AC-3 dependent syncframe carrying the height channels and the ETSI TS 103 420 object metadata) was muxed with a dec3 box that described a bare 5.1 bed. tvOS decoded the core, and an Atmos receiver reported multichannel PCM 5.1. Reported as AetherEngine #728, with the diagnosis and the measured syncframe headers by @kdorepos in #729.

handle_eac3() in libavformat/movenc.c gets two fields wrong for that shape:

chan_loc came from chanmap with a plain shift. (channel_map >> 5) & 0x1f reads a field that is MSB-first and nine bits wide as if it were LSB-first and five, so a 5.1.2 dependent substream declared no extra channels at all. Fixed upstream as f10fdd6310, on master only, not in any release branch; backported here.

The JOC extension was read from the independent substream only. complexity_index_type_a was taken from the first header of each packet and never from the dependent ones, although the AC-3 parser reads it there. With the objects in the dependent frame it stayed 0 and the box was written in its short form. Not upstream yet, proposed as FFmpeg PR 24963.

The dec3 payload for the reported source:

before: 14 00 0C 0F 02 00          chan_loc 0x000, no extension
after:  14 00 0C 0F 02 40 01 10    chan_loc 0x040 (Lvh/Rvh), JOC, 16 objects

A track whose objects sit in the independent substream already got a correct box and is unchanged.

What ships now

  • New patch_ffmpeg_eac3_dec3 in two independently guarded halves. The chan_loc half skips itself once the pinned FFmpeg tag carries f10fdd6310.
  • New EAC3Dec3Tests mux the reporter's two syncframe headers through the shipped libavformat, once with AetherEngine's fragmented-MP4 movflags and once with a trailer-written moov, and read the dec3 payload back. Both fail on 3.6.0 with exactly the bytes from the report. An AC-3 core without a dependent substream is the control and keeps its short box on both builds.

swift test: 30 tests in 9 suites pass.