diff options
Diffstat (limited to '')
-rw-r--r-- | src/decoder/oggflac_decoder_plugin.c (renamed from src/decoder/oggflac_plugin.c) | 84 |
1 files changed, 32 insertions, 52 deletions
diff --git a/src/decoder/oggflac_plugin.c b/src/decoder/oggflac_decoder_plugin.c index bdd589ccb..7e5f48318 100644 --- a/src/decoder/oggflac_plugin.c +++ b/src/decoder/oggflac_decoder_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2009 The Music Player Daemon Project + * Copyright (C) 2003-2010 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,19 +21,18 @@ * OggFLAC support (half-stolen from flac_plugin.c :)) */ +#include "config.h" /* must be first for large file support */ #include "_flac_common.h" #include "_ogg_common.h" +#include "flac_metadata.h" #include <glib.h> #include <OggFLAC/seekable_stream_decoder.h> #include <assert.h> #include <unistd.h> -static void oggflac_cleanup(struct flac_data *data, - OggFLAC__SeekableStreamDecoder * decoder) +static void oggflac_cleanup(OggFLAC__SeekableStreamDecoder * decoder) { - if (data->replay_gain_info) - replay_gain_info_free(data->replay_gain_info); if (decoder) OggFLAC__seekable_stream_decoder_delete(decoder); } @@ -67,7 +66,7 @@ static OggFLAC__SeekableStreamDecoderSeekStatus of_seek_cb(G_GNUC_UNUSED const { struct flac_data *data = (struct flac_data *) fdata; - if (!input_stream_seek(data->input_stream, offset, SEEK_SET)) + if (!input_stream_seek(data->input_stream, offset, SEEK_SET, NULL)) return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; return OggFLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; @@ -156,13 +155,8 @@ oggflac_write_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecoder *decoder, void *vdata) { struct flac_data *data = (struct flac_data *) vdata; - FLAC__uint32 samples = frame->header.blocksize; - float time_change; - time_change = ((float)samples) / frame->header.sample_rate; - data->time += time_change; - - return flac_common_write(data, frame, buf); + return flac_common_write(data, frame, buf, 0); } /* used by TagDup */ @@ -173,17 +167,7 @@ static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecode assert(data->tag != NULL); - switch (block->type) { - case FLAC__METADATA_TYPE_STREAMINFO: - data->tag->time = ((float)block->data.stream_info. - total_samples) / - block->data.stream_info.sample_rate + 0.5; - return; - case FLAC__METADATA_TYPE_VORBIS_COMMENT: - flac_vorbis_comments_to_tag(data->tag, NULL, block); - default: - break; - } + flac_tag_apply_metadata(data->tag, NULL, block); } /* used by decode */ @@ -259,24 +243,20 @@ fail: /* public functions: */ static struct tag * -oggflac_tag_dup(const char *file) +oggflac_stream_tag(struct input_stream *is) { - struct input_stream input_stream; OggFLAC__SeekableStreamDecoder *decoder; struct flac_data data; + struct tag *tag; - if (!input_stream_open(&input_stream, file)) - return NULL; - if (ogg_stream_type_detect(&input_stream) != FLAC) { - input_stream_close(&input_stream); + if (ogg_stream_type_detect(is) != FLAC) return NULL; - } /* rewind the stream, because ogg_stream_type_detect() has moved it */ - input_stream_seek(&input_stream, 0, SEEK_SET); + input_stream_seek(is, 0, SEEK_SET, NULL); - flac_data_init(&data, NULL, &input_stream); + flac_data_init(&data, NULL, is); data.tag = tag_new(); @@ -284,15 +264,17 @@ oggflac_tag_dup(const char *file) * data.tag will be set or unset, that's all we care about */ decoder = full_decoder_init_and_read_metadata(&data, 1); - oggflac_cleanup(&data, decoder); - input_stream_close(&input_stream); + oggflac_cleanup(decoder); - if (!tag_is_defined(data.tag)) { - tag_free(data.tag); + if (tag_is_defined(data.tag)) { + tag = data.tag; data.tag = NULL; - } + } else + tag = NULL; - return data.tag; + flac_data_deinit(&data); + + return tag; } static void @@ -300,13 +282,14 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) { OggFLAC__SeekableStreamDecoder *decoder = NULL; struct flac_data data; + struct audio_format audio_format; if (ogg_stream_type_detect(input_stream) != FLAC) return; /* rewind the stream, because ogg_stream_type_detect() has moved it */ - input_stream_seek(input_stream, 0, SEEK_SET); + input_stream_seek(input_stream, 0, SEEK_SET, NULL); flac_data_init(&data, mpd_decoder, input_stream); @@ -314,16 +297,13 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) goto fail; } - if (!audio_format_valid(&data.audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - data.audio_format.sample_rate, - data.audio_format.bits, - data.audio_format.channels); + if (!data.initialized) goto fail; - } - decoder_initialized(mpd_decoder, &data.audio_format, - input_stream->seekable, data.total_time); + decoder_initialized(mpd_decoder, &audio_format, + input_stream->seekable, + (float)data.total_frames / + (float)data.audio_format.sample_rate); while (true) { OggFLAC__seekable_stream_decoder_process_single(decoder); @@ -333,11 +313,10 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) } if (decoder_get_command(mpd_decoder) == DECODE_COMMAND_SEEK) { FLAC__uint64 seek_sample = decoder_seek_where(mpd_decoder) * - data.audio_format.sample_rate + 0.5; + data.audio_format.sample_rate; if (OggFLAC__seekable_stream_decoder_seek_absolute (decoder, seek_sample)) { - data.time = ((float)seek_sample) / - data.audio_format.sample_rate; + data.next_frame = seek_sample; data.position = 0; decoder_command_finished(mpd_decoder); } else @@ -352,7 +331,8 @@ oggflac_decode(struct decoder * mpd_decoder, struct input_stream *input_stream) } fail: - oggflac_cleanup(&data, decoder); + oggflac_cleanup(decoder); + flac_data_deinit(&data); } static const char *const oggflac_suffixes[] = { "ogg", "oga", NULL }; @@ -368,7 +348,7 @@ static const char *const oggflac_mime_types[] = { const struct decoder_plugin oggflac_decoder_plugin = { .name = "oggflac", .stream_decode = oggflac_decode, - .tag_dup = oggflac_tag_dup, + .stream_tag = oggflac_stream_tag, .suffixes = oggflac_suffixes, .mime_types = oggflac_mime_types }; |