aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder_api.c')
-rw-r--r--src/decoder_api.c124
1 files changed, 59 insertions, 65 deletions
diff --git a/src/decoder_api.c b/src/decoder_api.c
index 0f25daadb..1f5db3b72 100644
--- a/src/decoder_api.c
+++ b/src/decoder_api.c
@@ -38,7 +38,8 @@ void decoder_initialized(struct decoder * decoder,
{
assert(dc.state == DECODE_STATE_START);
assert(decoder != NULL);
- assert(!decoder->stream_tag_sent);
+ assert(decoder->stream_tag == NULL);
+ assert(decoder->decoder_tag == NULL);
assert(!decoder->seeking);
assert(audio_format != NULL);
assert(audio_format_defined(audio_format));
@@ -135,33 +136,6 @@ 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.
*/
@@ -195,6 +169,25 @@ do_send_tag(struct input_stream *is, const struct tag *tag)
return DECODE_COMMAND_NONE;
}
+static bool
+update_stream_tag(struct decoder *decoder, struct input_stream *is)
+{
+ struct tag *tag;
+
+ if (is == NULL)
+ return false;
+
+ tag = input_stream_tag(is);
+ if (tag == NULL)
+ return false;
+
+ if (decoder->stream_tag != NULL)
+ tag_free(decoder->stream_tag);
+
+ decoder->stream_tag = tag;
+ return true;
+}
+
enum decoder_command
decoder_data(struct decoder *decoder,
struct input_stream *is,
@@ -214,36 +207,25 @@ decoder_data(struct decoder *decoder,
length == 0)
return dc.command;
- if (is != NULL && !decoder->stream_tag_sent) {
- const struct tag *src;
- struct tag *tag1, *tag2;
-
- /* base is the current song's tag, or an empty new
- tag if the song has no tag */
- src = dc.current_song->tag;
- if (src == NULL)
- src = tag1 = tag_new();
- else
- tag1 = NULL;
-
- tag2 = tag_add_stream_tags(src, is);
- if (tag1 != NULL)
- /* free the empty tag created by tag_new(), we
- aren't going to send it */
- tag_free(tag1);
-
- if (tag2 != NULL)
- /* use the composite tag returned by
- tag_add_stream_tags() */
- src = tag2;
-
- if (src != NULL) {
- music_pipe_tag(src);
- if (tag2 != NULL)
- tag_free(tag2);
- }
+ /* send stream tags */
+
+ if (update_stream_tag(decoder, is)) {
+ enum decoder_command cmd;
- decoder->stream_tag_sent = true;
+ if (decoder->decoder_tag != NULL) {
+ /* merge with tag from decoder plugin */
+ struct tag *tag;
+
+ tag = tag_merge(decoder->stream_tag,
+ decoder->decoder_tag);
+ cmd = do_send_tag(is, tag);
+ tag_free(tag);
+ } else
+ /* send only the stream tag */
+ cmd = do_send_tag(is, decoder->stream_tag);
+
+ if (cmd != DECODE_COMMAND_NONE)
+ return cmd;
}
if (audio_format_equals(&dc.in_audio_format, &dc.out_audio_format)) {
@@ -299,21 +281,33 @@ enum decoder_command
decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
const struct tag *tag)
{
- struct tag *tag2 = is != NULL ? tag_add_stream_tags(tag, is) : NULL;
enum decoder_command cmd;
assert(dc.state == DECODE_STATE_DECODE);
+ assert(tag != NULL);
+
+ /* save the tag */
+
+ if (decoder->decoder_tag != NULL)
+ tag_free(decoder->decoder_tag);
+ decoder->decoder_tag = tag_dup(tag);
+
+ /* check for a new stream tag */
- if (tag2 != NULL)
- tag = tag2;
+ update_stream_tag(decoder, is);
- cmd = do_send_tag(is, tag);
+ /* send tag to music pipe */
- if (tag2 != NULL)
- tag_free(tag2);
+ if (decoder->stream_tag != NULL) {
+ /* merge with tag from input stream */
+ struct tag *merged;
- if (cmd == DECODE_COMMAND_NONE)
- decoder->stream_tag_sent = true;
+ merged = tag_merge(decoder->stream_tag, decoder->decoder_tag);
+ cmd = do_send_tag(is, merged);
+ tag_free(merged);
+ } else
+ /* send only the decoder tag */
+ cmd = do_send_tag(is, tag);
return cmd;
}