[FFmpeg-cvslog] r14571 - trunk/libavformat/matroskadec.c

aurel subversion
Tue Aug 5 02:40:59 CEST 2008


Author: aurel
Date: Tue Aug  5 02:40:58 2008
New Revision: 14571

Log:
matroskadec: use generic parser to parse matroska from toplevel

Modified:
   trunk/libavformat/matroskadec.c

Modified: trunk/libavformat/matroskadec.c
==============================================================================
--- trunk/libavformat/matroskadec.c	(original)
+++ trunk/libavformat/matroskadec.c	Tue Aug  5 02:40:58 2008
@@ -209,6 +209,7 @@ typedef struct MatroskaDemuxContext {
     int metadata_parsed;
     int index_parsed;
     int done;
+    int has_cluster_id;
 
     /* What to skip before effectively reading a packet. */
     int skip_to_keyframe;
@@ -407,6 +408,24 @@ static EbmlSyntax matroska_seekhead[] = 
     { 0 }
 };
 
+static EbmlSyntax matroska_segment[] = {
+    { MATROSKA_ID_INFO,           EBML_NEST, 0, 0, {.n=matroska_info       } },
+    { MATROSKA_ID_TRACKS,         EBML_NEST, 0, 0, {.n=matroska_tracks     } },
+    { MATROSKA_ID_ATTACHMENTS,    EBML_NEST, 0, 0, {.n=matroska_attachments} },
+    { MATROSKA_ID_CHAPTERS,       EBML_NEST, 0, 0, {.n=matroska_chapters   } },
+    { MATROSKA_ID_CUES,           EBML_NEST, 0, 0, {.n=matroska_index      } },
+    { MATROSKA_ID_TAGS,           EBML_NEST, 0, 0, {.n=matroska_tags       } },
+    { MATROSKA_ID_SEEKHEAD,       EBML_NEST, 0, 0, {.n=matroska_seekhead   } },
+    { MATROSKA_ID_CLUSTER,        EBML_STOP, 0, offsetof(MatroskaDemuxContext,has_cluster_id) },
+    { EBML_ID_VOID,               EBML_NONE },
+    { 0 }
+};
+
+static EbmlSyntax matroska_segments[] = {
+    { MATROSKA_ID_SEGMENT,        EBML_NEST, 0, 0, {.n=matroska_segment    } },
+    { 0 }
+};
+
 /*
  * The first few functions handle EBML file parsing. The rest
  * is the document interpretation. Matroska really just is a
@@ -1152,14 +1171,6 @@ static void ebml_free(EbmlSyntax *syntax
 }
 
 static int
-matroska_parse_info (MatroskaDemuxContext *matroska)
-{
-    int res = ebml_parse(matroska, matroska_info, matroska, MATROSKA_ID_INFO, 0);
-
-    return res;
-}
-
-static int
 matroska_decode_buffer(uint8_t** buf, int* buf_size, MatroskaTrack *track)
 {
     MatroskaTrackEncoding *encodings = track->encodings.elem;
@@ -1237,16 +1248,6 @@ matroska_decode_buffer(uint8_t** buf, in
 }
 
 static int
-matroska_parse_tracks (MatroskaDemuxContext *matroska)
-{
-    int i, res;
-
-    res = ebml_parse(matroska, matroska_tracks, matroska, MATROSKA_ID_TRACKS, 0);
-
-    return res;
-}
-
-static int
 matroska_parse_index (MatroskaDemuxContext *matroska)
 {
     return ebml_parse(matroska, matroska_index, matroska, MATROSKA_ID_CUES, 0);
@@ -1258,12 +1259,6 @@ matroska_parse_metadata (MatroskaDemuxCo
     return ebml_parse(matroska, matroska_tags, matroska, MATROSKA_ID_TAGS, 0);
 }
 
-static int
-matroska_parse_seekhead (MatroskaDemuxContext *matroska)
-{
-    return ebml_parse(matroska, matroska_seekhead, matroska, MATROSKA_ID_SEEKHEAD, 0);
-}
-
 static void
 matroska_execute_seekhead(MatroskaDemuxContext *matroska)
 {
@@ -1348,28 +1343,6 @@ matroska_execute_seekhead(MatroskaDemuxC
 }
 
 static int
-matroska_parse_attachments(AVFormatContext *s)
-{
-    MatroskaDemuxContext *matroska = s->priv_data;
-    int i, j, res;
-
-    res = ebml_parse(matroska, matroska_attachments, matroska, MATROSKA_ID_ATTACHMENTS, 0);
-
-    return res;
-}
-
-static int
-matroska_parse_chapters(AVFormatContext *s)
-{
-    MatroskaDemuxContext *matroska = s->priv_data;
-    int i, res;
-
-    res = ebml_parse(matroska, matroska_chapters, matroska, MATROSKA_ID_CHAPTERS, 0);
-
-    return res;
-}
-
-static int
 matroska_aac_profile (char *codec_id)
 {
     static const char *aac_profiles[] = {
@@ -1406,10 +1379,9 @@ matroska_read_header (AVFormatContext   
     MatroskaTrack *tracks;
     EbmlList *index_list;
     MatroskaIndex *index;
-    int i, j, last_level, res = 0;
     Ebml ebml = { 0 };
     AVStream *st;
-    uint32_t id;
+    int i, j;
 
     matroska->ctx = s;
 
@@ -1427,107 +1399,8 @@ matroska_read_header (AVFormatContext   
     ebml_free(ebml_syntax, &ebml);
 
     /* The next thing is a segment. */
-    while (1) {
-        if (!(id = ebml_peek_id(matroska, &last_level)))
-            return AVERROR(EIO);
-        if (id == MATROSKA_ID_SEGMENT)
-            break;
-
-        /* oi! */
-        av_log(matroska->ctx, AV_LOG_INFO,
-               "Expected a Segment ID (0x%x), but received 0x%x!\n",
-               MATROSKA_ID_SEGMENT, id);
-        if ((res = ebml_read_skip(matroska)) < 0)
-            return res;
-    }
-
-    /* We now have a Matroska segment.
-     * Seeks are from the beginning of the segment,
-     * after the segment ID/length. */
-    if ((res = ebml_read_master(matroska, &id)) < 0)
-        return res;
-    matroska->segment_start = url_ftell(s->pb);
-
-    matroska->time_scale = 1000000;
-    /* we've found our segment, start reading the different contents in here */
-    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) {
-            /* stream info */
-            case MATROSKA_ID_INFO: {
-                res = matroska_parse_info(matroska);
-                break;
-            }
-
-            /* track info headers */
-            case MATROSKA_ID_TRACKS: {
-                res = matroska_parse_tracks(matroska);
-                break;
-            }
-
-            /* stream index */
-            case MATROSKA_ID_CUES: {
-                if (!matroska->index_parsed) {
-                    res = matroska_parse_index(matroska);
-                } else
-                    res = ebml_read_skip(matroska);
-                break;
-            }
-
-            /* metadata */
-            case MATROSKA_ID_TAGS: {
-                if (!matroska->metadata_parsed) {
-                    res = matroska_parse_metadata(matroska);
-                } else
-                    res = ebml_read_skip(matroska);
-                break;
-            }
-
-            /* file index (if seekable, seek to Cues/Tags to parse it) */
-            case MATROSKA_ID_SEEKHEAD: {
-                res = matroska_parse_seekhead(matroska);
-                break;
-            }
-
-            case MATROSKA_ID_ATTACHMENTS: {
-                res = matroska_parse_attachments(s);
-                break;
-            }
-
-            case MATROSKA_ID_CLUSTER: {
-                /* Do not read the master - this will be done in the next
-                 * call to matroska_read_packet. */
-                res = 1;
-                break;
-            }
-
-            case MATROSKA_ID_CHAPTERS: {
-                res = matroska_parse_chapters(s);
-                break;
-            }
-
-            default:
-                av_log(matroska->ctx, AV_LOG_INFO,
-                       "Unknown matroska file header 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;
-        }
-    }
+    if (ebml_parse(matroska, matroska_segments, matroska, 0, 1) < 0)
+        return -1;
     matroska_execute_seekhead(matroska);
 
     /* Have we found a cluster? */
@@ -1781,7 +1654,6 @@ matroska_read_header (AVFormatContext   
 
         /* What do we do with private data? E.g. for Vorbis. */
     }
-    res = 0;
 
     attachements = attachements_list->elem;
     for (j=0; j<attachements_list->nb_elem; j++) {
@@ -1834,7 +1706,7 @@ matroska_read_header (AVFormatContext   
         }
     }
 
-    return res;
+    return 0;
 }
 
 static int
@@ -2291,8 +2163,7 @@ matroska_read_close (AVFormatContext *s)
     for (n=0; n < matroska->tracks.nb_elem; n++)
         if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO)
             av_free(tracks[n].audio.buf);
-    ebml_free(matroska_tracks, matroska);
-    ebml_free(matroska_index, matroska);
+    ebml_free(matroska_segment, matroska);
 
     return 0;
 }




More information about the ffmpeg-cvslog mailing list