blob: 596ad80cbf732b0990bb9f424750fff34288c8f6 [file] [log] [blame]
David Conradb061d892007-06-04 22:10:541/*
Aurelien Jacobsff33c5c2008-08-05 00:42:432 * Matroska file demuxer
Diego Biurrun5968d2d2008-08-05 08:28:573 * Copyright (c) 2003-2008 The FFmpeg Project
David Conradb061d892007-06-04 22:10:544 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
Reimar Döffinger6de4aec2007-06-20 17:37:1123 * @file matroskadec.c
David Conradb061d892007-06-04 22:10:5424 * Matroska file demuxer
25 * by Ronald Bultje <[email protected]>
26 * with a little help from Moritz Bunkus <[email protected]>
Aurelien Jacobsff33c5c2008-08-05 00:42:4327 * totally reworked by Aurelien Jacobs <[email protected]>
Diego Biurrun5968d2d2008-08-05 08:28:5728 * Specs available on the Matroska project page: http://www.matroska.org/.
David Conradb061d892007-06-04 22:10:5429 */
30
31#include "avformat.h"
32/* For codec_get_id(). */
33#include "riff.h"
Aurelien Jacobsf009e362008-07-27 15:11:0434#include "isom.h"
David Conradb061d892007-06-04 22:10:5435#include "matroska.h"
Aurelien Jacobs7bfacd42008-04-02 21:41:4836#include "libavcodec/mpeg4audio.h"
Diego Biurrun245976d2008-05-09 11:56:3637#include "libavutil/intfloat_readwrite.h"
Aurelien Jacobs5f8e0222008-08-05 00:39:4738#include "libavutil/avstring.h"
Aurelien Jacobsde3230f2008-05-09 01:53:5939#include "libavutil/lzo.h"
Aurelien Jacobsfbb878c2008-05-13 23:32:1340#ifdef CONFIG_ZLIB
41#include <zlib.h>
42#endif
Aurelien Jacobs54dddf02008-05-15 23:12:4143#ifdef CONFIG_BZLIB
44#include <bzlib.h>
45#endif
David Conradb061d892007-06-04 22:10:5446
Aurelien Jacobs789ed102008-08-05 00:40:0047typedef enum {
48 EBML_NONE,
49 EBML_UINT,
50 EBML_FLOAT,
51 EBML_STR,
52 EBML_UTF8,
53 EBML_BIN,
54 EBML_NEST,
55 EBML_PASS,
56 EBML_STOP,
57} EbmlType;
58
59typedef const struct EbmlSyntax {
60 uint32_t id;
61 EbmlType type;
62 int list_elem_size;
63 int data_offset;
64 union {
65 uint64_t u;
66 double f;
67 const char *s;
68 const struct EbmlSyntax *n;
69 } def;
70} EbmlSyntax;
71
72typedef struct {
73 int nb_elem;
74 void *elem;
75} EbmlList;
76
77typedef struct {
78 int size;
79 uint8_t *data;
80 int64_t pos;
81} EbmlBin;
82
Aurelien Jacobs63511322008-08-05 00:40:0283typedef struct {
84 uint64_t version;
85 uint64_t max_size;
86 uint64_t id_length;
87 char *doctype;
88 uint64_t doctype_version;
89} Ebml;
90
Aurelien Jacobs2cbc8812008-08-05 00:40:3191typedef struct {
92 uint64_t algo;
93 EbmlBin settings;
94} MatroskaTrackCompression;
David Conradb061d892007-06-04 22:10:5495
Aurelien Jacobs2cbc8812008-08-05 00:40:3196typedef struct {
97 uint64_t scope;
98 uint64_t type;
99 MatroskaTrackCompression compression;
100} MatroskaTrackEncoding;
David Conradb061d892007-06-04 22:10:54101
Aurelien Jacobs2cbc8812008-08-05 00:40:31102typedef struct {
103 double frame_rate;
104 uint64_t display_width;
105 uint64_t display_height;
106 uint64_t pixel_width;
107 uint64_t pixel_height;
108 uint64_t fourcc;
109} MatroskaTrackVideo;
David Conradb061d892007-06-04 22:10:54110
Aurelien Jacobs2cbc8812008-08-05 00:40:31111typedef struct {
112 double samplerate;
113 double out_samplerate;
114 uint64_t bitdepth;
115 uint64_t channels;
David Conradb061d892007-06-04 22:10:54116
Aurelien Jacobs2cbc8812008-08-05 00:40:31117 /* real audio header (extracted from extradata) */
118 int coded_framesize;
119 int sub_packet_h;
120 int frame_size;
121 int sub_packet_size;
122 int sub_packet_cnt;
123 int pkt_cnt;
124 uint8_t *buf;
125} MatroskaTrackAudio;
David Conradb061d892007-06-04 22:10:54126
Aurelien Jacobs2cbc8812008-08-05 00:40:31127typedef struct {
128 uint64_t num;
129 uint64_t type;
130 char *codec_id;
131 EbmlBin codec_priv;
132 char *language;
Anton Khirnov7ff97082008-06-01 13:54:11133 double time_scale;
David Conradb061d892007-06-04 22:10:54134 uint64_t default_duration;
Aurelien Jacobs4eff9742008-08-05 00:39:53135 uint64_t flag_default;
Aurelien Jacobs2cbc8812008-08-05 00:40:31136 MatroskaTrackVideo video;
137 MatroskaTrackAudio audio;
138 EbmlList encodings;
Aurelien Jacobsfc4d3352008-08-05 00:40:06139
140 AVStream *stream;
David Conradb061d892007-06-04 22:10:54141} MatroskaTrack;
142
Aurelien Jacobse5929fd2008-08-05 00:40:15143typedef struct {
Aurelien Jacobsb414cb82008-08-05 00:40:24144 char *filename;
145 char *mime;
146 EbmlBin bin;
147} MatroskaAttachement;
148
149typedef struct {
Aurelien Jacobs6bbd7c72008-08-05 00:40:21150 uint64_t start;
151 uint64_t end;
152 uint64_t uid;
153 char *title;
154} MatroskaChapter;
155
156typedef struct {
Aurelien Jacobse5929fd2008-08-05 00:40:15157 uint64_t track;
158 uint64_t pos;
159} MatroskaIndexPos;
160
161typedef struct {
162 uint64_t time;
163 EbmlList pos;
164} MatroskaIndex;
165
Aurelien Jacobs13b350a2008-08-05 00:40:36166typedef struct {
Aurelien Jacobs44015c52008-08-08 23:50:38167 char *name;
168 char *string;
169 EbmlList sub;
170} MatroskaTag;
171
172typedef struct {
Aurelien Jacobs13b350a2008-08-05 00:40:36173 uint64_t id;
174 uint64_t pos;
175} MatroskaSeekhead;
176
Aurelien Jacobsc171af92008-08-05 00:41:19177typedef struct {
Aurelien Jacobs8d75b5a2007-06-04 22:35:16178 uint64_t start;
179 uint64_t length;
David Conradb061d892007-06-04 22:10:54180} MatroskaLevel;
181
Aurelien Jacobsc171af92008-08-05 00:41:19182typedef struct {
David Conradb061d892007-06-04 22:10:54183 AVFormatContext *ctx;
184
Diego Biurrun5968d2d2008-08-05 08:28:57185 /* EBML stuff */
David Conradb061d892007-06-04 22:10:54186 int num_levels;
187 MatroskaLevel levels[EBML_MAX_DEPTH];
188 int level_up;
189
Aurelien Jacobs29708582008-08-05 00:40:27190 uint64_t time_scale;
191 double duration;
192 char *title;
Aurelien Jacobs2cbc8812008-08-05 00:40:31193 EbmlList tracks;
Aurelien Jacobsb414cb82008-08-05 00:40:24194 EbmlList attachments;
Aurelien Jacobs6bbd7c72008-08-05 00:40:21195 EbmlList chapters;
Aurelien Jacobse5929fd2008-08-05 00:40:15196 EbmlList index;
Aurelien Jacobs44015c52008-08-08 23:50:38197 EbmlList tags;
Aurelien Jacobs13b350a2008-08-05 00:40:36198 EbmlList seekhead;
David Conradb061d892007-06-04 22:10:54199
David Conradb061d892007-06-04 22:10:54200 /* byte position of the segment inside the stream */
201 offset_t segment_start;
202
Diego Biurrun5968d2d2008-08-05 08:28:57203 /* the packet queue */
David Conradb061d892007-06-04 22:10:54204 AVPacket **packets;
205 int num_packets;
206
Aurelien Jacobs8d75b5a2007-06-04 22:35:16207 int done;
Aurelien Jacobsce6f28b2008-08-05 00:40:58208 int has_cluster_id;
David Conradb061d892007-06-04 22:10:54209
David Conradb061d892007-06-04 22:10:54210 /* What to skip before effectively reading a packet. */
211 int skip_to_keyframe;
212 AVStream *skip_to_stream;
213} MatroskaDemuxContext;
214
Aurelien Jacobs209472b2008-08-05 00:41:05215typedef struct {
216 uint64_t duration;
217 int64_t reference;
218 EbmlBin bin;
219} MatroskaBlock;
220
221typedef struct {
222 uint64_t timecode;
223 EbmlList blocks;
224} MatroskaCluster;
225
Aurelien Jacobs4b3dc522008-06-02 23:01:14226#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x))
227
Aurelien Jacobs63511322008-08-05 00:40:02228static EbmlSyntax ebml_header[] = {
229 { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u=EBML_VERSION} },
230 { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u=8} },
231 { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {.u=4} },
232 { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s="(none)"} },
233 { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_version), {.u=1} },
234 { EBML_ID_EBMLVERSION, EBML_NONE },
235 { EBML_ID_DOCTYPEVERSION, EBML_NONE },
236 { EBML_ID_VOID, EBML_NONE },
237 { 0 }
238};
239
240static EbmlSyntax ebml_syntax[] = {
241 { EBML_ID_HEADER, EBML_NEST, 0, 0, {.n=ebml_header} },
242 { 0 }
243};
244
Aurelien Jacobs29708582008-08-05 00:40:27245static EbmlSyntax matroska_info[] = {
246 { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext,time_scale), {.u=1000000} },
247 { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext,duration) },
248 { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) },
249 { MATROSKA_ID_WRITINGAPP, EBML_NONE },
250 { MATROSKA_ID_MUXINGAPP, EBML_NONE },
251 { MATROSKA_ID_DATEUTC, EBML_NONE },
252 { MATROSKA_ID_SEGMENTUID, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15253 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs29708582008-08-05 00:40:27254 { EBML_ID_VOID, EBML_NONE },
255 { 0 }
256};
257
Aurelien Jacobs2cbc8812008-08-05 00:40:31258static EbmlSyntax matroska_track_video[] = {
259 { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT,0, offsetof(MatroskaTrackVideo,frame_rate) },
260 { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_width) },
261 { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) },
262 { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) },
263 { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) },
264 { MATROSKA_ID_VIDEOCOLORSPACE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,fourcc) },
Aurelien Jacobs5df3cc62008-08-13 21:15:15265 { MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE },
266 { MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE },
267 { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE },
268 { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE },
269 { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE },
Aurelien Jacobs2cbc8812008-08-05 00:40:31270 { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE },
271 { MATROSKA_ID_VIDEOSTEREOMODE, EBML_NONE },
272 { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE },
273 { EBML_ID_VOID, EBML_NONE },
274 { 0 }
275};
276
277static EbmlSyntax matroska_track_audio[] = {
278 { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT,0, offsetof(MatroskaTrackAudio,samplerate), {.f=8000.0} },
279 { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ,EBML_FLOAT,0,offsetof(MatroskaTrackAudio,out_samplerate) },
280 { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio,bitdepth) },
281 { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio,channels), {.u=1} },
282 { EBML_ID_VOID, EBML_NONE },
283 { 0 }
284};
285
286static EbmlSyntax matroska_track_encoding_compression[] = {
287 { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression,algo), {.u=0} },
288 { MATROSKA_ID_ENCODINGCOMPSETTINGS,EBML_BIN, 0, offsetof(MatroskaTrackCompression,settings) },
289 { EBML_ID_VOID, EBML_NONE },
290 { 0 }
291};
292
293static EbmlSyntax matroska_track_encoding[] = {
294 { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} },
295 { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} },
296 { MATROSKA_ID_ENCODINGCOMPRESSION,EBML_NEST, 0, offsetof(MatroskaTrackEncoding,compression), {.n=matroska_track_encoding_compression} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15297 { MATROSKA_ID_ENCODINGORDER, EBML_NONE },
Aurelien Jacobs2cbc8812008-08-05 00:40:31298 { EBML_ID_VOID, EBML_NONE },
299 { 0 }
300};
301
302static EbmlSyntax matroska_track_encodings[] = {
303 { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack,encodings), {.n=matroska_track_encoding} },
304 { EBML_ID_VOID, EBML_NONE },
305 { 0 }
306};
307
308static EbmlSyntax matroska_track[] = {
309 { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) },
310 { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack,type) },
311 { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack,codec_id) },
312 { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack,codec_priv) },
313 { MATROSKA_ID_TRACKLANGUAGE, EBML_UTF8, 0, offsetof(MatroskaTrack,language), {.s="eng"} },
314 { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) },
315 { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} },
316 { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} },
317 { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} },
318 { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} },
319 { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} },
320 { MATROSKA_ID_TRACKUID, EBML_NONE },
321 { MATROSKA_ID_TRACKNAME, EBML_NONE },
322 { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE },
323 { MATROSKA_ID_TRACKFLAGFORCED, EBML_NONE },
324 { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE },
325 { MATROSKA_ID_CODECNAME, EBML_NONE },
326 { MATROSKA_ID_CODECDECODEALL, EBML_NONE },
327 { MATROSKA_ID_CODECINFOURL, EBML_NONE },
328 { MATROSKA_ID_CODECDOWNLOADURL, EBML_NONE },
329 { MATROSKA_ID_TRACKMINCACHE, EBML_NONE },
330 { MATROSKA_ID_TRACKMAXCACHE, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15331 { MATROSKA_ID_TRACKMAXBLKADDID, EBML_NONE },
332 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs2cbc8812008-08-05 00:40:31333 { EBML_ID_VOID, EBML_NONE },
334 { 0 }
335};
336
337static EbmlSyntax matroska_tracks[] = {
338 { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext,tracks), {.n=matroska_track} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15339 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs2cbc8812008-08-05 00:40:31340 { EBML_ID_VOID, EBML_NONE },
341 { 0 }
342};
343
Aurelien Jacobsb414cb82008-08-05 00:40:24344static EbmlSyntax matroska_attachment[] = {
345 { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) },
346 { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachement,mime) },
347 { MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachement,bin) },
Aurelien Jacobs5df3cc62008-08-13 21:15:15348 { MATROSKA_ID_FILEDESC, EBML_NONE },
Aurelien Jacobsb414cb82008-08-05 00:40:24349 { MATROSKA_ID_FILEUID, EBML_NONE },
350 { EBML_ID_VOID, EBML_NONE },
351 { 0 }
352};
353
354static EbmlSyntax matroska_attachments[] = {
355 { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15356 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobsb414cb82008-08-05 00:40:24357 { EBML_ID_VOID, EBML_NONE },
358 { 0 }
359};
360
Aurelien Jacobs6bbd7c72008-08-05 00:40:21361static EbmlSyntax matroska_chapter_display[] = {
362 { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter,title) },
Aurelien Jacobs5df3cc62008-08-13 21:15:15363 { MATROSKA_ID_CHAPLANG, EBML_NONE },
Aurelien Jacobs6bbd7c72008-08-05 00:40:21364 { EBML_ID_VOID, EBML_NONE },
365 { 0 }
366};
367
368static EbmlSyntax matroska_chapter_entry[] = {
369 { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} },
370 { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} },
371 { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) },
372 { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} },
373 { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15374 { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE },
375 { MATROSKA_ID_CHAPTERPHYSEQUIV, EBML_NONE },
376 { MATROSKA_ID_CHAPTERATOM, EBML_NONE },
377 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs6bbd7c72008-08-05 00:40:21378 { EBML_ID_VOID, EBML_NONE },
379 { 0 }
380};
381
382static EbmlSyntax matroska_chapter[] = {
383 { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} },
384 { MATROSKA_ID_EDITIONUID, EBML_NONE },
385 { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE },
386 { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15387 { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE },
388 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs6bbd7c72008-08-05 00:40:21389 { EBML_ID_VOID, EBML_NONE },
390 { 0 }
391};
392
393static EbmlSyntax matroska_chapters[] = {
394 { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15395 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs6bbd7c72008-08-05 00:40:21396 { EBML_ID_VOID, EBML_NONE },
397 { 0 }
398};
399
Aurelien Jacobse5929fd2008-08-05 00:40:15400static EbmlSyntax matroska_index_pos[] = {
401 { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) },
402 { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos,pos) },
Aurelien Jacobs5df3cc62008-08-13 21:15:15403 { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE },
Aurelien Jacobse5929fd2008-08-05 00:40:15404 { EBML_ID_VOID, EBML_NONE },
405 { 0 }
406};
407
408static EbmlSyntax matroska_index_entry[] = {
409 { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex,time) },
410 { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex,pos), {.n=matroska_index_pos} },
411 { EBML_ID_VOID, EBML_NONE },
412 { 0 }
413};
414
415static EbmlSyntax matroska_index[] = {
416 { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15417 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobse5929fd2008-08-05 00:40:15418 { EBML_ID_VOID, EBML_NONE },
419 { 0 }
420};
421
Aurelien Jacobs44015c52008-08-08 23:50:38422static EbmlSyntax matroska_simpletag[] = {
423 { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) },
424 { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) },
425 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} },
426 { MATROSKA_ID_TAGLANG, EBML_NONE },
427 { MATROSKA_ID_TAGDEFAULT, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15428 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs44015c52008-08-08 23:50:38429 { EBML_ID_VOID, EBML_NONE },
430 { 0 }
431};
432
433static EbmlSyntax matroska_tag[] = {
434 { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), 0, {.n=matroska_simpletag} },
435 { MATROSKA_ID_TAGTARGETS, EBML_NONE },
Aurelien Jacobs5df3cc62008-08-13 21:15:15436 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs44015c52008-08-08 23:50:38437 { EBML_ID_VOID, EBML_NONE },
438 { 0 }
439};
440
Aurelien Jacobs434d4962008-08-05 00:40:18441static EbmlSyntax matroska_tags[] = {
Aurelien Jacobs44015c52008-08-08 23:50:38442 { MATROSKA_ID_TAG, EBML_NEST, 0, offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15443 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs434d4962008-08-05 00:40:18444 { EBML_ID_VOID, EBML_NONE },
445 { 0 }
446};
447
Aurelien Jacobs13b350a2008-08-05 00:40:36448static EbmlSyntax matroska_seekhead_entry[] = {
449 { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead,id) },
450 { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead,pos), {.u=-1} },
451 { EBML_ID_VOID, EBML_NONE },
452 { 0 }
453};
454
455static EbmlSyntax matroska_seekhead[] = {
456 { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext,seekhead), {.n=matroska_seekhead_entry} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15457 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs13b350a2008-08-05 00:40:36458 { EBML_ID_VOID, EBML_NONE },
459 { 0 }
460};
461
Aurelien Jacobsce6f28b2008-08-05 00:40:58462static EbmlSyntax matroska_segment[] = {
463 { MATROSKA_ID_INFO, EBML_NEST, 0, 0, {.n=matroska_info } },
464 { MATROSKA_ID_TRACKS, EBML_NEST, 0, 0, {.n=matroska_tracks } },
465 { MATROSKA_ID_ATTACHMENTS, EBML_NEST, 0, 0, {.n=matroska_attachments} },
466 { MATROSKA_ID_CHAPTERS, EBML_NEST, 0, 0, {.n=matroska_chapters } },
467 { MATROSKA_ID_CUES, EBML_NEST, 0, 0, {.n=matroska_index } },
468 { MATROSKA_ID_TAGS, EBML_NEST, 0, 0, {.n=matroska_tags } },
469 { MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } },
470 { MATROSKA_ID_CLUSTER, EBML_STOP, 0, offsetof(MatroskaDemuxContext,has_cluster_id) },
471 { EBML_ID_VOID, EBML_NONE },
472 { 0 }
473};
474
475static EbmlSyntax matroska_segments[] = {
476 { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, {.n=matroska_segment } },
477 { 0 }
478};
479
Aurelien Jacobs209472b2008-08-05 00:41:05480static EbmlSyntax matroska_blockgroup[] = {
481 { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
482 { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) },
483 { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} },
484 { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
485 { EBML_ID_VOID, EBML_NONE },
486 { 0 }
487};
488
489static EbmlSyntax matroska_cluster[] = {
490 { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) },
491 { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} },
492 { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15493 { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE },
494 { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE },
495 { EBML_ID_CRC32, EBML_NONE },
Aurelien Jacobs209472b2008-08-05 00:41:05496 { EBML_ID_VOID, EBML_NONE },
497 { 0 }
498};
499
500static EbmlSyntax matroska_clusters[] = {
501 { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} },
Aurelien Jacobs5df3cc62008-08-13 21:15:15502 { MATROSKA_ID_INFO, EBML_NONE },
503 { MATROSKA_ID_CUES, EBML_NONE },
504 { MATROSKA_ID_TAGS, EBML_NONE },
505 { MATROSKA_ID_SEEKHEAD, EBML_NONE },
Aurelien Jacobs209472b2008-08-05 00:41:05506 { 0 }
507};
508
Aurelien Jacobs44015c52008-08-08 23:50:38509#define SIZE_OFF(x) sizeof(((AVFormatContext*)0)->x),offsetof(AVFormatContext,x)
510const struct {
511 const char name[16];
512 int size;
513 int offset;
514} metadata[] = {
515 { "TITLE", SIZE_OFF(title) },
516 { "ARTIST", SIZE_OFF(author) },
517 { "WRITTEN_BY", SIZE_OFF(author) },
518 { "LEAD_PERFORMER", SIZE_OFF(author) },
519 { "COPYRIGHT", SIZE_OFF(copyright) },
520 { "COMMENT", SIZE_OFF(comment) },
521 { "ALBUM", SIZE_OFF(album) },
522 { "DATE_WRITTEN", SIZE_OFF(year) },
523 { "DATE_RELEASED", SIZE_OFF(year) },
524 { "PART_NUMBER", SIZE_OFF(track) },
525 { "GENRE", SIZE_OFF(genre) },
526};
527
David Conradb061d892007-06-04 22:10:54528/*
Diego Biurrun5968d2d2008-08-05 08:28:57529 * Return: Whether we reached the end of a level in the hierarchy or not.
David Conradb061d892007-06-04 22:10:54530 */
Aurelien Jacobs592110c2008-08-05 00:42:08531static int ebml_level_end(MatroskaDemuxContext *matroska)
David Conradb061d892007-06-04 22:10:54532{
Björn Axelsson899681c2007-11-21 07:41:00533 ByteIOContext *pb = matroska->ctx->pb;
David Conradb061d892007-06-04 22:10:54534 offset_t pos = url_ftell(pb);
David Conradb061d892007-06-04 22:10:54535
Aurelien Jacobs592110c2008-08-05 00:42:08536 if (matroska->num_levels > 0) {
David Conradb061d892007-06-04 22:10:54537 MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1];
Aurelien Jacobs592110c2008-08-05 00:42:08538 if (pos - level->start >= level->length) {
David Conradb061d892007-06-04 22:10:54539 matroska->num_levels--;
Aurelien Jacobs592110c2008-08-05 00:42:08540 return 1;
David Conradb061d892007-06-04 22:10:54541 }
542 }
Aurelien Jacobs592110c2008-08-05 00:42:08543 return 0;
David Conradb061d892007-06-04 22:10:54544}
545
546/*
547 * Read: an "EBML number", which is defined as a variable-length
548 * array of bytes. The first byte indicates the length by giving a
549 * number of 0-bits followed by a one. The position of the first
550 * "one" bit inside the first byte indicates the length of this
551 * number.
Diego Biurrun5968d2d2008-08-05 08:28:57552 * Returns: number of bytes read, < 0 on error
David Conradb061d892007-06-04 22:10:54553 */
Aurelien Jacobsc1e01132008-08-05 00:42:52554static int ebml_read_num(MatroskaDemuxContext *matroska, ByteIOContext *pb,
Aurelien Jacobsf7b96872008-08-05 00:42:05555 int max_size, uint64_t *number)
David Conradb061d892007-06-04 22:10:54556{
David Conradb061d892007-06-04 22:10:54557 int len_mask = 0x80, read = 1, n = 1;
558 int64_t total = 0;
559
Diego Biurrun5968d2d2008-08-05 08:28:57560 /* The first byte tells us the length in bytes - get_byte() can normally
David Conradb061d892007-06-04 22:10:54561 * return 0, but since that's not a valid first ebmlID byte, we can
562 * use it safely here to catch EOS. */
563 if (!(total = get_byte(pb))) {
564 /* we might encounter EOS here */
565 if (!url_feof(pb)) {
566 offset_t pos = url_ftell(pb);
567 av_log(matroska->ctx, AV_LOG_ERROR,
568 "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
569 pos, pos);
570 }
Panagiotis Issaris6f3e0b22007-07-19 15:23:32571 return AVERROR(EIO); /* EOS or actual I/O error */
David Conradb061d892007-06-04 22:10:54572 }
573
574 /* get the length of the EBML number */
575 while (read <= max_size && !(total & len_mask)) {
576 read++;
577 len_mask >>= 1;
578 }
579 if (read > max_size) {
580 offset_t pos = url_ftell(pb) - 1;
581 av_log(matroska->ctx, AV_LOG_ERROR,
582 "Invalid EBML number size tag 0x%02x at pos %"PRIu64" (0x%"PRIx64")\n",
583 (uint8_t) total, pos, pos);
584 return AVERROR_INVALIDDATA;
585 }
586
587 /* read out length */
588 total &= ~len_mask;
589 while (n++ < read)
590 total = (total << 8) | get_byte(pb);
591
592 *number = total;
593
594 return read;
595}
596
597/*
David Conradb061d892007-06-04 22:10:54598 * Read the next element as an unsigned int.
599 * 0 is success, < 0 is failure.
600 */
Aurelien Jacobsf7b96872008-08-05 00:42:05601static int ebml_read_uint(ByteIOContext *pb, int size, uint64_t *num)
David Conradb061d892007-06-04 22:10:54602{
Aurelien Jacobsc6cd2b32008-08-05 00:41:55603 int n = 0;
David Conradb061d892007-06-04 22:10:54604
Aurelien Jacobsba5a1f92008-08-05 00:41:52605 if (size < 1 || size > 8)
David Conradb061d892007-06-04 22:10:54606 return AVERROR_INVALIDDATA;
David Conradb061d892007-06-04 22:10:54607
Diego Biurrun5968d2d2008-08-05 08:28:57608 /* big-endian ordering; build up number */
David Conradb061d892007-06-04 22:10:54609 *num = 0;
610 while (n++ < size)
611 *num = (*num << 8) | get_byte(pb);
612
613 return 0;
614}
615
616/*
David Conradb061d892007-06-04 22:10:54617 * Read the next element as a float.
618 * 0 is success, < 0 is failure.
619 */
Aurelien Jacobsf7b96872008-08-05 00:42:05620static int ebml_read_float(ByteIOContext *pb, int size, double *num)
David Conradb061d892007-06-04 22:10:54621{
David Conradb061d892007-06-04 22:10:54622 if (size == 4) {
623 *num= av_int2flt(get_be32(pb));
624 } else if(size==8){
625 *num= av_int2dbl(get_be64(pb));
Aurelien Jacobsba5a1f92008-08-05 00:41:52626 } else
David Conradb061d892007-06-04 22:10:54627 return AVERROR_INVALIDDATA;
David Conradb061d892007-06-04 22:10:54628
629 return 0;
630}
631
632/*
633 * Read the next element as an ASCII string.
634 * 0 is success, < 0 is failure.
635 */
Aurelien Jacobsf7b96872008-08-05 00:42:05636static int ebml_read_ascii(ByteIOContext *pb, int size, char **str)
David Conradb061d892007-06-04 22:10:54637{
Aurelien Jacobsc6cd2b32008-08-05 00:41:55638 av_free(*str);
Diego Biurrun5968d2d2008-08-05 08:28:57639 /* EBML strings are usually not 0-terminated, so we allocate one
David Conradb061d892007-06-04 22:10:54640 * byte more, read the string and NULL-terminate it ourselves. */
Aurelien Jacobsc6cd2b32008-08-05 00:41:55641 if (!(*str = av_malloc(size + 1)))
Panagiotis Issaris769e10f2007-07-19 15:21:30642 return AVERROR(ENOMEM);
David Conradb061d892007-06-04 22:10:54643 if (get_buffer(pb, (uint8_t *) *str, size) != size) {
Aurelien Jacobsff2c2222008-06-02 23:37:14644 av_free(*str);
Panagiotis Issaris6f3e0b22007-07-19 15:23:32645 return AVERROR(EIO);
David Conradb061d892007-06-04 22:10:54646 }
647 (*str)[size] = '\0';
648
649 return 0;
650}
651
652/*
Aurelien Jacobs737c40d2008-08-05 00:42:39653 * Read the next element as binary data.
654 * 0 is success, < 0 is failure.
655 */
656static int ebml_read_binary(ByteIOContext *pb, int length, EbmlBin *bin)
657{
658 av_free(bin->data);
659 if (!(bin->data = av_malloc(length)))
660 return AVERROR(ENOMEM);
661
662 bin->size = length;
663 bin->pos = url_ftell(pb);
664 if (get_buffer(pb, bin->data, length) != length)
665 return AVERROR(EIO);
666
667 return 0;
668}
669
670/*
David Conradb061d892007-06-04 22:10:54671 * Read the next element, but only the header. The contents
672 * are supposed to be sub-elements which can be read separately.
673 * 0 is success, < 0 is failure.
674 */
Aurelien Jacobsf7b96872008-08-05 00:42:05675static int ebml_read_master(MatroskaDemuxContext *matroska, int length)
David Conradb061d892007-06-04 22:10:54676{
Björn Axelsson899681c2007-11-21 07:41:00677 ByteIOContext *pb = matroska->ctx->pb;
David Conradb061d892007-06-04 22:10:54678 MatroskaLevel *level;
David Conradb061d892007-06-04 22:10:54679
David Conradb061d892007-06-04 22:10:54680 if (matroska->num_levels >= EBML_MAX_DEPTH) {
681 av_log(matroska->ctx, AV_LOG_ERROR,
682 "File moves beyond max. allowed depth (%d)\n", EBML_MAX_DEPTH);
Panagiotis Issaris85565db2007-07-19 15:38:33683 return AVERROR(ENOSYS);
David Conradb061d892007-06-04 22:10:54684 }
685
David Conradb061d892007-06-04 22:10:54686 level = &matroska->levels[matroska->num_levels++];
687 level->start = url_ftell(pb);
688 level->length = length;
689
690 return 0;
691}
692
693/*
David Conradb061d892007-06-04 22:10:54694 * Read signed/unsigned "EBML" numbers.
Diego Biurrun5968d2d2008-08-05 08:28:57695 * Return: number of bytes processed, < 0 on error
David Conradb061d892007-06-04 22:10:54696 */
Aurelien Jacobsc1e01132008-08-05 00:42:52697static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska,
698 uint8_t *data, uint32_t size, uint64_t *num)
David Conradb061d892007-06-04 22:10:54699{
Aurelien Jacobsc1e01132008-08-05 00:42:52700 ByteIOContext pb;
701 init_put_byte(&pb, data, size, 0, NULL, NULL, NULL, NULL);
702 return ebml_read_num(matroska, &pb, 8, num);
David Conradb061d892007-06-04 22:10:54703}
704
705/*
706 * Same as above, but signed.
707 */
Aurelien Jacobsc1e01132008-08-05 00:42:52708static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska,
709 uint8_t *data, uint32_t size, int64_t *num)
David Conradb061d892007-06-04 22:10:54710{
711 uint64_t unum;
712 int res;
713
714 /* read as unsigned number first */
Aurelien Jacobsc1e01132008-08-05 00:42:52715 if ((res = matroska_ebmlnum_uint(matroska, data, size, &unum)) < 0)
David Conradb061d892007-06-04 22:10:54716 return res;
717
718 /* make signed (weird way) */
Aurelien Jacobs33ac07e2008-08-05 00:42:55719 *num = unum - ((1LL << (7*res - 1)) - 1);
David Conradb061d892007-06-04 22:10:54720
721 return res;
722}
723
Aurelien Jacobs789ed102008-08-05 00:40:00724static int ebml_parse_elem(MatroskaDemuxContext *matroska,
Aurelien Jacobs737c40d2008-08-05 00:42:39725 EbmlSyntax *syntax, void *data);
Aurelien Jacobs789ed102008-08-05 00:40:00726
727static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
728 uint32_t id, void *data)
729{
730 int i;
731 for (i=0; syntax[i].id; i++)
732 if (id == syntax[i].id)
733 break;
734 if (!syntax[i].id)
735 av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id);
736 return ebml_parse_elem(matroska, &syntax[i], data);
737}
738
Aurelien Jacobs66a37e02008-08-05 00:42:17739static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
740 void *data)
741{
Aurelien Jacobs88cca982008-08-05 00:42:58742 uint64_t id;
743 int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id);
744 id |= 1 << 7*res;
Aurelien Jacobs66a37e02008-08-05 00:42:17745 return res < 0 ? res : ebml_parse_id(matroska, syntax, id, data);
746}
747
Aurelien Jacobs9bcb92c2008-08-05 00:42:13748static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
Aurelien Jacobs6314cca2008-08-05 00:42:23749 void *data)
Aurelien Jacobs789ed102008-08-05 00:40:00750{
Aurelien Jacobsc005b3f2008-08-05 00:42:10751 int i, res = 0;
Aurelien Jacobs789ed102008-08-05 00:40:00752
753 for (i=0; syntax[i].id; i++)
754 switch (syntax[i].type) {
755 case EBML_UINT:
756 *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u;
757 break;
758 case EBML_FLOAT:
759 *(double *)((char *)data+syntax[i].data_offset) = syntax[i].def.f;
760 break;
761 case EBML_STR:
762 case EBML_UTF8:
763 *(char **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s);
764 break;
765 }
766
Aurelien Jacobs6314cca2008-08-05 00:42:23767 while (!res && !ebml_level_end(matroska))
Aurelien Jacobs66a37e02008-08-05 00:42:17768 res = ebml_parse(matroska, syntax, data);
Aurelien Jacobs789ed102008-08-05 00:40:00769
770 return res;
771}
772
Aurelien Jacobs737c40d2008-08-05 00:42:39773static int ebml_parse_elem(MatroskaDemuxContext *matroska,
774 EbmlSyntax *syntax, void *data)
775{
776 ByteIOContext *pb = matroska->ctx->pb;
777 uint32_t id = syntax->id;
778 uint64_t length;
779 int res;
780
781 data = (char *)data + syntax->data_offset;
782 if (syntax->list_elem_size) {
783 EbmlList *list = data;
784 list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
785 data = (char*)list->elem + list->nb_elem*syntax->list_elem_size;
786 memset(data, 0, syntax->list_elem_size);
787 list->nb_elem++;
788 }
789
790 if (syntax->type != EBML_PASS && syntax->type != EBML_STOP)
Aurelien Jacobsc1e01132008-08-05 00:42:52791 if ((res = ebml_read_num(matroska, pb, 8, &length)) < 0)
Aurelien Jacobs737c40d2008-08-05 00:42:39792 return res;
793
794 switch (syntax->type) {
795 case EBML_UINT: res = ebml_read_uint (pb, length, data); break;
796 case EBML_FLOAT: res = ebml_read_float (pb, length, data); break;
797 case EBML_STR:
798 case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break;
799 case EBML_BIN: res = ebml_read_binary(pb, length, data); break;
800 case EBML_NEST: if ((res=ebml_read_master(matroska, length)) < 0)
801 return res;
802 if (id == MATROSKA_ID_SEGMENT)
803 matroska->segment_start = url_ftell(matroska->ctx->pb);
804 return ebml_parse_nest(matroska, syntax->def.n, data);
805 case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data);
806 case EBML_STOP: *(int *)data = 1; return 1;
807 default: url_fskip(pb, length); return 0;
808 }
809 if (res == AVERROR_INVALIDDATA)
810 av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n");
811 else if (res == AVERROR(EIO))
812 av_log(matroska->ctx, AV_LOG_ERROR, "Read error\n");
813 return res;
814}
815
Aurelien Jacobs789ed102008-08-05 00:40:00816static void ebml_free(EbmlSyntax *syntax, void *data)
817{
818 int i, j;
819 for (i=0; syntax[i].id; i++) {
820 void *data_off = (char *)data + syntax[i].data_offset;
821 switch (syntax[i].type) {
822 case EBML_STR:
823 case EBML_UTF8: av_freep(data_off); break;
824 case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break;
825 case EBML_NEST:
826 if (syntax[i].list_elem_size) {
827 EbmlList *list = data_off;
828 char *ptr = list->elem;
829 for (j=0; j<list->nb_elem; j++, ptr+=syntax[i].list_elem_size)
830 ebml_free(syntax[i].def.n, ptr);
831 av_free(list->elem);
832 } else
833 ebml_free(syntax[i].def.n, data_off);
834 default: break;
835 }
836 }
837}
838
Aurelien Jacobs737c40d2008-08-05 00:42:39839
840/*
841 * Autodetecting...
842 */
843static int matroska_probe(AVProbeData *p)
844{
845 uint64_t total = 0;
846 int len_mask = 0x80, size = 1, n = 1;
847 char probe_data[] = "matroska";
848
Diego Biurrun5968d2d2008-08-05 08:28:57849 /* EBML header? */
Aurelien Jacobs737c40d2008-08-05 00:42:39850 if (AV_RB32(p->buf) != EBML_ID_HEADER)
851 return 0;
852
853 /* length of header */
854 total = p->buf[4];
855 while (size <= 8 && !(total & len_mask)) {
856 size++;
857 len_mask >>= 1;
858 }
859 if (size > 8)
860 return 0;
861 total &= (len_mask - 1);
862 while (n < size)
863 total = (total << 8) | p->buf[4 + n++];
864
Diego Biurrun5968d2d2008-08-05 08:28:57865 /* Does the probe data contain the whole header? */
Aurelien Jacobs737c40d2008-08-05 00:42:39866 if (p->buf_size < 4 + size + total)
867 return 0;
868
Diego Biurrun5968d2d2008-08-05 08:28:57869 /* The header must contain the document type 'matroska'. For now,
Aurelien Jacobs737c40d2008-08-05 00:42:39870 * we don't parse the whole header but simply check for the
871 * availability of that array of characters inside the header.
872 * Not fully fool-proof, but good enough. */
873 for (n = 4+size; n <= 4+size+total-(sizeof(probe_data)-1); n++)
874 if (!memcmp(p->buf+n, probe_data, sizeof(probe_data)-1))
875 return AVPROBE_SCORE_MAX;
876
877 return 0;
878}
879
880static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
881 int num)
882{
883 MatroskaTrack *tracks = matroska->tracks.elem;
884 int i;
885
886 for (i=0; i < matroska->tracks.nb_elem; i++)
887 if (tracks[i].num == num)
888 return &tracks[i];
889
890 av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num);
891 return NULL;
892}
893
Aurelien Jacobsf7b96872008-08-05 00:42:05894static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
895 MatroskaTrack *track)
Evgeniy Stepanov935ec5a2008-06-22 15:49:44896{
Aurelien Jacobs2cbc8812008-08-05 00:40:31897 MatroskaTrackEncoding *encodings = track->encodings.elem;
Evgeniy Stepanov935ec5a2008-06-22 15:49:44898 uint8_t* data = *buf;
899 int isize = *buf_size;
900 uint8_t* pkt_data = NULL;
901 int pkt_size = isize;
902 int result = 0;
903 int olen;
904
Aurelien Jacobs2cbc8812008-08-05 00:40:31905 switch (encodings[0].compression.algo) {
Evgeniy Stepanov935ec5a2008-06-22 15:49:44906 case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP:
Aurelien Jacobs2cbc8812008-08-05 00:40:31907 return encodings[0].compression.settings.size;
Evgeniy Stepanov935ec5a2008-06-22 15:49:44908 case MATROSKA_TRACK_ENCODING_COMP_LZO:
909 do {
910 olen = pkt_size *= 3;
911 pkt_data = av_realloc(pkt_data,
912 pkt_size+LZO_OUTPUT_PADDING);
913 result = lzo1x_decode(pkt_data, &olen, data, &isize);
914 } while (result==LZO_OUTPUT_FULL && pkt_size<10000000);
915 if (result)
916 goto failed;
917 pkt_size -= olen;
918 break;
919#ifdef CONFIG_ZLIB
920 case MATROSKA_TRACK_ENCODING_COMP_ZLIB: {
921 z_stream zstream = {0};
922 if (inflateInit(&zstream) != Z_OK)
923 return -1;
924 zstream.next_in = data;
925 zstream.avail_in = isize;
926 do {
927 pkt_size *= 3;
928 pkt_data = av_realloc(pkt_data, pkt_size);
929 zstream.avail_out = pkt_size - zstream.total_out;
930 zstream.next_out = pkt_data + zstream.total_out;
931 result = inflate(&zstream, Z_NO_FLUSH);
932 } while (result==Z_OK && pkt_size<10000000);
933 pkt_size = zstream.total_out;
934 inflateEnd(&zstream);
935 if (result != Z_STREAM_END)
936 goto failed;
937 break;
938 }
939#endif
940#ifdef CONFIG_BZLIB
941 case MATROSKA_TRACK_ENCODING_COMP_BZLIB: {
942 bz_stream bzstream = {0};
943 if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)
944 return -1;
945 bzstream.next_in = data;
946 bzstream.avail_in = isize;
947 do {
948 pkt_size *= 3;
949 pkt_data = av_realloc(pkt_data, pkt_size);
950 bzstream.avail_out = pkt_size - bzstream.total_out_lo32;
951 bzstream.next_out = pkt_data + bzstream.total_out_lo32;
952 result = BZ2_bzDecompress(&bzstream);
953 } while (result==BZ_OK && pkt_size<10000000);
954 pkt_size = bzstream.total_out_lo32;
955 BZ2_bzDecompressEnd(&bzstream);
956 if (result != BZ_STREAM_END)
957 goto failed;
958 break;
959 }
960#endif
961 }
962
963 *buf = pkt_data;
964 *buf_size = pkt_size;
965 return 0;
966 failed:
967 av_free(pkt_data);
968 return -1;
969}
970
Aurelien Jacobs44015c52008-08-08 23:50:38971static void matroska_convert_tags(AVFormatContext *s, EbmlList *list)
972{
973 MatroskaTag *tags = list->elem;
974 int i, j;
975
976 for (i=0; i < list->nb_elem; i++) {
977 for (j=0; j < ARRAY_SIZE(metadata); j++){
978 if (!strcmp(tags[i].name, metadata[j].name)) {
979 int *ptr = (int *)((char *)s + metadata[j].offset);
980 if (*ptr) continue;
981 if (metadata[j].size > sizeof(int))
982 av_strlcpy((char *)ptr, tags[i].string, metadata[j].size);
983 else
984 *ptr = atoi(tags[i].string);
985 }
986 }
987 if (tags[i].sub.nb_elem)
988 matroska_convert_tags(s, &tags[i].sub);
989 }
990}
991
Aurelien Jacobsf7b96872008-08-05 00:42:05992static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
Aurelien Jacobs13b350a2008-08-05 00:40:36993{
994 EbmlList *seekhead_list = &matroska->seekhead;
995 MatroskaSeekhead *seekhead = seekhead_list->elem;
Aurelien Jacobs13b350a2008-08-05 00:40:36996 uint32_t level_up = matroska->level_up;
997 offset_t before_pos = url_ftell(matroska->ctx->pb);
Aurelien Jacobs13b350a2008-08-05 00:40:36998 MatroskaLevel level;
Aurelien Jacobsf06a4882008-08-05 00:41:01999 int i;
David Conradb061d892007-06-04 22:10:541000
Aurelien Jacobs13b350a2008-08-05 00:40:361001 for (i=0; i<seekhead_list->nb_elem; i++) {
Aurelien Jacobs66cfc382008-08-05 00:42:331002 offset_t offset = seekhead[i].pos + matroska->segment_start;
1003
Aurelien Jacobs13b350a2008-08-05 00:40:361004 if (seekhead[i].pos <= before_pos
1005 || seekhead[i].id == MATROSKA_ID_SEEKHEAD
1006 || seekhead[i].id == MATROSKA_ID_CLUSTER)
1007 continue;
David Conradb061d892007-06-04 22:10:541008
Aurelien Jacobs43485712008-08-05 00:40:431009 /* seek */
Aurelien Jacobs66cfc382008-08-05 00:42:331010 if (url_fseek(matroska->ctx->pb, offset, SEEK_SET) != offset)
Aurelien Jacobs43485712008-08-05 00:40:431011 continue;
David Conradb061d892007-06-04 22:10:541012
Diego Biurrun5968d2d2008-08-05 08:28:571013 /* We don't want to lose our seekhead level, so we add
Aurelien Jacobs43485712008-08-05 00:40:431014 * a dummy. This is a crude hack. */
1015 if (matroska->num_levels == EBML_MAX_DEPTH) {
1016 av_log(matroska->ctx, AV_LOG_INFO,
1017 "Max EBML element depth (%d) reached, "
1018 "cannot parse further.\n", EBML_MAX_DEPTH);
1019 break;
1020 }
David Conradb061d892007-06-04 22:10:541021
Aurelien Jacobs43485712008-08-05 00:40:431022 level.start = 0;
1023 level.length = (uint64_t)-1;
1024 matroska->levels[matroska->num_levels] = level;
1025 matroska->num_levels++;
David Conradb061d892007-06-04 22:10:541026
Aurelien Jacobs66a37e02008-08-05 00:42:171027 ebml_parse(matroska, matroska_segment, matroska);
David Conradb061d892007-06-04 22:10:541028
Aurelien Jacobs43485712008-08-05 00:40:431029 /* remove dummy level */
1030 while (matroska->num_levels) {
1031 uint64_t length = matroska->levels[--matroska->num_levels].length;
1032 if (length == (uint64_t)-1)
1033 break;
1034 }
David Conradb061d892007-06-04 22:10:541035 }
1036
Aurelien Jacobs43485712008-08-05 00:40:431037 /* seek back */
Aurelien Jacobs66cfc382008-08-05 00:42:331038 url_fseek(matroska->ctx->pb, before_pos, SEEK_SET);
Aurelien Jacobs43485712008-08-05 00:40:431039 matroska->level_up = level_up;
David Conradb061d892007-06-04 22:10:541040}
1041
Aurelien Jacobsf7b96872008-08-05 00:42:051042static int matroska_aac_profile(char *codec_id)
David Conradb061d892007-06-04 22:10:541043{
Aurelien Jacobs8f35a2c2008-08-05 00:41:221044 static const char *aac_profiles[] = { "MAIN", "LC", "SSR" };
David Conradb061d892007-06-04 22:10:541045 int profile;
1046
1047 for (profile=0; profile<ARRAY_SIZE(aac_profiles); profile++)
1048 if (strstr(codec_id, aac_profiles[profile]))
1049 break;
1050 return profile + 1;
1051}
1052
Aurelien Jacobsf7b96872008-08-05 00:42:051053static int matroska_aac_sri(int samplerate)
David Conradb061d892007-06-04 22:10:541054{
David Conradb061d892007-06-04 22:10:541055 int sri;
1056
Aurelien Jacobs7bfacd42008-04-02 21:41:481057 for (sri=0; sri<ARRAY_SIZE(ff_mpeg4audio_sample_rates); sri++)
1058 if (ff_mpeg4audio_sample_rates[sri] == samplerate)
David Conradb061d892007-06-04 22:10:541059 break;
1060 return sri;
1061}
1062
Aurelien Jacobsf7b96872008-08-05 00:42:051063static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
David Conradb061d892007-06-04 22:10:541064{
1065 MatroskaDemuxContext *matroska = s->priv_data;
Aurelien Jacobs9c25baf2008-08-05 00:40:551066 EbmlList *attachements_list = &matroska->attachments;
1067 MatroskaAttachement *attachements;
1068 EbmlList *chapters_list = &matroska->chapters;
1069 MatroskaChapter *chapters;
Aurelien Jacobs9a9a3b02008-08-05 00:40:491070 MatroskaTrack *tracks;
Aurelien Jacobse5929fd2008-08-05 00:40:151071 EbmlList *index_list;
1072 MatroskaIndex *index;
Aurelien Jacobs63511322008-08-05 00:40:021073 Ebml ebml = { 0 };
Aurelien Jacobs9a9a3b02008-08-05 00:40:491074 AVStream *st;
Aurelien Jacobsce6f28b2008-08-05 00:40:581075 int i, j;
David Conradb061d892007-06-04 22:10:541076
1077 matroska->ctx = s;
1078
1079 /* First read the EBML header. */
Aurelien Jacobsc4d3d9b2008-08-05 00:42:201080 if (ebml_parse(matroska, ebml_syntax, &ebml)
Aurelien Jacobs63511322008-08-05 00:40:021081 || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t)
1082 || ebml.id_length > sizeof(uint32_t) || strcmp(ebml.doctype, "matroska")
1083 || ebml.doctype_version > 2) {
David Conradb061d892007-06-04 22:10:541084 av_log(matroska->ctx, AV_LOG_ERROR,
Aurelien Jacobs63511322008-08-05 00:40:021085 "EBML header using unsupported features\n"
1086 "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
1087 ebml.version, ebml.doctype, ebml.doctype_version);
David Conradb061d892007-06-04 22:10:541088 return AVERROR_NOFMT;
1089 }
Aurelien Jacobs63511322008-08-05 00:40:021090 ebml_free(ebml_syntax, &ebml);
David Conradb061d892007-06-04 22:10:541091
1092 /* The next thing is a segment. */
Aurelien Jacobsc4d3d9b2008-08-05 00:42:201093 if (ebml_parse(matroska, matroska_segments, matroska) < 0)
Aurelien Jacobsce6f28b2008-08-05 00:40:581094 return -1;
Aurelien Jacobs13b350a2008-08-05 00:40:361095 matroska_execute_seekhead(matroska);
David Conradb061d892007-06-04 22:10:541096
Aurelien Jacobs9c25baf2008-08-05 00:40:551097 if (matroska->duration)
1098 matroska->ctx->duration = matroska->duration * matroska->time_scale
1099 * 1000 / AV_TIME_BASE;
1100 if (matroska->title)
1101 strncpy(matroska->ctx->title, matroska->title,
1102 sizeof(matroska->ctx->title)-1);
Aurelien Jacobs44015c52008-08-08 23:50:381103 matroska_convert_tags(s, &matroska->tags);
Aurelien Jacobs9c25baf2008-08-05 00:40:551104
Aurelien Jacobsd88d8062008-08-05 00:40:521105 tracks = matroska->tracks.elem;
1106 for (i=0; i < matroska->tracks.nb_elem; i++) {
1107 MatroskaTrack *track = &tracks[i];
1108 enum CodecID codec_id = CODEC_ID_NONE;
Aurelien Jacobs9c25baf2008-08-05 00:40:551109 EbmlList *encodings_list = &tracks->encodings;
1110 MatroskaTrackEncoding *encodings = encodings_list->elem;
Aurelien Jacobsd88d8062008-08-05 00:40:521111 uint8_t *extradata = NULL;
1112 int extradata_size = 0;
1113 int extradata_offset = 0;
David Conradb061d892007-06-04 22:10:541114
Aurelien Jacobsd88d8062008-08-05 00:40:521115 /* Apply some sanity checks. */
Aurelien Jacobs9c25baf2008-08-05 00:40:551116 if (track->type != MATROSKA_TRACK_TYPE_VIDEO &&
1117 track->type != MATROSKA_TRACK_TYPE_AUDIO &&
1118 track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
1119 av_log(matroska->ctx, AV_LOG_INFO,
1120 "Unknown or unsupported track type %"PRIu64"\n",
1121 track->type);
1122 continue;
1123 }
Aurelien Jacobsd88d8062008-08-05 00:40:521124 if (track->codec_id == NULL)
1125 continue;
David Conradb061d892007-06-04 22:10:541126
Aurelien Jacobs9c25baf2008-08-05 00:40:551127 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
1128 if (!track->default_duration)
1129 track->default_duration = 1000000000/track->video.frame_rate;
1130 if (!track->video.display_width)
1131 track->video.display_width = track->video.pixel_width;
1132 if (!track->video.display_height)
1133 track->video.display_height = track->video.pixel_height;
1134 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
1135 if (!track->audio.out_samplerate)
1136 track->audio.out_samplerate = track->audio.samplerate;
1137 }
1138 if (encodings_list->nb_elem > 1) {
1139 av_log(matroska->ctx, AV_LOG_ERROR,
1140 "Multiple combined encodings no supported");
1141 } else if (encodings_list->nb_elem == 1) {
1142 if (encodings[0].type ||
1143 (encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP &&
1144#ifdef CONFIG_ZLIB
1145 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB &&
1146#endif
1147#ifdef CONFIG_BZLIB
1148 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB &&
1149#endif
1150 encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO)) {
1151 encodings[0].scope = 0;
1152 av_log(matroska->ctx, AV_LOG_ERROR,
1153 "Unsupported encoding type");
1154 } else if (track->codec_priv.size && encodings[0].scope&2) {
1155 uint8_t *codec_priv = track->codec_priv.data;
1156 int offset = matroska_decode_buffer(&track->codec_priv.data,
1157 &track->codec_priv.size,
1158 track);
1159 if (offset < 0) {
1160 track->codec_priv.data = NULL;
1161 track->codec_priv.size = 0;
1162 av_log(matroska->ctx, AV_LOG_ERROR,
1163 "Failed to decode codec private data\n");
1164 } else if (offset > 0) {
1165 track->codec_priv.data = av_malloc(track->codec_priv.size + offset);
1166 memcpy(track->codec_priv.data,
1167 encodings[0].compression.settings.data, offset);
1168 memcpy(track->codec_priv.data+offset, codec_priv,
1169 track->codec_priv.size);
1170 track->codec_priv.size += offset;
1171 }
1172 if (codec_priv != track->codec_priv.data)
1173 av_free(codec_priv);
1174 }
1175 }
1176
Aurelien Jacobsd88d8062008-08-05 00:40:521177 for(j=0; ff_mkv_codec_tags[j].id != CODEC_ID_NONE; j++){
1178 if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id,
1179 strlen(ff_mkv_codec_tags[j].str))){
1180 codec_id= ff_mkv_codec_tags[j].id;
1181 break;
David Conradb061d892007-06-04 22:10:541182 }
Aurelien Jacobsd88d8062008-08-05 00:40:521183 }
David Conradb061d892007-06-04 22:10:541184
Aurelien Jacobscc70d142008-08-05 00:43:011185 st = track->stream = av_new_stream(s, 0);
Aurelien Jacobsd88d8062008-08-05 00:40:521186 if (st == NULL)
1187 return AVERROR(ENOMEM);
1188
Aurelien Jacobscc8be502008-08-05 00:42:491189 if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC")
Aurelien Jacobs28ba69e2008-08-05 00:41:311190 && track->codec_priv.size >= 40
1191 && track->codec_priv.data != NULL) {
Aurelien Jacobsd88d8062008-08-05 00:40:521192 track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
1193 codec_id = codec_get_id(codec_bmp_tags, track->video.fourcc);
Aurelien Jacobscc8be502008-08-05 00:42:491194 } else if (!strcmp(track->codec_id, "A_MS/ACM")
Aurelien Jacobs28ba69e2008-08-05 00:41:311195 && track->codec_priv.size >= 18
1196 && track->codec_priv.data != NULL) {
Aurelien Jacobsd88d8062008-08-05 00:40:521197 uint16_t tag = AV_RL16(track->codec_priv.data);
1198 codec_id = codec_get_id(codec_wav_tags, tag);
Aurelien Jacobs28ba69e2008-08-05 00:41:311199 } else if (!strcmp(track->codec_id, "V_QUICKTIME")
1200 && (track->codec_priv.size >= 86)
1201 && (track->codec_priv.data != NULL)) {
Aurelien Jacobsd88d8062008-08-05 00:40:521202 track->video.fourcc = AV_RL32(track->codec_priv.data);
1203 codec_id=codec_get_id(codec_movvideo_tags, track->video.fourcc);
Aurelien Jacobs28ba69e2008-08-05 00:41:311204 } else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) {
Aurelien Jacobsd88d8062008-08-05 00:40:521205 int profile = matroska_aac_profile(track->codec_id);
1206 int sri = matroska_aac_sri(track->audio.samplerate);
1207 extradata = av_malloc(5);
1208 if (extradata == NULL)
Aurelien Jacobs28f450a2008-08-05 00:40:091209 return AVERROR(ENOMEM);
Aurelien Jacobsd88d8062008-08-05 00:40:521210 extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
1211 extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3);
1212 if (strstr(track->codec_id, "SBR")) {
1213 sri = matroska_aac_sri(track->audio.out_samplerate);
1214 extradata[2] = 0x56;
1215 extradata[3] = 0xE5;
1216 extradata[4] = 0x80 | (sri<<3);
1217 extradata_size = 5;
Aurelien Jacobs16f97ab2008-08-05 00:41:101218 } else
Aurelien Jacobsd88d8062008-08-05 00:40:521219 extradata_size = 2;
Aurelien Jacobs28ba69e2008-08-05 00:41:311220 } else if (codec_id == CODEC_ID_TTA) {
Aurelien Jacobsd88d8062008-08-05 00:40:521221 ByteIOContext b;
1222 extradata_size = 30;
1223 extradata = av_mallocz(extradata_size);
1224 if (extradata == NULL)
1225 return AVERROR(ENOMEM);
1226 init_put_byte(&b, extradata, extradata_size, 1,
1227 NULL, NULL, NULL, NULL);
1228 put_buffer(&b, "TTA1", 4);
1229 put_le16(&b, 1);
1230 put_le16(&b, track->audio.channels);
1231 put_le16(&b, track->audio.bitdepth);
1232 put_le32(&b, track->audio.out_samplerate);
1233 put_le32(&b, matroska->ctx->duration * track->audio.out_samplerate);
Aurelien Jacobs28ba69e2008-08-05 00:41:311234 } else if (codec_id == CODEC_ID_RV10 || codec_id == CODEC_ID_RV20 ||
1235 codec_id == CODEC_ID_RV30 || codec_id == CODEC_ID_RV40) {
Aurelien Jacobsd88d8062008-08-05 00:40:521236 extradata_offset = 26;
1237 track->codec_priv.size -= extradata_offset;
Aurelien Jacobs28ba69e2008-08-05 00:41:311238 } else if (codec_id == CODEC_ID_RA_144) {
Aurelien Jacobsd88d8062008-08-05 00:40:521239 track->audio.out_samplerate = 8000;
1240 track->audio.channels = 1;
Aurelien Jacobs28ba69e2008-08-05 00:41:311241 } else if (codec_id == CODEC_ID_RA_288 || codec_id == CODEC_ID_COOK ||
1242 codec_id == CODEC_ID_ATRAC3) {
Aurelien Jacobsd88d8062008-08-05 00:40:521243 ByteIOContext b;
David Conradb061d892007-06-04 22:10:541244
Aurelien Jacobsd88d8062008-08-05 00:40:521245 init_put_byte(&b, track->codec_priv.data,track->codec_priv.size,
1246 0, NULL, NULL, NULL, NULL);
1247 url_fskip(&b, 24);
1248 track->audio.coded_framesize = get_be32(&b);
1249 url_fskip(&b, 12);
1250 track->audio.sub_packet_h = get_be16(&b);
1251 track->audio.frame_size = get_be16(&b);
1252 track->audio.sub_packet_size = get_be16(&b);
1253 track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h);
1254 if (codec_id == CODEC_ID_RA_288) {
1255 st->codec->block_align = track->audio.coded_framesize;
1256 track->codec_priv.size = 0;
1257 } else {
1258 st->codec->block_align = track->audio.sub_packet_size;
1259 extradata_offset = 78;
Aurelien Jacobs2cbc8812008-08-05 00:40:311260 track->codec_priv.size -= extradata_offset;
David Conradb061d892007-06-04 22:10:541261 }
David Conradb061d892007-06-04 22:10:541262 }
Aurelien Jacobsd88d8062008-08-05 00:40:521263
Aurelien Jacobs16f97ab2008-08-05 00:41:101264 if (codec_id == CODEC_ID_NONE)
Aurelien Jacobsd88d8062008-08-05 00:40:521265 av_log(matroska->ctx, AV_LOG_INFO,
Aurelien Jacobs8f35a2c2008-08-05 00:41:221266 "Unknown/unsupported CodecID %s.\n", track->codec_id);
Aurelien Jacobsd88d8062008-08-05 00:40:521267
1268 av_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */
1269
1270 st->codec->codec_id = codec_id;
1271 st->start_time = 0;
1272 if (strcmp(track->language, "und"))
1273 av_strlcpy(st->language, track->language, 4);
1274
1275 if (track->flag_default)
1276 st->disposition |= AV_DISPOSITION_DEFAULT;
1277
1278 if (track->default_duration)
1279 av_reduce(&st->codec->time_base.num, &st->codec->time_base.den,
1280 track->default_duration, 1000000000, 30000);
1281
1282 if(extradata){
1283 st->codec->extradata = extradata;
1284 st->codec->extradata_size = extradata_size;
1285 } else if(track->codec_priv.data && track->codec_priv.size > 0){
1286 st->codec->extradata = av_malloc(track->codec_priv.size);
1287 if(st->codec->extradata == NULL)
1288 return AVERROR(ENOMEM);
1289 st->codec->extradata_size = track->codec_priv.size;
1290 memcpy(st->codec->extradata,
1291 track->codec_priv.data + extradata_offset,
1292 track->codec_priv.size);
1293 }
1294
1295 if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
1296 st->codec->codec_type = CODEC_TYPE_VIDEO;
1297 st->codec->codec_tag = track->video.fourcc;
1298 st->codec->width = track->video.pixel_width;
1299 st->codec->height = track->video.pixel_height;
1300 av_reduce(&st->codec->sample_aspect_ratio.num,
1301 &st->codec->sample_aspect_ratio.den,
1302 st->codec->height * track->video.display_width,
1303 st->codec-> width * track->video.display_height,
1304 255);
1305 st->need_parsing = AVSTREAM_PARSE_HEADERS;
1306 } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
1307 st->codec->codec_type = CODEC_TYPE_AUDIO;
1308 st->codec->sample_rate = track->audio.out_samplerate;
1309 st->codec->channels = track->audio.channels;
1310 } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) {
1311 st->codec->codec_type = CODEC_TYPE_SUBTITLE;
1312 }
David Conradb061d892007-06-04 22:10:541313 }
1314
Aurelien Jacobs9c25baf2008-08-05 00:40:551315 attachements = attachements_list->elem;
1316 for (j=0; j<attachements_list->nb_elem; j++) {
1317 if (!(attachements[j].filename && attachements[j].mime &&
1318 attachements[j].bin.data && attachements[j].bin.size > 0)) {
1319 av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n");
1320 } else {
Aurelien Jacobscc70d142008-08-05 00:43:011321 AVStream *st = av_new_stream(s, 0);
Aurelien Jacobs9c25baf2008-08-05 00:40:551322 if (st == NULL)
1323 break;
1324 st->filename = av_strdup(attachements[j].filename);
1325 st->codec->codec_id = CODEC_ID_NONE;
1326 st->codec->codec_type = CODEC_TYPE_ATTACHMENT;
1327 st->codec->extradata = av_malloc(attachements[j].bin.size);
1328 if(st->codec->extradata == NULL)
1329 break;
1330 st->codec->extradata_size = attachements[j].bin.size;
1331 memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size);
1332
1333 for (i=0; ff_mkv_mime_tags[i].id != CODEC_ID_NONE; i++) {
1334 if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime,
1335 strlen(ff_mkv_mime_tags[i].str))) {
1336 st->codec->codec_id = ff_mkv_mime_tags[i].id;
1337 break;
1338 }
1339 }
1340 }
1341 }
1342
1343 chapters = chapters_list->elem;
1344 for (i=0; i<chapters_list->nb_elem; i++)
1345 if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid)
1346 ff_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000},
1347 chapters[i].start, chapters[i].end,
1348 chapters[i].title);
1349
Aurelien Jacobse5929fd2008-08-05 00:40:151350 index_list = &matroska->index;
1351 index = index_list->elem;
1352 for (i=0; i<index_list->nb_elem; i++) {
1353 EbmlList *pos_list = &index[i].pos;
1354 MatroskaIndexPos *pos = pos_list->elem;
1355 for (j=0; j<pos_list->nb_elem; j++) {
Aurelien Jacobs009ecd52008-08-05 00:40:121356 MatroskaTrack *track = matroska_find_track_by_num(matroska,
Aurelien Jacobse5929fd2008-08-05 00:40:151357 pos[j].track);
Aurelien Jacobs009ecd52008-08-05 00:40:121358 if (track && track->stream)
1359 av_add_index_entry(track->stream,
Aurelien Jacobse5929fd2008-08-05 00:40:151360 pos[j].pos + matroska->segment_start,
1361 index[i].time*matroska->time_scale/AV_TIME_BASE,
Aurelien Jacobsffaa3ec2007-06-24 21:50:091362 0, 0, AVINDEX_KEYFRAME);
David Conradb061d892007-06-04 22:10:541363 }
1364 }
1365
Aurelien Jacobsce6f28b2008-08-05 00:40:581366 return 0;
David Conradb061d892007-06-04 22:10:541367}
1368
Aurelien Jacobs737c40d2008-08-05 00:42:391369/*
Aurelien Jacobs737c40d2008-08-05 00:42:391370 * Put one packet in an application-supplied AVPacket struct.
1371 * Returns 0 on success or -1 on failure.
1372 */
1373static int matroska_deliver_packet(MatroskaDemuxContext *matroska,
1374 AVPacket *pkt)
1375{
1376 if (matroska->num_packets > 0) {
1377 memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
1378 av_free(matroska->packets[0]);
1379 if (matroska->num_packets > 1) {
1380 memmove(&matroska->packets[0], &matroska->packets[1],
1381 (matroska->num_packets - 1) * sizeof(AVPacket *));
1382 matroska->packets =
1383 av_realloc(matroska->packets, (matroska->num_packets - 1) *
1384 sizeof(AVPacket *));
1385 } else {
1386 av_freep(&matroska->packets);
1387 }
1388 matroska->num_packets--;
1389 return 0;
1390 }
1391
1392 return -1;
1393}
1394
1395/*
1396 * Free all packets in our internal queue.
1397 */
1398static void matroska_clear_queue(MatroskaDemuxContext *matroska)
1399{
1400 if (matroska->packets) {
1401 int n;
1402 for (n = 0; n < matroska->num_packets; n++) {
1403 av_free_packet(matroska->packets[n]);
1404 av_free(matroska->packets[n]);
1405 }
Aurelien Jacobs00a34312008-08-06 00:21:101406 av_freep(&matroska->packets);
Aurelien Jacobs737c40d2008-08-05 00:42:391407 matroska->num_packets = 0;
1408 }
1409}
1410
Aurelien Jacobsf7b96872008-08-05 00:42:051411static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
1412 int size, int64_t pos, uint64_t cluster_time,
1413 uint64_t duration, int is_keyframe)
David Conradb061d892007-06-04 22:10:541414{
Aurelien Jacobs009ecd52008-08-05 00:40:121415 MatroskaTrack *track;
David Conradb061d892007-06-04 22:10:541416 int res = 0;
David Conradb061d892007-06-04 22:10:541417 AVStream *st;
1418 AVPacket *pkt;
David Conradb061d892007-06-04 22:10:541419 int16_t block_time;
1420 uint32_t *lace_size = NULL;
1421 int n, flags, laces = 0;
1422 uint64_t num;
1423
Aurelien Jacobsc1e01132008-08-05 00:42:521424 if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
David Conradb061d892007-06-04 22:10:541425 av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
David Conradb061d892007-06-04 22:10:541426 return res;
1427 }
1428 data += n;
1429 size -= n;
1430
David Conradb061d892007-06-04 22:10:541431 track = matroska_find_track_by_num(matroska, num);
Aurelien Jacobs009ecd52008-08-05 00:40:121432 if (size <= 3 || !track || !track->stream) {
David Conradb061d892007-06-04 22:10:541433 av_log(matroska->ctx, AV_LOG_INFO,
Aurelien Jacobs009ecd52008-08-05 00:40:121434 "Invalid stream %"PRIu64" or size %u\n", num, size);
David Conradb061d892007-06-04 22:10:541435 return res;
1436 }
Aurelien Jacobs009ecd52008-08-05 00:40:121437 st = track->stream;
Aurelien Jacobs16f97ab2008-08-05 00:41:101438 if (st->discard >= AVDISCARD_ALL)
David Conradb061d892007-06-04 22:10:541439 return res;
David Conradb061d892007-06-04 22:10:541440 if (duration == AV_NOPTS_VALUE)
Aurelien Jacobs009ecd52008-08-05 00:40:121441 duration = track->default_duration / matroska->time_scale;
David Conradb061d892007-06-04 22:10:541442
Aurelien Jacobs2ce746c2007-06-23 12:32:191443 block_time = AV_RB16(data);
David Conradb061d892007-06-04 22:10:541444 data += 2;
Aurelien Jacobs1607c532007-06-23 12:49:361445 flags = *data++;
1446 size -= 3;
David Conradb061d892007-06-04 22:10:541447 if (is_keyframe == -1)
David Conrad84fa6e22007-08-31 18:24:091448 is_keyframe = flags & 0x80 ? PKT_FLAG_KEY : 0;
David Conradb061d892007-06-04 22:10:541449
1450 if (matroska->skip_to_keyframe) {
Aurelien Jacobs16f97ab2008-08-05 00:41:101451 if (!is_keyframe || st != matroska->skip_to_stream)
David Conradb061d892007-06-04 22:10:541452 return res;
1453 matroska->skip_to_keyframe = 0;
1454 }
1455
1456 switch ((flags & 0x06) >> 1) {
1457 case 0x0: /* no lacing */
1458 laces = 1;
1459 lace_size = av_mallocz(sizeof(int));
1460 lace_size[0] = size;
1461 break;
1462
Diego Biurrun5968d2d2008-08-05 08:28:571463 case 0x1: /* Xiph lacing */
David Conradb061d892007-06-04 22:10:541464 case 0x2: /* fixed-size lacing */
1465 case 0x3: /* EBML lacing */
Michael Niedermayer9bf8b562008-05-28 21:22:081466 assert(size>0); // size <=3 is checked before size-=3 above
David Conradb061d892007-06-04 22:10:541467 laces = (*data) + 1;
1468 data += 1;
1469 size -= 1;
1470 lace_size = av_mallocz(laces * sizeof(int));
1471
1472 switch ((flags & 0x06) >> 1) {
Diego Biurrun5968d2d2008-08-05 08:28:571473 case 0x1: /* Xiph lacing */ {
David Conradb061d892007-06-04 22:10:541474 uint8_t temp;
1475 uint32_t total = 0;
1476 for (n = 0; res == 0 && n < laces - 1; n++) {
1477 while (1) {
1478 if (size == 0) {
1479 res = -1;
1480 break;
1481 }
1482 temp = *data;
1483 lace_size[n] += temp;
1484 data += 1;
1485 size -= 1;
1486 if (temp != 0xff)
1487 break;
1488 }
1489 total += lace_size[n];
1490 }
1491 lace_size[n] = size - total;
1492 break;
1493 }
1494
1495 case 0x2: /* fixed-size lacing */
1496 for (n = 0; n < laces; n++)
1497 lace_size[n] = size / laces;
1498 break;
1499
1500 case 0x3: /* EBML lacing */ {
1501 uint32_t total;
Aurelien Jacobsc1e01132008-08-05 00:42:521502 n = matroska_ebmlnum_uint(matroska, data, size, &num);
David Conradb061d892007-06-04 22:10:541503 if (n < 0) {
1504 av_log(matroska->ctx, AV_LOG_INFO,
1505 "EBML block data error\n");
1506 break;
1507 }
1508 data += n;
1509 size -= n;
1510 total = lace_size[0] = num;
1511 for (n = 1; res == 0 && n < laces - 1; n++) {
1512 int64_t snum;
1513 int r;
Aurelien Jacobsc1e01132008-08-05 00:42:521514 r = matroska_ebmlnum_sint(matroska, data, size, &snum);
David Conradb061d892007-06-04 22:10:541515 if (r < 0) {
1516 av_log(matroska->ctx, AV_LOG_INFO,
1517 "EBML block data error\n");
1518 break;
1519 }
1520 data += r;
1521 size -= r;
1522 lace_size[n] = lace_size[n - 1] + snum;
1523 total += lace_size[n];
1524 }
1525 lace_size[n] = size - total;
1526 break;
1527 }
1528 }
1529 break;
1530 }
1531
1532 if (res == 0) {
David Conradb061d892007-06-04 22:10:541533 uint64_t timecode = AV_NOPTS_VALUE;
1534
Aurelien Jacobs9c3e2f72007-08-10 15:37:551535 if (cluster_time != (uint64_t)-1
1536 && (block_time >= 0 || cluster_time >= -block_time))
David Conradb061d892007-06-04 22:10:541537 timecode = cluster_time + block_time;
1538
1539 for (n = 0; n < laces; n++) {
Aurelien Jacobsba8a76b2007-10-21 22:27:241540 if (st->codec->codec_id == CODEC_ID_RA_288 ||
1541 st->codec->codec_id == CODEC_ID_COOK ||
1542 st->codec->codec_id == CODEC_ID_ATRAC3) {
Aurelien Jacobsba8a76b2007-10-21 22:27:241543 int a = st->codec->block_align;
Aurelien Jacobs2cbc8812008-08-05 00:40:311544 int sps = track->audio.sub_packet_size;
1545 int cfs = track->audio.coded_framesize;
1546 int h = track->audio.sub_packet_h;
1547 int y = track->audio.sub_packet_cnt;
1548 int w = track->audio.frame_size;
Aurelien Jacobsba8a76b2007-10-21 22:27:241549 int x;
Aurelien Jacobseabb8ba2007-06-04 22:19:171550
Aurelien Jacobs2cbc8812008-08-05 00:40:311551 if (!track->audio.pkt_cnt) {
Aurelien Jacobsba8a76b2007-10-21 22:27:241552 if (st->codec->codec_id == CODEC_ID_RA_288)
1553 for (x=0; x<h/2; x++)
Aurelien Jacobs2cbc8812008-08-05 00:40:311554 memcpy(track->audio.buf+x*2*w+y*cfs,
Aurelien Jacobsba8a76b2007-10-21 22:27:241555 data+x*cfs, cfs);
1556 else
1557 for (x=0; x<w/sps; x++)
Aurelien Jacobs2cbc8812008-08-05 00:40:311558 memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);
Aurelien Jacobseabb8ba2007-06-04 22:19:171559
Aurelien Jacobs2cbc8812008-08-05 00:40:311560 if (++track->audio.sub_packet_cnt >= h) {
1561 track->audio.sub_packet_cnt = 0;
1562 track->audio.pkt_cnt = h*w / a;
Aurelien Jacobseabb8ba2007-06-04 22:19:171563 }
Aurelien Jacobsba8a76b2007-10-21 22:27:241564 }
Aurelien Jacobs2cbc8812008-08-05 00:40:311565 while (track->audio.pkt_cnt) {
Aurelien Jacobs77abe5e2007-06-04 22:21:291566 pkt = av_mallocz(sizeof(AVPacket));
Aurelien Jacobsba8a76b2007-10-21 22:27:241567 av_new_packet(pkt, a);
Aurelien Jacobs2cbc8812008-08-05 00:40:311568 memcpy(pkt->data, track->audio.buf
1569 + a * (h*w / a - track->audio.pkt_cnt--), a);
Aurelien Jacobs77abe5e2007-06-04 22:21:291570 pkt->pos = pos;
Aurelien Jacobsfc4d3352008-08-05 00:40:061571 pkt->stream_index = st->index;
Anton Khirnovb8702532008-08-06 00:17:471572 dynarray_add(&matroska->packets,&matroska->num_packets,pkt);
Aurelien Jacobseabb8ba2007-06-04 22:19:171573 }
Aurelien Jacobsba8a76b2007-10-21 22:27:241574 } else {
Aurelien Jacobs2cbc8812008-08-05 00:40:311575 MatroskaTrackEncoding *encodings = track->encodings.elem;
Evgeniy Stepanov935ec5a2008-06-22 15:49:441576 int offset = 0, pkt_size = lace_size[n];
Aurelien Jacobsde3230f2008-05-09 01:53:591577 uint8_t *pkt_data = data;
David Conradb061d892007-06-04 22:10:541578
Aurelien Jacobs2cbc8812008-08-05 00:40:311579 if (encodings && encodings->scope & 1) {
Aurelien Jacobs8f35a2c2008-08-05 00:41:221580 offset = matroska_decode_buffer(&pkt_data,&pkt_size, track);
Evgeniy Stepanov935ec5a2008-06-22 15:49:441581 if (offset < 0)
1582 continue;
Aurelien Jacobs53a1e822008-05-08 21:47:311583 }
1584
Aurelien Jacobsba8a76b2007-10-21 22:27:241585 pkt = av_mallocz(sizeof(AVPacket));
1586 /* XXX: prevent data copy... */
Aurelien Jacobsde3230f2008-05-09 01:53:591587 if (av_new_packet(pkt, pkt_size+offset) < 0) {
Aurelien Jacobs34ae4092008-06-02 23:27:141588 av_free(pkt);
Aurelien Jacobsba8a76b2007-10-21 22:27:241589 res = AVERROR(ENOMEM);
1590 n = laces-1;
1591 break;
1592 }
Aurelien Jacobs53a1e822008-05-08 21:47:311593 if (offset)
Aurelien Jacobs2cbc8812008-08-05 00:40:311594 memcpy (pkt->data, encodings->compression.settings.data, offset);
Aurelien Jacobsde3230f2008-05-09 01:53:591595 memcpy (pkt->data+offset, pkt_data, pkt_size);
Aurelien Jacobsba8a76b2007-10-21 22:27:241596
Aurelien Jacobs51e1cc12008-06-22 15:46:361597 if (pkt_data != data)
1598 av_free(pkt_data);
1599
Aurelien Jacobsba8a76b2007-10-21 22:27:241600 if (n == 0)
1601 pkt->flags = is_keyframe;
Aurelien Jacobsfc4d3352008-08-05 00:40:061602 pkt->stream_index = st->index;
Aurelien Jacobsba8a76b2007-10-21 22:27:241603
1604 pkt->pts = timecode;
1605 pkt->pos = pos;
1606 pkt->duration = duration;
1607
Anton Khirnovb8702532008-08-06 00:17:471608 dynarray_add(&matroska->packets, &matroska->num_packets, pkt);
Aurelien Jacobsba8a76b2007-10-21 22:27:241609 }
1610
1611 if (timecode != AV_NOPTS_VALUE)
1612 timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
David Conradb061d892007-06-04 22:10:541613 data += lace_size[n];
1614 }
1615 }
1616
1617 av_free(lace_size);
David Conradb061d892007-06-04 22:10:541618 return res;
1619}
1620
Aurelien Jacobsf7b96872008-08-05 00:42:051621static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
David Conradb061d892007-06-04 22:10:541622{
Aurelien Jacobs209472b2008-08-05 00:41:051623 MatroskaCluster cluster = { 0 };
1624 EbmlList *blocks_list;
1625 MatroskaBlock *blocks;
Aurelien Jacobs38797632008-08-05 00:42:261626 int i, res;
1627 if (matroska->has_cluster_id){
Diego Biurrun5968d2d2008-08-05 08:28:571628 /* For the first cluster we parse, its ID was already read as
Aurelien Jacobs38797632008-08-05 00:42:261629 part of matroska_read_header(), so don't read it again */
1630 res = ebml_parse_id(matroska, matroska_clusters,
1631 MATROSKA_ID_CLUSTER, &cluster);
1632 matroska->has_cluster_id = 0;
1633 } else
1634 res = ebml_parse(matroska, matroska_clusters, &cluster);
Aurelien Jacobs209472b2008-08-05 00:41:051635 blocks_list = &cluster.blocks;
1636 blocks = blocks_list->elem;
Aurelien Jacobs131f1cb2008-08-13 09:36:451637 for (i=0; i<blocks_list->nb_elem; i++)
Aurelien Jacobs209472b2008-08-05 00:41:051638 if (blocks[i].bin.size > 0)
1639 res=matroska_parse_block(matroska,
1640 blocks[i].bin.data, blocks[i].bin.size,
1641 blocks[i].bin.pos, cluster.timecode,
1642 blocks[i].duration, !blocks[i].reference);
1643 ebml_free(matroska_cluster, &cluster);
David Conradb061d892007-06-04 22:10:541644 return res;
1645}
1646
Aurelien Jacobsf7b96872008-08-05 00:42:051647static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
David Conradb061d892007-06-04 22:10:541648{
1649 MatroskaDemuxContext *matroska = s->priv_data;
David Conradb061d892007-06-04 22:10:541650
David Conradb061d892007-06-04 22:10:541651 while (matroska_deliver_packet(matroska, pkt)) {
David Conradb061d892007-06-04 22:10:541652 if (matroska->done)
Panagiotis Issaris6f3e0b22007-07-19 15:23:321653 return AVERROR(EIO);
Aurelien Jacobs209472b2008-08-05 00:41:051654 if (matroska_parse_cluster(matroska) < 0)
David Conradb061d892007-06-04 22:10:541655 matroska->done = 1;
1656 }
1657
1658 return 0;
1659}
1660
Aurelien Jacobsf7b96872008-08-05 00:42:051661static int matroska_read_seek(AVFormatContext *s, int stream_index,
1662 int64_t timestamp, int flags)
David Conradb061d892007-06-04 22:10:541663{
1664 MatroskaDemuxContext *matroska = s->priv_data;
1665 AVStream *st = s->streams[stream_index];
1666 int index;
1667
David Conradb061d892007-06-04 22:10:541668 index = av_index_search_timestamp(st, timestamp, flags);
1669 if (index < 0)
1670 return 0;
1671
Aurelien Jacobs243cc4c2007-12-29 18:35:381672 matroska_clear_queue(matroska);
1673
Björn Axelsson899681c2007-11-21 07:41:001674 url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET);
David Conradb061d892007-06-04 22:10:541675 matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY);
1676 matroska->skip_to_stream = st;
Joakim Platede6a9a22008-06-11 19:54:171677 av_update_cur_dts(s, st, st->index_entries[index].timestamp);
David Conradb061d892007-06-04 22:10:541678 return 0;
1679}
1680
Aurelien Jacobsf7b96872008-08-05 00:42:051681static int matroska_read_close(AVFormatContext *s)
David Conradb061d892007-06-04 22:10:541682{
1683 MatroskaDemuxContext *matroska = s->priv_data;
Aurelien Jacobs2cbc8812008-08-05 00:40:311684 MatroskaTrack *tracks = matroska->tracks.elem;
Aurelien Jacobs70109c02008-08-05 00:41:131685 int n;
David Conradb061d892007-06-04 22:10:541686
Aurelien Jacobs34c9c1b2007-12-29 18:32:471687 matroska_clear_queue(matroska);
David Conradb061d892007-06-04 22:10:541688
Aurelien Jacobs2cbc8812008-08-05 00:40:311689 for (n=0; n < matroska->tracks.nb_elem; n++)
1690 if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO)
1691 av_free(tracks[n].audio.buf);
Aurelien Jacobsce6f28b2008-08-05 00:40:581692 ebml_free(matroska_segment, matroska);
David Conradb061d892007-06-04 22:10:541693
1694 return 0;
1695}
1696
1697AVInputFormat matroska_demuxer = {
1698 "matroska",
Stefano Sabatinibde15e72008-06-03 16:20:541699 NULL_IF_CONFIG_SMALL("Matroska file format"),
David Conradb061d892007-06-04 22:10:541700 sizeof(MatroskaDemuxContext),
1701 matroska_probe,
1702 matroska_read_header,
1703 matroska_read_packet,
1704 matroska_read_close,
1705 matroska_read_seek,
1706};