From ac96022c1de5573b9c4ff03990ac07c4bba8e3f9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 3 Nov 2008 18:24:01 +0100 Subject: decoder_api: automatically send stream tag If an input stream provides tags (e.g. from an icecast server), send them in the decoder_data() and decoder_tag() methods. Removed the according code from the mp3 and oggvorbis plugins - decoders shouldn't have to care about stream tags. This patch also adds the missing decoder_tag() invocation to the mp3 plugin. --- src/decoder_api.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src/decoder_api.c') diff --git a/src/decoder_api.c b/src/decoder_api.c index e0dccdd01..6d577ec79 100644 --- a/src/decoder_api.c +++ b/src/decoder_api.c @@ -117,6 +117,33 @@ size_t decoder_read(struct decoder *decoder, } } +/** + * Add the tag items from the input stream (meta_name, meta_title) to + * a duplicate of the specified tag. The return value has to be freed + * with tag_free(). If this function returns NULL, then there are no + * tags provided by the stream. + */ +static struct tag * +tag_add_stream_tags(const struct tag *src_tag, const struct input_stream *is) +{ + struct tag *tag; + + assert(src_tag != NULL); + assert(is != NULL); + + if ((is->meta_name == NULL || tag_has_type(src_tag, TAG_ITEM_NAME)) && + (is->meta_title == NULL || tag_has_type(src_tag, TAG_ITEM_TITLE))) + return NULL; + + tag = tag_dup(src_tag); + if (is->meta_name != NULL && !tag_has_type(src_tag, TAG_ITEM_NAME)) + tag_add_item(tag, TAG_ITEM_NAME, is->meta_name); + if (is->meta_title != NULL && !tag_has_type(src_tag, TAG_ITEM_TITLE)) + tag_add_item(tag, TAG_ITEM_TITLE, is->meta_title); + + return tag; +} + /** * All chunks are full of decoded data; wait for the player to free * one. @@ -148,6 +175,20 @@ decoder_data(struct decoder *decoder, size_t nbytes; char *data; + if (is != NULL && !decoder->stream_tag_sent) { + struct tag *tag1 = tag_new(), *tag2; + + tag2 = tag_add_stream_tags(tag1, is); + tag_free(tag1); + + if (tag2 != NULL) { + music_pipe_tag(tag2); + tag_free(tag2); + } + + decoder->stream_tag_sent = true; + } + if (audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) { data = _data; } else { @@ -193,11 +234,21 @@ enum decoder_command decoder_tag(mpd_unused struct decoder *decoder, struct input_stream *is, const struct tag *tag) { + struct tag *tag2 = is != NULL ? tag_add_stream_tags(tag, is) : NULL; + + if (tag2 != NULL) + tag = tag2; + while (!music_pipe_tag(tag)) { enum decoder_command cmd = need_chunks(is); if (cmd != DECODE_COMMAND_NONE) return cmd; } + if (tag2 != NULL) + tag_free(tag2); + + decoder->stream_tag_sent = true; + return DECODE_COMMAND_NONE; } -- cgit v1.2.3