tag: id3v2: Port ID3 tag demuxer over to the new GstTagDemux in -base (now would...
authorTim-Philipp Müller <tim@centricular.net>
Sat, 6 Oct 2007 16:13:14 +0000 (16:13 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Sun, 14 Aug 2011 23:10:31 +0000 (00:10 +0100)
Original commit message from CVS:
* gst-libs/gst/tag/gstid3demux.c:
* gst-libs/gst/tag/gstid3demux.h:
* gst-libs/gst/tag/id3v2.c:
* gst-libs/gst/tag/id3v2.h:
* gst-libs/gst/tag/id3v2frames.c:
Port ID3 tag demuxer over to the new GstTagDemux in -base
(now would be a good time to test re-importing your music
collection).

gst-libs/gst/tag/id3v2.c
gst-libs/gst/tag/id3v2.h
gst-libs/gst/tag/id3v2frames.c

index 249acd0a4b24cd38086b5f2a5db140712de2dcbb..b017f2a64c757cca2397656b68a6019d869238b5 100644 (file)
@@ -35,7 +35,7 @@ static ID3TagsResult
 id3demux_id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size);
 
 guint
-read_synch_uint (guint8 * data, guint size)
+read_synch_uint (const guint8 * data, guint size)
 {
   gint i;
   guint result = 0;
@@ -62,50 +62,42 @@ read_synch_uint (guint8 * data, guint size)
   return result;
 }
 
-ID3TagsResult
-id3demux_read_id3v1_tag (GstBuffer * buffer, guint * id3v1_size,
-    GstTagList ** tags)
+guint
+id3demux_calc_id3v2_tag_size (GstBuffer * buf)
 {
-  GstTagList *new_tags;
-
-  guint8 *data;
+  guint8 *data, flags;
+  guint size;
 
-  g_return_val_if_fail (buffer != NULL, ID3TAGS_V1_BAD_SIZE);
+  g_assert (buf != NULL);
+  g_assert (GST_BUFFER_SIZE (buf) >= ID3V2_HDR_SIZE);
 
-  data = GST_BUFFER_DATA (buffer);
-
-  if (GST_BUFFER_SIZE (buffer) != ID3V1_TAG_SIZE)
-    return ID3TAGS_V1_BAD_SIZE;
+  data = GST_BUFFER_DATA (buf);
 
-  /* Check that buffer starts with 'TAG' */
-  if (data[0] != 'T' || data[1] != 'A' || data[2] != 'G') {
-    if (id3v1_size)
-      *id3v1_size = 0;
-    GST_DEBUG ("No ID3v1 tag in data");
-    return ID3TAGS_READ_TAG;
+  /* Check for 'ID3' string at start of buffer */
+  if (data[0] != 'I' || data[1] != 'D' || data[2] != '3') {
+    GST_DEBUG ("No ID3v2 tag in data");
+    return 0;
   }
 
-  g_return_val_if_fail (tags != NULL, ID3TAGS_READ_TAG);
+  /* Read the flags */
+  flags = data[5];
 
-  new_tags = gst_tag_list_new_from_id3v1 (GST_BUFFER_DATA (buffer));
-  if (new_tags == NULL)
-    return ID3TAGS_BROKEN_TAG;
+  /* Read the size from the header */
+  size = read_synch_uint (data + 6, 4);
+  if (size == 0)
+    return ID3V2_HDR_SIZE;
 
-  if (*tags) {
-    GstTagList *merged;
+  size += ID3V2_HDR_SIZE;
 
-    merged = gst_tag_list_merge (*tags, new_tags, GST_TAG_MERGE_REPLACE);
-    gst_tag_list_free (*tags);
-    gst_tag_list_free (new_tags);
-    *tags = merged;
-  } else
-    *tags = new_tags;
+  /* Expand the read size to include a footer if there is one */
+  if ((flags & ID3V2_HDR_FLAG_FOOTER))
+    size += 10;
 
-  if (id3v1_size)
-    *id3v1_size = ID3V1_TAG_SIZE;
-  return ID3TAGS_READ_TAG;
+  GST_DEBUG ("ID3v2 tag, size: %u bytes", size);
+  return size;
 }
 
+/* caller must pass buffer with full ID3 tag */
 ID3TagsResult
 id3demux_read_id3v2_tag (GstBuffer * buffer, guint * id3v2_size,
     GstTagList ** tags)
@@ -117,24 +109,16 @@ id3demux_read_id3v2_tag (GstBuffer * buffer, guint * id3v2_size,
   ID3TagsResult result;
   guint16 version;
 
-  g_return_val_if_fail (buffer != NULL, ID3TAGS_MORE_DATA);
+  read_size = id3demux_calc_id3v2_tag_size (buffer);
 
-  if (GST_BUFFER_SIZE (buffer) < ID3V2_MARK_SIZE)
-    return ID3TAGS_MORE_DATA;   /* Need more data to decide with */
-
-  data = GST_BUFFER_DATA (buffer);
+  if (id3v2_size)
+    *id3v2_size = read_size;
 
-  /* Check for 'ID3' string at start of buffer */
-  if (data[0] != 'I' || data[1] != 'D' || data[2] != '3') {
-    if (id3v2_size)
-      *id3v2_size = 0;
-    GST_DEBUG ("No ID3v2 tag in data");
-    return ID3TAGS_READ_TAG;
-  }
+  /* Ignore tag if it has no frames attached, but skip the header then */
+  if (read_size <= ID3V2_HDR_SIZE)
+    return ID3TAGS_BROKEN_TAG;
 
-  /* OK, get enough data to read the entire header */
-  if (GST_BUFFER_SIZE (buffer) < ID3V2_HDR_SIZE)
-    return ID3TAGS_MORE_DATA;   /* Need more data to decide with */
+  data = GST_BUFFER_DATA (buffer);
 
   /* Read the version */
   version = GST_READ_UINT16_BE (data + 3);
@@ -142,24 +126,6 @@ id3demux_read_id3v2_tag (GstBuffer * buffer, guint * id3v2_size,
   /* Read the flags */
   flags = data[5];
 
-  /* Read the size from the header */
-  read_size = read_synch_uint (data + 6, 4);
-  if (read_size == 0) {
-    /* Tag has no frames attached. Ignore it, but skip the header */
-    if (id3v2_size)
-      *id3v2_size = ID3V2_HDR_SIZE;
-    return ID3TAGS_BROKEN_TAG;
-  }
-  read_size += ID3V2_HDR_SIZE;
-
-  /* Expand the read size to include a footer if there is one */
-  if (flags & ID3V2_HDR_FLAG_FOOTER) {
-    read_size += 10;
-  }
-
-  if (id3v2_size)
-    *id3v2_size = read_size;
-
   /* Validate the version. At the moment, we only support up to 2.4.0 */
   if (ID3V2_VER_MAJOR (version) > 4 || ID3V2_VER_MINOR (version) > 0) {
     GST_WARNING ("ID3v2 tag is from revision 2.%d.%d, "
@@ -168,6 +134,7 @@ id3demux_read_id3v2_tag (GstBuffer * buffer, guint * id3v2_size,
     return ID3TAGS_READ_TAG;
   }
 
+  /* This shouldn't really happen! Caller should have checked first */
   if (GST_BUFFER_SIZE (buffer) < read_size) {
     GST_DEBUG
         ("Found ID3v2 tag with revision 2.%d.%d - need %u more bytes to read",
@@ -194,18 +161,7 @@ id3demux_read_id3v2_tag (GstBuffer * buffer, guint * id3v2_size,
 
   result = id3demux_id3v2_frames_to_tag_list (&work, read_size);
 
-  /* Actually read the tags */
-  if (work.tags != NULL) {
-    if (*tags) {
-      GstTagList *merged;
-
-      merged = gst_tag_list_merge (*tags, work.tags, GST_TAG_MERGE_REPLACE);
-      gst_tag_list_free (*tags);
-      gst_tag_list_free (work.tags);
-      *tags = merged;
-    } else
-      *tags = work.tags;
-  }
+  *tags = work.tags;
 
   if (work.prev_genre)
     g_free (work.prev_genre);
index 85a17cd4c7d7c46980046a23dffe233ef18e1dff..705a6a0dda4c783aa83448d51ef9deba6d4fdc6c 100644 (file)
@@ -31,18 +31,17 @@ G_BEGIN_DECLS
 #define ID3V2_HDR_SIZE 10
 
 typedef enum {
-  ID3TAGS_V1_BAD_SIZE,
   ID3TAGS_MORE_DATA,
   ID3TAGS_READ_TAG,
   ID3TAGS_BROKEN_TAG
 } ID3TagsResult;
 
 /* From id3tags.c */
-ID3TagsResult id3demux_read_id3v1_tag (GstBuffer *buffer, guint *id3v1_size,
-  GstTagList **tags);
+guint id3demux_calc_id3v2_tag_size (GstBuffer * buf);
 ID3TagsResult id3demux_read_id3v2_tag (GstBuffer *buffer, guint *id3v2_size,
   GstTagList **tags);
-G_END_DECLS
+
+guint read_synch_uint (const guint8 * data, guint size);
 
 /* Things shared by id3tags.c and id3v2frames.c */
 #define ID3V2_VERSION 0x0400
@@ -119,4 +118,6 @@ enum {
 /* From id3v2frames.c */
 gboolean id3demux_id3v2_parse_frame (ID3TagsWorking *work);
 
+G_END_DECLS
+
 #endif
index 153d49430e0cb005c48544de4f962bf9349ed009..76d4cbc3ea179f48f8f0f6c27664cda568f3e466 100644 (file)
@@ -61,8 +61,6 @@ static gboolean parse_picture_frame (ID3TagsWorking * work);
 #define ID3V2_ENCODING_UTF16BE 0x02
 #define ID3V2_ENCODING_UTF8    0x03
 
-extern guint read_synch_uint (guint8 * data, guint size);
-
 gboolean
 id3demux_id3v2_parse_frame (ID3TagsWorking * work)
 {