annotate matroskadec.c @ 6123:9f368d591c13 libavformat

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