Coverage Report

Created: 2025-12-31 07:55

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
40.0k
{
38
40.0k
    int i;
39
40
320k
    for( i = 0; i < i_in/2; i++  )
41
280k
    {
42
280k
        p_out[i*2] = p_in[i*2+1];
43
280k
        p_out[i*2+1] = p_in[i*2];
44
280k
    }
45
40.0k
}
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
199k
{
50
199k
    unsigned char tmp, cur = 0;
51
199k
    int bits_in, bits_out = 0;
52
199k
    int i, i_out = 0;
53
54
2.99M
    for( i = 0; i < i_in; i++  )
55
2.79M
    {
56
2.79M
        if( i%2 )
57
1.39M
        {
58
1.39M
            tmp = p_in[i-i_le];
59
1.39M
            bits_in = 8;
60
1.39M
        }
61
1.39M
        else
62
1.39M
        {
63
1.39M
            tmp = p_in[i+i_le] & 0x3F;
64
1.39M
            bits_in = 8 - 2;
65
1.39M
        }
66
67
2.79M
        if( bits_out < 8 )
68
2.79M
        {
69
2.79M
            int need = __MIN( 8 - bits_out, bits_in );
70
2.79M
            cur <<= need;
71
2.79M
            cur |= ( tmp >> (bits_in - need) );
72
2.79M
            tmp <<= (8 - bits_in + need);
73
2.79M
            tmp >>= (8 - bits_in + need);
74
2.79M
            bits_in -= need;
75
2.79M
            bits_out += need;
76
2.79M
        }
77
78
2.79M
        if( bits_out == 8 )
79
2.39M
        {
80
2.39M
            if( i_out % 2 )
81
1.19M
                p_out[i_out - i_out_le] = cur;
82
1.19M
            else
83
1.19M
                p_out[i_out + i_out_le] = cur;
84
2.39M
            cur = 0;
85
2.39M
            bits_out = 0;
86
2.39M
            i_out++;
87
2.39M
        }
88
89
2.79M
        bits_out += bits_in;
90
2.79M
        cur <<= bits_in;
91
2.79M
        cur |= tmp;
92
2.79M
    }
93
94
199k
    return i_out;
95
199k
}
96
97
static enum vlc_dts_syncword_e dts_header_getSyncword( const uint8_t *p_buf )
98
95.1M
{
99
95.1M
    if( memcmp( p_buf, "\x7F\xFE\x80\x01", 4 ) == 0 )
100
1.61M
        return DTS_SYNC_CORE_BE;
101
93.5M
    else
102
93.5M
    if( memcmp( p_buf, "\xFE\x7F\x01\x80", 4 ) == 0 )
103
70.7k
        return DTS_SYNC_CORE_LE;
104
93.4M
    else
105
93.4M
    if( memcmp( p_buf, "\x64\x58\x20\x25", 4 ) == 0 )
106
3.93M
        return DTS_SYNC_SUBSTREAM;
107
89.5M
    else
108
89.5M
    if( memcmp( p_buf, "\x1F\xFF\xE8\x00", 4 ) == 0
109
15.1k
     && p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
110
9.04k
        return DTS_SYNC_CORE_14BITS_BE;
111
89.5M
    else
112
89.5M
    if( memcmp( p_buf, "\xFF\x1F\x00\xE8", 4 ) == 0
113
409k
     && (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
114
392k
        return DTS_SYNC_CORE_14BITS_LE;
115
89.1M
    else
116
89.1M
    if( memcmp( p_buf, "\x0A\x80\x19\x21", 4 ) == 0 )
117
3.03M
        return DTS_SYNC_SUBSTREAM_LBR;
118
86.1M
    else
119
86.1M
        return DTS_SYNC_NONE;
120
95.1M
}
121
122
bool vlc_dts_header_IsSync( const void *p_buf, size_t i_buf )
123
76.3M
{
124
76.3M
    return i_buf >= 6
125
76.3M
        && dts_header_getSyncword( p_buf ) != DTS_SYNC_NONE;
126
76.3M
}
127
128
static unsigned int dca_get_samplerate( uint8_t i_sfreq )
129
1.04M
{
130
    /* See ETSI TS 102 114, table 5-5 */
131
1.04M
    const unsigned int p_dca_samplerates[16] = {
132
1.04M
        0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
133
1.04M
        12000, 24000, 48000, 96000, 192000
134
1.04M
    };
135
136
1.04M
    if( i_sfreq >= 16 )
137
0
        return 0;
138
1.04M
    return p_dca_samplerates[i_sfreq];
139
1.04M
}
140
141
static unsigned int dca_get_bitrate( uint8_t i_rate )
142
1.04M
{
143
    /* See ETSI TS 102 114, table 5-7 */
144
1.04M
    const unsigned int p_dca_bitrates[32] = {
145
1.04M
        32000,   56000,   64000,   96000,  112000,
146
1.04M
        128000, 192000,  224000,  256000,  320000,
147
1.04M
        384000, 448000,  512000,  576000,  640000,
148
1.04M
        768000, 896000, 1024000, 1152000, 1280000,
149
1.04M
        1344000, 1408000, 1411200, 1472000, 1536000,
150
1.04M
        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
1.04M
        0, 0, 0
154
1.04M
    };
155
156
1.04M
    if( i_rate >= 32 )
157
0
        return 0;
158
1.04M
    return p_dca_bitrates[i_rate];
159
1.04M
}
160
161
static uint16_t dca_get_channels( uint8_t i_amode, bool b_lfe,
162
                                  uint16_t *p_chan_mode )
163
1.04M
{
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
1.04M
    uint16_t i_physical_channels;
184
185
1.04M
    switch( i_amode )
186
1.04M
    {
187
13.7k
        case 0x0:
188
13.7k
            i_physical_channels = AOUT_CHAN_CENTER;
189
13.7k
            break;
190
5.14k
        case 0x1:
191
5.14k
            i_physical_channels = AOUT_CHANS_FRONT;
192
5.14k
            *p_chan_mode = AOUT_CHANMODE_DUALMONO;
193
5.14k
            break;
194
4.78k
        case 0x2:
195
8.19k
        case 0x3:
196
10.6k
        case 0x4:
197
10.6k
            i_physical_channels = AOUT_CHANS_FRONT;
198
10.6k
            break;
199
26.8k
        case 0x5:
200
26.8k
            i_physical_channels = AOUT_CHANS_3_0;
201
26.8k
            break;
202
1.04k
        case 0x6:
203
1.04k
            i_physical_channels = AOUT_CHANS_FRONT | AOUT_CHAN_REARCENTER;
204
1.04k
            break;
205
1.14k
        case 0x7:
206
1.14k
            i_physical_channels = AOUT_CHANS_4_CENTER_REAR;
207
1.14k
            break;
208
3.36k
        case 0x8:
209
3.36k
            i_physical_channels = AOUT_CHANS_4_0;
210
3.36k
            break;
211
1.94k
        case 0x9:
212
1.94k
            i_physical_channels = AOUT_CHANS_5_0;
213
1.94k
            break;
214
1.37k
        case 0xA:
215
3.93k
        case 0xB:
216
3.93k
            i_physical_channels = AOUT_CHANS_6_0;
217
3.93k
            break;
218
21.3k
        case 0xC:
219
21.3k
            i_physical_channels = AOUT_CHANS_CENTER | AOUT_CHANS_FRONT
220
21.3k
                                | AOUT_CHANS_REAR;
221
21.3k
            break;
222
13.4k
        case 0xD:
223
13.4k
            i_physical_channels = AOUT_CHANS_7_0;
224
13.4k
            break;
225
131k
        case 0xE:
226
140k
        case 0xF:
227
            /* FIXME: AOUT_CHANS_8_0 */
228
140k
            i_physical_channels = AOUT_CHANS_7_0;
229
140k
            break;
230
799k
        default:
231
799k
            return 0;
232
1.04M
    }
233
243k
    if (b_lfe)
234
54.5k
        i_physical_channels |= AOUT_CHAN_LFE;
235
236
243k
    return i_physical_channels;
237
1.04M
}
238
239
static uint8_t dca_get_LBR_channels( uint16_t nuSpkrActivityMask,
240
                                     uint16_t *pi_chans )
241
1.16M
{
242
1.16M
    uint16_t i_physical_channels = 0;
243
1.16M
    uint8_t i_channels = 0;
244
245
1.16M
    static const struct
246
1.16M
    {
247
1.16M
        int phy;
248
1.16M
        uint8_t nb;
249
1.16M
    } bitmask[16] = {
250
         /* table 7-10 */
251
1.16M
        { AOUT_CHAN_CENTER,     1 },
252
1.16M
        { AOUT_CHANS_FRONT,     2 },
253
1.16M
        { AOUT_CHANS_MIDDLE,    2 },
254
1.16M
        { AOUT_CHAN_LFE,        1 },
255
1.16M
        { AOUT_CHAN_REARCENTER, 1 },
256
1.16M
        { 0,                    2 },
257
1.16M
        { AOUT_CHANS_REAR,      2 },
258
1.16M
        { 0,                    1 },
259
1.16M
        { 0,                    1 },
260
1.16M
        { 0,                    2 },
261
1.16M
        { AOUT_CHANS_FRONT,     2 },
262
1.16M
        { AOUT_CHANS_MIDDLE,    2 },
263
1.16M
        { 0,                    1 },
264
1.16M
        { 0,                    2 },
265
1.16M
        { 0,                    1 },
266
1.16M
        { 0,                    2 },
267
1.16M
    };
268
269
15.5M
    for( int i=0 ; nuSpkrActivityMask; nuSpkrActivityMask >>= 1 )
270
14.3M
    {
271
14.3M
        if( nuSpkrActivityMask & 1 )
272
3.88M
        {
273
3.88M
            i_physical_channels |= bitmask[i].phy;
274
3.88M
            i_channels += bitmask[i].nb;
275
3.88M
        }
276
14.3M
        ++i;
277
14.3M
    }
278
1.16M
    *pi_chans = i_physical_channels;
279
1.16M
    return i_channels;
280
1.16M
}
281
282
static int dts_header_ParseSubstream( vlc_dts_header_t *p_header,
283
                                      const void *p_buffer )
284
1.92M
{
285
1.92M
    bs_t s;
286
1.92M
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
287
1.92M
    bs_skip( &s, 32 /*SYNCEXTSSH*/ + 8 /*UserDefinedBits*/ + 2 /*nExtSSIndex*/ );
288
1.92M
    uint8_t bHeaderSizeType = bs_read1( &s );
289
1.92M
    uint32_t nuBits4ExSSFsize;
290
1.92M
    uint16_t nuExtSSHeaderSize;
291
1.92M
    if( bHeaderSizeType == 0 )
292
1.76M
    {
293
1.76M
        nuExtSSHeaderSize = bs_read( &s, 8 /*nuBits4Header*/ );
294
1.76M
        nuBits4ExSSFsize = bs_read( &s, 16 );
295
1.76M
    }
296
158k
    else
297
158k
    {
298
158k
        nuExtSSHeaderSize = bs_read( &s, 12 /*nuBits4Header*/ );
299
158k
        nuBits4ExSSFsize = bs_read( &s, 20 );
300
158k
    }
301
1.92M
    memset( p_header, 0, sizeof(*p_header) );
302
1.92M
    p_header->syncword = DTS_SYNC_SUBSTREAM;
303
1.92M
    p_header->i_substream_header_size = nuExtSSHeaderSize + 1;
304
1.92M
    p_header->i_frame_size = nuBits4ExSSFsize + 1;
305
1.92M
    return VLC_SUCCESS;
306
1.92M
}
307
308
static int dts_header_ParseLBRExtSubstream( vlc_dts_header_t *p_header,
309
                                             const void *p_buffer )
310
1.65M
{
311
1.65M
    bs_t s;
312
1.65M
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
313
1.65M
    bs_skip( &s, 32 /*SYNCEXTSSH*/ );
314
1.65M
    uint8_t ucFmtInfoCode = bs_read( &s, 8 );
315
1.65M
    if( ucFmtInfoCode != 0x02 /*LBR_HDRCODE_DECODERINIT*/ )
316
477k
        return VLC_EGENERIC;
317
1.17M
    p_header->i_rate = bs_read( &s, 8 );
318
    /* See ETSI TS 102 114, table 9-3 */
319
1.17M
    const unsigned int LBRsamplerates[] = {
320
1.17M
        8000, 16000, 32000,
321
1.17M
        0, 0,
322
1.17M
        22050, 44100,
323
1.17M
        0, 0, 0,
324
1.17M
        12000, 24000, 48000,
325
1.17M
    };
326
1.17M
    if(p_header->i_rate >= ARRAY_SIZE(LBRsamplerates))
327
11.1k
        return VLC_EGENERIC;
328
1.16M
    p_header->i_rate = LBRsamplerates[p_header->i_rate];
329
1.16M
    if( p_header->i_rate < 16000 )
330
810k
        p_header->i_frame_length = 1024;
331
358k
    else if( p_header->i_rate < 32000 )
332
9.50k
        p_header->i_frame_length = 2048;
333
349k
    else
334
349k
        p_header->i_frame_length = 4096;
335
336
1.16M
    uint16_t i_spkrmask = bs_read( &s, 16 );
337
1.16M
    dca_get_LBR_channels( i_spkrmask, &p_header->i_physical_channels );
338
1.16M
    bs_skip( &s, 16 );
339
1.16M
    bs_skip( &s, 8 );
340
1.16M
    uint16_t nLBRBitRateMSnybbles = bs_read( &s, 8 );
341
1.16M
    bs_skip( &s, 16 );
342
1.16M
    uint16_t nLBRScaledBitRate_LSW = bs_read( &s, 16 );
343
1.16M
    p_header->i_bitrate = nLBRScaledBitRate_LSW | ((nLBRBitRateMSnybbles & 0xF0) << 12);
344
1.16M
    p_header->i_frame_size = 0;
345
1.16M
    return VLC_SUCCESS;
346
1.17M
}
347
348
static int dts_header_ParseCore( vlc_dts_header_t *p_header,
349
                                 const void *p_buffer)
350
1.05M
{
351
1.05M
    bs_t s;
352
1.05M
    bs_init( &s, p_buffer, VLC_DTS_HEADER_SIZE );
353
1.05M
    bs_skip( &s, 32 /*SYNC*/ + 1 /*FTYPE*/ + 5 /*SHORT*/ + 1 /*CPF*/ );
354
1.05M
    uint8_t i_nblks = bs_read( &s, 7 );
355
1.05M
    if( i_nblks < 5 )
356
3.91k
        return VLC_EGENERIC;
357
1.04M
    uint16_t i_fsize = bs_read( &s, 14 );
358
1.04M
    if( i_fsize < 95 )
359
6.75k
        return VLC_EGENERIC;
360
1.04M
    uint8_t i_amode = bs_read( &s, 6 );
361
1.04M
    uint8_t i_sfreq = bs_read( &s, 4 );
362
1.04M
    uint8_t i_rate = bs_read( &s, 5 );
363
1.04M
    bs_skip( &s, 1 /*FixedBit*/ + 1 /*DYNF*/ + 1 /*TIMEF*/ + 1 /*AUXF*/ +
364
1.04M
             1 /*HDCD*/ + 3 /*EXT_AUDIO_ID*/ + 1 /*EXT_AUDIO */ + 1 /*ASPF*/ );
365
1.04M
    uint8_t i_lff = bs_read( &s, 2 );
366
367
1.04M
    bool b_lfe = i_lff == 1 || i_lff == 2;
368
369
1.04M
    p_header->i_rate = dca_get_samplerate( i_sfreq );
370
1.04M
    p_header->i_bitrate = dca_get_bitrate( i_rate );
371
1.04M
    p_header->i_frame_size = i_fsize + 1;
372
1.04M
    if( p_header->syncword == DTS_SYNC_CORE_14BITS_LE ||
373
855k
        p_header->syncword == DTS_SYNC_CORE_14BITS_BE )
374
192k
        p_header->i_frame_size = p_header->i_frame_size * 16 / 14;
375
    /* See ETSI TS 102 114, table 5-2 */
376
1.04M
    p_header->i_frame_length = (i_nblks + 1) * 32;
377
1.04M
    p_header->i_chan_mode = 0;
378
1.04M
    p_header->i_physical_channels =
379
1.04M
        dca_get_channels( i_amode, b_lfe, &p_header->i_chan_mode );
380
381
1.04M
    if( !p_header->i_rate || !p_header->i_frame_size ||
382
1.01M
        !p_header->i_frame_length || !p_header->i_physical_channels )
383
818k
        return VLC_EGENERIC;
384
385
224k
    return VLC_SUCCESS;
386
1.04M
}
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
18.8M
{
412
18.8M
    if( i_buffer < VLC_DTS_HEADER_SIZE )
413
0
        return VLC_EGENERIC;
414
415
18.8M
    p_header->syncword = dts_header_getSyncword( p_buffer );
416
18.8M
    if( p_header->syncword == DTS_SYNC_NONE )
417
14.2M
        return VLC_EGENERIC;
418
419
4.63M
    switch( p_header->syncword )
420
4.63M
    {
421
40.0k
        case DTS_SYNC_CORE_LE:
422
40.0k
        {
423
40.0k
            uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
424
40.0k
            BufLeToBe( conv_buf, p_buffer, VLC_DTS_HEADER_SIZE );
425
40.0k
            return dts_header_ParseCore( p_header, conv_buf );
426
0
        }
427
813k
        case DTS_SYNC_CORE_BE:
428
813k
            return dts_header_ParseCore( p_header, p_buffer );
429
5.70k
        case DTS_SYNC_CORE_14BITS_BE:
430
199k
        case DTS_SYNC_CORE_14BITS_LE:
431
199k
        {
432
199k
            uint8_t conv_buf[VLC_DTS_HEADER_SIZE];
433
199k
            Buf14To16( conv_buf, p_buffer, VLC_DTS_HEADER_SIZE,
434
199k
                       p_header->syncword == DTS_SYNC_CORE_14BITS_LE, 0 );
435
199k
            return dts_header_ParseCore( p_header, conv_buf );
436
5.70k
        }
437
1.92M
        case DTS_SYNC_SUBSTREAM:
438
1.92M
            return dts_header_ParseSubstream( p_header, p_buffer );
439
1.65M
        case DTS_SYNC_SUBSTREAM_LBR:
440
1.65M
            return dts_header_ParseLBRExtSubstream( p_header, p_buffer );
441
0
        default:
442
0
            vlc_assert_unreachable();
443
4.63M
    }
444
4.63M
}