Ticket #11424: patch-flac

File patch-flac, 23.7 KB (added by ehainry@…, 17 years ago)

patch for _flac_common.h and flac_plugin.c (both remove the dependency on seekable_stream)

Line 
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 */