summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2008-08-05 00:42:39 +0000
committerAurelien Jacobs <aurel@gnuage.org>2008-08-05 00:42:39 +0000
commit737c40da20de07fd1b1ca99699f896c84b03f0ff (patch)
tree06d50219d1ac1eb87d39afb4c840c46503e98b07
parent1b6d23bbcbeb3bdb44747275295b92495c89ab6d (diff)
matroskadec: reorder some functions in a more logical order
Originally committed as revision 14604 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/matroskadec.c328
1 files changed, 162 insertions, 166 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 13508b08c9..4cdeb527e0 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -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.
@@ -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().
@@ -696,124 +696,54 @@ static int matroska_ebmlnum_sint(uint8_t *data, uint32_t size, int64_t *num)
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;
-
- 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)
{
@@ -857,51 +787,6 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
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;
@@ -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)
{
@@ -1378,6 +1318,62 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
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)