diff options
Diffstat (limited to 'src/decoder/vorbis_decoder_plugin.c')
-rw-r--r-- | src/decoder/vorbis_decoder_plugin.c | 131 |
1 files changed, 15 insertions, 116 deletions
diff --git a/src/decoder/vorbis_decoder_plugin.c b/src/decoder/vorbis_decoder_plugin.c index 0a3944ad6..15cdc0ca9 100644 --- a/src/decoder/vorbis_decoder_plugin.c +++ b/src/decoder/vorbis_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 @@ -18,9 +18,11 @@ */ #include "config.h" +#include "vorbis_comments.h" #include "_ogg_common.h" #include "audio_check.h" #include "uri.h" +#include "tag_handler.h" #ifndef HAVE_TREMOR #define OV_EXCLUDE_STATIC_CALLBACKS @@ -42,7 +44,6 @@ #include <assert.h> #include <errno.h> -#include <stdlib.h> #include <unistd.h> #undef G_LOG_DOMAIN @@ -80,7 +81,7 @@ static int ogg_seek_cb(void *data, ogg_int64_t offset, int whence) return vis->seekable && (!vis->decoder || decoder_get_command(vis->decoder) != DECODE_COMMAND_STOP) && - input_stream_seek(vis->input_stream, offset, whence, NULL) + input_stream_lock_seek(vis->input_stream, offset, whence, NULL) ? 0 : -1; } @@ -150,108 +151,6 @@ vorbis_is_open(struct vorbis_input_stream *vis, OggVorbis_File *vf, return true; } -static const char * -vorbis_comment_value(const char *comment, const char *needle) -{ - size_t len = strlen(needle); - - if (g_ascii_strncasecmp(comment, needle, len) == 0 && - comment[len] == '=') - return comment + len + 1; - - return NULL; -} - -static bool -vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments) -{ - const char *temp; - bool found = false; - - replay_gain_info_init(rgi); - - while (*comments) { - if ((temp = - vorbis_comment_value(*comments, "replaygain_track_gain"))) { - rgi->tuples[REPLAY_GAIN_TRACK].gain = atof(temp); - found = true; - } else if ((temp = vorbis_comment_value(*comments, - "replaygain_album_gain"))) { - rgi->tuples[REPLAY_GAIN_ALBUM].gain = atof(temp); - found = true; - } else if ((temp = vorbis_comment_value(*comments, - "replaygain_track_peak"))) { - rgi->tuples[REPLAY_GAIN_TRACK].peak = atof(temp); - found = true; - } else if ((temp = vorbis_comment_value(*comments, - "replaygain_album_peak"))) { - rgi->tuples[REPLAY_GAIN_ALBUM].peak = atof(temp); - found = true; - } - - comments++; - } - - return found; -} - -static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; -static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; - -/** - * Check if the comment's name equals the passed name, and if so, copy - * the comment value into the tag. - */ -static bool -vorbis_copy_comment(struct tag *tag, const char *comment, - const char *name, enum tag_type tag_type) -{ - const char *value; - - value = vorbis_comment_value(comment, name); - if (value != NULL) { - tag_add_item(tag, tag_type, value); - return true; - } - - return false; -} - -static void -vorbis_parse_comment(struct tag *tag, const char *comment) -{ - assert(tag != NULL); - - if (vorbis_copy_comment(tag, comment, VORBIS_COMMENT_TRACK_KEY, - TAG_TRACK) || - vorbis_copy_comment(tag, comment, VORBIS_COMMENT_DISC_KEY, - TAG_DISC) || - vorbis_copy_comment(tag, comment, "album artist", - TAG_ALBUM_ARTIST)) - return; - - for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) - if (vorbis_copy_comment(tag, comment, - tag_item_names[i], i)) - return; -} - -static struct tag * -vorbis_comments_to_tag(char **comments) -{ - struct tag *tag = tag_new(); - - while (*comments) - vorbis_parse_comment(tag, *comments++); - - if (tag_is_empty(tag)) { - tag_free(tag); - tag = NULL; - } - - return tag; -} - static void vorbis_send_comments(struct decoder *decoder, struct input_stream *is, char **comments) @@ -290,7 +189,7 @@ vorbis_stream_decode(struct decoder *decoder, /* 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); if (!vorbis_is_open(&vis, &vf, decoder, input_stream)) return; @@ -370,24 +269,24 @@ vorbis_stream_decode(struct decoder *decoder, ov_clear(&vf); } -static struct tag * -vorbis_stream_tag(struct input_stream *is) +static bool +vorbis_scan_stream(struct input_stream *is, + const struct tag_handler *handler, void *handler_ctx) { struct vorbis_input_stream vis; OggVorbis_File vf; if (!vorbis_is_open(&vis, &vf, NULL, is)) - return NULL; + return false; - struct tag *tag = vorbis_comments_to_tag(ov_comment(&vf, -1)->user_comments); + tag_handler_invoke_duration(handler, handler_ctx, + (int)(ov_time_total(&vf, -1) + 0.5)); - if (tag == NULL) - tag = tag_new(); - tag->time = (int)(ov_time_total(&vf, -1) + 0.5); + vorbis_comments_scan(ov_comment(&vf, -1)->user_comments, + handler, handler_ctx); ov_clear(&vf); - - return tag; + return true; } static const char *const vorbis_suffixes[] = { @@ -409,7 +308,7 @@ static const char *const vorbis_mime_types[] = { const struct decoder_plugin vorbis_decoder_plugin = { .name = "vorbis", .stream_decode = vorbis_stream_decode, - .stream_tag = vorbis_stream_tag, + .scan_stream = vorbis_scan_stream, .suffixes = vorbis_suffixes, .mime_types = vorbis_mime_types }; |