@@ -304,9 +304,19 @@ 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;
} MatroskaCluster;
typedef struct MatroskaLevel1Element {
@@ -356,7 +366,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;
@@ -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 },
@@ -3429,9 +3428,8 @@ end:
static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
{
- EbmlList *blocks_list;
- MatroskaBlock *blocks;
- int i, res;
+ MatroskaBlock *block = &matroska->current_cluster.block;
+ int res;
res = ebml_parse(matroska,
matroska_cluster_parsing,
&matroska->current_cluster);
@@ -3439,10 +3437,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
/* New Cluster */
if (matroska->current_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);
+ matroska->current_cluster_pos = avio_tell(matroska->ctx->pb);
/* sizeof the ID which was already read */
if (matroska->current_id)
matroska->current_cluster_pos -= 4;
@@ -3456,31 +3451,25 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
&matroska->current_cluster);
}
- if (!res &&
- matroska->current_cluster_num_blocks <
- matroska->current_cluster.blocks.nb_elem) {
- blocks_list = &matroska->current_cluster.blocks;
- blocks = blocks_list->elem;
-
- 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;
- if (!blocks[i].non_simple)
- blocks[i].duration = 0;
- res = matroska_parse_block(matroska, blocks[i].bin.buf, blocks[i].bin.data,
- blocks[i].bin.size, blocks[i].bin.pos,
+ 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;
+ if (!block->non_simple)
+ block->duration = 0;
+ 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,
+ block->duration, is_keyframe,
+ additional, block->additional_id,
+ block->additional.size,
matroska->current_cluster_pos,
- blocks[i].discard_padding);
- }
+ block->discard_padding);
}
+ ebml_free(matroska_blockgroup, block);
+ memset(block, 0, sizeof(*block));
+
return res;
}
@@ -3579,7 +3568,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;
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@googlemail.com> --- libavformat/matroskadec.c | 76 +++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 44 deletions(-)