diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2019-05-17 00:30:12 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2019-07-16 16:16:59 -0300 |
commit | 7087fc95b258793cf55953e10fb9005f01141bc2 (patch) | |
tree | 48c28168eeecf7bb87ad2d3edb74e4457c1f9cee /libavformat/matroskadec.c | |
parent | 3ed2755baaf3f8a9f088f8c7b9cc7bd8c629e8fb (diff) | |
download | ffmpeg-7087fc95b258793cf55953e10fb9005f01141bc2.tar.gz |
avformat/matroskadec: Reuse positions
Up until now, avio_tell was used multiple times in ebml_parse and its
subroutines, although the result of these calls can usually be simply
derived from the result of earlier calls to avio_tell. This has been
changed. Unnecessary calls to avio_tell in ebml_parse are avoided now.
Furthermore, there has been a slight change in the output of some error
messages relating to elements exceeding their containing master element:
The reported position of the element now points to the first byte of the
element ID and no longer to the first byte of the element's payload.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r-- | libavformat/matroskadec.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 8ab233b8df..686b988859 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -976,7 +976,8 @@ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) * Read the next element as binary data. * 0 is success, < 0 or NEEDS_CHECKING is failure. */ -static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) +static int ebml_read_binary(AVIOContext *pb, int length, + int64_t pos, EbmlBin *bin) { int ret; @@ -987,7 +988,7 @@ static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) bin->data = bin->buf->data; bin->size = length; - bin->pos = avio_tell(pb); + bin->pos = pos; if ((ret = avio_read(pb, bin->data, length)) != length) { av_buffer_unref(&bin->buf); bin->data = NULL; @@ -1003,9 +1004,9 @@ static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) * are supposed to be sub-elements which can be read separately. * 0 is success, < 0 is failure. */ -static int ebml_read_master(MatroskaDemuxContext *matroska, uint64_t length) +static int ebml_read_master(MatroskaDemuxContext *matroska, + uint64_t length, int64_t pos) { - AVIOContext *pb = matroska->ctx->pb; MatroskaLevel *level; if (matroska->num_levels >= EBML_MAX_DEPTH) { @@ -1015,7 +1016,7 @@ static int ebml_read_master(MatroskaDemuxContext *matroska, uint64_t length) } level = &matroska->levels[matroska->num_levels++]; - level->start = avio_tell(pb); + level->start = pos; level->length = length; return 0; @@ -1173,7 +1174,7 @@ static int ebml_parse(MatroskaDemuxContext *matroska, AVIOContext *pb = matroska->ctx->pb; uint32_t id; uint64_t length; - int64_t pos = avio_tell(pb); + int64_t pos = avio_tell(pb), pos_alt; int res, update_pos = 1, level_check; void *newelem; MatroskaLevel1Element *level1_elem; @@ -1201,8 +1202,11 @@ static int ebml_parse(MatroskaDemuxContext *matroska, return res; } matroska->current_id = id | 1 << 7 * res; - } else - pos -= (av_log2(matroska->current_id) + 7) / 8; + pos_alt = pos + res; + } else { + pos_alt = pos; + pos -= (av_log2(matroska->current_id) + 7) / 8; + } id = matroska->current_id; @@ -1247,14 +1251,15 @@ static int ebml_parse(MatroskaDemuxContext *matroska, length, max_lengths[syntax->type], syntax->type); return AVERROR_INVALIDDATA; } + + pos_alt += res; + if (matroska->num_levels > 0) { MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; - AVIOContext *pb = matroska->ctx->pb; - int64_t pos = avio_tell(pb); if (length != EBML_UNKNOWN_LENGTH && level->length != EBML_UNKNOWN_LENGTH) { - uint64_t elem_end = pos + length, + uint64_t elem_end = pos_alt + length, level_end = level->start + level->length; if (elem_end < level_end) { @@ -1309,14 +1314,14 @@ static int ebml_parse(MatroskaDemuxContext *matroska, res = ebml_read_ascii(pb, length, data); break; case EBML_BIN: - res = ebml_read_binary(pb, length, data); + res = ebml_read_binary(pb, length, pos_alt, data); break; case EBML_LEVEL1: case EBML_NEST: - if ((res = ebml_read_master(matroska, length)) < 0) + if ((res = ebml_read_master(matroska, length, pos_alt)) < 0) return res; if (id == MATROSKA_ID_SEGMENT) - matroska->segment_start = avio_tell(matroska->ctx->pb); + matroska->segment_start = pos_alt; if (id == MATROSKA_ID_CUES) matroska->cues_parsing_deferred = 0; if (syntax->type == EBML_LEVEL1 && |