OLD | NEW |
(Empty) | |
| 1 Index: libavformat/matroskadec.c |
| 2 =================================================================== |
| 3 --- libavformat/matroskadec.c (revision 105457) |
| 4 +++ libavformat/matroskadec.c (working copy) |
| 5 @@ -228,6 +228,11 @@ |
| 6 } MatroskaLevel; |
| 7 |
| 8 typedef struct { |
| 9 + uint64_t timecode; |
| 10 + EbmlList blocks; |
| 11 +} MatroskaCluster; |
| 12 + |
| 13 +typedef struct { |
| 14 AVFormatContext *ctx; |
| 15 |
| 16 /* EBML stuff */ |
| 17 @@ -262,6 +267,10 @@ |
| 18 |
| 19 /* File has a CUES element, but we defer parsing until it is needed. */ |
| 20 int cues_parsing_deferred; |
| 21 + |
| 22 + int current_cluster_num_blocks; |
| 23 + int64_t current_cluster_pos; |
| 24 + MatroskaCluster current_cluster; |
| 25 } MatroskaDemuxContext; |
| 26 |
| 27 typedef struct { |
| 28 @@ -271,11 +280,6 @@ |
| 29 EbmlBin bin; |
| 30 } MatroskaBlock; |
| 31 |
| 32 -typedef struct { |
| 33 - uint64_t timecode; |
| 34 - EbmlList blocks; |
| 35 -} MatroskaCluster; |
| 36 - |
| 37 static EbmlSyntax ebml_header[] = { |
| 38 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u
=EBML_VERSION} }, |
| 39 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.
u=8} }, |
| 40 @@ -546,6 +550,38 @@ |
| 41 { 0 } |
| 42 }; |
| 43 |
| 44 +static EbmlSyntax matroska_cluster_incremental_parsing[] = { |
| 45 + { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecod
e) }, |
| 46 + { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(Ma
troskaCluster,blocks), {.n=matroska_blockgroup} }, |
| 47 + { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(Ma
troskaCluster,blocks), {.n=matroska_blockgroup} }, |
| 48 + { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, |
| 49 + { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, |
| 50 + { MATROSKA_ID_INFO, EBML_NONE }, |
| 51 + { MATROSKA_ID_CUES, EBML_NONE }, |
| 52 + { MATROSKA_ID_TAGS, EBML_NONE }, |
| 53 + { MATROSKA_ID_SEEKHEAD, EBML_NONE }, |
| 54 + { MATROSKA_ID_CLUSTER, EBML_STOP }, |
| 55 + { 0 } |
| 56 +}; |
| 57 + |
| 58 +static EbmlSyntax matroska_cluster_incremental[] = { |
| 59 + { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecod
e) }, |
| 60 + { MATROSKA_ID_BLOCKGROUP, EBML_STOP }, |
| 61 + { MATROSKA_ID_SIMPLEBLOCK, EBML_STOP }, |
| 62 + { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, |
| 63 + { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, |
| 64 + { 0 } |
| 65 +}; |
| 66 + |
| 67 +static EbmlSyntax matroska_clusters_incremental[] = { |
| 68 + { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster_increme
ntal} }, |
| 69 + { MATROSKA_ID_INFO, EBML_NONE }, |
| 70 + { MATROSKA_ID_CUES, EBML_NONE }, |
| 71 + { MATROSKA_ID_TAGS, EBML_NONE }, |
| 72 + { MATROSKA_ID_SEEKHEAD, EBML_NONE }, |
| 73 + { 0 } |
| 74 +}; |
| 75 + |
| 76 static const char *matroska_doctypes[] = { "matroska", "webm" }; |
| 77 |
| 78 /* |
| 79 @@ -1690,6 +1726,7 @@ |
| 80 sizeof(AVPacket *)); |
| 81 } else { |
| 82 av_freep(&matroska->packets); |
| 83 + matroska->prev_pkt = NULL; |
| 84 } |
| 85 matroska->num_packets--; |
| 86 return 0; |
| 87 @@ -1993,6 +2030,59 @@ |
| 88 return res; |
| 89 } |
| 90 |
| 91 +static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska) |
| 92 +{ |
| 93 + EbmlList *blocks_list; |
| 94 + MatroskaBlock *blocks; |
| 95 + int i, res; |
| 96 + res = ebml_parse(matroska, |
| 97 + matroska_cluster_incremental_parsing, |
| 98 + &matroska->current_cluster); |
| 99 + if (res == 1) { |
| 100 + /* New Cluster */ |
| 101 + if (matroska->current_cluster_pos) |
| 102 + ebml_level_end(matroska); |
| 103 + ebml_free(matroska_cluster, &matroska->current_cluster); |
| 104 + memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster)); |
| 105 + matroska->current_cluster_num_blocks = 0; |
| 106 + matroska->current_cluster_pos = avio_tell(matroska->ctx->pb); |
| 107 + matroska->prev_pkt = NULL; |
| 108 + /* sizeof the ID which was already read */ |
| 109 + if (matroska->current_id) |
| 110 + matroska->current_cluster_pos -= 4; |
| 111 + res = ebml_parse(matroska, |
| 112 + matroska_clusters_incremental, |
| 113 + &matroska->current_cluster); |
| 114 + /* Try parsing the block agiain. */ |
| 115 + if (res == 1) |
| 116 + res = ebml_parse(matroska, |
| 117 + matroska_cluster_incremental_parsing, |
| 118 + &matroska->current_cluster); |
| 119 + } |
| 120 + |
| 121 + if (!res && |
| 122 + matroska->current_cluster_num_blocks < |
| 123 + matroska->current_cluster.blocks.nb_elem) { |
| 124 + blocks_list = &matroska->current_cluster.blocks; |
| 125 + blocks = blocks_list->elem; |
| 126 + |
| 127 + matroska->current_cluster_num_blocks = blocks_list->nb_elem; |
| 128 + i = blocks_list->nb_elem - 1; |
| 129 + if (blocks[i].bin.size > 0 && blocks[i].bin.data) { |
| 130 + int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1; |
| 131 + res=matroska_parse_block(matroska, |
| 132 + blocks[i].bin.data, blocks[i].bin.size, |
| 133 + blocks[i].bin.pos, |
| 134 + matroska->current_cluster.timecode, |
| 135 + blocks[i].duration, is_keyframe, |
| 136 + matroska->current_cluster_pos); |
| 137 + } |
| 138 + } |
| 139 + |
| 140 + if (res < 0) matroska->done = 1; |
| 141 + return res; |
| 142 +} |
| 143 + |
| 144 static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 145 { |
| 146 MatroskaDemuxContext *matroska = s->priv_data; |
| 147 @@ -2001,7 +2091,7 @@ |
| 148 while (!ret && matroska_deliver_packet(matroska, pkt)) { |
| 149 if (matroska->done) |
| 150 return AVERROR_EOF; |
| 151 - ret = matroska_parse_cluster(matroska); |
| 152 + ret = matroska_parse_cluster_incremental(matroska); |
| 153 } |
| 154 |
| 155 return ret; |
| 156 @@ -2075,6 +2165,7 @@ |
| 157 for (n=0; n < matroska->tracks.nb_elem; n++) |
| 158 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) |
| 159 av_free(tracks[n].audio.buf); |
| 160 + ebml_free(matroska_cluster, &matroska->current_cluster); |
| 161 ebml_free(matroska_segment, matroska); |
| 162 |
| 163 return 0; |
OLD | NEW |