| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 }; |
| OLD | NEW |