From 3fbd6d4e9c2c9dd023fae1d7035d45946fcdb2d4 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 12 Apr 2013 00:43:34 +0200 Subject: demux_mkv: split reading blocks and reading packets Move most code from demux_mkv_fill_buffer() to read_next_block(). The former is supposed to read raw blocks, while ..fill_buffer() reads blocks and turns them into packets. --- demux/demux_mkv.c | 84 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 37 deletions(-) (limited to 'demux/demux_mkv.c') diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index acc1849f37..d2e92befc8 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -2053,26 +2053,29 @@ struct block_info { uint8_t *data; }; -static void reset_block(struct block_info *block) +static void free_block(struct block_info *block) { free(block->data); - *block = (struct block_info){0}; - block->keyframe = true; + block->data = NULL; } static int read_block(demuxer_t *demuxer, struct block_info *block) { stream_t *s = demuxer->stream; + free_block(block); block->length = ebml_read_length(s, NULL); if (block->length > 500000000) - return -1; - free(block->data); + goto error; block->data = malloc(block->length + AV_LZO_INPUT_PADDING); demuxer->filepos = stream_tell(s); if (stream_read(s, block->data, block->length) != (int) block->length) - return -1; - return 0; + goto error; + return 1; + +error: + free_block(block); + return -1; } static int handle_block(demuxer_t *demuxer, struct block_info *block_info) @@ -2218,87 +2221,80 @@ static int read_block_group(demuxer_t *demuxer, int64_t end, { mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; - reset_block(block); + *block = (struct block_info){ .keyframe = true }; while (stream_tell(s) < end) { switch (ebml_read_id(s, NULL)) { case MATROSKA_ID_BLOCKDURATION: block->duration = ebml_read_uint(s, NULL); if (block->duration == EBML_UINT_INVALID) - return -1; + goto error; block->duration *= mkv_d->tc_scale; break; case MATROSKA_ID_BLOCK: if (read_block(demuxer, block) < 0) - return -1; + goto error; break; case MATROSKA_ID_REFERENCEBLOCK:; int64_t num = ebml_read_int(s, NULL); if (num == EBML_INT_INVALID) - return -1; + goto error; if (num) block->keyframe = false; break; case EBML_ID_INVALID: - return -1; + goto error; default: if (ebml_read_skip_or_resync_cluster(s, NULL) != 0) - return -1; + goto error; break; } } - return 0; + return block->data ? 1 : 0; + +error: + free_block(block); + return -1; } -static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) +static int read_next_block(demuxer_t *demuxer, struct block_info *block) { mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; stream_t *s = demuxer->stream; - struct block_info block = {0}; - reset_block(&block); while (1) { while (stream_tell(s) < mkv_d->cluster_end) { - reset_block(&block); - if (stream_tell(s) < mkv_d->cluster_end) { int64_t start_filepos = stream_tell(s); switch (ebml_read_id(s, NULL)) { - case MATROSKA_ID_TIMECODE:; + case MATROSKA_ID_TIMECODE: { uint64_t num = ebml_read_uint(s, NULL); if (num == EBML_UINT_INVALID) goto find_next_cluster; mkv_d->cluster_tc = num * mkv_d->tc_scale; add_cluster_position(demuxer, mkv_d->cluster_start, num); break; + } case MATROSKA_ID_BLOCKGROUP: { int64_t end = ebml_read_length(s, NULL); end += stream_tell(s); - if (read_block_group(demuxer, end, &block) < 0) + int res = read_block_group(demuxer, end, block); + if (res < 0) goto find_next_cluster; - if (block.data) { - int res = handle_block(demuxer, &block); - reset_block(&block); - if (res < 0) - goto find_next_cluster; - if (res > 0) - return 1; - } + if (res > 0) + return 1; break; } case MATROSKA_ID_SIMPLEBLOCK: { - block.simple = true; - if (read_block(demuxer, &block) < 0) - goto find_next_cluster; - int res = handle_block(demuxer, &block); - reset_block(&block); + *block = (struct block_info){ .simple = true }; + int res = read_block(demuxer, block); if (res < 0) goto find_next_cluster; if (res > 0) @@ -2322,7 +2318,6 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) } find_next_cluster: - reset_block(&block); mkv_d->cluster_end = 0; for (;;) { mkv_d->cluster_start = stream_tell(s); @@ -2330,7 +2325,7 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) if (id == MATROSKA_ID_CLUSTER) break; if (s->eof) - return 0; + return -1; ebml_read_skip_or_resync_cluster(s, NULL); } next_cluster: @@ -2339,8 +2334,23 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) if (mkv_d->cluster_end != EBML_UINT_INVALID) mkv_d->cluster_end += stream_tell(s); } +} - return 0; +static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) +{ + for (;;) { + int res; + struct block_info block; + res = read_next_block(demuxer, &block); + if (res < 0) + return 0; + if (res > 0) { + res = handle_block(demuxer, &block); + free_block(&block); + if (res > 0) + return 1; + } + } } static int create_index_until(struct demuxer *demuxer, uint64_t timecode) -- cgit v1.2.3