PR #23153 opened by Rodeo
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23153
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23153.patch
### Context
movenc currently writes stsd v1 even when the layout has more than 2 channels.
[before the change]
**_afinfo (and presumably any other tools using QuickTime / Core Audio) skip
and/or otherwise do not parse the layout contained in 'chan' atom written by
movenc:_**
```bash
ffmpeg -i AV_CH_LAYOUT_5POINT1_SIDE.FLAC -c pcm_s16le -y out.mov 2> /dev/null
&& afinfo out.mov
File: out.mov
File type ID: MooV
Num Tracks: 1
----
Data format: 6 ch, 48000 Hz, Int16, interleaved
no channel layout.
```
(for PCM codecs, that is; for compressed formats such as AAC and AC-3, afinfo
seems to read/parse the layout despite the stsd being a v1)
[after the change]
```bash
ffmpeg -i AV_CH_LAYOUT_5POINT1_SIDE.FLAC -c pcm_s16le -y out.mov 2> /dev/null
&& afinfo out.mov
File: out.mov
File type ID: MooV
Num Tracks: 1
----
Data format: 6 ch, 48000 Hz, Int16, interleaved
Channel layout: 5.1 (L R C LFE Ls Rs)
```
### QTFF specification says
Sound Sample Description (Version 0)
- Number of channels
- A 16-bit integer that indicates the number of sound channels used by the
sound sample. Set to 1 for
monaural sounds, 2 for stereo sounds. Higher numbers of channels are not
supported.
- Sample rate
- A 32-bit unsigned fixed-point number (16.16) that indicates the rate at
which the sound samples were
obtained. The integer portion of this number should match the media’s time
scale. Many older version
0 files have values of 22254.5454 or 1 1 127 .2727 , but most files have
integer values, such as 44100. Sample
rates greater than 2^16 are not supported.
Sound Sample Description (Version 1)
- The version field in the sample description is set to 1 for this version of
the sound description structure. In
version 1 of the sound description, introduced in QuickTime 3, the sound
description record is extended by 4
fields, each 4 bytes long, and includes the ability to add atoms to the sound
description.
(the above suggests that the limitations of version 0, such as number of
channels, or maximum sample rate, are carried over to version 1)
### More explicitly, it also says
Audio Channel Layout Atom (‘chan’)
- This atom is an optional extension to the sound sample description specifying
audio channel layouts for sound
media contained in QuickTime movies. It is a full atom followed by a big-endian
audio channel layout structure
as defined by Apple’s Core Audio framework. Audio channel layouts can be
applied to both compressed and
uncompressed sound formats.
- **_Note Audio channel layouts with more than two channels per track require
implementation with
a version 2 sound sample description._**
From cacd6b05d63add4263966c8f7c8c841c36373d0c Mon Sep 17 00:00:00 2001
From: Tim Walker <[email protected]>
Date: Tue, 19 May 2026 15:10:45 +0200
Subject: [PATCH 1/2] avformat/movenc: use sample_rate to determine audio stsd
version. timescale should be equal sample_rate, but the latter is the actual
"source" field used when writing the stsd atom.
---
libavformat/movenc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index d0346b6f4c..95b1e3a049 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1379,7 +1379,7 @@ static int mov_write_audio_tag(AVFormatContext *s,
AVIOContext *pb, MOVMuxContex
int ret = 0;
if (track->mode == MODE_MOV) {
- if (track->timescale > UINT16_MAX ||
!track->par->ch_layout.nb_channels) {
+ if (track->par->sample_rate > UINT16_MAX ||
!track->par->ch_layout.nb_channels) {
if (mov_get_lpcm_flags(track->par->codec_id))
tag = AV_RL32("lpcm");
version = 2;
--
2.52.0
From 9cabad666185e0f03aa9925a739530ebb3b0f66d Mon Sep 17 00:00:00 2001
From: Tim Walker <[email protected]>
Date: Tue, 19 May 2026 15:16:04 +0200
Subject: [PATCH 2/2] avformat/movenc: write stsd v2 atom when nb_channels > 2
Required by the QuickTime File Format specification.
---
libavformat/movenc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 95b1e3a049..6d551bb930 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1379,7 +1379,8 @@ static int mov_write_audio_tag(AVFormatContext *s,
AVIOContext *pb, MOVMuxContex
int ret = 0;
if (track->mode == MODE_MOV) {
- if (track->par->sample_rate > UINT16_MAX ||
!track->par->ch_layout.nb_channels) {
+ if (track->par->sample_rate > UINT16_MAX ||
!track->par->ch_layout.nb_channels ||
+ track->par->ch_layout.nb_channels > 2) {
if (mov_get_lpcm_flags(track->par->codec_id))
tag = AV_RL32("lpcm");
version = 2;
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]