From ba3a8474b6b3ef1355cf7173de2622adc34fce2e Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Sun, 1 Mar 2009 14:07:23 +0100
Subject: flac: parse stream tags

Parse the vorbis comments in libflac's metadata_callback and pass them
as tag struct to the decoder API.
---
 NEWS                       |  1 +
 src/decoder/_flac_common.c |  4 ++++
 src/decoder/flac_plugin.c  | 17 +++++++++++++++--
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index aa74e95dc..de61061d4 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ ver 0.15 - (200?/??/??)
   - sidplay: new decoder plugin for C64 SID (using libsidplay2)
   - fluidsynth: new decoder plugin for MIDI files (using libfluidsynth)
   - wildmidi: another decoder plugin for MIDI files (using libwildmidi)
+  - flac: parse stream tags
   - added configuration option to disable decoder plugins
 * audio outputs:
   - added option to disable audio outputs by default
diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c
index 6c2d19fd9..24c766ddb 100644
--- a/src/decoder/_flac_common.c
+++ b/src/decoder/_flac_common.c
@@ -187,6 +187,10 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
 		break;
 	case FLAC__METADATA_TYPE_VORBIS_COMMENT:
 		flac_parse_replay_gain(block, data);
+
+		if (data->tag != NULL)
+			flac_vorbis_comments_to_tag(data->tag, block);
+
 	default:
 		break;
 	}
diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c
index ce056d298..ec9495fda 100644
--- a/src/decoder/flac_plugin.c
+++ b/src/decoder/flac_plugin.c
@@ -292,6 +292,7 @@ flac_decode_internal(struct decoder * decoder,
 {
 	flac_decoder *flac_dec;
 	struct flac_data data;
+	enum decoder_command cmd;
 	const char *err = NULL;
 
 	if (!(flac_dec = flac_new()))
@@ -326,6 +327,8 @@ flac_decode_internal(struct decoder * decoder,
 		}
 	}
 
+	data.tag = tag_new();
+
 	if (!flac_process_metadata(flac_dec)) {
 		err = "problem reading metadata";
 		goto fail;
@@ -343,9 +346,17 @@ flac_decode_internal(struct decoder * decoder,
 			    input_stream->seekable, data.total_time);
 
 	while (true) {
+		if (!tag_is_empty(data.tag)) {
+			cmd = decoder_tag(decoder, input_stream, data.tag);
+			tag_free(data.tag);
+			data.tag = tag_new();
+		} else
+			cmd = decoder_get_command(decoder);
+
 		if (!flac_process_single(flac_dec))
 			break;
-		if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
+
+		if (cmd == DECODE_COMMAND_SEEK) {
 			FLAC__uint64 seek_sample = decoder_seek_where(decoder) *
 			    data.audio_format.sample_rate + 0.5;
 			if (flac_seek_absolute(flac_dec, seek_sample)) {
@@ -358,7 +369,7 @@ flac_decode_internal(struct decoder * decoder,
 		} else if (flac_get_state(flac_dec) == flac_decoder_eof)
 			break;
 	}
-	if (decoder_get_command(decoder) != DECODE_COMMAND_STOP) {
+	if (cmd != DECODE_COMMAND_STOP) {
 		flacPrintErroredState(flac_get_state(flac_dec));
 		flac_finish(flac_dec);
 	}
@@ -367,6 +378,8 @@ fail:
 	if (data.replay_gain_info)
 		replay_gain_info_free(data.replay_gain_info);
 
+	tag_free(data.tag);
+
 	if (flac_dec)
 		flac_delete(flac_dec);
 
-- 
cgit v1.2.3