matroskadec: reorder some functions in a more logical order
authorAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:42:39 +0000 (00:42 +0000)
committerAurelien Jacobs <aurel@gnuage.org>
Tue, 5 Aug 2008 00:42:39 +0000 (00:42 +0000)
Originally committed as revision 14604 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/matroskadec.c

index 13508b0..4cdeb52 100644 (file)
@@ -595,6 +595,24 @@ static int ebml_read_ascii(ByteIOContext *pb, int size, char **str)
 }
 
 /*
 }
 
 /*
+ * Read the next element as binary data.
+ * 0 is success, < 0 is failure.
+ */
+static int ebml_read_binary(ByteIOContext *pb, int length, EbmlBin *bin)
+{
+    av_free(bin->data);
+    if (!(bin->data = av_malloc(length)))
+        return AVERROR(ENOMEM);
+
+    bin->size = length;
+    bin->pos  = url_ftell(pb);
+    if (get_buffer(pb, bin->data, length) != length)
+        return AVERROR(EIO);
+
+    return 0;
+}
+
+/*
  * Read the next element, but only the header. The contents
  * are supposed to be sub-elements which can be read separately.
  * 0 is success, < 0 is failure.
  * Read the next element, but only the header. The contents
  * are supposed to be sub-elements which can be read separately.
  * 0 is success, < 0 is failure.
@@ -618,24 +636,6 @@ static int ebml_read_master(MatroskaDemuxContext *matroska, int length)
 }
 
 /*
 }
 
 /*
- * Read the next element as binary data.
- * 0 is success, < 0 is failure.
- */
-static int ebml_read_binary(ByteIOContext *pb, int length, EbmlBin *bin)
-{
-    av_free(bin->data);
-    if (!(bin->data = av_malloc(length)))
-        return AVERROR(ENOMEM);
-
-    bin->size = length;
-    bin->pos  = url_ftell(pb);
-    if (get_buffer(pb, bin->data, length) != length)
-        return AVERROR(EIO);
-
-    return 0;
-}
-
-/*
  * Read signed/unsigned "EBML" numbers.
  * Return: number of bytes processed, < 0 on error.
  * XXX: use ebml_read_num().
  * Read signed/unsigned "EBML" numbers.
  * Return: number of bytes processed, < 0 on error.
  * XXX: use ebml_read_num().
@@ -696,124 +696,54 @@ static int matroska_ebmlnum_sint(uint8_t *data, uint32_t size, int64_t *num)
     return res;
 }
 
     return res;
 }
 
+static int ebml_parse_elem(MatroskaDemuxContext *matroska,
+                           EbmlSyntax *syntax, void *data);
 
 
-static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
-                                                 int num)
+static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
+                         uint32_t id, void *data)
 {
 {
-    MatroskaTrack *tracks = matroska->tracks.elem;
     int i;
     int i;
-
-    for (i=0; i < matroska->tracks.nb_elem; i++)
-        if (tracks[i].num == num)
-            return &tracks[i];
-
-    av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num);
-    return NULL;
+    for (i=0; syntax[i].id; i++)
+        if (id == syntax[i].id)
+            break;
+    if (!syntax[i].id)
+        av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id);
+    return ebml_parse_elem(matroska, &syntax[i], data);
 }
 
 }
 
-
-/*
- * Put one packet in an application-supplied AVPacket struct.
- * Returns 0 on success or -1 on failure.
- */
-static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
-                                   AVPacket *pkt)
+static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
+                      void *data)
 {
 {
-    if (matroska->num_packets > 0) {
-        memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
-        av_free(matroska->packets[0]);
-        if (matroska->num_packets > 1) {
-            memmove(&matroska->packets[0], &matroska->packets[1],
-                    (matroska->num_packets - 1) * sizeof(AVPacket *));
-            matroska->packets =
-                av_realloc(matroska->packets, (matroska->num_packets - 1) *
-                           sizeof(AVPacket *));
-        } else {
-            av_freep(&matroska->packets);
-        }
-        matroska->num_packets--;
-        return 0;
-    }
-
-    return -1;
+    uint32_t id;
+    int res = ebml_read_element_id(matroska, &id);
+    return res < 0 ? res : ebml_parse_id(matroska, syntax, id, data);
 }
 
 }
 
-/*
- * Put a packet into our internal queue. Will be delivered to the
- * user/application during the next get_packet() call.
- */
-static void matroska_queue_packet(MatroskaDemuxContext *matroska, AVPacket *pkt)
+static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
+                           void *data)
 {
 {
-    matroska->packets =
-        av_realloc(matroska->packets, (matroska->num_packets + 1) *
-                   sizeof(AVPacket *));
-    matroska->packets[matroska->num_packets] = pkt;
-    matroska->num_packets++;
-}
+    int i, res = 0;
 
 
-/*
- * Free all packets in our internal queue.
- */
-static void matroska_clear_queue(MatroskaDemuxContext *matroska)
-{
-    if (matroska->packets) {
-        int n;
-        for (n = 0; n < matroska->num_packets; n++) {
-            av_free_packet(matroska->packets[n]);
-            av_free(matroska->packets[n]);
+    for (i=0; syntax[i].id; i++)
+        switch (syntax[i].type) {
+        case EBML_UINT:
+            *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u;
+            break;
+        case EBML_FLOAT:
+            *(double   *)((char *)data+syntax[i].data_offset) = syntax[i].def.f;
+            break;
+        case EBML_STR:
+        case EBML_UTF8:
+            *(char    **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s);
+            break;
         }
         }
-        av_free(matroska->packets);
-        matroska->packets = NULL;
-        matroska->num_packets = 0;
-    }
-}
-
-
-/*
- * Autodetecting...
- */
-static int matroska_probe(AVProbeData *p)
-{
-    uint64_t total = 0;
-    int len_mask = 0x80, size = 1, n = 1;
-    char probe_data[] = "matroska";
-
-    /* ebml header? */
-    if (AV_RB32(p->buf) != EBML_ID_HEADER)
-        return 0;
-
-    /* length of header */
-    total = p->buf[4];
-    while (size <= 8 && !(total & len_mask)) {
-        size++;
-        len_mask >>= 1;
-    }
-    if (size > 8)
-      return 0;
-    total &= (len_mask - 1);
-    while (n < size)
-        total = (total << 8) | p->buf[4 + n++];
-
-    /* does the probe data contain the whole header? */
-    if (p->buf_size < 4 + size + total)
-      return 0;
 
 
-    /* the header must contain the document type 'matroska'. For now,
-     * we don't parse the whole header but simply check for the
-     * availability of that array of characters inside the header.
-     * Not fully fool-proof, but good enough. */
-    for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++)
-        if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1))
-            return AVPROBE_SCORE_MAX;
+    while (!res && !ebml_level_end(matroska))
+        res = ebml_parse(matroska, syntax, data);
 
 
-    return 0;
+    return res;
 }
 
 }
 
-static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
-                         uint32_t id, void *data);
-static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
-                           void *data);
-
 static int ebml_parse_elem(MatroskaDemuxContext *matroska,
                            EbmlSyntax *syntax, void *data)
 {
 static int ebml_parse_elem(MatroskaDemuxContext *matroska,
                            EbmlSyntax *syntax, void *data)
 {
@@ -857,51 +787,6 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
     return res;
 }
 
     return res;
 }
 
-static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
-                         uint32_t id, void *data)
-{
-    int i;
-    for (i=0; syntax[i].id; i++)
-        if (id == syntax[i].id)
-            break;
-    if (!syntax[i].id)
-        av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id);
-    return ebml_parse_elem(matroska, &syntax[i], data);
-}
-
-static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
-                      void *data)
-{
-    uint32_t id;
-    int res = ebml_read_element_id(matroska, &id);
-    return res < 0 ? res : ebml_parse_id(matroska, syntax, id, data);
-}
-
-static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
-                           void *data)
-{
-    int i, res = 0;
-
-    for (i=0; syntax[i].id; i++)
-        switch (syntax[i].type) {
-        case EBML_UINT:
-            *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u;
-            break;
-        case EBML_FLOAT:
-            *(double   *)((char *)data+syntax[i].data_offset) = syntax[i].def.f;
-            break;
-        case EBML_STR:
-        case EBML_UTF8:
-            *(char    **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s);
-            break;
-        }
-
-    while (!res && !ebml_level_end(matroska))
-        res = ebml_parse(matroska, syntax, data);
-
-    return res;
-}
-
 static void ebml_free(EbmlSyntax *syntax, void *data)
 {
     int i, j;
 static void ebml_free(EbmlSyntax *syntax, void *data)
 {
     int i, j;
@@ -925,6 +810,61 @@ static void ebml_free(EbmlSyntax *syntax, void *data)
     }
 }
 
     }
 }
 
+
+/*
+ * Autodetecting...
+ */
+static int matroska_probe(AVProbeData *p)
+{
+    uint64_t total = 0;
+    int len_mask = 0x80, size = 1, n = 1;
+    char probe_data[] = "matroska";
+
+    /* ebml header? */
+    if (AV_RB32(p->buf) != EBML_ID_HEADER)
+        return 0;
+
+    /* length of header */
+    total = p->buf[4];
+    while (size <= 8 && !(total & len_mask)) {
+        size++;
+        len_mask >>= 1;
+    }
+    if (size > 8)
+      return 0;
+    total &= (len_mask - 1);
+    while (n < size)
+        total = (total << 8) | p->buf[4 + n++];
+
+    /* does the probe data contain the whole header? */
+    if (p->buf_size < 4 + size + total)
+      return 0;
+
+    /* the header must contain the document type 'matroska'. For now,
+     * we don't parse the whole header but simply check for the
+     * availability of that array of characters inside the header.
+     * Not fully fool-proof, but good enough. */
+    for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++)
+        if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1))
+            return AVPROBE_SCORE_MAX;
+
+    return 0;
+}
+
+static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
+                                                 int num)
+{
+    MatroskaTrack *tracks = matroska->tracks.elem;
+    int i;
+
+    for (i=0; i < matroska->tracks.nb_elem; i++)
+        if (tracks[i].num == num)
+            return &tracks[i];
+
+    av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num);
+    return NULL;
+}
+
 static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
                                   MatroskaTrack *track)
 {
 static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
                                   MatroskaTrack *track)
 {
@@ -1378,6 +1318,62 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
     return 0;
 }
 
     return 0;
 }
 
+/*
+ * Put a packet into our internal queue. Will be delivered to the
+ * user/application during the next get_packet() call.
+ */
+static void matroska_queue_packet(MatroskaDemuxContext *matroska, AVPacket *pkt)
+{
+    matroska->packets =
+        av_realloc(matroska->packets, (matroska->num_packets + 1) *
+                   sizeof(AVPacket *));
+    matroska->packets[matroska->num_packets] = pkt;
+    matroska->num_packets++;
+}
+
+/*
+ * Put one packet in an application-supplied AVPacket struct.
+ * Returns 0 on success or -1 on failure.
+ */
+static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
+                                   AVPacket *pkt)
+{
+    if (matroska->num_packets > 0) {
+        memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
+        av_free(matroska->packets[0]);
+        if (matroska->num_packets > 1) {
+            memmove(&matroska->packets[0], &matroska->packets[1],
+                    (matroska->num_packets - 1) * sizeof(AVPacket *));
+            matroska->packets =
+                av_realloc(matroska->packets, (matroska->num_packets - 1) *
+                           sizeof(AVPacket *));
+        } else {
+            av_freep(&matroska->packets);
+        }
+        matroska->num_packets--;
+        return 0;
+    }
+
+    return -1;
+}
+
+/*
+ * Free all packets in our internal queue.
+ */
+static void matroska_clear_queue(MatroskaDemuxContext *matroska)
+{
+    if (matroska->packets) {
+        int n;
+        for (n = 0; n < matroska->num_packets; n++) {
+            av_free_packet(matroska->packets[n]);
+            av_free(matroska->packets[n]);
+        }
+        av_free(matroska->packets);
+        matroska->packets = NULL;
+        matroska->num_packets = 0;
+    }
+}
+
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
                                 int size, int64_t pos, uint64_t cluster_time,
                                 uint64_t duration, int is_keyframe)
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
                                 int size, int64_t pos, uint64_t cluster_time,
                                 uint64_t duration, int is_keyframe)