FFmpeg
pcm-dvda.c
Go to the documentation of this file.
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 
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 */
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 */
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 */
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 */
66  /* reserved (4 bits), multichannel type (4 bits): 0 = type 1, the only
67  * defined sample structure; other values reserved */
69  /* reserved (3 bits), channel assignment (5 bits): selects one of the
70  * 21 channel-to-group allocations, see channel_assignments[] */
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 */
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
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 {
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 
135 {
136  PCMDVDAContext *s = avctx->priv_data;
137 
138  /* Invalid header to force parsing of the first header */
139  s->last_header = -1;
140 
141  return 0;
142 }
143 
145  const PCMDVDAHeader *header)
146 {
147  PCMDVDAContext *s = avctx->priv_data;
148  uint32_t header_int = header->quantization |
149  header->sampling_frequency << 8 |
150  header->channel_assignment << 16;
151  int assignment = header->channel_assignment & 0x1f;
152  int bits[2], rate[2];
153  uint64_t mask = 0;
154 
155  /* early exit if the header didn't change */
156  if (s->last_header == header_int)
157  return 0;
158  s->last_header = -1;
159 
160  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  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  s->group_channels[0] = channel_assignments[assignment].group1_channels;
172  s->group_channels[1] = channel_assignments[assignment].group2_channels;
173 
174  for (int i = 0; i < 2; i++) {
175  int quant = i ? header->quantization & 0xf : header->quantization >> 4;
176  int freq = i ? header->sampling_frequency & 0xf : header->sampling_frequency >> 4;
177 
178  /* 0xf marks an absent channel group */
179  if (i && (quant == 0xf || freq == 0xf))
180  s->group_channels[1] = 0;
181  if (!s->group_channels[i]) {
182  bits[i] = rate[i] = 0;
183  continue;
184  }
185 
186  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  bits[i] = 16 + 4 * quant;
193  rate[i] = (freq & 8 ? 44100 : 48000) << (freq & 7);
194 
195  if (bits[i] == 20) {
196  avpriv_request_sample(avctx, "20-bit group %d quantization", i + 1);
197  return AVERROR_PATCHWELCOME;
198  }
199  }
200 
201  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  s->group_bits[0] = bits[0];
208  s->group_bits[1] = bits[1];
209  s->channels = s->group_channels[0] + s->group_channels[1];
210  s->block_size = 2 * (s->group_channels[0] * bits[0] +
211  s->group_channels[1] * bits[1]) / 8;
212 
213  /* map the stream channel order to the native layout order */
214  for (int i = 0; i < s->channels; i++)
215  mask |= channel_assignments[assignment].channels[i];
216  for (int i = 0; i < s->channels; i++) {
217  uint64_t ch = channel_assignments[assignment].channels[i];
218  int pos = av_popcount64(mask & (ch - 1));
219  if (i < s->group_channels[0])
220  s->group_map[0][i] = pos;
221  else
222  s->group_map[1][i - s->group_channels[0]] = pos;
223  }
224 
225  avctx->sample_fmt = FFMAX(bits[0], bits[1]) == 16 ? AV_SAMPLE_FMT_S16
227  avctx->bits_per_raw_sample = FFMAX(bits[0], bits[1]);
228  avctx->sample_rate = rate[0];
231  avctx->bit_rate = (int64_t)s->block_size * rate[0] * 8 / 2;
232 
233  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  s->last_header = header_int;
241 
242  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  */
253  void *dst, int blocks)
254 {
255  PCMDVDAContext *s = avctx->priv_data;
256  int16_t *dst16 = dst;
257  int32_t *dst32 = dst;
258 
259  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  for (int g = 1; g >= 0; g--) {
263  const int ch = s->group_channels[g];
264  const int bits = s->group_bits[g];
265  const uint8_t *map = s->group_map[g];
266 
267  if (!ch)
268  continue;
269 
270  for (int n = 0; n < 2; n++) {
271  for (int j = 0; j < ch; j++) {
272  unsigned v = bytestream2_get_be16u(gb);
273  if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
274  dst16[n * s->channels + map[j]] = v;
275  else
276  dst32[n * s->channels + map[j]] = v << 16;
277  }
278  }
279  if (bits == 24) {
280  for (int n = 0; n < 2; n++)
281  for (int j = 0; j < ch; j++)
282  dst32[n * s->channels + map[j]] |=
283  bytestream2_get_byteu(gb) << 8;
284  }
285  }
286  dst16 += 2 * s->channels;
287  dst32 += 2 * s->channels;
288  }
289 }
290 
292  int *got_frame_ptr, AVPacket *avpkt)
293 {
294  const PCMDVDAHeader *header = (const PCMDVDAHeader *)avpkt->data;
295  PCMDVDAContext *s = avctx->priv_data;
296  int buf_size = avpkt->size;
297  GetByteContext gb;
298  int header_size;
299  int retval;
300  int blocks;
301 
302  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  header_size = offsetof(PCMDVDAHeader, first_access_unit_pointer) +
310  header->private_header_length;
311  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  if ((retval = pcm_dvda_parse_header(avctx, header)))
318  return retval;
319 
320  buf_size -= header_size;
321  blocks = buf_size / s->block_size;
322  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  if (!blocks) {
326  *got_frame_ptr = 0;
327  return avpkt->size;
328  }
329 
330  /* get output buffer */
331  frame->nb_samples = blocks * 2;
332  if ((retval = ff_get_buffer(avctx, frame, 0)) < 0)
333  return retval;
334 
335  bytestream2_init(&gb, avpkt->data + header_size, blocks * s->block_size);
336  pcm_dvda_decode_samples(avctx, &gb, frame->data[0], blocks);
337 
338  *got_frame_ptr = 1;
339 
340  return avpkt->size;
341 }
342 
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),
351  .p.capabilities = AV_CODEC_CAP_CHANNEL_CONF |
353 };
pcm_dvda_parse_header
static int pcm_dvda_parse_header(AVCodecContext *avctx, const PCMDVDAHeader *header)
Definition: pcm-dvda.c:144
pcm_dvda_decode_samples
static void pcm_dvda_decode_samples(AVCodecContext *avctx, GetByteContext *gb, void *dst, int blocks)
Definition: pcm-dvda.c:252
CH_C
#define CH_C
Definition: pcm-dvda.c:89
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1040
GetByteContext
Definition: bytestream.h:33
av_popcount64
#define av_popcount64
Definition: common.h:157
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
mask
int mask
Definition: mediacodecdec_common.c:154
PCMDVDAContext::group_map
uint8_t group_map[2][6]
Definition: pcm-dvda.c:86
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
AVPacket::data
uint8_t * data
Definition: packet.h:603
FFCodec
Definition: codec_internal.h:127
pcm_dvda_decode_init
static av_cold int pcm_dvda_decode_init(AVCodecContext *avctx)
Definition: pcm-dvda.c:134
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
PCMDVDAHeader::dynamic_range_control
uint8_t dynamic_range_control
Definition: pcm-dvda.c:75
FF_DEBUG_PICT_INFO
#define FF_DEBUG_PICT_INFO
Definition: avcodec.h:1393
PCMDVDAContext::block_size
int block_size
Definition: pcm-dvda.c:82
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1055
quant
static const uint8_t quant[64]
Definition: vmixdec.c:71
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:364
CH_L
#define CH_L
Definition: pcm-dvda.c:90
ff_pcm_dvda_decoder
const FFCodec ff_pcm_dvda_decoder
Definition: pcm-dvda.c:343
g
const char * g
Definition: vf_curves.c:128
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
bits
uint8_t bits
Definition: vp3data.h:128
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1571
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
channels
channels
Definition: aptx.h:31
decode.h
channel_assignments
static const struct @250 channel_assignments[21]
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:349
if
if(ret)
Definition: filter_design.txt:179
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
PCMDVDAHeader::channel_assignment
uint8_t channel_assignment
Definition: pcm-dvda.c:71
AV_CODEC_CAP_CHANNEL_CONF
#define AV_CODEC_CAP_CHANNEL_CONF
Codec should fill in channel configuration and samplerate instead of container.
Definition: codec.h:88
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1777
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:49
AVPacket::size
int size
Definition: packet.h:604
codec_internal.h
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
PCMDVDAHeader
Definition: pcm-dvda.c:38
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
CH_S
#define CH_S
Definition: pcm-dvda.c:93
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1047
PCMDVDAHeader::isrc_number
uint8_t isrc_number
Definition: pcm-dvda.c:42
CH_R
#define CH_R
Definition: pcm-dvda.c:91
PCMDVDAHeader::quantization
uint8_t quantization
Definition: pcm-dvda.c:60
PCMDVDAContext::last_header
uint32_t last_header
Definition: pcm-dvda.c:81
header
static const uint8_t header[24]
Definition: sdr2.c:68
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:622
group1_channels
uint8_t group1_channels
Definition: pcm-dvda.c:107
s
uint8_t s
Definition: llvidencdsp.c:39
PCMDVDAHeader::emphasis_downmix
uint8_t emphasis_downmix
Definition: pcm-dvda.c:56
pcm_dvda_decode_frame
static int pcm_dvda_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)
Definition: pcm-dvda.c:291
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
PCMDVDAContext::group_bits
int group_bits[2]
Definition: pcm-dvda.c:85
avcodec.h
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
PCMDVDAHeader::private_header_length
uint8_t private_header_length
Definition: pcm-dvda.c:47
pos
unsigned int pos
Definition: spdifenc.c:431
AVCodecContext
main external API structure.
Definition: avcodec.h:443
PCMDVDAHeader::multichannel_type
uint8_t multichannel_type
Definition: pcm-dvda.c:68
channel_layout.h
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
AVCodecContext::debug
int debug
debug
Definition: avcodec.h:1392
PCMDVDAHeader::first_access_unit_pointer
uint8_t first_access_unit_pointer[2]
Definition: pcm-dvda.c:50
CH_LFE
#define CH_LFE
Definition: pcm-dvda.c:92
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
group2_channels
uint8_t group2_channels
Definition: pcm-dvda.c:108
CH_RS
#define CH_RS
Definition: pcm-dvda.c:95
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
PCMDVDAContext
Definition: pcm-dvda.c:80
CH_LS
#define CH_LS
Definition: pcm-dvda.c:94
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
PCMDVDAContext::channels
int channels
Definition: pcm-dvda.c:83
int32_t
int32_t
Definition: audioconvert.c:56
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:59
AV_CODEC_ID_PCM_DVDA
@ AV_CODEC_ID_PCM_DVDA
Definition: codec_id.h:367
PCMDVDAHeader::isrc_data
uint8_t isrc_data
Definition: pcm-dvda.c:44
PCMDVDAHeader::sampling_frequency
uint8_t sampling_frequency
Definition: pcm-dvda.c:65
PCMDVDAContext::group_channels
int group_channels[2]
Definition: pcm-dvda.c:84