FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/pcm-dvda.c
Date: 2026-08-19 01:31:13
Exec Total Coverage
Lines: 96 119 80.7%
Functions: 4 4 100.0%
Branches: 49 72 68.1%

Line Branch Exec Source
1 /*
2 * LPCM codec for PCM formats found in DVD-Audio streams
3 * Copyright (c) 2026 Kacper Michajłow
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <assert.h>
23 #include <stddef.h>
24
25 #include "libavutil/channel_layout.h"
26
27 #include "avcodec.h"
28 #include "bytestream.h"
29 #include "codec_internal.h"
30 #include "decode.h"
31
32 /*
33 * Header of a linear PCM audio packet (A_PKT) of a DVD-Audio AOB. It
34 * follows the 0xa0 sub_stream_id byte of the MPEG private_stream_1 packet
35 * and is itself followed by 0 to 7 stuffing bytes and the audio data.
36 * Layout and semantics from US 6,580,671 (FIGS. 27 and 29, cols. 19-21).
37 */
38 typedef struct PCMDVDAHeader {
39 /* reserved (4 bits), ISRC number (4 bits): position, from 1 to 12, of
40 * the isrc_data byte within the track's 12-character International
41 * Standard Recording Code, which is spread over consecutive packets */
42 uint8_t isrc_number;
43 /* the ISRC character designated by isrc_number */
44 uint8_t isrc_data;
45 /* number of header bytes following this field, including the trailing
46 * stuffing bytes; the audio data starts right after */
47 uint8_t private_header_length;
48 /* big-endian byte offset, counted from the end of this field, of the
49 * first audio frame (access unit) to be presented at the packet's PTS */
50 uint8_t first_access_unit_pointer[2];
51 /* audio emphasis flag (1 bit): high-frequency emphasis is applied,
52 * never set for a group sampled at 96 or 88.2 kHz; reserved (3 bits);
53 * downmix code (4 bits): selects which of the 16 downmix coefficient
54 * tables of the title set (ATS_DM_COEFT #0..#15 in the ATSI_MAT) to
55 * use for multichannel to 2-channel output */
56 uint8_t emphasis_downmix;
57 /* quantization word length of channel group 1 (4 bits) and group 2
58 * (4 bits): 0 = 16, 1 = 20, 2 = 24 bits per sample;
59 * 0xf in group 2 when the group does not exist */
60 uint8_t quantization;
61 /* audio sampling frequency of channel group 1 (4 bits) and group 2
62 * (4 bits): 0 = 48 kHz, 1 = 96 kHz, 2 = 192 kHz, 8 = 44.1 kHz,
63 * 9 = 88.2 kHz, 0xa = 176.4 kHz; 0xf in group 2 when the group does
64 * not exist */
65 uint8_t sampling_frequency;
66 /* reserved (4 bits), multichannel type (4 bits): 0 = type 1, the only
67 * defined sample structure; other values reserved */
68 uint8_t multichannel_type;
69 /* reserved (3 bits), channel assignment (5 bits): selects one of the
70 * 21 channel-to-group allocations, see channel_assignments[] */
71 uint8_t channel_assignment;
72 /* dynamic range control: X (3 bits), Y (5 bits); playback may scale
73 * the audio by 2^(4 - X - Y/30) with 0 <= X <= 7, 0 <= Y <= 29, so
74 * 0x80 is unity gain; not applied, as with the other PCM decoders */
75 uint8_t dynamic_range_control;
76 } PCMDVDAHeader;
77
78 static_assert(sizeof(PCMDVDAHeader) == 11, "unexpected header padding");
79
80 typedef struct PCMDVDAContext {
81 uint32_t last_header; // Cached header to avoid reparsing
82 int block_size; // Size of a set of 2 samples over all channels
83 int channels;
84 int group_channels[2]; // Channels in group 1 / group 2 (0 = unused)
85 int group_bits[2]; // Quantization of group 1 / group 2
86 uint8_t group_map[2][6]; // Stream channel -> native layout position
87 } PCMDVDAContext;
88
89 #define CH_C AV_CH_FRONT_CENTER
90 #define CH_L AV_CH_FRONT_LEFT
91 #define CH_R AV_CH_FRONT_RIGHT
92 #define CH_LFE AV_CH_LOW_FREQUENCY
93 #define CH_S AV_CH_BACK_CENTER
94 #define CH_LS AV_CH_BACK_LEFT
95 #define CH_RS AV_CH_BACK_RIGHT
96
97 /*
98 * Channel allocation table (US 6,580,671 FIG. 26 and cols. 18-19): the
99 * speaker fed by each audio channel, in stream order (ACH0..ACH5, first
100 * channel group first), and how many channels each group holds. Beware
101 * that the counts column of FIG. 26 misprints the group 1 size of
102 * assignments 13 (3, not 2) and 18 (4, not 3). The group boundary drawn
103 * in the figure and the enumeration in cols. 18-19 agree on the values
104 * used here.
105 */
106 static const struct {
107 uint8_t group1_channels;
108 uint8_t group2_channels;
109 uint64_t channels[6];
110 } channel_assignments[21] = {
111 [ 0] = { 1, 0, { CH_C } },
112 [ 1] = { 2, 0, { CH_L, CH_R } },
113 [ 2] = { 2, 1, { CH_L, CH_R, CH_S } },
114 [ 3] = { 2, 2, { CH_L, CH_R, CH_LS, CH_RS } },
115 [ 4] = { 2, 1, { CH_L, CH_R, CH_LFE } },
116 [ 5] = { 2, 2, { CH_L, CH_R, CH_LFE, CH_S } },
117 [ 6] = { 2, 3, { CH_L, CH_R, CH_LFE, CH_LS, CH_RS } },
118 [ 7] = { 2, 1, { CH_L, CH_R, CH_C } },
119 [ 8] = { 2, 2, { CH_L, CH_R, CH_C, CH_S } },
120 [ 9] = { 2, 3, { CH_L, CH_R, CH_C, CH_LS, CH_RS } },
121 [10] = { 2, 2, { CH_L, CH_R, CH_C, CH_LFE } },
122 [11] = { 2, 3, { CH_L, CH_R, CH_C, CH_LFE, CH_S } },
123 [12] = { 2, 4, { CH_L, CH_R, CH_C, CH_LFE, CH_LS, CH_RS } },
124 [13] = { 3, 1, { CH_L, CH_R, CH_C, CH_S } },
125 [14] = { 3, 2, { CH_L, CH_R, CH_C, CH_LS, CH_RS } },
126 [15] = { 3, 1, { CH_L, CH_R, CH_C, CH_LFE } },
127 [16] = { 3, 2, { CH_L, CH_R, CH_C, CH_LFE, CH_S } },
128 [17] = { 3, 3, { CH_L, CH_R, CH_C, CH_LFE, CH_LS, CH_RS } },
129 [18] = { 4, 1, { CH_L, CH_R, CH_LS, CH_RS, CH_LFE } },
130 [19] = { 4, 1, { CH_L, CH_R, CH_LS, CH_RS, CH_C } },
131 [20] = { 4, 2, { CH_L, CH_R, CH_LS, CH_RS, CH_C, CH_LFE } },
132 };
133
134 2 static av_cold int pcm_dvda_decode_init(AVCodecContext *avctx)
135 {
136 2 PCMDVDAContext *s = avctx->priv_data;
137
138 /* Invalid header to force parsing of the first header */
139 2 s->last_header = -1;
140
141 2 return 0;
142 }
143
144 25 static int pcm_dvda_parse_header(AVCodecContext *avctx,
145 const PCMDVDAHeader *header)
146 {
147 25 PCMDVDAContext *s = avctx->priv_data;
148 25 uint32_t header_int = header->quantization |
149 25 header->sampling_frequency << 8 |
150 25 header->channel_assignment << 16;
151 25 int assignment = header->channel_assignment & 0x1f;
152 int bits[2], rate[2];
153 25 uint64_t mask = 0;
154
155 /* early exit if the header didn't change */
156
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 2 times.
25 if (s->last_header == header_int)
157 23 return 0;
158 2 s->last_header = -1;
159
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (avctx->debug & FF_DEBUG_PICT_INFO)
161 av_log(avctx, AV_LOG_DEBUG, "pcm_dvda_parse_header: header = %02x%02x%02x\n",
162 header->quantization, header->sampling_frequency,
163 header->channel_assignment);
164
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (assignment > 20) {
166 av_log(avctx, AV_LOG_ERROR, "invalid channel group assignment %d\n",
167 assignment);
168 return AVERROR_INVALIDDATA;
169 }
170
171 2 s->group_channels[0] = channel_assignments[assignment].group1_channels;
172 2 s->group_channels[1] = channel_assignments[assignment].group2_channels;
173
174
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < 2; i++) {
175
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 int quant = i ? header->quantization & 0xf : header->quantization >> 4;
176
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 int freq = i ? header->sampling_frequency & 0xf : header->sampling_frequency >> 4;
177
178 /* 0xf marks an absent channel group */
179
3/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if (i && (quant == 0xf || freq == 0xf))
180 2 s->group_channels[1] = 0;
181
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (!s->group_channels[i]) {
182 2 bits[i] = rate[i] = 0;
183 2 continue;
184 }
185
186
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (quant > 2 || (freq & 7) > 2) {
187 av_log(avctx, AV_LOG_ERROR,
188 "invalid group %d quantization %#x or sample rate %#x\n",
189 i + 1, quant, freq);
190 return AVERROR_INVALIDDATA;
191 }
192 2 bits[i] = 16 + 4 * quant;
193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 rate[i] = (freq & 8 ? 44100 : 48000) << (freq & 7);
194
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (bits[i] == 20) {
196 avpriv_request_sample(avctx, "20-bit group %d quantization", i + 1);
197 return AVERROR_PATCHWELCOME;
198 }
199 }
200
201
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (s->group_channels[1] && rate[1] != rate[0]) {
202 avpriv_request_sample(avctx, "Mixed group sample rates (%d, %d)",
203 rate[0], rate[1]);
204 return AVERROR_PATCHWELCOME;
205 }
206
207 2 s->group_bits[0] = bits[0];
208 2 s->group_bits[1] = bits[1];
209 2 s->channels = s->group_channels[0] + s->group_channels[1];
210 2 s->block_size = 2 * (s->group_channels[0] * bits[0] +
211 2 s->group_channels[1] * bits[1]) / 8;
212
213 /* map the stream channel order to the native layout order */
214
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < s->channels; i++)
215 4 mask |= channel_assignments[assignment].channels[i];
216
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (int i = 0; i < s->channels; i++) {
217 4 uint64_t ch = channel_assignments[assignment].channels[i];
218 4 int pos = av_popcount64(mask & (ch - 1));
219
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (i < s->group_channels[0])
220 4 s->group_map[0][i] = pos;
221 else
222 s->group_map[1][i - s->group_channels[0]] = pos;
223 }
224
225 4 avctx->sample_fmt = FFMAX(bits[0], bits[1]) == 16 ? AV_SAMPLE_FMT_S16
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 : AV_SAMPLE_FMT_S32;
227 2 avctx->bits_per_raw_sample = FFMAX(bits[0], bits[1]);
228 2 avctx->sample_rate = rate[0];
229 2 av_channel_layout_uninit(&avctx->ch_layout);
230 2 av_channel_layout_from_mask(&avctx->ch_layout, mask);
231 2 avctx->bit_rate = (int64_t)s->block_size * rate[0] * 8 / 2;
232
233 2 if (avctx->debug & FF_DEBUG_PICT_INFO)
234 ff_dlog(avctx,
235 "pcm_dvda_parse_header: %d channels, %d+%d bits per sample, "
236 "%d Hz, %"PRId64" bit/s\n",
237 s->channels, bits[0], bits[1], avctx->sample_rate,
238 avctx->bit_rate);
239
240 2 s->last_header = header_int;
241
242 2 return 0;
243 }
244
245 /*
246 * The audio data is arranged in sets of 2 samples per channel ("two-pair
247 * samples", US 6,580,671 FIG. 1B): each channel group contributes the
248 * 16-bit main words of all its channels for both samples, then, for 24-bit
249 * quantization, one low-order extra byte per channel and sample in the
250 * same order (FIG. 4B).
251 */
252 25 static void pcm_dvda_decode_samples(AVCodecContext *avctx, GetByteContext *gb,
253 void *dst, int blocks)
254 {
255 25 PCMDVDAContext *s = avctx->priv_data;
256 25 int16_t *dst16 = dst;
257 25 int32_t *dst32 = dst;
258
259
2/2
✓ Branch 0 taken 4171 times.
✓ Branch 1 taken 25 times.
4196 while (blocks--) {
260 /* the patent leaves the order of the groups within a set open
261 * (col. 16); discs store the second channel group first */
262
2/2
✓ Branch 0 taken 8342 times.
✓ Branch 1 taken 4171 times.
12513 for (int g = 1; g >= 0; g--) {
263 8342 const int ch = s->group_channels[g];
264 8342 const int bits = s->group_bits[g];
265 8342 const uint8_t *map = s->group_map[g];
266
267
2/2
✓ Branch 0 taken 4171 times.
✓ Branch 1 taken 4171 times.
8342 if (!ch)
268 4171 continue;
269
270
2/2
✓ Branch 0 taken 8342 times.
✓ Branch 1 taken 4171 times.
12513 for (int n = 0; n < 2; n++) {
271
2/2
✓ Branch 0 taken 16684 times.
✓ Branch 1 taken 8342 times.
25026 for (int j = 0; j < ch; j++) {
272 16684 unsigned v = bytestream2_get_be16u(gb);
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16684 times.
16684 if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
274 dst16[n * s->channels + map[j]] = v;
275 else
276 16684 dst32[n * s->channels + map[j]] = v << 16;
277 }
278 }
279
1/2
✓ Branch 0 taken 4171 times.
✗ Branch 1 not taken.
4171 if (bits == 24) {
280
2/2
✓ Branch 0 taken 8342 times.
✓ Branch 1 taken 4171 times.
12513 for (int n = 0; n < 2; n++)
281
2/2
✓ Branch 0 taken 16684 times.
✓ Branch 1 taken 8342 times.
25026 for (int j = 0; j < ch; j++)
282 16684 dst32[n * s->channels + map[j]] |=
283 16684 bytestream2_get_byteu(gb) << 8;
284 }
285 }
286 4171 dst16 += 2 * s->channels;
287 4171 dst32 += 2 * s->channels;
288 }
289 25 }
290
291 25 static int pcm_dvda_decode_frame(AVCodecContext *avctx, AVFrame *frame,
292 int *got_frame_ptr, AVPacket *avpkt)
293 {
294 25 const PCMDVDAHeader *header = (const PCMDVDAHeader *)avpkt->data;
295 25 PCMDVDAContext *s = avctx->priv_data;
296 25 int buf_size = avpkt->size;
297 GetByteContext gb;
298 int header_size;
299 int retval;
300 int blocks;
301
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (buf_size < sizeof(*header)) {
303 av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
304 return AVERROR_INVALIDDATA;
305 }
306
307 /* the private header length counts the bytes following its own field,
308 * including the stuffing bytes that precede the audio data */
309 25 header_size = offsetof(PCMDVDAHeader, first_access_unit_pointer) +
310 25 header->private_header_length;
311
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if (header_size < sizeof(*header) || header_size > buf_size) {
312 av_log(avctx, AV_LOG_ERROR, "invalid PCM header size %d\n",
313 header_size);
314 return AVERROR_INVALIDDATA;
315 }
316
317
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 if ((retval = pcm_dvda_parse_header(avctx, header)))
318 return retval;
319
320 25 buf_size -= header_size;
321 25 blocks = buf_size / s->block_size;
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (buf_size % s->block_size)
323 av_log(avctx, AV_LOG_DEBUG, "ignoring %d leftover bytes\n",
324 buf_size % s->block_size);
325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!blocks) {
326 *got_frame_ptr = 0;
327 return avpkt->size;
328 }
329
330 /* get output buffer */
331 25 frame->nb_samples = blocks * 2;
332
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 if ((retval = ff_get_buffer(avctx, frame, 0)) < 0)
333 return retval;
334
335 25 bytestream2_init(&gb, avpkt->data + header_size, blocks * s->block_size);
336 25 pcm_dvda_decode_samples(avctx, &gb, frame->data[0], blocks);
337
338 25 *got_frame_ptr = 1;
339
340 25 return avpkt->size;
341 }
342
343 const FFCodec ff_pcm_dvda_decoder = {
344 .p.name = "pcm_dvda",
345 CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for DVD-Audio media"),
346 .p.type = AVMEDIA_TYPE_AUDIO,
347 .p.id = AV_CODEC_ID_PCM_DVDA,
348 .priv_data_size = sizeof(PCMDVDAContext),
349 .init = pcm_dvda_decode_init,
350 FF_CODEC_DECODE_CB(pcm_dvda_decode_frame),
351 .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
352 AV_CODEC_CAP_DR1,
353 };
354