[FFmpeg-devel] [HACK] parse m4a metadata
Reimar Döffinger
Reimar.Doeffinger
Wed Jun 11 20:45:28 CEST 2008
Hello,
with attached patch FFmpeg can read the metadata from
http://samples.mplayerhq.hu/A-codecs/lossless/luckynight.m4a
It is still quite ugly, and I do not want to spend any time on it, so
cleaning up is something that someone else must do.
There is also a problem that the existing metadata code probably has,
too: The strings might contain linebreaks, which are coded mac-style as
\r whereas IMO FFmpeg should use \n instead.
Greetings,
Reimar D?ffinger
-------------- next part --------------
Index: libavformat/mov.c
===================================================================
--- libavformat/mov.c (revision 13651)
+++ libavformat/mov.c (working copy)
@@ -1334,6 +1334,71 @@
get_buffer(pb, str, FFMIN(size, str_size));
}
+static void mov_parse_ilst_string(ByteIOContext *pb, char *str, int size)
+{
+ uint32_t tag_size = get_be32(pb);
+ uint32_t tag = get_le32(pb);
+ url_fskip(pb, 8);
+ if (tag != MKTAG('d','a','t','a') || tag_size < 16) return;
+ tag_size -= 16;
+ get_buffer(pb, str, FFMIN(size, tag_size));
+}
+
+static void mov_read_ilst(MOVContext *c, ByteIOContext *pb, uint64_t end)
+{
+ while (url_ftell(pb) + 8 < end) {
+ uint32_t tag_size = get_be32(pb);
+ uint32_t tag = get_le32(pb);
+ uint64_t next = url_ftell(pb) + tag_size - 8;
+
+ if (next > end) // stop if tag_size is wrong
+ break;
+
+ switch (tag) {
+ case MKTAG(0xa9,'n','a','m'):
+ mov_parse_ilst_string(pb, c->fc->title, sizeof(c->fc->title));
+ break;
+ case MKTAG(0xa9,'A','R','T'):
+ mov_parse_ilst_string(pb, c->fc->author, sizeof(c->fc->author));
+ break;
+ case MKTAG(0xa9,'c','m','t'):
+ mov_parse_ilst_string(pb, c->fc->comment, sizeof(c->fc->comment));
+ break;
+ case MKTAG(0xa9,'a','l','b'):
+ mov_parse_ilst_string(pb, c->fc->album, sizeof(c->fc->album));
+ break;
+ case MKTAG('t','r','k','n'):
+ get_be32(pb); // length
+ get_be32(pb); // "data"
+ url_fskip(pb, 8);
+ c->fc->track = get_be32(pb);
+ break;
+ default:
+ break;
+ }
+
+ url_fseek(pb, next, SEEK_SET);
+ }
+}
+
+static void mov_read_meta(MOVContext *c, ByteIOContext *pb, uint64_t end)
+{
+ url_fskip(pb, 4);
+ while (url_ftell(pb) + 8 < end) {
+ uint32_t tag_size = get_be32(pb);
+ uint32_t tag = get_le32(pb);
+ uint64_t next = url_ftell(pb) + tag_size - 8;
+
+ if (next > end) // stop if tag_size is wrong
+ break;
+
+ if (tag == MKTAG('i','l','s','t'))
+ mov_read_ilst(c, pb, next);
+
+ url_fseek(pb, next, SEEK_SET);
+ }
+}
+
static int mov_read_udta(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
{
uint64_t end = url_ftell(pb) + atom.size;
@@ -1359,6 +1424,9 @@
case MKTAG(0xa9,'i','n','f'):
mov_parse_udta_string(pb, c->fc->comment, sizeof(c->fc->comment));
break;
+ case MKTAG('m','e','t','a'):
+ mov_read_meta(c, pb, next);
+ break;
default:
break;
}
More information about the ffmpeg-devel
mailing list