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