Mercurial > libavformat.hg
annotate matroskadec.c @ 6124:778065ad3ac5 libavformat
matroskadec: simplify parsing of the first cluster
Now that we save the currently parsed ebml element ID after an interruption,
we don't need to special case the parsing of the first cluster.
author | aurel |
---|---|
date | Fri, 11 Jun 2010 16:36:51 +0000 |
parents | 9f368d591c13 |
children | 933bed6fbdc0 |
rev | line source |
---|---|
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1 /* |
3685
c077c928bfe6
matroskadec: update copyright year and related comments
aurel
parents:
3684
diff
changeset
|
2 * Matroska file demuxer |
3692 | 3 * Copyright (c) 2003-2008 The FFmpeg Project |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
16 * |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
20 */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
21 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
22 /** |
5969
178de7695c6c
Remove explicit filename from Doxygen @file commands.
diego
parents:
5946
diff
changeset
|
23 * @file |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
24 * Matroska file demuxer |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
25 * by Ronald Bultje <rbultje@ronald.bitfreak.net> |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
26 * with a little help from Moritz Bunkus <moritz@bunkus.org> |
3685
c077c928bfe6
matroskadec: update copyright year and related comments
aurel
parents:
3684
diff
changeset
|
27 * totally reworked by Aurelien Jacobs <aurel@gnuage.org> |
3692 | 28 * Specs available on the Matroska project page: http://www.matroska.org/. |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
29 */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
30 |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
31 #include <stdio.h> |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
32 #include "avformat.h" |
5946
28ca2d77f997
Move the internal function declarations in avformat.h to internal.h.
stefano
parents:
5913
diff
changeset
|
33 #include "internal.h" |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5031
diff
changeset
|
34 /* For ff_codec_get_id(). */ |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
35 #include "riff.h" |
3601 | 36 #include "isom.h" |
5832 | 37 #include "rm.h" |
2142
3aa1f0f698de
split some common code from the mkv demuxer that will be useful to the muxer
aurel
parents:
2023
diff
changeset
|
38 #include "matroska.h" |
3201 | 39 #include "libavcodec/mpeg4audio.h" |
3286 | 40 #include "libavutil/intfloat_readwrite.h" |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4124
diff
changeset
|
41 #include "libavutil/intreadwrite.h" |
3628
5f2e1da55755
matroskadec: use more robust av_strlcpy() instead of strcpy()
aurel
parents:
3601
diff
changeset
|
42 #include "libavutil/avstring.h" |
3281 | 43 #include "libavutil/lzo.h" |
4206 | 44 #if CONFIG_ZLIB |
3293 | 45 #include <zlib.h> |
46 #endif | |
4206 | 47 #if CONFIG_BZLIB |
3298
edabe3db2b6e
matroskadec: add support for bzlib compressed tracks
aurel
parents:
3294
diff
changeset
|
48 #include <bzlib.h> |
edabe3db2b6e
matroskadec: add support for bzlib compressed tracks
aurel
parents:
3294
diff
changeset
|
49 #endif |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
50 |
3632 | 51 typedef enum { |
52 EBML_NONE, | |
53 EBML_UINT, | |
54 EBML_FLOAT, | |
55 EBML_STR, | |
56 EBML_UTF8, | |
57 EBML_BIN, | |
58 EBML_NEST, | |
59 EBML_PASS, | |
60 EBML_STOP, | |
61 } EbmlType; | |
62 | |
63 typedef const struct EbmlSyntax { | |
64 uint32_t id; | |
65 EbmlType type; | |
66 int list_elem_size; | |
67 int data_offset; | |
68 union { | |
69 uint64_t u; | |
70 double f; | |
71 const char *s; | |
72 const struct EbmlSyntax *n; | |
73 } def; | |
74 } EbmlSyntax; | |
75 | |
76 typedef struct { | |
77 int nb_elem; | |
78 void *elem; | |
79 } EbmlList; | |
80 | |
81 typedef struct { | |
82 int size; | |
83 uint8_t *data; | |
84 int64_t pos; | |
85 } EbmlBin; | |
86 | |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
87 typedef struct { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
88 uint64_t version; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
89 uint64_t max_size; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
90 uint64_t id_length; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
91 char *doctype; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
92 uint64_t doctype_version; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
93 } Ebml; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
94 |
3642 | 95 typedef struct { |
96 uint64_t algo; | |
97 EbmlBin settings; | |
98 } MatroskaTrackCompression; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
99 |
3642 | 100 typedef struct { |
101 uint64_t scope; | |
102 uint64_t type; | |
103 MatroskaTrackCompression compression; | |
104 } MatroskaTrackEncoding; | |
105 | |
106 typedef struct { | |
107 double frame_rate; | |
108 uint64_t display_width; | |
109 uint64_t display_height; | |
110 uint64_t pixel_width; | |
111 uint64_t pixel_height; | |
112 uint64_t fourcc; | |
113 } MatroskaTrackVideo; | |
2147 | 114 |
3642 | 115 typedef struct { |
116 double samplerate; | |
117 double out_samplerate; | |
118 uint64_t bitdepth; | |
119 uint64_t channels; | |
2147 | 120 |
3642 | 121 /* real audio header (extracted from extradata) */ |
122 int coded_framesize; | |
123 int sub_packet_h; | |
124 int frame_size; | |
125 int sub_packet_size; | |
126 int sub_packet_cnt; | |
127 int pkt_cnt; | |
128 uint8_t *buf; | |
129 } MatroskaTrackAudio; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
130 |
3642 | 131 typedef struct { |
132 uint64_t num; | |
4494 | 133 uint64_t uid; |
3642 | 134 uint64_t type; |
4493
40499405ef63
matroskadec: export track name through the metadata API
aurel
parents:
4492
diff
changeset
|
135 char *name; |
3642 | 136 char *codec_id; |
137 EbmlBin codec_priv; | |
138 char *language; | |
3408
da09478c97ce
matroskadec: read TrackTimecodeScale and set timebase accordingly
aurel
parents:
3407
diff
changeset
|
139 double time_scale; |
1912 | 140 uint64_t default_duration; |
3630 | 141 uint64_t flag_default; |
3642 | 142 MatroskaTrackVideo video; |
143 MatroskaTrackAudio audio; | |
144 EbmlList encodings; | |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
145 |
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
146 AVStream *stream; |
3915
7643d7c3fcf6
matroskadec: ensure that overlapping subtitles are not added to the index
aurel
parents:
3914
diff
changeset
|
147 int64_t end_timecode; |
5740
421297d526d0
matroskadec: timestamps are dts and not pts in ms vfw compatibility mode
aurel
parents:
5618
diff
changeset
|
148 int ms_compat; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
149 } MatroskaTrack; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
150 |
3637 | 151 typedef struct { |
4494 | 152 uint64_t uid; |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
153 char *filename; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
154 char *mime; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
155 EbmlBin bin; |
4495 | 156 |
157 AVStream *stream; | |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
158 } MatroskaAttachement; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
159 |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
160 typedef struct { |
3639 | 161 uint64_t start; |
162 uint64_t end; | |
163 uint64_t uid; | |
164 char *title; | |
4492
56ea2b1028fe
matroskadec: use new metadata API to export some simple information
aurel
parents:
4352
diff
changeset
|
165 |
56ea2b1028fe
matroskadec: use new metadata API to export some simple information
aurel
parents:
4352
diff
changeset
|
166 AVChapter *chapter; |
3639 | 167 } MatroskaChapter; |
168 | |
169 typedef struct { | |
3637 | 170 uint64_t track; |
171 uint64_t pos; | |
172 } MatroskaIndexPos; | |
173 | |
174 typedef struct { | |
175 uint64_t time; | |
176 EbmlList pos; | |
177 } MatroskaIndex; | |
178 | |
3644 | 179 typedef struct { |
3702 | 180 char *name; |
181 char *string; | |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
182 char *lang; |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
183 uint64_t def; |
3702 | 184 EbmlList sub; |
185 } MatroskaTag; | |
186 | |
187 typedef struct { | |
4495 | 188 char *type; |
189 uint64_t typevalue; | |
190 uint64_t trackuid; | |
191 uint64_t chapteruid; | |
192 uint64_t attachuid; | |
193 } MatroskaTagTarget; | |
194 | |
195 typedef struct { | |
196 MatroskaTagTarget target; | |
197 EbmlList tag; | |
198 } MatroskaTags; | |
199 | |
200 typedef struct { | |
3644 | 201 uint64_t id; |
202 uint64_t pos; | |
203 } MatroskaSeekhead; | |
204 | |
3658 | 205 typedef struct { |
2147 | 206 uint64_t start; |
207 uint64_t length; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
208 } MatroskaLevel; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
209 |
3658 | 210 typedef struct { |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
211 AVFormatContext *ctx; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
212 |
3692 | 213 /* EBML stuff */ |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
214 int num_levels; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
215 MatroskaLevel levels[EBML_MAX_DEPTH]; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
216 int level_up; |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
217 uint32_t current_id; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
218 |
3641 | 219 uint64_t time_scale; |
220 double duration; | |
221 char *title; | |
3642 | 222 EbmlList tracks; |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
223 EbmlList attachments; |
3639 | 224 EbmlList chapters; |
3637 | 225 EbmlList index; |
3702 | 226 EbmlList tags; |
3644 | 227 EbmlList seekhead; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
228 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
229 /* byte position of the segment inside the stream */ |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
230 int64_t segment_start; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
231 |
3692 | 232 /* the packet queue */ |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
233 AVPacket **packets; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
234 int num_packets; |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
235 AVPacket *prev_pkt; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
236 |
2147 | 237 int done; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
238 |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
239 /* What to skip before effectively reading a packet. */ |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
240 int skip_to_keyframe; |
3914
f7a20cf5438f
matroskadec: after seeking, skip up to the desired timestamp instead of
aurel
parents:
3913
diff
changeset
|
241 uint64_t skip_to_timecode; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
242 } MatroskaDemuxContext; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
243 |
3653 | 244 typedef struct { |
245 uint64_t duration; | |
246 int64_t reference; | |
5128
2397bd089f70
matroskadec: correctly parse flags for simpleblock frames
aurel
parents:
5058
diff
changeset
|
247 uint64_t non_simple; |
3653 | 248 EbmlBin bin; |
249 } MatroskaBlock; | |
250 | |
251 typedef struct { | |
252 uint64_t timecode; | |
253 EbmlList blocks; | |
254 } MatroskaCluster; | |
255 | |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
256 static EbmlSyntax ebml_header[] = { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
257 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u=EBML_VERSION} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
258 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u=8} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
259 { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {.u=4} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
260 { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s="(none)"} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
261 { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_version), {.u=1} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
262 { EBML_ID_EBMLVERSION, EBML_NONE }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
263 { EBML_ID_DOCTYPEVERSION, EBML_NONE }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
264 { 0 } |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
265 }; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
266 |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
267 static EbmlSyntax ebml_syntax[] = { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
268 { EBML_ID_HEADER, EBML_NEST, 0, 0, {.n=ebml_header} }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
269 { 0 } |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
270 }; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
271 |
3641 | 272 static EbmlSyntax matroska_info[] = { |
273 { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext,time_scale), {.u=1000000} }, | |
274 { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext,duration) }, | |
275 { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) }, | |
276 { MATROSKA_ID_WRITINGAPP, EBML_NONE }, | |
277 { MATROSKA_ID_MUXINGAPP, EBML_NONE }, | |
278 { MATROSKA_ID_DATEUTC, EBML_NONE }, | |
279 { MATROSKA_ID_SEGMENTUID, EBML_NONE }, | |
280 { 0 } | |
281 }; | |
282 | |
3642 | 283 static EbmlSyntax matroska_track_video[] = { |
284 { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT,0, offsetof(MatroskaTrackVideo,frame_rate) }, | |
285 { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_width) }, | |
286 { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) }, | |
287 { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) }, | |
288 { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) }, | |
289 { MATROSKA_ID_VIDEOCOLORSPACE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,fourcc) }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
290 { MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
291 { MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
292 { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
293 { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
294 { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, |
3642 | 295 { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE }, |
296 { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE }, | |
297 { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, | |
298 { 0 } | |
299 }; | |
300 | |
301 static EbmlSyntax matroska_track_audio[] = { | |
302 { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT,0, offsetof(MatroskaTrackAudio,samplerate), {.f=8000.0} }, | |
303 { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ,EBML_FLOAT,0,offsetof(MatroskaTrackAudio,out_samplerate) }, | |
304 { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio,bitdepth) }, | |
305 { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio,channels), {.u=1} }, | |
306 { 0 } | |
307 }; | |
308 | |
309 static EbmlSyntax matroska_track_encoding_compression[] = { | |
310 { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression,algo), {.u=0} }, | |
311 { MATROSKA_ID_ENCODINGCOMPSETTINGS,EBML_BIN, 0, offsetof(MatroskaTrackCompression,settings) }, | |
312 { 0 } | |
313 }; | |
314 | |
315 static EbmlSyntax matroska_track_encoding[] = { | |
316 { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} }, | |
317 { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} }, | |
318 { MATROSKA_ID_ENCODINGCOMPRESSION,EBML_NEST, 0, offsetof(MatroskaTrackEncoding,compression), {.n=matroska_track_encoding_compression} }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
319 { MATROSKA_ID_ENCODINGORDER, EBML_NONE }, |
3642 | 320 { 0 } |
321 }; | |
322 | |
323 static EbmlSyntax matroska_track_encodings[] = { | |
324 { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack,encodings), {.n=matroska_track_encoding} }, | |
325 { 0 } | |
326 }; | |
327 | |
328 static EbmlSyntax matroska_track[] = { | |
329 { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) }, | |
4493
40499405ef63
matroskadec: export track name through the metadata API
aurel
parents:
4492
diff
changeset
|
330 { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, offsetof(MatroskaTrack,name) }, |
4494 | 331 { MATROSKA_ID_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTrack,uid) }, |
3642 | 332 { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack,type) }, |
333 { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack,codec_id) }, | |
334 { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack,codec_priv) }, | |
335 { MATROSKA_ID_TRACKLANGUAGE, EBML_UTF8, 0, offsetof(MatroskaTrack,language), {.s="eng"} }, | |
336 { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) }, | |
337 { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} }, | |
338 { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} }, | |
339 { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} }, | |
340 { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} }, | |
341 { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} }, | |
342 { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, | |
343 { MATROSKA_ID_TRACKFLAGFORCED, EBML_NONE }, | |
344 { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, | |
345 { MATROSKA_ID_CODECNAME, EBML_NONE }, | |
346 { MATROSKA_ID_CODECDECODEALL, EBML_NONE }, | |
347 { MATROSKA_ID_CODECINFOURL, EBML_NONE }, | |
348 { MATROSKA_ID_CODECDOWNLOADURL, EBML_NONE }, | |
349 { MATROSKA_ID_TRACKMINCACHE, EBML_NONE }, | |
350 { MATROSKA_ID_TRACKMAXCACHE, EBML_NONE }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
351 { MATROSKA_ID_TRACKMAXBLKADDID, EBML_NONE }, |
3642 | 352 { 0 } |
353 }; | |
354 | |
355 static EbmlSyntax matroska_tracks[] = { | |
356 { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext,tracks), {.n=matroska_track} }, | |
357 { 0 } | |
358 }; | |
359 | |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
360 static EbmlSyntax matroska_attachment[] = { |
4494 | 361 { MATROSKA_ID_FILEUID, EBML_UINT, 0, offsetof(MatroskaAttachement,uid) }, |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
362 { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
363 { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachement,mime) }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
364 { MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachement,bin) }, |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
365 { MATROSKA_ID_FILEDESC, EBML_NONE }, |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
366 { 0 } |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
367 }; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
368 |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
369 static EbmlSyntax matroska_attachments[] = { |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
370 { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
371 { 0 } |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
372 }; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
373 |
3639 | 374 static EbmlSyntax matroska_chapter_display[] = { |
375 { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter,title) }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
376 { MATROSKA_ID_CHAPLANG, EBML_NONE }, |
3639 | 377 { 0 } |
378 }; | |
379 | |
380 static EbmlSyntax matroska_chapter_entry[] = { | |
381 { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} }, | |
382 { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} }, | |
383 { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) }, | |
384 { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} }, | |
385 { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
386 { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
387 { MATROSKA_ID_CHAPTERPHYSEQUIV, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
388 { MATROSKA_ID_CHAPTERATOM, EBML_NONE }, |
3639 | 389 { 0 } |
390 }; | |
391 | |
392 static EbmlSyntax matroska_chapter[] = { | |
393 { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} }, | |
394 { MATROSKA_ID_EDITIONUID, EBML_NONE }, | |
395 { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, | |
396 { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
397 { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE }, |
3639 | 398 { 0 } |
399 }; | |
400 | |
401 static EbmlSyntax matroska_chapters[] = { | |
402 { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} }, | |
403 { 0 } | |
404 }; | |
405 | |
3637 | 406 static EbmlSyntax matroska_index_pos[] = { |
407 { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) }, | |
408 { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos,pos) }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
409 { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE }, |
3637 | 410 { 0 } |
411 }; | |
412 | |
413 static EbmlSyntax matroska_index_entry[] = { | |
414 { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex,time) }, | |
415 { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex,pos), {.n=matroska_index_pos} }, | |
416 { 0 } | |
417 }; | |
418 | |
419 static EbmlSyntax matroska_index[] = { | |
420 { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, | |
421 { 0 } | |
422 }; | |
423 | |
3702 | 424 static EbmlSyntax matroska_simpletag[] = { |
425 { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) }, | |
426 { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) }, | |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
427 { MATROSKA_ID_TAGLANG, EBML_STR, 0, offsetof(MatroskaTag,lang), {.s="und"} }, |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
428 { MATROSKA_ID_TAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTag,def) }, |
6113
6f9d084d5888
Fix the MATROSKA_ID_TAGDEFAULT to match the specification (instead of
reimar
parents:
6058
diff
changeset
|
429 { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0, offsetof(MatroskaTag,def) }, |
3702 | 430 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} }, |
431 { 0 } | |
432 }; | |
433 | |
4495 | 434 static EbmlSyntax matroska_tagtargets[] = { |
435 { MATROSKA_ID_TAGTARGETS_TYPE, EBML_STR, 0, offsetof(MatroskaTagTarget,type) }, | |
436 { MATROSKA_ID_TAGTARGETS_TYPEVALUE, EBML_UINT, 0, offsetof(MatroskaTagTarget,typevalue), {.u=50} }, | |
437 { MATROSKA_ID_TAGTARGETS_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,trackuid) }, | |
438 { MATROSKA_ID_TAGTARGETS_CHAPTERUID,EBML_UINT, 0, offsetof(MatroskaTagTarget,chapteruid) }, | |
439 { MATROSKA_ID_TAGTARGETS_ATTACHUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,attachuid) }, | |
440 { 0 } | |
441 }; | |
442 | |
3702 | 443 static EbmlSyntax matroska_tag[] = { |
4495 | 444 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags,tag), {.n=matroska_simpletag} }, |
445 { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0, offsetof(MatroskaTags,target), {.n=matroska_tagtargets} }, | |
3702 | 446 { 0 } |
447 }; | |
448 | |
3638 | 449 static EbmlSyntax matroska_tags[] = { |
4495 | 450 { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} }, |
3638 | 451 { 0 } |
452 }; | |
453 | |
3644 | 454 static EbmlSyntax matroska_seekhead_entry[] = { |
455 { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead,id) }, | |
456 { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead,pos), {.u=-1} }, | |
457 { 0 } | |
458 }; | |
459 | |
460 static EbmlSyntax matroska_seekhead[] = { | |
461 { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext,seekhead), {.n=matroska_seekhead_entry} }, | |
462 { 0 } | |
463 }; | |
464 | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
465 static EbmlSyntax matroska_segment[] = { |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
466 { MATROSKA_ID_INFO, EBML_NEST, 0, 0, {.n=matroska_info } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
467 { MATROSKA_ID_TRACKS, EBML_NEST, 0, 0, {.n=matroska_tracks } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
468 { MATROSKA_ID_ATTACHMENTS, EBML_NEST, 0, 0, {.n=matroska_attachments} }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
469 { MATROSKA_ID_CHAPTERS, EBML_NEST, 0, 0, {.n=matroska_chapters } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
470 { MATROSKA_ID_CUES, EBML_NEST, 0, 0, {.n=matroska_index } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
471 { MATROSKA_ID_TAGS, EBML_NEST, 0, 0, {.n=matroska_tags } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
472 { MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } }, |
6124 | 473 { MATROSKA_ID_CLUSTER, EBML_STOP }, |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
474 { 0 } |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
475 }; |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
476 |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
477 static EbmlSyntax matroska_segments[] = { |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
478 { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, {.n=matroska_segment } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
479 { 0 } |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
480 }; |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
481 |
3653 | 482 static EbmlSyntax matroska_blockgroup[] = { |
483 { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, | |
484 { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, | |
485 { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} }, | |
486 { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) }, | |
5128
2397bd089f70
matroskadec: correctly parse flags for simpleblock frames
aurel
parents:
5058
diff
changeset
|
487 { 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} }, |
3653 | 488 { 0 } |
489 }; | |
490 | |
491 static EbmlSyntax matroska_cluster[] = { | |
492 { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, | |
493 { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, | |
494 { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
495 { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
496 { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, |
3653 | 497 { 0 } |
498 }; | |
499 | |
500 static EbmlSyntax matroska_clusters[] = { | |
501 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, | |
3717
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
502 { MATROSKA_ID_INFO, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
503 { MATROSKA_ID_CUES, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
504 { MATROSKA_ID_TAGS, EBML_NONE }, |
f65dc584662d
matroskadec: list some more ebml IDs found in the wild and that we ignore
aurel
parents:
3713
diff
changeset
|
505 { MATROSKA_ID_SEEKHEAD, EBML_NONE }, |
3653 | 506 { 0 } |
507 }; | |
508 | |
6029 | 509 static const char *matroska_doctypes[] = { "matroska", "webm" }; |
510 | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
511 /* |
3692 | 512 * Return: Whether we reached the end of a level in the hierarchy or not. |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
513 */ |
3674 | 514 static int ebml_level_end(MatroskaDemuxContext *matroska) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
515 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2657
diff
changeset
|
516 ByteIOContext *pb = matroska->ctx->pb; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
517 int64_t pos = url_ftell(pb); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
518 |
3674 | 519 if (matroska->num_levels > 0) { |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
520 MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; |
3674 | 521 if (pos - level->start >= level->length) { |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
522 matroska->num_levels--; |
3674 | 523 return 1; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
524 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
525 } |
3674 | 526 return 0; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
527 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
528 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
529 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
530 * Read: an "EBML number", which is defined as a variable-length |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
531 * array of bytes. The first byte indicates the length by giving a |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
532 * number of 0-bits followed by a one. The position of the first |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
533 * "one" bit inside the first byte indicates the length of this |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
534 * number. |
3692 | 535 * Returns: number of bytes read, < 0 on error |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
536 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
537 static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
538 int max_size, uint64_t *number) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
539 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
540 int len_mask = 0x80, read = 1, n = 1; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
541 int64_t total = 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
542 |
3692 | 543 /* The first byte tells us the length in bytes - get_byte() can normally |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
544 * return 0, but since that's not a valid first ebmlID byte, we can |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
545 * use it safely here to catch EOS. */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
546 if (!(total = get_byte(pb))) { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
547 /* we might encounter EOS here */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
548 if (!url_feof(pb)) { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
549 int64_t pos = url_ftell(pb); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
550 av_log(matroska->ctx, AV_LOG_ERROR, |
881 | 551 "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
552 pos, pos); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
553 } |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
554 return AVERROR(EIO); /* EOS or actual I/O error */ |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
555 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
556 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
557 /* get the length of the EBML number */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
558 while (read <= max_size && !(total & len_mask)) { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
559 read++; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
560 len_mask >>= 1; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
561 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
562 if (read > max_size) { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
563 int64_t pos = url_ftell(pb) - 1; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
564 av_log(matroska->ctx, AV_LOG_ERROR, |
881 | 565 "Invalid EBML number size tag 0x%02x at pos %"PRIu64" (0x%"PRIx64")\n", |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
566 (uint8_t) total, pos, pos); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
567 return AVERROR_INVALIDDATA; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
568 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
569 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
570 /* read out length */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
571 total &= ~len_mask; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
572 while (n++ < read) |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
573 total = (total << 8) | get_byte(pb); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
574 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
575 *number = total; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
576 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
577 return read; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
578 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
579 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
580 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
581 * Read the next element as an unsigned int. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
582 * 0 is success, < 0 is failure. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
583 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
584 static int ebml_read_uint(ByteIOContext *pb, int size, uint64_t *num) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
585 { |
3670
04b4e89c09d6
matroskadec: extract common code out of ebml_read_*()
aurel
parents:
3669
diff
changeset
|
586 int n = 0; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
587 |
3669
836de2dd2615
matroskadec: simplify/cleanup error logging in ebml_read_*()
aurel
parents:
3668
diff
changeset
|
588 if (size < 1 || size > 8) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
589 return AVERROR_INVALIDDATA; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
590 |
3692 | 591 /* big-endian ordering; build up number */ |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
592 *num = 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
593 while (n++ < size) |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
594 *num = (*num << 8) | get_byte(pb); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
595 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
596 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
597 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
598 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
599 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
600 * Read the next element as a float. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
601 * 0 is success, < 0 is failure. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
602 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
603 static int ebml_read_float(ByteIOContext *pb, int size, double *num) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
604 { |
824 | 605 if (size == 4) { |
606 *num= av_int2flt(get_be32(pb)); | |
607 } else if(size==8){ | |
608 *num= av_int2dbl(get_be64(pb)); | |
3669
836de2dd2615
matroskadec: simplify/cleanup error logging in ebml_read_*()
aurel
parents:
3668
diff
changeset
|
609 } else |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
610 return AVERROR_INVALIDDATA; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
611 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
612 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
613 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
614 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
615 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
616 * Read the next element as an ASCII string. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
617 * 0 is success, < 0 is failure. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
618 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
619 static int ebml_read_ascii(ByteIOContext *pb, int size, char **str) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
620 { |
3670
04b4e89c09d6
matroskadec: extract common code out of ebml_read_*()
aurel
parents:
3669
diff
changeset
|
621 av_free(*str); |
3692 | 622 /* EBML strings are usually not 0-terminated, so we allocate one |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
623 * byte more, read the string and NULL-terminate it ourselves. */ |
3670
04b4e89c09d6
matroskadec: extract common code out of ebml_read_*()
aurel
parents:
3669
diff
changeset
|
624 if (!(*str = av_malloc(size + 1))) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2264
diff
changeset
|
625 return AVERROR(ENOMEM); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
626 if (get_buffer(pb, (uint8_t *) *str, size) != size) { |
6015 | 627 av_freep(str); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
628 return AVERROR(EIO); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
629 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
630 (*str)[size] = '\0'; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
631 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
632 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
633 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
634 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
635 /* |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
636 * Read the next element as binary data. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
637 * 0 is success, < 0 is failure. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
638 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
639 static int ebml_read_binary(ByteIOContext *pb, int length, EbmlBin *bin) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
640 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
641 av_free(bin->data); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
642 if (!(bin->data = av_malloc(length))) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
643 return AVERROR(ENOMEM); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
644 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
645 bin->size = length; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
646 bin->pos = url_ftell(pb); |
6018 | 647 if (get_buffer(pb, bin->data, length) != length) { |
648 av_freep(&bin->data); | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
649 return AVERROR(EIO); |
6018 | 650 } |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
651 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
652 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
653 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
654 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
655 /* |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
656 * Read the next element, but only the header. The contents |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
657 * are supposed to be sub-elements which can be read separately. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
658 * 0 is success, < 0 is failure. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
659 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
660 static int ebml_read_master(MatroskaDemuxContext *matroska, int length) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
661 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2657
diff
changeset
|
662 ByteIOContext *pb = matroska->ctx->pb; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
663 MatroskaLevel *level; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
664 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
665 if (matroska->num_levels >= EBML_MAX_DEPTH) { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
666 av_log(matroska->ctx, AV_LOG_ERROR, |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
667 "File moves beyond max. allowed depth (%d)\n", EBML_MAX_DEPTH); |
2276
3c1e2d519277
Replace all occurrences of AVERROR_NOTSUPP with AVERROR(ENOSYS).
takis
parents:
2274
diff
changeset
|
668 return AVERROR(ENOSYS); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
669 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
670 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
671 level = &matroska->levels[matroska->num_levels++]; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
672 level->start = url_ftell(pb); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
673 level->length = length; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
674 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
675 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
676 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
677 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
678 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
679 * Read signed/unsigned "EBML" numbers. |
3692 | 680 * Return: number of bytes processed, < 0 on error |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
681 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
682 static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska, |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
683 uint8_t *data, uint32_t size, uint64_t *num) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
684 { |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
685 ByteIOContext pb; |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
686 init_put_byte(&pb, data, size, 0, NULL, NULL, NULL, NULL); |
6017
9565f0ce6f2e
matroskadec: Fix buffer overread in matroska_ebmlnum_uint
conrad
parents:
6016
diff
changeset
|
687 return ebml_read_num(matroska, &pb, FFMIN(size, 8), num); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
688 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
689 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
690 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
691 * Same as above, but signed. |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
692 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
693 static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska, |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
694 uint8_t *data, uint32_t size, int64_t *num) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
695 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
696 uint64_t unum; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
697 int res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
698 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
699 /* read as unsigned number first */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
700 if ((res = matroska_ebmlnum_uint(matroska, data, size, &unum)) < 0) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
701 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
702 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
703 /* make signed (weird way) */ |
3689 | 704 *num = unum - ((1LL << (7*res - 1)) - 1); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
705 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
706 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
707 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
708 |
3632 | 709 static int ebml_parse_elem(MatroskaDemuxContext *matroska, |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
710 EbmlSyntax *syntax, void *data); |
3632 | 711 |
712 static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, | |
713 uint32_t id, void *data) | |
714 { | |
715 int i; | |
716 for (i=0; syntax[i].id; i++) | |
717 if (id == syntax[i].id) | |
718 break; | |
3745
47807c439186
matroskadec: handle EBML_ID_VOID and EBML_ID_CRC32 in a generic way
aurel
parents:
3717
diff
changeset
|
719 if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) |
3632 | 720 av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id); |
721 return ebml_parse_elem(matroska, &syntax[i], data); | |
722 } | |
723 | |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
724 static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
725 void *data) |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
726 { |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
727 if (!matroska->current_id) { |
3690
50c074bc02b4
matroskadec: expand useless ebml_read_element_id() wrapper
aurel
parents:
3689
diff
changeset
|
728 uint64_t id; |
50c074bc02b4
matroskadec: expand useless ebml_read_element_id() wrapper
aurel
parents:
3689
diff
changeset
|
729 int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id); |
6122
ad7cfe404294
matroskadec: cosmetic: split a line to make it more readable
aurel
parents:
6114
diff
changeset
|
730 if (res < 0) |
ad7cfe404294
matroskadec: cosmetic: split a line to make it more readable
aurel
parents:
6114
diff
changeset
|
731 return res; |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
732 matroska->current_id = id | 1 << 7*res; |
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
733 } |
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
734 return ebml_parse_id(matroska, syntax, matroska->current_id, data); |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
735 } |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
736 |
3676
d2ff1b7ad060
matroskadec: rename ebml_parse() to ebml_parse_nest()
aurel
parents:
3675
diff
changeset
|
737 static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, |
3679
039a28684d43
matroskadec: remove now unused parameter 'once' from ebml_parse_nest()
aurel
parents:
3678
diff
changeset
|
738 void *data) |
3632 | 739 { |
3675
736c7c66234a
matroskadec: don't care about the number of bytes read by ebml_read_element_id()
aurel
parents:
3674
diff
changeset
|
740 int i, res = 0; |
3632 | 741 |
742 for (i=0; syntax[i].id; i++) | |
743 switch (syntax[i].type) { | |
744 case EBML_UINT: | |
745 *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u; | |
746 break; | |
747 case EBML_FLOAT: | |
748 *(double *)((char *)data+syntax[i].data_offset) = syntax[i].def.f; | |
749 break; | |
750 case EBML_STR: | |
751 case EBML_UTF8: | |
752 *(char **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s); | |
753 break; | |
754 } | |
755 | |
3679
039a28684d43
matroskadec: remove now unused parameter 'once' from ebml_parse_nest()
aurel
parents:
3678
diff
changeset
|
756 while (!res && !ebml_level_end(matroska)) |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
757 res = ebml_parse(matroska, syntax, data); |
3632 | 758 |
759 return res; | |
760 } | |
761 | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
762 static int ebml_parse_elem(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
763 EbmlSyntax *syntax, void *data) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
764 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
765 ByteIOContext *pb = matroska->ctx->pb; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
766 uint32_t id = syntax->id; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
767 uint64_t length; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
768 int res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
769 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
770 data = (char *)data + syntax->data_offset; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
771 if (syntax->list_elem_size) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
772 EbmlList *list = data; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
773 list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
774 data = (char*)list->elem + list->nb_elem*syntax->list_elem_size; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
775 memset(data, 0, syntax->list_elem_size); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
776 list->nb_elem++; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
777 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
778 |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
779 if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) { |
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
780 matroska->current_id = 0; |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
781 if ((res = ebml_read_num(matroska, pb, 8, &length)) < 0) |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
782 return res; |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
783 } |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
784 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
785 switch (syntax->type) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
786 case EBML_UINT: res = ebml_read_uint (pb, length, data); break; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
787 case EBML_FLOAT: res = ebml_read_float (pb, length, data); break; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
788 case EBML_STR: |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
789 case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
790 case EBML_BIN: res = ebml_read_binary(pb, length, data); break; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
791 case EBML_NEST: if ((res=ebml_read_master(matroska, length)) < 0) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
792 return res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
793 if (id == MATROSKA_ID_SEGMENT) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
794 matroska->segment_start = url_ftell(matroska->ctx->pb); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
795 return ebml_parse_nest(matroska, syntax->def.n, data); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
796 case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data); |
6124 | 797 case EBML_STOP: return 1; |
3747
b8f428926617
matroskadec: stop parsing when skipping en element crossing over the end of file
aurel
parents:
3746
diff
changeset
|
798 default: return url_fseek(pb,length,SEEK_CUR)<0 ? AVERROR(EIO) : 0; |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
799 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
800 if (res == AVERROR_INVALIDDATA) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
801 av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n"); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
802 else if (res == AVERROR(EIO)) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
803 av_log(matroska->ctx, AV_LOG_ERROR, "Read error\n"); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
804 return res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
805 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
806 |
3632 | 807 static void ebml_free(EbmlSyntax *syntax, void *data) |
808 { | |
809 int i, j; | |
810 for (i=0; syntax[i].id; i++) { | |
811 void *data_off = (char *)data + syntax[i].data_offset; | |
812 switch (syntax[i].type) { | |
813 case EBML_STR: | |
814 case EBML_UTF8: av_freep(data_off); break; | |
815 case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break; | |
816 case EBML_NEST: | |
817 if (syntax[i].list_elem_size) { | |
818 EbmlList *list = data_off; | |
819 char *ptr = list->elem; | |
820 for (j=0; j<list->nb_elem; j++, ptr+=syntax[i].list_elem_size) | |
821 ebml_free(syntax[i].def.n, ptr); | |
822 av_free(list->elem); | |
823 } else | |
824 ebml_free(syntax[i].def.n, data_off); | |
825 default: break; | |
826 } | |
827 } | |
828 } | |
829 | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
830 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
831 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
832 * Autodetecting... |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
833 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
834 static int matroska_probe(AVProbeData *p) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
835 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
836 uint64_t total = 0; |
6029 | 837 int len_mask = 0x80, size = 1, n = 1, i; |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
838 |
3692 | 839 /* EBML header? */ |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
840 if (AV_RB32(p->buf) != EBML_ID_HEADER) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
841 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
842 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
843 /* length of header */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
844 total = p->buf[4]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
845 while (size <= 8 && !(total & len_mask)) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
846 size++; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
847 len_mask >>= 1; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
848 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
849 if (size > 8) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
850 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
851 total &= (len_mask - 1); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
852 while (n < size) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
853 total = (total << 8) | p->buf[4 + n++]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
854 |
3692 | 855 /* Does the probe data contain the whole header? */ |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
856 if (p->buf_size < 4 + size + total) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
857 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
858 |
6029 | 859 /* The header should contain a known document type. For now, |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
860 * we don't parse the whole header but simply check for the |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
861 * availability of that array of characters inside the header. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
862 * Not fully fool-proof, but good enough. */ |
6029 | 863 for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) { |
864 int probelen = strlen(matroska_doctypes[i]); | |
865 for (n = 4+size; n <= 4+size+total-probelen; n++) | |
866 if (!memcmp(p->buf+n, matroska_doctypes[i], probelen)) | |
867 return AVPROBE_SCORE_MAX; | |
868 } | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
869 |
6030 | 870 // probably valid EBML header but no recognized doctype |
871 return AVPROBE_SCORE_MAX/2; | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
872 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
873 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
874 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
875 int num) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
876 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
877 MatroskaTrack *tracks = matroska->tracks.elem; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
878 int i; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
879 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
880 for (i=0; i < matroska->tracks.nb_elem; i++) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
881 if (tracks[i].num == num) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
882 return &tracks[i]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
883 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
884 av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
885 return NULL; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
886 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
887 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
888 static int matroska_decode_buffer(uint8_t** buf, int* buf_size, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
889 MatroskaTrack *track) |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
890 { |
3642 | 891 MatroskaTrackEncoding *encodings = track->encodings.elem; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
892 uint8_t* data = *buf; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
893 int isize = *buf_size; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
894 uint8_t* pkt_data = NULL; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
895 int pkt_size = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
896 int result = 0; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
897 int olen; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
898 |
3642 | 899 switch (encodings[0].compression.algo) { |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
900 case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: |
3642 | 901 return encodings[0].compression.settings.size; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
902 case MATROSKA_TRACK_ENCODING_COMP_LZO: |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
903 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
904 olen = pkt_size *= 3; |
4352 | 905 pkt_data = av_realloc(pkt_data, pkt_size+AV_LZO_OUTPUT_PADDING); |
4349
96dba41bad7f
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
4331
diff
changeset
|
906 result = av_lzo1x_decode(pkt_data, &olen, data, &isize); |
96dba41bad7f
Add av_ prefix to LZO stuff and thus make it officially part of the public API.
reimar
parents:
4331
diff
changeset
|
907 } while (result==AV_LZO_OUTPUT_FULL && pkt_size<10000000); |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
908 if (result) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
909 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
910 pkt_size -= olen; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
911 break; |
4206 | 912 #if CONFIG_ZLIB |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
913 case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
914 z_stream zstream = {0}; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
915 if (inflateInit(&zstream) != Z_OK) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
916 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
917 zstream.next_in = data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
918 zstream.avail_in = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
919 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
920 pkt_size *= 3; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
921 pkt_data = av_realloc(pkt_data, pkt_size); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
922 zstream.avail_out = pkt_size - zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
923 zstream.next_out = pkt_data + zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
924 result = inflate(&zstream, Z_NO_FLUSH); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
925 } while (result==Z_OK && pkt_size<10000000); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
926 pkt_size = zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
927 inflateEnd(&zstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
928 if (result != Z_STREAM_END) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
929 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
930 break; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
931 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
932 #endif |
4206 | 933 #if CONFIG_BZLIB |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
934 case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
935 bz_stream bzstream = {0}; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
936 if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
937 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
938 bzstream.next_in = data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
939 bzstream.avail_in = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
940 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
941 pkt_size *= 3; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
942 pkt_data = av_realloc(pkt_data, pkt_size); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
943 bzstream.avail_out = pkt_size - bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
944 bzstream.next_out = pkt_data + bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
945 result = BZ2_bzDecompress(&bzstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
946 } while (result==BZ_OK && pkt_size<10000000); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
947 pkt_size = bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
948 BZ2_bzDecompressEnd(&bzstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
949 if (result != BZ_STREAM_END) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
950 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
951 break; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
952 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
953 #endif |
3748
6b469866ffda
matroskadec: fail cleanly when the required compression lib is not compiled in
aurel
parents:
3747
diff
changeset
|
954 default: |
6b469866ffda
matroskadec: fail cleanly when the required compression lib is not compiled in
aurel
parents:
3747
diff
changeset
|
955 return -1; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
956 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
957 |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
958 *buf = pkt_data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
959 *buf_size = pkt_size; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
960 return 0; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
961 failed: |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
962 av_free(pkt_data); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
963 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
964 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
965 |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
966 static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, |
3951
9315ab7b1c0d
matroskadec: pass duration as parameter of matroska_fix_ass_packet()
aurel
parents:
3922
diff
changeset
|
967 AVPacket *pkt, uint64_t display_duration) |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
968 { |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
969 char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
970 for (; *ptr!=',' && ptr<end-1; ptr++); |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
971 if (*ptr == ',') |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
972 layer = ++ptr; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
973 for (; *ptr!=',' && ptr<end-1; ptr++); |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
974 if (*ptr == ',') { |
3951
9315ab7b1c0d
matroskadec: pass duration as parameter of matroska_fix_ass_packet()
aurel
parents:
3922
diff
changeset
|
975 int64_t end_pts = pkt->pts + display_duration; |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
976 int sc = matroska->time_scale * pkt->pts / 10000000; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
977 int ec = matroska->time_scale * end_pts / 10000000; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
978 int sh, sm, ss, eh, em, es, len; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
979 sh = sc/360000; sc -= 360000*sh; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
980 sm = sc/ 6000; sc -= 6000*sm; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
981 ss = sc/ 100; sc -= 100*ss; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
982 eh = ec/360000; ec -= 360000*eh; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
983 em = ec/ 6000; ec -= 6000*em; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
984 es = ec/ 100; ec -= 100*es; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
985 *ptr++ = '\0'; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
986 len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
987 if (!(line = av_malloc(len))) |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
988 return; |
3953
f1a9ff04eb4b
matroskadec: ass events lines must end with a DOS style EOL
aurel
parents:
3952
diff
changeset
|
989 snprintf(line,len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
990 layer, sh, sm, ss, sc, eh, em, es, ec, ptr); |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
991 av_free(pkt->data); |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
992 pkt->data = line; |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
993 pkt->size = strlen(line); |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
994 } |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
995 } |
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
996 |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
997 static void matroska_merge_packets(AVPacket *out, AVPacket *in) |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
998 { |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
999 out->data = av_realloc(out->data, out->size+in->size); |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1000 memcpy(out->data+out->size, in->data, in->size); |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1001 out->size += in->size; |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1002 av_destruct_packet(in); |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1003 av_free(in); |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1004 } |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1005 |
4495 | 1006 static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, |
1007 AVMetadata **metadata, char *prefix) | |
3702 | 1008 { |
1009 MatroskaTag *tags = list->elem; | |
4495 | 1010 char key[1024]; |
1011 int i; | |
3702 | 1012 |
1013 for (i=0; i < list->nb_elem; i++) { | |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1014 const char *lang = strcmp(tags[i].lang, "und") ? tags[i].lang : NULL; |
4495 | 1015 if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name); |
1016 else av_strlcpy(key, tags[i].name, sizeof(key)); | |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1017 if (tags[i].def || !lang) { |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1018 av_metadata_set2(metadata, key, tags[i].string, 0); |
4495 | 1019 if (tags[i].sub.nb_elem) |
1020 matroska_convert_tag(s, &tags[i].sub, metadata, key); | |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1021 } |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1022 if (lang) { |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1023 av_strlcat(key, "-", sizeof(key)); |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1024 av_strlcat(key, lang, sizeof(key)); |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1025 av_metadata_set2(metadata, key, tags[i].string, 0); |
4497
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1026 if (tags[i].sub.nb_elem) |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1027 matroska_convert_tag(s, &tags[i].sub, metadata, key); |
dc79722bbc25
matroskadec: export language of metadata tags when available
aurel
parents:
4495
diff
changeset
|
1028 } |
4495 | 1029 } |
1030 } | |
1031 | |
1032 static void matroska_convert_tags(AVFormatContext *s) | |
1033 { | |
1034 MatroskaDemuxContext *matroska = s->priv_data; | |
1035 MatroskaTags *tags = matroska->tags.elem; | |
1036 int i, j; | |
1037 | |
1038 for (i=0; i < matroska->tags.nb_elem; i++) { | |
1039 if (tags[i].target.attachuid) { | |
1040 MatroskaAttachement *attachment = matroska->attachments.elem; | |
1041 for (j=0; j<matroska->attachments.nb_elem; j++) | |
1042 if (attachment[j].uid == tags[i].target.attachuid) | |
1043 matroska_convert_tag(s, &tags[i].tag, | |
1044 &attachment[j].stream->metadata, NULL); | |
1045 } else if (tags[i].target.chapteruid) { | |
1046 MatroskaChapter *chapter = matroska->chapters.elem; | |
1047 for (j=0; j<matroska->chapters.nb_elem; j++) | |
1048 if (chapter[j].uid == tags[i].target.chapteruid) | |
1049 matroska_convert_tag(s, &tags[i].tag, | |
1050 &chapter[j].chapter->metadata, NULL); | |
1051 } else if (tags[i].target.trackuid) { | |
1052 MatroskaTrack *track = matroska->tracks.elem; | |
1053 for (j=0; j<matroska->tracks.nb_elem; j++) | |
1054 if (track[j].uid == tags[i].target.trackuid) | |
1055 matroska_convert_tag(s, &tags[i].tag, | |
1056 &track[j].stream->metadata, NULL); | |
1057 } else { | |
5031
1b5282d4863f
matroskadec: prepend TargetType to metadata key name
aurel
parents:
4916
diff
changeset
|
1058 matroska_convert_tag(s, &tags[i].tag, &s->metadata, |
1b5282d4863f
matroskadec: prepend TargetType to metadata key name
aurel
parents:
4916
diff
changeset
|
1059 tags[i].target.type); |
3702 | 1060 } |
1061 } | |
1062 } | |
1063 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1064 static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) |
3644 | 1065 { |
1066 EbmlList *seekhead_list = &matroska->seekhead; | |
1067 MatroskaSeekhead *seekhead = seekhead_list->elem; | |
1068 uint32_t level_up = matroska->level_up; | |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
1069 int64_t before_pos = url_ftell(matroska->ctx->pb); |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
1070 uint32_t saved_id = matroska->current_id; |
3644 | 1071 MatroskaLevel level; |
3652
a22da874fc50
matroskadec: use generic parser inside matroska_execute_seekhead()
aurel
parents:
3651
diff
changeset
|
1072 int i; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1073 |
6114
10c9d304794f
Do not attempt to seek to index for streamed files and if the user explicitly
reimar
parents:
6113
diff
changeset
|
1074 // we should not do any seeking in the streaming case |
10c9d304794f
Do not attempt to seek to index for streamed files and if the user explicitly
reimar
parents:
6113
diff
changeset
|
1075 if (url_is_streamed(matroska->ctx->pb) || |
10c9d304794f
Do not attempt to seek to index for streamed files and if the user explicitly
reimar
parents:
6113
diff
changeset
|
1076 (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) |
10c9d304794f
Do not attempt to seek to index for streamed files and if the user explicitly
reimar
parents:
6113
diff
changeset
|
1077 return; |
10c9d304794f
Do not attempt to seek to index for streamed files and if the user explicitly
reimar
parents:
6113
diff
changeset
|
1078 |
3644 | 1079 for (i=0; i<seekhead_list->nb_elem; i++) { |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
1080 int64_t offset = seekhead[i].pos + matroska->segment_start; |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
1081 |
3644 | 1082 if (seekhead[i].pos <= before_pos |
1083 || seekhead[i].id == MATROSKA_ID_SEEKHEAD | |
1084 || seekhead[i].id == MATROSKA_ID_CLUSTER) | |
1085 continue; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1086 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1087 /* seek */ |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
1088 if (url_fseek(matroska->ctx->pb, offset, SEEK_SET) != offset) |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1089 continue; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1090 |
3692 | 1091 /* We don't want to lose our seekhead level, so we add |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1092 * a dummy. This is a crude hack. */ |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1093 if (matroska->num_levels == EBML_MAX_DEPTH) { |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1094 av_log(matroska->ctx, AV_LOG_INFO, |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1095 "Max EBML element depth (%d) reached, " |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1096 "cannot parse further.\n", EBML_MAX_DEPTH); |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1097 break; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1098 } |
885 | 1099 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1100 level.start = 0; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1101 level.length = (uint64_t)-1; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1102 matroska->levels[matroska->num_levels] = level; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1103 matroska->num_levels++; |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
1104 matroska->current_id = 0; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1105 |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
1106 ebml_parse(matroska, matroska_segment, matroska); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1107 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1108 /* remove dummy level */ |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1109 while (matroska->num_levels) { |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1110 uint64_t length = matroska->levels[--matroska->num_levels].length; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1111 if (length == (uint64_t)-1) |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1112 break; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1113 } |
3644 | 1114 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1115 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1116 /* seek back */ |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
1117 url_fseek(matroska->ctx->pb, before_pos, SEEK_SET); |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1118 matroska->level_up = level_up; |
6123
9f368d591c13
matroskadec: store the ID of the currently parsed ebml element
aurel
parents:
6122
diff
changeset
|
1119 matroska->current_id = saved_id; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1120 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1121 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1122 static int matroska_aac_profile(char *codec_id) |
1468 | 1123 { |
3762 | 1124 static const char * const aac_profiles[] = { "MAIN", "LC", "SSR" }; |
1468 | 1125 int profile; |
1126 | |
4001 | 1127 for (profile=0; profile<FF_ARRAY_ELEMS(aac_profiles); profile++) |
1468 | 1128 if (strstr(codec_id, aac_profiles[profile])) |
1129 break; | |
1130 return profile + 1; | |
1131 } | |
1132 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1133 static int matroska_aac_sri(int samplerate) |
1468 | 1134 { |
1135 int sri; | |
1136 | |
4001 | 1137 for (sri=0; sri<FF_ARRAY_ELEMS(ff_mpeg4audio_sample_rates); sri++) |
3201 | 1138 if (ff_mpeg4audio_sample_rates[sri] == samplerate) |
1468 | 1139 break; |
1140 return sri; | |
1141 } | |
1142 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1143 static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1144 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1145 MatroskaDemuxContext *matroska = s->priv_data; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1146 EbmlList *attachements_list = &matroska->attachments; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1147 MatroskaAttachement *attachements; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1148 EbmlList *chapters_list = &matroska->chapters; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1149 MatroskaChapter *chapters; |
3648 | 1150 MatroskaTrack *tracks; |
3637 | 1151 EbmlList *index_list; |
1152 MatroskaIndex *index; | |
4027
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1153 int index_scale = 1; |
4218
4162b8362ed6
matroskadec: ensure we only consider chapters which are properly ordered
aurel
parents:
4206
diff
changeset
|
1154 uint64_t max_start = 0; |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1155 Ebml ebml = { 0 }; |
3648 | 1156 AVStream *st; |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1157 int i, j; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1158 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1159 matroska->ctx = s; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1160 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1161 /* First read the EBML header. */ |
3678
fd968e67ac6a
matroskadec: directly use ebml_parse() or ebml_parse_id() where it's enough
aurel
parents:
3677
diff
changeset
|
1162 if (ebml_parse(matroska, ebml_syntax, &ebml) |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1163 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) |
6029 | 1164 || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) { |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1165 av_log(matroska->ctx, AV_LOG_ERROR, |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1166 "EBML header using unsupported features\n" |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1167 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1168 ebml.version, ebml.doctype, ebml.doctype_version); |
6029 | 1169 ebml_free(ebml_syntax, &ebml); |
5838 | 1170 return AVERROR_PATCHWELCOME; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1171 } |
6029 | 1172 for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) |
1173 if (!strcmp(ebml.doctype, matroska_doctypes[i])) | |
1174 break; | |
1175 if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) { | |
6030 | 1176 av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype); |
6029 | 1177 } |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1178 ebml_free(ebml_syntax, &ebml); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1179 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1180 /* The next thing is a segment. */ |
3678
fd968e67ac6a
matroskadec: directly use ebml_parse() or ebml_parse_id() where it's enough
aurel
parents:
3677
diff
changeset
|
1181 if (ebml_parse(matroska, matroska_segments, matroska) < 0) |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1182 return -1; |
3644 | 1183 matroska_execute_seekhead(matroska); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1184 |
6016
ce535a7152ef
matroskadec: Ensure time_scale is nonzero, fixes divide-by-zero if the file
conrad
parents:
6015
diff
changeset
|
1185 if (!matroska->time_scale) |
ce535a7152ef
matroskadec: Ensure time_scale is nonzero, fixes divide-by-zero if the file
conrad
parents:
6015
diff
changeset
|
1186 matroska->time_scale = 1000000; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1187 if (matroska->duration) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1188 matroska->ctx->duration = matroska->duration * matroska->time_scale |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1189 * 1000 / AV_TIME_BASE; |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1190 av_metadata_set2(&s->metadata, "title", matroska->title, 0); |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1191 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1192 tracks = matroska->tracks.elem; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1193 for (i=0; i < matroska->tracks.nb_elem; i++) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1194 MatroskaTrack *track = &tracks[i]; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1195 enum CodecID codec_id = CODEC_ID_NONE; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1196 EbmlList *encodings_list = &tracks->encodings; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1197 MatroskaTrackEncoding *encodings = encodings_list->elem; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1198 uint8_t *extradata = NULL; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1199 int extradata_size = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1200 int extradata_offset = 0; |
4249
ffedcd3d4bed
matroskadec: merge ByteIOContext declarations at upper level
aurel
parents:
4248
diff
changeset
|
1201 ByteIOContext b; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1202 |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1203 /* Apply some sanity checks. */ |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1204 if (track->type != MATROSKA_TRACK_TYPE_VIDEO && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1205 track->type != MATROSKA_TRACK_TYPE_AUDIO && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1206 track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1207 av_log(matroska->ctx, AV_LOG_INFO, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1208 "Unknown or unsupported track type %"PRIu64"\n", |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1209 track->type); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1210 continue; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1211 } |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1212 if (track->codec_id == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1213 continue; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1214 |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1215 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1216 if (!track->default_duration) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1217 track->default_duration = 1000000000/track->video.frame_rate; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1218 if (!track->video.display_width) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1219 track->video.display_width = track->video.pixel_width; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1220 if (!track->video.display_height) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1221 track->video.display_height = track->video.pixel_height; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1222 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1223 if (!track->audio.out_samplerate) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1224 track->audio.out_samplerate = track->audio.samplerate; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1225 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1226 if (encodings_list->nb_elem > 1) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1227 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1228 "Multiple combined encodings no supported"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1229 } else if (encodings_list->nb_elem == 1) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1230 if (encodings[0].type || |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1231 (encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && |
4206 | 1232 #if CONFIG_ZLIB |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1233 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1234 #endif |
4206 | 1235 #if CONFIG_BZLIB |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1236 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1237 #endif |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1238 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO)) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1239 encodings[0].scope = 0; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1240 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1241 "Unsupported encoding type"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1242 } else if (track->codec_priv.size && encodings[0].scope&2) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1243 uint8_t *codec_priv = track->codec_priv.data; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1244 int offset = matroska_decode_buffer(&track->codec_priv.data, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1245 &track->codec_priv.size, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1246 track); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1247 if (offset < 0) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1248 track->codec_priv.data = NULL; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1249 track->codec_priv.size = 0; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1250 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1251 "Failed to decode codec private data\n"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1252 } else if (offset > 0) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1253 track->codec_priv.data = av_malloc(track->codec_priv.size + offset); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1254 memcpy(track->codec_priv.data, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1255 encodings[0].compression.settings.data, offset); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1256 memcpy(track->codec_priv.data+offset, codec_priv, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1257 track->codec_priv.size); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1258 track->codec_priv.size += offset; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1259 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1260 if (codec_priv != track->codec_priv.data) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1261 av_free(codec_priv); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1262 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1263 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1264 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1265 for(j=0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++){ |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1266 if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1267 strlen(ff_mkv_codec_tags[j].str))){ |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1268 codec_id= ff_mkv_codec_tags[j].id; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1269 break; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1270 } |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1271 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1272 |
3691 | 1273 st = track->stream = av_new_stream(s, 0); |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1274 if (st == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1275 return AVERROR(ENOMEM); |
1024 | 1276 |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3685
diff
changeset
|
1277 if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") |
3662 | 1278 && track->codec_priv.size >= 40 |
1279 && track->codec_priv.data != NULL) { | |
5740
421297d526d0
matroskadec: timestamps are dts and not pts in ms vfw compatibility mode
aurel
parents:
5618
diff
changeset
|
1280 track->ms_compat = 1; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1281 track->video.fourcc = AV_RL32(track->codec_priv.data + 16); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5031
diff
changeset
|
1282 codec_id = ff_codec_get_id(ff_codec_bmp_tags, track->video.fourcc); |
5142
1f237326c8bc
matroskadec: add correct extradata offset for V_MS/VFW/FOURCC tracks
aurel
parents:
5141
diff
changeset
|
1283 extradata_offset = 40; |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3685
diff
changeset
|
1284 } else if (!strcmp(track->codec_id, "A_MS/ACM") |
5250
4b736fd7d0fd
matroskadec: fix handling of A_MS/ACM track with no extradata
aurel
parents:
5142
diff
changeset
|
1285 && track->codec_priv.size >= 14 |
3662 | 1286 && track->codec_priv.data != NULL) { |
4248
6e4ce186db2e
matroskadec: parse the WAVEFORMATEX header and discard it from extradata
aurel
parents:
4218
diff
changeset
|
1287 init_put_byte(&b, track->codec_priv.data, track->codec_priv.size, |
6e4ce186db2e
matroskadec: parse the WAVEFORMATEX header and discard it from extradata
aurel
parents:
4218
diff
changeset
|
1288 URL_RDONLY, NULL, NULL, NULL, NULL); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5031
diff
changeset
|
1289 ff_get_wav_header(&b, st->codec, track->codec_priv.size); |
4248
6e4ce186db2e
matroskadec: parse the WAVEFORMATEX header and discard it from extradata
aurel
parents:
4218
diff
changeset
|
1290 codec_id = st->codec->codec_id; |
5250
4b736fd7d0fd
matroskadec: fix handling of A_MS/ACM track with no extradata
aurel
parents:
5142
diff
changeset
|
1291 extradata_offset = FFMIN(track->codec_priv.size, 18); |
3662 | 1292 } else if (!strcmp(track->codec_id, "V_QUICKTIME") |
1293 && (track->codec_priv.size >= 86) | |
1294 && (track->codec_priv.data != NULL)) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1295 track->video.fourcc = AV_RL32(track->codec_priv.data); |
5058
33a244b7ca65
Add ff_ prefixes to exported symbols in libavformat/riff.h.
diego
parents:
5031
diff
changeset
|
1296 codec_id=ff_codec_get_id(codec_movvideo_tags, track->video.fourcc); |
3746 | 1297 } else if (codec_id == CODEC_ID_PCM_S16BE) { |
1298 switch (track->audio.bitdepth) { | |
1299 case 8: codec_id = CODEC_ID_PCM_U8; break; | |
1300 case 24: codec_id = CODEC_ID_PCM_S24BE; break; | |
1301 case 32: codec_id = CODEC_ID_PCM_S32BE; break; | |
1302 } | |
1303 } else if (codec_id == CODEC_ID_PCM_S16LE) { | |
1304 switch (track->audio.bitdepth) { | |
1305 case 8: codec_id = CODEC_ID_PCM_U8; break; | |
1306 case 24: codec_id = CODEC_ID_PCM_S24LE; break; | |
1307 case 32: codec_id = CODEC_ID_PCM_S32LE; break; | |
1308 } | |
1309 } else if (codec_id==CODEC_ID_PCM_F32LE && track->audio.bitdepth==64) { | |
1310 codec_id = CODEC_ID_PCM_F64LE; | |
3662 | 1311 } else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) { |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1312 int profile = matroska_aac_profile(track->codec_id); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1313 int sri = matroska_aac_sri(track->audio.samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1314 extradata = av_malloc(5); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1315 if (extradata == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1316 return AVERROR(ENOMEM); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1317 extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1318 extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1319 if (strstr(track->codec_id, "SBR")) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1320 sri = matroska_aac_sri(track->audio.out_samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1321 extradata[2] = 0x56; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1322 extradata[3] = 0xE5; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1323 extradata[4] = 0x80 | (sri<<3); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1324 extradata_size = 5; |
3655 | 1325 } else |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1326 extradata_size = 2; |
3662 | 1327 } else if (codec_id == CODEC_ID_TTA) { |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1328 extradata_size = 30; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1329 extradata = av_mallocz(extradata_size); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1330 if (extradata == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1331 return AVERROR(ENOMEM); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1332 init_put_byte(&b, extradata, extradata_size, 1, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1333 NULL, NULL, NULL, NULL); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1334 put_buffer(&b, "TTA1", 4); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1335 put_le16(&b, 1); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1336 put_le16(&b, track->audio.channels); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1337 put_le16(&b, track->audio.bitdepth); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1338 put_le32(&b, track->audio.out_samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1339 put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate); |
3662 | 1340 } else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 || |
1341 codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1342 extradata_offset = 26; |
3662 | 1343 } else if (codec_id == CODEC_ID_RA_144) { |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1344 track->audio.out_samplerate = 8000; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1345 track->audio.channels = 1; |
3662 | 1346 } else if (codec_id == CODEC_ID_RA_288 || codec_id == CODEC_ID_COOK || |
5832 | 1347 codec_id == CODEC_ID_ATRAC3 || codec_id == CODEC_ID_SIPR) { |
1348 int flavor; | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1349 init_put_byte(&b, track->codec_priv.data,track->codec_priv.size, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1350 0, NULL, NULL, NULL, NULL); |
5832 | 1351 url_fskip(&b, 22); |
1352 flavor = get_be16(&b); | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1353 track->audio.coded_framesize = get_be32(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1354 url_fskip(&b, 12); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1355 track->audio.sub_packet_h = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1356 track->audio.frame_size = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1357 track->audio.sub_packet_size = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1358 track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1359 if (codec_id == CODEC_ID_RA_288) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1360 st->codec->block_align = track->audio.coded_framesize; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1361 track->codec_priv.size = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1362 } else { |
5832 | 1363 if (codec_id == CODEC_ID_SIPR && flavor < 4) { |
1364 const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; | |
1365 track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; | |
1366 st->codec->bit_rate = sipr_bit_rate[flavor]; | |
1367 } | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1368 st->codec->block_align = track->audio.sub_packet_size; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1369 extradata_offset = 78; |
1531 | 1370 } |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1371 } |
5141 | 1372 track->codec_priv.size -= extradata_offset; |
1531 | 1373 |
3655 | 1374 if (codec_id == CODEC_ID_NONE) |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1375 av_log(matroska->ctx, AV_LOG_INFO, |
3659 | 1376 "Unknown/unsupported CodecID %s.\n", track->codec_id); |
2144 | 1377 |
3912
32652a9c2624
matroskadec: sanitize track time_scale before using it
aurel
parents:
3899
diff
changeset
|
1378 if (track->time_scale < 0.01) |
32652a9c2624
matroskadec: sanitize track time_scale before using it
aurel
parents:
3899
diff
changeset
|
1379 track->time_scale = 1.0; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1380 av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */ |
2144 | 1381 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1382 st->codec->codec_id = codec_id; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1383 st->start_time = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1384 if (strcmp(track->language, "und")) |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1385 av_metadata_set2(&st->metadata, "language", track->language, 0); |
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1386 av_metadata_set2(&st->metadata, "title", track->name, 0); |
2144 | 1387 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1388 if (track->flag_default) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1389 st->disposition |= AV_DISPOSITION_DEFAULT; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1390 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1391 if (track->default_duration) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1392 av_reduce(&st->codec->time_base.num, &st->codec->time_base.den, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1393 track->default_duration, 1000000000, 30000); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1394 |
5251
75a5bf71fad3
matroskadec: don't overwrite extradata already read by ff_get_wav_header()
aurel
parents:
5250
diff
changeset
|
1395 if (!st->codec->extradata) { |
5252 | 1396 if(extradata){ |
1397 st->codec->extradata = extradata; | |
1398 st->codec->extradata_size = extradata_size; | |
1399 } else if(track->codec_priv.data && track->codec_priv.size > 0){ | |
1400 st->codec->extradata = av_mallocz(track->codec_priv.size + | |
1401 FF_INPUT_BUFFER_PADDING_SIZE); | |
1402 if(st->codec->extradata == NULL) | |
1403 return AVERROR(ENOMEM); | |
1404 st->codec->extradata_size = track->codec_priv.size; | |
1405 memcpy(st->codec->extradata, | |
1406 track->codec_priv.data + extradata_offset, | |
1407 track->codec_priv.size); | |
1408 } | |
5251
75a5bf71fad3
matroskadec: don't overwrite extradata already read by ff_get_wav_header()
aurel
parents:
5250
diff
changeset
|
1409 } |
692
b0144ebc71dd
H.264 and Vorbis support in matroska patch by (M«©ns Rullg«©rd |mru inprovide com)
michael
parents:
652
diff
changeset
|
1410 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1411 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5838
diff
changeset
|
1412 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1413 st->codec->codec_tag = track->video.fourcc; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1414 st->codec->width = track->video.pixel_width; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1415 st->codec->height = track->video.pixel_height; |
3759
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3748
diff
changeset
|
1416 av_reduce(&st->sample_aspect_ratio.num, |
27537074f2a9
convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents:
3748
diff
changeset
|
1417 &st->sample_aspect_ratio.den, |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1418 st->codec->height * track->video.display_width, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1419 st->codec-> width * track->video.display_height, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1420 255); |
5129
87e2b58a305a
matroskadec: disable h264 parser as long as it totally mess up frame type
aurel
parents:
5128
diff
changeset
|
1421 if (st->codec->codec_id != CODEC_ID_H264) |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1422 st->need_parsing = AVSTREAM_PARSE_HEADERS; |
6005 | 1423 if (track->default_duration) |
1424 st->avg_frame_rate = av_d2q(1000000000.0/track->default_duration, INT_MAX); | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1425 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5838
diff
changeset
|
1426 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1427 st->codec->sample_rate = track->audio.out_samplerate; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1428 st->codec->channels = track->audio.channels; |
5973
210e90a62044
seems aac gets screwed up by the parser so disable it
bcoudurier
parents:
5972
diff
changeset
|
1429 if (st->codec->codec_id != CODEC_ID_AAC) |
5972
41a3f142ca68
parse stream headers for audio streams in mkv, needed for frame size
bcoudurier
parents:
5969
diff
changeset
|
1430 st->need_parsing = AVSTREAM_PARSE_HEADERS; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1431 } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5838
diff
changeset
|
1432 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1433 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1434 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1435 |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1436 attachements = attachements_list->elem; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1437 for (j=0; j<attachements_list->nb_elem; j++) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1438 if (!(attachements[j].filename && attachements[j].mime && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1439 attachements[j].bin.data && attachements[j].bin.size > 0)) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1440 av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1441 } else { |
3691 | 1442 AVStream *st = av_new_stream(s, 0); |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1443 if (st == NULL) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1444 break; |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1445 av_metadata_set2(&st->metadata, "filename",attachements[j].filename, 0); |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1446 st->codec->codec_id = CODEC_ID_NONE; |
5910
536e5527c1e0
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
5838
diff
changeset
|
1447 st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1448 st->codec->extradata = av_malloc(attachements[j].bin.size); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1449 if(st->codec->extradata == NULL) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1450 break; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1451 st->codec->extradata_size = attachements[j].bin.size; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1452 memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1453 |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1454 for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1455 if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1456 strlen(ff_mkv_mime_tags[i].str))) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1457 st->codec->codec_id = ff_mkv_mime_tags[i].id; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1458 break; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1459 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1460 } |
4495 | 1461 attachements[j].stream = st; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1462 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1463 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1464 |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1465 chapters = chapters_list->elem; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1466 for (i=0; i<chapters_list->nb_elem; i++) |
4218
4162b8362ed6
matroskadec: ensure we only consider chapters which are properly ordered
aurel
parents:
4206
diff
changeset
|
1467 if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid |
4162b8362ed6
matroskadec: ensure we only consider chapters which are properly ordered
aurel
parents:
4206
diff
changeset
|
1468 && (max_start==0 || chapters[i].start > max_start)) { |
4492
56ea2b1028fe
matroskadec: use new metadata API to export some simple information
aurel
parents:
4352
diff
changeset
|
1469 chapters[i].chapter = |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1470 ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000}, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1471 chapters[i].start, chapters[i].end, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1472 chapters[i].title); |
5982
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1473 av_metadata_set2(&chapters[i].chapter->metadata, |
f74198942337
Mark av_metadata_set() as deprecated, and use av_metadata_set2()
stefano
parents:
5973
diff
changeset
|
1474 "title", chapters[i].title, 0); |
4218
4162b8362ed6
matroskadec: ensure we only consider chapters which are properly ordered
aurel
parents:
4206
diff
changeset
|
1475 max_start = chapters[i].start; |
4162b8362ed6
matroskadec: ensure we only consider chapters which are properly ordered
aurel
parents:
4206
diff
changeset
|
1476 } |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1477 |
3637 | 1478 index_list = &matroska->index; |
1479 index = index_list->elem; | |
4027
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1480 if (index_list->nb_elem |
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1481 && index[0].time > 100000000000000/matroska->time_scale) { |
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1482 av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n"); |
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1483 index_scale = matroska->time_scale; |
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1484 } |
3637 | 1485 for (i=0; i<index_list->nb_elem; i++) { |
1486 EbmlList *pos_list = &index[i].pos; | |
1487 MatroskaIndexPos *pos = pos_list->elem; | |
1488 for (j=0; j<pos_list->nb_elem; j++) { | |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1489 MatroskaTrack *track = matroska_find_track_by_num(matroska, |
3637 | 1490 pos[j].track); |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1491 if (track && track->stream) |
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1492 av_add_index_entry(track->stream, |
3637 | 1493 pos[j].pos + matroska->segment_start, |
4027
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1494 index[i].time/index_scale, 0, 0, |
11fbf47f3e16
matroskadec: fix index timestamps for some broken files
aurel
parents:
4001
diff
changeset
|
1495 AVINDEX_KEYFRAME); |
2012 | 1496 } |
1497 } | |
1498 | |
4495 | 1499 matroska_convert_tags(s); |
1500 | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1501 return 0; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1502 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1503 |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1504 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1505 * Put one packet in an application-supplied AVPacket struct. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1506 * Returns 0 on success or -1 on failure. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1507 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1508 static int matroska_deliver_packet(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1509 AVPacket *pkt) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1510 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1511 if (matroska->num_packets > 0) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1512 memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1513 av_free(matroska->packets[0]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1514 if (matroska->num_packets > 1) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1515 memmove(&matroska->packets[0], &matroska->packets[1], |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1516 (matroska->num_packets - 1) * sizeof(AVPacket *)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1517 matroska->packets = |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1518 av_realloc(matroska->packets, (matroska->num_packets - 1) * |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1519 sizeof(AVPacket *)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1520 } else { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1521 av_freep(&matroska->packets); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1522 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1523 matroska->num_packets--; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1524 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1525 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1526 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1527 return -1; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1528 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1529 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1530 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1531 * Free all packets in our internal queue. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1532 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1533 static void matroska_clear_queue(MatroskaDemuxContext *matroska) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1534 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1535 if (matroska->packets) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1536 int n; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1537 for (n = 0; n < matroska->num_packets; n++) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1538 av_free_packet(matroska->packets[n]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1539 av_free(matroska->packets[n]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1540 } |
3696
4aef467adb6b
matroskadec: use av_freep(&x) instead of av_free(x);x=NULL
aurel
parents:
3695
diff
changeset
|
1541 av_freep(&matroska->packets); |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1542 matroska->num_packets = 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1543 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1544 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1545 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1546 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1547 int size, int64_t pos, uint64_t cluster_time, |
3897
5aa1cbbd79e0
matroskadec: ensure that the timecode added to the index are is the one
aurel
parents:
3894
diff
changeset
|
1548 uint64_t duration, int is_keyframe, |
5aa1cbbd79e0
matroskadec: ensure that the timecode added to the index are is the one
aurel
parents:
3894
diff
changeset
|
1549 int64_t cluster_pos) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1550 { |
3913
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1551 uint64_t timecode = AV_NOPTS_VALUE; |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1552 MatroskaTrack *track; |
3899
5901b4ccda4a
matroskadec: remove now useless vstream and is_video_key_frame
aurel
parents:
3898
diff
changeset
|
1553 int res = 0; |
2013
fc0b19650faa
add an intermediate variable (prepare for next patch)
aurel
parents:
2012
diff
changeset
|
1554 AVStream *st; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1555 AVPacket *pkt; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1556 int16_t block_time; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1557 uint32_t *lace_size = NULL; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1558 int n, flags, laces = 0; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1559 uint64_t num; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1560 |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1561 if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) { |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1562 av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n"); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1563 return res; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1564 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1565 data += n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1566 size -= n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1567 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1568 track = matroska_find_track_by_num(matroska, num); |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1569 if (size <= 3 || !track || !track->stream) { |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1570 av_log(matroska->ctx, AV_LOG_INFO, |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1571 "Invalid stream %"PRIu64" or size %u\n", num, size); |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1572 return res; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1573 } |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1574 st = track->stream; |
3655 | 1575 if (st->discard >= AVDISCARD_ALL) |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1576 return res; |
1914 | 1577 if (duration == AV_NOPTS_VALUE) |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1578 duration = track->default_duration / matroska->time_scale; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1579 |
2185 | 1580 block_time = AV_RB16(data); |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1581 data += 2; |
2188 | 1582 flags = *data++; |
1583 size -= 3; | |
1831 | 1584 if (is_keyframe == -1) |
5913
11bb10c37225
Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents:
5910
diff
changeset
|
1585 is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0; |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1586 |
3913
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1587 if (cluster_time != (uint64_t)-1 |
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1588 && (block_time >= 0 || cluster_time >= -block_time)) { |
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1589 timecode = cluster_time + block_time; |
3915
7643d7c3fcf6
matroskadec: ensure that overlapping subtitles are not added to the index
aurel
parents:
3914
diff
changeset
|
1590 if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE |
7643d7c3fcf6
matroskadec: ensure that overlapping subtitles are not added to the index
aurel
parents:
3914
diff
changeset
|
1591 && timecode < track->end_timecode) |
7643d7c3fcf6
matroskadec: ensure that overlapping subtitles are not added to the index
aurel
parents:
3914
diff
changeset
|
1592 is_keyframe = 0; /* overlapping subtitles are not key frame */ |
3922
56dc585dcda4
matroskadec: simplify, first_timecode is already in the index
aurel
parents:
3921
diff
changeset
|
1593 if (is_keyframe) |
3913
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1594 av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME); |
3915
7643d7c3fcf6
matroskadec: ensure that overlapping subtitles are not added to the index
aurel
parents:
3914
diff
changeset
|
1595 track->end_timecode = FFMAX(track->end_timecode, timecode+duration); |
3913
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1596 } |
253050919116
matroskadec: move timecode calculation a little earlier
aurel
parents:
3912
diff
changeset
|
1597 |
3916
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1598 if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { |
3914
f7a20cf5438f
matroskadec: after seeking, skip up to the desired timestamp instead of
aurel
parents:
3913
diff
changeset
|
1599 if (!is_keyframe || timecode < matroska->skip_to_timecode) |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1600 return res; |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1601 matroska->skip_to_keyframe = 0; |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1602 } |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1603 |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1604 switch ((flags & 0x06) >> 1) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1605 case 0x0: /* no lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1606 laces = 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1607 lace_size = av_mallocz(sizeof(int)); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1608 lace_size[0] = size; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1609 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1610 |
3692 | 1611 case 0x1: /* Xiph lacing */ |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1612 case 0x2: /* fixed-size lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1613 case 0x3: /* EBML lacing */ |
3391 | 1614 assert(size>0); // size <=3 is checked before size-=3 above |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1615 laces = (*data) + 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1616 data += 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1617 size -= 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1618 lace_size = av_mallocz(laces * sizeof(int)); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1619 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1620 switch ((flags & 0x06) >> 1) { |
3692 | 1621 case 0x1: /* Xiph lacing */ { |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1622 uint8_t temp; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1623 uint32_t total = 0; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1624 for (n = 0; res == 0 && n < laces - 1; n++) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1625 while (1) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1626 if (size == 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1627 res = -1; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1628 break; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1629 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1630 temp = *data; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1631 lace_size[n] += temp; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1632 data += 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1633 size -= 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1634 if (temp != 0xff) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1635 break; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1636 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1637 total += lace_size[n]; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1638 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1639 lace_size[n] = size - total; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1640 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1641 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1642 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1643 case 0x2: /* fixed-size lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1644 for (n = 0; n < laces; n++) |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1645 lace_size[n] = size / laces; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1646 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1647 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1648 case 0x3: /* EBML lacing */ { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1649 uint32_t total; |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1650 n = matroska_ebmlnum_uint(matroska, data, size, &num); |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1651 if (n < 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1652 av_log(matroska->ctx, AV_LOG_INFO, |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1653 "EBML block data error\n"); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1654 break; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1655 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1656 data += n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1657 size -= n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1658 total = lace_size[0] = num; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1659 for (n = 1; res == 0 && n < laces - 1; n++) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1660 int64_t snum; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1661 int r; |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1662 r = matroska_ebmlnum_sint(matroska, data, size, &snum); |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1663 if (r < 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1664 av_log(matroska->ctx, AV_LOG_INFO, |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1665 "EBML block data error\n"); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1666 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1667 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1668 data += r; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1669 size -= r; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1670 lace_size[n] = lace_size[n - 1] + snum; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1671 total += lace_size[n]; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1672 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1673 lace_size[n] = size - total; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1674 break; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1675 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1676 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1677 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1678 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1679 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1680 if (res == 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1681 for (n = 0; n < laces; n++) { |
5513
f4eceb1eb100
mkvdec: Avoid divide-by-zero crash on invalid real audio tracks
conrad
parents:
5252
diff
changeset
|
1682 if ((st->codec->codec_id == CODEC_ID_RA_288 || |
f4eceb1eb100
mkvdec: Avoid divide-by-zero crash on invalid real audio tracks
conrad
parents:
5252
diff
changeset
|
1683 st->codec->codec_id == CODEC_ID_COOK || |
5832 | 1684 st->codec->codec_id == CODEC_ID_SIPR || |
5513
f4eceb1eb100
mkvdec: Avoid divide-by-zero crash on invalid real audio tracks
conrad
parents:
5252
diff
changeset
|
1685 st->codec->codec_id == CODEC_ID_ATRAC3) && |
f4eceb1eb100
mkvdec: Avoid divide-by-zero crash on invalid real audio tracks
conrad
parents:
5252
diff
changeset
|
1686 st->codec->block_align && track->audio.sub_packet_size) { |
2657 | 1687 int a = st->codec->block_align; |
3642 | 1688 int sps = track->audio.sub_packet_size; |
1689 int cfs = track->audio.coded_framesize; | |
1690 int h = track->audio.sub_packet_h; | |
1691 int y = track->audio.sub_packet_cnt; | |
1692 int w = track->audio.frame_size; | |
2657 | 1693 int x; |
1694 | |
3642 | 1695 if (!track->audio.pkt_cnt) { |
2657 | 1696 if (st->codec->codec_id == CODEC_ID_RA_288) |
1697 for (x=0; x<h/2; x++) | |
3642 | 1698 memcpy(track->audio.buf+x*2*w+y*cfs, |
2657 | 1699 data+x*cfs, cfs); |
5832 | 1700 else if (st->codec->codec_id == CODEC_ID_SIPR) |
1701 memcpy(track->audio.buf + y*w, data, w); | |
2657 | 1702 else |
1703 for (x=0; x<w/sps; x++) | |
3642 | 1704 memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); |
2657 | 1705 |
3642 | 1706 if (++track->audio.sub_packet_cnt >= h) { |
5832 | 1707 if (st->codec->codec_id == CODEC_ID_SIPR) |
1708 ff_rm_reorder_sipr_data(track->audio.buf, h, w); | |
3642 | 1709 track->audio.sub_packet_cnt = 0; |
1710 track->audio.pkt_cnt = h*w / a; | |
2144 | 1711 } |
2657 | 1712 } |
3642 | 1713 while (track->audio.pkt_cnt) { |
2145 | 1714 pkt = av_mallocz(sizeof(AVPacket)); |
2657 | 1715 av_new_packet(pkt, a); |
3642 | 1716 memcpy(pkt->data, track->audio.buf |
1717 + a * (h*w / a - track->audio.pkt_cnt--), a); | |
2657 | 1718 pkt->pos = pos; |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
1719 pkt->stream_index = st->index; |
3695
5825a6cfd3bd
matroskadec: replace matroska_queue_packet with a single call to dynarray_add
aurel
parents:
3692
diff
changeset
|
1720 dynarray_add(&matroska->packets,&matroska->num_packets,pkt); |
2144 | 1721 } |
2657 | 1722 } else { |
3642 | 1723 MatroskaTrackEncoding *encodings = track->encodings.elem; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
1724 int offset = 0, pkt_size = lace_size[n]; |
3281 | 1725 uint8_t *pkt_data = data; |
1726 | |
5762 | 1727 if (lace_size[n] > size) { |
1728 av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n"); | |
1729 break; | |
1730 } | |
1731 | |
3642 | 1732 if (encodings && encodings->scope & 1) { |
3659 | 1733 offset = matroska_decode_buffer(&pkt_data,&pkt_size, track); |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
1734 if (offset < 0) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
1735 continue; |
3279 | 1736 } |
1737 | |
2657 | 1738 pkt = av_mallocz(sizeof(AVPacket)); |
1739 /* XXX: prevent data copy... */ | |
3281 | 1740 if (av_new_packet(pkt, pkt_size+offset) < 0) { |
3415 | 1741 av_free(pkt); |
2657 | 1742 res = AVERROR(ENOMEM); |
1743 break; | |
1744 } | |
3279 | 1745 if (offset) |
3642 | 1746 memcpy (pkt->data, encodings->compression.settings.data, offset); |
3281 | 1747 memcpy (pkt->data+offset, pkt_data, pkt_size); |
2657 | 1748 |
3493 | 1749 if (pkt_data != data) |
1750 av_free(pkt_data); | |
1751 | |
2657 | 1752 if (n == 0) |
1753 pkt->flags = is_keyframe; | |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
1754 pkt->stream_index = st->index; |
2657 | 1755 |
5740
421297d526d0
matroskadec: timestamps are dts and not pts in ms vfw compatibility mode
aurel
parents:
5618
diff
changeset
|
1756 if (track->ms_compat) |
421297d526d0
matroskadec: timestamps are dts and not pts in ms vfw compatibility mode
aurel
parents:
5618
diff
changeset
|
1757 pkt->dts = timecode; |
421297d526d0
matroskadec: timestamps are dts and not pts in ms vfw compatibility mode
aurel
parents:
5618
diff
changeset
|
1758 else |
5741 | 1759 pkt->pts = timecode; |
2657 | 1760 pkt->pos = pos; |
3952
9808dea139a1
matroskadec: set duration only for CODEC_ID_TEXT subtitles
aurel
parents:
3951
diff
changeset
|
1761 if (st->codec->codec_id == CODEC_ID_TEXT) |
3892
8f1928b41f45
matroska: subtitle display duration must be stored in pkt->convergence_duration
aurel
parents:
3786
diff
changeset
|
1762 pkt->convergence_duration = duration; |
3952
9808dea139a1
matroskadec: set duration only for CODEC_ID_TEXT subtitles
aurel
parents:
3951
diff
changeset
|
1763 else if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE) |
3892
8f1928b41f45
matroska: subtitle display duration must be stored in pkt->convergence_duration
aurel
parents:
3786
diff
changeset
|
1764 pkt->duration = duration; |
2657 | 1765 |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
1766 if (st->codec->codec_id == CODEC_ID_SSA) |
3951
9315ab7b1c0d
matroskadec: pass duration as parameter of matroska_fix_ass_packet()
aurel
parents:
3922
diff
changeset
|
1767 matroska_fix_ass_packet(matroska, pkt, duration); |
3894
30c8c9f53b9d
matroskadec: fix ASS subtitle track packets before emitting them
aurel
parents:
3892
diff
changeset
|
1768 |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1769 if (matroska->prev_pkt && |
3971
eed7b7cb02a9
matroskadec: don't merge packets which have no timestamp
aurel
parents:
3954
diff
changeset
|
1770 timecode != AV_NOPTS_VALUE && |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1771 matroska->prev_pkt->pts == timecode && |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1772 matroska->prev_pkt->stream_index == st->index) |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1773 matroska_merge_packets(matroska->prev_pkt, pkt); |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1774 else { |
3972 | 1775 dynarray_add(&matroska->packets,&matroska->num_packets,pkt); |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1776 matroska->prev_pkt = pkt; |
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1777 } |
2657 | 1778 } |
1779 | |
1780 if (timecode != AV_NOPTS_VALUE) | |
1781 timecode = duration ? timecode + duration : AV_NOPTS_VALUE; | |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1782 data += lace_size[n]; |
5762 | 1783 size -= lace_size[n]; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1784 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1785 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1786 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1787 av_free(lace_size); |
3899
5901b4ccda4a
matroskadec: remove now useless vstream and is_video_key_frame
aurel
parents:
3898
diff
changeset
|
1788 return res; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1789 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1790 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1791 static int matroska_parse_cluster(MatroskaDemuxContext *matroska) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1792 { |
3653 | 1793 MatroskaCluster cluster = { 0 }; |
1794 EbmlList *blocks_list; | |
1795 MatroskaBlock *blocks; | |
3897
5aa1cbbd79e0
matroskadec: ensure that the timecode added to the index are is the one
aurel
parents:
3894
diff
changeset
|
1796 int i, res; |
3973
549a09cf23fe
Remove offset_t typedef and use int64_t directly instead.
diego
parents:
3972
diff
changeset
|
1797 int64_t pos = url_ftell(matroska->ctx->pb); |
3954
0ebebd2ba034
matroskadec: merge ASS events which share the same pts in the same AVPavket
aurel
parents:
3953
diff
changeset
|
1798 matroska->prev_pkt = NULL; |
6124 | 1799 if (matroska->current_id) |
3773
2533332ca752
matroskadec: on the fly index construction for index-less files
aurel
parents:
3772
diff
changeset
|
1800 pos -= 4; /* sizeof the ID which was already read */ |
3680
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1801 res = ebml_parse(matroska, matroska_clusters, &cluster); |
3653 | 1802 blocks_list = &cluster.blocks; |
1803 blocks = blocks_list->elem; | |
3713
b337fe64a31f
matroskadec: parse available blocks even when cluster parsing failed
aurel
parents:
3702
diff
changeset
|
1804 for (i=0; i<blocks_list->nb_elem; i++) |
6058 | 1805 if (blocks[i].bin.size > 0 && blocks[i].bin.data) { |
5128
2397bd089f70
matroskadec: correctly parse flags for simpleblock frames
aurel
parents:
5058
diff
changeset
|
1806 int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1; |
3653 | 1807 res=matroska_parse_block(matroska, |
1808 blocks[i].bin.data, blocks[i].bin.size, | |
1809 blocks[i].bin.pos, cluster.timecode, | |
5128
2397bd089f70
matroskadec: correctly parse flags for simpleblock frames
aurel
parents:
5058
diff
changeset
|
1810 blocks[i].duration, is_keyframe, |
3897
5aa1cbbd79e0
matroskadec: ensure that the timecode added to the index are is the one
aurel
parents:
3894
diff
changeset
|
1811 pos); |
5128
2397bd089f70
matroskadec: correctly parse flags for simpleblock frames
aurel
parents:
5058
diff
changeset
|
1812 } |
3653 | 1813 ebml_free(matroska_cluster, &cluster); |
3771
9e9dce9660e4
matroskadec: move setting of matroska->done inside matroska_parse_cluster()
aurel
parents:
3768
diff
changeset
|
1814 if (res < 0) matroska->done = 1; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1815 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1816 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1817 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1818 static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1819 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1820 MatroskaDemuxContext *matroska = s->priv_data; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1821 |
1899 | 1822 while (matroska_deliver_packet(matroska, pkt)) { |
1900 | 1823 if (matroska->done) |
4543
e7e7b9f7edf4
matroskadec: return AVERROR_EOF upon detection of end of file
aurel
parents:
4497
diff
changeset
|
1824 return AVERROR_EOF; |
3771
9e9dce9660e4
matroskadec: move setting of matroska->done inside matroska_parse_cluster()
aurel
parents:
3768
diff
changeset
|
1825 matroska_parse_cluster(matroska); |
1899 | 1826 } |
1827 | |
1828 return 0; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1829 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1830 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1831 static int matroska_read_seek(AVFormatContext *s, int stream_index, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1832 int64_t timestamp, int flags) |
2012 | 1833 { |
1834 MatroskaDemuxContext *matroska = s->priv_data; | |
3916
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1835 MatroskaTrack *tracks = matroska->tracks.elem; |
2012 | 1836 AVStream *st = s->streams[stream_index]; |
3916
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1837 int i, index, index_sub, index_min; |
2012 | 1838 |
3922
56dc585dcda4
matroskadec: simplify, first_timecode is already in the index
aurel
parents:
3921
diff
changeset
|
1839 if (!st->nb_index_entries) |
56dc585dcda4
matroskadec: simplify, first_timecode is already in the index
aurel
parents:
3921
diff
changeset
|
1840 return 0; |
56dc585dcda4
matroskadec: simplify, first_timecode is already in the index
aurel
parents:
3921
diff
changeset
|
1841 timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); |
3772
7814581e98ff
matroskadec: don't try to seek to negative timestamp
aurel
parents:
3771
diff
changeset
|
1842 |
3785
fd49d42b918f
matroskadec: seek to the last position known in the index before resorting to
aurel
parents:
3782
diff
changeset
|
1843 if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { |
3922
56dc585dcda4
matroskadec: simplify, first_timecode is already in the index
aurel
parents:
3921
diff
changeset
|
1844 url_fseek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET); |
3786 | 1845 while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { |
1846 matroska_clear_queue(matroska); | |
1847 if (matroska_parse_cluster(matroska) < 0) | |
1848 break; | |
1849 } | |
3785
fd49d42b918f
matroskadec: seek to the last position known in the index before resorting to
aurel
parents:
3782
diff
changeset
|
1850 } |
3774
fa5cc40e0164
matroskadec: full seeking support in index-less files
aurel
parents:
3773
diff
changeset
|
1851 |
fa5cc40e0164
matroskadec: full seeking support in index-less files
aurel
parents:
3773
diff
changeset
|
1852 matroska_clear_queue(matroska); |
2012 | 1853 if (index < 0) |
1854 return 0; | |
1855 | |
3916
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1856 index_min = index; |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1857 for (i=0; i < matroska->tracks.nb_elem; i++) { |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1858 tracks[i].end_timecode = 0; |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1859 if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1860 && !tracks[i].stream->discard != AVDISCARD_ALL) { |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1861 index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD); |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1862 if (index_sub >= 0 |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1863 && st->index_entries[index_sub].pos < st->index_entries[index_min].pos |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1864 && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale) |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1865 index_min = index_sub; |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1866 } |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1867 } |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1868 |
4a7174c2b34e
matroskadec: demux relevant subtitle packets after a seek
aurel
parents:
3915
diff
changeset
|
1869 url_fseek(s->pb, st->index_entries[index_min].pos, SEEK_SET); |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1870 matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY); |
3914
f7a20cf5438f
matroskadec: after seeking, skip up to the desired timestamp instead of
aurel
parents:
3913
diff
changeset
|
1871 matroska->skip_to_timecode = st->index_entries[index].timestamp; |
3775 | 1872 matroska->done = 0; |
3462 | 1873 av_update_cur_dts(s, st, st->index_entries[index].timestamp); |
2012 | 1874 return 0; |
1875 } | |
1876 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1877 static int matroska_read_close(AVFormatContext *s) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1878 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1879 MatroskaDemuxContext *matroska = s->priv_data; |
3642 | 1880 MatroskaTrack *tracks = matroska->tracks.elem; |
3656 | 1881 int n; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1882 |
2871
b2f261fccb0b
move internal queue freeing code in its own function
aurel
parents:
2870
diff
changeset
|
1883 matroska_clear_queue(matroska); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1884 |
3642 | 1885 for (n=0; n < matroska->tracks.nb_elem; n++) |
1886 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) | |
1887 av_free(tracks[n].audio.buf); | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1888 ebml_free(matroska_segment, matroska); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1889 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1890 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1891 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1892 |
1169 | 1893 AVInputFormat matroska_demuxer = { |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1894 "matroska", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3422
diff
changeset
|
1895 NULL_IF_CONFIG_SMALL("Matroska file format"), |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1896 sizeof(MatroskaDemuxContext), |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1897 matroska_probe, |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1898 matroska_read_header, |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1899 matroska_read_packet, |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1900 matroska_read_close, |
2012 | 1901 matroska_read_seek, |
4618
5b9eddbee9c4
Add some basic metadata conversion tables for matroska and asf.
aurel
parents:
4543
diff
changeset
|
1902 .metadata_conv = ff_mkv_metadata_conv, |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1903 }; |