changeset 3640:122a7c807f80 libavformat

matroskadec: use generic parser to parse attachments
author aurel
date Tue, 05 Aug 2008 00:40:24 +0000
parents 74787fc857be
children 2788411945cf
files matroskadec.c
diffstat 1 files changed, 42 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/matroskadec.c	Tue Aug 05 00:40:21 2008 +0000
+++ b/matroskadec.c	Tue Aug 05 00:40:24 2008 +0000
@@ -159,6 +159,12 @@
                                     sizeof(MatroskaSubtitleTrack)))
 
 typedef struct {
+    char *filename;
+    char *mime;
+    EbmlBin bin;
+} MatroskaAttachement;
+
+typedef struct {
     uint64_t start;
     uint64_t end;
     uint64_t uid;
@@ -190,6 +196,7 @@
 
     /* timescale in the file */
     int64_t time_scale;
+    EbmlList attachments;
     EbmlList chapters;
     EbmlList index;
 
@@ -238,6 +245,21 @@
     { 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 @@
 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;
-        }
-
-        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)
+    EbmlList *attachements_list = &matroska->attachments;
+    MatroskaAttachement *attachements;
+    int i, j, res;
+
+    res = ebml_parse(matroska, matroska_attachments, matroska, MATROSKA_ID_ATTACHMENTS, 0);
+
+    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)
                 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;
-
-                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++);
-            if (st == NULL)
-                return AVERROR(ENOMEM);
-            st->filename = av_strdup(name);
+            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 @@
             }
 
             case MATROSKA_ID_ATTACHMENTS: {
-                if ((res = ebml_read_master(matroska, &id)) < 0)
-                    break;
                 res = matroska_parse_attachments(s);
                 break;
             }