From 6df478bf891b9fc5626e4a0b993899f310ba0a1c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 25 May 2014 09:07:32 +0200 Subject: matroskadec: split parsing tracks into a separate function --- libavformat/matroskadec.c | 127 +++++++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 58 deletions(-) (limited to 'libavformat/matroskadec.c') diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 7c6ae8050e..828c191222 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1438,68 +1438,13 @@ static int matroska_aac_sri(int samplerate) return sri; } -static int matroska_read_header(AVFormatContext *s) +static int matroska_parse_tracks(AVFormatContext *s) { MatroskaDemuxContext *matroska = s->priv_data; - EbmlList *attachments_list = &matroska->attachments; - EbmlList *chapters_list = &matroska->chapters; - MatroskaAttachment *attachments; - MatroskaChapter *chapters; - MatroskaTrack *tracks; - uint64_t max_start = 0; - int64_t pos; - Ebml ebml = { 0 }; + MatroskaTrack *tracks = matroska->tracks.elem; AVStream *st; - int i, j, res; - - matroska->ctx = s; - - /* First read the EBML header. */ - if (ebml_parse(matroska, ebml_syntax, &ebml) || - ebml.version > EBML_VERSION || - ebml.max_size > sizeof(uint64_t) || - ebml.id_length > sizeof(uint32_t) || - ebml.doctype_version > 2) { - av_log(matroska->ctx, AV_LOG_ERROR, - "EBML header using unsupported features\n" - "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", - ebml.version, ebml.doctype, ebml.doctype_version); - ebml_free(ebml_syntax, &ebml); - return AVERROR_PATCHWELCOME; - } - for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) - if (!strcmp(ebml.doctype, matroska_doctypes[i])) - break; - if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) { - av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype); - if (matroska->ctx->error_recognition & AV_EF_EXPLODE) { - ebml_free(ebml_syntax, &ebml); - return AVERROR_INVALIDDATA; - } - } - ebml_free(ebml_syntax, &ebml); - - /* The next thing is a segment. */ - pos = avio_tell(matroska->ctx->pb); - res = ebml_parse(matroska, matroska_segments, matroska); - // try resyncing until we find a EBML_STOP type element. - while (res != 1) { - res = matroska_resync(matroska, pos); - if (res < 0) - return res; - pos = avio_tell(matroska->ctx->pb); - res = ebml_parse(matroska, matroska_segment, matroska); - } - matroska_execute_seekhead(matroska); - - if (!matroska->time_scale) - matroska->time_scale = 1000000; - if (matroska->duration) - matroska->ctx->duration = matroska->duration * matroska->time_scale * - 1000 / AV_TIME_BASE; - av_dict_set(&s->metadata, "title", matroska->title, 0); + int i, j; - tracks = matroska->tracks.elem; for (i = 0; i < matroska->tracks.nb_elem; i++) { MatroskaTrack *track = &tracks[i]; enum AVCodecID codec_id = AV_CODEC_ID_NONE; @@ -1795,6 +1740,72 @@ static int matroska_read_header(AVFormatContext *s) } } + return 0; +} + +static int matroska_read_header(AVFormatContext *s) +{ + MatroskaDemuxContext *matroska = s->priv_data; + EbmlList *attachments_list = &matroska->attachments; + EbmlList *chapters_list = &matroska->chapters; + MatroskaAttachment *attachments; + MatroskaChapter *chapters; + uint64_t max_start = 0; + int64_t pos; + Ebml ebml = { 0 }; + int i, j, res; + + matroska->ctx = s; + + /* First read the EBML header. */ + if (ebml_parse(matroska, ebml_syntax, &ebml) || + ebml.version > EBML_VERSION || + ebml.max_size > sizeof(uint64_t) || + ebml.id_length > sizeof(uint32_t) || + ebml.doctype_version > 2) { + av_log(matroska->ctx, AV_LOG_ERROR, + "EBML header using unsupported features\n" + "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", + ebml.version, ebml.doctype, ebml.doctype_version); + ebml_free(ebml_syntax, &ebml); + return AVERROR_PATCHWELCOME; + } + for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) + if (!strcmp(ebml.doctype, matroska_doctypes[i])) + break; + if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) { + av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype); + if (matroska->ctx->error_recognition & AV_EF_EXPLODE) { + ebml_free(ebml_syntax, &ebml); + return AVERROR_INVALIDDATA; + } + } + ebml_free(ebml_syntax, &ebml); + + /* The next thing is a segment. */ + pos = avio_tell(matroska->ctx->pb); + res = ebml_parse(matroska, matroska_segments, matroska); + // try resyncing until we find a EBML_STOP type element. + while (res != 1) { + res = matroska_resync(matroska, pos); + if (res < 0) + return res; + pos = avio_tell(matroska->ctx->pb); + res = ebml_parse(matroska, matroska_segment, matroska); + } + matroska_execute_seekhead(matroska); + + if (!matroska->time_scale) + matroska->time_scale = 1000000; + if (matroska->duration) + matroska->ctx->duration = matroska->duration * matroska->time_scale * + 1000 / AV_TIME_BASE; + av_dict_set(&s->metadata, "title", matroska->title, 0); + + res = matroska_parse_tracks(s); + if (res < 0) + return res; + attachments = attachments_list->elem; for (j = 0; j < attachments_list->nb_elem; j++) { if (!(attachments[j].filename && attachments[j].mime && -- cgit v1.2.3