Use new tagging stuff to read and write flac metadata. Only handles vorbiscomment...
authorChristophe Fergeau <teuf@gnome.org>
Fri, 28 Nov 2003 13:04:21 +0000 (13:04 +0000)
committerChristophe Fergeau <teuf@gnome.org>
Fri, 28 Nov 2003 13:04:21 +0000 (13:04 +0000)
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
ext/flac/gstflacdec.c
ext/flac/gstflacdec.h
ext/flac/gstflacenc.c
ext/flac/gstflacenc.h

index 6b399ef..a52b94f 100644 (file)
@@ -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;
 
index 5f775b4..a67c4a9 100644 (file)
@@ -25,6 +25,9 @@
 
 /*#define DEBUG_ENABLED */
 #include "gstflacdec.h"
+#include <gst/gsttaginterface.h>
+
+#include <gst/tags/gsttagediting.h>
 
 #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");
-  }
-}
index b5a1e17..ba62e52 100644 (file)
@@ -45,7 +45,6 @@ struct _FlacDec {
   GstElement    element;
 
   GstPad       *sinkpad,*srcpad;
-       GstCaps *metadata;
   GstByteStream *bs;
 
   FLAC__SeekableStreamDecoder *decoder;
index 68597f3..d8928a0 100644 (file)
@@ -25,7 +25,8 @@
 #include <string.h>
 
 #include <gstflacenc.h>
-
+#include <gst/tags/gsttagediting.h>
+#include <gst/gsttaginterface.h>
 #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),
index ac3254b..cc404de 100644 (file)
@@ -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 {