Commit ffa64a4d authored by Andreas Rheinhardt's avatar Andreas Rheinhardt Committed by James Almer

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: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
parent f3ca3e7f
...@@ -304,9 +304,20 @@ typedef struct MatroskaLevel { ...@@ -304,9 +304,20 @@ typedef struct MatroskaLevel {
uint64_t length; uint64_t length;
} MatroskaLevel; } 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 { typedef struct MatroskaCluster {
MatroskaBlock block;
uint64_t timecode; uint64_t timecode;
EbmlList blocks; int64_t pos;
} MatroskaCluster; } MatroskaCluster;
typedef struct MatroskaLevel1Element { typedef struct MatroskaLevel1Element {
...@@ -356,8 +367,6 @@ typedef struct MatroskaDemuxContext { ...@@ -356,8 +367,6 @@ typedef struct MatroskaDemuxContext {
MatroskaLevel1Element level1_elems[64]; MatroskaLevel1Element level1_elems[64];
int num_level1_elems; int num_level1_elems;
int current_cluster_num_blocks;
int64_t current_cluster_pos;
MatroskaCluster current_cluster; MatroskaCluster current_cluster;
/* WebM DASH Manifest live flag */ /* WebM DASH Manifest live flag */
...@@ -367,16 +376,6 @@ typedef struct MatroskaDemuxContext { ...@@ -367,16 +376,6 @@ typedef struct MatroskaDemuxContext {
int bandwidth; int bandwidth;
} MatroskaDemuxContext; } 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[] = { static const EbmlSyntax ebml_header[] = {
{ EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml, version), { .u = EBML_VERSION } }, { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml, version), { .u = EBML_VERSION } },
{ EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml, max_size), { .u = 8 } }, { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml, max_size), { .u = 8 } },
...@@ -705,9 +704,9 @@ static const EbmlSyntax matroska_blockgroup[] = { ...@@ -705,9 +704,9 @@ static const EbmlSyntax matroska_blockgroup[] = {
}; };
static const EbmlSyntax matroska_cluster_parsing[] = { static const EbmlSyntax matroska_cluster_parsing[] = {
{ MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) }, { MATROSKA_ID_CLUSTERTIMECODE, EBML_UINT, 0, offsetof(MatroskaCluster, timecode) },
{ MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster, blocks), { .n = matroska_blockgroup } }, { MATROSKA_ID_BLOCKGROUP, EBML_NEST, 0, 0, { .n = matroska_blockgroup } },
{ MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster, blocks), { .n = matroska_blockgroup } }, { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, 0, 0, { .n = matroska_blockgroup } },
{ MATROSKA_ID_CLUSTERPOSITION, EBML_NONE }, { MATROSKA_ID_CLUSTERPOSITION, EBML_NONE },
{ MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE }, { MATROSKA_ID_CLUSTERPREVSIZE, EBML_NONE },
{ MATROSKA_ID_INFO, EBML_NONE }, { MATROSKA_ID_INFO, EBML_NONE },
...@@ -3452,57 +3451,48 @@ end: ...@@ -3452,57 +3451,48 @@ end:
static int matroska_parse_cluster(MatroskaDemuxContext *matroska) static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
{ {
EbmlList *blocks_list; MatroskaCluster *cluster = &matroska->current_cluster;
MatroskaBlock *blocks; MatroskaBlock *block = &cluster->block;
int i, res; int res;
res = ebml_parse(matroska, res = ebml_parse(matroska,
matroska_cluster_parsing, matroska_cluster_parsing,
&matroska->current_cluster); cluster);
if (res == 1) { if (res == 1) {
/* New Cluster */ /* New Cluster */
if (matroska->current_cluster_pos) if (cluster->pos)
ebml_level_end(matroska); ebml_level_end(matroska);
ebml_free(matroska_cluster_parsing, &matroska->current_cluster); cluster->pos = avio_tell(matroska->ctx->pb);
memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster));
matroska->current_cluster_num_blocks = 0;
matroska->current_cluster_pos = avio_tell(matroska->ctx->pb);
/* sizeof the ID which was already read */ /* sizeof the ID which was already read */
if (matroska->current_id) if (matroska->current_id)
matroska->current_cluster_pos -= 4; cluster->pos -= 4;
res = ebml_parse(matroska, res = ebml_parse(matroska,
matroska_clusters, matroska_clusters,
&matroska->current_cluster); cluster);
/* Try parsing the block again. */ /* Try parsing the block again. */
if (res == 1) if (res == 1)
res = ebml_parse(matroska, res = ebml_parse(matroska,
matroska_cluster_parsing, matroska_cluster_parsing,
&matroska->current_cluster); cluster);
} }
if (!res && if (!res && block->bin.size > 0) {
matroska->current_cluster_num_blocks < int is_keyframe = block->non_simple ? block->reference == INT64_MIN : -1;
matroska->current_cluster.blocks.nb_elem) { uint8_t* additional = block->additional.size > 0 ?
blocks_list = &matroska->current_cluster.blocks; block->additional.data : NULL;
blocks = blocks_list->elem;
matroska->current_cluster_num_blocks = blocks_list->nb_elem; res = matroska_parse_block(matroska, block->bin.buf, block->bin.data,
i = blocks_list->nb_elem - 1; block->bin.size, block->bin.pos,
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,
matroska->current_cluster.timecode, matroska->current_cluster.timecode,
blocks[i].duration, is_keyframe, block->duration, is_keyframe,
additional, blocks[i].additional_id, additional, block->additional_id,
blocks[i].additional.size, block->additional.size,
matroska->current_cluster_pos, cluster->pos,
blocks[i].discard_padding); block->discard_padding);
}
} }
ebml_free(matroska_blockgroup, block);
memset(block, 0, sizeof(*block));
return res; return res;
} }
...@@ -3600,7 +3590,6 @@ static int matroska_read_close(AVFormatContext *s) ...@@ -3600,7 +3590,6 @@ static int matroska_read_close(AVFormatContext *s)
for (n = 0; n < matroska->tracks.nb_elem; n++) for (n = 0; n < matroska->tracks.nb_elem; n++)
if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO)
av_freep(&tracks[n].audio.buf); av_freep(&tracks[n].audio.buf);
ebml_free(matroska_cluster_parsing, &matroska->current_cluster);
ebml_free(matroska_segment, matroska); ebml_free(matroska_segment, matroska);
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment