Mercurial > libavformat.hg
annotate matroskadec.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | 6b469866ffda |
children | 27537074f2a9 |
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 /** |
2175
9438e2e7faf2
Fix @file in matroskadec.c, it was still matroska.c
reimar
parents:
2147
diff
changeset
|
23 * @file matroskadec.c |
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 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
31 #include "avformat.h" |
1897
abbc781d608a
use codec_get_id() instead of deprecated codec_get_[bmp/wav]_id()
aurel
parents:
1832
diff
changeset
|
32 /* For codec_get_id(). */ |
1172
6a5e58d2114b
move common stuff from avienc.c and wav.c to new file riff.c
mru
parents:
1169
diff
changeset
|
33 #include "riff.h" |
3601 | 34 #include "isom.h" |
2142
3aa1f0f698de
split some common code from the mkv demuxer that will be useful to the muxer
aurel
parents:
2023
diff
changeset
|
35 #include "matroska.h" |
3201 | 36 #include "libavcodec/mpeg4audio.h" |
3286 | 37 #include "libavutil/intfloat_readwrite.h" |
3628
5f2e1da55755
matroskadec: use more robust av_strlcpy() instead of strcpy()
aurel
parents:
3601
diff
changeset
|
38 #include "libavutil/avstring.h" |
3281 | 39 #include "libavutil/lzo.h" |
3293 | 40 #ifdef CONFIG_ZLIB |
41 #include <zlib.h> | |
42 #endif | |
3298
edabe3db2b6e
matroskadec: add support for bzlib compressed tracks
aurel
parents:
3294
diff
changeset
|
43 #ifdef CONFIG_BZLIB |
edabe3db2b6e
matroskadec: add support for bzlib compressed tracks
aurel
parents:
3294
diff
changeset
|
44 #include <bzlib.h> |
edabe3db2b6e
matroskadec: add support for bzlib compressed tracks
aurel
parents:
3294
diff
changeset
|
45 #endif |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
46 |
3632 | 47 typedef enum { |
48 EBML_NONE, | |
49 EBML_UINT, | |
50 EBML_FLOAT, | |
51 EBML_STR, | |
52 EBML_UTF8, | |
53 EBML_BIN, | |
54 EBML_NEST, | |
55 EBML_PASS, | |
56 EBML_STOP, | |
57 } EbmlType; | |
58 | |
59 typedef const struct EbmlSyntax { | |
60 uint32_t id; | |
61 EbmlType type; | |
62 int list_elem_size; | |
63 int data_offset; | |
64 union { | |
65 uint64_t u; | |
66 double f; | |
67 const char *s; | |
68 const struct EbmlSyntax *n; | |
69 } def; | |
70 } EbmlSyntax; | |
71 | |
72 typedef struct { | |
73 int nb_elem; | |
74 void *elem; | |
75 } EbmlList; | |
76 | |
77 typedef struct { | |
78 int size; | |
79 uint8_t *data; | |
80 int64_t pos; | |
81 } EbmlBin; | |
82 | |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
83 typedef struct { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
84 uint64_t version; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
85 uint64_t max_size; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
86 uint64_t id_length; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
87 char *doctype; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
88 uint64_t doctype_version; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
89 } Ebml; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
90 |
3642 | 91 typedef struct { |
92 uint64_t algo; | |
93 EbmlBin settings; | |
94 } MatroskaTrackCompression; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
95 |
3642 | 96 typedef struct { |
97 uint64_t scope; | |
98 uint64_t type; | |
99 MatroskaTrackCompression compression; | |
100 } MatroskaTrackEncoding; | |
101 | |
102 typedef struct { | |
103 double frame_rate; | |
104 uint64_t display_width; | |
105 uint64_t display_height; | |
106 uint64_t pixel_width; | |
107 uint64_t pixel_height; | |
108 uint64_t fourcc; | |
109 } MatroskaTrackVideo; | |
2147 | 110 |
3642 | 111 typedef struct { |
112 double samplerate; | |
113 double out_samplerate; | |
114 uint64_t bitdepth; | |
115 uint64_t channels; | |
2147 | 116 |
3642 | 117 /* real audio header (extracted from extradata) */ |
118 int coded_framesize; | |
119 int sub_packet_h; | |
120 int frame_size; | |
121 int sub_packet_size; | |
122 int sub_packet_cnt; | |
123 int pkt_cnt; | |
124 uint8_t *buf; | |
125 } MatroskaTrackAudio; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
126 |
3642 | 127 typedef struct { |
128 uint64_t num; | |
129 uint64_t type; | |
130 char *codec_id; | |
131 EbmlBin codec_priv; | |
132 char *language; | |
3408
da09478c97ce
matroskadec: read TrackTimecodeScale and set timebase accordingly
aurel
parents:
3407
diff
changeset
|
133 double time_scale; |
1912 | 134 uint64_t default_duration; |
3630 | 135 uint64_t flag_default; |
3642 | 136 MatroskaTrackVideo video; |
137 MatroskaTrackAudio audio; | |
138 EbmlList encodings; | |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
139 |
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
140 AVStream *stream; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
141 } MatroskaTrack; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
142 |
3637 | 143 typedef struct { |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
144 char *filename; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
145 char *mime; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
146 EbmlBin bin; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
147 } MatroskaAttachement; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
148 |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
149 typedef struct { |
3639 | 150 uint64_t start; |
151 uint64_t end; | |
152 uint64_t uid; | |
153 char *title; | |
154 } MatroskaChapter; | |
155 | |
156 typedef struct { | |
3637 | 157 uint64_t track; |
158 uint64_t pos; | |
159 } MatroskaIndexPos; | |
160 | |
161 typedef struct { | |
162 uint64_t time; | |
163 EbmlList pos; | |
164 } MatroskaIndex; | |
165 | |
3644 | 166 typedef struct { |
3702 | 167 char *name; |
168 char *string; | |
169 EbmlList sub; | |
170 } MatroskaTag; | |
171 | |
172 typedef struct { | |
3644 | 173 uint64_t id; |
174 uint64_t pos; | |
175 } MatroskaSeekhead; | |
176 | |
3658 | 177 typedef struct { |
2147 | 178 uint64_t start; |
179 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
|
180 } MatroskaLevel; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
181 |
3658 | 182 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
|
183 AVFormatContext *ctx; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
184 |
3692 | 185 /* 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
|
186 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
|
187 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
|
188 int level_up; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
189 |
3641 | 190 uint64_t time_scale; |
191 double duration; | |
192 char *title; | |
3642 | 193 EbmlList tracks; |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
194 EbmlList attachments; |
3639 | 195 EbmlList chapters; |
3637 | 196 EbmlList index; |
3702 | 197 EbmlList tags; |
3644 | 198 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
|
199 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
200 /* byte position of the segment inside the stream */ |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
201 offset_t segment_start; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
202 |
3692 | 203 /* 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
|
204 AVPacket **packets; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
205 int num_packets; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
206 |
2147 | 207 int done; |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
208 int has_cluster_id; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
209 |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
210 /* 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
|
211 int skip_to_keyframe; |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
212 AVStream *skip_to_stream; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
213 } MatroskaDemuxContext; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
214 |
3653 | 215 typedef struct { |
216 uint64_t duration; | |
217 int64_t reference; | |
218 EbmlBin bin; | |
219 } MatroskaBlock; | |
220 | |
221 typedef struct { | |
222 uint64_t timecode; | |
223 EbmlList blocks; | |
224 } MatroskaCluster; | |
225 | |
3413
b7f86452706e
matroskadec: move ARRAY_SIZE() macro at top of the file
aurel
parents:
3409
diff
changeset
|
226 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) |
b7f86452706e
matroskadec: move ARRAY_SIZE() macro at top of the file
aurel
parents:
3409
diff
changeset
|
227 |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
228 static EbmlSyntax ebml_header[] = { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
229 { 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
|
230 { 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
|
231 { 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
|
232 { 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
|
233 { 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
|
234 { EBML_ID_EBMLVERSION, EBML_NONE }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
235 { EBML_ID_DOCTYPEVERSION, EBML_NONE }, |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
236 { 0 } |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
237 }; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
238 |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
239 static EbmlSyntax ebml_syntax[] = { |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
240 { 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
|
241 { 0 } |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
242 }; |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
243 |
3641 | 244 static EbmlSyntax matroska_info[] = { |
245 { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext,time_scale), {.u=1000000} }, | |
246 { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext,duration) }, | |
247 { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) }, | |
248 { MATROSKA_ID_WRITINGAPP, EBML_NONE }, | |
249 { MATROSKA_ID_MUXINGAPP, EBML_NONE }, | |
250 { MATROSKA_ID_DATEUTC, EBML_NONE }, | |
251 { MATROSKA_ID_SEGMENTUID, EBML_NONE }, | |
252 { 0 } | |
253 }; | |
254 | |
3642 | 255 static EbmlSyntax matroska_track_video[] = { |
256 { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT,0, offsetof(MatroskaTrackVideo,frame_rate) }, | |
257 { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_width) }, | |
258 { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) }, | |
259 { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) }, | |
260 { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) }, | |
261 { 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
|
262 { 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
|
263 { 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
|
264 { 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
|
265 { 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
|
266 { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, |
3642 | 267 { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE }, |
268 { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE }, | |
269 { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, | |
270 { 0 } | |
271 }; | |
272 | |
273 static EbmlSyntax matroska_track_audio[] = { | |
274 { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT,0, offsetof(MatroskaTrackAudio,samplerate), {.f=8000.0} }, | |
275 { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ,EBML_FLOAT,0,offsetof(MatroskaTrackAudio,out_samplerate) }, | |
276 { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio,bitdepth) }, | |
277 { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio,channels), {.u=1} }, | |
278 { 0 } | |
279 }; | |
280 | |
281 static EbmlSyntax matroska_track_encoding_compression[] = { | |
282 { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression,algo), {.u=0} }, | |
283 { MATROSKA_ID_ENCODINGCOMPSETTINGS,EBML_BIN, 0, offsetof(MatroskaTrackCompression,settings) }, | |
284 { 0 } | |
285 }; | |
286 | |
287 static EbmlSyntax matroska_track_encoding[] = { | |
288 { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} }, | |
289 { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} }, | |
290 { 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
|
291 { MATROSKA_ID_ENCODINGORDER, EBML_NONE }, |
3642 | 292 { 0 } |
293 }; | |
294 | |
295 static EbmlSyntax matroska_track_encodings[] = { | |
296 { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack,encodings), {.n=matroska_track_encoding} }, | |
297 { 0 } | |
298 }; | |
299 | |
300 static EbmlSyntax matroska_track[] = { | |
301 { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) }, | |
302 { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack,type) }, | |
303 { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack,codec_id) }, | |
304 { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack,codec_priv) }, | |
305 { MATROSKA_ID_TRACKLANGUAGE, EBML_UTF8, 0, offsetof(MatroskaTrack,language), {.s="eng"} }, | |
306 { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) }, | |
307 { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} }, | |
308 { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} }, | |
309 { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} }, | |
310 { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} }, | |
311 { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} }, | |
312 { MATROSKA_ID_TRACKUID, EBML_NONE }, | |
313 { MATROSKA_ID_TRACKNAME, EBML_NONE }, | |
314 { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, | |
315 { MATROSKA_ID_TRACKFLAGFORCED, EBML_NONE }, | |
316 { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, | |
317 { MATROSKA_ID_CODECNAME, EBML_NONE }, | |
318 { MATROSKA_ID_CODECDECODEALL, EBML_NONE }, | |
319 { MATROSKA_ID_CODECINFOURL, EBML_NONE }, | |
320 { MATROSKA_ID_CODECDOWNLOADURL, EBML_NONE }, | |
321 { MATROSKA_ID_TRACKMINCACHE, EBML_NONE }, | |
322 { 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
|
323 { MATROSKA_ID_TRACKMAXBLKADDID, EBML_NONE }, |
3642 | 324 { 0 } |
325 }; | |
326 | |
327 static EbmlSyntax matroska_tracks[] = { | |
328 { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext,tracks), {.n=matroska_track} }, | |
329 { 0 } | |
330 }; | |
331 | |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
332 static EbmlSyntax matroska_attachment[] = { |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
333 { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
334 { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachement,mime) }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
335 { 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
|
336 { MATROSKA_ID_FILEDESC, EBML_NONE }, |
3640
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
337 { MATROSKA_ID_FILEUID, EBML_NONE }, |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
338 { 0 } |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
339 }; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
340 |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
341 static EbmlSyntax matroska_attachments[] = { |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
342 { 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
|
343 { 0 } |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
344 }; |
122a7c807f80
matroskadec: use generic parser to parse attachments
aurel
parents:
3639
diff
changeset
|
345 |
3639 | 346 static EbmlSyntax matroska_chapter_display[] = { |
347 { 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
|
348 { MATROSKA_ID_CHAPLANG, EBML_NONE }, |
3639 | 349 { 0 } |
350 }; | |
351 | |
352 static EbmlSyntax matroska_chapter_entry[] = { | |
353 { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} }, | |
354 { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} }, | |
355 { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) }, | |
356 { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} }, | |
357 { 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
|
358 { 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
|
359 { 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
|
360 { MATROSKA_ID_CHAPTERATOM, EBML_NONE }, |
3639 | 361 { 0 } |
362 }; | |
363 | |
364 static EbmlSyntax matroska_chapter[] = { | |
365 { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} }, | |
366 { MATROSKA_ID_EDITIONUID, EBML_NONE }, | |
367 { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, | |
368 { 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
|
369 { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE }, |
3639 | 370 { 0 } |
371 }; | |
372 | |
373 static EbmlSyntax matroska_chapters[] = { | |
374 { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} }, | |
375 { 0 } | |
376 }; | |
377 | |
3637 | 378 static EbmlSyntax matroska_index_pos[] = { |
379 { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) }, | |
380 { 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
|
381 { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE }, |
3637 | 382 { 0 } |
383 }; | |
384 | |
385 static EbmlSyntax matroska_index_entry[] = { | |
386 { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex,time) }, | |
387 { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex,pos), {.n=matroska_index_pos} }, | |
388 { 0 } | |
389 }; | |
390 | |
391 static EbmlSyntax matroska_index[] = { | |
392 { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, | |
393 { 0 } | |
394 }; | |
395 | |
3702 | 396 static EbmlSyntax matroska_simpletag[] = { |
397 { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) }, | |
398 { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) }, | |
399 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} }, | |
400 { MATROSKA_ID_TAGLANG, EBML_NONE }, | |
401 { MATROSKA_ID_TAGDEFAULT, EBML_NONE }, | |
402 { 0 } | |
403 }; | |
404 | |
405 static EbmlSyntax matroska_tag[] = { | |
406 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), 0, {.n=matroska_simpletag} }, | |
407 { MATROSKA_ID_TAGTARGETS, EBML_NONE }, | |
408 { 0 } | |
409 }; | |
410 | |
3638 | 411 static EbmlSyntax matroska_tags[] = { |
3702 | 412 { MATROSKA_ID_TAG, EBML_NEST, 0, offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} }, |
3638 | 413 { 0 } |
414 }; | |
415 | |
3644 | 416 static EbmlSyntax matroska_seekhead_entry[] = { |
417 { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead,id) }, | |
418 { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead,pos), {.u=-1} }, | |
419 { 0 } | |
420 }; | |
421 | |
422 static EbmlSyntax matroska_seekhead[] = { | |
423 { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext,seekhead), {.n=matroska_seekhead_entry} }, | |
424 { 0 } | |
425 }; | |
426 | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
427 static EbmlSyntax matroska_segment[] = { |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
428 { 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
|
429 { 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
|
430 { 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
|
431 { 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
|
432 { 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
|
433 { 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
|
434 { MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
435 { MATROSKA_ID_CLUSTER, EBML_STOP, 0, offsetof(MatroskaDemuxContext,has_cluster_id) }, |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
436 { 0 } |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
437 }; |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
438 |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
439 static EbmlSyntax matroska_segments[] = { |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
440 { 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
|
441 { 0 } |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
442 }; |
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
443 |
3653 | 444 static EbmlSyntax matroska_blockgroup[] = { |
445 { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, | |
446 { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, | |
447 { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} }, | |
448 { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) }, | |
449 { 0 } | |
450 }; | |
451 | |
452 static EbmlSyntax matroska_cluster[] = { | |
453 { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, | |
454 { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, | |
455 { 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
|
456 { 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
|
457 { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, |
3653 | 458 { 0 } |
459 }; | |
460 | |
461 static EbmlSyntax matroska_clusters[] = { | |
462 { 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
|
463 { 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
|
464 { 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
|
465 { 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
|
466 { MATROSKA_ID_SEEKHEAD, EBML_NONE }, |
3653 | 467 { 0 } |
468 }; | |
469 | |
3702 | 470 #define SIZE_OFF(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x) |
471 const struct { | |
472 const char name[16]; | |
473 int size; | |
474 int offset; | |
475 } metadata[] = { | |
476 { "TITLE", SIZE_OFF(title) }, | |
477 { "ARTIST", SIZE_OFF(author) }, | |
478 { "WRITTEN_BY", SIZE_OFF(author) }, | |
479 { "LEAD_PERFORMER", SIZE_OFF(author) }, | |
480 { "COPYRIGHT", SIZE_OFF(copyright) }, | |
481 { "COMMENT", SIZE_OFF(comment) }, | |
482 { "ALBUM", SIZE_OFF(album) }, | |
483 { "DATE_WRITTEN", SIZE_OFF(year) }, | |
484 { "DATE_RELEASED", SIZE_OFF(year) }, | |
485 { "PART_NUMBER", SIZE_OFF(track) }, | |
486 { "GENRE", SIZE_OFF(genre) }, | |
487 }; | |
488 | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
489 /* |
3692 | 490 * 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
|
491 */ |
3674 | 492 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
|
493 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2657
diff
changeset
|
494 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
|
495 offset_t pos = 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
|
496 |
3674 | 497 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
|
498 MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; |
3674 | 499 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
|
500 matroska->num_levels--; |
3674 | 501 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
|
502 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
503 } |
3674 | 504 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
|
505 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
506 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
507 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
508 * 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
|
509 * 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
|
510 * 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
|
511 * "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
|
512 * number. |
3692 | 513 * 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
|
514 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
515 static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb, |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
516 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
|
517 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
518 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
|
519 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
|
520 |
3692 | 521 /* 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
|
522 * 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
|
523 * 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
|
524 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
|
525 /* 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
|
526 if (!url_feof(pb)) { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
527 offset_t pos = 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
|
528 av_log(matroska->ctx, AV_LOG_ERROR, |
881 | 529 "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
|
530 pos, pos); |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
531 } |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
532 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
|
533 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
534 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
535 /* 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
|
536 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
|
537 read++; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
538 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
|
539 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
540 if (read > max_size) { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
541 offset_t pos = url_ftell(pb) - 1; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
542 av_log(matroska->ctx, AV_LOG_ERROR, |
881 | 543 "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
|
544 (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
|
545 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
|
546 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
547 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
548 /* 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
|
549 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
|
550 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
|
551 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
|
552 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
553 *number = total; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
554 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
555 return read; |
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 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
558 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
559 * 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
|
560 * 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
|
561 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
562 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
|
563 { |
3670
04b4e89c09d6
matroskadec: extract common code out of ebml_read_*()
aurel
parents:
3669
diff
changeset
|
564 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
|
565 |
3669
836de2dd2615
matroskadec: simplify/cleanup error logging in ebml_read_*()
aurel
parents:
3668
diff
changeset
|
566 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
|
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 |
3692 | 569 /* 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
|
570 *num = 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
571 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
|
572 *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
|
573 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
574 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
575 } |
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 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
578 * 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
|
579 * 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
|
580 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
581 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
|
582 { |
824 | 583 if (size == 4) { |
584 *num= av_int2flt(get_be32(pb)); | |
585 } else if(size==8){ | |
586 *num= av_int2dbl(get_be64(pb)); | |
3669
836de2dd2615
matroskadec: simplify/cleanup error logging in ebml_read_*()
aurel
parents:
3668
diff
changeset
|
587 } else |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
588 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
|
589 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
590 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
591 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
592 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
593 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
594 * 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
|
595 * 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
|
596 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
597 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
|
598 { |
3670
04b4e89c09d6
matroskadec: extract common code out of ebml_read_*()
aurel
parents:
3669
diff
changeset
|
599 av_free(*str); |
3692 | 600 /* 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
|
601 * 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
|
602 if (!(*str = av_malloc(size + 1))) |
2273
7eb456c4ed8a
Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents:
2264
diff
changeset
|
603 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
|
604 if (get_buffer(pb, (uint8_t *) *str, size) != size) { |
3416 | 605 av_free(*str); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
606 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
|
607 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
608 (*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
|
609 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
610 return 0; |
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 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
613 /* |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
614 * Read the next element as binary data. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
615 * 0 is success, < 0 is failure. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
616 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
617 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
|
618 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
619 av_free(bin->data); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
620 if (!(bin->data = av_malloc(length))) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
621 return AVERROR(ENOMEM); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
622 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
623 bin->size = length; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
624 bin->pos = url_ftell(pb); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
625 if (get_buffer(pb, bin->data, length) != length) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
626 return AVERROR(EIO); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
627 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
628 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
629 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
630 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
631 /* |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
632 * 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
|
633 * 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
|
634 * 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
|
635 */ |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
636 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
|
637 { |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2657
diff
changeset
|
638 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
|
639 MatroskaLevel *level; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
640 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
641 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
|
642 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
|
643 "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
|
644 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
|
645 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
646 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
647 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
|
648 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
|
649 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
|
650 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
651 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
652 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
653 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
654 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
655 * Read signed/unsigned "EBML" numbers. |
3692 | 656 * 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
|
657 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
658 static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska, |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
659 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
|
660 { |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
661 ByteIOContext pb; |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
662 init_put_byte(&pb, data, size, 0, NULL, NULL, NULL, NULL); |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
663 return ebml_read_num(matroska, &pb, 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
|
664 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
665 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
666 /* |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
667 * 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
|
668 */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
669 static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska, |
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
670 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
|
671 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
672 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
|
673 int res; |
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 /* read as unsigned number first */ |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
676 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
|
677 return res; |
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 /* make signed (weird way) */ |
3689 | 680 *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
|
681 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
682 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
683 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
684 |
3632 | 685 static int ebml_parse_elem(MatroskaDemuxContext *matroska, |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
686 EbmlSyntax *syntax, void *data); |
3632 | 687 |
688 static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, | |
689 uint32_t id, void *data) | |
690 { | |
691 int i; | |
692 for (i=0; syntax[i].id; i++) | |
693 if (id == syntax[i].id) | |
694 break; | |
3745
47807c439186
matroskadec: handle EBML_ID_VOID and EBML_ID_CRC32 in a generic way
aurel
parents:
3717
diff
changeset
|
695 if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) |
3632 | 696 av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id); |
697 return ebml_parse_elem(matroska, &syntax[i], data); | |
698 } | |
699 | |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
700 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
|
701 void *data) |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
702 { |
3690
50c074bc02b4
matroskadec: expand useless ebml_read_element_id() wrapper
aurel
parents:
3689
diff
changeset
|
703 uint64_t id; |
50c074bc02b4
matroskadec: expand useless ebml_read_element_id() wrapper
aurel
parents:
3689
diff
changeset
|
704 int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id); |
50c074bc02b4
matroskadec: expand useless ebml_read_element_id() wrapper
aurel
parents:
3689
diff
changeset
|
705 id |= 1 << 7*res; |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
706 return res < 0 ? res : ebml_parse_id(matroska, syntax, id, data); |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
707 } |
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
708 |
3676
d2ff1b7ad060
matroskadec: rename ebml_parse() to ebml_parse_nest()
aurel
parents:
3675
diff
changeset
|
709 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
|
710 void *data) |
3632 | 711 { |
3675
736c7c66234a
matroskadec: don't care about the number of bytes read by ebml_read_element_id()
aurel
parents:
3674
diff
changeset
|
712 int i, res = 0; |
3632 | 713 |
714 for (i=0; syntax[i].id; i++) | |
715 switch (syntax[i].type) { | |
716 case EBML_UINT: | |
717 *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u; | |
718 break; | |
719 case EBML_FLOAT: | |
720 *(double *)((char *)data+syntax[i].data_offset) = syntax[i].def.f; | |
721 break; | |
722 case EBML_STR: | |
723 case EBML_UTF8: | |
724 *(char **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s); | |
725 break; | |
726 } | |
727 | |
3679
039a28684d43
matroskadec: remove now unused parameter 'once' from ebml_parse_nest()
aurel
parents:
3678
diff
changeset
|
728 while (!res && !ebml_level_end(matroska)) |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
729 res = ebml_parse(matroska, syntax, data); |
3632 | 730 |
731 return res; | |
732 } | |
733 | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
734 static int ebml_parse_elem(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
735 EbmlSyntax *syntax, void *data) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
736 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
737 ByteIOContext *pb = matroska->ctx->pb; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
738 uint32_t id = syntax->id; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
739 uint64_t length; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
740 int res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
741 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
742 data = (char *)data + syntax->data_offset; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
743 if (syntax->list_elem_size) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
744 EbmlList *list = data; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
745 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
|
746 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
|
747 memset(data, 0, syntax->list_elem_size); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
748 list->nb_elem++; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
749 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
750 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
751 if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
752 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
|
753 return res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
754 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
755 switch (syntax->type) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
756 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
|
757 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
|
758 case EBML_STR: |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
759 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
|
760 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
|
761 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
|
762 return res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
763 if (id == MATROSKA_ID_SEGMENT) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
764 matroska->segment_start = url_ftell(matroska->ctx->pb); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
765 return ebml_parse_nest(matroska, syntax->def.n, data); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
766 case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
767 case EBML_STOP: *(int *)data = 1; return 1; |
3747
b8f428926617
matroskadec: stop parsing when skipping en element crossing over the end of file
aurel
parents:
3746
diff
changeset
|
768 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
|
769 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
770 if (res == AVERROR_INVALIDDATA) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
771 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
|
772 else if (res == AVERROR(EIO)) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
773 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
|
774 return res; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
775 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
776 |
3632 | 777 static void ebml_free(EbmlSyntax *syntax, void *data) |
778 { | |
779 int i, j; | |
780 for (i=0; syntax[i].id; i++) { | |
781 void *data_off = (char *)data + syntax[i].data_offset; | |
782 switch (syntax[i].type) { | |
783 case EBML_STR: | |
784 case EBML_UTF8: av_freep(data_off); break; | |
785 case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break; | |
786 case EBML_NEST: | |
787 if (syntax[i].list_elem_size) { | |
788 EbmlList *list = data_off; | |
789 char *ptr = list->elem; | |
790 for (j=0; j<list->nb_elem; j++, ptr+=syntax[i].list_elem_size) | |
791 ebml_free(syntax[i].def.n, ptr); | |
792 av_free(list->elem); | |
793 } else | |
794 ebml_free(syntax[i].def.n, data_off); | |
795 default: break; | |
796 } | |
797 } | |
798 } | |
799 | |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
800 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
801 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
802 * Autodetecting... |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
803 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
804 static int matroska_probe(AVProbeData *p) |
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 uint64_t total = 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
807 int len_mask = 0x80, size = 1, n = 1; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
808 char probe_data[] = "matroska"; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
809 |
3692 | 810 /* EBML header? */ |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
811 if (AV_RB32(p->buf) != EBML_ID_HEADER) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
812 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
813 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
814 /* length of header */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
815 total = p->buf[4]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
816 while (size <= 8 && !(total & len_mask)) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
817 size++; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
818 len_mask >>= 1; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
819 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
820 if (size > 8) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
821 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
822 total &= (len_mask - 1); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
823 while (n < size) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
824 total = (total << 8) | p->buf[4 + n++]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
825 |
3692 | 826 /* Does the probe data contain the whole header? */ |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
827 if (p->buf_size < 4 + size + total) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
828 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
829 |
3692 | 830 /* The header must contain the document type 'matroska'. For now, |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
831 * 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
|
832 * availability of that array of characters inside the header. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
833 * Not fully fool-proof, but good enough. */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
834 for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
835 if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1)) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
836 return AVPROBE_SCORE_MAX; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
837 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
838 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
839 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
840 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
841 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
842 int num) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
843 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
844 MatroskaTrack *tracks = matroska->tracks.elem; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
845 int i; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
846 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
847 for (i=0; i < matroska->tracks.nb_elem; i++) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
848 if (tracks[i].num == num) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
849 return &tracks[i]; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
850 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
851 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
|
852 return NULL; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
853 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
854 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
855 static int matroska_decode_buffer(uint8_t** buf, int* buf_size, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
856 MatroskaTrack *track) |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
857 { |
3642 | 858 MatroskaTrackEncoding *encodings = track->encodings.elem; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
859 uint8_t* data = *buf; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
860 int isize = *buf_size; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
861 uint8_t* pkt_data = NULL; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
862 int pkt_size = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
863 int result = 0; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
864 int olen; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
865 |
3642 | 866 switch (encodings[0].compression.algo) { |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
867 case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: |
3642 | 868 return encodings[0].compression.settings.size; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
869 case MATROSKA_TRACK_ENCODING_COMP_LZO: |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
870 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
871 olen = pkt_size *= 3; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
872 pkt_data = av_realloc(pkt_data, |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
873 pkt_size+LZO_OUTPUT_PADDING); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
874 result = lzo1x_decode(pkt_data, &olen, data, &isize); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
875 } while (result==LZO_OUTPUT_FULL && pkt_size<10000000); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
876 if (result) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
877 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
878 pkt_size -= olen; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
879 break; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
880 #ifdef CONFIG_ZLIB |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
881 case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
882 z_stream zstream = {0}; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
883 if (inflateInit(&zstream) != Z_OK) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
884 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
885 zstream.next_in = data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
886 zstream.avail_in = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
887 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
888 pkt_size *= 3; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
889 pkt_data = av_realloc(pkt_data, pkt_size); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
890 zstream.avail_out = pkt_size - zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
891 zstream.next_out = pkt_data + zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
892 result = inflate(&zstream, Z_NO_FLUSH); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
893 } while (result==Z_OK && pkt_size<10000000); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
894 pkt_size = zstream.total_out; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
895 inflateEnd(&zstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
896 if (result != Z_STREAM_END) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
897 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
898 break; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
899 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
900 #endif |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
901 #ifdef CONFIG_BZLIB |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
902 case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
903 bz_stream bzstream = {0}; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
904 if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
905 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
906 bzstream.next_in = data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
907 bzstream.avail_in = isize; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
908 do { |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
909 pkt_size *= 3; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
910 pkt_data = av_realloc(pkt_data, pkt_size); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
911 bzstream.avail_out = pkt_size - bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
912 bzstream.next_out = pkt_data + bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
913 result = BZ2_bzDecompress(&bzstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
914 } while (result==BZ_OK && pkt_size<10000000); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
915 pkt_size = bzstream.total_out_lo32; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
916 BZ2_bzDecompressEnd(&bzstream); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
917 if (result != BZ_STREAM_END) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
918 goto failed; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
919 break; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
920 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
921 #endif |
3748
6b469866ffda
matroskadec: fail cleanly when the required compression lib is not compiled in
aurel
parents:
3747
diff
changeset
|
922 default: |
6b469866ffda
matroskadec: fail cleanly when the required compression lib is not compiled in
aurel
parents:
3747
diff
changeset
|
923 return -1; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
924 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
925 |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
926 *buf = pkt_data; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
927 *buf_size = pkt_size; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
928 return 0; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
929 failed: |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
930 av_free(pkt_data); |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
931 return -1; |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
932 } |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
933 |
3702 | 934 static void matroska_convert_tags(AVFormatContext *s, EbmlList *list) |
935 { | |
936 MatroskaTag *tags = list->elem; | |
937 int i, j; | |
938 | |
939 for (i=0; i < list->nb_elem; i++) { | |
940 for (j=0; j < ARRAY_SIZE(metadata); j++){ | |
941 if (!strcmp(tags[i].name, metadata[j].name)) { | |
942 int *ptr = (int *)((char *)s + metadata[j].offset); | |
943 if (*ptr) continue; | |
944 if (metadata[j].size > sizeof(int)) | |
945 av_strlcpy((char *)ptr, tags[i].string, metadata[j].size); | |
946 else | |
947 *ptr = atoi(tags[i].string); | |
948 } | |
949 } | |
950 if (tags[i].sub.nb_elem) | |
951 matroska_convert_tags(s, &tags[i].sub); | |
952 } | |
953 } | |
954 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
955 static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) |
3644 | 956 { |
957 EbmlList *seekhead_list = &matroska->seekhead; | |
958 MatroskaSeekhead *seekhead = seekhead_list->elem; | |
959 uint32_t level_up = matroska->level_up; | |
960 offset_t before_pos = url_ftell(matroska->ctx->pb); | |
961 MatroskaLevel level; | |
3652
a22da874fc50
matroskadec: use generic parser inside matroska_execute_seekhead()
aurel
parents:
3651
diff
changeset
|
962 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
|
963 |
3644 | 964 for (i=0; i<seekhead_list->nb_elem; i++) { |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
965 offset_t offset = seekhead[i].pos + matroska->segment_start; |
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
966 |
3644 | 967 if (seekhead[i].pos <= before_pos |
968 || seekhead[i].id == MATROSKA_ID_SEEKHEAD | |
969 || seekhead[i].id == MATROSKA_ID_CLUSTER) | |
970 continue; | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
971 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
972 /* seek */ |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
973 if (url_fseek(matroska->ctx->pb, offset, SEEK_SET) != offset) |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
974 continue; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
975 |
3692 | 976 /* 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
|
977 * a dummy. This is a crude hack. */ |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
978 if (matroska->num_levels == EBML_MAX_DEPTH) { |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
979 av_log(matroska->ctx, AV_LOG_INFO, |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
980 "Max EBML element depth (%d) reached, " |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
981 "cannot parse further.\n", EBML_MAX_DEPTH); |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
982 break; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
983 } |
885 | 984 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
985 level.start = 0; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
986 level.length = (uint64_t)-1; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
987 matroska->levels[matroska->num_levels] = level; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
988 matroska->num_levels++; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
989 |
3677
0aed3a6e4e81
matroskadec: new ebml_parse() function, centralize ebml_read_element_id() calls
aurel
parents:
3676
diff
changeset
|
990 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
|
991 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
992 /* remove dummy level */ |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
993 while (matroska->num_levels) { |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
994 uint64_t length = matroska->levels[--matroska->num_levels].length; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
995 if (length == (uint64_t)-1) |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
996 break; |
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
997 } |
3644 | 998 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
999 |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1000 /* seek back */ |
3682
1332d68c8210
matroskadec: remove now useless wrapper ebml_read_seek()
aurel
parents:
3681
diff
changeset
|
1001 url_fseek(matroska->ctx->pb, before_pos, SEEK_SET); |
3646
370243aa26c0
matroskadec: cosmetics: indentation of matroska_execute_seekhead()
aurel
parents:
3645
diff
changeset
|
1002 matroska->level_up = level_up; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1003 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1004 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1005 static int matroska_aac_profile(char *codec_id) |
1468 | 1006 { |
3659 | 1007 static const char *aac_profiles[] = { "MAIN", "LC", "SSR" }; |
1468 | 1008 int profile; |
1009 | |
1010 for (profile=0; profile<ARRAY_SIZE(aac_profiles); profile++) | |
1011 if (strstr(codec_id, aac_profiles[profile])) | |
1012 break; | |
1013 return profile + 1; | |
1014 } | |
1015 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1016 static int matroska_aac_sri(int samplerate) |
1468 | 1017 { |
1018 int sri; | |
1019 | |
3201 | 1020 for (sri=0; sri<ARRAY_SIZE(ff_mpeg4audio_sample_rates); sri++) |
1021 if (ff_mpeg4audio_sample_rates[sri] == samplerate) | |
1468 | 1022 break; |
1023 return sri; | |
1024 } | |
1025 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1026 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
|
1027 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1028 MatroskaDemuxContext *matroska = s->priv_data; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1029 EbmlList *attachements_list = &matroska->attachments; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1030 MatroskaAttachement *attachements; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1031 EbmlList *chapters_list = &matroska->chapters; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1032 MatroskaChapter *chapters; |
3648 | 1033 MatroskaTrack *tracks; |
3637 | 1034 EbmlList *index_list; |
1035 MatroskaIndex *index; | |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1036 Ebml ebml = { 0 }; |
3648 | 1037 AVStream *st; |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1038 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
|
1039 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1040 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
|
1041 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1042 /* 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
|
1043 if (ebml_parse(matroska, ebml_syntax, &ebml) |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1044 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1045 || ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska") |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1046 || 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
|
1047 av_log(matroska->ctx, AV_LOG_ERROR, |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1048 "EBML header using unsupported features\n" |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1049 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", |
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1050 ebml.version, ebml.doctype, ebml.doctype_version); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1051 return AVERROR_NOFMT; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1052 } |
3633
7a44217312bb
matroskadec: use generic ebml parser to parse ebml header
aurel
parents:
3632
diff
changeset
|
1053 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
|
1054 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1055 /* 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
|
1056 if (ebml_parse(matroska, matroska_segments, matroska) < 0) |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1057 return -1; |
3644 | 1058 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
|
1059 |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1060 if (matroska->duration) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1061 matroska->ctx->duration = matroska->duration * matroska->time_scale |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1062 * 1000 / AV_TIME_BASE; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1063 if (matroska->title) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1064 strncpy(matroska->ctx->title, matroska->title, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1065 sizeof(matroska->ctx->title)-1); |
3702 | 1066 matroska_convert_tags(s, &matroska->tags); |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1067 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1068 tracks = matroska->tracks.elem; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1069 for (i=0; i < matroska->tracks.nb_elem; i++) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1070 MatroskaTrack *track = &tracks[i]; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1071 enum CodecID codec_id = CODEC_ID_NONE; |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1072 EbmlList *encodings_list = &tracks->encodings; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1073 MatroskaTrackEncoding *encodings = encodings_list->elem; |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1074 uint8_t *extradata = NULL; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1075 int extradata_size = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1076 int extradata_offset = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1077 |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1078 /* Apply some sanity checks. */ |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1079 if (track->type != MATROSKA_TRACK_TYPE_VIDEO && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1080 track->type != MATROSKA_TRACK_TYPE_AUDIO && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1081 track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1082 av_log(matroska->ctx, AV_LOG_INFO, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1083 "Unknown or unsupported track type %"PRIu64"\n", |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1084 track->type); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1085 continue; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1086 } |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1087 if (track->codec_id == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1088 continue; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1089 |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1090 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1091 if (!track->default_duration) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1092 track->default_duration = 1000000000/track->video.frame_rate; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1093 if (!track->video.display_width) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1094 track->video.display_width = track->video.pixel_width; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1095 if (!track->video.display_height) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1096 track->video.display_height = track->video.pixel_height; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1097 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1098 if (!track->audio.out_samplerate) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1099 track->audio.out_samplerate = track->audio.samplerate; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1100 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1101 if (encodings_list->nb_elem > 1) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1102 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1103 "Multiple combined encodings no supported"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1104 } else if (encodings_list->nb_elem == 1) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1105 if (encodings[0].type || |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1106 (encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1107 #ifdef CONFIG_ZLIB |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1108 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1109 #endif |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1110 #ifdef CONFIG_BZLIB |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1111 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1112 #endif |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1113 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO)) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1114 encodings[0].scope = 0; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1115 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1116 "Unsupported encoding type"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1117 } else if (track->codec_priv.size && encodings[0].scope&2) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1118 uint8_t *codec_priv = track->codec_priv.data; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1119 int offset = matroska_decode_buffer(&track->codec_priv.data, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1120 &track->codec_priv.size, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1121 track); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1122 if (offset < 0) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1123 track->codec_priv.data = NULL; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1124 track->codec_priv.size = 0; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1125 av_log(matroska->ctx, AV_LOG_ERROR, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1126 "Failed to decode codec private data\n"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1127 } else if (offset > 0) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1128 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
|
1129 memcpy(track->codec_priv.data, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1130 encodings[0].compression.settings.data, offset); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1131 memcpy(track->codec_priv.data+offset, codec_priv, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1132 track->codec_priv.size); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1133 track->codec_priv.size += offset; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1134 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1135 if (codec_priv != track->codec_priv.data) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1136 av_free(codec_priv); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1137 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1138 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1139 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1140 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
|
1141 if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1142 strlen(ff_mkv_codec_tags[j].str))){ |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1143 codec_id= ff_mkv_codec_tags[j].id; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1144 break; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1145 } |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1146 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1147 |
3691 | 1148 st = track->stream = av_new_stream(s, 0); |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1149 if (st == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1150 return AVERROR(ENOMEM); |
1024 | 1151 |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3685
diff
changeset
|
1152 if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") |
3662 | 1153 && track->codec_priv.size >= 40 |
1154 && track->codec_priv.data != NULL) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1155 track->video.fourcc = AV_RL32(track->codec_priv.data + 16); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1156 codec_id = codec_get_id(codec_bmp_tags, track->video.fourcc); |
3687
494a55f131f3
matroska: expand useless define for MS compat codec id strings
aurel
parents:
3685
diff
changeset
|
1157 } else if (!strcmp(track->codec_id, "A_MS/ACM") |
3662 | 1158 && track->codec_priv.size >= 18 |
1159 && track->codec_priv.data != NULL) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1160 uint16_t tag = AV_RL16(track->codec_priv.data); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1161 codec_id = codec_get_id(codec_wav_tags, tag); |
3662 | 1162 } else if (!strcmp(track->codec_id, "V_QUICKTIME") |
1163 && (track->codec_priv.size >= 86) | |
1164 && (track->codec_priv.data != NULL)) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1165 track->video.fourcc = AV_RL32(track->codec_priv.data); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1166 codec_id=codec_get_id(codec_movvideo_tags, track->video.fourcc); |
3746 | 1167 } else if (codec_id == CODEC_ID_PCM_S16BE) { |
1168 switch (track->audio.bitdepth) { | |
1169 case 8: codec_id = CODEC_ID_PCM_U8; break; | |
1170 case 24: codec_id = CODEC_ID_PCM_S24BE; break; | |
1171 case 32: codec_id = CODEC_ID_PCM_S32BE; break; | |
1172 } | |
1173 } else if (codec_id == CODEC_ID_PCM_S16LE) { | |
1174 switch (track->audio.bitdepth) { | |
1175 case 8: codec_id = CODEC_ID_PCM_U8; break; | |
1176 case 24: codec_id = CODEC_ID_PCM_S24LE; break; | |
1177 case 32: codec_id = CODEC_ID_PCM_S32LE; break; | |
1178 } | |
1179 } else if (codec_id==CODEC_ID_PCM_F32LE && track->audio.bitdepth==64) { | |
1180 codec_id = CODEC_ID_PCM_F64LE; | |
3662 | 1181 } 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
|
1182 int profile = matroska_aac_profile(track->codec_id); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1183 int sri = matroska_aac_sri(track->audio.samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1184 extradata = av_malloc(5); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1185 if (extradata == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1186 return AVERROR(ENOMEM); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1187 extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1188 extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1189 if (strstr(track->codec_id, "SBR")) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1190 sri = matroska_aac_sri(track->audio.out_samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1191 extradata[2] = 0x56; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1192 extradata[3] = 0xE5; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1193 extradata[4] = 0x80 | (sri<<3); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1194 extradata_size = 5; |
3655 | 1195 } else |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1196 extradata_size = 2; |
3662 | 1197 } else if (codec_id == CODEC_ID_TTA) { |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1198 ByteIOContext b; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1199 extradata_size = 30; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1200 extradata = av_mallocz(extradata_size); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1201 if (extradata == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1202 return AVERROR(ENOMEM); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1203 init_put_byte(&b, extradata, extradata_size, 1, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1204 NULL, NULL, NULL, NULL); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1205 put_buffer(&b, "TTA1", 4); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1206 put_le16(&b, 1); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1207 put_le16(&b, track->audio.channels); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1208 put_le16(&b, track->audio.bitdepth); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1209 put_le32(&b, track->audio.out_samplerate); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1210 put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate); |
3662 | 1211 } else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 || |
1212 codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1213 extradata_offset = 26; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1214 track->codec_priv.size -= extradata_offset; |
3662 | 1215 } else if (codec_id == CODEC_ID_RA_144) { |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1216 track->audio.out_samplerate = 8000; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1217 track->audio.channels = 1; |
3662 | 1218 } else if (codec_id == CODEC_ID_RA_288 || codec_id == CODEC_ID_COOK || |
1219 codec_id == CODEC_ID_ATRAC3) { | |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1220 ByteIOContext b; |
1534 | 1221 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1222 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
|
1223 0, NULL, NULL, NULL, NULL); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1224 url_fskip(&b, 24); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1225 track->audio.coded_framesize = get_be32(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1226 url_fskip(&b, 12); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1227 track->audio.sub_packet_h = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1228 track->audio.frame_size = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1229 track->audio.sub_packet_size = get_be16(&b); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1230 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
|
1231 if (codec_id == CODEC_ID_RA_288) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1232 st->codec->block_align = track->audio.coded_framesize; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1233 track->codec_priv.size = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1234 } else { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1235 st->codec->block_align = track->audio.sub_packet_size; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1236 extradata_offset = 78; |
3642 | 1237 track->codec_priv.size -= extradata_offset; |
1531 | 1238 } |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1239 } |
1531 | 1240 |
3655 | 1241 if (codec_id == CODEC_ID_NONE) |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1242 av_log(matroska->ctx, AV_LOG_INFO, |
3659 | 1243 "Unknown/unsupported CodecID %s.\n", track->codec_id); |
2144 | 1244 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1245 av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */ |
2144 | 1246 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1247 st->codec->codec_id = codec_id; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1248 st->start_time = 0; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1249 if (strcmp(track->language, "und")) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1250 av_strlcpy(st->language, track->language, 4); |
2144 | 1251 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1252 if (track->flag_default) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1253 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
|
1254 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1255 if (track->default_duration) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1256 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
|
1257 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
|
1258 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1259 if(extradata){ |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1260 st->codec->extradata = extradata; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1261 st->codec->extradata_size = extradata_size; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1262 } else if(track->codec_priv.data && track->codec_priv.size > 0){ |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1263 st->codec->extradata = av_malloc(track->codec_priv.size); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1264 if(st->codec->extradata == NULL) |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1265 return AVERROR(ENOMEM); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1266 st->codec->extradata_size = track->codec_priv.size; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1267 memcpy(st->codec->extradata, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1268 track->codec_priv.data + extradata_offset, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1269 track->codec_priv.size); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1270 } |
692
b0144ebc71dd
H.264 and Vorbis support in matroska patch by (M«©ns Rullg«©rd |mru inprovide com)
michael
parents:
652
diff
changeset
|
1271 |
3649
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1272 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1273 st->codec->codec_type = CODEC_TYPE_VIDEO; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1274 st->codec->codec_tag = track->video.fourcc; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1275 st->codec->width = track->video.pixel_width; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1276 st->codec->height = track->video.pixel_height; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1277 av_reduce(&st->codec->sample_aspect_ratio.num, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1278 &st->codec->sample_aspect_ratio.den, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1279 st->codec->height * track->video.display_width, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1280 st->codec-> width * track->video.display_height, |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1281 255); |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1282 st->need_parsing = AVSTREAM_PARSE_HEADERS; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1283 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1284 st->codec->codec_type = CODEC_TYPE_AUDIO; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1285 st->codec->sample_rate = track->audio.out_samplerate; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1286 st->codec->channels = track->audio.channels; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1287 } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1288 st->codec->codec_type = CODEC_TYPE_SUBTITLE; |
71da9d010bae
matroskadec: cosmetics: indentation of matroska_read_header()
aurel
parents:
3648
diff
changeset
|
1289 } |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1290 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1291 |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1292 attachements = attachements_list->elem; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1293 for (j=0; j<attachements_list->nb_elem; j++) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1294 if (!(attachements[j].filename && attachements[j].mime && |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1295 attachements[j].bin.data && attachements[j].bin.size > 0)) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1296 av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1297 } else { |
3691 | 1298 AVStream *st = av_new_stream(s, 0); |
3650
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1299 if (st == NULL) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1300 break; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1301 st->filename = av_strdup(attachements[j].filename); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1302 st->codec->codec_id = CODEC_ID_NONE; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1303 st->codec->codec_type = CODEC_TYPE_ATTACHMENT; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1304 st->codec->extradata = av_malloc(attachements[j].bin.size); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1305 if(st->codec->extradata == NULL) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1306 break; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1307 st->codec->extradata_size = attachements[j].bin.size; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1308 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
|
1309 |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1310 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
|
1311 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
|
1312 strlen(ff_mkv_mime_tags[i].str))) { |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1313 st->codec->codec_id = ff_mkv_mime_tags[i].id; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1314 break; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1315 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1316 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1317 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1318 } |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1319 |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1320 chapters = chapters_list->elem; |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1321 for (i=0; i<chapters_list->nb_elem; i++) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1322 if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid) |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1323 ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000}, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1324 chapters[i].start, chapters[i].end, |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1325 chapters[i].title); |
f31190f3d234
matroskadec: move context settings to matroska_read_header()
aurel
parents:
3649
diff
changeset
|
1326 |
3637 | 1327 index_list = &matroska->index; |
1328 index = index_list->elem; | |
1329 for (i=0; i<index_list->nb_elem; i++) { | |
1330 EbmlList *pos_list = &index[i].pos; | |
1331 MatroskaIndexPos *pos = pos_list->elem; | |
1332 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
|
1333 MatroskaTrack *track = matroska_find_track_by_num(matroska, |
3637 | 1334 pos[j].track); |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1335 if (track && track->stream) |
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1336 av_add_index_entry(track->stream, |
3637 | 1337 pos[j].pos + matroska->segment_start, |
1338 index[i].time*matroska->time_scale/AV_TIME_BASE, | |
2202 | 1339 0, 0, AVINDEX_KEYFRAME); |
2012 | 1340 } |
1341 } | |
1342 | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1343 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
|
1344 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1345 |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1346 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1347 * Put one packet in an application-supplied AVPacket struct. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1348 * Returns 0 on success or -1 on failure. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1349 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1350 static int matroska_deliver_packet(MatroskaDemuxContext *matroska, |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1351 AVPacket *pkt) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1352 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1353 if (matroska->num_packets > 0) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1354 memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1355 av_free(matroska->packets[0]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1356 if (matroska->num_packets > 1) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1357 memmove(&matroska->packets[0], &matroska->packets[1], |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1358 (matroska->num_packets - 1) * sizeof(AVPacket *)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1359 matroska->packets = |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1360 av_realloc(matroska->packets, (matroska->num_packets - 1) * |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1361 sizeof(AVPacket *)); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1362 } else { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1363 av_freep(&matroska->packets); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1364 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1365 matroska->num_packets--; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1366 return 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1367 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1368 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1369 return -1; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1370 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1371 |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1372 /* |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1373 * Free all packets in our internal queue. |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1374 */ |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1375 static void matroska_clear_queue(MatroskaDemuxContext *matroska) |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1376 { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1377 if (matroska->packets) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1378 int n; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1379 for (n = 0; n < matroska->num_packets; n++) { |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1380 av_free_packet(matroska->packets[n]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1381 av_free(matroska->packets[n]); |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1382 } |
3696
4aef467adb6b
matroskadec: use av_freep(&x) instead of av_free(x);x=NULL
aurel
parents:
3695
diff
changeset
|
1383 av_freep(&matroska->packets); |
3684
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1384 matroska->num_packets = 0; |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1385 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1386 } |
2350faade9fb
matroskadec: reorder some functions in a more logical order
aurel
parents:
3683
diff
changeset
|
1387 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1388 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1389 int size, int64_t pos, uint64_t cluster_time, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1390 uint64_t duration, int is_keyframe) |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1391 { |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1392 MatroskaTrack *track; |
1901
3f05dc37b4ec
extract ebml_read_binary() out of matroska_parse_block()
aurel
parents:
1900
diff
changeset
|
1393 int res = 0; |
2013
fc0b19650faa
add an intermediate variable (prepare for next patch)
aurel
parents:
2012
diff
changeset
|
1394 AVStream *st; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1395 AVPacket *pkt; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1396 int16_t block_time; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1397 uint32_t *lace_size = NULL; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1398 int n, flags, laces = 0; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1399 uint64_t num; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1400 |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1401 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
|
1402 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
|
1403 return res; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1404 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1405 data += n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1406 size -= n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1407 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1408 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
|
1409 if (size <= 3 || !track || !track->stream) { |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1410 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
|
1411 "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
|
1412 return res; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1413 } |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1414 st = track->stream; |
3655 | 1415 if (st->discard >= AVDISCARD_ALL) |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1416 return res; |
1914 | 1417 if (duration == AV_NOPTS_VALUE) |
3636
1f8f906eb49e
matroskadec: return pointer instead of index in matroska_find_track_by_num()
aurel
parents:
3635
diff
changeset
|
1418 duration = track->default_duration / matroska->time_scale; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1419 |
2185 | 1420 block_time = AV_RB16(data); |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1421 data += 2; |
2188 | 1422 flags = *data++; |
1423 size -= 3; | |
1831 | 1424 if (is_keyframe == -1) |
2415
3aa642c08cde
SimpleBlock keyframe flag is the most significant bit
conrad
parents:
2390
diff
changeset
|
1425 is_keyframe = flags & 0x80 ? PKT_FLAG_KEY : 0; |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1426 |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1427 if (matroska->skip_to_keyframe) { |
3655 | 1428 if (!is_keyframe || st != matroska->skip_to_stream) |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1429 return res; |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1430 matroska->skip_to_keyframe = 0; |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1431 } |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1432 |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1433 switch ((flags & 0x06) >> 1) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1434 case 0x0: /* no lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1435 laces = 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1436 lace_size = av_mallocz(sizeof(int)); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1437 lace_size[0] = size; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1438 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1439 |
3692 | 1440 case 0x1: /* Xiph lacing */ |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1441 case 0x2: /* fixed-size lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1442 case 0x3: /* EBML lacing */ |
3391 | 1443 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
|
1444 laces = (*data) + 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1445 data += 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1446 size -= 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1447 lace_size = av_mallocz(laces * sizeof(int)); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1448 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1449 switch ((flags & 0x06) >> 1) { |
3692 | 1450 case 0x1: /* Xiph lacing */ { |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1451 uint8_t temp; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1452 uint32_t total = 0; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1453 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
|
1454 while (1) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1455 if (size == 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1456 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
|
1457 break; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1458 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1459 temp = *data; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1460 lace_size[n] += temp; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1461 data += 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1462 size -= 1; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1463 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
|
1464 break; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1465 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1466 total += lace_size[n]; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1467 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1468 lace_size[n] = size - total; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1469 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1470 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1471 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1472 case 0x2: /* fixed-size lacing */ |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1473 for (n = 0; n < laces; n++) |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1474 lace_size[n] = size / laces; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1475 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1476 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1477 case 0x3: /* EBML lacing */ { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1478 uint32_t total; |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1479 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
|
1480 if (n < 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1481 av_log(matroska->ctx, AV_LOG_INFO, |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1482 "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
|
1483 break; |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1484 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1485 data += n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1486 size -= n; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1487 total = lace_size[0] = num; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1488 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
|
1489 int64_t snum; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1490 int r; |
3688
eb4649280c36
matroskadec: implement matroska_ebmlnum_uint() using ebml_read_num()
aurel
parents:
3687
diff
changeset
|
1491 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
|
1492 if (r < 0) { |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1493 av_log(matroska->ctx, AV_LOG_INFO, |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1494 "EBML block data error\n"); |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1495 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1496 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1497 data += r; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1498 size -= r; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1499 lace_size[n] = lace_size[n - 1] + snum; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1500 total += lace_size[n]; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1501 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1502 lace_size[n] = size - total; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1503 break; |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1504 } |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1505 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1506 break; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1507 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1508 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1509 if (res == 0) { |
1911 | 1510 uint64_t timecode = AV_NOPTS_VALUE; |
1511 | |
2364
7c31128b23f8
ensure that negative block_time are properly checked
aurel
parents:
2276
diff
changeset
|
1512 if (cluster_time != (uint64_t)-1 |
7c31128b23f8
ensure that negative block_time are properly checked
aurel
parents:
2276
diff
changeset
|
1513 && (block_time >= 0 || cluster_time >= -block_time)) |
1911 | 1514 timecode = cluster_time + block_time; |
1515 | |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1516 for (n = 0; n < laces; n++) { |
2657 | 1517 if (st->codec->codec_id == CODEC_ID_RA_288 || |
1518 st->codec->codec_id == CODEC_ID_COOK || | |
1519 st->codec->codec_id == CODEC_ID_ATRAC3) { | |
1520 int a = st->codec->block_align; | |
3642 | 1521 int sps = track->audio.sub_packet_size; |
1522 int cfs = track->audio.coded_framesize; | |
1523 int h = track->audio.sub_packet_h; | |
1524 int y = track->audio.sub_packet_cnt; | |
1525 int w = track->audio.frame_size; | |
2657 | 1526 int x; |
1527 | |
3642 | 1528 if (!track->audio.pkt_cnt) { |
2657 | 1529 if (st->codec->codec_id == CODEC_ID_RA_288) |
1530 for (x=0; x<h/2; x++) | |
3642 | 1531 memcpy(track->audio.buf+x*2*w+y*cfs, |
2657 | 1532 data+x*cfs, cfs); |
1533 else | |
1534 for (x=0; x<w/sps; x++) | |
3642 | 1535 memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); |
2657 | 1536 |
3642 | 1537 if (++track->audio.sub_packet_cnt >= h) { |
1538 track->audio.sub_packet_cnt = 0; | |
1539 track->audio.pkt_cnt = h*w / a; | |
2144 | 1540 } |
2657 | 1541 } |
3642 | 1542 while (track->audio.pkt_cnt) { |
2145 | 1543 pkt = av_mallocz(sizeof(AVPacket)); |
2657 | 1544 av_new_packet(pkt, a); |
3642 | 1545 memcpy(pkt->data, track->audio.buf |
1546 + a * (h*w / a - track->audio.pkt_cnt--), a); | |
2657 | 1547 pkt->pos = pos; |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
1548 pkt->stream_index = st->index; |
3695
5825a6cfd3bd
matroskadec: replace matroska_queue_packet with a single call to dynarray_add
aurel
parents:
3692
diff
changeset
|
1549 dynarray_add(&matroska->packets,&matroska->num_packets,pkt); |
2144 | 1550 } |
2657 | 1551 } else { |
3642 | 1552 MatroskaTrackEncoding *encodings = track->encodings.elem; |
3494
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
1553 int offset = 0, pkt_size = lace_size[n]; |
3281 | 1554 uint8_t *pkt_data = data; |
1555 | |
3642 | 1556 if (encodings && encodings->scope & 1) { |
3659 | 1557 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
|
1558 if (offset < 0) |
8bf1a8e12b43
matroskadec: move buffer decoding code to a separate function
aurel
parents:
3493
diff
changeset
|
1559 continue; |
3279 | 1560 } |
1561 | |
2657 | 1562 pkt = av_mallocz(sizeof(AVPacket)); |
1563 /* XXX: prevent data copy... */ | |
3281 | 1564 if (av_new_packet(pkt, pkt_size+offset) < 0) { |
3415 | 1565 av_free(pkt); |
2657 | 1566 res = AVERROR(ENOMEM); |
1567 n = laces-1; | |
1568 break; | |
1569 } | |
3279 | 1570 if (offset) |
3642 | 1571 memcpy (pkt->data, encodings->compression.settings.data, offset); |
3281 | 1572 memcpy (pkt->data+offset, pkt_data, pkt_size); |
2657 | 1573 |
3493 | 1574 if (pkt_data != data) |
1575 av_free(pkt_data); | |
1576 | |
2657 | 1577 if (n == 0) |
1578 pkt->flags = is_keyframe; | |
3634
f206f746ff61
matroskadec: store an AVStream pointer instead of a stream index
aurel
parents:
3633
diff
changeset
|
1579 pkt->stream_index = st->index; |
2657 | 1580 |
1581 pkt->pts = timecode; | |
1582 pkt->pos = pos; | |
1583 pkt->duration = duration; | |
1584 | |
3695
5825a6cfd3bd
matroskadec: replace matroska_queue_packet with a single call to dynarray_add
aurel
parents:
3692
diff
changeset
|
1585 dynarray_add(&matroska->packets, &matroska->num_packets, pkt); |
2657 | 1586 } |
1587 | |
1588 if (timecode != AV_NOPTS_VALUE) | |
1589 timecode = duration ? timecode + duration : AV_NOPTS_VALUE; | |
1830
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1590 data += lace_size[n]; |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1591 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1592 } |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1593 |
ae69f36fe685
cosmetics: fix indentation of the new matroska_parse_block() function
aurel
parents:
1829
diff
changeset
|
1594 av_free(lace_size); |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1595 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1596 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1597 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1598 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
|
1599 { |
3653 | 1600 MatroskaCluster cluster = { 0 }; |
1601 EbmlList *blocks_list; | |
1602 MatroskaBlock *blocks; | |
3680
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1603 int i, res; |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1604 if (matroska->has_cluster_id){ |
3692 | 1605 /* For the first cluster we parse, its ID was already read as |
3680
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1606 part of matroska_read_header(), so don't read it again */ |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1607 res = ebml_parse_id(matroska, matroska_clusters, |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1608 MATROSKA_ID_CLUSTER, &cluster); |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1609 matroska->has_cluster_id = 0; |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1610 } else |
8aa88bbf5f01
matroskadec: don't try to re-read already parsed ID in matroska_parse_cluster()
aurel
parents:
3679
diff
changeset
|
1611 res = ebml_parse(matroska, matroska_clusters, &cluster); |
3653 | 1612 blocks_list = &cluster.blocks; |
1613 blocks = blocks_list->elem; | |
3713
b337fe64a31f
matroskadec: parse available blocks even when cluster parsing failed
aurel
parents:
3702
diff
changeset
|
1614 for (i=0; i<blocks_list->nb_elem; i++) |
3653 | 1615 if (blocks[i].bin.size > 0) |
1616 res=matroska_parse_block(matroska, | |
1617 blocks[i].bin.data, blocks[i].bin.size, | |
1618 blocks[i].bin.pos, cluster.timecode, | |
1619 blocks[i].duration, !blocks[i].reference); | |
1620 ebml_free(matroska_cluster, &cluster); | |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1621 return res; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1622 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1623 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1624 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
|
1625 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1626 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
|
1627 |
1899 | 1628 while (matroska_deliver_packet(matroska, pkt)) { |
1900 | 1629 if (matroska->done) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
1630 return AVERROR(EIO); |
3653 | 1631 if (matroska_parse_cluster(matroska) < 0) |
1900 | 1632 matroska->done = 1; |
1899 | 1633 } |
1634 | |
1635 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
|
1636 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1637 |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1638 static int matroska_read_seek(AVFormatContext *s, int stream_index, |
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1639 int64_t timestamp, int flags) |
2012 | 1640 { |
1641 MatroskaDemuxContext *matroska = s->priv_data; | |
1642 AVStream *st = s->streams[stream_index]; | |
1643 int index; | |
1644 | |
1645 index = av_index_search_timestamp(st, timestamp, flags); | |
1646 if (index < 0) | |
1647 return 0; | |
1648 | |
2872 | 1649 matroska_clear_queue(matroska); |
1650 | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2657
diff
changeset
|
1651 url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET); |
2014
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1652 matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY); |
de75a5a81f28
add support for seeking to a keyframe instead of a random frame
aurel
parents:
2013
diff
changeset
|
1653 matroska->skip_to_stream = st; |
3462 | 1654 av_update_cur_dts(s, st, st->index_entries[index].timestamp); |
2012 | 1655 return 0; |
1656 } | |
1657 | |
3673
b0188029f916
matroskadec: cosmetics: consistent style for function declarations
aurel
parents:
3672
diff
changeset
|
1658 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
|
1659 { |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1660 MatroskaDemuxContext *matroska = s->priv_data; |
3642 | 1661 MatroskaTrack *tracks = matroska->tracks.elem; |
3656 | 1662 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
|
1663 |
2871
b2f261fccb0b
move internal queue freeing code in its own function
aurel
parents:
2870
diff
changeset
|
1664 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
|
1665 |
3642 | 1666 for (n=0; n < matroska->tracks.nb_elem; n++) |
1667 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) | |
1668 av_free(tracks[n].audio.buf); | |
3651
57c346e50442
matroskadec: use generic parser to parse matroska from toplevel
aurel
parents:
3650
diff
changeset
|
1669 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
|
1670 |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1671 return 0; |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1672 } |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1673 |
1169 | 1674 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
|
1675 "matroska", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3422
diff
changeset
|
1676 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
|
1677 sizeof(MatroskaDemuxContext), |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1678 matroska_probe, |
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1679 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
|
1680 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
|
1681 matroska_read_close, |
2012 | 1682 matroska_read_seek, |
380
9416dc106e06
matroska demuxer by ("Ronald S. Bultje" <R dot S dot Bultje at students dot uu dot nl>)
michael
parents:
diff
changeset
|
1683 }; |