Coverage Report

Created: 2025-07-23 07:11

/src/vlc/modules/packetizer/flac.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * flac.c: flac packetizer module.
3
 *****************************************************************************
4
 * Copyright (C) 1999-2017 VLC authors and VideoLAN
5
 *
6
 * Authors: Gildas Bazin <gbazin@videolan.org>
7
 *          Sigmund Augdal Helberg <dnumgis@videolan.org>
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
/*****************************************************************************
25
 * Preamble
26
 *****************************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
# include "config.h"
30
#endif
31
32
#include <vlc_common.h>
33
#include <vlc_plugin.h>
34
#include <vlc_codec.h>
35
36
#include <vlc_block_helper.h>
37
#include "packetizer_helper.h"
38
#include "flac.h"
39
40
/*****************************************************************************
41
 * Module descriptor
42
 *****************************************************************************/
43
static int  Open (vlc_object_t *);
44
static void Close(vlc_object_t *);
45
46
104
vlc_module_begin()
47
52
    set_subcategory(SUBCAT_SOUT_PACKETIZER)
48
52
    set_description(N_("Flac audio packetizer"))
49
52
    set_capability("audio packetizer", 50)
50
104
    set_callbacks(Open, Close)
51
52
vlc_module_end()
52
53
/*****************************************************************************
54
 * decoder_sys_t : FLAC decoder descriptor
55
 *****************************************************************************/
56
typedef struct
57
{
58
    /*
59
     * Input properties
60
     */
61
    int i_state;
62
63
    block_bytestream_t bytestream;
64
    size_t i_offset;
65
66
    /*
67
     * FLAC properties
68
     */
69
    struct flac_stream_info stream_info;
70
    bool b_stream_info;
71
72
    /*
73
     * Common properties
74
     */
75
    date_t pts;
76
    struct flac_header_info headerinfo;
77
78
    size_t i_last_frame_size;
79
    uint16_t crc;
80
    size_t i_buf_offset; /* in final buffer before crc check / validation / retry */
81
    size_t i_buf;
82
    uint8_t *p_buf;
83
84
    int i_next_block_flags;
85
} decoder_sys_t;
86
87
static const int pi_channels_maps[9] =
88
{
89
    0,
90
    AOUT_CHAN_CENTER,
91
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
92
    AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
93
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
94
     | AOUT_CHAN_REARRIGHT,
95
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
96
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
97
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
98
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
99
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
100
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT
101
     | AOUT_CHAN_MIDDLERIGHT,
102
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
103
     | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
104
     | AOUT_CHAN_LFE
105
};
106
107
108
/*****************************************************************************
109
 * ProcessHeader: process Flac header.
110
 *****************************************************************************/
111
static void ProcessHeader(decoder_t *p_dec)
112
41
{
113
41
    decoder_sys_t *p_sys = p_dec->p_sys;
114
115
41
    int i_extra = p_dec->fmt_in->i_extra;
116
41
    char *p_extra = p_dec->fmt_in->p_extra;
117
118
41
    if (i_extra > 8 && !memcmp(p_extra, "fLaC", 4)) {
119
0
        i_extra -= 8;
120
0
        p_extra += 8;
121
0
    }
122
123
41
    if (i_extra < FLAC_STREAMINFO_SIZE)
124
0
        return;
125
126
41
    FLAC_ParseStreamInfo( (uint8_t *) p_extra, &p_sys->stream_info );
127
128
41
    p_sys->b_stream_info = true;
129
130
41
    p_dec->fmt_out.i_extra = i_extra;
131
41
    free(p_dec->fmt_out.p_extra);
132
41
    p_dec->fmt_out.p_extra = malloc(i_extra);
133
41
    if (p_dec->fmt_out.p_extra)
134
41
        memcpy(p_dec->fmt_out.p_extra, p_extra, i_extra);
135
0
    else
136
0
        p_dec->fmt_out.i_extra = 0;
137
41
}
138
139
/* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
140
static const uint8_t flac_crc8_table[256] = {
141
        0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
142
        0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
143
        0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
144
        0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
145
        0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
146
        0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
147
        0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
148
        0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
149
        0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
150
        0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
151
        0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
152
        0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
153
        0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
154
        0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
155
        0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
156
        0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
157
        0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
158
        0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
159
        0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
160
        0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
161
        0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
162
        0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
163
        0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
164
        0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
165
        0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
166
        0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
167
        0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
168
        0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
169
        0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
170
        0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
171
        0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
172
        0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
173
};
174
175
static uint8_t flac_crc8(const uint8_t *data, size_t len)
176
246k
{
177
246k
    uint8_t crc = 0;
178
179
1.61M
    while (len--)
180
1.36M
        crc = flac_crc8_table[crc ^ *data++];
181
182
246k
    return crc;
183
246k
}
184
185
/* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
186
static const uint16_t flac_crc16_table[256] = {
187
    0x0000,  0x8005,  0x800f,  0x000a,  0x801b,  0x001e,  0x0014,  0x8011,
188
    0x8033,  0x0036,  0x003c,  0x8039,  0x0028,  0x802d,  0x8027,  0x0022,
189
    0x8063,  0x0066,  0x006c,  0x8069,  0x0078,  0x807d,  0x8077,  0x0072,
190
    0x0050,  0x8055,  0x805f,  0x005a,  0x804b,  0x004e,  0x0044,  0x8041,
191
    0x80c3,  0x00c6,  0x00cc,  0x80c9,  0x00d8,  0x80dd,  0x80d7,  0x00d2,
192
    0x00f0,  0x80f5,  0x80ff,  0x00fa,  0x80eb,  0x00ee,  0x00e4,  0x80e1,
193
    0x00a0,  0x80a5,  0x80af,  0x00aa,  0x80bb,  0x00be,  0x00b4,  0x80b1,
194
    0x8093,  0x0096,  0x009c,  0x8099,  0x0088,  0x808d,  0x8087,  0x0082,
195
    0x8183,  0x0186,  0x018c,  0x8189,  0x0198,  0x819d,  0x8197,  0x0192,
196
    0x01b0,  0x81b5,  0x81bf,  0x01ba,  0x81ab,  0x01ae,  0x01a4,  0x81a1,
197
    0x01e0,  0x81e5,  0x81ef,  0x01ea,  0x81fb,  0x01fe,  0x01f4,  0x81f1,
198
    0x81d3,  0x01d6,  0x01dc,  0x81d9,  0x01c8,  0x81cd,  0x81c7,  0x01c2,
199
    0x0140,  0x8145,  0x814f,  0x014a,  0x815b,  0x015e,  0x0154,  0x8151,
200
    0x8173,  0x0176,  0x017c,  0x8179,  0x0168,  0x816d,  0x8167,  0x0162,
201
    0x8123,  0x0126,  0x012c,  0x8129,  0x0138,  0x813d,  0x8137,  0x0132,
202
    0x0110,  0x8115,  0x811f,  0x011a,  0x810b,  0x010e,  0x0104,  0x8101,
203
    0x8303,  0x0306,  0x030c,  0x8309,  0x0318,  0x831d,  0x8317,  0x0312,
204
    0x0330,  0x8335,  0x833f,  0x033a,  0x832b,  0x032e,  0x0324,  0x8321,
205
    0x0360,  0x8365,  0x836f,  0x036a,  0x837b,  0x037e,  0x0374,  0x8371,
206
    0x8353,  0x0356,  0x035c,  0x8359,  0x0348,  0x834d,  0x8347,  0x0342,
207
    0x03c0,  0x83c5,  0x83cf,  0x03ca,  0x83db,  0x03de,  0x03d4,  0x83d1,
208
    0x83f3,  0x03f6,  0x03fc,  0x83f9,  0x03e8,  0x83ed,  0x83e7,  0x03e2,
209
    0x83a3,  0x03a6,  0x03ac,  0x83a9,  0x03b8,  0x83bd,  0x83b7,  0x03b2,
210
    0x0390,  0x8395,  0x839f,  0x039a,  0x838b,  0x038e,  0x0384,  0x8381,
211
    0x0280,  0x8285,  0x828f,  0x028a,  0x829b,  0x029e,  0x0294,  0x8291,
212
    0x82b3,  0x02b6,  0x02bc,  0x82b9,  0x02a8,  0x82ad,  0x82a7,  0x02a2,
213
    0x82e3,  0x02e6,  0x02ec,  0x82e9,  0x02f8,  0x82fd,  0x82f7,  0x02f2,
214
    0x02d0,  0x82d5,  0x82df,  0x02da,  0x82cb,  0x02ce,  0x02c4,  0x82c1,
215
    0x8243,  0x0246,  0x024c,  0x8249,  0x0258,  0x825d,  0x8257,  0x0252,
216
    0x0270,  0x8275,  0x827f,  0x027a,  0x826b,  0x026e,  0x0264,  0x8261,
217
    0x0220,  0x8225,  0x822f,  0x022a,  0x823b,  0x023e,  0x0234,  0x8231,
218
    0x8213,  0x0216,  0x021c,  0x8219,  0x0208,  0x820d,  0x8207,  0x0202
219
};
220
221
static uint16_t flac_crc16(uint16_t crc, uint8_t byte)
222
143M
{
223
143M
    return (crc << 8) ^ flac_crc16_table[(crc >> 8) ^ byte];
224
143M
}
225
#if 0
226
/* Gives the previous CRC value, before hashing last_byte through it */
227
static uint16_t flac_crc16_undo(uint16_t crc, const uint8_t last_byte)
228
{
229
    /*
230
     * Given a byte b, gives a position X in flac_crc16_table, such as:
231
     *      flac_crc16_rev_table[flac_crc16_table[X] & 0xff] == X
232
     * This works because flac_crc16_table[i] & 0xff yields 256 unique values.
233
     */
234
    static const uint8_t flac_crc16_rev_table[256] = {
235
        0x00, 0x7f, 0xff, 0x80, 0x7e, 0x01, 0x81, 0xfe,
236
        0xfc, 0x83, 0x03, 0x7c, 0x82, 0xfd, 0x7d, 0x02,
237
        0x78, 0x07, 0x87, 0xf8, 0x06, 0x79, 0xf9, 0x86,
238
        0x84, 0xfb, 0x7b, 0x04, 0xfa, 0x85, 0x05, 0x7a,
239
        0xf0, 0x8f, 0x0f, 0x70, 0x8e, 0xf1, 0x71, 0x0e,
240
        0x0c, 0x73, 0xf3, 0x8c, 0x72, 0x0d, 0x8d, 0xf2,
241
        0x88, 0xf7, 0x77, 0x08, 0xf6, 0x89, 0x09, 0x76,
242
        0x74, 0x0b, 0x8b, 0xf4, 0x0a, 0x75, 0xf5, 0x8a,
243
        0x60, 0x1f, 0x9f, 0xe0, 0x1e, 0x61, 0xe1, 0x9e,
244
        0x9c, 0xe3, 0x63, 0x1c, 0xe2, 0x9d, 0x1d, 0x62,
245
        0x18, 0x67, 0xe7, 0x98, 0x66, 0x19, 0x99, 0xe6,
246
        0xe4, 0x9b, 0x1b, 0x64, 0x9a, 0xe5, 0x65, 0x1a,
247
        0x90, 0xef, 0x6f, 0x10, 0xee, 0x91, 0x11, 0x6e,
248
        0x6c, 0x13, 0x93, 0xec, 0x12, 0x6d, 0xed, 0x92,
249
        0xe8, 0x97, 0x17, 0x68, 0x96, 0xe9, 0x69, 0x16,
250
        0x14, 0x6b, 0xeb, 0x94, 0x6a, 0x15, 0x95, 0xea,
251
        0xc0, 0xbf, 0x3f, 0x40, 0xbe, 0xc1, 0x41, 0x3e,
252
        0x3c, 0x43, 0xc3, 0xbc, 0x42, 0x3d, 0xbd, 0xc2,
253
        0xb8, 0xc7, 0x47, 0x38, 0xc6, 0xb9, 0x39, 0x46,
254
        0x44, 0x3b, 0xbb, 0xc4, 0x3a, 0x45, 0xc5, 0xba,
255
        0x30, 0x4f, 0xcf, 0xb0, 0x4e, 0x31, 0xb1, 0xce,
256
        0xcc, 0xb3, 0x33, 0x4c, 0xb2, 0xcd, 0x4d, 0x32,
257
        0x48, 0x37, 0xb7, 0xc8, 0x36, 0x49, 0xc9, 0xb6,
258
        0xb4, 0xcb, 0x4b, 0x34, 0xca, 0xb5, 0x35, 0x4a,
259
        0xa0, 0xdf, 0x5f, 0x20, 0xde, 0xa1, 0x21, 0x5e,
260
        0x5c, 0x23, 0xa3, 0xdc, 0x22, 0x5d, 0xdd, 0xa2,
261
        0xd8, 0xa7, 0x27, 0x58, 0xa6, 0xd9, 0x59, 0x26,
262
        0x24, 0x5b, 0xdb, 0xa4, 0x5a, 0x25, 0xa5, 0xda,
263
        0x50, 0x2f, 0xaf, 0xd0, 0x2e, 0x51, 0xd1, 0xae,
264
        0xac, 0xd3, 0x53, 0x2c, 0xd2, 0xad, 0x2d, 0x52,
265
        0x28, 0x57, 0xd7, 0xa8, 0x56, 0x29, 0xa9, 0xd6,
266
        0xd4, 0xab, 0x2b, 0x54, 0xaa, 0xd5, 0x55, 0x2a,
267
    };
268
    uint8_t idx = flac_crc16_rev_table[crc & 0xff];
269
    return ((idx ^ last_byte) << 8) | ((crc ^ flac_crc16_table[idx]) >> 8);
270
}
271
#endif
272
273
static void Flush(decoder_t *p_dec)
274
0
{
275
0
    decoder_sys_t *p_sys = p_dec->p_sys;
276
277
0
    p_sys->i_state = STATE_NOSYNC;
278
0
    p_sys->i_offset = 0;
279
0
    date_Set( &p_sys->pts, VLC_TICK_INVALID );
280
0
    block_BytestreamEmpty(&p_sys->bytestream);
281
0
}
282
283
static const uint8_t * FLACStartcodeHelper(const uint8_t *p, const uint8_t *end)
284
13.4M
{
285
54.2M
    while( p && p < end )
286
54.2M
    {
287
54.2M
        if( (p = memchr(p, 0xFF, end - p)) )
288
54.2M
        {
289
54.2M
            if( end - p > 1 && (p[1] & 0xFE) == 0xF8 )
290
13.4M
                return p;
291
40.7M
            else
292
40.7M
                p++;
293
54.2M
        }
294
54.2M
    }
295
14.4k
    return NULL;
296
13.4M
}
297
298
static bool FLACStartcodeMatcher(uint8_t i, size_t i_pos, const uint8_t *p_startcode)
299
19.2k
{
300
19.2k
    VLC_UNUSED(p_startcode);
301
19.2k
    return (i_pos == 0) ? i == 0xFF : (i & 0xFE) == 0xF8;
302
19.2k
}
303
304
/* */
305
static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
306
4.11k
{
307
4.11k
    decoder_sys_t *p_sys = p_dec->p_sys;
308
4.11k
    uint8_t p_header[FLAC_HEADER_SIZE_MAX];
309
4.11k
    block_t *out = NULL, *in = NULL;
310
311
4.11k
    if ( pp_block && *pp_block)
312
4.06k
    {
313
4.06k
        in = *pp_block;
314
4.06k
        *pp_block = NULL;
315
4.06k
        if (in->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
316
0
            Flush(p_dec);
317
0
            p_sys->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
318
0
            if (in->i_flags&BLOCK_FLAG_CORRUPTED) {
319
0
                block_Release(in);
320
0
                return NULL;
321
0
            }
322
0
        }
323
4.06k
    }
324
325
4.11k
    if (!p_sys->b_stream_info)
326
41
        ProcessHeader(p_dec);
327
328
4.11k
    if (p_sys->stream_info.channels > 8)
329
0
    {
330
0
        if(in)
331
0
            block_Release(in);
332
0
        msg_Err(p_dec, "This stream uses too many audio channels (%d > 8)",
333
0
            p_sys->stream_info.channels);
334
0
        return NULL;
335
0
    }
336
337
4.11k
    if ( in )
338
4.06k
        block_BytestreamPush(&p_sys->bytestream, in);
339
340
19.5M
    while (1) switch (p_sys->i_state) {
341
721k
    case STATE_NOSYNC:
342
721k
        if(block_FindStartcodeFromOffset(&p_sys->bytestream, &p_sys->i_offset,
343
721k
                                         NULL, 2,
344
721k
                                         FLACStartcodeHelper,
345
721k
                                         FLACStartcodeMatcher) == VLC_SUCCESS)
346
721k
        {
347
721k
            p_sys->i_state = STATE_SYNC;
348
721k
        }
349
350
        /* First Sync is now on bytestream head, offset == 0 */
351
721k
        block_SkipBytes(&p_sys->bytestream, p_sys->i_offset);
352
721k
        block_BytestreamFlush(&p_sys->bytestream);
353
721k
        p_sys->i_offset = 0;
354
355
721k
        if( p_sys->i_state != STATE_SYNC )
356
66
            return NULL; /* Need more data */
357
        /* fallthrough */
358
359
721k
    case STATE_SYNC:
360
        /* Sync state is unverified until we have read frame header and checked CRC
361
           Once validated, we'll send data from NEXT_SYNC state where we'll
362
           compute frame size */
363
721k
        p_sys->i_state = STATE_HEADER;
364
        /* fallthrough */
365
366
721k
    case STATE_HEADER:
367
721k
    {
368
        /* Get FLAC frame header (MAX_FLAC_HEADER_SIZE bytes) */
369
721k
        if (block_PeekBytes(&p_sys->bytestream, p_header, FLAC_HEADER_SIZE_MAX))
370
52
            return NULL; /* Need more data */
371
372
        /* Check if frame is valid and get frame info */
373
721k
        const struct flac_stream_info *streaminfo =
374
721k
                p_sys->b_stream_info ? &p_sys->stream_info : NULL;
375
721k
        struct flac_header_info headerinfo;
376
721k
        int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX, streaminfo,
377
721k
                                       flac_crc8, &headerinfo);
378
721k
        if (!i_ret || !FLAC_CheckFrameInfo(streaminfo, &headerinfo)) {
379
603k
            msg_Dbg(p_dec, "emulated sync word");
380
603k
            block_SkipByte(&p_sys->bytestream);
381
603k
            p_sys->i_offset = 0;
382
603k
            p_sys->i_state = STATE_NOSYNC;
383
603k
            break;
384
603k
        }
385
386
118k
        p_sys->headerinfo = headerinfo;
387
118k
        p_sys->i_state = STATE_NEXT_SYNC;
388
118k
        p_sys->i_offset = FLAC_FRAME_SIZE_MIN;
389
118k
        p_sys->i_buf_offset = 0;
390
118k
        p_sys->crc = 0;
391
392
        /* We have to read until next frame sync code to compute current frame size
393
         * from that boundary.
394
         * The confusing part below is that sync code needs to be verified in case
395
         * it would appear in data, so we also need to check next frame header CRC
396
         */
397
118k
    }
398
        /* fallthrough */
399
400
12.7M
    case STATE_NEXT_SYNC:
401
12.7M
    {
402
        /* First Sync is on bytestream head, offset will be the position
403
         * of the next sync code candidate */
404
12.7M
        if(block_FindStartcodeFromOffset(&p_sys->bytestream, &p_sys->i_offset,
405
12.7M
                                         NULL, 2,
406
12.7M
                                         FLACStartcodeHelper,
407
12.7M
                                         FLACStartcodeMatcher) != VLC_SUCCESS)
408
870
        {
409
870
            size_t i_remain = block_BytestreamRemaining( &p_sys->bytestream );
410
870
            if( pp_block == NULL && i_remain > FLAC_FRAME_SIZE_MIN ) /* EOF/Drain */
411
39
            {
412
                /* There is no other synccode in the bytestream,
413
                 * we assume the end of our flac frame is end of bytestream */
414
39
                p_sys->i_offset = i_remain;
415
39
                p_sys->i_state = STATE_GET_DATA;
416
39
                continue;
417
39
            }
418
831
            return NULL;
419
870
        }
420
421
        /* Check next header */
422
12.7M
        uint8_t nextheader[FLAC_HEADER_SIZE_MAX];
423
12.7M
        if (block_PeekOffsetBytes(&p_sys->bytestream, p_sys->i_offset,
424
12.7M
                                  nextheader, FLAC_HEADER_SIZE_MAX))
425
562
            return NULL; /* Need more data */
426
427
12.7M
        const struct flac_stream_info *streaminfo =
428
12.7M
                p_sys->b_stream_info ? &p_sys->stream_info : NULL;
429
12.7M
        struct flac_header_info dummy;
430
        /* Check if frame is valid and get frame info */
431
12.7M
        if(!FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX, streaminfo, NULL, &dummy)||
432
12.7M
           !FLAC_CheckFrameInfo(streaminfo, &dummy))
433
6.46M
        {
434
            /* Keep trying to find next sync point in bytestream */
435
6.46M
            p_sys->i_offset++;
436
6.46M
            continue;
437
6.46M
        }
438
439
6.25M
        p_sys->i_state = STATE_GET_DATA;
440
6.25M
        continue;
441
12.7M
    }
442
443
6.25M
    case STATE_GET_DATA:
444
        /* i_offset is the next sync point candidate
445
         * our frame_size is the offset from the first sync */
446
6.25M
        if( pp_block != NULL &&
447
6.25M
            p_sys->b_stream_info &&
448
6.25M
            p_sys->stream_info.min_framesize > p_sys->i_offset )
449
14.8k
        {
450
14.8k
            p_sys->i_offset += 1;
451
14.8k
            p_sys->i_state = STATE_NEXT_SYNC;
452
14.8k
            break;
453
14.8k
        }
454
6.24M
        else if( p_sys->b_stream_info &&
455
6.24M
                 p_sys->stream_info.max_framesize > FLAC_FRAME_SIZE_MIN &&
456
6.24M
                 p_sys->stream_info.max_framesize < p_sys->i_offset )
457
111k
        {
458
            /* Something went wrong, truncate stream head and restart */
459
111k
            msg_Warn(p_dec, "discarding bytes as we're over framesize %u, %zu",
460
111k
                     p_sys->stream_info.max_framesize,
461
111k
                     p_sys->i_offset);
462
111k
            if( block_SkipBytes( &p_sys->bytestream,
463
111k
                                 FLAC_HEADER_SIZE_MAX + 2 ) != VLC_SUCCESS )
464
0
                return NULL;
465
111k
            block_BytestreamFlush( &p_sys->bytestream );
466
111k
            p_sys->crc = 0;
467
111k
            p_sys->i_buf_offset = 0;
468
111k
            p_sys->i_offset = 0;
469
111k
            p_sys->i_state = STATE_NOSYNC;
470
111k
            p_sys->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
471
111k
            break;
472
111k
        }
473
6.13M
        else
474
6.13M
        {
475
            /* Allocate enough for storage */
476
6.13M
            if( p_sys->i_offset > p_sys->i_buf )
477
375k
            {
478
375k
                size_t i_min_alloc = __MAX(p_sys->i_last_frame_size, p_sys->i_offset);
479
375k
                uint8_t *p_realloc = realloc( p_sys->p_buf, i_min_alloc );
480
375k
                if( p_realloc )
481
375k
                {
482
375k
                    p_sys->i_buf = i_min_alloc;
483
375k
                    p_sys->p_buf = p_realloc;
484
375k
                }
485
486
375k
                if ( !p_sys->p_buf )
487
0
                    return NULL;
488
375k
            }
489
490
            /* Copy from previous sync point up to to current (offset) */
491
6.13M
            block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_buf_offset,
492
6.13M
                                   &p_sys->p_buf[p_sys->i_buf_offset],
493
6.13M
                                    p_sys->i_offset - p_sys->i_buf_offset );
494
495
            /* update crc to include this data chunk */
496
136M
            for( size_t i = p_sys->i_buf_offset; i < p_sys->i_offset - 2; i++ )
497
130M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[i] );
498
499
6.13M
            uint16_t stream_crc = GetWBE(&p_sys->p_buf[p_sys->i_offset - 2]);
500
6.13M
            if( stream_crc != p_sys->crc )
501
6.13M
            {
502
                /* False positive syncpoint as the CRC does not match */
503
                /* Add the 2 last bytes which were not the CRC sum, and go for next sync point */
504
6.13M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[p_sys->i_offset - 2] );
505
6.13M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[p_sys->i_offset - 1] );
506
6.13M
                p_sys->i_buf_offset = p_sys->i_offset;
507
6.13M
                p_sys->i_offset += 1;
508
6.13M
                p_sys->i_state = !pp_block ? STATE_NOSYNC : STATE_NEXT_SYNC;
509
6.13M
                break; /* continue */
510
6.13M
            }
511
512
2.59k
            p_sys->i_state = STATE_SEND_DATA;
513
514
            /* frame size between the two sync codes is now known */
515
2.59k
            p_sys->i_last_frame_size = p_sys->i_offset;
516
2.59k
            p_sys->i_buf = p_sys->i_offset;
517
518
            /* clean */
519
2.59k
            block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
520
2.59k
            block_BytestreamFlush( &p_sys->bytestream );
521
2.59k
            p_sys->i_offset = 0;
522
2.59k
            p_sys->crc = 0;
523
2.59k
            p_sys->i_buf_offset = 0;
524
525
2.59k
            if( block_BytestreamRemaining(&p_sys->bytestream) > 0 || pp_block == NULL /* drain */)
526
2.59k
                p_sys->i_state = STATE_SEND_DATA;
527
0
            else
528
0
                p_sys->i_state = STATE_NOSYNC;
529
2.59k
        }
530
2.59k
        break;
531
532
2.59k
    case STATE_SEND_DATA:
533
2.59k
        p_dec->fmt_out.audio.i_rate = p_sys->headerinfo.i_rate;
534
2.59k
        p_dec->fmt_out.audio.i_channels = p_sys->headerinfo.i_channels;
535
2.59k
        p_dec->fmt_out.audio.i_physical_channels = pi_channels_maps[p_sys->stream_info.channels];
536
537
2.59k
        if( p_sys->bytestream.p_block &&
538
2.59k
            p_sys->bytestream.p_block->i_pts > date_Get( &p_sys->pts ) &&
539
2.59k
            p_sys->bytestream.p_block->i_pts != VLC_TICK_INVALID )
540
10
        {
541
10
            date_Init( &p_sys->pts, p_sys->headerinfo.i_rate, 1 );
542
10
            date_Set( &p_sys->pts, p_sys->bytestream.p_block->i_pts );
543
10
            p_sys->bytestream.p_block->i_pts = VLC_TICK_INVALID;
544
10
        }
545
546
547
2.59k
        out = block_heap_Alloc( p_sys->p_buf, p_sys->i_buf );
548
2.59k
        if( out )
549
2.59k
        {
550
2.59k
            out->i_dts = out->i_pts = date_Get( &p_sys->pts );
551
2.59k
            out->i_flags = p_sys->i_next_block_flags;
552
2.59k
            p_sys->i_next_block_flags = 0;
553
2.59k
        }
554
0
        else
555
0
            p_sys->p_buf = NULL;
556
557
2.59k
        date_Increment( &p_sys->pts, p_sys->headerinfo.i_frame_length );
558
2.59k
        if( out )
559
2.59k
            out->i_length = date_Get( &p_sys->pts ) - out->i_pts;
560
0
        else
561
0
            free( p_sys->p_buf );
562
563
2.59k
        p_sys->i_buf_offset = 0;
564
2.59k
        p_sys->i_buf = 0;
565
2.59k
        p_sys->p_buf = NULL;
566
2.59k
        p_sys->i_offset = 0;
567
2.59k
        p_sys->i_state = STATE_NOSYNC;
568
569
        /* So p_block doesn't get re-added several times */
570
2.59k
        if ( pp_block )
571
2.59k
            *pp_block = block_BytestreamPop(&p_sys->bytestream);
572
573
2.59k
        return out;
574
19.5M
    }
575
576
0
    return NULL;
577
4.11k
}
578
579
static int Open(vlc_object_t *p_this)
580
{
581
    decoder_t *p_dec = (decoder_t*)p_this;
582
    decoder_sys_t *p_sys;
583
584
    if (p_dec->fmt_in->i_codec != VLC_CODEC_FLAC)
585
        return VLC_EGENERIC;
586
587
588
    /* */
589
    p_dec->p_sys = p_sys = malloc(sizeof(*p_sys));
590
    if (!p_sys)
591
        return VLC_ENOMEM;
592
593
    p_sys->i_state       = STATE_NOSYNC;
594
    p_sys->i_offset      = 0;
595
    p_sys->b_stream_info = false;
596
    p_sys->i_last_frame_size = FLAC_FRAME_SIZE_MIN;
597
    p_sys->headerinfo.i_pts  = VLC_TICK_INVALID;
598
    p_sys->i_buf_offset  = 0;
599
    p_sys->i_buf         = 0;
600
    p_sys->p_buf         = NULL;
601
    p_sys->i_next_block_flags = 0;
602
    block_BytestreamInit(&p_sys->bytestream);
603
    date_Init( &p_sys->pts, 1, 1 );
604
605
    /* */
606
    es_format_Copy(&p_dec->fmt_out, p_dec->fmt_in);
607
    p_dec->fmt_out.i_codec = VLC_CODEC_FLAC;
608
    p_dec->fmt_out.b_packetized = true;
609
610
    /* */
611
    p_dec->pf_packetize = Packetize;
612
    p_dec->pf_flush     = Flush;
613
    p_dec->pf_get_cc    = NULL;
614
615
    return VLC_SUCCESS;
616
}
617
618
static void Close(vlc_object_t *p_this)
619
{
620
    decoder_t *p_dec = (decoder_t *)p_this;
621
    decoder_sys_t *p_sys = p_dec->p_sys;
622
623
    block_BytestreamRelease(&p_sys->bytestream);
624
    free(p_sys->p_buf);
625
    free(p_sys);
626
}