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