aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/vorbis_decoder_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder/vorbis_decoder_plugin.c')
-rw-r--r--src/decoder/vorbis_decoder_plugin.c131
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
};