From b169b0a68f1992ec0171754cc755c3c623d2101b Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Fri, 28 Nov 2003 13:04:21 +0000 Subject: [PATCH] Use new tagging stuff to read and write flac metadata. Only handles vorbiscomment tags, and not (older) id3v2 tags. Original commit message from CVS: Use new tagging stuff to read and write flac metadata. Only handles vorbiscomment tags, and not (older) id3v2 tags. --- ext/flac/gstflac.c | 4 ++ ext/flac/gstflacdec.c | 88 ++++++++--------------------------------- ext/flac/gstflacdec.h | 1 - ext/flac/gstflacenc.c | 106 ++++++++++++++++++++++++++------------------------ ext/flac/gstflacenc.h | 4 +- 5 files changed, 77 insertions(+), 126 deletions(-) diff --git a/ext/flac/gstflac.c b/ext/flac/gstflac.c index 6b399ef..a52b94f 100644 --- a/ext/flac/gstflac.c +++ b/ext/flac/gstflac.c @@ -32,6 +32,10 @@ plugin_init (GstPlugin *plugin) if (!gst_library_load ("gstbytestream")) return FALSE; + /* we need the gsttags plugin for metadata querying */ + if (!gst_plugin_load ("gsttags")) + return FALSE; + if (!gst_element_register (plugin, "flacenc", GST_RANK_NONE, GST_TYPE_FLACENC)) return FALSE; diff --git a/ext/flac/gstflacdec.c b/ext/flac/gstflacdec.c index 5f775b4..a67c4a9 100644 --- a/ext/flac/gstflacdec.c +++ b/ext/flac/gstflacdec.c @@ -25,6 +25,9 @@ /*#define DEBUG_ENABLED */ #include "gstflacdec.h" +#include + +#include #include "flac_compat.h" @@ -66,14 +69,6 @@ static gboolean gst_flacdec_src_query (GstPad *pad, GstQueryType type, static const GstEventMask* gst_flacdec_get_src_event_masks (GstPad *pad); static gboolean gst_flacdec_src_event (GstPad *pad, GstEvent *event); -static void gst_flacdec_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gst_flacdec_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); static FLAC__SeekableStreamDecoderReadStatus gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder, @@ -186,14 +181,7 @@ gst_flacdec_class_init (FlacDecClass *klass) gobject_class = (GObjectClass*) klass; parent_class = g_type_class_ref(GST_TYPE_ELEMENT); - - g_object_class_install_property (gobject_class, ARG_METADATA, - g_param_spec_boxed ("metadata", "Metadata", "(logical) Stream metadata", - GST_TYPE_CAPS, G_PARAM_READABLE)); - gobject_class->get_property = gst_flacdec_get_property; - gobject_class->set_property = gst_flacdec_set_property; - gstelement_class->change_state = gst_flacdec_change_state; } @@ -219,7 +207,6 @@ gst_flacdec_init (FlacDec *flacdec) flacdec->init = TRUE; flacdec->eos = FALSE; flacdec->seek_pending = FALSE; - flacdec->metadata = NULL; FLAC__seekable_stream_decoder_set_read_callback (flacdec->decoder, gst_flacdec_read); FLAC__seekable_stream_decoder_set_seek_callback (flacdec->decoder, gst_flacdec_seek); @@ -246,20 +233,15 @@ gst_flacdec_init (FlacDec *flacdec) static gboolean gst_flacdec_update_metadata (FlacDec *flacdec, const FLAC__StreamMetadata *metadata) { + GstTagList *list; guint32 number_of_comments, cursor, str_len; gchar *p_value, *value, *name, *str_ptr; - GstProps *props = NULL; - GstPropsEntry *entry; - - /* clear old one */ - if (flacdec->metadata) { - gst_caps_unref (flacdec->metadata); - flacdec->metadata = NULL; + + list = gst_tag_list_new (); + if (list == NULL) { + return FALSE; } - /* create props to hold the key/value pairs */ - props = gst_props_empty_new (); - number_of_comments = metadata->data.vorbis_comment.num_comments; value = NULL; GST_DEBUG ("%d tag(s) found", number_of_comments); @@ -271,23 +253,20 @@ gst_flacdec_update_metadata (FlacDec *flacdec, const FLAC__StreamMetadata *metad if (p_value) { name = g_strndup (str_ptr, p_value - str_ptr); - value = g_strndup (p_value + 1, str_ptr + str_len - p_value); + value = g_strndup (p_value + 1, str_ptr + str_len - p_value - 1); - entry = gst_props_entry_new (name, GST_PROPS_STRING_TYPE, value); - gst_props_add_entry (props, (GstPropsEntry *) entry); - GST_DEBUG ("%s : %s", name, value); - + gst_vorbis_tag_add (list, name, value); g_free (name); g_free (value); } } - - flacdec->metadata = gst_caps_new ("vorbisfile_metadata", - "application/x-gst-metadata", - props); - g_object_notify (G_OBJECT (flacdec), "metadata"); - + + + gst_element_found_tags (GST_ELEMENT (flacdec), list); + if (GST_PAD_IS_USABLE (flacdec->srcpad)) { + gst_pad_push (flacdec->srcpad, GST_DATA (gst_event_new_tag (list))); + } return TRUE; } @@ -790,38 +769,3 @@ gst_flacdec_change_state (GstElement *element) return GST_STATE_SUCCESS; } - -static void -gst_flacdec_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - FlacDec *flacdec; - - g_return_if_fail (GST_IS_FLACDEC (object)); - - flacdec = GST_FLACDEC (object); - - switch (prop_id) { - default: - g_warning ("Unknown property id\n"); - } -} - -static void -gst_flacdec_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - FlacDec *flacdec; - - g_return_if_fail (GST_IS_FLACDEC(object)); - - flacdec = GST_FLACDEC (object); - - switch (prop_id) { - case ARG_METADATA: - g_value_set_boxed (value, flacdec->metadata); - break; - default: - g_warning ("Unknown property id\n"); - } -} diff --git a/ext/flac/gstflacdec.h b/ext/flac/gstflacdec.h index b5a1e17..ba62e52 100644 --- a/ext/flac/gstflacdec.h +++ b/ext/flac/gstflacdec.h @@ -45,7 +45,6 @@ struct _FlacDec { GstElement element; GstPad *sinkpad,*srcpad; - GstCaps *metadata; GstByteStream *bs; FLAC__SeekableStreamDecoder *decoder; diff --git a/ext/flac/gstflacenc.c b/ext/flac/gstflacenc.c index 68597f3..d8928a0 100644 --- a/ext/flac/gstflacenc.c +++ b/ext/flac/gstflacenc.c @@ -25,7 +25,8 @@ #include #include - +#include +#include #include "flac_compat.h" static GstPadTemplate *src_template, *sink_template; @@ -108,7 +109,15 @@ flacenc_get_type (void) 0, (GInstanceInitFunc)gst_flacenc_init, }; + + static const GInterfaceInfo tag_setter_info = { + NULL, + NULL, + NULL + }; + flacenc_type = g_type_register_static (GST_TYPE_ELEMENT, "FlacEnc", &flacenc_info, 0); + g_type_add_interface_static (flacenc_type, GST_TYPE_TAG_SETTER, &tag_setter_info); } return flacenc_type; } @@ -333,31 +342,13 @@ gst_flacenc_init (FlacEnc *flacenc) FLAC__seekable_stream_encoder_set_client_data (flacenc->encoder, flacenc); - - flacenc->metadata = GST_CAPS_NEW ( - "flacenc_metadata", - "application/x-gst-metadata", - "DESCRIPTION", GST_PROPS_STRING ("Track encoded with GStreamer"), - "DATE", GST_PROPS_STRING (""), - "TRACKNUMBER", GST_PROPS_STRING (""), - "TITLE", GST_PROPS_STRING (""), - "ARTIST", GST_PROPS_STRING (""), - "ALBUM", GST_PROPS_STRING (""), - "GENRE", GST_PROPS_STRING (""), - "VERSION", GST_PROPS_STRING (""), - "COPYRIGHT", GST_PROPS_STRING (""), - "LICENSE", GST_PROPS_STRING (""), - "ORGANISATION", GST_PROPS_STRING (""), - "LOCATION", GST_PROPS_STRING (""), - "CONTACT", GST_PROPS_STRING (""), - "ISRC", GST_PROPS_STRING ("") - ); flacenc->negotiated = FALSE; flacenc->first = TRUE; flacenc->first_buf = NULL; flacenc->data = NULL; gst_flacenc_update_quality (flacenc, DEFAULT_QUALITY); + flacenc->tags = gst_tag_list_new (); } static void @@ -492,46 +483,51 @@ gst_flacenc_write_callback (const FLAC__SeekableStreamEncoder *encoder, return FLAC__STREAM_ENCODER_OK; } +void add_one_tag (const GstTagList *list, + const gchar *tag, + gpointer user_data) +{ + GList *comments; + GList *it; + FlacEnc *flacenc = GST_FLACENC (user_data); + + comments = gst_tag_to_vorbis_comments (list, tag); + for (it = comments; it != NULL; it = it->next) { + FLAC__StreamMetadata_VorbisComment_Entry commment_entry; + commment_entry.length = GUINT32_TO_LE (strlen(it->data) + 1); + commment_entry.entry = it->data; + FLAC__metadata_object_vorbiscomment_insert_comment (flacenc->meta[0], + flacenc->meta[0]->data.vorbis_comment.num_comments, + commment_entry, + TRUE); + g_free (it->data); + } + g_list_free (comments); +} + static void -gst_flacenc_set_metadata (FlacEnc *flacenc, GstCaps *caps) +gst_flacenc_set_metadata (FlacEnc *flacenc) { - guint indice; - guint comments; - const gchar *meta_types[] = { "TITLE", "VERSION", "ALBUM", "TRACKNUMBER", - "ARTIST", "PERFORMER", "COPYRIGHT", "LICENSE", - "ORGANISATION", "DESCRIPTION", "GENRE", "DATE", - "LOCATION", "CONTACT", "ISRC", NULL }; + const GstTagList *user_tags; + GstTagList *copy; g_return_if_fail (flacenc != NULL); - + user_tags = gst_tag_setter_get_list (GST_TAG_SETTER (flacenc)); + if ((flacenc->tags == NULL) && (user_tags == NULL)) { + return; + } + copy = gst_tag_list_merge (user_tags, flacenc->tags, + gst_tag_setter_get_merge_mode (GST_TAG_SETTER (flacenc))); flacenc->meta = g_malloc (sizeof (FLAC__StreamMetadata **)); flacenc->meta[0] = FLAC__metadata_object_new (FLAC__METADATA_TYPE_VORBIS_COMMENT); - - for ( indice = 0, comments=0; meta_types[indice] != NULL; indice++) { - if (gst_caps_has_property(caps, meta_types[indice])) { - const gchar *entry; - gchar *data; - FLAC__StreamMetadata_VorbisComment_Entry commment_entry; - - gst_caps_get_string(caps, (gchar *)meta_types[indice], &entry); - - if (!strcmp (entry, "")) - continue; - - data = g_strdup_printf("%s=%s", meta_types[indice], entry); - commment_entry.length = GUINT32_TO_LE (strlen(entry) + strlen(meta_types[indice]) + 1); - commment_entry.entry = g_convert (data, commment_entry.length, "UTF8", "ISO-8859-1", NULL, NULL, NULL); - - FLAC__metadata_object_vorbiscomment_insert_comment (flacenc->meta[0], comments++, commment_entry, TRUE); - } - } + gst_tag_list_foreach ((GstTagList*)copy, add_one_tag, flacenc); FLAC__seekable_stream_encoder_set_metadata(flacenc->encoder, flacenc->meta, 1); + gst_tag_list_free (copy); } - static void gst_flacenc_chain (GstPad *pad, GstData *_data) { @@ -553,10 +549,19 @@ gst_flacenc_chain (GstPad *pad, GstData *_data) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: FLAC__seekable_stream_encoder_finish(flacenc->encoder); + break; + case GST_EVENT_TAG: + if (flacenc->tags) { + gst_tag_list_merge (flacenc->tags, gst_event_tag_get_list (event), + gst_tag_setter_get_merge_mode (GST_TAG_SETTER (flacenc))); + } else { + g_assert_not_reached (); + } + break; default: - gst_pad_event_default (pad, event); break; } + gst_pad_event_default (pad, event); return; } @@ -575,8 +580,7 @@ gst_flacenc_chain (GstPad *pad, GstData *_data) FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) { FLAC__SeekableStreamEncoderState state; - - gst_flacenc_set_metadata (flacenc, flacenc->metadata); + gst_flacenc_set_metadata (flacenc); state = FLAC__seekable_stream_encoder_init (flacenc->encoder); if (state != FLAC__STREAM_ENCODER_OK) { gst_element_error (GST_ELEMENT (flacenc), diff --git a/ext/flac/gstflacenc.h b/ext/flac/gstflacenc.h index ac3254b..cc404de 100644 --- a/ext/flac/gstflacenc.h +++ b/ext/flac/gstflacenc.h @@ -44,8 +44,6 @@ struct _FlacEnc { GstPad *sinkpad,*srcpad; - GstCaps *metadata; - gboolean first; GstBuffer *first_buf; gboolean eos; @@ -59,6 +57,8 @@ struct _FlacEnc { FLAC__SeekableStreamEncoder *encoder; FLAC__StreamMetadata **meta; + + GstTagList * tags; }; struct _FlacEncClass { -- 2.7.4