summaryrefslogtreecommitdiff
path: root/src/demuxers/id3.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/demuxers/id3.c')
-rw-r--r--src/demuxers/id3.c139
1 files changed, 55 insertions, 84 deletions
diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c
index f11e80e8d..2b433f515 100644
--- a/src/demuxers/id3.c
+++ b/src/demuxers/id3.c
@@ -40,8 +40,8 @@
#define LOG
*/
-#include "xine_internal.h"
-#include "xineutils.h"
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
#include "bswap.h"
#include "id3.h"
@@ -229,17 +229,17 @@ static int id3v2_parse_genre(char* dest, char *src, int len) {
return 1;
}
-static int id3v2_parse_header(input_plugin_t *input, uint8_t *mp3_frame_header,
+static int id3v2_parse_header(input_plugin_t *input, uint32_t id3_signature,
id3v2_header_t *tag_header) {
uint8_t buf[6];
- tag_header->id = _X_BE_32(mp3_frame_header);
+ tag_header->id = be2me_32(id3_signature);
if (input->read (input, buf, 6) == 6) {
tag_header->revision = buf[0];
tag_header->flags = buf[1];
tag_header->size = _X_BE_32_synchsafe(&buf[2]);
- lprintf("tag: ID3 v2.%d.%d\n", mp3_frame_header[3], tag_header->revision);
+ lprintf("tag: ID3 v2.%d.%d\n", tag_header->id & 0xFF, tag_header->revision);
lprintf("flags: %d\n", tag_header->flags);
lprintf("size: %zu\n", tag_header->size);
return 1;
@@ -273,17 +273,11 @@ static int id3v22_parse_frame_header(input_plugin_t *input,
static int id3v22_interp_frame(input_plugin_t *input,
xine_stream_t *stream,
id3v22_frame_header_t *frame_header) {
- char *buf;
- int enc;
const size_t bufsize = frame_header->size + 2;
if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
return 0;
-
- buf = malloc(bufsize);
- if (buf == NULL) {
- lprintf("malloc error");
- return 0;
- }
+ char buf[bufsize];
+ int enc;
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
@@ -293,7 +287,7 @@ static int id3v22_interp_frame(input_plugin_t *input,
enc = 0;
switch (frame_header->id) {
- case ( FOURCC_TAG(0, 'T', 'C', 'O') ):
+ case ( BE_FOURCC(0, 'T', 'C', 'O') ):
{
char tmp[1024];
@@ -303,27 +297,27 @@ static int id3v22_interp_frame(input_plugin_t *input,
}
break;
- case ( FOURCC_TAG(0, 'T', 'T', '2') ):
+ case ( BE_FOURCC(0, 'T', 'T', '2') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG(0, 'T', 'P', '1') ):
+ case ( BE_FOURCC(0, 'T', 'P', '1') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG(0, 'T', 'A', 'L') ):
+ case ( BE_FOURCC(0, 'T', 'A', 'L') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG(0, 'T', 'Y', 'E') ):
+ case ( BE_FOURCC(0, 'T', 'Y', 'E') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG(0, 'C', 'O', 'M') ):
+ case ( BE_FOURCC(0, 'C', 'O', 'M') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]);
break;
- case ( FOURCC_TAG(0, 'T', 'R', 'K') ):
+ case ( BE_FOURCC(0, 'T', 'R', 'K') ):
_x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1);
break;
@@ -331,24 +325,22 @@ static int id3v22_interp_frame(input_plugin_t *input,
lprintf("unhandled frame\n");
}
- free(buf);
return 1;
} else {
lprintf("read error\n");
- free(buf);
return 0;
}
}
static int id3v22_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+ xine_stream_t *stream,
+ uint32_t id3_signature) {
id3v2_header_t tag_header;
id3v22_frame_header_t tag_frame_header;
int pos = 0;
- if (id3v2_parse_header(input, mp3_frame_header, &tag_header)) {
+ if (id3v2_parse_header(input, id3_signature, &tag_header)) {
if (tag_header.flags & ID3V22_ZERO_FLAG) {
/* invalid flags */
@@ -471,17 +463,11 @@ static int id3v23_parse_frame_ext_header(input_plugin_t *input,
static int id3v23_interp_frame(input_plugin_t *input,
xine_stream_t *stream,
id3v23_frame_header_t *frame_header) {
- char *buf;
- int enc;
const size_t bufsize = frame_header->size + 2;
if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
return 0;
-
- buf = malloc(bufsize);
- if (buf == NULL) {
- lprintf("malloc error");
- return 0;
- }
+ char buf[bufsize];
+ int enc;
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
@@ -491,7 +477,7 @@ static int id3v23_interp_frame(input_plugin_t *input,
enc = 0;
switch (frame_header->id) {
- case ( FOURCC_TAG('T', 'C', 'O', 'N') ):
+ case ( BE_FOURCC('T', 'C', 'O', 'N') ):
{
char tmp[1024];
@@ -501,31 +487,31 @@ static int id3v23_interp_frame(input_plugin_t *input,
}
break;
- case ( FOURCC_TAG('T', 'I', 'T', '2') ):
+ case ( BE_FOURCC('T', 'I', 'T', '2') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'P', 'E', '1') ):
+ case ( BE_FOURCC('T', 'P', 'E', '1') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'A', 'L', 'B') ):
+ case ( BE_FOURCC('T', 'A', 'L', 'B') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'Y', 'E', 'R') ):
+ case ( BE_FOURCC('T', 'Y', 'E', 'R') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('C', 'O', 'M', 'M') ):
+ case ( BE_FOURCC('C', 'O', 'M', 'M') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'R', 'C', 'K') ):
+ case ( BE_FOURCC('T', 'R', 'C', 'K') ):
_x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1);
break;
- case FOURCC_TAG('T', 'P', 'O', 'S'):
+ case BE_FOURCC('T', 'P', 'O', 'S'):
_x_meta_info_set(stream, XINE_META_INFO_DISCNUMBER, buf + 1);
break;
@@ -533,24 +519,22 @@ static int id3v23_interp_frame(input_plugin_t *input,
lprintf("unhandled frame\n");
}
- free(buf);
return 1;
} else {
lprintf("read error\n");
- free(buf);
return 0;
}
}
static int id3v23_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+ xine_stream_t *stream,
+ uint32_t id3_signature) {
id3v2_header_t tag_header;
id3v23_frame_header_t tag_frame_header;
id3v23_frame_ext_header_t tag_frame_ext_header;
int pos = 0;
- if (id3v2_parse_header(input, mp3_frame_header, &tag_header)) {
+ if (id3v2_parse_header(input, id3_signature, &tag_header)) {
if (tag_header.flags & ID3V23_ZERO_FLAG) {
/* invalid flags */
@@ -730,17 +714,11 @@ static int id3v24_parse_ext_header(input_plugin_t *input,
static int id3v24_interp_frame(input_plugin_t *input,
xine_stream_t *stream,
id3v24_frame_header_t *frame_header) {
- char *buf;
- int enc;
const size_t bufsize = frame_header->size + 2;
if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */
return 0;
-
- buf = malloc(bufsize);
- if (buf == NULL) {
- lprintf("malloc error");
- return 0;
- }
+ char buf[bufsize];
+ int enc;
if (input->read (input, buf, frame_header->size) == frame_header->size) {
buf[frame_header->size] = 0;
@@ -752,7 +730,7 @@ static int id3v24_interp_frame(input_plugin_t *input,
lprintf("data: %s\n", buf+1);
switch (frame_header->id) {
- case ( FOURCC_TAG('T', 'C', 'O', 'N') ):
+ case ( BE_FOURCC('T', 'C', 'O', 'N') ):
{
char tmp[1024];
@@ -762,32 +740,32 @@ static int id3v24_interp_frame(input_plugin_t *input,
}
break;
- case ( FOURCC_TAG('T', 'I', 'T', '2') ):
+ case ( BE_FOURCC('T', 'I', 'T', '2') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'P', 'E', '1') ):
+ case ( BE_FOURCC('T', 'P', 'E', '1') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'A', 'L', 'B') ):
+ case ( BE_FOURCC('T', 'A', 'L', 'B') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'Y', 'E', 'R') ):
- case ( FOURCC_TAG('T', 'D', 'R', 'C') ):
+ case ( BE_FOURCC('T', 'Y', 'E', 'R') ):
+ case ( BE_FOURCC('T', 'D', 'R', 'C') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('C', 'O', 'M', 'M') ):
+ case ( BE_FOURCC('C', 'O', 'M', 'M') ):
_x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]);
break;
- case ( FOURCC_TAG('T', 'R', 'C', 'K') ):
+ case ( BE_FOURCC('T', 'R', 'C', 'K') ):
_x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1);
break;
- case FOURCC_TAG('T', 'P', 'O', 'S'):
+ case BE_FOURCC('T', 'P', 'O', 'S'):
_x_meta_info_set(stream, XINE_META_INFO_DISCNUMBER, buf + 1);
break;
@@ -795,24 +773,22 @@ static int id3v24_interp_frame(input_plugin_t *input,
lprintf("unhandled frame\n");
}
- free(buf);
return 1;
} else {
lprintf("read error\n");
- free(buf);
return 0;
}
}
static int id3v24_parse_tag(input_plugin_t *input,
- xine_stream_t *stream,
- int8_t *mp3_frame_header) {
+ xine_stream_t *stream,
+ uint32_t id3_signature) {
id3v2_header_t tag_header;
id3v24_frame_header_t tag_frame_header;
id3v24_frame_ext_header_t tag_frame_ext_header;
int pos = 0;
- if (id3v2_parse_header(input, mp3_frame_header, &tag_header)) {
+ if (id3v2_parse_header(input, id3_signature, &tag_header)) {
if (tag_header.flags & ID3V24_ZERO_FLAG) {
/* invalid flags */
@@ -875,30 +851,25 @@ static int id3v24_parse_tag(input_plugin_t *input,
int id3v2_parse_tag(input_plugin_t *input,
xine_stream_t *stream,
- int8_t *mp3_frame_header) {
- _x_assert(mp3_frame_header[0] == 'I' && mp3_frame_header[1] == 'D' && mp3_frame_header[2] == '3');
-
- int result = 0;
+ uint32_t id3_signature) {
+ _x_assert((id3_signature & ID3V2X_MASK) == ID3V2X_TAG);
- switch(mp3_frame_header[3]) {
- case 2:
+ switch(id3_signature) {
+ case ID3V22_TAG:
xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.2 tag\n");
- result = id3v22_parse_tag(input, stream, mp3_frame_header);
- break;
+ return id3v22_parse_tag(input, stream, id3_signature);
- case 3:
+ case ID3V23_TAG:
xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.3 tag\n");
- result = id3v23_parse_tag(input, stream, mp3_frame_header);
- break;
+ return id3v23_parse_tag(input, stream, id3_signature);
- case 4:
+ case ID3V24_TAG:
xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.4 tag\n");
- result = id3v24_parse_tag(input, stream, mp3_frame_header);
- break;
+ return id3v24_parse_tag(input, stream, id3_signature);
default:
- xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unknown ID3v2 version: 0x%02x.\n", mp3_frame_header[3]);
+ xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unknown ID3v2 signature: 0x%08x.\n", be2me_32(id3_signature));
}
- return result;
+ return 0;
}