diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2019-05-17 00:29:59 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2019-06-23 00:47:50 -0300 |
commit | ffa64a4db8ba37face9508caee0cf25efff70c4a (patch) | |
tree | c0552429be19ff290881ab6e220717ac87803556 | |
parent | f3ca3e7f19c86563c2d3bca82962567396b1cc13 (diff) | |
download | ffmpeg-ffa64a4db8ba37face9508caee0cf25efff70c4a.tar.gz |
avformat/matroskadec: Don't keep old blocks
Before this commit, the Matroska muxer would read a block when required
to do so, parse the block, create and return the necessary AVPackets and
yet keep the blocks (in a dynamically allocated list), although they
aren't used at all any more. This has been changed. There is no list any
more and the block is immediately discarded after parsing.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r-- | libavformat/matroskadec.c | 87 |
1 files changed, 38 insertions, 49 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b594bc4a95..c449edf7dd 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -304,9 +304,20 @@ typedef struct MatroskaLevel { uint64_t length; } MatroskaLevel; +typedef struct MatroskaBlock { + uint64_t duration; + int64_t reference; + uint64_t non_simple; + EbmlBin bin; + uint64_t additional_id; + EbmlBin additional; + int64_t discard_padding; +} MatroskaBlock; + typedef struct MatroskaCluster { + MatroskaBlock block; uint64_t timecode; - EbmlList blocks; + int64_t pos; } MatroskaCluster; typedef struct MatroskaLevel1Element { @@ -356,8 +367,6 @@ typedef struct MatroskaDemuxContext { MatroskaLevel1Element level1_elems[64]; int num_level1_elems; - int current_cluster_num_blocks; - int64_t current_cluster_pos; MatroskaCluster current_cluster; /* WebM DASH Manifest live flag */ @@ -367,16 +376,6 @@ typedef struct MatroskaDemuxContext { int bandwidth; } MatroskaDemuxContext; -typedef struct MatroskaBlock { - uint64_t duration; - int64_t reference; - uint64_t non_simple; - EbmlBin bin; - uint64_t additional_id; - EbmlBin additional; - int64_t discard_padding; -} MatroskaBlock; - static const EbmlSyntax ebml_header[] = { { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml, version), { .u = EBML_VERSION } }, { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml, max_size), { .u = 8 } }, @@ -705,9 +704,9 @@ static const EbmlSyntax matroska_blockgroup[] = { }; static const EbmlSyntax matroska_cluster_parsing[] = { - { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) }, - { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster, blocks), { .n = matroska_blockgroup } }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster, blocks), { .n = matroska_blockgroup } }, + { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) }, + { MATROSKA_ID_BLOCKGROUP, EBML_NEST, 0, 0, { .n = matroska_blockgroup } }, + { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, 0, 0, { .n = matroska_blockgroup } }, { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE }, { MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE }, { MATROSKA_ID_INFO, EBML_NONE }, @@ -3452,57 +3451,48 @@ end: static int matroska_parse_cluster(MatroskaDemuxContext *matroska) { - EbmlList *blocks_list; - MatroskaBlock *blocks; - int i, res; + MatroskaCluster *cluster = &matroska->current_cluster; + MatroskaBlock *block = &cluster->block; + int res; res = ebml_parse(matroska, matroska_cluster_parsing, - &matroska->current_cluster); + cluster); if (res == 1) { /* New Cluster */ - if (matroska->current_cluster_pos) + if (cluster->pos) ebml_level_end(matroska); - ebml_free(matroska_cluster_parsing, &matroska->current_cluster); - memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster)); - matroska->current_cluster_num_blocks = 0; - matroska->current_cluster_pos = avio_tell(matroska->ctx->pb); + cluster->pos = avio_tell(matroska->ctx->pb); /* sizeof the ID which was already read */ if (matroska->current_id) - matroska->current_cluster_pos -= 4; + cluster->pos -= 4; res = ebml_parse(matroska, matroska_clusters, - &matroska->current_cluster); + cluster); /* Try parsing the block again. */ if (res == 1) res = ebml_parse(matroska, matroska_cluster_parsing, - &matroska->current_cluster); + cluster); } - if (!res && - matroska->current_cluster_num_blocks < - matroska->current_cluster.blocks.nb_elem) { - blocks_list = &matroska->current_cluster.blocks; - blocks = blocks_list->elem; + if (!res && block->bin.size > 0) { + int is_keyframe = block->non_simple ? block->reference == INT64_MIN : -1; + uint8_t* additional = block->additional.size > 0 ? + block->additional.data : NULL; - matroska->current_cluster_num_blocks = blocks_list->nb_elem; - i = blocks_list->nb_elem - 1; - if (blocks[i].bin.size > 0 && blocks[i].bin.data) { - int is_keyframe = blocks[i].non_simple ? blocks[i].reference == INT64_MIN : -1; - uint8_t* additional = blocks[i].additional.size > 0 ? - blocks[i].additional.data : NULL; - - res = matroska_parse_block(matroska, blocks[i].bin.buf, blocks[i].bin.data, - blocks[i].bin.size, blocks[i].bin.pos, + res = matroska_parse_block(matroska, block->bin.buf, block->bin.data, + block->bin.size, block->bin.pos, matroska->current_cluster.timecode, - blocks[i].duration, is_keyframe, - additional, blocks[i].additional_id, - blocks[i].additional.size, - matroska->current_cluster_pos, - blocks[i].discard_padding); - } + block->duration, is_keyframe, + additional, block->additional_id, + block->additional.size, + cluster->pos, + block->discard_padding); } + ebml_free(matroska_blockgroup, block); + memset(block, 0, sizeof(*block)); + return res; } @@ -3600,7 +3590,6 @@ static int matroska_read_close(AVFormatContext *s) for (n = 0; n < matroska->tracks.nb_elem; n++) if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) av_freep(&tracks[n].audio.buf); - ebml_free(matroska_cluster_parsing, &matroska->current_cluster); ebml_free(matroska_segment, matroska); return 0; |