GNOME Bugzilla – Bug 348644
[id3demux] Gets the wrong part of binary blob for ID3 v2.2 tags
Last modified: 2006-07-25 16:50:35 UTC
There is a problem in id3demux when trying to convert an IDv2.2 tag to IDv2.4 using the recent id3demux in CVS in conjunction with patch #69560 on bug #334375 It apears to be getting the last 3 characters of the previous blob, e.g. In the attached sample of a file, the hexdump contains this: TP1....Boards Of Canada.TCM..+.marcus eoin/michael sandison (warp music).TAL When attempting to convert the non-gst supported TCM (composer) into a blob, it uses creates a mime type of: "application/x-gst-id3v2-ada Note the "ada" is the last 3 chars of Canada, which leads me to expect that it it is offset somehow, later on in id3v2mux when injecting this (using that patch) it creates a segfault. GST_DEBUG="id3demux:5,id3v2mux:5" GST_PLUGIN_PATH=/usr/local/lib/gstreamer-0.10 gst-launch filesrc location=test4.mp3 ! id3demux ! id3v2mux ! filesink location=test4-retagged.mp3 LOG (0x8fa09d8 - 0:00:00.354571000) id3demux(22381) id3tags.c(462):id3demux_id3v2_frames_to_tag_list: Frame @ 37 (0x25) id TPE1 size 18, next=61 (0x3d) obsolete=0 LOG (0x8fa09d8 - 0:00:00.354722000) id3demux(22381) id3v2frames.c(260):parse_text_identification_frame: Read 1 fields from Text ID frame of size 17. First is 'Boards Of Canada' LOG (0x8fa09d8 - 0:00:00.354923000) id3demux(22381) id3tags.c(473):id3demux_id3v2_frames_to_tag_list: Extracted frame with id TPE1 LOG (0x8fa09d8 - 0:00:00.355060000) id3demux(22381) id3tags.c(462):id3demux_id3v2_frames_to_tag_list: Frame @ 61 (0x3d) id TCOM size 43, next=110 (0x6e) obsolete=0 LOG (0x8fa09d8 - 0:00:00.355197000) id3demux(22381) id3tags.c(475):id3demux_id3v2_frames_to_tag_list: Failed to extract frame with id TCOM LOG (0x8fa09d8 - 0:00:00.355342000) id3demux(22381) id3tags.c(353):id3demux_add_id3v2_frame_blob_to_taglist: Making a binary blob with application/x-gst-id3v2-ada DEBUG (0x90bad80 - 0:00:00.547121000) id3v2mux(22393) gstid3v2mux.cc(174):void add_one_tag(const GstTagList*, const gchar*, void*): Setting title to Ready Lets Go DEBUG (0x90bad80 - 0:00:00.547345000) id3v2mux(22393) gstid3v2mux.cc(192):void add_one_tag(const GstTagList*, const gchar*, void*): Setting artist to Boards Of Canada DEBUG (0x90bad80 - 0:00:00.547512000) id3v2mux(22393) gstid3v2mux.cc(464):void add_one_tag(const GstTagList*, const gchar*, void*): Setting binary blob of length 151701320 and mime-type application/x-gst-id3v2-ada Will attach file.
Created attachment 69584 [details] First 700 bytes of file with ID3 tags
Created attachment 69586 [details] Wasn't long enough
Indeed, frame header sizes differ in earlier ID3v2 versions (ID3V2_HDR_SIZE was the wrong define anyway, it was pure luck that it worked for ID3v2.4, it refers to the tag header and not the frame header). Should be fixed in CVS: 2006-07-25 Tim-Philipp Müller <tim at centricular dot net> * gst/id3demux/id3tags.c: (id3demux_add_id3v2_frame_blob_to_taglist): Extract frames for ID3v2 versions prior to ID3v2.3.0 properly as well, and add the version to the blob's buffer caps, since that information will be needed for deserialisation later on (#348644). For deserialisation, you should use something like: ID3v2::Frame *frame; const GValue *val; GstBuffer *buf; val = gst_tag_list_get_value_index (list, tag, i); buf = (GstBuffer *) gst_value_get_mini_object (val); if (buf && GST_BUFFER_CAPS (buf)) { GstStructure *s; gint version = 0; s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); if (s && gst_structure_get_int (s, "version", &version) && version > 0) { ByteVector bytes ((char *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); GST_DEBUG ("Injecting ID3v2.%u frame %u/%u of length %u and type %" GST_PTR_FORMAT, version, i, num_tags, GST_BUFFER_SIZE (buf), s); frame = factory->createFrame (bytes, (TagLib::uint) version); id3v2tag->addFrame (frame); } } ie. use the createFrame() method that takes the ID3v2 version as last parameter.