matroskadec: use generic parser to parse attachments
authorAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:40:24 +0000 (00:40 +0000)
committerAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:40:24 +0000 (00:40 +0000)
Originally committed as revision 14560 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/matroskadec.c

index 8d2f9c2270f6d0b6c47cc79cf7123bffed66e84d..01b856a90eb84f1b5136433ca9655ef46883aa3e 100644 (file)
@@ -158,6 +158,12 @@ typedef struct MatroskaSubtitleTrack {
                                     sizeof(MatroskaAudioTrack), \
                                     sizeof(MatroskaSubtitleTrack)))
 
+typedef struct {
+    char *filename;
+    char *mime;
+    EbmlBin bin;
+} MatroskaAttachement;
+
 typedef struct {
     uint64_t start;
     uint64_t end;
@@ -190,6 +196,7 @@ typedef struct MatroskaDemuxContext {
 
     /* timescale in the file */
     int64_t time_scale;
+    EbmlList attachments;
     EbmlList chapters;
     EbmlList index;
 
@@ -238,6 +245,21 @@ static EbmlSyntax ebml_syntax[] = {
     { 0 }
 };
 
+static EbmlSyntax matroska_attachment[] = {
+    { MATROSKA_ID_FILENAME,           EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) },
+    { MATROSKA_ID_FILEMIMETYPE,       EBML_STR,  0, offsetof(MatroskaAttachement,mime) },
+    { MATROSKA_ID_FILEDATA,           EBML_BIN,  0, offsetof(MatroskaAttachement,bin) },
+    { MATROSKA_ID_FILEUID,            EBML_NONE },
+    { EBML_ID_VOID,                   EBML_NONE },
+    { 0 }
+};
+
+static EbmlSyntax matroska_attachments[] = {
+    { MATROSKA_ID_ATTACHEDFILE,       EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} },
+    { EBML_ID_VOID,                   EBML_NONE },
+    { 0 }
+};
+
 static EbmlSyntax matroska_chapter_display[] = {
     { MATROSKA_ID_CHAPSTRING,         EBML_UTF8, 0, offsetof(MatroskaChapter,title) },
     { EBML_ID_VOID,                   EBML_NONE },
@@ -1988,110 +2010,37 @@ static int
 matroska_parse_attachments(AVFormatContext *s)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
-    int res = 0;
-    uint32_t id;
-
-    av_log(matroska->ctx, AV_LOG_DEBUG, "parsing attachments...\n");
-
-    while (res == 0) {
-        if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-            res = AVERROR(EIO);
-            break;
-        } else if (matroska->level_up) {
-            matroska->level_up--;
-            break;
-        }
+    EbmlList *attachements_list = &matroska->attachments;
+    MatroskaAttachement *attachements;
+    int i, j, res;
 
-        switch (id) {
-        case MATROSKA_ID_ATTACHEDFILE: {
-            char* name = NULL;
-            char* mime = NULL;
-            uint8_t* data = NULL;
-            int i, data_size = 0;
-            AVStream *st;
-
-            if ((res = ebml_read_master(matroska, &id)) < 0)
-                break;
-
-            while (res == 0) {
-                if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
-                    res = AVERROR(EIO);
-                    break;
-                } else if (matroska->level_up) {
-                    matroska->level_up--;
-                    break;
-                }
-
-                switch (id) {
-                case MATROSKA_ID_FILENAME:
-                    res = ebml_read_utf8 (matroska, &id, &name);
-                    break;
-
-                case MATROSKA_ID_FILEMIMETYPE:
-                    res = ebml_read_ascii (matroska, &id, &mime);
-                    break;
-
-                case MATROSKA_ID_FILEDATA:
-                    res = ebml_read_binary(matroska, &id, &data, &data_size);
-                    break;
+    res = ebml_parse(matroska, matroska_attachments, matroska, MATROSKA_ID_ATTACHMENTS, 0);
 
-                default:
-                    av_log(matroska->ctx, AV_LOG_INFO,
-                           "Unknown attachedfile ID 0x%x\n", id);
-                case MATROSKA_ID_FILEUID:
-                case EBML_ID_VOID:
-                    res = ebml_read_skip(matroska);
-                    break;
-                }
-
-                if (matroska->level_up) {
-                    matroska->level_up--;
-                    break;
-                }
-            }
-
-            if (!(name && mime && data && data_size > 0)) {
-                av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
-                break;
-            }
-
-            st = av_new_stream(s, matroska->num_streams++);
+    attachements = attachements_list->elem;
+    for (j=0; j<attachements_list->nb_elem; j++) {
+        if (!(attachements[j].filename && attachements[j].mime &&
+              attachements[j].bin.data && attachements[j].bin.size > 0)) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
+        } else {
+            AVStream *st = av_new_stream(s, matroska->num_streams++);
             if (st == NULL)
-                return AVERROR(ENOMEM);
-            st->filename = av_strdup(name);
+                break;
+            st->filename          = av_strdup(attachements[j].filename);
             st->codec->codec_id = CODEC_ID_NONE;
             st->codec->codec_type = CODEC_TYPE_ATTACHMENT;
-            st->codec->extradata = av_malloc(data_size);
+            st->codec->extradata  = av_malloc(attachements[j].bin.size);
             if(st->codec->extradata == NULL)
-                return AVERROR(ENOMEM);
-            st->codec->extradata_size = data_size;
-            memcpy(st->codec->extradata, data, data_size);
+                break;
+            st->codec->extradata_size = attachements[j].bin.size;
+            memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size);
 
             for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) {
-                if (!strncmp(ff_mkv_mime_tags[i].str, mime,
+                if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime,
                              strlen(ff_mkv_mime_tags[i].str))) {
                     st->codec->codec_id = ff_mkv_mime_tags[i].id;
                     break;
                 }
             }
-
-            av_log(matroska->ctx, AV_LOG_DEBUG, "new attachment: %s, %s, size %d \n", name, mime, data_size);
-            break;
-        }
-
-        default:
-            av_log(matroska->ctx, AV_LOG_INFO,
-                   "Unknown attachments ID 0x%x\n", id);
-            /* fall-through */
-
-        case EBML_ID_VOID:
-            res = ebml_read_skip(matroska);
-            break;
-        }
-
-        if (matroska->level_up) {
-            matroska->level_up--;
-            break;
         }
     }
 
@@ -2246,8 +2195,6 @@ matroska_read_header (AVFormatContext    *s,
             }
 
             case MATROSKA_ID_ATTACHMENTS: {
-                if ((res = ebml_read_master(matroska, &id)) < 0)
-                    break;
                 res = matroska_parse_attachments(s);
                 break;
             }