aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/inputPlugins/_flac_common.h99
-rw-r--r--src/inputPlugins/flac_plugin.c162
-rw-r--r--src/inputPlugins/oggflac_plugin.c5
3 files changed, 205 insertions, 61 deletions
diff --git a/src/inputPlugins/_flac_common.h b/src/inputPlugins/_flac_common.h
index 6143cbfe7..eab7971e5 100644
--- a/src/inputPlugins/_flac_common.h
+++ b/src/inputPlugins/_flac_common.h
@@ -30,7 +30,104 @@
#include "../inputStream.h"
#include "../outputBuffer.h"
#include "../decode.h"
-#include <FLAC/seekable_stream_decoder.h>
+#include <FLAC/export.h>
+#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
+# include <FLAC/seekable_stream_decoder.h>
+# define flac_decoder FLAC__SeekableStreamDecoder
+# define flac_new(x) FLAC__seekable_stream_decoder_new(x)
+
+# define flac_get_decode_position(x,y) \
+ FLAC__seekable_stream_decoder_get_decode_position(x,y)
+# define flac_get_state(x) FLAC__seekable_stream_decoder_get_state(x)
+# define flac_process_single(x) FLAC__seekable_stream_decoder_process_single(x)
+# define flac_process_metadata(x) \
+ FLAC__seekable_stream_decoder_process_until_end_of_metadata(x)
+# define flac_seek_absolute(x,y) \
+ FLAC__seekable_stream_decoder_seek_absolute(x,y)
+# define flac_finish(x) FLAC__seekable_stream_decoder_finish(x)
+# define flac_delete(x) FLAC__seekable_stream_decoder_delete(x)
+
+# define flac_decoder_eof FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM
+
+# define flac_read_status FLAC__SeekableStreamDecoderReadStatus
+# define flac_read_status_continue \
+ FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK
+# define flac_read_status_eof FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK
+# define flac_read_status_abort \
+ FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR
+
+# define flac_seek_status FLAC__SeekableStreamDecoderSeekStatus
+# define flac_seek_status_ok FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK
+# define flac_seek_status_error FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR
+
+# define flac_tell_status FLAC__SeekableStreamDecoderTellStatus
+# define flac_tell_status_ok FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK
+# define flac_tell_status_error \
+ FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
+# define flac_tell_status_unsupported \
+ FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_ERROR
+
+# define flac_length_status FLAC__SeekableStreamDecoderLengthStatus
+# define flac_length_status_ok FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK
+# define flac_length_status_error \
+ FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
+# define flac_length_status_unsupported \
+ FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_ERROR
+
+# ifdef HAVE_OGGFLAC
+# include <OggFLAC/seekable_stream_decoder.h>
+# endif
+#else /* FLAC_API_VERSION_CURRENT >= 7 */
+ /* OggFLAC support is handled by our flac_plugin already */
+# ifdef HAVE_OGGFLAC
+# undef HAVE_OGGFLAC
+# endif
+# include <FLAC/stream_decoder.h>
+# include "_ogg_common.h"
+# define flac_decoder FLAC__StreamDecoder
+# define flac_new(x) FLAC__stream_decoder_new(x)
+
+# define flac_init(a,b,c,d,e,f,g,h,i,j) \
+ (FLAC__stream_decoder_init_stream(a,b,c,d,e,f,g,h,i,j) \
+ == FLAC__STREAM_DECODER_INIT_STATUS_OK)
+# define flac_get_decode_position(x,y) \
+ FLAC__stream_decoder_get_decode_position(x,y)
+# define flac_get_state(x) FLAC__stream_decoder_get_state(x)
+# define flac_process_single(x) FLAC__stream_decoder_process_single(x)
+# define flac_process_metadata(x) \
+ FLAC__stream_decoder_process_until_end_of_metadata(x)
+# define flac_seek_absolute(x,y) FLAC__stream_decoder_seek_absolute(x,y)
+# define flac_finish(x) FLAC__stream_decoder_finish(x)
+# define flac_delete(x) FLAC__stream_decoder_delete(x)
+
+# define flac_decoder_eof FLAC__STREAM_DECODER_END_OF_STREAM
+
+# define flac_read_status FLAC__StreamDecoderReadStatus
+# define flac_read_status_continue \
+ FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
+# define flac_read_status_eof FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
+# define flac_read_status_abort FLAC__STREAM_DECODER_READ_STATUS_ABORT
+
+# define flac_seek_status FLAC__StreamDecoderSeekStatus
+# define flac_seek_status_ok FLAC__STREAM_DECODER_SEEK_STATUS_OK
+# define flac_seek_status_error FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
+# define flac_seek_status_unsupported \
+ FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED
+
+# define flac_tell_status FLAC__StreamDecoderTellStatus
+# define flac_tell_status_ok FLAC__STREAM_DECODER_TELL_STATUS_OK
+# define flac_tell_status_error FLAC__STREAM_DECODER_TELL_STATUS_ERROR
+# define flac_tell_status_unsupported \
+ FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED
+
+# define flac_length_status FLAC__StreamDecoderLengthStatus
+# define flac_length_status_ok FLAC__STREAM_DECODER_LENGTH_STATUS_OK
+# define flac_length_status_error FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
+# define flac_length_status_unsupported \
+ FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED
+
+#endif /* FLAC_API_VERSION_CURRENT >= 7 */
+
#include <FLAC/metadata.h>
#define FLAC_CHUNK_SIZE 4080
diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c
index 49ddf82a7..0b0625417 100644
--- a/src/inputPlugins/flac_plugin.c
+++ b/src/inputPlugins/flac_plugin.c
@@ -16,12 +16,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "../inputPlugin.h"
+#include "_flac_common.h"
#ifdef HAVE_FLAC
-#include "_flac_common.h"
-
#include "../utils.h"
#include "../log.h"
#include "../pcm_utils.h"
@@ -33,16 +31,13 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <FLAC/stream_decoder.h>
-#include <FLAC/metadata.h>
-/* this code is based on flac123, from flac-tools */
+/* this code was based on flac123, from flac-tools */
-static FLAC__StreamDecoderReadStatus flacRead(const FLAC__StreamDecoder
- * flacDec,
- FLAC__byte buf[],
- unsigned *bytes,
- void *fdata)
+static flac_read_status flacRead(const flac_decoder * flacDec,
+ FLAC__byte buf[],
+ unsigned *bytes,
+ void *fdata)
{
FlacData *data = (FlacData *) fdata;
size_t r;
@@ -59,52 +54,49 @@ static FLAC__StreamDecoderReadStatus flacRead(const FLAC__StreamDecoder
if (r == 0 && !data->dc->stop) {
if (inputStreamAtEOF(data->inStream))
- return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
+ return flac_read_status_eof;
else
- return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
+ return flac_read_status_abort;
}
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ return flac_read_status_continue;
}
-static FLAC__StreamDecoderSeekStatus flacSeek(const FLAC__StreamDecoder
- * flacDec,
- FLAC__uint64 offset,
- void *fdata)
+static flac_seek_status flacSeek(const flac_decoder * flacDec,
+ FLAC__uint64 offset,
+ void *fdata)
{
FlacData *data = (FlacData *) fdata;
if (seekInputStream(data->inStream, offset, SEEK_SET) < 0) {
- return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+ return flac_seek_status_error;
}
- return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+ return flac_tell_status_ok;
}
-static FLAC__StreamDecoderTellStatus flacTell(const FLAC__StreamDecoder
- * flacDec,
- FLAC__uint64 * offset,
- void *fdata)
+static flac_tell_status flacTell(const flac_decoder * flacDec,
+ FLAC__uint64 * offset,
+ void *fdata)
{
FlacData *data = (FlacData *) fdata;
*offset = (long)(data->inStream->offset);
- return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+ return flac_tell_status_ok;
}
-static FLAC__StreamDecoderLengthStatus flacLength(const FLAC__StreamDecoder
- * flacDec,
- FLAC__uint64 * length,
- void *fdata)
+static flac_length_status flacLength(const flac_decoder * flacDec,
+ FLAC__uint64 * length,
+ void *fdata)
{
FlacData *data = (FlacData *) fdata;
*length = (size_t) (data->inStream->size);
- return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+ return flac_length_status_ok;
}
-static FLAC__bool flacEOF(const FLAC__StreamDecoder * flacDec, void *fdata)
+static FLAC__bool flacEOF(const flac_decoder * flacDec, void *fdata)
{
FlacData *data = (FlacData *) fdata;
@@ -113,12 +105,75 @@ static FLAC__bool flacEOF(const FLAC__StreamDecoder * flacDec, void *fdata)
return false;
}
-static void flacError(const FLAC__StreamDecoder * dec,
+static void flacError(const flac_decoder *dec,
FLAC__StreamDecoderErrorStatus status, void *fdata)
{
flac_error_common_cb("flac", status, (FlacData *) fdata);
}
+#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
+static void flacPrintErroredState(FLAC__SeekableStreamDecoderState state)
+{
+ const char *str = ""; /* "" to silence compiler warning */
+ switch (state) {
+ case FLAC__SEEKABLE_STREAM_DECODER_OK:
+ case FLAC__SEEKABLE_STREAM_DECODER_SEEKING:
+ case FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM:
+ return;
+ case FLAC__SEEKABLE_STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
+ str = "allocation error";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_READ_ERROR:
+ str = "read error";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR:
+ str = "seek error";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR:
+ str = "seekable stream error";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_ALREADY_INITIALIZED:
+ str = "decoder already initialized";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_INVALID_CALLBACK:
+ str = "invalid callback";
+ break;
+ case FLAC__SEEKABLE_STREAM_DECODER_UNINITIALIZED:
+ str = "decoder uninitialized";
+ }
+ ERROR("flac %s\n", str);
+}
+
+static int flac_init(FLAC__SeekableStreamDecoder *dec,
+ FLAC__SeekableStreamDecoderReadCallback read_cb,
+ FLAC__SeekableStreamDecoderSeekCallback seek_cb,
+ FLAC__SeekableStreamDecoderTellCallback tell_cb,
+ FLAC__SeekableStreamDecoderLengthCallback length_cb,
+ FLAC__SeekableStreamDecoderEofCallback eof_cb,
+ FLAC__SeekableStreamDecoderWriteCallback write_cb,
+ FLAC__SeekableStreamDecoderMetadataCallback metadata_cb,
+ FLAC__SeekableStreamDecoderErrorCallback error_cb,
+ void *data)
+{
+ int s = 1;
+ s &= FLAC__seekable_stream_decoder_set_read_callback(dec, read_cb);
+ s &= FLAC__seekable_stream_decoder_set_seek_callback(dec, seek_cb);
+ s &= FLAC__seekable_stream_decoder_set_tell_callback(dec, tell_cb);
+ s &= FLAC__seekable_stream_decoder_set_length_callback(dec, length_cb);
+ s &= FLAC__seekable_stream_decoder_set_eof_callback(dec, eof_cb);
+ s &= FLAC__seekable_stream_decoder_set_write_callback(dec, write_cb);
+ s &= FLAC__seekable_stream_decoder_set_metadata_callback(dec,
+ metadata_cb);
+ s &= FLAC__seekable_stream_decoder_set_metadata_respond(dec,
+ FLAC__METADATA_TYPE_VORBIS_COMMENT);
+ s &= FLAC__seekable_stream_decoder_set_error_callback(dec, error_cb);
+ s &= FLAC__seekable_stream_decoder_set_client_data(dec, data);
+ if (!s || (FLAC__seekable_stream_decoder_init(dec) !=
+ FLAC__SEEKABLE_STREAM_DECODER_OK))
+ return 0;
+ return 1;
+}
+#else /* FLAC_API_VERSION_CURRENT >= 7 */
static void flacPrintErroredState(FLAC__StreamDecoderState state)
{
const char *str = ""; /* "" to silence compiler warning */
@@ -143,19 +198,19 @@ static void flacPrintErroredState(FLAC__StreamDecoderState state)
break;
case FLAC__STREAM_DECODER_UNINITIALIZED:
str = "decoder uninitialized";
- break;
}
ERROR("flac %s\n", str);
}
+#endif /* FLAC_API_VERSION_CURRENT >= 7 */
-static void flacMetadata(const FLAC__StreamDecoder * dec,
+static void flacMetadata(const flac_decoder * dec,
const FLAC__StreamMetadata * block, void *vdata)
{
flac_metadata_common_cb(block, (FlacData *) vdata);
}
-static FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__StreamDecoder *
- dec, const FLAC__Frame * frame,
+static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
+ const FLAC__Frame * frame,
const FLAC__int32 * const buf[],
void *vdata)
{
@@ -171,7 +226,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const FLAC__StreamDecoder *
timeChange = ((float)samples) / frame->header.sample_rate;
data->time += timeChange;
- FLAC__stream_decoder_get_decode_position(dec, &newPosition);
+ flac_get_decode_position(dec, &newPosition);
if (data->position) {
data->bitRate =
((newPosition - data->position) * 8.0 / timeChange)
@@ -287,27 +342,25 @@ static MpdTag *flacTagDup(char *file)
static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
InputStream * inStream)
{
- FLAC__StreamDecoder *flacDec;
+ flac_decoder *flacDec;
FlacData data;
int ret = 0;
- if (!(flacDec = FLAC__stream_decoder_new()))
+ if (!(flacDec = flac_new()))
return -1;
init_FlacData(&data, cb, dc, inStream);
- if (FLAC__stream_decoder_init_stream(flacDec, flacRead, flacSeek,
- flacTell, flacLength, flacEOF,
- flacWrite, flacMetadata,
- flacError, (void *)&data)
- != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
+ if (!flac_init(flacDec, flacRead, flacSeek, flacTell, flacLength,
+ flacEOF, flacWrite, flacMetadata, flacError,
+ (void *)&data)) {
ERROR("flac problem doing init()\n");
- flacPrintErroredState(FLAC__stream_decoder_get_state(flacDec));
+ flacPrintErroredState(flac_get_state(flacDec));
ret = -1;
goto fail;
}
- if (!FLAC__stream_decoder_process_until_end_of_metadata(flacDec)) {
+ if (!flac_process_metadata(flacDec)) {
ERROR("flac problem reading metadata\n");
- flacPrintErroredState(FLAC__stream_decoder_get_state(flacDec));
+ flacPrintErroredState(flac_get_state(flacDec));
ret = -1;
goto fail;
}
@@ -315,17 +368,14 @@ static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
dc->state = DECODE_STATE_DECODE;
while (1) {
- if (!FLAC__stream_decoder_process_single(flacDec))
+ if (!flac_process_single(flacDec))
break;
- if (FLAC__stream_decoder_get_state(flacDec) ==
- FLAC__STREAM_DECODER_END_OF_STREAM)
+ if (flac_get_state(flacDec) == flac_decoder_eof)
break;
if (dc->seek) {
FLAC__uint64 sampleToSeek = dc->seekWhere *
dc->audioFormat.sampleRate + 0.5;
- if (FLAC__stream_decoder_seek_absolute(flacDec,
- sampleToSeek))
- {
+ if (flac_seek_absolute(flacDec, sampleToSeek)) {
clearOutputBuffer(cb);
data.time = ((float)sampleToSeek) /
dc->audioFormat.sampleRate;
@@ -336,8 +386,8 @@ static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
}
}
if (!dc->stop) {
- flacPrintErroredState(FLAC__stream_decoder_get_state(flacDec));
- FLAC__stream_decoder_finish(flacDec);
+ flacPrintErroredState(flac_get_state(flacDec));
+ flac_finish(flacDec);
}
/* send last little bit */
if (data.chunk_length > 0 && !dc->stop) {
@@ -358,7 +408,7 @@ fail:
freeReplayGainInfo(data.replayGainInfo);
if (flacDec)
- FLAC__stream_decoder_delete(flacDec);
+ flac_delete(flacDec);
closeInputStream(inStream);
diff --git a/src/inputPlugins/oggflac_plugin.c b/src/inputPlugins/oggflac_plugin.c
index 83984e620..721f38742 100644
--- a/src/inputPlugins/oggflac_plugin.c
+++ b/src/inputPlugins/oggflac_plugin.c
@@ -19,11 +19,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "../inputPlugin.h"
+#include "_flac_common.h"
#ifdef HAVE_OGGFLAC
-#include "_flac_common.h"
#include "_ogg_common.h"
#include "../utils.h"
@@ -37,8 +36,6 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <OggFLAC/seekable_stream_decoder.h>
-#include <FLAC/metadata.h>
static void oggflac_cleanup(InputStream * inStream,
FlacData * data,