Coverage Report

Created: 2026-09-28 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/packetizer/dts_header.c
Line
Count
Source
1
/*****************************************************************************
2
 * dts_header.c: parse DTS audio headers info
3
 *****************************************************************************
4
 * Copyright (C) 2004-2009 VLC authors and VideoLAN
5
 *
6
 * Authors: Gildas Bazin <gbazin@netcourrier.com>
7
 *          Laurent Aimar
8
 *
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation; either version 2.1 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program; if not, write to the Free Software Foundation,
21
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
 *****************************************************************************/
23
24
#ifdef HAVE_CONFIG_H
25
# include "config.h"
26
#endif
27
28
#include <vlc_common.h>
29
#include <vlc_bits.h>
30
#include <vlc_aout.h>
31
32
#include "dts_header.h"
33
34
#include <assert.h>
35
36
static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
37
83.1k
{
38
83.1k
    int i;
39
40
665k
    for( i = 0; i < i_in/2; i++  )
41
582k
    {
42
582k
        p_out[i*2] = p_in[i*2+1];
43
582k
        p_out[i*2+1] = p_in[i*2];
44
582k
    }
45
83.1k
}
46
47
static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le,
48
                      int i_out_le )
49
52.9k
{
50
52.9k
    unsigned char tmp, cur = 0;
51
52.9k
    int bits_in, bits_out = 0;
52
52.9k
    int i, i_out = 0;
53
54
794k
    for( i = 0; i < i_in; i++  )
55
741k
    {
56
741k
        if( i%2 )
57
370k
        {
58
370k
            tmp = p_in[i-i_le];
59
370k
            bits_in = 8;
60
370k
        }
61
370k
        else
62
370k
        {
63
370k
            tmp = p_in[i+i_le] & 0x3F;
64
370k
            bits_in = 8 - 2;
65
370k
        }
66
67
741k
        if( bits_out < 8 )
68
741k
        {
69
741k
            int need = __MIN( 8 - bits_out, bits_in );
70
741k
            cur <<= need;
71
741k
            cur |= ( tmp >> (bits_in - need) );
72
741k
            tmp <<= (8 - bits_in + need);
73
741k
            tmp >>= (8 - bits_in + need);
74
741k
            bits_in -= need;
75
741k
            bits_out += need;
76
741k
        }
77
78
741k
        if( bits_out == 8 )
79
635k
        {
80
635k
            if( i_out % 2 )
81
317k
                p_out[i_out - i_out_le] = cur;
82
317k
            else
83
317k
                p_out[i_out + i_out_le] = cur;
84
635k
            cur = 0;
85
635k
            bits_out = 0;
86
635k
            i_out++;
87
635k
        }
88
89
741k
        bits_out += bits_in;
90
741k
        cur <<= bits_in;
91
741k
        cur |= tmp;
92
741k
    }
93
94
52.9k
    return i_out;
95
52.9k
}
96
97
static enum vlc_dts_syncword_e dts_header_getSyncword( const uint8_t *p_buf )
98
72.7M
{
99
72.7M
    if( memcmp( p_buf, "\x7F\xFE\x80\x01", 4 ) == 0 )
100
905k
        return DTS_SYNC_CORE_BE;
101
71.8M
    else
102
71.8M
    if( memcmp( p_buf, "\xFE\x7F\x01\x80", 4 ) == 0 )
103
159k
        return DTS_SYNC_CORE_LE;
104
71.7M
    else
105
71.7M
    if( memcmp( p_buf, "\x64\x58\x20\x25", 4 ) == 0 )
106
947k
        return DTS_SYNC_SUBSTREAM;
107
70.7M
    else
108
70.7M
    if( memcmp( p_buf, "\x1F\xFF\xE8\x00", 4 ) == 0
109
9.86k
     && p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
110
5.17k
        return DTS_SYNC_CORE_14BITS_BE;
111
70.7M
    else
112
70.7M
    if( memcmp( p_buf, "\xFF\x1F\x00\xE8", 4 ) == 0
113
116k
     && (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
114
102k
        return DTS_SYNC_CORE_14BITS_LE;
115
70.6M
    else
116
70.6M
    if( memcmp( p_buf, "\x0A\x80\x19\x21", 4 ) == 0 )
117
1.22M
        return DTS_SYNC_SUBSTREAM_LBR;
118
69.4M
    else
119
69.4M
        return DTS_SYNC_NONE;
120
72.7M
}
121
122
bool vlc_dts_header_IsSync( const void *p_buf, size_t i_buf )
123
64.7M
{
124
64.7M
    return i_buf >= 6
125
64.7M
        && dts_header_getSyncword( p_buf ) != DTS_SYNC_NONE;
126
64.7M
}
127
128
static unsigned int dca_get_samplerate( uint8_t i_sfreq )
129
568k
{
130
    /* See ETSI TS 102 114, table 5-5 */
131
568k
    const unsigned int p_dca_samplerates[16] = {
132
568k
        0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
133
568k
        12000, 24000, 48000, 96000, 192000
134
568k
    };
135
136
568k
    if( i_sfreq >= 16 )
137
0
        return 0;
138
568k
    return p_dca_samplerates[i_sfreq];
139
568k
}
140
141
static unsigned int dca_get_bitrate( uint8_t i_rate )
142
568k
{
143
    /* See ETSI TS 102 114, table 5-7 */
144
568k
    const unsigned int p_dca_bitrates[32] = {
145
568k
        32000,   56000,   64000,   96000,  112000,
146
568k
        128000, 192000,  224000,  256000,  320000,
147
568k
        384000, 448000,  512000,  576000,  640000,
148
568k
        768000, 896000, 1024000, 1152000, 1280000,
149
568k
        1344000, 1408000, 1411200, 1472000, 1536000,
150
568k
        1920000, 2048000, 3072000, 3840000,
151
        /* FIXME: The following can't be put in a VLC audio_format_t:
152
         * 1: open, 2: variable, 3: lossless */
153
568k
        0, 0, 0
154
568k
    };
155
156
568k
    if( i_rate >= 32 )
157
0
        return 0;
158
568k
    return p_dca_bitrates[i_rate];
159
568k
}
160
161
static uint16_t dca_get_channels( uint8_t i_amode, bool b_lfe,
162
                                  uint16_t *p_chan_mode )
163
568k
{
164
    /* See ETSI TS 102 114, table 5-4
165
     * 00: A
166
     * 01: A + B (dual mono)
167
     * 02: L + R (stereo)
168
     * 03: (L+R) + (L-R) (sum and difference)
169
     * 04: LT + RT (left and right total)
170
     * 05: C + L + R
171
     * 06: L + R + S
172
     * 07: C + L + R + S
173
     * 08: L + R + SL + SR
174
     * 09: C + L + R + SL + SR
175
     * 0A: CL + CR + L + R + SL + SR
176
     * 0B: C + L + R + LR + RR + OV
177
     * 0C: CF + CR + LF + RF + LR + RR
178
     * 0D: CL + C + CR + L + R + SL + SR
179
     * 0E: CL + CR + L + R + SL1 + SL2 + SR1 + SR2
180
     * 0F: CL + C + CR + L + R + SL + S + SR
181
     * 10-3F: user defined */
182
183
568k
    uint16_t i_physical_channels;
184
185
568k
    switch( i_amode )
186
568k
    {
187
16.2k
        case 0x0:
188
16.2k
            i_physical_channels = AOUT_CHAN_CENTER;
189
16.2k
            break;
190
2.02k
        case 0x1:
191
2.02k
            i_physical_channels = AOUT_CHANS_FRONT;
192
2.02k
            *p_chan_mode = AOUT_CHANMODE_DUALMONO;
193
2.02k
            break;
194
2.43k
        case 0x2:
195
34.0k
        case 0x3:
196
39.8k
        case 0x4:
197
39.8k
            i_physical_channels = AOUT_CHANS_FRONT;
198
39.8k
            break;
199
10.2k
        case 0x5:
200
10.2k
            i_physical_channels = AOUT_CHANS_3_0;
201
10.2k
            break;
202
2.08k
        case 0x6:
203
2.08k
            i_physical_channels = AOUT_CHANS_FRONT | AOUT_CHAN_REARCENTER;
204
2.08k
            break;
205
5.08k
        case 0x7:
206
5.08k
            i_physical_channels = AOUT_CHANS_4_CENTER_REAR;
207
5.08k
            break;
208
5.49k
        case 0x8:
209
5.49k
            i_physical_channels = AOUT_CHANS_4_0;
210
5.49k
            break;
211
15.6k
        case 0x9:
212
15.6k
            i_physical_channels = AOUT_CHANS_5_0;
213
15.6k
            break;
214
16.7k
        case 0xA:
215
17.9k
        case 0xB:
216
17.9k
            i_physical_channels = AOUT_CHANS_6_0;
217
17.9k
            break;
218
18.6k
        case 0xC:
219
18.6k
            i_physical_channels = AOUT_CHANS_CENTER | AOUT_CHANS_FRONT
220
18.6k
                                | AOUT_CHANS_REAR;
221
18.6k
            break;
222
10.8k
        case 0xD:
223
10.8k
            i_physical_channels = AOUT_CHANS_7_0;
224
10.8k
            break;
225
14.8k
        case 0xE:
226
16.5k
        case 0xF:
227
            /* FIXME: AOUT_CHANS_8_0 */
228
16.5k
            i_physical_channels = AOUT_CHANS_7_0;
229
16.5k
            break;
230
407k
        default:
231
407k
            return 0;
232
568k
    }
233
160k
    if (b_lfe)
234
41.0k
        i_physical_channels |= AOUT_CHAN_LFE;
235
236
160k
    return i_physical_channels;
237
568k
}
238
239
static uint8_t dca_get_LBR_channels( uint16_t nuSpkrActivityMask,
240
                                     uint16_t *pi_chans )
241
509k
{
242
509k
    uint16_t i_physical_channels = 0;
243
509k
    uint8_t i_channels = 0;
244
245
509k
    static const struct
246
509k
    {
247
509k
        int phy;
248
509k
        uint8_t nb;
249
509k
    } bitmask[16] = {
250
         /* table 7-10 */
251
509k
        { AOUT_CHAN_CENTER,     1 },
252
509k
        { AOUT_CHANS_FRONT,     2 },
253
509k
        { AOUT_CHANS_MIDDLE,    2 },
254
509k
        { AOUT_CHAN_LFE,        1 },
255
509k
        { AOUT_CHAN_REARCENTER, 1 },
256
509k
        { 0,                    2 },
257
509k
        { AOUT_CHANS_REAR,      2 },
258
509k
        { 0,                    1 },
259
509k
        { 0,                    1 },
260
509k
        { 0,                    2 },
261
509k
        { AOUT_CHANS_FRONT,     2 },
262
509k
        { AOUT_CHANS_MIDDLE,    2 },
263
509k
        { 0,                    1 },
264
509k
        { 0,                    2 },
265
509k
        { 0,                    1 },
266
509k
        { 0,                    2 },
267
509k
    };
268
269
6.38M
    for( int i=0 ; nuSpkrActivityMask; nuSpkrActivityMask >>= 1 )
270
5.88M
    {
271
5.88M
        if( nuSpkrActivityMask & 1 )
272
1.82M
        {
273
1.82M
            i_physical_channels |= bitmask[i].phy;
274
1.82M
            i_channels += bitmask[i].nb;
275
1.82M
        }
276
5.88M
        ++i;
277
5.88M
    }
278
509k
    *pi_chans = i_physical_channels;
279
509k
    return i_channels;
280
509k
}
281
282
static int dts_header_ParseSubstream( vlc_dts_header_t *p_header,
283
                                      const void *p_buffer )
284
472k
{
285
472k
    bs_t s;
286
472k
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
287
472k
    bs_skip( &s, 32 /*SYNCEXTSSH*/ + 8 /*UserDefinedBits*/ + 2 /*nExtSSIndex*/ );
288
472k
    uint8_t bHeaderSizeType = bs_read1( &s );
289
472k
    uint32_t nuBits4ExSSFsize;
290
472k
    uint16_t nuExtSSHeaderSize;
291
472k
    if( bHeaderSizeType == 0 )
292
441k
    {
293
441k
        nuExtSSHeaderSize = bs_read( &s, 8 /*nuBits4Header*/ );
294
441k
        nuBits4ExSSFsize = bs_read( &s, 16 );
295
441k
    }
296
30.9k
    else
297
30.9k
    {
298
30.9k
        nuExtSSHeaderSize = bs_read( &s, 12 /*nuBits4Header*/ );
299
30.9k
        nuBits4ExSSFsize = bs_read( &s, 20 );
300
30.9k
    }
301
472k
    memset( p_header, 0, sizeof(*p_header) );
302
472k
    p_header->syncword = DTS_SYNC_SUBSTREAM;
303
472k
    p_header->i_substream_header_size = nuExtSSHeaderSize + 1;
304
472k
    p_header->i_frame_size = nuBits4ExSSFsize + 1;
305
472k
    return VLC_SUCCESS;
306
472k
}
307
308
static int dts_header_ParseLBRExtSubstream( vlc_dts_header_t *p_header,
309
                                             const void *p_buffer )
310
685k
{
311
685k
    bs_t s;
312
685k
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
313
685k
    bs_skip( &s, 32 /*SYNCEXTSSH*/ );
314
685k
    uint8_t ucFmtInfoCode = bs_read( &s, 8 );
315
685k
    if( ucFmtInfoCode != 0x02 /*LBR_HDRCODE_DECODERINIT*/ )
316
158k
        return VLC_EGENERIC;
317
527k
    p_header->i_rate = bs_read( &s, 8 );
318
    /* See ETSI TS 102 114, table 9-3 */
319
527k
    const unsigned int LBRsamplerates[] = {
320
527k
        8000, 16000, 32000,
321
527k
        0, 0,
322
527k
        22050, 44100,
323
527k
        0, 0, 0,
324
527k
        12000, 24000, 48000,
325
527k
    };
326
527k
    if(p_header->i_rate >= ARRAY_SIZE(LBRsamplerates))
327
17.7k
        return VLC_EGENERIC;
328
509k
    p_header->i_rate = LBRsamplerates[p_header->i_rate];
329
509k
    if( p_header->i_rate < 16000 )
330
343k
        p_header->i_frame_length = 1024;
331
165k
    else if( p_header->i_rate < 32000 )
332
5.67k
        p_header->i_frame_length = 2048;
333
159k
    else
334
159k
        p_header->i_frame_length = 4096;
335
336
509k
    uint16_t i_spkrmask = bs_read( &s, 16 );
337
509k
    dca_get_LBR_channels( i_spkrmask, &p_header->i_physical_channels );
338
509k
    bs_skip( &s, 16 );
339
509k
    bs_skip( &s, 8 );
340
509k
    uint16_t nLBRBitRateMSnybbles = bs_read( &s, 8 );
341
509k
    bs_skip( &s, 16 );
342
509k
    uint16_t nLBRScaledBitRate_LSW = bs_read( &s, 16 );
343
509k
    p_header->i_bitrate = nLBRScaledBitRate_LSW | ((nLBRBitRateMSnybbles & 0xF0) << 12);
344
509k
    p_header->i_frame_size = 0;
345
509k
    return VLC_SUCCESS;
346
527k
}
347
348
static int dts_header_ParseCore( vlc_dts_header_t *p_header,
349
                                 const void *p_buffer)
350
589k
{
351
589k
    bs_t s;
352
589k
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
353
589k
    bs_skip( &s, 32 /*SYNC*/ + 1 /*FTYPE*/ + 5 /*SHORT*/ + 1 /*CPF*/ );
354
589k
    uint8_t i_nblks = bs_read( &s, 7 );
355
589k
    if( i_nblks < 5 )
356
17.0k
        return VLC_EGENERIC;
357
572k
    uint16_t i_fsize = bs_read( &s, 14 );
358
572k
    if( i_fsize < 95 )
359
4.11k
        return VLC_EGENERIC;
360
568k
    uint8_t i_amode = bs_read( &s, 6 );
361
568k
    uint8_t i_sfreq = bs_read( &s, 4 );
362
568k
    uint8_t i_rate = bs_read( &s, 5 );
363
568k
    bs_skip( &s, 1 /*FixedBit*/ + 1 /*DYNF*/ + 1 /*TIMEF*/ + 1 /*AUXF*/ +
364
568k
             1 /*HDCD*/ + 3 /*EXT_AUDIO_ID*/ + 1 /*EXT_AUDIO */ + 1 /*ASPF*/ );
365
568k
    uint8_t i_lff = bs_read( &s, 2 );
366
367
568k
    bool b_lfe = i_lff == 1 || i_lff == 2;
368
369
568k
    p_header->i_rate = dca_get_samplerate( i_sfreq );
370
568k
    p_header->i_bitrate = dca_get_bitrate( i_rate );
371
568k
    p_header->i_frame_size = i_fsize + 1;
372
568k
    if( p_header->syncword == DTS_SYNC_CORE_14BITS_LE ||
373
520k
        p_header->syncword == DTS_SYNC_CORE_14BITS_BE )
374
50.4k
        p_header->i_frame_size = p_header->i_frame_size * 16 / 14;
375
    /* See ETSI TS 102 114, table 5-2 */
376
568k
    p_header->i_frame_length = (i_nblks + 1) * 32;
377
568k
    p_header->i_chan_mode = 0;
378
568k
    p_header->i_physical_channels =
379
568k
        dca_get_channels( i_amode, b_lfe, &p_header->i_chan_mode );
380
381
568k
    if( !p_header->i_rate || !p_header->i_frame_size ||
382
501k
        !p_header->i_frame_length || !p_header->i_physical_channels )
383
448k
        return VLC_EGENERIC;
384
385
119k
    return VLC_SUCCESS;
386
568k
}
387
388
ssize_t vlc_dts_header_Convert14b16b( void *p_dst, size_t i_dst,
389
                                      const void *p_src, size_t i_src,
390
                                      bool b_out_le )
391
0
{
392
0
    size_t i_size = i_src * 14 / 16;
393
0
    if( i_src <= VLC_DTS_HEADER_SIZE || i_size > i_dst )
394
0
        return -1;
395
396
0
    enum vlc_dts_syncword_e syncword = dts_header_getSyncword( p_src );
397
0
    if( syncword == DTS_SYNC_NONE )
398
0
        return -1;
399
400
0
    if( syncword != DTS_SYNC_CORE_14BITS_BE
401
0
     && syncword != DTS_SYNC_CORE_14BITS_LE )
402
0
        return -1;
403
404
0
    int i_ret = Buf14To16( p_dst, p_src, i_src,
405
0
                           syncword == DTS_SYNC_CORE_14BITS_LE, b_out_le );
406
0
    return i_ret;
407
0
}
408
409
int vlc_dts_header_Parse( vlc_dts_header_t *p_header,
410
                          const void *p_buffer, size_t i_buffer)
411
8.01M
{
412
8.01M
    if( i_buffer < VLC_DTS_HEADER_SIZE )
413
0
        return VLC_EGENERIC;
414
415
8.01M
    p_header->syncword = dts_header_getSyncword( p_buffer );
416
8.01M
    if( p_header->syncword == DTS_SYNC_NONE )
417
6.26M
        return VLC_EGENERIC;
418
419
1.74M
    switch( p_header->syncword )
420
1.74M
    {
421
83.1k
        case DTS_SYNC_CORE_LE:
422
83.1k
        {
423
83.1k
            uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
424
83.1k
            BufLeToBe( conv_buf, p_buffer, VLC_DTS_HEADER_SIZE );
425
83.1k
            return dts_header_ParseCore( p_header, conv_buf );
426
0
        }
427
453k
        case DTS_SYNC_CORE_BE:
428
453k
            return dts_header_ParseCore( p_header, p_buffer );
429
2.89k
        case DTS_SYNC_CORE_14BITS_BE:
430
52.9k
        case DTS_SYNC_CORE_14BITS_LE:
431
52.9k
        {
432
52.9k
            uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
433
52.9k
            Buf14To16( conv_buf, p_buffer, VLC_DTS_HEADER_SIZE,
434
52.9k
                       p_header->syncword == DTS_SYNC_CORE_14BITS_LE, 0 );
435
52.9k
            return dts_header_ParseCore( p_header, conv_buf );
436
2.89k
        }
437
472k
        case DTS_SYNC_SUBSTREAM:
438
472k
            return dts_header_ParseSubstream( p_header, p_buffer );
439
685k
        case DTS_SYNC_SUBSTREAM_LBR:
440
685k
            return dts_header_ParseLBRExtSubstream( p_header, p_buffer );
441
0
        default:
442
0
            vlc_assert_unreachable();
443
1.74M
    }
444
1.74M
}