add support for serial number in Ogg streams
[platform/upstream/flac.git] / src / libOggFLAC / stream_decoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include <string.h> /* for memset() */
22 #include "ogg/ogg.h"
23 #include "FLAC/assert.h"
24 #include "protected/stream_decoder.h"
25
26 #ifdef min
27 #undef min
28 #endif
29 #define min(x,y) ((x)<(y)?(x):(y))
30
31 /***********************************************************************
32  *
33  * Private class method prototypes
34  *
35  ***********************************************************************/
36
37 static void set_defaults_(OggFLAC__StreamDecoder *decoder);
38 static FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
39 static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data);
40 static void metadata_callback_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
41 static void error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
42
43
44 /***********************************************************************
45  *
46  * Private class data
47  *
48  ***********************************************************************/
49
50 typedef struct OggFLAC__StreamDecoderPrivate {
51         OggFLAC__StreamDecoderReadCallback read_callback;
52         OggFLAC__StreamDecoderWriteCallback write_callback;
53         OggFLAC__StreamDecoderMetadataCallback metadata_callback;
54         OggFLAC__StreamDecoderErrorCallback error_callback;
55         void *client_data;
56         FLAC__StreamDecoder *FLAC_stream_decoder;
57         struct {
58                 ogg_stream_state stream_state;
59                 ogg_sync_state sync_state;
60                 FLAC__bool need_serial_number;
61         } ogg;
62 } OggFLAC__StreamDecoderPrivate;
63
64 /***********************************************************************
65  *
66  * Public static class data
67  *
68  ***********************************************************************/
69
70 const char * const OggFLAC__StreamDecoderStateString[] = {
71         "OggFLAC__STREAM_DECODER_OK",
72         "OggFLAC__STREAM_DECODER_OGG_ERROR",
73         "OggFLAC__STREAM_DECODER_READ_ERROR",
74         "OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR",
75         "OggFLAC__STREAM_DECODER_INVALID_CALLBACK",
76         "OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR",
77         "OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED",
78         "OggFLAC__STREAM_DECODER_UNINITIALIZED"
79 };
80
81
82 /***********************************************************************
83  *
84  * Class constructor/destructor
85  *
86  ***********************************************************************/
87 OggFLAC__StreamDecoder *OggFLAC__stream_decoder_new()
88 {
89         OggFLAC__StreamDecoder *decoder;
90
91         decoder = (OggFLAC__StreamDecoder*)malloc(sizeof(OggFLAC__StreamDecoder));
92         if(decoder == 0) {
93                 return 0;
94         }
95         memset(decoder, 0, sizeof(OggFLAC__StreamDecoder));
96
97         decoder->protected_ = (OggFLAC__StreamDecoderProtected*)malloc(sizeof(OggFLAC__StreamDecoderProtected));
98         if(decoder->protected_ == 0) {
99                 free(decoder);
100                 return 0;
101         }
102         memset(decoder->protected_, 0, sizeof(OggFLAC__StreamDecoderProtected));
103
104         decoder->private_ = (OggFLAC__StreamDecoderPrivate*)malloc(sizeof(OggFLAC__StreamDecoderPrivate));
105         if(decoder->private_ == 0) {
106                 free(decoder->protected_);
107                 free(decoder);
108                 return 0;
109         }
110         memset(decoder->private_, 0, sizeof(OggFLAC__StreamDecoderPrivate));
111
112         decoder->private_->FLAC_stream_decoder = FLAC__stream_decoder_new();
113         if(0 == decoder->private_->FLAC_stream_decoder) {
114                 free(decoder->private_);
115                 free(decoder->protected_);
116                 free(decoder);
117                 return 0;
118         }
119
120         set_defaults_(decoder);
121
122         decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
123
124         return decoder;
125 }
126
127 void OggFLAC__stream_decoder_delete(OggFLAC__StreamDecoder *decoder)
128 {
129         FLAC__ASSERT(0 != decoder);
130         FLAC__ASSERT(0 != decoder->protected_);
131         FLAC__ASSERT(0 != decoder->private_);
132         FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
133
134         OggFLAC__stream_decoder_finish(decoder);
135
136         FLAC__stream_decoder_delete(decoder->private_->FLAC_stream_decoder);
137
138         free(decoder->private_);
139         free(decoder->protected_);
140         free(decoder);
141 }
142
143 /***********************************************************************
144  *
145  * Public class methods
146  *
147  ***********************************************************************/
148
149 OggFLAC__StreamDecoderState OggFLAC__stream_decoder_init(OggFLAC__StreamDecoder *decoder)
150 {
151         FLAC__ASSERT(0 != decoder);
152
153         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
154                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_ALREADY_INITIALIZED;
155
156         if(0 == decoder->private_->read_callback || 0 == decoder->private_->write_callback || 0 == decoder->private_->metadata_callback || 0 == decoder->private_->error_callback)
157                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_INVALID_CALLBACK;
158
159         decoder->private_->ogg.need_serial_number = decoder->protected_->use_first_serial_number;
160         /* we will determine the serial number later if necessary */
161         if(ogg_stream_init(&decoder->private_->ogg.stream_state, decoder->protected_->serial_number) != 0)
162                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
163
164         if(ogg_sync_init(&decoder->private_->ogg.sync_state) != 0)
165                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_OGG_ERROR;
166
167         FLAC__stream_decoder_set_read_callback(decoder->private_->FLAC_stream_decoder, read_callback_);
168         FLAC__stream_decoder_set_write_callback(decoder->private_->FLAC_stream_decoder, write_callback_);
169         FLAC__stream_decoder_set_metadata_callback(decoder->private_->FLAC_stream_decoder, metadata_callback_);
170         FLAC__stream_decoder_set_error_callback(decoder->private_->FLAC_stream_decoder, error_callback_);
171         FLAC__stream_decoder_set_client_data(decoder->private_->FLAC_stream_decoder, decoder);
172
173         if(FLAC__stream_decoder_init(decoder->private_->FLAC_stream_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
174                 return decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
175
176         return decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
177 }
178
179 void OggFLAC__stream_decoder_finish(OggFLAC__StreamDecoder *decoder)
180 {
181         FLAC__ASSERT(0 != decoder);
182         FLAC__ASSERT(0 != decoder->private_);
183         FLAC__ASSERT(0 != decoder->protected_);
184
185         if(decoder->protected_->state == OggFLAC__STREAM_DECODER_UNINITIALIZED)
186                 return;
187
188         FLAC__ASSERT(0 != decoder->private_->FLAC_stream_decoder);
189
190         FLAC__stream_decoder_finish(decoder->private_->FLAC_stream_decoder);
191
192         (void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
193         (void)ogg_stream_clear(&decoder->private_->ogg.stream_state);
194
195         set_defaults_(decoder);
196
197         decoder->protected_->state = OggFLAC__STREAM_DECODER_UNINITIALIZED;
198 }
199
200 FLAC__bool OggFLAC__stream_decoder_set_read_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderReadCallback value)
201 {
202         FLAC__ASSERT(0 != decoder);
203         FLAC__ASSERT(0 != decoder->private_);
204         FLAC__ASSERT(0 != decoder->protected_);
205         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
206                 return false;
207         decoder->private_->read_callback = value;
208         return true;
209 }
210
211 FLAC__bool OggFLAC__stream_decoder_set_write_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderWriteCallback value)
212 {
213         FLAC__ASSERT(0 != decoder);
214         FLAC__ASSERT(0 != decoder->private_);
215         FLAC__ASSERT(0 != decoder->protected_);
216         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
217                 return false;
218         decoder->private_->write_callback = value;
219         return true;
220 }
221
222 FLAC__bool OggFLAC__stream_decoder_set_metadata_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderMetadataCallback value)
223 {
224         FLAC__ASSERT(0 != decoder);
225         FLAC__ASSERT(0 != decoder->private_);
226         FLAC__ASSERT(0 != decoder->protected_);
227         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
228                 return false;
229         decoder->private_->metadata_callback = value;
230         return true;
231 }
232
233 FLAC__bool OggFLAC__stream_decoder_set_error_callback(OggFLAC__StreamDecoder *decoder, OggFLAC__StreamDecoderErrorCallback value)
234 {
235         FLAC__ASSERT(0 != decoder);
236         FLAC__ASSERT(0 != decoder->private_);
237         FLAC__ASSERT(0 != decoder->protected_);
238         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
239                 return false;
240         decoder->private_->error_callback = value;
241         return true;
242 }
243
244 FLAC__bool OggFLAC__stream_decoder_set_client_data(OggFLAC__StreamDecoder *decoder, void *value)
245 {
246         FLAC__ASSERT(0 != decoder);
247         FLAC__ASSERT(0 != decoder->private_);
248         FLAC__ASSERT(0 != decoder->protected_);
249         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
250                 return false;
251         decoder->private_->client_data = value;
252         return true;
253 }
254
255 FLAC__bool OggFLAC__stream_decoder_set_serial_number(OggFLAC__StreamDecoder *decoder, long value)
256 {
257         FLAC__ASSERT(0 != decoder);
258         FLAC__ASSERT(0 != decoder->private_);
259         FLAC__ASSERT(0 != decoder->protected_);
260         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
261                 return false;
262         decoder->protected_->use_first_serial_number = false;
263         decoder->protected_->serial_number = value;
264         return true;
265 }
266
267 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
268 {
269         FLAC__ASSERT(0 != decoder);
270         FLAC__ASSERT(0 != decoder->private_);
271         FLAC__ASSERT(0 != decoder->protected_);
272         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
273                 return false;
274         return FLAC__stream_decoder_set_metadata_respond(decoder->private_->FLAC_stream_decoder, type);
275 }
276
277 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
278 {
279         FLAC__ASSERT(0 != decoder);
280         FLAC__ASSERT(0 != decoder->private_);
281         FLAC__ASSERT(0 != decoder->protected_);
282         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
283                 return false;
284         return FLAC__stream_decoder_set_metadata_respond_application(decoder->private_->FLAC_stream_decoder, id);
285 }
286
287 FLAC__bool OggFLAC__stream_decoder_set_metadata_respond_all(OggFLAC__StreamDecoder *decoder)
288 {
289         FLAC__ASSERT(0 != decoder);
290         FLAC__ASSERT(0 != decoder->private_);
291         FLAC__ASSERT(0 != decoder->protected_);
292         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
293                 return false;
294         return FLAC__stream_decoder_set_metadata_respond_all(decoder->private_->FLAC_stream_decoder);
295 }
296
297 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore(OggFLAC__StreamDecoder *decoder, FLAC__MetadataType type)
298 {
299         FLAC__ASSERT(0 != decoder);
300         FLAC__ASSERT(0 != decoder->private_);
301         FLAC__ASSERT(0 != decoder->protected_);
302         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
303                 return false;
304         return FLAC__stream_decoder_set_metadata_ignore(decoder->private_->FLAC_stream_decoder, type);
305 }
306
307 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_application(OggFLAC__StreamDecoder *decoder, const FLAC__byte id[4])
308 {
309         FLAC__ASSERT(0 != decoder);
310         FLAC__ASSERT(0 != decoder->private_);
311         FLAC__ASSERT(0 != decoder->protected_);
312         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
313                 return false;
314         return FLAC__stream_decoder_set_metadata_ignore_application(decoder->private_->FLAC_stream_decoder, id);
315 }
316
317 FLAC__bool OggFLAC__stream_decoder_set_metadata_ignore_all(OggFLAC__StreamDecoder *decoder)
318 {
319         FLAC__ASSERT(0 != decoder);
320         FLAC__ASSERT(0 != decoder->private_);
321         FLAC__ASSERT(0 != decoder->protected_);
322         if(decoder->protected_->state != OggFLAC__STREAM_DECODER_UNINITIALIZED)
323                 return false;
324         return FLAC__stream_decoder_set_metadata_ignore_all(decoder->private_->FLAC_stream_decoder);
325 }
326
327 OggFLAC__StreamDecoderState OggFLAC__stream_decoder_get_state(const OggFLAC__StreamDecoder *decoder)
328 {
329         FLAC__ASSERT(0 != decoder);
330         FLAC__ASSERT(0 != decoder->protected_);
331         return decoder->protected_->state;
332 }
333
334 FLAC__StreamDecoderState OggFLAC__stream_decoder_get_FLAC_stream_decoder_state(const OggFLAC__StreamDecoder *decoder)
335 {
336         FLAC__ASSERT(0 != decoder);
337         FLAC__ASSERT(0 != decoder->private_);
338         return FLAC__stream_decoder_get_state(decoder->private_->FLAC_stream_decoder);
339 }
340
341 unsigned OggFLAC__stream_decoder_get_channels(const OggFLAC__StreamDecoder *decoder)
342 {
343         FLAC__ASSERT(0 != decoder);
344         FLAC__ASSERT(0 != decoder->private_);
345         return FLAC__stream_decoder_get_channels(decoder->private_->FLAC_stream_decoder);
346 }
347
348 FLAC__ChannelAssignment OggFLAC__stream_decoder_get_channel_assignment(const OggFLAC__StreamDecoder *decoder)
349 {
350         FLAC__ASSERT(0 != decoder);
351         FLAC__ASSERT(0 != decoder->private_);
352         return FLAC__stream_decoder_get_channel_assignment(decoder->private_->FLAC_stream_decoder);
353 }
354
355 unsigned OggFLAC__stream_decoder_get_bits_per_sample(const OggFLAC__StreamDecoder *decoder)
356 {
357         FLAC__ASSERT(0 != decoder);
358         FLAC__ASSERT(0 != decoder->private_);
359         return FLAC__stream_decoder_get_bits_per_sample(decoder->private_->FLAC_stream_decoder);
360 }
361
362 unsigned OggFLAC__stream_decoder_get_sample_rate(const OggFLAC__StreamDecoder *decoder)
363 {
364         FLAC__ASSERT(0 != decoder);
365         FLAC__ASSERT(0 != decoder->private_);
366         return FLAC__stream_decoder_get_sample_rate(decoder->private_->FLAC_stream_decoder);
367 }
368
369 unsigned OggFLAC__stream_decoder_get_blocksize(const OggFLAC__StreamDecoder *decoder)
370 {
371         FLAC__ASSERT(0 != decoder);
372         FLAC__ASSERT(0 != decoder->private_);
373         return FLAC__stream_decoder_get_blocksize(decoder->private_->FLAC_stream_decoder);
374 }
375
376 FLAC__bool OggFLAC__stream_decoder_flush(OggFLAC__StreamDecoder *decoder)
377 {
378         FLAC__ASSERT(0 != decoder);
379         FLAC__ASSERT(0 != decoder->private_);
380         FLAC__ASSERT(0 != decoder->protected_);
381
382         (void)ogg_sync_clear(&decoder->private_->ogg.sync_state);
383
384         if(!FLAC__stream_decoder_flush(decoder->private_->FLAC_stream_decoder)) {
385                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
386                 return false;
387         }
388
389         decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
390
391         return true;
392 }
393
394 FLAC__bool OggFLAC__stream_decoder_reset(OggFLAC__StreamDecoder *decoder)
395 {
396         FLAC__ASSERT(0 != decoder);
397         FLAC__ASSERT(0 != decoder->private_);
398         FLAC__ASSERT(0 != decoder->protected_);
399
400         if(!OggFLAC__stream_decoder_flush(decoder)) {
401                 decoder->protected_->state = OggFLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
402                 return false;
403         }
404
405         if(!FLAC__stream_decoder_reset(decoder->private_->FLAC_stream_decoder)) {
406                 decoder->protected_->state = OggFLAC__STREAM_DECODER_FLAC_STREAM_DECODER_ERROR;
407                 return false;
408         }
409
410         decoder->protected_->state = OggFLAC__STREAM_DECODER_OK;
411
412         return true;
413 }
414
415 FLAC__bool OggFLAC__stream_decoder_process_single(OggFLAC__StreamDecoder *decoder)
416 {
417         FLAC__ASSERT(0 != decoder);
418         FLAC__ASSERT(0 != decoder->private_);
419         return FLAC__stream_decoder_process_single(decoder->private_->FLAC_stream_decoder);
420 }
421
422 FLAC__bool OggFLAC__stream_decoder_process_until_end_of_metadata(OggFLAC__StreamDecoder *decoder)
423 {
424         FLAC__ASSERT(0 != decoder);
425         FLAC__ASSERT(0 != decoder->private_);
426         return FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->FLAC_stream_decoder);
427 }
428
429 FLAC__bool OggFLAC__stream_decoder_process_until_end_of_stream(OggFLAC__StreamDecoder *decoder)
430 {
431         FLAC__ASSERT(0 != decoder);
432         FLAC__ASSERT(0 != decoder->private_);
433         return FLAC__stream_decoder_process_until_end_of_stream(decoder->private_->FLAC_stream_decoder);
434 }
435
436
437 /***********************************************************************
438  *
439  * Private class methods
440  *
441  ***********************************************************************/
442
443 void set_defaults_(OggFLAC__StreamDecoder *decoder)
444 {
445         decoder->private_->read_callback = 0;
446         decoder->private_->write_callback = 0;
447         decoder->private_->metadata_callback = 0;
448         decoder->private_->error_callback = 0;
449         decoder->private_->client_data = 0;
450         decoder->protected_->use_first_serial_number = true;
451 }
452
453 FLAC__StreamDecoderReadStatus read_callback_(const FLAC__StreamDecoder *unused, FLAC__byte buffer[], unsigned *bytes, void *client_data)
454 {
455         static const unsigned OGG_BYTES_CHUNK = 8192;
456         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
457         unsigned ogg_bytes_to_read, ogg_bytes_read;
458         ogg_page page;
459         char *oggbuf;
460
461         (void)unused;
462
463         /*
464          * We have to be careful not to read in more than the
465          * FLAC__StreamDecoder says it has room for.  We know
466          * that the size of the decoded data must be no more
467          * than the encoded data we will read.
468          */
469         ogg_bytes_to_read = min(*bytes, OGG_BYTES_CHUNK);
470         oggbuf = ogg_sync_buffer(&decoder->private_->ogg.sync_state, ogg_bytes_to_read);
471
472         if(decoder->private_->read_callback(decoder, oggbuf, &ogg_bytes_to_read, decoder->private_->client_data) != FLAC__STREAM_DECODER_READ_STATUS_CONTINUE) {
473                 decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
474                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
475         }
476         ogg_bytes_read = ogg_bytes_to_read;
477
478         if(ogg_sync_wrote(&decoder->private_->ogg.sync_state, ogg_bytes_read) < 0) {
479                 decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
480                 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
481         }
482
483         *bytes = 0;
484         while(ogg_sync_pageout(&decoder->private_->ogg.sync_state, &page) == 1) {
485                 /* grab the serial number if necessary */
486                 if(decoder->private_->ogg.need_serial_number) {
487                         decoder->private_->ogg.stream_state.serialno = decoder->protected_->serial_number = ogg_page_serialno(&page);
488                         decoder->private_->ogg.need_serial_number = false;
489                 }
490                 if(ogg_stream_pagein(&decoder->private_->ogg.stream_state, &page) == 0) {
491                         ogg_packet packet;
492
493                         while(ogg_stream_packetout(&decoder->private_->ogg.stream_state, &packet) == 1) {
494                                 memcpy(buffer, packet.packet, packet.bytes);
495                                 *bytes += packet.bytes;
496                                 buffer += packet.bytes;
497                         }
498                 } else {
499                         decoder->protected_->state = OggFLAC__STREAM_DECODER_READ_ERROR;
500                         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
501                 }
502         }
503
504         return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
505 }
506
507 FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__StreamDecoder *unused, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
508 {
509         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
510         (void)unused;
511         return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data);
512 }
513
514 void metadata_callback_(const FLAC__StreamDecoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
515 {
516         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
517         (void)unused;
518         decoder->private_->metadata_callback(decoder, metadata, decoder->private_->client_data);
519 }
520
521 void error_callback_(const FLAC__StreamDecoder *unused, FLAC__StreamDecoderErrorStatus status, void *client_data)
522 {
523         OggFLAC__StreamDecoder *decoder = (OggFLAC__StreamDecoder*)client_data;
524         (void)unused;
525         decoder->private_->error_callback(decoder, status, decoder->private_->client_data);
526 }