1 | --- src/inputPlugins/_flac_common.h.orig 2007-04-02 11:51:57.000000000 +0200 |
---|
2 | +++ src/inputPlugins/_flac_common.h 2007-04-02 11:52:10.000000000 +0200 |
---|
3 | @@ -30,7 +30,116 @@ |
---|
4 | #include "../inputStream.h" |
---|
5 | #include "../outputBuffer.h" |
---|
6 | #include "../decode.h" |
---|
7 | -#include <FLAC/seekable_stream_decoder.h> |
---|
8 | +#include <FLAC/export.h> |
---|
9 | +#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 |
---|
10 | +# include <FLAC/seekable_stream_decoder.h> |
---|
11 | +# define flac_decoder FLAC__SeekableStreamDecoder |
---|
12 | +# define flac_new() FLAC__seekable_stream_decoder_new() |
---|
13 | + |
---|
14 | +# define flac_ogg_init(a,b,c,d,e,f,g,h,i,j) (0) |
---|
15 | + |
---|
16 | +# define flac_get_decode_position(x,y) \ |
---|
17 | + FLAC__seekable_stream_decoder_get_decode_position(x,y) |
---|
18 | +# define flac_get_state(x) FLAC__seekable_stream_decoder_get_state(x) |
---|
19 | +# define flac_process_single(x) FLAC__seekable_stream_decoder_process_single(x) |
---|
20 | +# define flac_process_metadata(x) \ |
---|
21 | + FLAC__seekable_stream_decoder_process_until_end_of_metadata(x) |
---|
22 | +# define flac_seek_absolute(x,y) \ |
---|
23 | + FLAC__seekable_stream_decoder_seek_absolute(x,y) |
---|
24 | +# define flac_finish(x) FLAC__seekable_stream_decoder_finish(x) |
---|
25 | +# define flac_delete(x) FLAC__seekable_stream_decoder_delete(x) |
---|
26 | + |
---|
27 | +# define flac_decoder_eof FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM |
---|
28 | + |
---|
29 | +typedef unsigned flac_read_status_size_t; |
---|
30 | +# define flac_read_status FLAC__SeekableStreamDecoderReadStatus |
---|
31 | +# define flac_read_status_continue \ |
---|
32 | + FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK |
---|
33 | +# define flac_read_status_eof FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK |
---|
34 | +# define flac_read_status_abort \ |
---|
35 | + FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR |
---|
36 | + |
---|
37 | +# define flac_seek_status FLAC__SeekableStreamDecoderSeekStatus |
---|
38 | +# define flac_seek_status_ok FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK |
---|
39 | +# define flac_seek_status_error FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR |
---|
40 | + |
---|
41 | +# define flac_tell_status FLAC__SeekableStreamDecoderTellStatus |
---|
42 | +# define flac_tell_status_ok FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK |
---|
43 | +# define flac_tell_status_error \ |
---|
44 | + FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR |
---|
45 | +# define flac_tell_status_unsupported \ |
---|
46 | + FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR |
---|
47 | + |
---|
48 | +# define flac_length_status FLAC__SeekableStreamDecoderLengthStatus |
---|
49 | +# define flac_length_status_ok FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK |
---|
50 | +# define flac_length_status_error \ |
---|
51 | + FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR |
---|
52 | +# define flac_length_status_unsupported \ |
---|
53 | + FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR |
---|
54 | + |
---|
55 | +# ifdef HAVE_OGGFLAC |
---|
56 | +# include <OggFLAC/seekable_stream_decoder.h> |
---|
57 | +# endif |
---|
58 | +#else /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
59 | + |
---|
60 | + /* OggFLAC support is handled by our flac_plugin already, and |
---|
61 | + * thus we *can* always have it if libFLAC was compiled with it */ |
---|
62 | +# ifndef HAVE_OGGFLAC |
---|
63 | +# define HAVE_OGGFLAC 1 |
---|
64 | +# endif |
---|
65 | +# include "_ogg_common.h" |
---|
66 | +# undef HAVE_OGGFLAC /* we don't need this defined anymore */ |
---|
67 | + |
---|
68 | +# include <FLAC/stream_decoder.h> |
---|
69 | +# define flac_decoder FLAC__StreamDecoder |
---|
70 | +# define flac_new() FLAC__stream_decoder_new() |
---|
71 | + |
---|
72 | +# define flac_init(a,b,c,d,e,f,g,h,i,j) \ |
---|
73 | + (FLAC__stream_decoder_init_stream(a,b,c,d,e,f,g,h,i,j) \ |
---|
74 | + == FLAC__STREAM_DECODER_INIT_STATUS_OK) |
---|
75 | +# define flac_ogg_init(a,b,c,d,e,f,g,h,i,j) \ |
---|
76 | + (FLAC__stream_decoder_init_ogg_stream(a,b,c,d,e,f,g,h,i,j) \ |
---|
77 | + == FLAC__STREAM_DECODER_INIT_STATUS_OK) |
---|
78 | + |
---|
79 | +# define flac_get_decode_position(x,y) \ |
---|
80 | + FLAC__stream_decoder_get_decode_position(x,y) |
---|
81 | +# define flac_get_state(x) FLAC__stream_decoder_get_state(x) |
---|
82 | +# define flac_process_single(x) FLAC__stream_decoder_process_single(x) |
---|
83 | +# define flac_process_metadata(x) \ |
---|
84 | + FLAC__stream_decoder_process_until_end_of_metadata(x) |
---|
85 | +# define flac_seek_absolute(x,y) FLAC__stream_decoder_seek_absolute(x,y) |
---|
86 | +# define flac_finish(x) FLAC__stream_decoder_finish(x) |
---|
87 | +# define flac_delete(x) FLAC__stream_decoder_delete(x) |
---|
88 | + |
---|
89 | +# define flac_decoder_eof FLAC__STREAM_DECODER_END_OF_STREAM |
---|
90 | + |
---|
91 | +typedef size_t flac_read_status_size_t; |
---|
92 | +# define flac_read_status FLAC__StreamDecoderReadStatus |
---|
93 | +# define flac_read_status_continue \ |
---|
94 | + FLAC__STREAM_DECODER_READ_STATUS_CONTINUE |
---|
95 | +# define flac_read_status_eof FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM |
---|
96 | +# define flac_read_status_abort FLAC__STREAM_DECODER_READ_STATUS_ABORT |
---|
97 | + |
---|
98 | +# define flac_seek_status FLAC__StreamDecoderSeekStatus |
---|
99 | +# define flac_seek_status_ok FLAC__STREAM_DECODER_SEEK_STATUS_OK |
---|
100 | +# define flac_seek_status_error FLAC__STREAM_DECODER_SEEK_STATUS_ERROR |
---|
101 | +# define flac_seek_status_unsupported \ |
---|
102 | + FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED |
---|
103 | + |
---|
104 | +# define flac_tell_status FLAC__StreamDecoderTellStatus |
---|
105 | +# define flac_tell_status_ok FLAC__STREAM_DECODER_TELL_STATUS_OK |
---|
106 | +# define flac_tell_status_error FLAC__STREAM_DECODER_TELL_STATUS_ERROR |
---|
107 | +# define flac_tell_status_unsupported \ |
---|
108 | + FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED |
---|
109 | + |
---|
110 | +# define flac_length_status FLAC__StreamDecoderLengthStatus |
---|
111 | +# define flac_length_status_ok FLAC__STREAM_DECODER_LENGTH_STATUS_OK |
---|
112 | +# define flac_length_status_error FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR |
---|
113 | +# define flac_length_status_unsupported \ |
---|
114 | + FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED |
---|
115 | + |
---|
116 | +#endif /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
117 | + |
---|
118 | #include <FLAC/metadata.h> |
---|
119 | |
---|
120 | #define FLAC_CHUNK_SIZE 4080 |
---|
121 | |
---|
122 | --- src/inputPlugins/flac_plugin.c.orig 2007-04-02 11:54:26.000000000 +0200 |
---|
123 | +++ src/inputPlugins/flac_plugin.c 2007-04-02 11:54:42.000000000 +0200 |
---|
124 | @@ -16,12 +16,10 @@ |
---|
125 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
126 | */ |
---|
127 | |
---|
128 | -#include "../inputPlugin.h" |
---|
129 | +#include "_flac_common.h" |
---|
130 | |
---|
131 | #ifdef HAVE_FLAC |
---|
132 | |
---|
133 | -#include "_flac_common.h" |
---|
134 | - |
---|
135 | #include "../utils.h" |
---|
136 | #include "../log.h" |
---|
137 | #include "../pcm_utils.h" |
---|
138 | @@ -33,166 +31,14 @@ |
---|
139 | #include <stdio.h> |
---|
140 | #include <string.h> |
---|
141 | #include <unistd.h> |
---|
142 | -#include <FLAC/seekable_stream_decoder.h> |
---|
143 | -#include <FLAC/metadata.h> |
---|
144 | - |
---|
145 | -/* this code is based on flac123, from flac-tools */ |
---|
146 | - |
---|
147 | -static void flacError(const FLAC__SeekableStreamDecoder *, |
---|
148 | - FLAC__StreamDecoderErrorStatus, void *); |
---|
149 | -static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state); |
---|
150 | -static void flacMetadata(const FLAC__SeekableStreamDecoder *, |
---|
151 | - const FLAC__StreamMetadata *, void *); |
---|
152 | -static FLAC__StreamDecoderWriteStatus flacWrite(const |
---|
153 | - FLAC__SeekableStreamDecoder *, |
---|
154 | - const FLAC__Frame *, |
---|
155 | - const FLAC__int32 * const buf[], |
---|
156 | - void *); |
---|
157 | -static FLAC__SeekableStreamDecoderReadStatus flacRead(const |
---|
158 | - FLAC__SeekableStreamDecoder |
---|
159 | - *, FLAC__byte buf[], |
---|
160 | - unsigned *, void *); |
---|
161 | -static FLAC__SeekableStreamDecoderSeekStatus flacSeek(const |
---|
162 | - FLAC__SeekableStreamDecoder |
---|
163 | - *, FLAC__uint64, void *); |
---|
164 | -static FLAC__SeekableStreamDecoderTellStatus flacTell(const |
---|
165 | - FLAC__SeekableStreamDecoder |
---|
166 | - *, FLAC__uint64 *, |
---|
167 | - void *); |
---|
168 | -static FLAC__SeekableStreamDecoderLengthStatus flacLength(const |
---|
169 | - FLAC__SeekableStreamDecoder |
---|
170 | - *, FLAC__uint64 *, |
---|
171 | - void *); |
---|
172 | -static FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, void *); |
---|
173 | - |
---|
174 | -static int flac_decode(OutputBuffer * cb, DecoderControl * dc, |
---|
175 | - InputStream * inStream) |
---|
176 | -{ |
---|
177 | - FLAC__SeekableStreamDecoder *flacDec = NULL; |
---|
178 | - FlacData data; |
---|
179 | - int status = 1; |
---|
180 | - int ret = 0; |
---|
181 | - |
---|
182 | - init_FlacData(&data, cb, dc, inStream); |
---|
183 | - |
---|
184 | - if (!(flacDec = FLAC__seekable_stream_decoder_new())) { |
---|
185 | - ret = -1; |
---|
186 | - goto fail; |
---|
187 | - } |
---|
188 | - /*status&=FLAC__file_decoder_set_md5_checking(flacDec,1); */ |
---|
189 | - status &= FLAC__seekable_stream_decoder_set_read_callback(flacDec, |
---|
190 | - flacRead); |
---|
191 | - status &= FLAC__seekable_stream_decoder_set_seek_callback(flacDec, |
---|
192 | - flacSeek); |
---|
193 | - status &= FLAC__seekable_stream_decoder_set_tell_callback(flacDec, |
---|
194 | - flacTell); |
---|
195 | - status &= FLAC__seekable_stream_decoder_set_length_callback(flacDec, |
---|
196 | - flacLength); |
---|
197 | - status &= |
---|
198 | - FLAC__seekable_stream_decoder_set_eof_callback(flacDec, flacEOF); |
---|
199 | - status &= |
---|
200 | - FLAC__seekable_stream_decoder_set_write_callback(flacDec, |
---|
201 | - flacWrite); |
---|
202 | - status &= |
---|
203 | - FLAC__seekable_stream_decoder_set_metadata_callback(flacDec, |
---|
204 | - flacMetadata); |
---|
205 | - status &= |
---|
206 | - FLAC__seekable_stream_decoder_set_metadata_respond(flacDec, |
---|
207 | - FLAC__METADATA_TYPE_VORBIS_COMMENT); |
---|
208 | - status &= |
---|
209 | - FLAC__seekable_stream_decoder_set_error_callback(flacDec, |
---|
210 | - flacError); |
---|
211 | - status &= |
---|
212 | - FLAC__seekable_stream_decoder_set_client_data(flacDec, |
---|
213 | - (void *)&data); |
---|
214 | - if (!status) { |
---|
215 | - ERROR("flac problem before init()\n"); |
---|
216 | - flacPrintErroredState(FLAC__seekable_stream_decoder_get_state |
---|
217 | - (flacDec)); |
---|
218 | - ret = -1; |
---|
219 | - goto fail; |
---|
220 | - } |
---|
221 | - |
---|
222 | - if (FLAC__seekable_stream_decoder_init(flacDec) != |
---|
223 | - FLAC__SEEKABLE_STREAM_DECODER_OK) { |
---|
224 | - ERROR("flac problem doing init()\n"); |
---|
225 | - flacPrintErroredState(FLAC__seekable_stream_decoder_get_state |
---|
226 | - (flacDec)); |
---|
227 | - ret = -1; |
---|
228 | - goto fail; |
---|
229 | - } |
---|
230 | - |
---|
231 | - if (!FLAC__seekable_stream_decoder_process_until_end_of_metadata |
---|
232 | - (flacDec)) { |
---|
233 | - ERROR("flac problem reading metadata\n"); |
---|
234 | - flacPrintErroredState(FLAC__seekable_stream_decoder_get_state |
---|
235 | - (flacDec)); |
---|
236 | - ret = -1; |
---|
237 | - goto fail; |
---|
238 | - } |
---|
239 | - |
---|
240 | - dc->state = DECODE_STATE_DECODE; |
---|
241 | - |
---|
242 | - while (1) { |
---|
243 | - FLAC__seekable_stream_decoder_process_single(flacDec); |
---|
244 | - if (FLAC__seekable_stream_decoder_get_state(flacDec) != |
---|
245 | - FLAC__SEEKABLE_STREAM_DECODER_OK) { |
---|
246 | - break; |
---|
247 | - } |
---|
248 | - if (dc->seek) { |
---|
249 | - FLAC__uint64 sampleToSeek = dc->seekWhere * |
---|
250 | - dc->audioFormat.sampleRate + 0.5; |
---|
251 | - if (FLAC__seekable_stream_decoder_seek_absolute(flacDec, |
---|
252 | - sampleToSeek)) |
---|
253 | - { |
---|
254 | - clearOutputBuffer(cb); |
---|
255 | - data.time = ((float)sampleToSeek) / |
---|
256 | - dc->audioFormat.sampleRate; |
---|
257 | - data.position = 0; |
---|
258 | - } else |
---|
259 | - dc->seekError = 1; |
---|
260 | - dc->seek = 0; |
---|
261 | - } |
---|
262 | - } |
---|
263 | - /* I don't think we need this bit here! -shank */ |
---|
264 | - /*FLAC__file_decoder_process_until_end_of_file(flacDec); */ |
---|
265 | - if (!dc->stop) { |
---|
266 | - flacPrintErroredState(FLAC__seekable_stream_decoder_get_state |
---|
267 | - (flacDec)); |
---|
268 | - FLAC__seekable_stream_decoder_finish(flacDec); |
---|
269 | - } |
---|
270 | - /* send last little bit */ |
---|
271 | - if (data.chunk_length > 0 && !dc->stop) { |
---|
272 | - flacSendChunk(&data); |
---|
273 | - flushOutputBuffer(data.cb); |
---|
274 | - } |
---|
275 | - |
---|
276 | - /*if(dc->seek) { |
---|
277 | - dc->seekError = 1; |
---|
278 | - dc->seek = 0; |
---|
279 | - } */ |
---|
280 | - |
---|
281 | - dc->state = DECODE_STATE_STOP; |
---|
282 | - dc->stop = 0; |
---|
283 | - |
---|
284 | -fail: |
---|
285 | - if (data.replayGainInfo) |
---|
286 | - freeReplayGainInfo(data.replayGainInfo); |
---|
287 | - |
---|
288 | - if (flacDec) |
---|
289 | - FLAC__seekable_stream_decoder_delete(flacDec); |
---|
290 | - |
---|
291 | - closeInputStream(inStream); |
---|
292 | +#include <assert.h> |
---|
293 | |
---|
294 | - return ret; |
---|
295 | -} |
---|
296 | +/* this code was based on flac123, from flac-tools */ |
---|
297 | |
---|
298 | -static FLAC__SeekableStreamDecoderReadStatus flacRead(const |
---|
299 | - FLAC__SeekableStreamDecoder |
---|
300 | - * flacDec, |
---|
301 | - FLAC__byte buf[], |
---|
302 | - unsigned *bytes, |
---|
303 | - void *fdata) |
---|
304 | +static flac_read_status flacRead(const flac_decoder * flacDec, |
---|
305 | + FLAC__byte buf[], |
---|
306 | + flac_read_status_size_t *bytes, |
---|
307 | + void *fdata) |
---|
308 | { |
---|
309 | FlacData *data = (FlacData *) fdata; |
---|
310 | size_t r; |
---|
311 | @@ -207,55 +53,51 @@ |
---|
312 | } |
---|
313 | *bytes = r; |
---|
314 | |
---|
315 | - if (*bytes == 0 && !inputStreamAtEOF(data->inStream) && !data->dc->stop) |
---|
316 | - return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; |
---|
317 | - |
---|
318 | - return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; |
---|
319 | + if (r == 0 && !data->dc->stop) { |
---|
320 | + if (inputStreamAtEOF(data->inStream)) |
---|
321 | + return flac_read_status_eof; |
---|
322 | + else |
---|
323 | + return flac_read_status_abort; |
---|
324 | + } |
---|
325 | + return flac_read_status_continue; |
---|
326 | } |
---|
327 | |
---|
328 | -static FLAC__SeekableStreamDecoderSeekStatus flacSeek(const |
---|
329 | - FLAC__SeekableStreamDecoder |
---|
330 | - * flacDec, |
---|
331 | - FLAC__uint64 offset, |
---|
332 | - void *fdata) |
---|
333 | +static flac_seek_status flacSeek(const flac_decoder * flacDec, |
---|
334 | + FLAC__uint64 offset, |
---|
335 | + void *fdata) |
---|
336 | { |
---|
337 | FlacData *data = (FlacData *) fdata; |
---|
338 | |
---|
339 | if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) { |
---|
340 | - return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; |
---|
341 | + return flac_seek_status_error; |
---|
342 | } |
---|
343 | |
---|
344 | - return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; |
---|
345 | + return flac_seek_status_ok; |
---|
346 | } |
---|
347 | |
---|
348 | -static FLAC__SeekableStreamDecoderTellStatus flacTell(const |
---|
349 | - FLAC__SeekableStreamDecoder |
---|
350 | - * flacDec, |
---|
351 | - FLAC__uint64 * offset, |
---|
352 | - void *fdata) |
---|
353 | +static flac_tell_status flacTell(const flac_decoder * flacDec, |
---|
354 | + FLAC__uint64 * offset, |
---|
355 | + void *fdata) |
---|
356 | { |
---|
357 | FlacData *data = (FlacData *) fdata; |
---|
358 | |
---|
359 | *offset = (long)(data->inStream->offset); |
---|
360 | |
---|
361 | - return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; |
---|
362 | + return flac_tell_status_ok; |
---|
363 | } |
---|
364 | |
---|
365 | -static FLAC__SeekableStreamDecoderLengthStatus flacLength(const |
---|
366 | - FLAC__SeekableStreamDecoder |
---|
367 | - * flacDec, |
---|
368 | - FLAC__uint64 * length, |
---|
369 | - void *fdata) |
---|
370 | +static flac_length_status flacLength(const flac_decoder * flacDec, |
---|
371 | + FLAC__uint64 * length, |
---|
372 | + void *fdata) |
---|
373 | { |
---|
374 | FlacData *data = (FlacData *) fdata; |
---|
375 | |
---|
376 | *length = (size_t) (data->inStream->size); |
---|
377 | |
---|
378 | - return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; |
---|
379 | + return flac_length_status_ok; |
---|
380 | } |
---|
381 | |
---|
382 | -static FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder * flacDec, |
---|
383 | - void *fdata) |
---|
384 | +static FLAC__bool flacEOF(const flac_decoder * flacDec, void *fdata) |
---|
385 | { |
---|
386 | FlacData *data = (FlacData *) fdata; |
---|
387 | |
---|
388 | @@ -264,52 +106,112 @@ |
---|
389 | return false; |
---|
390 | } |
---|
391 | |
---|
392 | -static void flacError(const FLAC__SeekableStreamDecoder * dec, |
---|
393 | +static void flacError(const flac_decoder *dec, |
---|
394 | FLAC__StreamDecoderErrorStatus status, void *fdata) |
---|
395 | { |
---|
396 | flac_error_common_cb("flac", status, (FlacData *) fdata); |
---|
397 | } |
---|
398 | |
---|
399 | +#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 |
---|
400 | static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state) |
---|
401 | { |
---|
402 | + const char *str = ""; /* "" to silence compiler warning */ |
---|
403 | switch (state) { |
---|
404 | + case FLAC__SEEKABLE_STREAM_DECODER_OK: |
---|
405 | + case FLAC__SEEKABLE_STREAM_DECODER_SEEKING: |
---|
406 | + case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM: |
---|
407 | + return; |
---|
408 | case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR: |
---|
409 | - ERROR("flac allocation error\n"); |
---|
410 | + str = "allocation error"; |
---|
411 | break; |
---|
412 | case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR: |
---|
413 | - ERROR("flac read error\n"); |
---|
414 | + str = "read error"; |
---|
415 | break; |
---|
416 | case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR: |
---|
417 | - ERROR("flac seek error\n"); |
---|
418 | + str = "seek error"; |
---|
419 | break; |
---|
420 | case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR: |
---|
421 | - ERROR("flac seekable stream error\n"); |
---|
422 | + str = "seekable stream error"; |
---|
423 | break; |
---|
424 | case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED: |
---|
425 | - ERROR("flac decoder already initialized\n"); |
---|
426 | + str = "decoder already initialized"; |
---|
427 | break; |
---|
428 | case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK: |
---|
429 | - ERROR("invalid flac callback\n"); |
---|
430 | + str = "invalid callback"; |
---|
431 | break; |
---|
432 | case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED: |
---|
433 | - ERROR("flac decoder uninitialized\n"); |
---|
434 | + str = "decoder uninitialized"; |
---|
435 | + } |
---|
436 | + ERROR("flac %s\n", str); |
---|
437 | +} |
---|
438 | + |
---|
439 | +static int flac_init(FLAC__SeekableStreamDecoder *dec, |
---|
440 | + FLAC__SeekableStreamDecoderReadCallback read_cb, |
---|
441 | + FLAC__SeekableStreamDecoderSeekCallback seek_cb, |
---|
442 | + FLAC__SeekableStreamDecoderTellCallback tell_cb, |
---|
443 | + FLAC__SeekableStreamDecoderLengthCallback length_cb, |
---|
444 | + FLAC__SeekableStreamDecoderEofCallback eof_cb, |
---|
445 | + FLAC__SeekableStreamDecoderWriteCallback write_cb, |
---|
446 | + FLAC__SeekableStreamDecoderMetadataCallback metadata_cb, |
---|
447 | + FLAC__SeekableStreamDecoderErrorCallback error_cb, |
---|
448 | + void *data) |
---|
449 | +{ |
---|
450 | + int s = 1; |
---|
451 | + s &= FLAC__seekable_stream_decoder_set_read_callback(dec, read_cb); |
---|
452 | + s &= FLAC__seekable_stream_decoder_set_seek_callback(dec, seek_cb); |
---|
453 | + s &= FLAC__seekable_stream_decoder_set_tell_callback(dec, tell_cb); |
---|
454 | + s &= FLAC__seekable_stream_decoder_set_length_callback(dec, length_cb); |
---|
455 | + s &= FLAC__seekable_stream_decoder_set_eof_callback(dec, eof_cb); |
---|
456 | + s &= FLAC__seekable_stream_decoder_set_write_callback(dec, write_cb); |
---|
457 | + s &= FLAC__seekable_stream_decoder_set_metadata_callback(dec, |
---|
458 | + metadata_cb); |
---|
459 | + s &= FLAC__seekable_stream_decoder_set_metadata_respond(dec, |
---|
460 | + FLAC__METADATA_TYPE_VORBIS_COMMENT); |
---|
461 | + s &= FLAC__seekable_stream_decoder_set_error_callback(dec, error_cb); |
---|
462 | + s &= FLAC__seekable_stream_decoder_set_client_data(dec, data); |
---|
463 | + if (!s || (FLAC__seekable_stream_decoder_init(dec) != |
---|
464 | + FLAC__SEEKABLE_STREAM_DECODER_OK)) |
---|
465 | + return 0; |
---|
466 | + return 1; |
---|
467 | +} |
---|
468 | +#else /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
469 | +static void flacPrintErroredState(FLAC__StreamDecoderState state) |
---|
470 | +{ |
---|
471 | + const char *str = ""; /* "" to silence compiler warning */ |
---|
472 | + switch (state) { |
---|
473 | + case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA: |
---|
474 | + case FLAC__STREAM_DECODER_READ_METADATA: |
---|
475 | + case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC: |
---|
476 | + case FLAC__STREAM_DECODER_READ_FRAME: |
---|
477 | + case FLAC__STREAM_DECODER_END_OF_STREAM: |
---|
478 | + return; |
---|
479 | + case FLAC__STREAM_DECODER_OGG_ERROR: |
---|
480 | + str = "error in the Ogg layer"; |
---|
481 | break; |
---|
482 | - case FLAC__SEEKABLE_STREAM_DECODER_OK: |
---|
483 | - case FLAC__SEEKABLE_STREAM_DECODER_SEEKING: |
---|
484 | - case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM: |
---|
485 | + case FLAC__STREAM_DECODER_SEEK_ERROR: |
---|
486 | + str = "seek error"; |
---|
487 | + break; |
---|
488 | + case FLAC__STREAM_DECODER_ABORTED: |
---|
489 | + str = "decoder aborted by read"; |
---|
490 | + break; |
---|
491 | + case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR: |
---|
492 | + str = "allocation error"; |
---|
493 | break; |
---|
494 | + case FLAC__STREAM_DECODER_UNINITIALIZED: |
---|
495 | + str = "decoder uninitialized"; |
---|
496 | } |
---|
497 | + ERROR("flac %s\n", str); |
---|
498 | } |
---|
499 | +#endif /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
500 | |
---|
501 | -static void flacMetadata(const FLAC__SeekableStreamDecoder * dec, |
---|
502 | +static void flacMetadata(const flac_decoder * dec, |
---|
503 | const FLAC__StreamMetadata * block, void *vdata) |
---|
504 | { |
---|
505 | flac_metadata_common_cb(block, (FlacData *) vdata); |
---|
506 | } |
---|
507 | |
---|
508 | -static FLAC__StreamDecoderWriteStatus flacWrite(const |
---|
509 | - FLAC__SeekableStreamDecoder * |
---|
510 | - dec, const FLAC__Frame * frame, |
---|
511 | +static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec, |
---|
512 | + const FLAC__Frame * frame, |
---|
513 | const FLAC__int32 * const buf[], |
---|
514 | void *vdata) |
---|
515 | { |
---|
516 | @@ -325,7 +227,7 @@ |
---|
517 | timeChange = ((float)samples) / frame->header.sample_rate; |
---|
518 | data->time += timeChange; |
---|
519 | |
---|
520 | - FLAC__seekable_stream_decoder_get_decode_position(dec, &newPosition); |
---|
521 | + flac_get_decode_position(dec, &newPosition); |
---|
522 | if (data->position) { |
---|
523 | data->bitRate = |
---|
524 | ((newPosition - data->position) * 8.0 / timeChange) |
---|
525 | @@ -438,12 +340,179 @@ |
---|
526 | return ret; |
---|
527 | } |
---|
528 | |
---|
529 | +static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc, |
---|
530 | + InputStream * inStream, int is_ogg) |
---|
531 | +{ |
---|
532 | + flac_decoder *flacDec; |
---|
533 | + FlacData data; |
---|
534 | + const char *err = NULL; |
---|
535 | + |
---|
536 | + if (!(flacDec = flac_new())) |
---|
537 | + return -1; |
---|
538 | + init_FlacData(&data, cb, dc, inStream); |
---|
539 | + if (is_ogg) { |
---|
540 | + if (!flac_ogg_init(flacDec, flacRead, flacSeek, flacTell, |
---|
541 | + flacLength, flacEOF, flacWrite, flacMetadata, |
---|
542 | + flacError, (void *)&data)) { |
---|
543 | + err = "doing Ogg init()"; |
---|
544 | + goto fail; |
---|
545 | + } |
---|
546 | + } else { |
---|
547 | + if (!flac_init(flacDec, flacRead, flacSeek, flacTell, |
---|
548 | + flacLength, flacEOF, flacWrite, flacMetadata, |
---|
549 | + flacError, (void *)&data)) { |
---|
550 | + err = "doing init()"; |
---|
551 | + goto fail; |
---|
552 | + } |
---|
553 | + if (!flac_process_metadata(flacDec)) { |
---|
554 | + err = "problem reading metadata"; |
---|
555 | + goto fail; |
---|
556 | + } |
---|
557 | + } |
---|
558 | + |
---|
559 | + dc->state = DECODE_STATE_DECODE; |
---|
560 | + |
---|
561 | + while (1) { |
---|
562 | + if (!flac_process_single(flacDec)) |
---|
563 | + break; |
---|
564 | + if (flac_get_state(flacDec) == flac_decoder_eof) |
---|
565 | + break; |
---|
566 | + if (dc->seek) { |
---|
567 | + FLAC__uint64 sampleToSeek = dc->seekWhere * |
---|
568 | + dc->audioFormat.sampleRate + 0.5; |
---|
569 | + if (flac_seek_absolute(flacDec, sampleToSeek)) { |
---|
570 | + clearOutputBuffer(cb); |
---|
571 | + data.time = ((float)sampleToSeek) / |
---|
572 | + dc->audioFormat.sampleRate; |
---|
573 | + data.position = 0; |
---|
574 | + } else |
---|
575 | + dc->seekError = 1; |
---|
576 | + dc->seek = 0; |
---|
577 | + } |
---|
578 | + } |
---|
579 | + if (!dc->stop) { |
---|
580 | + flacPrintErroredState(flac_get_state(flacDec)); |
---|
581 | + flac_finish(flacDec); |
---|
582 | + } |
---|
583 | + /* send last little bit */ |
---|
584 | + if (data.chunk_length > 0 && !dc->stop) { |
---|
585 | + flacSendChunk(&data); |
---|
586 | + flushOutputBuffer(data.cb); |
---|
587 | + } |
---|
588 | + |
---|
589 | + /*if(dc->seek) { |
---|
590 | + dc->seekError = 1; |
---|
591 | + dc->seek = 0; |
---|
592 | + } */ |
---|
593 | + |
---|
594 | + dc->state = DECODE_STATE_STOP; |
---|
595 | + dc->stop = 0; |
---|
596 | + |
---|
597 | +fail: |
---|
598 | + if (data.replayGainInfo) |
---|
599 | + freeReplayGainInfo(data.replayGainInfo); |
---|
600 | + |
---|
601 | + if (flacDec) |
---|
602 | + flac_delete(flacDec); |
---|
603 | + |
---|
604 | + closeInputStream(inStream); |
---|
605 | + |
---|
606 | + if (err) { |
---|
607 | + ERROR("flac %s\n", err); |
---|
608 | + return -1; |
---|
609 | + } |
---|
610 | + return 0; |
---|
611 | +} |
---|
612 | + |
---|
613 | +static int flac_decode(OutputBuffer * cb, DecoderControl * dc, |
---|
614 | + InputStream * inStream) |
---|
615 | +{ |
---|
616 | + return flac_decode_internal(cb, dc, inStream, 0); |
---|
617 | +} |
---|
618 | + |
---|
619 | +#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 |
---|
620 | +# define flac_plugin_init NULL |
---|
621 | +#else /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
622 | +/* some of this stuff is duplicated from oggflac_plugin.c */ |
---|
623 | +extern InputPlugin oggflacPlugin; |
---|
624 | + |
---|
625 | +static MpdTag *oggflac_tag_dup(char *file) |
---|
626 | +{ |
---|
627 | + MpdTag *ret = NULL; |
---|
628 | + FLAC__Metadata_Iterator *it; |
---|
629 | + FLAC__StreamMetadata *block; |
---|
630 | + FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new(); |
---|
631 | + |
---|
632 | + if (!(FLAC__metadata_chain_read_ogg(chain, file))) |
---|
633 | + goto out; |
---|
634 | + it = FLAC__metadata_iterator_new(); |
---|
635 | + FLAC__metadata_iterator_init(it, chain); |
---|
636 | + do { |
---|
637 | + if (!(block = FLAC__metadata_iterator_get_block(it))) |
---|
638 | + break; |
---|
639 | + if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { |
---|
640 | + ret = copyVorbisCommentBlockToMpdTag(block, ret); |
---|
641 | + } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) { |
---|
642 | + if (!ret) |
---|
643 | + ret = newMpdTag(); |
---|
644 | + ret->time = ((float)block->data.stream_info. |
---|
645 | + total_samples) / |
---|
646 | + block->data.stream_info.sample_rate + 0.5; |
---|
647 | + } |
---|
648 | + } while (FLAC__metadata_iterator_next(it)); |
---|
649 | + FLAC__metadata_iterator_delete(it); |
---|
650 | +out: |
---|
651 | + FLAC__metadata_chain_delete(chain); |
---|
652 | + return ret; |
---|
653 | +} |
---|
654 | + |
---|
655 | +static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc, |
---|
656 | + InputStream * inStream) |
---|
657 | +{ |
---|
658 | + return flac_decode_internal(cb, dc, inStream, 1); |
---|
659 | +} |
---|
660 | + |
---|
661 | +static unsigned int oggflac_try_decode(InputStream * inStream) |
---|
662 | +{ |
---|
663 | + return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0; |
---|
664 | +} |
---|
665 | + |
---|
666 | +static char *oggflac_suffixes[] = { "ogg", NULL }; |
---|
667 | +static char *oggflac_mime_types[] = { "audio/x-flac+ogg", |
---|
668 | + "application/ogg", |
---|
669 | + "application/x-ogg", |
---|
670 | + NULL }; |
---|
671 | + |
---|
672 | +static int flac_plugin_init(void) |
---|
673 | +{ |
---|
674 | + if (!FLAC_API_SUPPORTS_OGG_FLAC) { |
---|
675 | + DEBUG("libFLAC does not support OggFLAC\n"); |
---|
676 | + return 1; |
---|
677 | + } |
---|
678 | + DEBUG("libFLAC supports OggFLAC, initializing OggFLAC support\n"); |
---|
679 | + assert(oggflacPlugin.name == NULL); |
---|
680 | + oggflacPlugin.name = "oggflac"; |
---|
681 | + oggflacPlugin.tryDecodeFunc = oggflac_try_decode; |
---|
682 | + oggflacPlugin.streamDecodeFunc = oggflac_decode; |
---|
683 | + oggflacPlugin.tagDupFunc = oggflac_tag_dup; |
---|
684 | + oggflacPlugin.streamTypes = INPUT_PLUGIN_STREAM_URL | |
---|
685 | + INPUT_PLUGIN_STREAM_FILE; |
---|
686 | + oggflacPlugin.suffixes = oggflac_suffixes; |
---|
687 | + oggflacPlugin.mimeTypes = oggflac_mime_types; |
---|
688 | + loadInputPlugin(&oggflacPlugin); |
---|
689 | + return 1; |
---|
690 | +} |
---|
691 | + |
---|
692 | +#endif /* FLAC_API_VERSION_CURRENT >= 7 */ |
---|
693 | + |
---|
694 | static char *flacSuffixes[] = { "flac", NULL }; |
---|
695 | -static char *flac_mime_types[] = { "application/x-flac", NULL }; |
---|
696 | +static char *flac_mime_types[] = { "audio/x-flac", |
---|
697 | + "application/x-flac", |
---|
698 | + NULL }; |
---|
699 | |
---|
700 | InputPlugin flacPlugin = { |
---|
701 | "flac", |
---|
702 | - NULL, |
---|
703 | + flac_plugin_init, |
---|
704 | NULL, |
---|
705 | NULL, |
---|
706 | flac_decode, |
---|
707 | @@ -456,17 +525,6 @@ |
---|
708 | |
---|
709 | #else /* !HAVE_FLAC */ |
---|
710 | |
---|
711 | -InputPlugin flacPlugin = { |
---|
712 | - NULL, |
---|
713 | - NULL, |
---|
714 | - NULL, |
---|
715 | - NULL, |
---|
716 | - NULL, |
---|
717 | - NULL, |
---|
718 | - NULL, |
---|
719 | - 0, |
---|
720 | - NULL, |
---|
721 | - NULL, |
---|
722 | -}; |
---|
723 | +InputPlugin flacPlugin; |
---|
724 | |
---|
725 | #endif /* HAVE_FLAC */ |
---|