aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/flac_decoder_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder/flac_decoder_plugin.c')
-rw-r--r--src/decoder/flac_decoder_plugin.c185
1 files changed, 87 insertions, 98 deletions
diff --git a/src/decoder/flac_decoder_plugin.c b/src/decoder/flac_decoder_plugin.c
index 9d980b79d..fb0b3502d 100644
--- a/src/decoder/flac_decoder_plugin.c
+++ b/src/decoder/flac_decoder_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2010 The Music Player Daemon Project
+ * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -50,7 +50,7 @@ flac_read_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
if (r == 0) {
if (decoder_get_command(data->decoder) != DECODE_COMMAND_NONE ||
- input_stream_eof(data->input_stream))
+ input_stream_lock_eof(data->input_stream))
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
else
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
@@ -68,7 +68,8 @@ flac_seek_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
if (!data->input_stream->seekable)
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
- if (!input_stream_seek(data->input_stream, offset, SEEK_SET, NULL))
+ if (!input_stream_lock_seek(data->input_stream, offset, SEEK_SET,
+ NULL))
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
@@ -109,53 +110,40 @@ flac_eof_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd, void *fdata)
return (decoder_get_command(data->decoder) != DECODE_COMMAND_NONE &&
decoder_get_command(data->decoder) != DECODE_COMMAND_SEEK) ||
- input_stream_eof(data->input_stream);
+ input_stream_lock_eof(data->input_stream);
}
static void
flac_error_cb(G_GNUC_UNUSED const FLAC__StreamDecoder *fd,
FLAC__StreamDecoderErrorStatus status, void *fdata)
{
- flac_error_common_cb("flac", status, (struct flac_data *) fdata);
+ flac_error_common_cb(status, (struct flac_data *) 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";
+ break;
}
- g_warning("%s\n", str);
+ g_warning("%s\n", FLAC__SeekableStreamDecoderStateString[state]);
}
#else /* FLAC_API_VERSION_CURRENT >= 7 */
static void flacPrintErroredState(FLAC__StreamDecoderState state)
{
- const char *str = ""; /* "" to silence compiler warning */
switch (state) {
case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
case FLAC__STREAM_DECODER_READ_METADATA:
@@ -163,23 +151,16 @@ static void flacPrintErroredState(FLAC__StreamDecoderState state)
case FLAC__STREAM_DECODER_READ_FRAME:
case FLAC__STREAM_DECODER_END_OF_STREAM:
return;
+
case FLAC__STREAM_DECODER_OGG_ERROR:
- str = "error in the Ogg layer";
- break;
case FLAC__STREAM_DECODER_SEEK_ERROR:
- str = "seek error";
- break;
case FLAC__STREAM_DECODER_ABORTED:
- str = "decoder aborted by read";
- break;
case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
- str = "allocation error";
- break;
case FLAC__STREAM_DECODER_UNINITIALIZED:
- str = "decoder uninitialized";
+ break;
}
- g_warning("%s\n", str);
+ g_warning("%s\n", FLAC__StreamDecoderStateString[state]);
}
#endif /* FLAC_API_VERSION_CURRENT >= 7 */
@@ -210,10 +191,11 @@ flac_write_cb(const FLAC__StreamDecoder *dec, const FLAC__Frame *frame,
return flac_common_write(data, frame, buf, nbytes);
}
-static struct tag *
-flac_tag_dup(const char *file)
+static bool
+flac_scan_file(const char *file,
+ const struct tag_handler *handler, void *handler_ctx)
{
- return flac_tag_load(file, NULL);
+ return flac_scan_file2(file, NULL, handler, handler_ctx);
}
/**
@@ -305,17 +287,56 @@ flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
/* end of this sub track */
break;
- if (!FLAC__stream_decoder_process_single(flac_dec)) {
- cmd = decoder_get_command(decoder);
- if (cmd != DECODE_COMMAND_SEEK)
- break;
+ if (!FLAC__stream_decoder_process_single(flac_dec) &&
+ decoder_get_command(decoder) == DECODE_COMMAND_NONE) {
+ /* a failure that was not triggered by a
+ decoder command */
+ flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec));
+ break;
}
}
+}
- if (cmd != DECODE_COMMAND_STOP) {
- flacPrintErroredState(FLAC__stream_decoder_get_state(flac_dec));
- FLAC__stream_decoder_finish(flac_dec);
- }
+static FLAC__StreamDecoderInitStatus
+stream_init_oggflac(FLAC__StreamDecoder *flac_dec, struct flac_data *data)
+{
+#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
+ return FLAC__stream_decoder_init_ogg_stream(flac_dec,
+ flac_read_cb,
+ flac_seek_cb,
+ flac_tell_cb,
+ flac_length_cb,
+ flac_eof_cb,
+ flac_write_cb,
+ flacMetadata,
+ flac_error_cb,
+ data);
+#else
+ (void)flac_dec;
+ (void)data;
+
+ return FLAC__STREAM_DECODER_INIT_STATUS_ERROR;
+#endif
+}
+
+static FLAC__StreamDecoderInitStatus
+stream_init_flac(FLAC__StreamDecoder *flac_dec, struct flac_data *data)
+{
+ return FLAC__stream_decoder_init_stream(flac_dec,
+ flac_read_cb, flac_seek_cb,
+ flac_tell_cb, flac_length_cb,
+ flac_eof_cb, flac_write_cb,
+ flacMetadata,
+ flac_error_cb,
+ data);
+}
+
+static FLAC__StreamDecoderInitStatus
+stream_init(FLAC__StreamDecoder *flac_dec, struct flac_data *data, bool is_ogg)
+{
+ return is_ogg
+ ? stream_init_oggflac(flac_dec, data)
+ : stream_init_flac(flac_dec, data);
}
static void
@@ -325,7 +346,6 @@ flac_decode_internal(struct decoder * decoder,
{
FLAC__StreamDecoder *flac_dec;
struct flac_data data;
- const char *err = NULL;
flac_dec = flac_decoder_new();
if (flac_dec == NULL)
@@ -334,58 +354,30 @@ flac_decode_internal(struct decoder * decoder,
flac_data_init(&data, decoder, input_stream);
data.tag = tag_new();
- if (is_ogg) {
+ FLAC__StreamDecoderInitStatus status =
+ stream_init(flac_dec, &data, is_ogg);
+ if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
+ flac_data_deinit(&data);
+ FLAC__stream_decoder_delete(flac_dec);
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
- FLAC__StreamDecoderInitStatus status =
- FLAC__stream_decoder_init_ogg_stream(flac_dec,
- flac_read_cb,
- flac_seek_cb,
- flac_tell_cb,
- flac_length_cb,
- flac_eof_cb,
- flac_write_cb,
- flacMetadata,
- flac_error_cb,
- (void *)&data);
- if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- err = "doing Ogg init()";
- goto fail;
- }
-#else
- goto fail;
+ g_warning("%s", FLAC__StreamDecoderInitStatusString[status]);
#endif
- } else {
- FLAC__StreamDecoderInitStatus status =
- FLAC__stream_decoder_init_stream(flac_dec,
- flac_read_cb,
- flac_seek_cb,
- flac_tell_cb,
- flac_length_cb,
- flac_eof_cb,
- flac_write_cb,
- flacMetadata,
- flac_error_cb,
- (void *)&data);
- if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
- err = "doing init()";
- goto fail;
- }
+ return;
}
if (!flac_decoder_initialize(&data, flac_dec, 0)) {
flac_data_deinit(&data);
+ FLAC__stream_decoder_finish(flac_dec);
FLAC__stream_decoder_delete(flac_dec);
return;
}
flac_decoder_loop(&data, flac_dec, 0, 0);
-fail:
flac_data_deinit(&data);
- FLAC__stream_decoder_delete(flac_dec);
- if (err)
- g_warning("%s\n", err);
+ FLAC__stream_decoder_finish(flac_dec);
+ FLAC__stream_decoder_delete(flac_dec);
}
static void
@@ -409,36 +401,33 @@ oggflac_init(G_GNUC_UNUSED const struct config_param *param)
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
-static struct tag *
-oggflac_tag_dup(const char *file)
+static bool
+oggflac_scan_file(const char *file,
+ const struct tag_handler *handler, void *handler_ctx)
{
- struct tag *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;
+ if (!(FLAC__metadata_chain_read_ogg(chain, file))) {
+ FLAC__metadata_chain_delete(chain);
+ return false;
+ }
+
it = FLAC__metadata_iterator_new();
FLAC__metadata_iterator_init(it, chain);
- ret = tag_new();
do {
if (!(block = FLAC__metadata_iterator_get_block(it)))
break;
- flac_tag_apply_metadata(ret, NULL, block);
+ flac_scan_metadata(NULL, block,
+ handler, handler_ctx);
} while (FLAC__metadata_iterator_next(it));
FLAC__metadata_iterator_delete(it);
- if (!tag_is_defined(ret)) {
- tag_free(ret);
- ret = NULL;
- }
-
-out:
FLAC__metadata_chain_delete(chain);
- return ret;
+ return true;
}
static void
@@ -449,7 +438,7 @@ oggflac_decode(struct decoder *decoder, struct input_stream *input_stream)
/* rewind the stream, because ogg_stream_type_detect() has
moved it */
- input_stream_seek(input_stream, 0, SEEK_SET, NULL);
+ input_stream_lock_seek(input_stream, 0, SEEK_SET, NULL);
flac_decode_internal(decoder, input_stream, true);
}
@@ -471,7 +460,7 @@ const struct decoder_plugin oggflac_decoder_plugin = {
.init = oggflac_init,
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
.stream_decode = oggflac_decode,
- .tag_dup = oggflac_tag_dup,
+ .scan_file = oggflac_scan_file,
.suffixes = oggflac_suffixes,
.mime_types = oggflac_mime_types
#endif
@@ -491,7 +480,7 @@ static const char *const flac_mime_types[] = {
const struct decoder_plugin flac_decoder_plugin = {
.name = "flac",
.stream_decode = flac_decode,
- .tag_dup = flac_tag_dup,
+ .scan_file = flac_scan_file,
.suffixes = flac_suffixes,
.mime_types = flac_mime_types,
};