Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(848)

Unified Diff: ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c

Issue 8296016: Parse matroska clusters incrementally as opposed to all at once. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ffmpeg/patches/ugly/41_matroska_cluster_incremental.patch ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c
diff --git a/ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c b/ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c
index a74bc41aee5e578f81b9054571bfd145c498c375..693f12ac31c29e58bb169ee4884e156b660630dc 100644
--- a/ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c
+++ b/ffmpeg/source/patched-ffmpeg/libavformat/matroskadec.c
@@ -228,6 +228,11 @@ typedef struct {
} MatroskaLevel;
typedef struct {
+ uint64_t timecode;
+ EbmlList blocks;
+} MatroskaCluster;
+
+typedef struct {
AVFormatContext *ctx;
/* EBML stuff */
@@ -262,6 +267,10 @@ typedef struct {
/* File has a CUES element, but we defer parsing until it is needed. */
int cues_parsing_deferred;
+
+ int current_cluster_num_blocks;
+ int64_t current_cluster_pos;
+ MatroskaCluster current_cluster;
} MatroskaDemuxContext;
typedef struct {
@@ -271,11 +280,6 @@ typedef struct {
EbmlBin bin;
} MatroskaBlock;
-typedef struct {
- uint64_t timecode;
- EbmlList blocks;
-} MatroskaCluster;
-
static 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} },
@@ -546,6 +550,38 @@ static EbmlSyntax matroska_clusters[] = {
{ 0 }
};
+static EbmlSyntax matroska_cluster_incremental_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_CLUSTERPOSITION,EBML_NONE },
+ { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE },
+ { MATROSKA_ID_INFO, EBML_NONE },
+ { MATROSKA_ID_CUES, EBML_NONE },
+ { MATROSKA_ID_TAGS, EBML_NONE },
+ { MATROSKA_ID_SEEKHEAD, EBML_NONE },
+ { MATROSKA_ID_CLUSTER, EBML_STOP },
+ { 0 }
+};
+
+static EbmlSyntax matroska_cluster_incremental[] = {
+ { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) },
+ { MATROSKA_ID_BLOCKGROUP, EBML_STOP },
+ { MATROSKA_ID_SIMPLEBLOCK, EBML_STOP },
+ { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE },
+ { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE },
+ { 0 }
+};
+
+static EbmlSyntax matroska_clusters_incremental[] = {
+ { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster_incremental} },
+ { MATROSKA_ID_INFO, EBML_NONE },
+ { MATROSKA_ID_CUES, EBML_NONE },
+ { MATROSKA_ID_TAGS, EBML_NONE },
+ { MATROSKA_ID_SEEKHEAD, EBML_NONE },
+ { 0 }
+};
+
static const char *matroska_doctypes[] = { "matroska", "webm" };
/*
@@ -1690,6 +1726,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
sizeof(AVPacket *));
} else {
av_freep(&matroska->packets);
+ matroska->prev_pkt = NULL;
}
matroska->num_packets--;
return 0;
@@ -1993,6 +2030,59 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
return res;
}
+static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
+{
+ EbmlList *blocks_list;
+ MatroskaBlock *blocks;
+ int i, res;
+ res = ebml_parse(matroska,
+ matroska_cluster_incremental_parsing,
+ &matroska->current_cluster);
+ if (res == 1) {
+ /* New Cluster */
+ if (matroska->current_cluster_pos)
+ ebml_level_end(matroska);
+ ebml_free(matroska_cluster, &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->prev_pkt = NULL;
+ /* sizeof the ID which was already read */
+ if (matroska->current_id)
+ matroska->current_cluster_pos -= 4;
+ res = ebml_parse(matroska,
+ matroska_clusters_incremental,
+ &matroska->current_cluster);
+ /* Try parsing the block agiain. */
+ if (res == 1)
+ res = ebml_parse(matroska,
+ matroska_cluster_incremental_parsing,
+ &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 : -1;
+ res=matroska_parse_block(matroska,
+ blocks[i].bin.data, blocks[i].bin.size,
+ blocks[i].bin.pos,
+ matroska->current_cluster.timecode,
+ blocks[i].duration, is_keyframe,
+ matroska->current_cluster_pos);
+ }
+ }
+
+ if (res < 0) matroska->done = 1;
+ return res;
+}
+
static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MatroskaDemuxContext *matroska = s->priv_data;
@@ -2001,7 +2091,7 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
while (!ret && matroska_deliver_packet(matroska, pkt)) {
if (matroska->done)
return AVERROR_EOF;
- ret = matroska_parse_cluster(matroska);
+ ret = matroska_parse_cluster_incremental(matroska);
}
return ret;
@@ -2075,6 +2165,7 @@ 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_free(tracks[n].audio.buf);
+ ebml_free(matroska_cluster, &matroska->current_cluster);
ebml_free(matroska_segment, matroska);
return 0;
« no previous file with comments | « ffmpeg/patches/ugly/41_matroska_cluster_incremental.patch ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698