]> git.sesse.net Git - vlc/blob - modules/packetizer/flac.c
flac packetizer: verbose error message
[vlc] / modules / packetizer / flac.c
1 /*****************************************************************************
2  * flac.c: flac packetizer module.
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *          Sigmund Augdal Helberg <dnumgis@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36
37 #include <vlc_block_helper.h>
38 #include <vlc_bits.h>
39 #include "packetizer_helper.h"
40
41 /*****************************************************************************
42  * Module descriptor
43  *****************************************************************************/
44 static int  Open (vlc_object_t *);
45 static void Close(vlc_object_t *);
46
47 vlc_module_begin()
48     set_category(CAT_SOUT)
49     set_subcategory(SUBCAT_SOUT_PACKETIZER)
50     set_description(N_("Flac audio packetizer"))
51     set_capability("packetizer", 50)
52     set_callbacks(Open, Close)
53 vlc_module_end()
54
55 /*****************************************************************************
56  * decoder_sys_t : FLAC decoder descriptor
57  *****************************************************************************/
58 #define MAX_FLAC_HEADER_SIZE 16
59 struct decoder_sys_t
60 {
61     /*
62      * Input properties
63      */
64     int i_state;
65
66     block_bytestream_t bytestream;
67
68     /*
69      * FLAC properties
70      */
71     struct
72     {
73         unsigned min_blocksize, max_blocksize;
74         unsigned min_framesize, max_framesize;
75         unsigned sample_rate;
76         unsigned channels;
77         unsigned bits_per_sample;
78
79     } stream_info;
80     bool b_stream_info;
81
82     /*
83      * Common properties
84      */
85     date_t  end_date;
86     mtime_t i_pts;
87
88     int i_frame_length;
89     size_t i_frame_size;
90     unsigned int i_rate, i_channels, i_bits_per_sample;
91 };
92
93 static const int pi_channels_maps[9] =
94 {
95     0,
96     AOUT_CHAN_CENTER,
97     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
98     AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
99     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
100      | AOUT_CHAN_REARRIGHT,
101     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
102      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
103     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
104      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
105     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
106      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT
107      | AOUT_CHAN_MIDDLERIGHT,
108     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT
109      | AOUT_CHAN_REARRIGHT | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT
110      | AOUT_CHAN_LFE
111 };
112
113
114 /*****************************************************************************
115  * ProcessHeader: process Flac header.
116  *****************************************************************************/
117 static void ProcessHeader(decoder_t *p_dec)
118 {
119     decoder_sys_t *p_sys = p_dec->p_sys;
120
121     bs_t bs;
122     int i_extra = p_dec->fmt_in.i_extra;
123     char *p_extra = p_dec->fmt_in.p_extra;
124
125     if (i_extra > 8 && !memcmp(p_extra, "fLaC", 4)) {
126         i_extra -= 8;
127         p_extra += 8;
128     }
129
130     if (p_dec->fmt_in.i_extra < 14)
131         return;
132
133     bs_init(&bs, p_extra, i_extra);
134
135     p_sys->stream_info.min_blocksize = bs_read(&bs, 16);
136     p_sys->stream_info.max_blocksize = bs_read(&bs, 16);
137
138     p_sys->stream_info.min_framesize = bs_read(&bs, 24);
139     p_sys->stream_info.max_framesize = bs_read(&bs, 24);
140
141     p_sys->stream_info.sample_rate = bs_read(&bs, 20);
142     p_sys->stream_info.channels = bs_read(&bs, 3) + 1;
143     p_sys->stream_info.bits_per_sample = bs_read(&bs, 5) + 1;
144
145     p_sys->b_stream_info = true;
146
147     p_dec->fmt_out.i_extra = i_extra;
148     free(p_dec->fmt_out.p_extra);
149     p_dec->fmt_out.p_extra = malloc(i_extra);
150     if (p_dec->fmt_out.p_extra)
151         memcpy(p_dec->fmt_out.p_extra, p_extra, i_extra);
152     else
153         p_dec->fmt_out.i_extra = 0;
154 }
155
156 /* Will return 0xffffffffffffffff for an invalid utf-8 sequence */
157 static uint64_t read_utf8(const uint8_t *p_buf, int *pi_read)
158 {
159     uint64_t i_result = 0;
160     unsigned i;
161
162     if (!(p_buf[0] & 0x80)) { /* 0xxxxxxx */
163         i_result = p_buf[0];
164         i = 0;
165     } else if (p_buf[0] & 0xC0 && !(p_buf[0] & 0x20)) { /* 110xxxxx */
166         i_result = p_buf[0] & 0x1F;
167         i = 1;
168     } else if (p_buf[0] & 0xE0 && !(p_buf[0] & 0x10)) { /* 1110xxxx */
169         i_result = p_buf[0] & 0x0F;
170         i = 2;
171     } else if (p_buf[0] & 0xF0 && !(p_buf[0] & 0x08)) { /* 11110xxx */
172         i_result = p_buf[0] & 0x07;
173         i = 3;
174     } else if (p_buf[0] & 0xF8 && !(p_buf[0] & 0x04)) { /* 111110xx */
175         i_result = p_buf[0] & 0x03;
176         i = 4;
177     } else if (p_buf[0] & 0xFC && !(p_buf[0] & 0x02)) { /* 1111110x */
178         i_result = p_buf[0] & 0x01;
179         i = 5;
180     } else if (p_buf[0] & 0xFE && !(p_buf[0] & 0x01)) { /* 11111110 */
181         i_result = 0;
182         i = 6;
183     } else {
184         return INT64_C(0xffffffffffffffff);
185     }
186
187     for (unsigned j = 1; j <= i; j++) {
188         if (!(p_buf[j] & 0x80) || (p_buf[j] & 0x40)) { /* 10xxxxxx */
189             return INT64_C(0xffffffffffffffff);
190         }
191         i_result <<= 6;
192         i_result |= (p_buf[j] & 0x3F);
193     }
194
195     *pi_read = i;
196     return i_result;
197 }
198
199 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
200 static const uint8_t flac_crc8_table[256] = {
201         0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
202         0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
203         0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
204         0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
205         0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
206         0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
207         0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
208         0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
209         0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
210         0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
211         0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
212         0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
213         0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
214         0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
215         0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
216         0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
217         0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
218         0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
219         0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
220         0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
221         0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
222         0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
223         0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
224         0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
225         0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
226         0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
227         0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
228         0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
229         0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
230         0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
231         0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
232         0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
233 };
234
235 static uint8_t flac_crc8(const uint8_t *data, unsigned len)
236 {
237     uint8_t crc = 0;
238
239     while (len--)
240         crc = flac_crc8_table[crc ^ *data++];
241
242     return crc;
243 }
244
245 /*****************************************************************************
246  * SyncInfo: parse FLAC sync info
247  *****************************************************************************/
248 static int SyncInfo(decoder_t *p_dec, uint8_t *p_buf,
249                      unsigned int * pi_channels,
250                      unsigned int * pi_sample_rate,
251                      unsigned int * pi_bits_per_sample)
252 {
253     decoder_sys_t *p_sys = p_dec->p_sys;
254
255     /* Check syncword */
256     if (p_buf[0] != 0xFF || (p_buf[1] & 0xFE) != 0xF8)
257         return 0;
258
259     /* Check there is no emulated sync code in the rest of the header */
260     if (p_buf[2] == 0xff || p_buf[3] == 0xFF)
261         return 0;
262
263     /* Find blocksize (framelength) */
264     int blocksize_hint = 0;
265     unsigned blocksize = p_buf[2] >> 4;
266     if (blocksize >= 8) {
267         blocksize = 256 << (blocksize - 8);
268     } else if (blocksize == 0) { /* value 0 is reserved */
269         if (p_sys->b_stream_info &&
270             p_sys->stream_info.min_blocksize == p_sys->stream_info.max_blocksize)
271             blocksize = p_sys->stream_info.min_blocksize;
272         else
273             return 0; /* We can't do anything with this */
274     } else if (blocksize == 1) {
275         blocksize = 192;
276     } else if (blocksize == 6 || blocksize == 7) {
277         blocksize_hint = blocksize;
278         blocksize = 0;
279     } else /* 2, 3, 4, 5 */ {
280         blocksize = 576 << (blocksize - 2);
281     }
282
283     if (p_sys->b_stream_info)
284         if (blocksize < p_sys->stream_info.min_blocksize ||
285             blocksize > p_sys->stream_info.max_blocksize)
286             return 0;
287
288     /* Find samplerate */
289     int samplerate_hint = p_buf[2] & 0xf;;
290     unsigned int samplerate;
291     if (samplerate_hint == 0) {
292         if (p_sys->b_stream_info)
293             samplerate = p_sys->stream_info.sample_rate;
294         else
295             return 0; /* We can't do anything with this */
296     } else if (samplerate_hint == 15) {
297         return 0; /* invalid */
298     } else if (samplerate_hint < 12) {
299         static const int16_t flac_samplerate[12] = {
300             0,    8820, 17640, 19200,
301             800,  1600, 2205,  2400,
302             3200, 4410, 4800,  9600, 
303         };
304         samplerate = flac_samplerate[samplerate_hint] * 10;
305     } else {
306         samplerate = 0; /* at end of header */
307     }
308
309     /* Find channels */
310     unsigned channels = p_buf[3] >> 4;
311     if (channels >= 8) {
312         if (channels >= 11) /* reserved */
313             return 0;
314         channels = 2;
315     } else
316         channels++;
317
318
319     /* Find bits per sample */
320     static const int8_t flac_bits_per_sample[8] = {
321         0, 8, 12, -1, 16, 20, 24, -1
322     };
323     int bits_per_sample = flac_bits_per_sample[(p_buf[3] & 0x0e) >> 1];
324     if (bits_per_sample == 0) {
325         if (p_sys->b_stream_info)
326             bits_per_sample = p_sys->stream_info.bits_per_sample;
327         else
328             return 0;
329     } else if (bits_per_sample < 0)
330         return 0;
331
332
333     /* reserved for future use */
334     if (p_buf[3] & 0x01)
335         return 0;
336
337     /* End of fixed size header */
338     int i_header = 4;
339
340     /* Check Sample/Frame number */
341     int i_read;
342     if (read_utf8(&p_buf[i_header++], &i_read) == INT64_C(0xffffffffffffffff))
343         return 0;
344
345     i_header += i_read;
346
347     /* Read blocksize */
348     if (blocksize_hint) {
349         blocksize = p_buf[i_header++];
350         if (blocksize_hint == 7) {
351             blocksize <<= 8;
352             blocksize |= p_buf[i_header++];
353         }
354         blocksize++;
355     }
356
357     /* Read sample rate */
358     if (samplerate == 0) {
359         samplerate = p_buf[i_header++];
360         if (samplerate_hint != 12) { /* 16 bits */
361             samplerate <<= 8;
362             samplerate |= p_buf[i_header++];
363         }
364
365         if (samplerate_hint == 12)
366             samplerate *= 1000;
367         else if (samplerate_hint == 14)
368             samplerate *= 10;
369     }
370
371     /* Check the CRC-8 byte */
372     if (flac_crc8(p_buf, i_header) != p_buf[i_header])
373         return 0;
374
375     /* Sanity check using stream info header when possible */
376     if (p_sys->b_stream_info) {
377         if (blocksize < p_sys->stream_info.min_blocksize ||
378             blocksize > p_sys->stream_info.max_blocksize)
379             return 0;
380         if ((unsigned)bits_per_sample != p_sys->stream_info.bits_per_sample)
381             return 0;
382         if (samplerate != p_sys->stream_info.sample_rate)
383             return 0;
384     }
385
386     *pi_bits_per_sample = bits_per_sample;
387     *pi_sample_rate = samplerate;
388     *pi_channels = channels;
389
390     return blocksize;
391 }
392
393 /* */
394 static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
395 {
396     decoder_sys_t *p_sys = p_dec->p_sys;
397     uint8_t p_header[MAX_FLAC_HEADER_SIZE];
398     block_t *out;
399
400     if (!pp_block || !*pp_block)
401         return NULL;
402
403     block_t *in = *pp_block;
404
405     if (in->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
406         if (in->i_flags&BLOCK_FLAG_CORRUPTED) {
407             p_sys->i_state = STATE_NOSYNC;
408             block_BytestreamEmpty(&p_sys->bytestream);
409         }
410         date_Set(&p_sys->end_date, 0);
411         block_Release(*pp_block);
412         return NULL;
413     }
414
415     if (!p_sys->b_stream_info)
416         ProcessHeader(p_dec);
417
418     if (p_sys->stream_info.channels > 8) {
419         msg_Err(p_dec, "This stream uses too many audio channels (%d > 8)",
420             p_sys->stream_info.channels);
421         return NULL;
422     }
423
424     if (!date_Get(&p_sys->end_date) && in->i_pts <= VLC_TS_INVALID) {
425         /* We've just started the stream, wait for the first PTS. */
426         block_Release(in);
427         return NULL;
428     } else if (!date_Get(&p_sys->end_date)) {
429         /* The first PTS is as good as anything else. */
430         p_sys->i_rate = p_dec->fmt_out.audio.i_rate;
431         date_Init(&p_sys->end_date, p_sys->i_rate, 1);
432         date_Set(&p_sys->end_date, in->i_pts);
433     }
434
435     block_BytestreamPush(&p_sys->bytestream, in);
436
437     while (1) {
438         switch (p_sys->i_state) {
439         case STATE_NOSYNC:
440             while (block_PeekBytes(&p_sys->bytestream, p_header, 2)
441                    == VLC_SUCCESS) {
442                 if (p_header[0] == 0xFF && (p_header[1] & 0xFE) == 0xF8) {
443                     p_sys->i_state = STATE_SYNC;
444                     break;
445                 }
446                 block_SkipByte(&p_sys->bytestream);
447             }
448             if (p_sys->i_state != STATE_SYNC) {
449                 block_BytestreamFlush(&p_sys->bytestream);
450                 return NULL; /* Need more data */
451             }
452
453         case STATE_SYNC:
454             /* New frame, set the Presentation Time Stamp */
455             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
456             if (p_sys->i_pts > VLC_TS_INVALID &&
457                 p_sys->i_pts != date_Get(&p_sys->end_date))
458                 date_Set(&p_sys->end_date, p_sys->i_pts);
459             p_sys->i_state = STATE_HEADER;
460
461         case STATE_HEADER:
462             /* Get FLAC frame header (MAX_FLAC_HEADER_SIZE bytes) */
463             if (block_PeekBytes(&p_sys->bytestream, p_header,
464                                  MAX_FLAC_HEADER_SIZE) != VLC_SUCCESS)
465                 return NULL; /* Need more data */
466
467             /* Check if frame is valid and get frame info */
468             p_sys->i_frame_length = SyncInfo(p_dec, p_header,
469                                               &p_sys->i_channels,
470                                               &p_sys->i_rate,
471                                               &p_sys->i_bits_per_sample);
472             if (!p_sys->i_frame_length) {
473                 msg_Dbg(p_dec, "emulated sync word");
474                 block_SkipByte(&p_sys->bytestream);
475                 p_sys->i_state = STATE_NOSYNC;
476                 break;
477             }
478             if (p_sys->i_rate != p_dec->fmt_out.audio.i_rate) {
479                 p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
480                 const mtime_t i_end_date = date_Get(&p_sys->end_date);
481                 date_Init(&p_sys->end_date, p_sys->i_rate, 1);
482                 date_Set(&p_sys->end_date, i_end_date);
483             }
484             p_sys->i_state = STATE_NEXT_SYNC;
485             p_sys->i_frame_size = p_sys->b_stream_info && p_sys->stream_info.min_framesize > 0 ?
486                                                             p_sys->stream_info.min_framesize : 1;
487
488         case STATE_NEXT_SYNC:
489             /* TODO: If pp_block == NULL, flush the buffer without checking the
490              * next sync word */
491
492             /* Check if next expected frame contains the sync word */
493             while (block_PeekOffsetBytes(&p_sys->bytestream,
494                                           p_sys->i_frame_size, p_header,
495                                           MAX_FLAC_HEADER_SIZE)
496                    == VLC_SUCCESS) {
497                 if (p_header[0] == 0xFF && (p_header[1] & 0xFE) == 0xF8) {
498                     /* Check if frame is valid and get frame info */
499                     int i_frame_length =
500                         SyncInfo(p_dec, p_header,
501                                   &p_sys->i_channels,
502                                   &p_sys->i_rate,
503                                   &p_sys->i_bits_per_sample);
504
505                     if (i_frame_length) {
506                         p_sys->i_state = STATE_SEND_DATA;
507                         break;
508                     }
509                 }
510                 p_sys->i_frame_size++;
511             }
512
513             if (p_sys->i_state != STATE_SEND_DATA) {
514                 if (p_sys->b_stream_info && p_sys->stream_info.max_framesize > 0 &&
515                     p_sys->i_frame_size > p_sys->stream_info.max_framesize) {
516                     block_SkipByte(&p_sys->bytestream);
517                     p_sys->i_state = STATE_NOSYNC;
518                     return NULL;
519                 }
520                 /* Need more data */
521                 return NULL;
522             }
523
524         case STATE_SEND_DATA:
525             out = block_Alloc(p_sys->i_frame_size);
526
527             /* Copy the whole frame into the buffer. When we reach this point
528              * we already know we have enough data available. */
529             block_GetBytes(&p_sys->bytestream, out->p_buffer,
530                             p_sys->i_frame_size);
531
532             /* Make sure we don't reuse the same pts twice */
533             if (p_sys->i_pts == p_sys->bytestream.p_block->i_pts)
534                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
535
536             p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
537             p_dec->fmt_out.audio.i_physical_channels =
538                 p_dec->fmt_out.audio.i_original_channels =
539                     pi_channels_maps[p_sys->stream_info.channels];
540
541             /* So p_block doesn't get re-added several times */
542             *pp_block = block_BytestreamPop(&p_sys->bytestream);
543
544             p_sys->i_state = STATE_NOSYNC;
545
546             /* Date management */
547             out->i_pts =
548                 out->i_dts = date_Get(&p_sys->end_date);
549             date_Increment(&p_sys->end_date, p_sys->i_frame_length);
550             out->i_length =
551                 date_Get(&p_sys->end_date) - out->i_pts;
552
553             return out;
554         }
555     }
556
557     return NULL;
558 }
559
560 static int Open(vlc_object_t *p_this)
561 {
562     decoder_t *p_dec = (decoder_t*)p_this;
563     decoder_sys_t *p_sys;
564
565     if (p_dec->fmt_in.i_codec != VLC_CODEC_FLAC)
566         return VLC_EGENERIC;
567
568     /* */
569     p_dec->p_sys = p_sys = malloc(sizeof(*p_sys));
570     if (!p_sys)
571         return VLC_ENOMEM;
572
573     date_Set(&p_sys->end_date, 0);
574     p_sys->i_state       = STATE_NOSYNC;
575     p_sys->b_stream_info = false;
576     p_sys->i_pts         = VLC_TS_INVALID;
577     block_BytestreamInit(&p_sys->bytestream);
578
579     /* */
580     es_format_Copy(&p_dec->fmt_out, &p_dec->fmt_in);
581     p_dec->fmt_out.i_cat   = AUDIO_ES;
582     p_dec->fmt_out.i_codec = VLC_CODEC_FLAC;
583
584     /* */
585     p_dec->pf_decode_audio = NULL;
586     p_dec->pf_packetize    = Packetize;
587
588     return VLC_SUCCESS;
589 }
590
591 static void Close(vlc_object_t *p_this)
592 {
593     decoder_t *p_dec = (decoder_t *)p_this;
594     decoder_sys_t *p_sys = p_dec->p_sys;
595
596     block_BytestreamRelease(&p_sys->bytestream);
597     free(p_sys);
598 }