diff options
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r-- | libavformat/mov.c | 164 |
1 files changed, 82 insertions, 82 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 5010ec8df5..becfeec3bb 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -66,7 +66,7 @@ typedef struct MOVParseTableEntry { int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom); } MOVParseTableEntry; -static const MOVParseTableEntry mov_default_parse_table[]; +static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom); static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, unsigned len, const char *key) @@ -355,87 +355,6 @@ static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } -static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int64_t total_size = 0; - MOVAtom a; - int i; - - if (atom.size < 0) - atom.size = INT64_MAX; - while (total_size + 8 <= atom.size && !url_feof(pb)) { - int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL; - a.size = atom.size; - a.type=0; - if (atom.size >= 8) { - a.size = avio_rb32(pb); - a.type = avio_rl32(pb); - if (atom.type != MKTAG('r','o','o','t') && - atom.type != MKTAG('m','o','o','v')) - { - if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) - { - av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); - avio_skip(pb, -8); - return 0; - } - } - total_size += 8; - if (a.size == 1) { /* 64 bit extended size */ - a.size = avio_rb64(pb) - 8; - total_size += 8; - } - } - av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", - a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); - if (a.size == 0) { - a.size = atom.size - total_size + 8; - } - a.size -= 8; - if (a.size < 0) - break; - a.size = FFMIN(a.size, atom.size - total_size); - - for (i = 0; mov_default_parse_table[i].type; i++) - if (mov_default_parse_table[i].type == a.type) { - parse = mov_default_parse_table[i].parse; - break; - } - - // container is user data - if (!parse && (atom.type == MKTAG('u','d','t','a') || - atom.type == MKTAG('i','l','s','t'))) - parse = mov_read_udta_string; - - if (!parse) { /* skip leaf atoms data */ - avio_skip(pb, a.size); - } else { - int64_t start_pos = avio_tell(pb); - int64_t left; - int err = parse(c, pb, a); - if (err < 0) - return err; - if (c->found_moov && c->found_mdat && - ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || - start_pos + a.size == avio_size(pb))) { - if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) - c->next_root_atom = start_pos + a.size; - return 0; - } - left = a.size - avio_tell(pb) + start_pos; - if (left > 0) /* skip garbage at atom end */ - avio_skip(pb, left); - } - - total_size += a.size; - } - - if (total_size < atom.size && atom.size < 0x7ffff) - avio_skip(pb, atom.size - total_size); - - return 0; -} - static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; @@ -2726,6 +2645,87 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { 0, NULL } }; +static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + int64_t total_size = 0; + MOVAtom a; + int i; + + if (atom.size < 0) + atom.size = INT64_MAX; + while (total_size + 8 <= atom.size && !url_feof(pb)) { + int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL; + a.size = atom.size; + a.type=0; + if (atom.size >= 8) { + a.size = avio_rb32(pb); + a.type = avio_rl32(pb); + if (atom.type != MKTAG('r','o','o','t') && + atom.type != MKTAG('m','o','o','v')) + { + if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) + { + av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); + avio_skip(pb, -8); + return 0; + } + } + total_size += 8; + if (a.size == 1) { /* 64 bit extended size */ + a.size = avio_rb64(pb) - 8; + total_size += 8; + } + } + av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", + a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); + if (a.size == 0) { + a.size = atom.size - total_size + 8; + } + a.size -= 8; + if (a.size < 0) + break; + a.size = FFMIN(a.size, atom.size - total_size); + + for (i = 0; mov_default_parse_table[i].type; i++) + if (mov_default_parse_table[i].type == a.type) { + parse = mov_default_parse_table[i].parse; + break; + } + + // container is user data + if (!parse && (atom.type == MKTAG('u','d','t','a') || + atom.type == MKTAG('i','l','s','t'))) + parse = mov_read_udta_string; + + if (!parse) { /* skip leaf atoms data */ + avio_skip(pb, a.size); + } else { + int64_t start_pos = avio_tell(pb); + int64_t left; + int err = parse(c, pb, a); + if (err < 0) + return err; + if (c->found_moov && c->found_mdat && + ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || + start_pos + a.size == avio_size(pb))) { + if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) + c->next_root_atom = start_pos + a.size; + return 0; + } + left = a.size - avio_tell(pb) + start_pos; + if (left > 0) /* skip garbage at atom end */ + avio_skip(pb, left); + } + + total_size += a.size; + } + + if (total_size < atom.size && atom.size < 0x7ffff) + avio_skip(pb, atom.size - total_size); + + return 0; +} + static int mov_probe(AVProbeData *p) { unsigned int offset; |