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_decoder FLAC__SeekableStreamDecoder
|
||||||
# define flac_new(x) FLAC__seekable_stream_decoder_new(x)
|
# 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) \
|
# define flac_get_decode_position(x,y) \
|
||||||
FLAC__seekable_stream_decoder_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_get_state(x) FLAC__seekable_stream_decoder_get_state(x)
|
||||||
@ -78,18 +80,26 @@
|
|||||||
# include <OggFLAC/seekable_stream_decoder.h>
|
# include <OggFLAC/seekable_stream_decoder.h>
|
||||||
# endif
|
# endif
|
||||||
#else /* FLAC_API_VERSION_CURRENT >= 7 */
|
#else /* FLAC_API_VERSION_CURRENT >= 7 */
|
||||||
/* OggFLAC support is handled by our flac_plugin already */
|
|
||||||
# ifdef HAVE_OGGFLAC
|
/* OggFLAC support is handled by our flac_plugin already, and
|
||||||
# undef HAVE_OGGFLAC
|
* thus we *can* always have it if libFLAC was compiled with it */
|
||||||
|
# ifndef HAVE_OGGFLAC
|
||||||
|
# define HAVE_OGGFLAC 1
|
||||||
# endif
|
# endif
|
||||||
# include <FLAC/stream_decoder.h>
|
|
||||||
# include "_ogg_common.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_decoder FLAC__StreamDecoder
|
||||||
# define flac_new(x) FLAC__stream_decoder_new(x)
|
# define flac_new(x) FLAC__stream_decoder_new(x)
|
||||||
|
|
||||||
# define flac_init(a,b,c,d,e,f,g,h,i,j) \
|
# 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_stream(a,b,c,d,e,f,g,h,i,j) \
|
||||||
== FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
== 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) \
|
# define flac_get_decode_position(x,y) \
|
||||||
FLAC__stream_decoder_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_get_state(x) FLAC__stream_decoder_get_state(x)
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/* this code was based on flac123, from flac-tools */
|
/* this code was based on flac123, from flac-tools */
|
||||||
|
|
||||||
@ -339,30 +340,34 @@ static MpdTag *flacTagDup(char *file)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flac_decode(OutputBuffer * cb, DecoderControl * dc,
|
static int flac_decode_internal(OutputBuffer * cb, DecoderControl * dc,
|
||||||
InputStream * inStream)
|
InputStream * inStream, int is_ogg)
|
||||||
{
|
{
|
||||||
flac_decoder *flacDec;
|
flac_decoder *flacDec;
|
||||||
FlacData data;
|
FlacData data;
|
||||||
int ret = 0;
|
const char *err = NULL;
|
||||||
|
|
||||||
if (!(flacDec = flac_new()))
|
if (!(flacDec = flac_new()))
|
||||||
return -1;
|
return -1;
|
||||||
init_FlacData(&data, cb, dc, inStream);
|
init_FlacData(&data, cb, dc, inStream);
|
||||||
if (!flac_init(flacDec, flacRead, flacSeek, flacTell, flacLength,
|
if (is_ogg) {
|
||||||
flacEOF, flacWrite, flacMetadata, flacError,
|
if (!flac_ogg_init(flacDec, flacRead, flacSeek, flacTell,
|
||||||
(void *)&data)) {
|
flacLength, flacEOF, flacWrite, flacMetadata,
|
||||||
ERROR("flac problem doing init()\n");
|
flacError, (void *)&data)) {
|
||||||
flacPrintErroredState(flac_get_state(flacDec));
|
err = "doing Ogg init()";
|
||||||
ret = -1;
|
goto fail;
|
||||||
goto fail;
|
}
|
||||||
}
|
} else {
|
||||||
|
if (!flac_init(flacDec, flacRead, flacSeek, flacTell,
|
||||||
if (!flac_process_metadata(flacDec)) {
|
flacLength, flacEOF, flacWrite, flacMetadata,
|
||||||
ERROR("flac problem reading metadata\n");
|
flacError, (void *)&data)) {
|
||||||
flacPrintErroredState(flac_get_state(flacDec));
|
err = "doing init()";
|
||||||
ret = -1;
|
goto fail;
|
||||||
goto fail;
|
}
|
||||||
|
if (!flac_process_metadata(flacDec)) {
|
||||||
|
err = "problem reading metadata";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc->state = DECODE_STATE_DECODE;
|
dc->state = DECODE_STATE_DECODE;
|
||||||
@ -412,15 +417,97 @@ fail:
|
|||||||
|
|
||||||
closeInputStream(inStream);
|
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;
|
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 *flacSuffixes[] = { "flac", NULL };
|
||||||
static char *flac_mime_types[] = { "application/x-flac", NULL };
|
static char *flac_mime_types[] = { "application/x-flac", NULL };
|
||||||
|
|
||||||
InputPlugin flacPlugin = {
|
InputPlugin flacPlugin = {
|
||||||
"flac",
|
"flac",
|
||||||
NULL,
|
flac_plugin_init,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
flac_decode,
|
flac_decode,
|
||||||
|
Loading…
Reference in New Issue
Block a user