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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ffmpeg/patches/ugly/41_matroska_cluster_incremental.patch ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Matroska file demuxer 2 * Matroska file demuxer
3 * Copyright (c) 2003-2008 The FFmpeg Project 3 * Copyright (c) 2003-2008 The FFmpeg Project
4 * 4 *
5 * This file is part of FFmpeg. 5 * This file is part of FFmpeg.
6 * 6 *
7 * FFmpeg is free software; you can redistribute it and/or 7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 uint64_t id; 221 uint64_t id;
222 uint64_t pos; 222 uint64_t pos;
223 } MatroskaSeekhead; 223 } MatroskaSeekhead;
224 224
225 typedef struct { 225 typedef struct {
226 uint64_t start; 226 uint64_t start;
227 uint64_t length; 227 uint64_t length;
228 } MatroskaLevel; 228 } MatroskaLevel;
229 229
230 typedef struct { 230 typedef struct {
231 uint64_t timecode;
232 EbmlList blocks;
233 } MatroskaCluster;
234
235 typedef struct {
231 AVFormatContext *ctx; 236 AVFormatContext *ctx;
232 237
233 /* EBML stuff */ 238 /* EBML stuff */
234 int num_levels; 239 int num_levels;
235 MatroskaLevel levels[EBML_MAX_DEPTH]; 240 MatroskaLevel levels[EBML_MAX_DEPTH];
236 int level_up; 241 int level_up;
237 uint32_t current_id; 242 uint32_t current_id;
238 243
239 uint64_t time_scale; 244 uint64_t time_scale;
240 double duration; 245 double duration;
(...skipping 14 matching lines...) Expand all
255 AVPacket *prev_pkt; 260 AVPacket *prev_pkt;
256 261
257 int done; 262 int done;
258 263
259 /* What to skip before effectively reading a packet. */ 264 /* What to skip before effectively reading a packet. */
260 int skip_to_keyframe; 265 int skip_to_keyframe;
261 uint64_t skip_to_timecode; 266 uint64_t skip_to_timecode;
262 267
263 /* File has a CUES element, but we defer parsing until it is needed. */ 268 /* File has a CUES element, but we defer parsing until it is needed. */
264 int cues_parsing_deferred; 269 int cues_parsing_deferred;
270
271 int current_cluster_num_blocks;
272 int64_t current_cluster_pos;
273 MatroskaCluster current_cluster;
265 } MatroskaDemuxContext; 274 } MatroskaDemuxContext;
266 275
267 typedef struct { 276 typedef struct {
268 uint64_t duration; 277 uint64_t duration;
269 int64_t reference; 278 int64_t reference;
270 uint64_t non_simple; 279 uint64_t non_simple;
271 EbmlBin bin; 280 EbmlBin bin;
272 } MatroskaBlock; 281 } MatroskaBlock;
273 282
274 typedef struct {
275 uint64_t timecode;
276 EbmlList blocks;
277 } MatroskaCluster;
278
279 static EbmlSyntax ebml_header[] = { 283 static EbmlSyntax ebml_header[] = {
280 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u= EBML_VERSION} }, 284 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u= EBML_VERSION} },
281 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u =8} }, 285 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u =8} },
282 { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {. u=4} }, 286 { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {. u=4} },
283 { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s= "(none)"} }, 287 { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s= "(none)"} },
284 { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_versio n), {.u=1} }, 288 { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_versio n), {.u=1} },
285 { EBML_ID_EBMLVERSION, EBML_NONE }, 289 { EBML_ID_EBMLVERSION, EBML_NONE },
286 { EBML_ID_DOCTYPEVERSION, EBML_NONE }, 290 { EBML_ID_DOCTYPEVERSION, EBML_NONE },
287 { 0 } 291 { 0 }
288 }; 292 };
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 543
540 static EbmlSyntax matroska_clusters[] = { 544 static EbmlSyntax matroska_clusters[] = {
541 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, 545 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} },
542 { MATROSKA_ID_INFO, EBML_NONE }, 546 { MATROSKA_ID_INFO, EBML_NONE },
543 { MATROSKA_ID_CUES, EBML_NONE }, 547 { MATROSKA_ID_CUES, EBML_NONE },
544 { MATROSKA_ID_TAGS, EBML_NONE }, 548 { MATROSKA_ID_TAGS, EBML_NONE },
545 { MATROSKA_ID_SEEKHEAD, EBML_NONE }, 549 { MATROSKA_ID_SEEKHEAD, EBML_NONE },
546 { 0 } 550 { 0 }
547 }; 551 };
548 552
553 static EbmlSyntax matroska_cluster_incremental_parsing[] = {
554 { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode ) },
555 { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(Mat roskaCluster,blocks), {.n=matroska_blockgroup} },
556 { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(Mat roskaCluster,blocks), {.n=matroska_blockgroup} },
557 { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE },
558 { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE },
559 { MATROSKA_ID_INFO, EBML_NONE },
560 { MATROSKA_ID_CUES, EBML_NONE },
561 { MATROSKA_ID_TAGS, EBML_NONE },
562 { MATROSKA_ID_SEEKHEAD, EBML_NONE },
563 { MATROSKA_ID_CLUSTER, EBML_STOP },
564 { 0 }
565 };
566
567 static EbmlSyntax matroska_cluster_incremental[] = {
568 { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode ) },
569 { MATROSKA_ID_BLOCKGROUP, EBML_STOP },
570 { MATROSKA_ID_SIMPLEBLOCK, EBML_STOP },
571 { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE },
572 { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE },
573 { 0 }
574 };
575
576 static EbmlSyntax matroska_clusters_incremental[] = {
577 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster_incremen tal} },
578 { MATROSKA_ID_INFO, EBML_NONE },
579 { MATROSKA_ID_CUES, EBML_NONE },
580 { MATROSKA_ID_TAGS, EBML_NONE },
581 { MATROSKA_ID_SEEKHEAD, EBML_NONE },
582 { 0 }
583 };
584
549 static const char *matroska_doctypes[] = { "matroska", "webm" }; 585 static const char *matroska_doctypes[] = { "matroska", "webm" };
550 586
551 /* 587 /*
552 * Return: Whether we reached the end of a level in the hierarchy or not. 588 * Return: Whether we reached the end of a level in the hierarchy or not.
553 */ 589 */
554 static int ebml_level_end(MatroskaDemuxContext *matroska) 590 static int ebml_level_end(MatroskaDemuxContext *matroska)
555 { 591 {
556 AVIOContext *pb = matroska->ctx->pb; 592 AVIOContext *pb = matroska->ctx->pb;
557 int64_t pos = avio_tell(pb); 593 int64_t pos = avio_tell(pb);
558 594
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); 1719 memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
1684 av_free(matroska->packets[0]); 1720 av_free(matroska->packets[0]);
1685 if (matroska->num_packets > 1) { 1721 if (matroska->num_packets > 1) {
1686 memmove(&matroska->packets[0], &matroska->packets[1], 1722 memmove(&matroska->packets[0], &matroska->packets[1],
1687 (matroska->num_packets - 1) * sizeof(AVPacket *)); 1723 (matroska->num_packets - 1) * sizeof(AVPacket *));
1688 matroska->packets = 1724 matroska->packets =
1689 av_realloc(matroska->packets, (matroska->num_packets - 1) * 1725 av_realloc(matroska->packets, (matroska->num_packets - 1) *
1690 sizeof(AVPacket *)); 1726 sizeof(AVPacket *));
1691 } else { 1727 } else {
1692 av_freep(&matroska->packets); 1728 av_freep(&matroska->packets);
1729 matroska->prev_pkt = NULL;
1693 } 1730 }
1694 matroska->num_packets--; 1731 matroska->num_packets--;
1695 return 0; 1732 return 0;
1696 } 1733 }
1697 1734
1698 return -1; 1735 return -1;
1699 } 1736 }
1700 1737
1701 /* 1738 /*
1702 * Free all packets in our internal queue. 1739 * Free all packets in our internal queue.
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 blocks[i].bin.data, blocks[i].bin.size, 2023 blocks[i].bin.data, blocks[i].bin.size,
1987 blocks[i].bin.pos, cluster.timecode, 2024 blocks[i].bin.pos, cluster.timecode,
1988 blocks[i].duration, is_keyframe, 2025 blocks[i].duration, is_keyframe,
1989 pos); 2026 pos);
1990 } 2027 }
1991 ebml_free(matroska_cluster, &cluster); 2028 ebml_free(matroska_cluster, &cluster);
1992 if (res < 0) matroska->done = 1; 2029 if (res < 0) matroska->done = 1;
1993 return res; 2030 return res;
1994 } 2031 }
1995 2032
2033 static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
2034 {
2035 EbmlList *blocks_list;
2036 MatroskaBlock *blocks;
2037 int i, res;
2038 res = ebml_parse(matroska,
2039 matroska_cluster_incremental_parsing,
2040 &matroska->current_cluster);
2041 if (res == 1) {
2042 /* New Cluster */
2043 if (matroska->current_cluster_pos)
2044 ebml_level_end(matroska);
2045 ebml_free(matroska_cluster, &matroska->current_cluster);
2046 memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster));
2047 matroska->current_cluster_num_blocks = 0;
2048 matroska->current_cluster_pos = avio_tell(matroska->ctx->pb);
2049 matroska->prev_pkt = NULL;
2050 /* sizeof the ID which was already read */
2051 if (matroska->current_id)
2052 matroska->current_cluster_pos -= 4;
2053 res = ebml_parse(matroska,
2054 matroska_clusters_incremental,
2055 &matroska->current_cluster);
2056 /* Try parsing the block agiain. */
2057 if (res == 1)
2058 res = ebml_parse(matroska,
2059 matroska_cluster_incremental_parsing,
2060 &matroska->current_cluster);
2061 }
2062
2063 if (!res &&
2064 matroska->current_cluster_num_blocks <
2065 matroska->current_cluster.blocks.nb_elem) {
2066 blocks_list = &matroska->current_cluster.blocks;
2067 blocks = blocks_list->elem;
2068
2069 matroska->current_cluster_num_blocks = blocks_list->nb_elem;
2070 i = blocks_list->nb_elem - 1;
2071 if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
2072 int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
2073 res=matroska_parse_block(matroska,
2074 blocks[i].bin.data, blocks[i].bin.size,
2075 blocks[i].bin.pos,
2076 matroska->current_cluster.timecode,
2077 blocks[i].duration, is_keyframe,
2078 matroska->current_cluster_pos);
2079 }
2080 }
2081
2082 if (res < 0) matroska->done = 1;
2083 return res;
2084 }
2085
1996 static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) 2086 static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
1997 { 2087 {
1998 MatroskaDemuxContext *matroska = s->priv_data; 2088 MatroskaDemuxContext *matroska = s->priv_data;
1999 int ret = 0; 2089 int ret = 0;
2000 2090
2001 while (!ret && matroska_deliver_packet(matroska, pkt)) { 2091 while (!ret && matroska_deliver_packet(matroska, pkt)) {
2002 if (matroska->done) 2092 if (matroska->done)
2003 return AVERROR_EOF; 2093 return AVERROR_EOF;
2004 ret = matroska_parse_cluster(matroska); 2094 ret = matroska_parse_cluster_incremental(matroska);
2005 } 2095 }
2006 2096
2007 return ret; 2097 return ret;
2008 } 2098 }
2009 2099
2010 static int matroska_read_seek(AVFormatContext *s, int stream_index, 2100 static int matroska_read_seek(AVFormatContext *s, int stream_index,
2011 int64_t timestamp, int flags) 2101 int64_t timestamp, int flags)
2012 { 2102 {
2013 MatroskaDemuxContext *matroska = s->priv_data; 2103 MatroskaDemuxContext *matroska = s->priv_data;
2014 MatroskaTrack *tracks = matroska->tracks.elem; 2104 MatroskaTrack *tracks = matroska->tracks.elem;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 { 2158 {
2069 MatroskaDemuxContext *matroska = s->priv_data; 2159 MatroskaDemuxContext *matroska = s->priv_data;
2070 MatroskaTrack *tracks = matroska->tracks.elem; 2160 MatroskaTrack *tracks = matroska->tracks.elem;
2071 int n; 2161 int n;
2072 2162
2073 matroska_clear_queue(matroska); 2163 matroska_clear_queue(matroska);
2074 2164
2075 for (n=0; n < matroska->tracks.nb_elem; n++) 2165 for (n=0; n < matroska->tracks.nb_elem; n++)
2076 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) 2166 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO)
2077 av_free(tracks[n].audio.buf); 2167 av_free(tracks[n].audio.buf);
2168 ebml_free(matroska_cluster, &matroska->current_cluster);
2078 ebml_free(matroska_segment, matroska); 2169 ebml_free(matroska_segment, matroska);
2079 2170
2080 return 0; 2171 return 0;
2081 } 2172 }
2082 2173
2083 AVInputFormat ff_matroska_demuxer = { 2174 AVInputFormat ff_matroska_demuxer = {
2084 "matroska,webm", 2175 "matroska,webm",
2085 NULL_IF_CONFIG_SMALL("Matroska/WebM file format"), 2176 NULL_IF_CONFIG_SMALL("Matroska/WebM file format"),
2086 sizeof(MatroskaDemuxContext), 2177 sizeof(MatroskaDemuxContext),
2087 matroska_probe, 2178 matroska_probe,
2088 matroska_read_header, 2179 matroska_read_header,
2089 matroska_read_packet, 2180 matroska_read_packet,
2090 matroska_read_close, 2181 matroska_read_close,
2091 matroska_read_seek, 2182 matroska_read_seek,
2092 }; 2183 };
OLDNEW
« 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