mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
- Ripped some ID3 tag parsing from libid3 for typefind.
Original commit message from CVS: - Ripped some ID3 tag parsing from libid3 for typefind. - Added ID3V1 to fypefind. - Don't check for a valid mp3 header after finding the ID3 tag as some ID3 tags seem broken.
This commit is contained in:
parent
a160852f16
commit
003d45f660
1 changed files with 42 additions and 25 deletions
|
@ -31,36 +31,53 @@ static GstTypeDefinition mp3type_definitions[] = {
|
||||||
static GstCaps*
|
static GstCaps*
|
||||||
mp3_type_find(GstBuffer *buf, gpointer private)
|
mp3_type_find(GstBuffer *buf, gpointer private)
|
||||||
{
|
{
|
||||||
gchar *data;
|
guint8 *data;
|
||||||
|
gint size;
|
||||||
gulong head;
|
gulong head;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
|
||||||
data = GST_BUFFER_DATA(buf);
|
data = GST_BUFFER_DATA (buf);
|
||||||
|
size = GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
GST_DEBUG (0,"mp3typefind: typefind");
|
GST_DEBUG (0,"mp3typefind: typefind");
|
||||||
|
|
||||||
/* check for ID3 Tag first and forward ID3 length */
|
/* gracefully ripped from libid3 */
|
||||||
if (!memcmp (data, "ID3", 3))
|
if (size >= 3 &&
|
||||||
{
|
data[0] == 'T' && data[1] == 'A' && data[2] == 'G') {
|
||||||
guint32 skip;
|
/* ID V1 tags */
|
||||||
/* ignore next 3 bytes */
|
data += 128;
|
||||||
data += 6;
|
|
||||||
/* if you want that thing faster, do it */
|
GST_DEBUG (0, "mp3typefind: detected ID3 Tag V1");
|
||||||
skip = GUINT32_FROM_BE(*((guint32 *)data));
|
}
|
||||||
skip = (((skip & 0x7f000000) >> 3) |
|
else {
|
||||||
((skip & 0x007f0000) >> 2) |
|
if (size >= 10 &&
|
||||||
((skip & 0x00007f00) >> 1) |
|
(data[0] == 'I' && data[1] == 'D' && data[2] == '3') &&
|
||||||
((skip & 0x0000007f) >> 0)) + 4;
|
data[3] < 0xff && data[4] < 0xff &&
|
||||||
GST_DEBUG (0, "mp3typefind: detected ID3 Tag with %u bytes", skip + 6);
|
data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80)
|
||||||
/* return if buffer is not big enough */
|
{
|
||||||
if (GST_BUFFER_SIZE (buf) < skip + 10)
|
guint32 skip = 0;
|
||||||
{
|
|
||||||
GST_DEBUG (0, "mp3typefind: buffer too small (%d) to go on typefinding", skip + 6);
|
skip = (skip << 7) | (data[6] & 0x7f);
|
||||||
return NULL;
|
skip = (skip << 7) | (data[7] & 0x7f);
|
||||||
}
|
skip = (skip << 7) | (data[8] & 0x7f);
|
||||||
data += skip;
|
skip = (skip << 7) | (data[9] & 0x7f);
|
||||||
|
|
||||||
|
if (data[0] == 'I') {
|
||||||
|
/* ID3V2 */
|
||||||
|
/* footer present? */
|
||||||
|
if (data[5] & 0x10)
|
||||||
|
skip += 10;
|
||||||
|
|
||||||
|
skip += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG (0, "mp3typefind: detected ID3 Tag V2 with %u bytes", skip);
|
||||||
|
|
||||||
|
/* we currently accept a valid ID3 tag as an mp3 as some ID3 tags have invalid
|
||||||
|
* offsets so the next check might fail */
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now with the right postion, do typefinding */
|
/* now with the right postion, do typefinding */
|
||||||
head = GULONG_FROM_BE(*((gulong *)data));
|
head = GULONG_FROM_BE(*((gulong *)data));
|
||||||
if ((head & 0xffe00000) != 0xffe00000)
|
if ((head & 0xffe00000) != 0xffe00000)
|
||||||
|
@ -74,8 +91,8 @@ mp3_type_find(GstBuffer *buf, gpointer private)
|
||||||
if (((head >> 10) & 0x3) == 0x3)
|
if (((head >> 10) & 0x3) == 0x3)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
done:
|
||||||
caps = gst_caps_new ("mp3_type_find", "audio/mp3", NULL);
|
caps = gst_caps_new ("mp3_type_find", "audio/mp3", NULL);
|
||||||
/* gst_caps_set(caps,"layer",GST_PROPS_INT(4-((head>>17)&0x3))); */
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue