Add OggFLAC support when using the new 1.1.3 FLAC library
This means that when using libFLAC as a shared object, OggFLAC support is dependent on the compile-time options of the libFLAC library loaded. git-svn-id: https://svn.musicpd.org/mpd/trunk@5112 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
b152086ae4
commit
63dd4b4598
@ -36,6 +36,8 @@
|
||||
# define flac_decoder FLAC__SeekableStreamDecoder
|
||||
# define flac_new(x) FLAC__seekable_stream_decoder_new(x)
|
||||
|
||||
# define flac_ogg_init(a,b,c,d,e,f,g,h,i,j) (0)
|
||||
|
||||
# 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)
|
||||
@ -78,18 +80,26 @@
|
||||
# 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
|
||||
|
||||
/* OggFLAC support is handled by our flac_plugin already, and
|
||||
* thus we *can* always have it if libFLAC was compiled with it */
|
||||
# ifndef HAVE_OGGFLAC
|
||||
# define HAVE_OGGFLAC 1
|
||||
# endif
|
||||
# include <FLAC/stream_decoder.h>
|
||||
# include "_ogg_common.h"
|
||||
# undef HAVE_OGGFLAC /* we don't need this defined anymore */
|
||||
|
||||
# include <FLAC/stream_decoder.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_ogg_init(a,b,c,d,e,f,g,h,i,j) \
|
||||
(FLAC__stream_decoder_init_ogg_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)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* this code was based on flac123, from flac-tools */
|
||||
|
||||
@ -339,30 +340,34 @@ static MpdTag *flacTagDup(char *file)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
|
||||
InputStream * inStream)
|
||||
static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
|
||||
InputStream * inStream, int is_ogg)
|
||||
{
|
||||
flac_decoder *flacDec;
|
||||
FlacData data;
|
||||
int ret = 0;
|
||||
const char *err = NULL;
|
||||
|
||||
if (!(flacDec = flac_new()))
|
||||
return -1;
|
||||
init_FlacData(&data, cb, dc, inStream);
|
||||
if (!flac_init(flacDec, flacRead, flacSeek, flacTell, flacLength,
|
||||
flacEOF, flacWrite, flacMetadata, flacError,
|
||||
(void *)&data)) {
|
||||
ERROR("flac problem doing init()\n");
|
||||
flacPrintErroredState(flac_get_state(flacDec));
|
||||
ret = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!flac_process_metadata(flacDec)) {
|
||||
ERROR("flac problem reading metadata\n");
|
||||
flacPrintErroredState(flac_get_state(flacDec));
|
||||
ret = -1;
|
||||
goto fail;
|
||||
if (is_ogg) {
|
||||
if (!flac_ogg_init(flacDec, flacRead, flacSeek, flacTell,
|
||||
flacLength, flacEOF, flacWrite, flacMetadata,
|
||||
flacError, (void *)&data)) {
|
||||
err = "doing Ogg init()";
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if (!flac_init(flacDec, flacRead, flacSeek, flacTell,
|
||||
flacLength, flacEOF, flacWrite, flacMetadata,
|
||||
flacError, (void *)&data)) {
|
||||
err = "doing init()";
|
||||
goto fail;
|
||||
}
|
||||
if (!flac_process_metadata(flacDec)) {
|
||||
err = "problem reading metadata";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
dc->state = DECODE_STATE_DECODE;
|
||||
@ -412,15 +417,97 @@ fail:
|
||||
|
||||
closeInputStream(inStream);
|
||||
|
||||
if (err) {
|
||||
ERROR("flac %s\n", err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
|
||||
InputStream * inStream)
|
||||
{
|
||||
return flac_decode_internal(cb, dc, inStream, 0);
|
||||
}
|
||||
|
||||
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7
|
||||
# define flac_plugin_init NULL
|
||||
#else /* FLAC_API_VERSION_CURRENT >= 7 */
|
||||
/* some of this stuff is duplicated from oggflac_plugin.c */
|
||||
extern InputPlugin oggflacPlugin;
|
||||
|
||||
static MpdTag *oggflac_tag_dup(char *file)
|
||||
{
|
||||
MpdTag *ret = NULL;
|
||||
FLAC__Metadata_Iterator *it;
|
||||
FLAC__StreamMetadata *block;
|
||||
FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();
|
||||
|
||||
if (!(FLAC__metadata_chain_read_ogg(chain, file)))
|
||||
goto out;
|
||||
it = FLAC__metadata_iterator_new();
|
||||
FLAC__metadata_iterator_init(it, chain);
|
||||
do {
|
||||
if (!(block = FLAC__metadata_iterator_get_block(it)))
|
||||
break;
|
||||
if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
|
||||
ret = copyVorbisCommentBlockToMpdTag(block, ret);
|
||||
} else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
|
||||
if (!ret)
|
||||
ret = newMpdTag();
|
||||
ret->time = ((float)block->data.stream_info.
|
||||
total_samples) /
|
||||
block->data.stream_info.sample_rate + 0.5;
|
||||
}
|
||||
} while (FLAC__metadata_iterator_next(it));
|
||||
FLAC__metadata_iterator_delete(it);
|
||||
out:
|
||||
FLAC__metadata_chain_delete(chain);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int oggflac_decode(OutputBuffer * cb, DecoderControl * dc,
|
||||
InputStream * inStream)
|
||||
{
|
||||
return flac_decode_internal(cb, dc, inStream, 1);
|
||||
}
|
||||
|
||||
static unsigned int oggflac_try_decode(InputStream * inStream)
|
||||
{
|
||||
return (ogg_stream_type_detect(inStream) == FLAC) ? 1 : 0;
|
||||
}
|
||||
|
||||
static char *oggflac_suffixes[] = { "ogg", NULL };
|
||||
static char *oggflac_mime_types[] = { "application/ogg", NULL };
|
||||
|
||||
static int flac_plugin_init(void)
|
||||
{
|
||||
if (!FLAC_API_SUPPORTS_OGG_FLAC) {
|
||||
DEBUG("libFLAC does not support OggFLAC\n");
|
||||
return 1;
|
||||
}
|
||||
DEBUG("libFLAC supports OggFLAC, initializing OggFLAC support\n");
|
||||
assert(oggflacPlugin.name == NULL);
|
||||
oggflacPlugin.name = "oggflac";
|
||||
oggflacPlugin.tryDecodeFunc = oggflac_try_decode;
|
||||
oggflacPlugin.streamDecodeFunc = oggflac_decode;
|
||||
oggflacPlugin.tagDupFunc = oggflac_tag_dup;
|
||||
oggflacPlugin.streamTypes = INPUT_PLUGIN_STREAM_URL |
|
||||
INPUT_PLUGIN_STREAM_FILE;
|
||||
oggflacPlugin.suffixes = oggflac_suffixes;
|
||||
oggflacPlugin.mimeTypes = oggflac_mime_types;
|
||||
loadInputPlugin(&oggflacPlugin);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* FLAC_API_VERSION_CURRENT >= 7 */
|
||||
|
||||
static char *flacSuffixes[] = { "flac", NULL };
|
||||
static char *flac_mime_types[] = { "application/x-flac", NULL };
|
||||
|
||||
InputPlugin flacPlugin = {
|
||||
"flac",
|
||||
NULL,
|
||||
flac_plugin_init,
|
||||
NULL,
|
||||
NULL,
|
||||
flac_decode,
|
||||
|
Loading…
Reference in New Issue
Block a user