From 2ff93c3826e1aaa85ce6ebec6681fc6a65e090ab Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Sat, 6 Oct 2007 16:13:14 +0000 Subject: [PATCH] tag: id3v2: Port ID3 tag demuxer over to the new GstTagDemux in -base (now would be a good time to test re-importi... 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 | 112 +++++++++++++---------------------------- gst-libs/gst/tag/id3v2.h | 9 ++-- gst-libs/gst/tag/id3v2frames.c | 2 - 3 files changed, 39 insertions(+), 84 deletions(-) diff --git a/gst-libs/gst/tag/id3v2.c b/gst-libs/gst/tag/id3v2.c index 249acd0..b017f2a 100644 --- a/gst-libs/gst/tag/id3v2.c +++ b/gst-libs/gst/tag/id3v2.c @@ -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); diff --git a/gst-libs/gst/tag/id3v2.h b/gst-libs/gst/tag/id3v2.h index 85a17cd..705a6a0 100644 --- a/gst-libs/gst/tag/id3v2.h +++ b/gst-libs/gst/tag/id3v2.h @@ -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 diff --git a/gst-libs/gst/tag/id3v2frames.c b/gst-libs/gst/tag/id3v2frames.c index 153d494..76d4cbc 100644 --- a/gst-libs/gst/tag/id3v2frames.c +++ b/gst-libs/gst/tag/id3v2frames.c @@ -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) { -- 2.7.4