Coverage Report

Created: 2025-10-12 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/packetizer/flac.c
Line
Count
Source
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
108
vlc_module_begin()
47
54
    set_subcategory(SUBCAT_SOUT_PACKETIZER)
48
54
    set_description(N_("Flac audio packetizer"))
49
54
    set_capability("audio packetizer", 50)
50
108
    set_callbacks(Open, Close)
51
54
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
2.74k
{
113
2.74k
    decoder_sys_t *p_sys = p_dec->p_sys;
114
115
2.74k
    int i_extra = p_dec->fmt_in->i_extra;
116
2.74k
    char *p_extra = p_dec->fmt_in->p_extra;
117
118
2.74k
    if (i_extra > 8 && !memcmp(p_extra, "fLaC", 4)) {
119
189
        i_extra -= 8;
120
189
        p_extra += 8;
121
189
    }
122
123
2.74k
    if (i_extra < FLAC_STREAMINFO_SIZE)
124
189
        return;
125
126
2.55k
    FLAC_ParseStreamInfo( (uint8_t *) p_extra, &p_sys->stream_info );
127
128
2.55k
    p_sys->b_stream_info = true;
129
130
2.55k
    p_dec->fmt_out.i_extra = i_extra;
131
2.55k
    free(p_dec->fmt_out.p_extra);
132
2.55k
    p_dec->fmt_out.p_extra = malloc(i_extra);
133
2.55k
    if (p_dec->fmt_out.p_extra)
134
2.55k
        memcpy(p_dec->fmt_out.p_extra, p_extra, i_extra);
135
0
    else
136
0
        p_dec->fmt_out.i_extra = 0;
137
2.55k
}
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
674k
{
177
674k
    uint8_t crc = 0;
178
179
4.63M
    while (len--)
180
3.95M
        crc = flac_crc8_table[crc ^ *data++];
181
182
674k
    return crc;
183
674k
}
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
685M
{
223
685M
    return (crc << 8) ^ flac_crc16_table[(crc >> 8) ^ byte];
224
685M
}
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
66.0M
{
285
307M
    while( p && p < end )
286
306M
    {
287
306M
        if( (p = memchr(p, 0xFF, end - p)) )
288
306M
        {
289
306M
            if( end - p > 1 && (p[1] & 0xFE) == 0xF8 )
290
66.0M
                return p;
291
240M
            else
292
240M
                p++;
293
306M
        }
294
306M
    }
295
90.8k
    return NULL;
296
66.0M
}
297
298
static bool FLACStartcodeMatcher(uint8_t i, size_t i_pos, const uint8_t *p_startcode)
299
117k
{
300
117k
    VLC_UNUSED(p_startcode);
301
117k
    return (i_pos == 0) ? i == 0xFF : (i & 0xFE) == 0xF8;
302
117k
}
303
304
/* */
305
static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
306
94.2k
{
307
94.2k
    decoder_sys_t *p_sys = p_dec->p_sys;
308
94.2k
    uint8_t p_header[FLAC_HEADER_SIZE_MAX];
309
94.2k
    block_t *out = NULL, *in = NULL;
310
311
94.2k
    if ( pp_block && *pp_block)
312
91.6k
    {
313
91.6k
        in = *pp_block;
314
91.6k
        *pp_block = NULL;
315
91.6k
        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
91.6k
    }
324
325
94.2k
    if (!p_sys->b_stream_info)
326
2.74k
        ProcessHeader(p_dec);
327
328
94.2k
    if (p_sys->stream_info.channels > 8)
329
17
    {
330
17
        if(in)
331
16
            block_Release(in);
332
17
        msg_Err(p_dec, "This stream uses too many audio channels (%d > 8)",
333
17
            p_sys->stream_info.channels);
334
17
        return NULL;
335
17
    }
336
337
94.1k
    if ( in )
338
91.6k
        block_BytestreamPush(&p_sys->bytestream, in);
339
340
86.8M
    while (1) switch (p_sys->i_state) {
341
3.64M
    case STATE_NOSYNC:
342
3.64M
        if(block_FindStartcodeFromOffset(&p_sys->bytestream, &p_sys->i_offset,
343
3.64M
                                         NULL, 2,
344
3.64M
                                         FLACStartcodeHelper,
345
3.64M
                                         FLACStartcodeMatcher) == VLC_SUCCESS)
346
3.64M
        {
347
3.64M
            p_sys->i_state = STATE_SYNC;
348
3.64M
        }
349
350
        /* First Sync is now on bytestream head, offset == 0 */
351
3.64M
        block_SkipBytes(&p_sys->bytestream, p_sys->i_offset);
352
3.64M
        block_BytestreamFlush(&p_sys->bytestream);
353
3.64M
        p_sys->i_offset = 0;
354
355
3.64M
        if( p_sys->i_state != STATE_SYNC )
356
2.85k
            return NULL; /* Need more data */
357
        /* fallthrough */
358
359
3.64M
    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
3.64M
        p_sys->i_state = STATE_HEADER;
364
        /* fallthrough */
365
366
3.64M
    case STATE_HEADER:
367
3.64M
    {
368
        /* Get FLAC frame header (MAX_FLAC_HEADER_SIZE bytes) */
369
3.64M
        if (block_PeekBytes(&p_sys->bytestream, p_header, FLAC_HEADER_SIZE_MAX))
370
1.08k
            return NULL; /* Need more data */
371
372
        /* Check if frame is valid and get frame info */
373
3.64M
        const struct flac_stream_info *streaminfo =
374
3.64M
                p_sys->b_stream_info ? &p_sys->stream_info : NULL;
375
3.64M
        struct flac_header_info headerinfo;
376
3.64M
        int i_ret = FLAC_ParseSyncInfo(p_header, FLAC_HEADER_SIZE_MAX, streaminfo,
377
3.64M
                                       flac_crc8, &headerinfo);
378
3.64M
        if (!i_ret || !FLAC_CheckFrameInfo(streaminfo, &headerinfo)) {
379
3.32M
            msg_Dbg(p_dec, "emulated sync word");
380
3.32M
            block_SkipByte(&p_sys->bytestream);
381
3.32M
            p_sys->i_offset = 0;
382
3.32M
            p_sys->i_state = STATE_NOSYNC;
383
3.32M
            break;
384
3.32M
        }
385
386
318k
        p_sys->headerinfo = headerinfo;
387
318k
        p_sys->i_state = STATE_NEXT_SYNC;
388
318k
        p_sys->i_offset = FLAC_FRAME_SIZE_MIN;
389
318k
        p_sys->i_buf_offset = 0;
390
318k
        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
318k
    }
398
        /* fallthrough */
399
400
62.3M
    case STATE_NEXT_SYNC:
401
62.3M
    {
402
        /* First Sync is on bytestream head, offset will be the position
403
         * of the next sync code candidate */
404
62.3M
        if(block_FindStartcodeFromOffset(&p_sys->bytestream, &p_sys->i_offset,
405
62.3M
                                         NULL, 2,
406
62.3M
                                         FLACStartcodeHelper,
407
62.3M
                                         FLACStartcodeMatcher) != VLC_SUCCESS)
408
5.37k
        {
409
5.37k
            size_t i_remain = block_BytestreamRemaining( &p_sys->bytestream );
410
5.37k
            if( pp_block == NULL && i_remain > FLAC_FRAME_SIZE_MIN ) /* EOF/Drain */
411
1.30k
            {
412
                /* There is no other synccode in the bytestream,
413
                 * we assume the end of our flac frame is end of bytestream */
414
1.30k
                p_sys->i_offset = i_remain;
415
1.30k
                p_sys->i_state = STATE_GET_DATA;
416
1.30k
                continue;
417
1.30k
            }
418
4.07k
            return NULL;
419
5.37k
        }
420
421
        /* Check next header */
422
62.3M
        uint8_t nextheader[FLAC_HEADER_SIZE_MAX];
423
62.3M
        if (block_PeekOffsetBytes(&p_sys->bytestream, p_sys->i_offset,
424
62.3M
                                  nextheader, FLAC_HEADER_SIZE_MAX))
425
2.08k
            return NULL; /* Need more data */
426
427
62.3M
        const struct flac_stream_info *streaminfo =
428
62.3M
                p_sys->b_stream_info ? &p_sys->stream_info : NULL;
429
62.3M
        struct flac_header_info dummy;
430
        /* Check if frame is valid and get frame info */
431
62.3M
        if(!FLAC_ParseSyncInfo(nextheader, FLAC_HEADER_SIZE_MAX, streaminfo, NULL, &dummy)||
432
31.3M
           !FLAC_CheckFrameInfo(streaminfo, &dummy))
433
41.2M
        {
434
            /* Keep trying to find next sync point in bytestream */
435
41.2M
            p_sys->i_offset++;
436
41.2M
            continue;
437
41.2M
        }
438
439
21.0M
        p_sys->i_state = STATE_GET_DATA;
440
21.0M
        continue;
441
62.3M
    }
442
443
21.0M
    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
21.0M
        if( pp_block != NULL &&
447
21.0M
            p_sys->b_stream_info &&
448
21.0M
            p_sys->stream_info.min_framesize > p_sys->i_offset )
449
6.18M
        {
450
6.18M
            p_sys->i_offset += 1;
451
6.18M
            p_sys->i_state = STATE_NEXT_SYNC;
452
6.18M
            break;
453
6.18M
        }
454
14.9M
        else if( p_sys->b_stream_info &&
455
14.9M
                 p_sys->stream_info.max_framesize > FLAC_FRAME_SIZE_MIN &&
456
14.8M
                 p_sys->stream_info.max_framesize < p_sys->i_offset )
457
220k
        {
458
            /* Something went wrong, truncate stream head and restart */
459
220k
            msg_Warn(p_dec, "discarding bytes as we're over framesize %u, %zu",
460
220k
                     p_sys->stream_info.max_framesize,
461
220k
                     p_sys->i_offset);
462
220k
            if( block_SkipBytes( &p_sys->bytestream,
463
220k
                                 FLAC_HEADER_SIZE_MAX + 2 ) != VLC_SUCCESS )
464
19
                return NULL;
465
220k
            block_BytestreamFlush( &p_sys->bytestream );
466
220k
            p_sys->crc = 0;
467
220k
            p_sys->i_buf_offset = 0;
468
220k
            p_sys->i_offset = 0;
469
220k
            p_sys->i_state = STATE_NOSYNC;
470
220k
            p_sys->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
471
220k
            break;
472
220k
        }
473
14.6M
        else
474
14.6M
        {
475
            /* Allocate enough for storage */
476
14.6M
            if( p_sys->i_offset > p_sys->i_buf )
477
1.47M
            {
478
1.47M
                size_t i_min_alloc = __MAX(p_sys->i_last_frame_size, p_sys->i_offset);
479
1.47M
                uint8_t *p_realloc = realloc( p_sys->p_buf, i_min_alloc );
480
1.47M
                if( p_realloc )
481
1.47M
                {
482
1.47M
                    p_sys->i_buf = i_min_alloc;
483
1.47M
                    p_sys->p_buf = p_realloc;
484
1.47M
                }
485
486
1.47M
                if ( !p_sys->p_buf )
487
0
                    return NULL;
488
1.47M
            }
489
490
            /* Copy from previous sync point up to to current (offset) */
491
14.6M
            if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_buf_offset,
492
14.6M
                                       &p_sys->p_buf[p_sys->i_buf_offset],
493
14.6M
                                       p_sys->i_offset - p_sys->i_buf_offset ))
494
0
                return NULL;
495
496
            /* update crc to include this data chunk */
497
670M
            for( size_t i = p_sys->i_buf_offset; i < p_sys->i_offset - 2; i++ )
498
655M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[i] );
499
500
14.6M
            uint16_t stream_crc = GetWBE(&p_sys->p_buf[p_sys->i_offset - 2]);
501
14.6M
            if( stream_crc != p_sys->crc )
502
14.5M
            {
503
                /* False positive syncpoint as the CRC does not match */
504
                /* Add the 2 last bytes which were not the CRC sum, and go for next sync point */
505
14.5M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[p_sys->i_offset - 2] );
506
14.5M
                p_sys->crc = flac_crc16( p_sys->crc, p_sys->p_buf[p_sys->i_offset - 1] );
507
14.5M
                p_sys->i_buf_offset = p_sys->i_offset;
508
14.5M
                p_sys->i_offset += 1;
509
14.5M
                p_sys->i_state = !pp_block ? STATE_NOSYNC : STATE_NEXT_SYNC;
510
14.5M
                break; /* continue */
511
14.5M
            }
512
513
84.0k
            p_sys->i_state = STATE_SEND_DATA;
514
515
            /* frame size between the two sync codes is now known */
516
84.0k
            p_sys->i_last_frame_size = p_sys->i_offset;
517
84.0k
            p_sys->i_buf = p_sys->i_offset;
518
519
            /* clean */
520
84.0k
            block_SkipBytes( &p_sys->bytestream, p_sys->i_offset );
521
84.0k
            block_BytestreamFlush( &p_sys->bytestream );
522
84.0k
            p_sys->i_offset = 0;
523
84.0k
            p_sys->crc = 0;
524
84.0k
            p_sys->i_buf_offset = 0;
525
526
84.0k
            if( block_BytestreamRemaining(&p_sys->bytestream) > 0 || pp_block == NULL /* drain */)
527
84.0k
                p_sys->i_state = STATE_SEND_DATA;
528
0
            else
529
0
                p_sys->i_state = STATE_NOSYNC;
530
84.0k
        }
531
84.0k
        break;
532
533
84.0k
    case STATE_SEND_DATA:
534
84.0k
        p_dec->fmt_out.audio.i_rate = p_sys->headerinfo.i_rate;
535
84.0k
        p_dec->fmt_out.audio.i_channels = p_sys->headerinfo.i_channels;
536
84.0k
        p_dec->fmt_out.audio.i_physical_channels = pi_channels_maps[p_sys->stream_info.channels];
537
538
84.0k
        if( p_sys->bytestream.p_block &&
539
83.9k
            p_sys->bytestream.p_block->i_pts > date_Get( &p_sys->pts ) &&
540
573
            p_sys->bytestream.p_block->i_pts != VLC_TICK_INVALID )
541
573
        {
542
573
            date_Init( &p_sys->pts, p_sys->headerinfo.i_rate, 1 );
543
573
            date_Set( &p_sys->pts, p_sys->bytestream.p_block->i_pts );
544
573
            p_sys->bytestream.p_block->i_pts = VLC_TICK_INVALID;
545
573
        }
546
547
548
84.0k
        out = block_heap_Alloc( p_sys->p_buf, p_sys->i_buf );
549
84.0k
        if( out )
550
84.0k
        {
551
84.0k
            out->i_dts = out->i_pts = date_Get( &p_sys->pts );
552
84.0k
            out->i_flags = p_sys->i_next_block_flags;
553
84.0k
            p_sys->i_next_block_flags = 0;
554
84.0k
        }
555
0
        else
556
0
            p_sys->p_buf = NULL;
557
558
84.0k
        date_Increment( &p_sys->pts, p_sys->headerinfo.i_frame_length );
559
84.0k
        if( out )
560
84.0k
            out->i_length = date_Get( &p_sys->pts ) - out->i_pts;
561
0
        else
562
0
            free( p_sys->p_buf );
563
564
84.0k
        p_sys->i_buf_offset = 0;
565
84.0k
        p_sys->i_buf = 0;
566
84.0k
        p_sys->p_buf = NULL;
567
84.0k
        p_sys->i_offset = 0;
568
84.0k
        p_sys->i_state = STATE_NOSYNC;
569
570
        /* So p_block doesn't get re-added several times */
571
84.0k
        if ( pp_block )
572
83.9k
            *pp_block = block_BytestreamPop(&p_sys->bytestream);
573
574
84.0k
        return out;
575
86.8M
    }
576
577
0
    return NULL;
578
94.1k
}
579
580
static int Open(vlc_object_t *p_this)
581
{
582
    decoder_t *p_dec = (decoder_t*)p_this;
583
    decoder_sys_t *p_sys;
584
585
    if (p_dec->fmt_in->i_codec != VLC_CODEC_FLAC)
586
        return VLC_EGENERIC;
587
588
589
    /* */
590
    p_dec->p_sys = p_sys = malloc(sizeof(*p_sys));
591
    if (!p_sys)
592
        return VLC_ENOMEM;
593
594
    p_sys->i_state       = STATE_NOSYNC;
595
    p_sys->i_offset      = 0;
596
    p_sys->b_stream_info = false;
597
    p_sys->i_last_frame_size = FLAC_FRAME_SIZE_MIN;
598
    p_sys->headerinfo.i_pts  = VLC_TICK_INVALID;
599
    p_sys->i_buf_offset  = 0;
600
    p_sys->i_buf         = 0;
601
    p_sys->p_buf         = NULL;
602
    p_sys->i_next_block_flags = 0;
603
    block_BytestreamInit(&p_sys->bytestream);
604
    date_Init( &p_sys->pts, 1, 1 );
605
606
    /* */
607
    es_format_Copy(&p_dec->fmt_out, p_dec->fmt_in);
608
    p_dec->fmt_out.i_codec = VLC_CODEC_FLAC;
609
    p_dec->fmt_out.b_packetized = true;
610
611
    /* */
612
    p_dec->pf_packetize = Packetize;
613
    p_dec->pf_flush     = Flush;
614
    p_dec->pf_get_cc    = NULL;
615
616
    return VLC_SUCCESS;
617
}
618
619
static void Close(vlc_object_t *p_this)
620
{
621
    decoder_t *p_dec = (decoder_t *)p_this;
622
    decoder_sys_t *p_sys = p_dec->p_sys;
623
624
    block_BytestreamRelease(&p_sys->bytestream);
625
    free(p_sys->p_buf);
626
    free(p_sys);
627
}