Mercurial > mplayer.hg
annotate libmpdemux/demux_mkv.c @ 36295:0bd0297b073a
Handle special argument -1 to switch_ratio as intended.
Reset to the original aspect ratio that would have been used for
the very first rescaling rather than to the display size ratio.
This will now handle anamorphic videos correctly as well.
author | ib |
---|---|
date | Thu, 01 Aug 2013 21:18:14 +0000 |
parents | 34c05e3ea263 |
children | 139f2b064ef9 |
rev | line source |
---|---|
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1 /* |
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
2 * Matroska demuxer |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
3 * Copyright (C) 2004 Aurelien Jacobs <aurel@gnuage.org> |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
4 * Based on the one written by Ronald Bultje for gstreamer |
29238
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
5 * and on demux_mkv.cpp from Moritz Bunkus. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
6 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
7 * This file is part of MPlayer. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
8 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
9 * MPlayer is free software; you can redistribute it and/or modify |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
10 * it under the terms of the GNU General Public License as published by |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
11 * the Free Software Foundation; either version 2 of the License, or |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
12 * (at your option) any later version. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
13 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
14 * MPlayer is distributed in the hope that it will be useful, |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
17 * GNU General Public License for more details. |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
18 * |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
19 * You should have received a copy of the GNU General Public License along |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
d643e4643313
Add standard license header to all files in libmpdemux.
diego
parents:
28468
diff
changeset
|
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
22 */ |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
23 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
24 #include "config.h" |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
25 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
26 #include <stdlib.h> |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
27 #include <stdio.h> |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
28 #include <ctype.h> |
18558
4928dd61f136
Fix potential integer overflows in memory allocation.
rtogni
parents:
18507
diff
changeset
|
29 #include <inttypes.h> |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
30 |
22605
4d81dbdf46b9
Add explicit location for headers from the stream/ directory.
diego
parents:
22445
diff
changeset
|
31 #include "stream/stream.h" |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
32 #include "demuxer.h" |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
33 #include "stheader.h" |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
34 #include "ebml.h" |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
35 #include "matroska.h" |
30573
02420b32391b
Add separate header for real_fix_timestamp(); avoids forward declarations.
diego
parents:
30085
diff
changeset
|
36 #include "demux_real.h" |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
37 |
32461 | 38 #include "sub/ass_mp.h" |
20680 | 39 #include "mp_msg.h" |
40 #include "help_mp.h" | |
41 | |
32459
1a605463f62b
Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
32454
diff
changeset
|
42 #include "sub/vobsub.h" |
32454
69d3be4d52a2
Create a new directory, "sub", for subtitles and OSD related code.
cigaes
parents:
32225
diff
changeset
|
43 #include "sub/subreader.h" |
32467 | 44 #include "sub/sub.h" |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
45 |
22616 | 46 #include "libavutil/common.h" |
47 | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26752
diff
changeset
|
48 #ifdef CONFIG_QTX_CODECS |
22606
97343cedd966
Use explicit path for headers from the loader/ directory.
diego
parents:
22605
diff
changeset
|
49 #include "loader/qtx/qtxsdk/components.h" |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
50 #endif |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
51 |
28440 | 52 #if CONFIG_ZLIB |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
53 #include <zlib.h> |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
54 #endif |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
55 |
22081 | 56 #include "libavutil/lzo.h" |
23386
585d2136f018
Get rid of __attribute__((__packed__)) in Matroska demuxer
reimar
parents:
23310
diff
changeset
|
57 #include "libavutil/intreadwrite.h" |
23703
9fb716ab06a3
Avoid code duplication and ugly config.h hack by using av_strlcat/av_strlcpy
reimar
parents:
23630
diff
changeset
|
58 #include "libavutil/avstring.h" |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
59 |
31177 | 60 static const unsigned char sipr_swaps[38][2] = { |
18036 | 61 {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, |
62 {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, | |
63 {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, | |
64 {42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83}, | |
31177 | 65 {77,80} |
66 }; | |
18036 | 67 |
68 // Map flavour to bytes per second | |
69 #define SIPR_FLAVORS 4 | |
70 #define ATRC_FLAVORS 8 | |
71 #define COOK_FLAVORS 34 | |
31177 | 72 static const int sipr_fl2bps[SIPR_FLAVORS] = { 813, 1062, 625, 2000 }; |
73 static const int atrc_fl2bps[ATRC_FLAVORS] = { | |
74 8269, 11714, 13092, 16538, 18260, 22050, 33075, 44100 }; | |
75 static const int cook_fl2bps[COOK_FLAVORS] = { | |
76 1000, 1378, 2024, 2584, 4005, 5513, 8010, 4005, 750, 2498, | |
77 4048, 5513, 8010, 11973, 8010, 2584, 4005, 2067, 2584, 2584, | |
78 4005, 4005, 5513, 5513, 8010, 12059, 1550, 8010, 12059, 5513, | |
79 12016, 16408, 22911, 33506 | |
80 }; | |
81 | |
82 typedef struct { | |
83 uint32_t order, type, scope; | |
84 uint32_t comp_algo; | |
85 uint8_t *comp_settings; | |
32220 | 86 size_t comp_settings_len; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
87 } mkv_content_encoding_t; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
88 |
31177 | 89 typedef struct mkv_track { |
90 int tnum; | |
91 char *name; | |
92 | |
93 char *codec_id; | |
94 int ms_compat; | |
95 char *language; | |
96 | |
97 int type; | |
98 | |
99 uint32_t v_width, v_height, v_dwidth, v_dheight; | |
100 float v_frate; | |
101 | |
102 uint32_t a_formattag; | |
103 uint32_t a_channels, a_bps; | |
104 float a_sfreq; | |
105 | |
106 float default_duration; | |
107 | |
108 int default_track; | |
109 | |
110 void *private_data; | |
32220 | 111 size_t private_size; |
31177 | 112 |
113 /* stuff for realmedia */ | |
114 int realmedia; | |
115 int64_t rv_kf_base; | |
116 int rv_kf_pts; | |
117 float rv_pts; /* previous video timestamp */ | |
118 float ra_pts; /* previous audio timestamp */ | |
119 | |
120 /** realaudio descrambling */ | |
121 int sub_packet_size; ///< sub packet size, per stream | |
122 int sub_packet_h; ///< number of coded frames per block | |
123 int coded_framesize; ///< coded frame size, per stream | |
124 int audiopk_size; ///< audio packet size | |
125 unsigned char *audio_buf; ///< place to store reordered audio data | |
126 float *audio_timestamp; ///< timestamp for each audio packet | |
127 int sub_packet_cnt; ///< number of subpacket already received | |
128 int audio_filepos; ///< file position of first audio packet in block | |
129 | |
130 /* stuff for quicktime */ | |
131 int fix_i_bps; | |
132 float qt_last_a_pts; | |
133 | |
134 int subtitle_type; | |
135 | |
136 /* The timecodes of video frames might have to be reordered if they're | |
137 in display order (the timecodes, not the frames themselves!). In this | |
138 case demux packets have to be cached with the help of these variables. */ | |
139 int reorder_timecodes; | |
140 demux_packet_t **cached_dps; | |
141 int num_cached_dps, num_allocated_dps; | |
142 float max_pts; | |
143 | |
144 /* generic content encoding support */ | |
145 mkv_content_encoding_t *encodings; | |
146 int num_encodings; | |
147 | |
148 /* For VobSubs and SSA/ASS */ | |
149 sh_sub_t *sh_sub; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
150 } mkv_track_t; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
151 |
31177 | 152 typedef struct mkv_index { |
153 int tnum; | |
154 uint64_t timecode, filepos; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
155 } mkv_index_t; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
156 |
31177 | 157 typedef struct mkv_demuxer { |
158 off_t segment_start; | |
159 | |
160 float duration, last_pts; | |
161 uint64_t last_filepos; | |
162 | |
163 mkv_track_t **tracks; | |
164 int num_tracks; | |
165 | |
166 uint64_t tc_scale, cluster_tc, first_tc; | |
167 int has_first_tc; | |
168 | |
169 uint64_t cluster_size; | |
170 uint64_t blockgroup_size; | |
171 | |
172 mkv_index_t *indexes; | |
173 int num_indexes; | |
174 | |
175 off_t *parsed_cues; | |
176 int parsed_cues_num; | |
177 off_t *parsed_seekhead; | |
178 int parsed_seekhead_num; | |
179 | |
180 uint64_t *cluster_positions; | |
181 int num_cluster_pos; | |
182 | |
183 int64_t skip_to_timecode; | |
184 int v_skip_to_keyframe, a_skip_to_keyframe; | |
185 | |
186 int64_t stop_timecode; | |
187 | |
188 int last_aid; | |
189 int audio_tracks[MAX_A_STREAMS]; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
190 } mkv_demuxer_t; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
191 |
23386
585d2136f018
Get rid of __attribute__((__packed__)) in Matroska demuxer
reimar
parents:
23310
diff
changeset
|
192 #define REALHEADER_SIZE 16 |
585d2136f018
Get rid of __attribute__((__packed__)) in Matroska demuxer
reimar
parents:
23310
diff
changeset
|
193 #define RVPROPERTIES_SIZE 34 |
585d2136f018
Get rid of __attribute__((__packed__)) in Matroska demuxer
reimar
parents:
23310
diff
changeset
|
194 #define RAPROPERTIES4_SIZE 56 |
585d2136f018
Get rid of __attribute__((__packed__)) in Matroska demuxer
reimar
parents:
23310
diff
changeset
|
195 #define RAPROPERTIES5_SIZE 70 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
196 |
20140
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
197 /** |
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
198 * \brief ensures there is space for at least one additional element |
29691
183ea012e25b
Change grow_array argument from void ** to void *, this avoids a aliasing
reimar
parents:
29490
diff
changeset
|
199 * \param arrayp array to grow |
20140
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
200 * \param nelem current number of elements in array |
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
201 * \param elsize size of one array element |
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
202 */ |
31177 | 203 static void av_noinline grow_array(void *arrayp, int nelem, size_t elsize) |
204 { | |
205 void **array = arrayp; | |
206 void *oldp = *array; | |
207 if (nelem & 31) | |
208 return; | |
209 if (nelem > UINT_MAX / elsize - 32) | |
210 *array = NULL; | |
211 else | |
212 *array = realloc(*array, (nelem + 32) * elsize); | |
213 if (!*array) | |
214 free(oldp); | |
20140
1861d40674ca
Simplify (by using realloc with NULL parameter) and refactor code to grow
reimar
parents:
20137
diff
changeset
|
215 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
216 |
31177 | 217 static mkv_track_t *demux_mkv_find_track_by_num(mkv_demuxer_t *d, int n, |
218 int type) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
219 { |
31177 | 220 int i, id; |
221 | |
222 for (i = 0, id = 0; i < d->num_tracks; i++) | |
223 if (d->tracks[i] != NULL && d->tracks[i]->type == type) | |
224 if (id++ == n) | |
225 return d->tracks[i]; | |
226 | |
227 return NULL; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
228 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
229 |
31177 | 230 static void add_cluster_position(mkv_demuxer_t *mkv_d, uint64_t position) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
231 { |
31177 | 232 int i = mkv_d->num_cluster_pos; |
233 | |
234 while (i--) | |
235 if (mkv_d->cluster_positions[i] == position) | |
236 return; | |
237 | |
238 grow_array(&mkv_d->cluster_positions, mkv_d->num_cluster_pos, | |
239 sizeof(uint64_t)); | |
240 if (!mkv_d->cluster_positions) { | |
241 mkv_d->num_cluster_pos = 0; | |
242 return; | |
243 } | |
244 mkv_d->cluster_positions[mkv_d->num_cluster_pos++] = position; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
245 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
246 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
247 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
248 #define AAC_SYNC_EXTENSION_TYPE 0x02b7 |
31177 | 249 static int aac_get_sample_rate_index(uint32_t sample_rate) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
250 { |
31177 | 251 static const int srates[] = { |
252 92017, 75132, 55426, 46009, 37566, 27713, | |
253 23004, 18783, 13856, 11502, 9391, 0 | |
254 }; | |
255 int i = 0; | |
256 while (sample_rate < srates[i]) | |
257 i++; | |
258 return i; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
259 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
260 |
14054 | 261 /** \brief Free cached demux packets |
262 * | |
263 * Reordering the timecodes requires caching of demux packets. This function | |
264 * frees all these cached packets and the memory for the cached pointers | |
265 * itself. | |
266 * | |
267 * \param demuxer The demuxer for which the cache is to be freed. | |
268 */ | |
31177 | 269 static void free_cached_dps(demuxer_t *demuxer) |
14054 | 270 { |
31177 | 271 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
272 mkv_track_t *track; | |
273 int i, k; | |
274 | |
275 for (k = 0; k < mkv_d->num_tracks; k++) { | |
276 track = mkv_d->tracks[k]; | |
277 for (i = 0; i < track->num_cached_dps; i++) | |
278 free_demux_packet(track->cached_dps[i]); | |
279 free(track->cached_dps); | |
280 track->cached_dps = NULL; | |
281 track->num_cached_dps = 0; | |
282 track->num_allocated_dps = 0; | |
283 track->max_pts = 0; | |
14054 | 284 } |
285 } | |
286 | |
31177 | 287 static int demux_mkv_decode(mkv_track_t *track, uint8_t *src, |
32220 | 288 uint8_t **dest, size_t *size, uint32_t type) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
289 { |
31177 | 290 int i, result; |
291 int modified = 0; | |
292 | |
293 *dest = src; | |
294 if (track->num_encodings <= 0) | |
295 return 0; | |
296 | |
297 for (i = 0; i < track->num_encodings; i++) { | |
298 if (!(track->encodings[i].scope & type)) | |
299 continue; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
300 |
28440 | 301 #if CONFIG_ZLIB |
31177 | 302 if (track->encodings[i].comp_algo == 0) { |
303 /* zlib encoded track */ | |
304 z_stream zstream; | |
305 | |
306 zstream.zalloc = (alloc_func) 0; | |
307 zstream.zfree = (free_func) 0; | |
308 zstream.opaque = (voidpf) 0; | |
309 if (inflateInit(&zstream) != Z_OK) { | |
310 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
311 MSGTR_MPDEMUX_MKV_ZlibInitializationFailed); | |
312 return modified; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
313 } |
31177 | 314 zstream.next_in = (Bytef *) src; |
315 zstream.avail_in = *size; | |
316 | |
317 modified = 1; | |
318 *dest = NULL; | |
319 zstream.avail_out = *size; | |
320 do { | |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
321 if (*size > SIZE_MAX - 4000 - AV_LZO_INPUT_PADDING) |
32220 | 322 goto zlib_fail; |
323 | |
31177 | 324 *size += 4000; |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
325 *dest = realloc(*dest, *size + AV_LZO_INPUT_PADDING); |
32225
8ebdc8466b2f
Check for realloc failure. Ignore the memleak this causes since
reimar
parents:
32224
diff
changeset
|
326 if (!*dest) |
8ebdc8466b2f
Check for realloc failure. Ignore the memleak this causes since
reimar
parents:
32224
diff
changeset
|
327 goto zlib_fail; |
31177 | 328 zstream.next_out = (Bytef *) (*dest + zstream.total_out); |
329 result = inflate(&zstream, Z_NO_FLUSH); | |
330 if (result != Z_OK && result != Z_STREAM_END) { | |
32220 | 331 zlib_fail: |
31177 | 332 mp_msg(MSGT_DEMUX, MSGL_WARN, |
333 MSGTR_MPDEMUX_MKV_ZlibDecompressionFailed); | |
334 free(*dest); | |
335 *dest = NULL; | |
336 inflateEnd(&zstream); | |
337 return modified; | |
338 } | |
339 zstream.avail_out += 4000; | |
340 } while (zstream.avail_out == 4000 && zstream.avail_in != 0 | |
341 && result != Z_STREAM_END); | |
342 | |
343 *size = zstream.total_out; | |
344 inflateEnd(&zstream); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
345 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
346 #endif |
31177 | 347 if (track->encodings[i].comp_algo == 2) { |
348 /* lzo encoded track */ | |
32221
4034fb538bc1
Fix decoded length calculation of LZO decompression in demux_mkv.
reimar
parents:
32220
diff
changeset
|
349 int out_avail; |
32220 | 350 int dstlen = *size > SIZE_MAX/3 ? *size : *size * 3; |
31177 | 351 |
352 *dest = NULL; | |
353 while (1) { | |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
354 // Max of both because we might decompress the input multiple |
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
355 // times. Makes no sense but is possible. |
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
356 int padding = FFMAX(AV_LZO_OUTPUT_PADDING, AV_LZO_INPUT_PADDING); |
31177 | 357 int srclen = *size; |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
358 if (dstlen > SIZE_MAX - padding) |
31177 | 359 goto lzo_fail; |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
360 *dest = realloc(*dest, dstlen + padding); |
32225
8ebdc8466b2f
Check for realloc failure. Ignore the memleak this causes since
reimar
parents:
32224
diff
changeset
|
361 if (!*dest) |
8ebdc8466b2f
Check for realloc failure. Ignore the memleak this causes since
reimar
parents:
32224
diff
changeset
|
362 goto lzo_fail; |
32221
4034fb538bc1
Fix decoded length calculation of LZO decompression in demux_mkv.
reimar
parents:
32220
diff
changeset
|
363 out_avail = dstlen; |
4034fb538bc1
Fix decoded length calculation of LZO decompression in demux_mkv.
reimar
parents:
32220
diff
changeset
|
364 result = av_lzo1x_decode(*dest, &out_avail, src, &srclen); |
31177 | 365 if (result == 0) |
366 break; | |
367 if (!(result & AV_LZO_OUTPUT_FULL)) { | |
32222 | 368 lzo_fail: |
31177 | 369 mp_msg(MSGT_DEMUX, MSGL_WARN, |
370 MSGTR_MPDEMUX_MKV_LzoDecompressionFailed); | |
371 free(*dest); | |
372 *dest = NULL; | |
373 return modified; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
374 } |
31177 | 375 mp_msg(MSGT_DEMUX, MSGL_DBG2, |
376 "[mkv] lzo decompression buffer too small.\n"); | |
32224
23ba595c0292
Matroska allows data to be compressed multiple times, thus ensure
reimar
parents:
32223
diff
changeset
|
377 if (dstlen > (SIZE_MAX - padding)/2) |
32220 | 378 goto lzo_fail; |
31177 | 379 dstlen *= 2; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
380 } |
32221
4034fb538bc1
Fix decoded length calculation of LZO decompression in demux_mkv.
reimar
parents:
32220
diff
changeset
|
381 *size = dstlen - out_avail; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
382 } |
34398
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
383 else if (track->encodings[i].comp_algo == 3) |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
384 { |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
385 *dest = malloc (*size + track->encodings[i].comp_settings_len); |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
386 memcpy(*dest, track->encodings[i].comp_settings, |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
387 track->encodings[i].comp_settings_len); |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
388 memcpy(*dest + track->encodings[i].comp_settings_len, src, *size); |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
389 *size += track->encodings[i].comp_settings_len; |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
390 modified = 1; |
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
391 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
392 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
393 |
31177 | 394 return modified; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
395 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
396 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
397 |
31177 | 398 static int demux_mkv_read_info(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
399 { |
31177 | 400 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
401 stream_t *s = demuxer->stream; | |
402 uint64_t length, l; | |
403 int il; | |
404 uint64_t tc_scale = 1000000; | |
405 long double duration = 0.; | |
406 | |
407 length = ebml_read_length(s, NULL); | |
408 while (length > 0) { | |
409 switch (ebml_read_id(s, &il)) { | |
410 case MATROSKA_ID_TIMECODESCALE: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
411 { |
31177 | 412 uint64_t num = ebml_read_uint(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
413 if (num == EBML_UINT_INVALID) |
31177 | 414 return 1; |
19809
99d375aab4db
Fix movie duration calculation in case when TimecodeScale element comes after
eugeni
parents:
19645
diff
changeset
|
415 tc_scale = num; |
31177 | 416 mp_msg(MSGT_DEMUX, MSGL_V, |
417 "[mkv] | + timecode scale: %" PRIu64 "\n", tc_scale); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
418 break; |
31177 | 419 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
420 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
421 case MATROSKA_ID_DURATION: |
31177 | 422 { |
423 long double num = ebml_read_float(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
424 if (num == EBML_FLOAT_INVALID) |
31177 | 425 return 1; |
19809
99d375aab4db
Fix movie duration calculation in case when TimecodeScale element comes after
eugeni
parents:
19645
diff
changeset
|
426 duration = num; |
31177 | 427 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + duration: %.3Lfs\n", |
428 duration * tc_scale / 1000000000.0); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
429 break; |
31177 | 430 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
431 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
432 default: |
31177 | 433 ebml_read_skip(s, &l); |
434 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
435 } |
31177 | 436 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
437 } |
31177 | 438 mkv_d->tc_scale = tc_scale; |
439 mkv_d->duration = duration * tc_scale / 1000000000.0; | |
440 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
441 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
442 |
20133 | 443 /** |
444 * \brief free array of kv_content_encoding_t | |
445 * \param encodings pointer to array | |
446 * \param numencodings number of encodings in array | |
447 */ | |
31177 | 448 static void demux_mkv_free_encodings(mkv_content_encoding_t *encodings, |
449 int numencodings) | |
20133 | 450 { |
31177 | 451 while (numencodings-- > 0) |
452 free(encodings[numencodings].comp_settings); | |
453 free(encodings); | |
20133 | 454 } |
455 | |
31177 | 456 static int demux_mkv_read_trackencodings(demuxer_t *demuxer, |
457 mkv_track_t *track) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
458 { |
31177 | 459 stream_t *s = demuxer->stream; |
460 mkv_content_encoding_t *ce, e; | |
461 uint64_t len, length, l; | |
462 int il, n; | |
463 | |
464 ce = malloc(sizeof(*ce)); | |
465 n = 0; | |
466 | |
467 len = length = ebml_read_length(s, &il); | |
468 len += il; | |
469 while (length > 0) { | |
470 switch (ebml_read_id(s, &il)) { | |
471 case MATROSKA_ID_CONTENTENCODING: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
472 { |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
473 uint64_t len; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
474 int i; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
475 |
31177 | 476 memset(&e, 0, sizeof(e)); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
477 e.scope = 1; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
478 |
31177 | 479 len = ebml_read_length(s, &i); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
480 l = len + i; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
481 |
31177 | 482 while (len > 0) { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
483 uint64_t num, l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
484 int il; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
485 |
31177 | 486 switch (ebml_read_id(s, &il)) { |
487 case MATROSKA_ID_CONTENTENCODINGORDER: | |
488 num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
489 if (num == EBML_UINT_INVALID) |
31177 | 490 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
491 e.order = num; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
492 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
493 |
31177 | 494 case MATROSKA_ID_CONTENTENCODINGSCOPE: |
495 num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
496 if (num == EBML_UINT_INVALID) |
31177 | 497 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
498 e.scope = num; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
499 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
500 |
31177 | 501 case MATROSKA_ID_CONTENTENCODINGTYPE: |
502 num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
503 if (num == EBML_UINT_INVALID) |
31177 | 504 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
505 e.type = num; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
506 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
507 |
31177 | 508 case MATROSKA_ID_CONTENTCOMPRESSION: |
509 { | |
510 uint64_t le; | |
511 | |
512 le = ebml_read_length(s, &i); | |
513 l = le + i; | |
514 | |
515 while (le > 0) { | |
516 uint64_t l; | |
517 int il; | |
518 | |
519 switch (ebml_read_id(s, &il)) { | |
520 case MATROSKA_ID_CONTENTCOMPALGO: | |
521 num = ebml_read_uint(s, &l); | |
522 if (num == EBML_UINT_INVALID) | |
20133 | 523 goto err_out; |
31177 | 524 e.comp_algo = num; |
525 break; | |
526 | |
527 case MATROSKA_ID_CONTENTCOMPSETTINGS: | |
528 l = ebml_read_length(s, &i); | |
32220 | 529 if (l > SIZE_MAX) |
530 goto err_out; | |
31177 | 531 e.comp_settings = malloc(l); |
532 stream_read(s, e.comp_settings, l); | |
533 e.comp_settings_len = l; | |
534 l += i; | |
535 break; | |
536 | |
537 default: | |
538 ebml_read_skip(s, &l); | |
539 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
540 } |
31177 | 541 le -= l + il; |
542 } | |
543 | |
544 if (e.type == 1) { | |
545 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
546 MSGTR_MPDEMUX_MKV_TrackEncrypted, | |
547 track->tnum); | |
548 } else if (e.type != 0) { | |
549 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
550 MSGTR_MPDEMUX_MKV_UnknownContentEncoding, | |
551 track->tnum); | |
552 } | |
553 | |
34398
9120eb514454
Add support of compression algorithm 3 (header stripping) in mkv demuxer.
iive
parents:
33011
diff
changeset
|
554 if (e.comp_algo != 0 && e.comp_algo != 2 && e.comp_algo != 3) { |
31177 | 555 mp_msg(MSGT_DEMUX, MSGL_WARN, |
556 MSGTR_MPDEMUX_MKV_UnknownCompression, | |
557 track->tnum, e.comp_algo); | |
558 } | |
28440 | 559 #if !CONFIG_ZLIB |
31177 | 560 else if (e.comp_algo == 0) { |
561 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
562 MSGTR_MPDEMUX_MKV_ZlibCompressionUnsupported, | |
563 track->tnum); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
564 } |
31177 | 565 #endif |
566 | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
567 break; |
31177 | 568 } |
569 | |
570 default: | |
571 ebml_read_skip(s, &l); | |
572 break; | |
573 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
574 len -= l + il; |
31177 | 575 } |
576 for (i = 0; i < n; i++) | |
577 if (e.order <= ce[i].order) | |
578 break; | |
579 ce = realloc(ce, (n + 1) * sizeof(*ce)); | |
580 memmove(ce + i + 1, ce + i, (n - i) * sizeof(*ce)); | |
581 memcpy(ce + i, &e, sizeof(e)); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
582 n++; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
583 break; |
31177 | 584 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
585 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
586 default: |
31177 | 587 ebml_read_skip(s, &l); |
588 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
589 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
590 |
31177 | 591 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
592 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
593 |
31177 | 594 track->encodings = ce; |
595 track->num_encodings = n; | |
596 return len; | |
20133 | 597 |
598 err_out: | |
31177 | 599 demux_mkv_free_encodings(ce, n); |
600 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
601 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
602 |
31177 | 603 static int demux_mkv_read_trackaudio(demuxer_t *demuxer, mkv_track_t *track) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
604 { |
31177 | 605 stream_t *s = demuxer->stream; |
606 uint64_t len, length, l; | |
607 int il; | |
608 | |
609 track->a_sfreq = 8000.0; | |
610 track->a_channels = 1; | |
611 | |
612 len = length = ebml_read_length(s, &il); | |
613 len += il; | |
614 while (length > 0) { | |
615 switch (ebml_read_id(s, &il)) { | |
616 case MATROSKA_ID_AUDIOSAMPLINGFREQ: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
617 { |
31177 | 618 long double num = ebml_read_float(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
619 if (num == EBML_FLOAT_INVALID) |
31177 | 620 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
621 track->a_sfreq = num; |
31177 | 622 mp_msg(MSGT_DEMUX, MSGL_V, |
623 "[mkv] | + Sampling frequency: %f\n", track->a_sfreq); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
624 break; |
31177 | 625 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
626 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
627 case MATROSKA_ID_AUDIOBITDEPTH: |
31177 | 628 { |
629 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
630 if (num == EBML_UINT_INVALID) |
31177 | 631 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
632 track->a_bps = num; |
31177 | 633 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Bit depth: %u\n", |
634 track->a_bps); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
635 break; |
31177 | 636 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
637 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
638 case MATROSKA_ID_AUDIOCHANNELS: |
31177 | 639 { |
640 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
641 if (num == EBML_UINT_INVALID) |
31177 | 642 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
643 track->a_channels = num; |
31177 | 644 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Channels: %u\n", |
645 track->a_channels); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
646 break; |
31177 | 647 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
648 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
649 default: |
31177 | 650 ebml_read_skip(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
651 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
652 } |
31177 | 653 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
654 } |
31177 | 655 return len; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
656 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
657 |
31177 | 658 static int demux_mkv_read_trackvideo(demuxer_t *demuxer, mkv_track_t *track) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
659 { |
31177 | 660 stream_t *s = demuxer->stream; |
661 uint64_t len, length, l; | |
662 int il; | |
663 | |
664 len = length = ebml_read_length(s, &il); | |
665 len += il; | |
666 while (length > 0) { | |
667 switch (ebml_read_id(s, &il)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
668 case MATROSKA_ID_VIDEOFRAMERATE: |
31177 | 669 { |
670 long double num = ebml_read_float(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
671 if (num == EBML_FLOAT_INVALID) |
31177 | 672 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
673 track->v_frate = num; |
31177 | 674 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Frame rate: %f\n", |
675 track->v_frate); | |
14058
4dee22ed8608
Make use of the default duration for one frame if it is present in the file. This produces much smoother timecodes for laced audio frames. And I REALLY don't know why I missed that before...
mosu
parents:
14054
diff
changeset
|
676 if (track->v_frate > 0) |
31177 | 677 track->default_duration = 1 / track->v_frate; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
678 break; |
31177 | 679 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
680 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
681 case MATROSKA_ID_VIDEODISPLAYWIDTH: |
31177 | 682 { |
683 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
684 if (num == EBML_UINT_INVALID) |
31177 | 685 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
686 track->v_dwidth = num; |
31177 | 687 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Display width: %u\n", |
688 track->v_dwidth); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
689 break; |
31177 | 690 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
691 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
692 case MATROSKA_ID_VIDEODISPLAYHEIGHT: |
31177 | 693 { |
694 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
695 if (num == EBML_UINT_INVALID) |
31177 | 696 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
697 track->v_dheight = num; |
31177 | 698 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Display height: %u\n", |
699 track->v_dheight); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
700 break; |
31177 | 701 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
702 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
703 case MATROSKA_ID_VIDEOPIXELWIDTH: |
31177 | 704 { |
705 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
706 if (num == EBML_UINT_INVALID) |
31177 | 707 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
708 track->v_width = num; |
31177 | 709 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel width: %u\n", |
710 track->v_width); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
711 break; |
31177 | 712 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
713 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
714 case MATROSKA_ID_VIDEOPIXELHEIGHT: |
31177 | 715 { |
716 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
717 if (num == EBML_UINT_INVALID) |
31177 | 718 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
719 track->v_height = num; |
31177 | 720 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Pixel height: %u\n", |
721 track->v_height); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
722 break; |
31177 | 723 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
724 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
725 default: |
31177 | 726 ebml_read_skip(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
727 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
728 } |
31177 | 729 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
730 } |
31177 | 731 return len; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
732 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
733 |
20135
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
734 /** |
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
735 * \brief free any data associated with given track |
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
736 * \param track track of which to free data |
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
737 */ |
31177 | 738 static void demux_mkv_free_trackentry(mkv_track_t *track) |
739 { | |
740 free(track->name); | |
741 free(track->codec_id); | |
742 free(track->language); | |
743 free(track->private_data); | |
744 free(track->audio_buf); | |
745 free(track->audio_timestamp); | |
746 demux_mkv_free_encodings(track->encodings, track->num_encodings); | |
747 free(track); | |
20135
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
748 } |
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
749 |
31177 | 750 static int demux_mkv_read_trackentry(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
751 { |
31177 | 752 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
753 stream_t *s = demuxer->stream; | |
754 mkv_track_t *track; | |
755 uint64_t len, length, l; | |
756 int il; | |
757 | |
758 track = calloc(1, sizeof(*track)); | |
759 /* set default values */ | |
760 track->default_track = 1; | |
761 track->name = 0; | |
762 track->language = strdup("eng"); | |
763 | |
764 len = length = ebml_read_length(s, &il); | |
765 len += il; | |
766 while (length > 0) { | |
767 switch (ebml_read_id(s, &il)) { | |
768 case MATROSKA_ID_TRACKNUMBER: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
769 { |
31177 | 770 uint64_t num = ebml_read_uint(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
771 if (num == EBML_UINT_INVALID) |
31177 | 772 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
773 track->tnum = num; |
31177 | 774 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Track number: %u\n", |
775 track->tnum); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
776 break; |
31177 | 777 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
778 |
19640 | 779 case MATROSKA_ID_TRACKNAME: |
31177 | 780 track->name = ebml_read_utf8(s, &l); |
19640 | 781 if (track->name == NULL) |
31177 | 782 goto err_out; |
783 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Name: %s\n", | |
784 track->name); | |
19640 | 785 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
786 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
787 case MATROSKA_ID_TRACKTYPE: |
31177 | 788 { |
789 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
790 if (num == EBML_UINT_INVALID) |
31177 | 791 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
792 track->type = num; |
31177 | 793 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Track type: "); |
794 switch (track->type) { | |
795 case MATROSKA_TRACK_AUDIO: | |
796 mp_msg(MSGT_DEMUX, MSGL_V, "Audio\n"); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
797 break; |
31177 | 798 case MATROSKA_TRACK_VIDEO: |
799 mp_msg(MSGT_DEMUX, MSGL_V, "Video\n"); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
800 break; |
31177 | 801 case MATROSKA_TRACK_SUBTITLE: |
802 mp_msg(MSGT_DEMUX, MSGL_V, "Subtitle\n"); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
803 break; |
31177 | 804 default: |
805 mp_msg(MSGT_DEMUX, MSGL_V, "unknown\n"); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
806 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
807 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
808 break; |
31177 | 809 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
810 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
811 case MATROSKA_ID_TRACKAUDIO: |
31177 | 812 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Audio track\n"); |
813 l = demux_mkv_read_trackaudio(demuxer, track); | |
814 if (l == 0) | |
815 goto err_out; | |
816 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
817 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
818 case MATROSKA_ID_TRACKVIDEO: |
31177 | 819 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Video track\n"); |
820 l = demux_mkv_read_trackvideo(demuxer, track); | |
821 if (l == 0) | |
822 goto err_out; | |
823 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
824 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
825 case MATROSKA_ID_CODECID: |
31177 | 826 track->codec_id = ebml_read_ascii(s, &l); |
827 if (track->codec_id == NULL) | |
828 goto err_out; | |
829 if (!strcmp(track->codec_id, MKV_V_MSCOMP) | |
830 || !strcmp(track->codec_id, MKV_A_ACM)) | |
831 track->ms_compat = 1; | |
832 else if (!strcmp(track->codec_id, MKV_S_VOBSUB)) | |
833 track->subtitle_type = MATROSKA_SUBTYPE_VOBSUB; | |
834 else if (!strcmp(track->codec_id, MKV_S_TEXTSSA) | |
835 || !strcmp(track->codec_id, MKV_S_TEXTASS) | |
836 || !strcmp(track->codec_id, MKV_S_SSA) | |
837 || !strcmp(track->codec_id, MKV_S_ASS)) { | |
838 track->subtitle_type = MATROSKA_SUBTYPE_SSA; | |
839 } else if (!strcmp(track->codec_id, MKV_S_TEXTASCII)) | |
840 track->subtitle_type = MATROSKA_SUBTYPE_TEXT; | |
841 if (!strcmp(track->codec_id, MKV_S_TEXTUTF8)) { | |
842 track->subtitle_type = MATROSKA_SUBTYPE_TEXT; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
843 } |
31177 | 844 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Codec ID: %s\n", |
845 track->codec_id); | |
846 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
847 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
848 case MATROSKA_ID_CODECPRIVATE: |
31177 | 849 { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
850 int x; |
31177 | 851 uint64_t num = ebml_read_length(s, &x); |
852 // audit: cheap guard against overflows later.. | |
853 if (num > SIZE_MAX - 1000) | |
854 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
855 l = x + num; |
31177 | 856 track->private_data = malloc(num + AV_LZO_INPUT_PADDING); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
857 if (stream_read(s, track->private_data, num) != (int) num) |
31177 | 858 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
859 track->private_size = num; |
31177 | 860 mp_msg(MSGT_DEMUX, MSGL_V, |
32223 | 861 "[mkv] | + CodecPrivate, length " "%zu\n", |
31177 | 862 track->private_size); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
863 break; |
31177 | 864 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
865 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
866 case MATROSKA_ID_TRACKLANGUAGE: |
31177 | 867 free(track->language); |
868 track->language = ebml_read_utf8(s, &l); | |
869 if (track->language == NULL) | |
870 goto err_out; | |
871 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Language: %s\n", | |
872 track->language); | |
873 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
874 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
875 case MATROSKA_ID_TRACKFLAGDEFAULT: |
31177 | 876 { |
877 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
878 if (num == EBML_UINT_INVALID) |
31177 | 879 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
880 track->default_track = num; |
31177 | 881 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Default flag: %u\n", |
882 track->default_track); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
883 break; |
31177 | 884 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
885 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
886 case MATROSKA_ID_TRACKDEFAULTDURATION: |
31177 | 887 { |
888 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
889 if (num == EBML_UINT_INVALID) |
31177 | 890 goto err_out; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
891 if (num == 0) |
31177 | 892 mp_msg(MSGT_DEMUX, MSGL_V, |
893 "[mkv] | + Default duration: 0"); | |
894 else { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
895 track->v_frate = 1000000000.0 / num; |
14058
4dee22ed8608
Make use of the default duration for one frame if it is present in the file. This produces much smoother timecodes for laced audio frames. And I REALLY don't know why I missed that before...
mosu
parents:
14054
diff
changeset
|
896 track->default_duration = num / 1000000000.0; |
31177 | 897 mp_msg(MSGT_DEMUX, MSGL_V, |
898 "[mkv] | + Default duration: " | |
899 "%.3fms ( = %.3f fps)\n", num / 1000000.0, | |
900 track->v_frate); | |
901 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
902 break; |
31177 | 903 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
904 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
905 case MATROSKA_ID_TRACKENCODINGS: |
31177 | 906 l = demux_mkv_read_trackencodings(demuxer, track); |
907 if (l == 0) | |
908 goto err_out; | |
909 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
910 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
911 default: |
31177 | 912 ebml_read_skip(s, &l); |
913 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
914 } |
31177 | 915 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
916 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
917 |
31177 | 918 mkv_d->tracks[mkv_d->num_tracks++] = track; |
919 return len; | |
20135
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
920 |
7079d029d27c
Free track data if error occurs while reading trackentry
reimar
parents:
20133
diff
changeset
|
921 err_out: |
31177 | 922 demux_mkv_free_trackentry(track); |
923 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
924 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
925 |
31177 | 926 static int demux_mkv_read_tracks(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
927 { |
31177 | 928 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
929 stream_t *s = demuxer->stream; | |
930 uint64_t length, l; | |
931 int il; | |
932 | |
933 mkv_d->tracks = malloc(sizeof(*mkv_d->tracks)); | |
934 mkv_d->num_tracks = 0; | |
935 | |
936 length = ebml_read_length(s, NULL); | |
937 while (length > 0) { | |
938 switch (ebml_read_id(s, &il)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
939 case MATROSKA_ID_TRACKENTRY: |
31177 | 940 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + a track...\n"); |
941 mkv_d->tracks = realloc(mkv_d->tracks, (mkv_d->num_tracks + 1) | |
942 * sizeof(*mkv_d->tracks)); | |
943 l = demux_mkv_read_trackentry(demuxer); | |
944 if (l == 0) | |
945 return 1; | |
946 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
947 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
948 default: |
31177 | 949 ebml_read_skip(s, &l); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
950 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
951 } |
31177 | 952 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
953 } |
31177 | 954 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
955 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
956 |
31177 | 957 static int demux_mkv_read_cues(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
958 { |
31177 | 959 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
960 stream_t *s = demuxer->stream; | |
961 uint64_t length, l, time, track, pos; | |
962 off_t off; | |
963 int i, il; | |
964 | |
965 if (index_mode == 0) { | |
966 ebml_read_skip(s, NULL); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
967 return 0; |
31177 | 968 } |
969 off = stream_tell(s); | |
970 for (i = 0; i < mkv_d->parsed_cues_num; i++) | |
971 if (mkv_d->parsed_cues[i] == off) { | |
972 ebml_read_skip(s, NULL); | |
973 return 0; | |
974 } | |
975 mkv_d->parsed_cues = realloc(mkv_d->parsed_cues, | |
976 (mkv_d->parsed_cues_num + 1) * sizeof(off_t)); | |
977 mkv_d->parsed_cues[mkv_d->parsed_cues_num++] = off; | |
978 | |
979 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing cues ] -----------\n"); | |
980 length = ebml_read_length(s, NULL); | |
981 | |
982 while (length > 0) { | |
983 time = track = pos = EBML_UINT_INVALID; | |
984 | |
985 switch (ebml_read_id(s, &il)) { | |
986 case MATROSKA_ID_POINTENTRY: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
987 { |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
988 uint64_t len; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
989 |
31177 | 990 len = ebml_read_length(s, &i); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
991 l = len + i; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
992 |
31177 | 993 while (len > 0) { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
994 uint64_t l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
995 int il; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
996 |
31177 | 997 switch (ebml_read_id(s, &il)) { |
998 case MATROSKA_ID_CUETIME: | |
999 time = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1000 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1001 |
31177 | 1002 case MATROSKA_ID_CUETRACKPOSITION: |
1003 { | |
1004 uint64_t le; | |
1005 | |
1006 le = ebml_read_length(s, &i); | |
1007 l = le + i; | |
1008 | |
1009 while (le > 0) { | |
1010 uint64_t l; | |
1011 int il; | |
1012 | |
1013 switch (ebml_read_id(s, &il)) { | |
1014 case MATROSKA_ID_CUETRACK: | |
1015 track = ebml_read_uint(s, &l); | |
1016 break; | |
1017 | |
1018 case MATROSKA_ID_CUECLUSTERPOSITION: | |
1019 pos = ebml_read_uint(s, &l); | |
1020 break; | |
1021 | |
1022 default: | |
1023 ebml_read_skip(s, &l); | |
1024 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1025 } |
31177 | 1026 le -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1027 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1028 break; |
31177 | 1029 } |
1030 | |
1031 default: | |
1032 ebml_read_skip(s, &l); | |
1033 break; | |
1034 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1035 len -= l + il; |
31177 | 1036 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1037 break; |
31177 | 1038 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1039 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1040 default: |
31177 | 1041 ebml_read_skip(s, &l); |
1042 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1043 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1044 |
31177 | 1045 length -= l + il; |
1046 | |
1047 if (time != EBML_UINT_INVALID && track != EBML_UINT_INVALID | |
1048 && pos != EBML_UINT_INVALID) { | |
1049 grow_array(&mkv_d->indexes, mkv_d->num_indexes, | |
1050 sizeof(mkv_index_t)); | |
1051 if (!mkv_d->indexes) { | |
1052 mkv_d->num_indexes = 0; | |
1053 break; | |
1054 } | |
1055 mkv_d->indexes[mkv_d->num_indexes].tnum = track; | |
1056 mkv_d->indexes[mkv_d->num_indexes].timecode = time; | |
1057 mkv_d->indexes[mkv_d->num_indexes].filepos = mkv_d->segment_start | |
1058 + pos; | |
1059 mp_msg(MSGT_DEMUX, MSGL_DBG2, | |
1060 "[mkv] |+ found cue point " "for track %" PRIu64 | |
1061 ": timecode %" PRIu64 ", filepos: %" PRIu64 "\n", track, | |
1062 time, mkv_d->segment_start + pos); | |
1063 mkv_d->num_indexes++; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1064 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1065 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1066 |
31177 | 1067 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] \\---- [ parsing cues ] -----------\n"); |
1068 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1069 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1070 |
31177 | 1071 static int demux_mkv_read_chapters(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1072 { |
31177 | 1073 stream_t *s = demuxer->stream; |
1074 uint64_t length, l; | |
1075 int il; | |
1076 | |
1077 if (demuxer->chapters) { | |
1078 ebml_read_skip(s, NULL); | |
1079 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1080 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1081 |
31177 | 1082 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] /---- [ parsing chapters ] ---------\n"); |
1083 length = ebml_read_length(s, NULL); | |
1084 | |
1085 while (length > 0) { | |
1086 switch (ebml_read_id(s, &il)) { | |
1087 case MATROSKA_ID_EDITIONENTRY: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1088 { |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1089 uint64_t len; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1090 int i; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1091 |
31177 | 1092 len = ebml_read_length(s, &i); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1093 l = len + i; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1094 |
31177 | 1095 while (len > 0) { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1096 uint64_t l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1097 int il; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1098 |
31177 | 1099 switch (ebml_read_id(s, &il)) { |
1100 case MATROSKA_ID_CHAPTERATOM: | |
1101 { | |
1102 uint64_t len, start = 0, end = 0; | |
1103 char *name = 0; | |
1104 int i; | |
1105 int cid; | |
1106 | |
1107 len = ebml_read_length(s, &i); | |
1108 l = len + i; | |
1109 | |
1110 while (len > 0) { | |
1111 uint64_t l; | |
1112 int il; | |
1113 | |
1114 switch (ebml_read_id(s, &il)) { | |
1115 case MATROSKA_ID_CHAPTERTIMESTART: | |
1116 start = ebml_read_uint(s, &l) / 1000000; | |
1117 break; | |
1118 | |
1119 case MATROSKA_ID_CHAPTERTIMEEND: | |
1120 end = ebml_read_uint(s, &l) / 1000000; | |
1121 break; | |
1122 | |
1123 case MATROSKA_ID_CHAPTERDISPLAY: | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1124 { |
31177 | 1125 uint64_t len; |
1126 int i; | |
1127 | |
1128 len = ebml_read_length(s, &i); | |
1129 l = len + i; | |
1130 while (len > 0) { | |
1131 uint64_t l; | |
1132 int il; | |
1133 | |
1134 switch (ebml_read_id(s, &il)) { | |
1135 case MATROSKA_ID_CHAPSTRING: | |
1136 name = ebml_read_utf8(s, &l); | |
1137 break; | |
1138 default: | |
1139 ebml_read_skip(s, &l); | |
1140 break; | |
1141 } | |
1142 len -= l + il; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1143 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1144 } |
31177 | 1145 break; |
1146 | |
1147 default: | |
1148 ebml_read_skip(s, &l); | |
1149 break; | |
1150 } | |
1151 len -= l + il; | |
1152 } | |
1153 | |
1154 if (!name) | |
19342 | 1155 name = strdup("(unnamed)"); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29238
diff
changeset
|
1156 |
31177 | 1157 cid = demuxer_add_chapter(demuxer, name, start, end); |
1158 | |
1159 mp_msg(MSGT_DEMUX, MSGL_V, | |
1160 "[mkv] Chapter %u from %02d:%02d:%02d." | |
1161 "%03d to %02d:%02d:%02d.%03d, %s\n", cid, | |
1162 (int) (start / 60 / 60 / 1000), | |
1163 (int) ((start / 60 / 1000) % 60), | |
1164 (int) ((start / 1000) % 60), | |
1165 (int) (start % 1000), | |
1166 (int) (end / 60 / 60 / 1000), | |
1167 (int) ((end / 60 / 1000) % 60), | |
1168 (int) ((end / 1000) % 60), | |
1169 (int) (end % 1000), name); | |
1170 | |
1171 free(name); | |
1172 break; | |
1173 } | |
1174 | |
1175 default: | |
1176 ebml_read_skip(s, &l); | |
1177 break; | |
1178 } | |
1179 len -= l + il; | |
1180 } | |
1181 break; | |
1182 } | |
1183 | |
1184 default: | |
1185 ebml_read_skip(s, &l); | |
1186 break; | |
1187 } | |
1188 | |
1189 length -= l + il; | |
1190 } | |
1191 | |
1192 mp_msg(MSGT_DEMUX, MSGL_V, | |
1193 "[mkv] \\---- [ parsing chapters ] ---------\n"); | |
1194 return 0; | |
1195 } | |
1196 | |
1197 static int demux_mkv_read_tags(demuxer_t *demuxer) | |
1198 { | |
1199 ebml_read_skip(demuxer->stream, NULL); | |
1200 return 0; | |
1201 } | |
1202 | |
1203 static int demux_mkv_read_attachments(demuxer_t *demuxer) | |
1204 { | |
1205 stream_t *s = demuxer->stream; | |
1206 uint64_t length, l; | |
1207 int il; | |
1208 | |
1209 mp_msg(MSGT_DEMUX, MSGL_V, | |
1210 "[mkv] /---- [ parsing attachments ] ---------\n"); | |
1211 length = ebml_read_length(s, NULL); | |
1212 | |
1213 while (length > 0) { | |
1214 switch (ebml_read_id(s, &il)) { | |
1215 case MATROSKA_ID_ATTACHEDFILE: | |
1216 { | |
1217 uint64_t len; | |
1218 int i; | |
1219 char *name = NULL; | |
1220 char *mime = NULL; | |
1221 char *data = NULL; | |
1222 int data_size = 0; | |
1223 | |
1224 len = ebml_read_length(s, &i); | |
1225 l = len + i; | |
1226 | |
1227 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + an attachment...\n"); | |
1228 | |
1229 while (len > 0) { | |
1230 uint64_t l; | |
1231 int il; | |
1232 | |
1233 switch (ebml_read_id(s, &il)) { | |
1234 case MATROSKA_ID_FILENAME: | |
1235 name = ebml_read_utf8(s, &l); | |
1236 if (name == NULL) | |
1237 return 0; | |
1238 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + FileName: %s\n", | |
1239 name); | |
1240 break; | |
1241 | |
1242 case MATROSKA_ID_FILEMIMETYPE: | |
1243 mime = ebml_read_ascii(s, &l); | |
1244 if (mime == NULL) | |
1245 return 0; | |
1246 mp_msg(MSGT_DEMUX, MSGL_V, | |
1247 "[mkv] | + FileMimeType: %s\n", mime); | |
1248 break; | |
1249 | |
1250 case MATROSKA_ID_FILEDATA: | |
1251 { | |
1252 int x; | |
1253 uint64_t num = ebml_read_length(s, &x); | |
1254 l = x + num; | |
1255 free(data); | |
32220 | 1256 if (num > SIZE_MAX) |
1257 return 0; | |
31177 | 1258 data = malloc(num); |
1259 if (stream_read(s, data, num) != (int) num) { | |
1260 free(data); | |
1261 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1262 } |
31177 | 1263 data_size = num; |
1264 mp_msg(MSGT_DEMUX, MSGL_V, | |
1265 "[mkv] | + FileData, length " "%u\n", | |
1266 data_size); | |
1267 break; | |
1268 } | |
1269 | |
1270 default: | |
1271 ebml_read_skip(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1272 break; |
31177 | 1273 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1274 len -= l + il; |
31177 | 1275 } |
1276 | |
1277 demuxer_add_attachment(demuxer, name, mime, data, data_size); | |
1278 mp_msg(MSGT_DEMUX, MSGL_V, | |
1279 "[mkv] Attachment: %s, %s, %u bytes\n", name, mime, | |
1280 data_size); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1281 break; |
31177 | 1282 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1283 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1284 default: |
31177 | 1285 ebml_read_skip(s, &l); |
1286 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1287 } |
31177 | 1288 length -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1289 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1290 |
31177 | 1291 mp_msg(MSGT_DEMUX, MSGL_V, |
1292 "[mkv] \\---- [ parsing attachments ] ---------\n"); | |
1293 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1294 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1295 |
31177 | 1296 static int demux_mkv_read_seekhead(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1297 { |
31177 | 1298 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
1299 stream_t *s = demuxer->stream; | |
1300 uint64_t length, l, seek_pos, saved_pos, num; | |
1301 uint32_t seek_id; | |
1302 int i, il, res = 0; | |
1303 off_t off; | |
1304 | |
1305 off = stream_tell(s); | |
1306 for (i = 0; i < mkv_d->parsed_seekhead_num; i++) | |
1307 if (mkv_d->parsed_seekhead[i] == off) { | |
1308 ebml_read_skip(s, NULL); | |
1309 return 0; | |
1310 } | |
32220 | 1311 if (mkv_d->parsed_seekhead_num >= INT_MAX || |
1312 mkv_d->parsed_seekhead_num > SIZE_MAX/sizeof(off_t)) | |
1313 return 0; | |
31177 | 1314 mkv_d->parsed_seekhead = realloc(mkv_d->parsed_seekhead, |
1315 (mkv_d->parsed_seekhead_num + 1) | |
1316 * sizeof(off_t)); | |
1317 mkv_d->parsed_seekhead[mkv_d->parsed_seekhead_num++] = off; | |
1318 | |
1319 mp_msg(MSGT_DEMUX, MSGL_V, | |
1320 "[mkv] /---- [ parsing seek head ] ---------\n"); | |
1321 length = ebml_read_length(s, NULL); | |
1322 /* off now holds the position of the next element after the seek head. */ | |
1323 off = stream_tell(s) + length; | |
1324 while (length > 0 && !res) { | |
1325 | |
1326 seek_id = 0; | |
1327 seek_pos = EBML_UINT_INVALID; | |
1328 | |
1329 switch (ebml_read_id(s, &il)) { | |
1330 case MATROSKA_ID_SEEKENTRY: | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1331 { |
31177 | 1332 uint64_t len; |
1333 | |
1334 len = ebml_read_length(s, &i); | |
1335 l = len + i; | |
1336 | |
1337 while (len > 0) { | |
1338 uint64_t l; | |
1339 int il; | |
1340 | |
1341 switch (ebml_read_id(s, &il)) { | |
1342 case MATROSKA_ID_SEEKID: | |
1343 num = ebml_read_uint(s, &l); | |
1344 if (num != EBML_UINT_INVALID) | |
1345 seek_id = num; | |
1346 break; | |
1347 | |
1348 case MATROSKA_ID_SEEKPOSITION: | |
1349 seek_pos = ebml_read_uint(s, &l); | |
1350 break; | |
1351 | |
1352 default: | |
1353 ebml_read_skip(s, &l); | |
1354 break; | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1355 } |
31177 | 1356 len -= l + il; |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1357 } |
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1358 |
31177 | 1359 break; |
1360 } | |
1361 | |
1362 default: | |
1363 ebml_read_skip(s, &l); | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1364 break; |
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1365 } |
31177 | 1366 length -= l + il; |
1367 | |
1368 if (seek_id == 0 || seek_id == MATROSKA_ID_CLUSTER | |
1369 || seek_pos == EBML_UINT_INVALID | |
1370 || ((mkv_d->segment_start + seek_pos) >= | |
1371 (uint64_t) demuxer->movi_end)) | |
1372 continue; | |
1373 | |
1374 saved_pos = stream_tell(s); | |
1375 if (!stream_seek(s, mkv_d->segment_start + seek_pos)) | |
1376 res = 1; | |
1377 else { | |
1378 if (ebml_read_id(s, &il) != seek_id) | |
1379 res = 1; | |
1380 else | |
1381 switch (seek_id) { | |
1382 case MATROSKA_ID_CUES: | |
1383 if (demux_mkv_read_cues(demuxer)) | |
1384 res = 1; | |
1385 break; | |
1386 | |
1387 case MATROSKA_ID_TAGS: | |
1388 if (demux_mkv_read_tags(demuxer)) | |
1389 res = 1; | |
1390 break; | |
1391 | |
1392 case MATROSKA_ID_SEEKHEAD: | |
1393 if (demux_mkv_read_seekhead(demuxer)) | |
1394 res = 1; | |
1395 break; | |
1396 | |
1397 case MATROSKA_ID_CHAPTERS: | |
1398 if (demux_mkv_read_chapters(demuxer)) | |
1399 res = 1; | |
1400 break; | |
1401 } | |
1402 } | |
1403 | |
1404 stream_seek(s, saved_pos); | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1405 } |
31177 | 1406 if (res) { |
1407 /* If there was an error then try to skip this seek head. */ | |
1408 if (stream_seek(s, off)) | |
1409 res = 0; | |
1410 } else if (length > 0) | |
1411 stream_seek(s, stream_tell(s) + length); | |
1412 mp_msg(MSGT_DEMUX, MSGL_V, | |
1413 "[mkv] \\---- [ parsing seek head ] ---------\n"); | |
1414 return res; | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1415 } |
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
1416 |
31177 | 1417 static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track, |
1418 int vid); | |
1419 static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, | |
1420 int aid); | |
1421 static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, | |
1422 int sid); | |
1423 | |
1424 static void display_create_tracks(demuxer_t *demuxer) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1425 { |
31177 | 1426 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
1427 int i, vid = 0, aid = 0, sid = 0; | |
1428 | |
1429 for (i = 0; i < mkv_d->num_tracks; i++) { | |
1430 char *type = "unknown", str[32]; | |
1431 *str = '\0'; | |
1432 switch (mkv_d->tracks[i]->type) { | |
1433 case MATROSKA_TRACK_VIDEO: | |
1434 type = "video"; | |
1435 demux_mkv_open_video(demuxer, mkv_d->tracks[i], vid); | |
1436 if (mkv_d->tracks[i]->name) | |
1437 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VID_%d_NAME=%s\n", vid, | |
1438 mkv_d->tracks[i]->name); | |
1439 sprintf(str, "-vid %u", vid++); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1440 break; |
31177 | 1441 case MATROSKA_TRACK_AUDIO: |
1442 type = "audio"; | |
1443 demux_mkv_open_audio(demuxer, mkv_d->tracks[i], aid); | |
1444 if (mkv_d->tracks[i]->name) | |
1445 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_NAME=%s\n", aid, | |
1446 mkv_d->tracks[i]->name); | |
1447 sprintf(str, "-aid %u, -alang %.5s", aid++, | |
1448 mkv_d->tracks[i]->language); | |
1449 break; | |
1450 case MATROSKA_TRACK_SUBTITLE: | |
1451 type = "subtitles"; | |
1452 demux_mkv_open_sub(demuxer, mkv_d->tracks[i], sid); | |
1453 if (mkv_d->tracks[i]->name) | |
1454 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_NAME=%s\n", sid, | |
1455 mkv_d->tracks[i]->name); | |
1456 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n", sid, | |
1457 mkv_d->tracks[i]->language); | |
1458 sprintf(str, "-sid %u, -slang %.5s", sid++, | |
1459 mkv_d->tracks[i]->language); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1460 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1461 } |
31177 | 1462 if (mkv_d->tracks[i]->name) |
1463 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackIDName, | |
1464 mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, | |
1465 mkv_d->tracks[i]->name, str); | |
1466 else | |
1467 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_TrackID, | |
1468 mkv_d->tracks[i]->tnum, type, mkv_d->tracks[i]->codec_id, | |
1469 str); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1470 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1471 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1472 |
23270
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1473 typedef struct { |
31177 | 1474 char *id; |
1475 int fourcc; | |
1476 int extradata; | |
23270
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1477 } videocodec_info_t; |
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1478 |
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1479 static const videocodec_info_t vinfo[] = { |
31177 | 1480 {MKV_V_MPEG1, mmioFOURCC('m', 'p', 'g', '1'), 0}, |
1481 {MKV_V_MPEG2, mmioFOURCC('m', 'p', 'g', '2'), 0}, | |
1482 {MKV_V_MPEG4_SP, mmioFOURCC('m', 'p', '4', 'v'), 1}, | |
1483 {MKV_V_MPEG4_ASP, mmioFOURCC('m', 'p', '4', 'v'), 1}, | |
1484 {MKV_V_MPEG4_AP, mmioFOURCC('m', 'p', '4', 'v'), 1}, | |
1485 {MKV_V_MPEG4_AVC, mmioFOURCC('a', 'v', 'c', '1'), 1}, | |
1486 {MKV_V_THEORA, mmioFOURCC('t', 'h', 'e', 'o'), 1}, | |
31263 | 1487 {MKV_V_VP8, mmioFOURCC('V', 'P', '8', '0'), 0}, |
31177 | 1488 {NULL, 0, 0} |
23270
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1489 }; |
f094c9256137
Avoid code duplication in mkv demuxer for standard fourcc/extradata handling
reimar
parents:
23187
diff
changeset
|
1490 |
31177 | 1491 static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track, |
1492 int vid) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1493 { |
31177 | 1494 BITMAPINFOHEADER *bih; |
1495 void *ImageDesc = NULL; | |
1496 sh_video_t *sh_v; | |
1497 | |
1498 if (track->ms_compat) { /* MS compatibility mode */ | |
1499 BITMAPINFOHEADER *src; | |
1500 | |
1501 if (track->private_data == NULL | |
32220 | 1502 || track->private_size >= INT_MAX - 1000 |
32111 | 1503 || track->private_size < sizeof(*bih)) |
31177 | 1504 return 1; |
1505 | |
1506 src = (BITMAPINFOHEADER *) track->private_data; | |
1507 bih = calloc(1, track->private_size); | |
1508 bih->biSize = le2me_32(src->biSize); | |
1509 bih->biWidth = le2me_32(src->biWidth); | |
1510 bih->biHeight = le2me_32(src->biHeight); | |
1511 bih->biPlanes = le2me_16(src->biPlanes); | |
1512 bih->biBitCount = le2me_16(src->biBitCount); | |
1513 bih->biCompression = le2me_32(src->biCompression); | |
1514 bih->biSizeImage = le2me_32(src->biSizeImage); | |
1515 bih->biXPelsPerMeter = le2me_32(src->biXPelsPerMeter); | |
1516 bih->biYPelsPerMeter = le2me_32(src->biYPelsPerMeter); | |
1517 bih->biClrUsed = le2me_32(src->biClrUsed); | |
1518 bih->biClrImportant = le2me_32(src->biClrImportant); | |
32111 | 1519 memcpy(bih + 1, |
1520 src + 1, | |
1521 track->private_size - sizeof(*bih)); | |
31177 | 1522 |
1523 if (track->v_width == 0) | |
1524 track->v_width = bih->biWidth; | |
1525 if (track->v_height == 0) | |
1526 track->v_height = bih->biHeight; | |
1527 } else { | |
32111 | 1528 bih = calloc(1, sizeof(*bih)); |
1529 bih->biSize = sizeof(*bih); | |
31177 | 1530 bih->biWidth = track->v_width; |
1531 bih->biHeight = track->v_height; | |
1532 bih->biBitCount = 24; | |
1533 bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount / 8; | |
1534 | |
1535 if (track->private_size >= RVPROPERTIES_SIZE | |
1536 && (!strcmp(track->codec_id, MKV_V_REALV10) | |
1537 || !strcmp(track->codec_id, MKV_V_REALV20) | |
1538 || !strcmp(track->codec_id, MKV_V_REALV30) | |
1539 || !strcmp(track->codec_id, MKV_V_REALV40))) { | |
1540 unsigned char *dst, *src; | |
1541 uint32_t type2; | |
32220 | 1542 size_t cnt; |
31177 | 1543 |
1544 src = (uint8_t *) track->private_data + RVPROPERTIES_SIZE; | |
1545 | |
1546 cnt = track->private_size - RVPROPERTIES_SIZE; | |
32220 | 1547 if (cnt > INT_MAX - sizeof(*bih) - 8) { |
1548 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
35341 | 1549 free(bih); |
32220 | 1550 return 1; |
1551 } | |
32111 | 1552 bih = realloc(bih, sizeof(*bih) + 8 + cnt); |
31177 | 1553 bih->biSize = 48 + cnt; |
1554 bih->biPlanes = 1; | |
1555 type2 = AV_RB32(src - 4); | |
1556 if (type2 == 0x10003000 || type2 == 0x10003001) | |
1557 bih->biCompression = mmioFOURCC('R', 'V', '1', '3'); | |
1558 else | |
1559 bih->biCompression = | |
1560 mmioFOURCC('R', 'V', track->codec_id[9], '0'); | |
1561 dst = (unsigned char *) (bih + 1); | |
1562 // copy type1 and type2 info from rv properties | |
1563 memcpy(dst, src - 8, 8); | |
1564 stream_read(demuxer->stream, dst + 8, cnt); | |
1565 track->realmedia = 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1566 |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26752
diff
changeset
|
1567 #ifdef CONFIG_QTX_CODECS |
31177 | 1568 } else if (track->private_size >= sizeof(ImageDescription) |
1569 && !strcmp(track->codec_id, MKV_V_QUICKTIME)) { | |
1570 ImageDescriptionPtr idesc; | |
1571 | |
1572 idesc = (ImageDescriptionPtr) track->private_data; | |
1573 idesc->idSize = be2me_32(idesc->idSize); | |
1574 idesc->cType = be2me_32(idesc->cType); | |
1575 idesc->version = be2me_16(idesc->version); | |
1576 idesc->revisionLevel = be2me_16(idesc->revisionLevel); | |
1577 idesc->vendor = be2me_32(idesc->vendor); | |
1578 idesc->temporalQuality = be2me_32(idesc->temporalQuality); | |
1579 idesc->spatialQuality = be2me_32(idesc->spatialQuality); | |
1580 idesc->width = be2me_16(idesc->width); | |
1581 idesc->height = be2me_16(idesc->height); | |
1582 idesc->hRes = be2me_32(idesc->hRes); | |
1583 idesc->vRes = be2me_32(idesc->vRes); | |
1584 idesc->dataSize = be2me_32(idesc->dataSize); | |
1585 idesc->frameCount = be2me_16(idesc->frameCount); | |
1586 idesc->depth = be2me_16(idesc->depth); | |
1587 idesc->clutID = be2me_16(idesc->clutID); | |
1588 bih->biPlanes = 1; | |
1589 bih->biCompression = idesc->cType; | |
1590 ImageDesc = idesc; | |
1591 #endif /* CONFIG_QTX_CODECS */ | |
1592 | |
1593 } else { | |
1594 const videocodec_info_t *vi = vinfo; | |
1595 while (vi->id && strcmp(vi->id, track->codec_id)) | |
1596 vi++; | |
1597 bih->biCompression = vi->fourcc; | |
1598 if (vi->extradata && track->private_data | |
1599 && (track->private_size > 0)) { | |
1600 bih->biSize += track->private_size; | |
1601 bih = realloc(bih, bih->biSize); | |
1602 memcpy(bih + 1, track->private_data, track->private_size); | |
19154 | 1603 } |
31177 | 1604 track->reorder_timecodes = user_correct_pts == 0; |
1605 if (!vi->id) { | |
1606 mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID, | |
1607 track->codec_id, track->tnum); | |
1608 free(bih); | |
1609 return 1; | |
1610 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1611 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1612 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1613 |
31177 | 1614 sh_v = new_sh_video_vid(demuxer, track->tnum, vid); |
1615 sh_v->bih = bih; | |
1616 sh_v->format = sh_v->bih->biCompression; | |
1617 if (track->v_frate == 0.0) | |
1618 track->v_frate = 25.0; | |
1619 sh_v->fps = track->v_frate; | |
1620 sh_v->frametime = 1 / track->v_frate; | |
1621 sh_v->aspect = 0; | |
1622 if (!track->realmedia) { | |
1623 sh_v->disp_w = track->v_width; | |
1624 sh_v->disp_h = track->v_height; | |
1625 if (track->v_dheight) | |
1626 sh_v->aspect = (float) track->v_dwidth / (float) track->v_dheight; | |
1627 } else { | |
1628 // vd_realvid.c will set aspect to disp_w/disp_h and rederive | |
1629 // disp_w and disp_h from the RealVideo stream contents returned | |
1630 // by the Real DLLs. If DisplayWidth/DisplayHeight was not set in | |
1631 // the Matroska file then it has already been set to PixelWidth/Height | |
1632 // by check_track_information. | |
1633 sh_v->disp_w = track->v_dwidth; | |
1634 sh_v->disp_h = track->v_dheight; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1635 } |
31177 | 1636 sh_v->ImageDesc = ImageDesc; |
1637 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Aspect: %f\n", sh_v->aspect); | |
1638 | |
1639 sh_v->ds = demuxer->video; | |
1640 return 0; | |
1641 } | |
1642 | |
1643 static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track, | |
1644 int aid) | |
1645 { | |
1646 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; | |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31602
diff
changeset
|
1647 sh_audio_t *sh_a = new_sh_audio_aid(demuxer, track->tnum, aid, |
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31602
diff
changeset
|
1648 track->language); |
31177 | 1649 demux_packet_t *dp; |
1650 if (!sh_a) | |
1651 return 1; | |
1652 mkv_d->audio_tracks[mkv_d->last_aid] = track->tnum; | |
1653 | |
1654 sh_a->default_track = track->default_track; | |
1655 sh_a->ds = demuxer->audio; | |
32111 | 1656 sh_a->wf = malloc(sizeof(*sh_a->wf)); |
32113 | 1657 if (track->ms_compat && (track->private_size >= sizeof(*sh_a->wf))) { |
31177 | 1658 WAVEFORMATEX *wf = (WAVEFORMATEX *) track->private_data; |
32220 | 1659 if (track->private_size > USHRT_MAX + sizeof(WAVEFORMATEX)) { |
1660 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
1661 free_sh_audio(demuxer, track->tnum); | |
1662 return 1; | |
1663 } | |
31177 | 1664 sh_a->wf = realloc(sh_a->wf, track->private_size); |
1665 sh_a->wf->wFormatTag = le2me_16(wf->wFormatTag); | |
1666 sh_a->wf->nChannels = le2me_16(wf->nChannels); | |
1667 sh_a->wf->nSamplesPerSec = le2me_32(wf->nSamplesPerSec); | |
1668 sh_a->wf->nAvgBytesPerSec = le2me_32(wf->nAvgBytesPerSec); | |
1669 sh_a->wf->nBlockAlign = le2me_16(wf->nBlockAlign); | |
1670 sh_a->wf->wBitsPerSample = le2me_16(wf->wBitsPerSample); | |
32113 | 1671 sh_a->wf->cbSize = track->private_size - sizeof(*sh_a->wf); |
31177 | 1672 memcpy(sh_a->wf + 1, wf + 1, |
32113 | 1673 track->private_size - sizeof(*sh_a->wf)); |
31177 | 1674 if (track->a_sfreq == 0.0) |
1675 track->a_sfreq = sh_a->wf->nSamplesPerSec; | |
1676 if (track->a_channels == 0) | |
1677 track->a_channels = sh_a->wf->nChannels; | |
1678 if (track->a_bps == 0) | |
1679 track->a_bps = sh_a->wf->wBitsPerSample; | |
1680 track->a_formattag = sh_a->wf->wFormatTag; | |
1681 } else { | |
32113 | 1682 memset(sh_a->wf, 0, sizeof(*sh_a->wf)); |
31177 | 1683 if (!strcmp(track->codec_id, MKV_A_MP3) |
1684 || !strcmp(track->codec_id, MKV_A_MP2)) | |
1685 track->a_formattag = 0x0055; | |
1686 else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3))) | |
1687 track->a_formattag = 0x2000; | |
1688 else if (!strcmp(track->codec_id, MKV_A_DTS)) | |
1689 track->a_formattag = 0x2001; | |
33011
e9a733c1e2a1
Support E-AC3 in deprecated native matroska demuxer.
cehoyos
parents:
32467
diff
changeset
|
1690 else if (!strcmp(track->codec_id, MKV_A_EAC3)) |
e9a733c1e2a1
Support E-AC3 in deprecated native matroska demuxer.
cehoyos
parents:
32467
diff
changeset
|
1691 track->a_formattag = mmioFOURCC('E', 'A', 'C', '3'); |
31177 | 1692 else if (!strcmp(track->codec_id, MKV_A_PCM) |
1693 || !strcmp(track->codec_id, MKV_A_PCM_BE)) | |
1694 track->a_formattag = 0x0001; | |
1695 else if (!strcmp(track->codec_id, MKV_A_AAC_2MAIN) | |
1696 || !strncmp(track->codec_id, MKV_A_AAC_2LC, | |
1697 strlen(MKV_A_AAC_2LC)) | |
1698 || !strcmp(track->codec_id, MKV_A_AAC_2SSR) | |
1699 || !strcmp(track->codec_id, MKV_A_AAC_4MAIN) | |
1700 || !strncmp(track->codec_id, MKV_A_AAC_4LC, | |
1701 strlen(MKV_A_AAC_4LC)) | |
1702 || !strcmp(track->codec_id, MKV_A_AAC_4SSR) | |
1703 || !strcmp(track->codec_id, MKV_A_AAC_4LTP) | |
1704 || !strcmp(track->codec_id, MKV_A_AAC)) | |
1705 track->a_formattag = mmioFOURCC('M', 'P', '4', 'A'); | |
1706 else if (!strcmp(track->codec_id, MKV_A_VORBIS)) { | |
1707 if (track->private_data == NULL) | |
1708 return 1; | |
1709 track->a_formattag = mmioFOURCC('v', 'r', 'b', 's'); | |
1710 } else if (!strcmp(track->codec_id, MKV_A_QDMC)) | |
1711 track->a_formattag = mmioFOURCC('Q', 'D', 'M', 'C'); | |
1712 else if (!strcmp(track->codec_id, MKV_A_QDMC2)) | |
1713 track->a_formattag = mmioFOURCC('Q', 'D', 'M', '2'); | |
1714 else if (!strcmp(track->codec_id, MKV_A_WAVPACK)) | |
1715 track->a_formattag = mmioFOURCC('W', 'V', 'P', 'K'); | |
1716 else if (!strcmp(track->codec_id, MKV_A_TRUEHD)) | |
1717 track->a_formattag = mmioFOURCC('T', 'R', 'H', 'D'); | |
1718 else if (!strcmp(track->codec_id, MKV_A_FLAC)) { | |
1719 if (track->private_data == NULL || track->private_size == 0) { | |
1720 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
1721 MSGTR_MPDEMUX_MKV_FlacTrackDoesNotContainValidHeaders); | |
1722 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1723 } |
31177 | 1724 track->a_formattag = mmioFOURCC('f', 'L', 'a', 'C'); |
1725 } else if (track->private_size >= RAPROPERTIES4_SIZE) { | |
1726 if (!strcmp(track->codec_id, MKV_A_REAL28)) | |
1727 track->a_formattag = mmioFOURCC('2', '8', '_', '8'); | |
1728 else if (!strcmp(track->codec_id, MKV_A_REALATRC)) | |
1729 track->a_formattag = mmioFOURCC('a', 't', 'r', 'c'); | |
1730 else if (!strcmp(track->codec_id, MKV_A_REALCOOK)) | |
1731 track->a_formattag = mmioFOURCC('c', 'o', 'o', 'k'); | |
1732 else if (!strcmp(track->codec_id, MKV_A_REALDNET)) | |
1733 track->a_formattag = mmioFOURCC('d', 'n', 'e', 't'); | |
1734 else if (!strcmp(track->codec_id, MKV_A_REALSIPR)) | |
1735 track->a_formattag = mmioFOURCC('s', 'i', 'p', 'r'); | |
1736 } else { | |
1737 mp_msg(MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownAudioCodec, | |
1738 track->codec_id, track->tnum); | |
1739 free_sh_audio(demuxer, track->tnum); | |
1740 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1741 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1742 } |
31177 | 1743 |
1744 sh_a->format = track->a_formattag; | |
1745 sh_a->wf->wFormatTag = track->a_formattag; | |
1746 sh_a->channels = track->a_channels; | |
1747 sh_a->wf->nChannels = track->a_channels; | |
1748 sh_a->samplerate = (uint32_t) track->a_sfreq; | |
1749 sh_a->wf->nSamplesPerSec = (uint32_t) track->a_sfreq; | |
1750 if (track->a_bps == 0) { | |
1751 sh_a->samplesize = 2; | |
1752 sh_a->wf->wBitsPerSample = 16; | |
1753 } else { | |
1754 sh_a->samplesize = track->a_bps / 8; | |
1755 sh_a->wf->wBitsPerSample = track->a_bps; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1756 } |
31177 | 1757 if (track->a_formattag == 0x0055) { /* MP3 || MP2 */ |
1758 sh_a->wf->nAvgBytesPerSec = 16000; | |
1759 sh_a->wf->nBlockAlign = 1152; | |
1760 } else if ((track->a_formattag == 0x2000) || /* AC3 */ | |
33011
e9a733c1e2a1
Support E-AC3 in deprecated native matroska demuxer.
cehoyos
parents:
32467
diff
changeset
|
1761 (track->a_formattag == mmioFOURCC('E', 'A', 'C', '3')) || |
31177 | 1762 (track->a_formattag == 0x2001)) { /* DTS */ |
1763 free(sh_a->wf); | |
1764 sh_a->wf = NULL; | |
1765 } else if (track->a_formattag == 0x0001) { /* PCM || PCM_BE */ | |
1766 sh_a->wf->nAvgBytesPerSec = sh_a->channels * sh_a->samplerate * 2; | |
1767 sh_a->wf->nBlockAlign = sh_a->wf->nAvgBytesPerSec; | |
1768 if (!strcmp(track->codec_id, MKV_A_PCM_BE)) | |
1769 sh_a->format = mmioFOURCC('t', 'w', 'o', 's'); | |
1770 } else if (!strcmp(track->codec_id, MKV_A_QDMC) | |
1771 || !strcmp(track->codec_id, MKV_A_QDMC2)) { | |
1772 sh_a->wf->nAvgBytesPerSec = 16000; | |
1773 sh_a->wf->nBlockAlign = 1486; | |
1774 track->fix_i_bps = 1; | |
1775 track->qt_last_a_pts = 0.0; | |
1776 if (track->private_data != NULL) { | |
32220 | 1777 if (track->private_size > INT_MAX) { |
1778 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
1779 free_sh_audio(demuxer, track->tnum); | |
1780 return 1; | |
1781 } | |
31177 | 1782 sh_a->codecdata = malloc(track->private_size); |
1783 memcpy(sh_a->codecdata, track->private_data, track->private_size); | |
1784 sh_a->codecdata_len = track->private_size; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1785 } |
31177 | 1786 } else if (track->a_formattag == mmioFOURCC('M', 'P', '4', 'A')) { |
1787 int profile, srate_idx; | |
1788 | |
1789 sh_a->wf->nAvgBytesPerSec = 16000; | |
1790 sh_a->wf->nBlockAlign = 1024; | |
1791 | |
1792 if (!strcmp(track->codec_id, MKV_A_AAC) | |
1793 && (NULL != track->private_data)) { | |
32220 | 1794 if (track->private_size > INT_MAX) { |
1795 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
1796 free_sh_audio(demuxer, track->tnum); | |
1797 return 1; | |
1798 } | |
31177 | 1799 sh_a->codecdata = malloc(track->private_size); |
1800 memcpy(sh_a->codecdata, track->private_data, track->private_size); | |
1801 sh_a->codecdata_len = track->private_size; | |
1802 return 0; | |
1803 } | |
1804 | |
1805 /* Recreate the 'private data' */ | |
1806 /* which faad2 uses in its initialization */ | |
1807 srate_idx = aac_get_sample_rate_index(sh_a->samplerate); | |
1808 if (!strncmp(&track->codec_id[12], "MAIN", 4)) | |
1809 profile = 0; | |
1810 else if (!strncmp(&track->codec_id[12], "LC", 2)) | |
1811 profile = 1; | |
1812 else if (!strncmp(&track->codec_id[12], "SSR", 3)) | |
1813 profile = 2; | |
1814 else | |
1815 profile = 3; | |
1816 sh_a->codecdata = malloc(5); | |
1817 sh_a->codecdata[0] = ((profile + 1) << 3) | ((srate_idx & 0xE) >> 1); | |
1818 sh_a->codecdata[1] = | |
1819 ((srate_idx & 0x1) << 7) | (track->a_channels << 3); | |
1820 | |
1821 if (strstr(track->codec_id, "SBR") != NULL) { | |
1822 /* HE-AAC (aka SBR AAC) */ | |
1823 sh_a->codecdata_len = 5; | |
1824 | |
1825 sh_a->samplerate *= 2; | |
1826 sh_a->wf->nSamplesPerSec *= 2; | |
1827 srate_idx = aac_get_sample_rate_index(sh_a->samplerate); | |
1828 sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3; | |
1829 sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5; | |
1830 sh_a->codecdata[4] = (1 << 7) | (srate_idx << 3); | |
1831 track->default_duration = 1024.0 / (sh_a->samplerate / 2); | |
1832 } else { | |
1833 sh_a->codecdata_len = 2; | |
1834 track->default_duration = 1024.0 / (float) sh_a->samplerate; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1835 } |
31177 | 1836 } else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) { /* VORBIS */ |
32220 | 1837 if (track->private_size > USHRT_MAX) { |
1838 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
1839 free_sh_audio(demuxer, track->tnum); | |
1840 return 1; | |
1841 } | |
31177 | 1842 sh_a->wf->cbSize = track->private_size; |
32113 | 1843 sh_a->wf = realloc(sh_a->wf, sizeof(*sh_a->wf) + sh_a->wf->cbSize); |
31177 | 1844 memcpy((unsigned char *) (sh_a->wf + 1), track->private_data, |
1845 sh_a->wf->cbSize); | |
1846 } else if (track->private_size >= RAPROPERTIES4_SIZE | |
1847 && !strncmp(track->codec_id, MKV_A_REALATRC, 7)) { | |
1848 /* Common initialization for all RealAudio codecs */ | |
1849 unsigned char *src = track->private_data; | |
1850 int codecdata_length, version; | |
1851 int flavor; | |
1852 | |
1853 sh_a->wf->nAvgBytesPerSec = 0; /* FIXME !? */ | |
1854 | |
1855 version = AV_RB16(src + 4); | |
1856 flavor = AV_RB16(src + 22); | |
1857 track->coded_framesize = AV_RB32(src + 24); | |
1858 track->sub_packet_h = AV_RB16(src + 40); | |
1859 sh_a->wf->nBlockAlign = track->audiopk_size = AV_RB16(src + 42); | |
1860 track->sub_packet_size = AV_RB16(src + 44); | |
1861 if (version == 4) { | |
1862 src += RAPROPERTIES4_SIZE; | |
1863 src += src[0] + 1; | |
1864 src += src[0] + 1; | |
1865 } else | |
1866 src += RAPROPERTIES5_SIZE; | |
1867 | |
1868 src += 3; | |
1869 if (version == 5) | |
1870 src++; | |
1871 codecdata_length = AV_RB32(src); | |
1872 src += 4; | |
1873 sh_a->wf->cbSize = codecdata_length; | |
32113 | 1874 sh_a->wf = realloc(sh_a->wf, sizeof(*sh_a->wf) + sh_a->wf->cbSize); |
31177 | 1875 memcpy(((char *) (sh_a->wf + 1)), src, codecdata_length); |
1876 | |
1877 switch (track->a_formattag) { | |
1878 case mmioFOURCC('a', 't', 'r', 'c'): | |
1879 sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor]; | |
1880 sh_a->wf->nBlockAlign = track->sub_packet_size; | |
1881 track->audio_buf = | |
1882 malloc(track->sub_packet_h * track->audiopk_size); | |
1883 track->audio_timestamp = | |
1884 malloc(track->sub_packet_h * sizeof(float)); | |
1885 break; | |
1886 case mmioFOURCC('c', 'o', 'o', 'k'): | |
1887 sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor]; | |
1888 sh_a->wf->nBlockAlign = track->sub_packet_size; | |
1889 track->audio_buf = | |
1890 malloc(track->sub_packet_h * track->audiopk_size); | |
1891 track->audio_timestamp = | |
1892 malloc(track->sub_packet_h * sizeof(float)); | |
1893 break; | |
1894 case mmioFOURCC('s', 'i', 'p', 'r'): | |
1895 sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor]; | |
1896 sh_a->wf->nBlockAlign = track->coded_framesize; | |
1897 track->audio_buf = | |
1898 malloc(track->sub_packet_h * track->audiopk_size); | |
1899 track->audio_timestamp = | |
1900 malloc(track->sub_packet_h * sizeof(float)); | |
1901 break; | |
1902 case mmioFOURCC('2', '8', '_', '8'): | |
1903 sh_a->wf->nAvgBytesPerSec = 3600; | |
1904 sh_a->wf->nBlockAlign = track->coded_framesize; | |
1905 track->audio_buf = | |
1906 malloc(track->sub_packet_h * track->audiopk_size); | |
1907 track->audio_timestamp = | |
1908 malloc(track->sub_packet_h * sizeof(float)); | |
1909 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1910 } |
31177 | 1911 |
1912 track->realmedia = 1; | |
1913 } else if (!strcmp(track->codec_id, MKV_A_FLAC) | |
1914 || (track->a_formattag == 0xf1ac)) { | |
1915 unsigned char *ptr; | |
32220 | 1916 size_t size; |
31177 | 1917 free(sh_a->wf); |
1918 sh_a->wf = NULL; | |
1919 | |
1920 if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C')) { | |
1921 ptr = track->private_data; | |
1922 size = track->private_size; | |
1923 } else { | |
1924 sh_a->format = mmioFOURCC('f', 'L', 'a', 'C'); | |
32113 | 1925 ptr = (unsigned char *) track->private_data + sizeof(*sh_a->wf); |
1926 size = track->private_size - sizeof(*sh_a->wf); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1927 } |
31177 | 1928 if (size < 4 || ptr[0] != 'f' || ptr[1] != 'L' || ptr[2] != 'a' |
1929 || ptr[3] != 'C') { | |
1930 dp = new_demux_packet(4); | |
1931 memcpy(dp->buffer, "fLaC", 4); | |
1932 } else { | |
1933 dp = new_demux_packet(size); | |
1934 memcpy(dp->buffer, ptr, size); | |
1935 } | |
1936 dp->pts = 0; | |
1937 dp->flags = 0; | |
1938 ds_add_packet(demuxer->audio, dp); | |
1939 } else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || | |
1940 track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { | |
1941 /* do nothing, still works */ | |
1942 } else if (!track->ms_compat | |
32113 | 1943 || (track->private_size < sizeof(*sh_a->wf))) { |
31177 | 1944 free_sh_audio(demuxer, track->tnum); |
1945 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1946 } |
31177 | 1947 |
1948 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1949 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1950 |
31177 | 1951 static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track, |
1952 int sid) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1953 { |
31177 | 1954 if (track->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN) { |
32220 | 1955 size_t size; |
1956 int m; | |
31177 | 1957 uint8_t *buffer; |
31609
cd81fce1f010
Make the stream language an argument to the stream creation function
reimar
parents:
31602
diff
changeset
|
1958 sh_sub_t *sh = new_sh_sub_sid(demuxer, track->tnum, sid, track->language); |
31177 | 1959 track->sh_sub = sh; |
1960 sh->type = 't'; | |
1961 if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB) | |
1962 sh->type = 'v'; | |
1963 if (track->subtitle_type == MATROSKA_SUBTYPE_SSA) | |
1964 sh->type = 'a'; | |
1965 size = track->private_size; | |
1966 m = demux_mkv_decode(track, track->private_data, &buffer, &size, 2); | |
1967 if (buffer && m) { | |
1968 free(track->private_data); | |
1969 track->private_data = buffer; | |
1970 track->private_size = size; | |
25651
3d5fb36693ac
Factorize private data decoding for subtitle tracks in mkv demuxer.
eugeni
parents:
25432
diff
changeset
|
1971 } |
32220 | 1972 if (track->private_size > INT_MAX) { |
1973 mp_msg(MSGT_DEMUX, MSGL_ERR, "[mkv] Integer overflow!\n"); | |
1974 return 1; | |
1975 } | |
31177 | 1976 sh->extradata = malloc(track->private_size); |
1977 memcpy(sh->extradata, track->private_data, track->private_size); | |
1978 sh->extradata_len = track->private_size; | |
1979 sh->default_track = track->default_track; | |
1980 } else { | |
1981 mp_msg(MSGT_DEMUX, MSGL_ERR, | |
1982 MSGTR_MPDEMUX_MKV_SubtitleTypeNotSupported, track->codec_id); | |
1983 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1984 } |
31177 | 1985 |
1986 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1987 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1988 |
31177 | 1989 static int demux_mkv_open(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
1990 { |
31177 | 1991 stream_t *s = demuxer->stream; |
1992 mkv_demuxer_t *mkv_d; | |
1993 mkv_track_t *track; | |
1994 int i, version, cont = 0; | |
1995 char *str; | |
1996 | |
1997 stream_seek(s, s->start_pos); | |
1998 str = ebml_read_header(s, &version); | |
31263 | 1999 if (str == NULL || (strcmp(str, "matroska") && strcmp(str, "webm")) || version > 2) { |
31177 | 2000 mp_msg(MSGT_DEMUX, MSGL_DBG2, "[mkv] no head found\n"); |
2001 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2002 } |
31177 | 2003 free(str); |
2004 | |
2005 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Found the head...\n"); | |
2006 | |
2007 if (ebml_read_id(s, NULL) != MATROSKA_ID_SEGMENT) { | |
2008 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] but no segment :(\n"); | |
2009 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2010 } |
31177 | 2011 ebml_read_length(s, NULL); /* return bytes number until EOF */ |
2012 | |
2013 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] + a segment...\n"); | |
2014 | |
2015 mkv_d = calloc(1, sizeof(mkv_demuxer_t)); | |
2016 demuxer->priv = mkv_d; | |
2017 mkv_d->tc_scale = 1000000; | |
2018 mkv_d->segment_start = stream_tell(s); | |
2019 mkv_d->parsed_cues = malloc(sizeof(off_t)); | |
2020 mkv_d->parsed_seekhead = malloc(sizeof(off_t)); | |
2021 | |
2022 while (!cont) { | |
2023 switch (ebml_read_id(s, NULL)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2024 case MATROSKA_ID_INFO: |
31177 | 2025 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] |+ segment information...\n"); |
2026 cont = demux_mkv_read_info(demuxer); | |
2027 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2028 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2029 case MATROSKA_ID_TRACKS: |
31177 | 2030 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] |+ segment tracks...\n"); |
2031 cont = demux_mkv_read_tracks(demuxer); | |
2032 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2033 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2034 case MATROSKA_ID_CUES: |
31177 | 2035 cont = demux_mkv_read_cues(demuxer); |
2036 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2037 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2038 case MATROSKA_ID_TAGS: |
31177 | 2039 cont = demux_mkv_read_tags(demuxer); |
2040 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2041 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2042 case MATROSKA_ID_SEEKHEAD: |
31177 | 2043 cont = demux_mkv_read_seekhead(demuxer); |
2044 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2045 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2046 case MATROSKA_ID_CHAPTERS: |
31177 | 2047 cont = demux_mkv_read_chapters(demuxer); |
2048 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2049 |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
2050 case MATROSKA_ID_ATTACHMENTS: |
31177 | 2051 cont = demux_mkv_read_attachments(demuxer); |
2052 break; | |
18937
9e95ac641e77
Initial libass release (without mencoder support).
eugeni
parents:
18934
diff
changeset
|
2053 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2054 case MATROSKA_ID_CLUSTER: |
31177 | 2055 { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2056 int p, l; |
31177 | 2057 mp_msg(MSGT_DEMUX, MSGL_V, |
2058 "[mkv] |+ found cluster, headers are " | |
2059 "parsed completely :)\n"); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2060 /* get the first cluster timecode */ |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2061 p = stream_tell(s); |
31177 | 2062 l = ebml_read_length(s, NULL); |
2063 while (ebml_read_id(s, NULL) != MATROSKA_ID_CLUSTERTIMECODE) { | |
2064 ebml_read_skip(s, NULL); | |
2065 if (stream_tell(s) >= p + l) | |
2066 break; | |
2067 } | |
2068 if (stream_tell(s) < p + l) { | |
2069 uint64_t num = ebml_read_uint(s, NULL); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2070 if (num == EBML_UINT_INVALID) |
31177 | 2071 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2072 mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2073 mkv_d->has_first_tc = 1; |
31177 | 2074 } |
2075 stream_seek(s, p - 4); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2076 cont = 1; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2077 break; |
31177 | 2078 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2079 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2080 default: |
31177 | 2081 cont = 1; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2082 case EBML_ID_VOID: |
31177 | 2083 ebml_read_skip(s, NULL); |
18754
e0077bdf5ee5
feed any audio track present in the mux; switch to any of the available audio tracks
nicodvb
parents:
18708
diff
changeset
|
2084 break; |
e0077bdf5ee5
feed any audio track present in the mux; switch to any of the available audio tracks
nicodvb
parents:
18708
diff
changeset
|
2085 } |
e0077bdf5ee5
feed any audio track present in the mux; switch to any of the available audio tracks
nicodvb
parents:
18708
diff
changeset
|
2086 } |
e0077bdf5ee5
feed any audio track present in the mux; switch to any of the available audio tracks
nicodvb
parents:
18708
diff
changeset
|
2087 |
31177 | 2088 display_create_tracks(demuxer); |
2089 | |
2090 /* select video track */ | |
2091 track = NULL; | |
2092 if (demuxer->video->id == -1) { /* automatically select a video track */ | |
2093 /* search for a video track that has the 'default' flag set */ | |
2094 for (i = 0; i < mkv_d->num_tracks; i++) | |
2095 if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO | |
2096 && mkv_d->tracks[i]->default_track) { | |
2097 track = mkv_d->tracks[i]; | |
2098 break; | |
2099 } | |
2100 | |
2101 if (track == NULL) | |
2102 /* no track has the 'default' flag set */ | |
2103 /* let's take the first video track */ | |
2104 for (i = 0; i < mkv_d->num_tracks; i++) | |
2105 if (mkv_d->tracks[i]->type == MATROSKA_TRACK_VIDEO) { | |
2106 track = mkv_d->tracks[i]; | |
2107 break; | |
2108 } | |
2109 } else if (demuxer->video->id != -2) /* -2 = no video at all */ | |
2110 track = demux_mkv_find_track_by_num(mkv_d, demuxer->video->id, | |
2111 MATROSKA_TRACK_VIDEO); | |
2112 | |
2113 if (track && demuxer->v_streams[track->tnum]) { | |
2114 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_WillPlayVideoTrack, | |
2115 track->tnum); | |
2116 demuxer->video->id = track->tnum; | |
2117 demuxer->video->sh = demuxer->v_streams[track->tnum]; | |
2118 } else { | |
2119 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_NoVideoTrackFound); | |
2120 demuxer->video->id = -2; | |
2121 } | |
2122 | |
2123 /* select audio track */ | |
2124 track = NULL; | |
2125 if (track == NULL) | |
2126 /* search for an audio track that has the 'default' flag set */ | |
2127 for (i = 0; i < mkv_d->num_tracks; i++) | |
2128 if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO | |
2129 && mkv_d->tracks[i]->default_track) { | |
2130 track = mkv_d->tracks[i]; | |
2131 break; | |
2132 } | |
2133 | |
2134 if (track == NULL) | |
2135 /* no track has the 'default' flag set */ | |
2136 /* let's take the first audio track */ | |
2137 for (i = 0; i < mkv_d->num_tracks; i++) | |
2138 if (mkv_d->tracks[i]->type == MATROSKA_TRACK_AUDIO) { | |
2139 track = mkv_d->tracks[i]; | |
2140 break; | |
2141 } | |
2142 | |
2143 if (track && demuxer->a_streams[track->tnum]) { | |
2144 demuxer->audio->id = track->tnum; | |
2145 demuxer->audio->sh = demuxer->a_streams[track->tnum]; | |
2146 } else { | |
2147 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_MPDEMUX_MKV_NoAudioTrackFound); | |
2148 demuxer->audio->id = -2; | |
2149 } | |
2150 | |
2151 | |
2152 if (demuxer->audio->id != -2) | |
2153 for (i = 0; i < mkv_d->num_tracks; i++) { | |
2154 if (mkv_d->tracks[i]->type != MATROSKA_TRACK_AUDIO) | |
2155 continue; | |
2156 if (demuxer->a_streams[track->tnum]) { | |
2157 mkv_d->last_aid++; | |
2158 if (mkv_d->last_aid == MAX_A_STREAMS) | |
2159 break; | |
2160 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2161 } |
31177 | 2162 |
2163 if (demuxer->chapters) { | |
2164 for (i = 0; i < (int) demuxer->num_chapters; i++) { | |
2165 demuxer->chapters[i].start -= mkv_d->first_tc; | |
2166 demuxer->chapters[i].end -= mkv_d->first_tc; | |
2167 } | |
2168 if (dvd_last_chapter > 0 && dvd_last_chapter <= demuxer->num_chapters) { | |
2169 if (demuxer->chapters[dvd_last_chapter - 1].end != 0) | |
2170 mkv_d->stop_timecode = | |
2171 demuxer->chapters[dvd_last_chapter - 1].end; | |
2172 else if (dvd_last_chapter + 1 <= demuxer->num_chapters) | |
2173 mkv_d->stop_timecode = | |
2174 demuxer->chapters[dvd_last_chapter].start; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2175 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2176 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2177 |
31177 | 2178 if (s->end_pos == 0 || (mkv_d->indexes == NULL && index_mode < 0)) |
2179 demuxer->seekable = 0; | |
2180 else { | |
2181 demuxer->movi_start = s->start_pos; | |
2182 demuxer->movi_end = s->end_pos; | |
2183 demuxer->seekable = 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2184 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2185 |
31177 | 2186 return DEMUXER_TYPE_MATROSKA; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2187 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2188 |
31177 | 2189 static void demux_close_mkv(demuxer_t *demuxer) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2190 { |
31177 | 2191 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2192 | |
2193 if (mkv_d) { | |
2194 int i; | |
2195 free_cached_dps(demuxer); | |
2196 if (mkv_d->tracks) { | |
2197 for (i = 0; i < mkv_d->num_tracks; i++) | |
2198 demux_mkv_free_trackentry(mkv_d->tracks[i]); | |
2199 free(mkv_d->tracks); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2200 } |
31177 | 2201 free(mkv_d->indexes); |
2202 free(mkv_d->cluster_positions); | |
2203 free(mkv_d->parsed_cues); | |
2204 free(mkv_d->parsed_seekhead); | |
2205 free(mkv_d); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2206 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2207 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2208 |
31177 | 2209 static int demux_mkv_read_block_lacing(uint8_t *buffer, uint64_t *size, |
2210 uint8_t *laces, | |
2211 uint32_t **all_lace_sizes) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2212 { |
31177 | 2213 uint32_t total = 0, *lace_size; |
2214 uint8_t flags; | |
2215 int i; | |
2216 | |
2217 *all_lace_sizes = NULL; | |
2218 lace_size = NULL; | |
2219 /* lacing flags */ | |
2220 flags = *buffer++; | |
2221 (*size)--; | |
2222 | |
2223 switch ((flags & 0x06) >> 1) { | |
2224 case 0: /* no lacing */ | |
2225 *laces = 1; | |
2226 lace_size = calloc(*laces, sizeof(uint32_t)); | |
2227 lace_size[0] = *size; | |
2228 break; | |
2229 | |
2230 case 1: /* xiph lacing */ | |
2231 case 2: /* fixed-size lacing */ | |
2232 case 3: /* EBML lacing */ | |
2233 *laces = *buffer++; | |
2234 (*size)--; | |
2235 (*laces)++; | |
2236 lace_size = calloc(*laces, sizeof(uint32_t)); | |
2237 | |
2238 switch ((flags & 0x06) >> 1) { | |
2239 case 1: /* xiph lacing */ | |
2240 for (i = 0; i < *laces - 1; i++) { | |
2241 lace_size[i] = 0; | |
2242 do { | |
2243 lace_size[i] += *buffer; | |
2244 (*size)--; | |
2245 } while (*buffer++ == 0xFF); | |
2246 total += lace_size[i]; | |
2247 } | |
2248 lace_size[i] = *size - total; | |
2249 break; | |
2250 | |
2251 case 2: /* fixed-size lacing */ | |
2252 for (i = 0; i < *laces; i++) | |
2253 lace_size[i] = *size / *laces; | |
2254 break; | |
2255 | |
2256 case 3: /* EBML lacing */ | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2257 { |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2258 int l; |
31177 | 2259 uint64_t num = ebml_read_vlen_uint(buffer, &l); |
12065 | 2260 if (num == EBML_UINT_INVALID) { |
31177 | 2261 free(lace_size); |
2262 return 1; | |
12065 | 2263 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2264 buffer += l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2265 *size -= l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2266 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2267 total = lace_size[0] = num; |
31177 | 2268 for (i = 1; i < *laces - 1; i++) { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2269 int64_t snum; |
31177 | 2270 snum = ebml_read_vlen_int(buffer, &l); |
12065 | 2271 if (snum == EBML_INT_INVALID) { |
31177 | 2272 free(lace_size); |
2273 return 1; | |
12065 | 2274 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2275 buffer += l; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2276 *size -= l; |
31177 | 2277 lace_size[i] = lace_size[i - 1] + snum; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2278 total += lace_size[i]; |
31177 | 2279 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2280 lace_size[i] = *size - total; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2281 break; |
31177 | 2282 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2283 } |
31177 | 2284 break; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2285 } |
31177 | 2286 *all_lace_sizes = lace_size; |
2287 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2288 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2289 |
31177 | 2290 static void handle_subtitles(demuxer_t *demuxer, mkv_track_t *track, |
2291 char *block, int64_t size, | |
2292 uint64_t block_duration, uint64_t timecode) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2293 { |
31177 | 2294 demux_packet_t *dp; |
2295 | |
2296 if (block_duration == 0) { | |
2297 mp_msg(MSGT_DEMUX, MSGL_WARN, | |
2298 MSGTR_MPDEMUX_MKV_NoBlockDurationForSubtitleTrackFound); | |
2299 return; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2300 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2301 |
31177 | 2302 sub_utf8 = 1; |
2303 dp = new_demux_packet(size); | |
2304 memcpy(dp->buffer, block, size); | |
2305 dp->pts = timecode / 1000.0f; | |
2306 dp->endpts = (timecode + block_duration) / 1000.0f; | |
2307 ds_add_packet(demuxer->sub, dp); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2308 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2309 |
31177 | 2310 static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track, |
2311 uint8_t *buffer, uint32_t size, int block_bref) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2312 { |
31177 | 2313 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2314 demux_packet_t *dp; | |
2315 uint32_t timestamp = mkv_d->last_pts * 1000; | |
2316 | |
2317 dp = new_demux_packet(size); | |
2318 memcpy(dp->buffer, buffer, size); | |
2319 | |
2320 if (mkv_d->v_skip_to_keyframe) { | |
2321 dp->pts = mkv_d->last_pts; | |
2322 track->rv_kf_base = 0; | |
2323 track->rv_kf_pts = timestamp; | |
2324 } else | |
2325 dp->pts = | |
2326 real_fix_timestamp(dp->buffer, timestamp, | |
2327 ((sh_video_t *) demuxer->video->sh)->bih-> | |
2328 biCompression, &track->rv_kf_base, | |
2329 &track->rv_kf_pts, NULL); | |
2330 dp->pos = demuxer->filepos; | |
2331 dp->flags = block_bref ? 0 : 0x10; | |
2332 | |
2333 ds_add_packet(demuxer->video, dp); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2334 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2335 |
31177 | 2336 static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track, |
2337 uint8_t *buffer, uint32_t size, int block_bref) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2338 { |
31177 | 2339 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2340 int sps = track->sub_packet_size; | |
2341 int sph = track->sub_packet_h; | |
2342 int cfs = track->coded_framesize; | |
2343 int w = track->audiopk_size; | |
2344 int spc = track->sub_packet_cnt; | |
2345 demux_packet_t *dp; | |
2346 int x; | |
2347 | |
2348 if ((track->a_formattag == mmioFOURCC('2', '8', '_', '8')) | |
2349 || (track->a_formattag == mmioFOURCC('c', 'o', 'o', 'k')) | |
2350 || (track->a_formattag == mmioFOURCC('a', 't', 'r', 'c')) | |
2351 || (track->a_formattag == mmioFOURCC('s', 'i', 'p', 'r'))) { | |
18036 | 2352 // if(!block_bref) |
2353 // spc = track->sub_packet_cnt = 0; | |
31177 | 2354 switch (track->a_formattag) { |
18036 | 2355 case mmioFOURCC('2', '8', '_', '8'): |
31177 | 2356 for (x = 0; x < sph / 2; x++) |
2357 memcpy(track->audio_buf + x * 2 * w + spc * cfs, | |
2358 buffer + cfs * x, cfs); | |
2359 break; | |
18036 | 2360 case mmioFOURCC('c', 'o', 'o', 'k'): |
2361 case mmioFOURCC('a', 't', 'r', 'c'): | |
31177 | 2362 for (x = 0; x < w / sps; x++) |
2363 memcpy(track->audio_buf + | |
2364 sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + | |
2365 (spc >> 1)), buffer + sps * x, sps); | |
2366 break; | |
18036 | 2367 case mmioFOURCC('s', 'i', 'p', 'r'): |
31177 | 2368 memcpy(track->audio_buf + spc * w, buffer, w); |
2369 if (spc == sph - 1) { | |
2370 int n; | |
2371 int bs = sph * w * 2 / 96; // nibbles per subpacket | |
2372 // Perform reordering | |
2373 for (n = 0; n < 38; n++) { | |
2374 int j; | |
2375 int i = bs * sipr_swaps[n][0]; | |
2376 int o = bs * sipr_swaps[n][1]; | |
2377 // swap nibbles of block 'i' with 'o' TODO: optimize | |
2378 for (j = 0; j < bs; j++) { | |
2379 int x = (i & 1) ? | |
2380 (track->audio_buf[i >> 1] >> 4) : | |
2381 (track->audio_buf[i >> 1] & 0x0F); | |
2382 int y = (o & 1) ? | |
2383 (track->audio_buf[o >> 1] >> 4) : | |
2384 (track->audio_buf[o >> 1] & 0x0F); | |
2385 if (o & 1) | |
2386 track->audio_buf[o >> 1] = | |
2387 (track->audio_buf[o >> 1] & 0x0F) | (x << 4); | |
2388 else | |
2389 track->audio_buf[o >> 1] = | |
2390 (track->audio_buf[o >> 1] & 0xF0) | x; | |
2391 if (i & 1) | |
2392 track->audio_buf[i >> 1] = | |
2393 (track->audio_buf[i >> 1] & 0x0F) | (y << 4); | |
2394 else | |
2395 track->audio_buf[i >> 1] = | |
2396 (track->audio_buf[i >> 1] & 0xF0) | y; | |
2397 ++i; | |
2398 ++o; | |
18036 | 2399 } |
2400 } | |
2401 } | |
31177 | 2402 break; |
18036 | 2403 } |
31177 | 2404 track->audio_timestamp[track->sub_packet_cnt] = |
2405 (track->ra_pts == mkv_d->last_pts) ? 0 : (mkv_d->last_pts); | |
2406 track->ra_pts = mkv_d->last_pts; | |
2407 if (track->sub_packet_cnt == 0) | |
2408 track->audio_filepos = demuxer->filepos; | |
2409 if (++(track->sub_packet_cnt) == sph) { | |
2410 int apk_usize = | |
32112 | 2411 ((sh_audio_t *) demuxer->audio->sh)->wf->nBlockAlign; |
31177 | 2412 track->sub_packet_cnt = 0; |
2413 // Release all the audio packets | |
2414 for (x = 0; x < sph * w / apk_usize; x++) { | |
2415 dp = new_demux_packet(apk_usize); | |
2416 memcpy(dp->buffer, track->audio_buf + x * apk_usize, | |
2417 apk_usize); | |
2418 /* Put timestamp only on packets that correspond to original | |
2419 * audio packets in file */ | |
2420 dp->pts = (x * apk_usize % w) ? 0 : | |
2421 track->audio_timestamp[x * apk_usize / w]; | |
2422 dp->pos = track->audio_filepos; // all equal | |
2423 dp->flags = x ? 0 : 0x10; // Mark first packet as keyframe | |
2424 ds_add_packet(demuxer->audio, dp); | |
2425 } | |
2426 } | |
2427 } else { // Not a codec that require reordering | |
2428 dp = new_demux_packet(size); | |
2429 memcpy(dp->buffer, buffer, size); | |
2430 if (track->ra_pts == mkv_d->last_pts && !mkv_d->a_skip_to_keyframe) | |
2431 dp->pts = 0; | |
2432 else | |
2433 dp->pts = mkv_d->last_pts; | |
2434 track->ra_pts = mkv_d->last_pts; | |
2435 | |
2436 dp->pos = demuxer->filepos; | |
2437 dp->flags = block_bref ? 0 : 0x10; | |
2438 ds_add_packet(demuxer->audio, dp); | |
2439 } | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2440 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2441 |
14054 | 2442 /** Reorder timecodes and add cached demux packets to the queues. |
2443 * | |
2444 * Timecode reordering is needed if a video track contains B frames that | |
2445 * are timestamped in display order (e.g. MPEG-1, MPEG-2 or "native" MPEG-4). | |
2446 * MPlayer doesn't like timestamps in display order. This function adjusts | |
2447 * the timestamp of cached frames (which are exactly one I/P frame followed | |
2448 * by one or more B frames) so that they are in coding order again. | |
2449 * | |
2450 * Example: The track with 25 FPS contains four frames with the timecodes | |
2451 * I at 0ms, P at 120ms, B at 40ms and B at 80ms. As soon as the next I | |
2452 * or P frame arrives these timecodes can be changed to I at 0ms, P at 40ms, | |
2453 * B at 80ms and B at 120ms. | |
2454 * | |
16912
4dea8b8f3b65
sort timestamps instead of assuming conventional B-frame order. (fixes x264 B-pyramid)
lorenm
parents:
16877
diff
changeset
|
2455 * This works for simple H.264 B-frame pyramids, but not for arbitrary orders. |
4dea8b8f3b65
sort timestamps instead of assuming conventional B-frame order. (fixes x264 B-pyramid)
lorenm
parents:
16877
diff
changeset
|
2456 * |
14054 | 2457 * \param demuxer The Matroska demuxer struct for this instance. |
2458 * \param track The track structure whose cache should be handled. | |
2459 */ | |
31177 | 2460 static void flush_cached_dps(demuxer_t *demuxer, mkv_track_t *track) |
14054 | 2461 { |
31177 | 2462 int i, ok; |
2463 | |
2464 if (track->num_cached_dps == 0) | |
2465 return; | |
2466 | |
2467 do { | |
2468 ok = 1; | |
2469 for (i = 1; i < track->num_cached_dps; i++) | |
2470 if (track->cached_dps[i - 1]->pts > track->cached_dps[i]->pts) { | |
2471 float tmp_pts = track->cached_dps[i - 1]->pts; | |
2472 track->cached_dps[i - 1]->pts = track->cached_dps[i]->pts; | |
2473 track->cached_dps[i]->pts = tmp_pts; | |
2474 ok = 0; | |
2475 } | |
2476 } while (!ok); | |
2477 | |
2478 for (i = 0; i < track->num_cached_dps; i++) | |
2479 ds_add_packet(demuxer->video, track->cached_dps[i]); | |
2480 track->num_cached_dps = 0; | |
14054 | 2481 } |
2482 | |
2483 /** Cache video frames if timecodes have to be reordered. | |
2484 * | |
2485 * Timecode reordering is needed if a video track contains B frames that | |
2486 * are timestamped in display order (e.g. MPEG-1, MPEG-2 or "native" MPEG-4). | |
2487 * This function takes in a Matroska block read from the file, allocates a | |
2488 * demux packet for it, fills in its values, allocates space for storing | |
2489 * pointers to the cached demux packets and adds the packet to it. If | |
2490 * the packet contains an I or a P frame then ::flush_cached_dps is called | |
2491 * in order to send the old cached frames downstream. | |
2492 * | |
2493 * \param demuxer The Matroska demuxer struct for this instance. | |
2494 * \param track The packet is meant for this track. | |
2495 * \param buffer The actual frame contents. | |
2496 * \param size The frame size in bytes. | |
2497 * \param block_bref A relative timecode (backward reference). If it is \c 0 | |
2498 * then the frame is an I frame. | |
2499 * \param block_fref A relative timecode (forward reference). If it is \c 0 | |
2500 * then the frame is either an I frame or a P frame depending on the value | |
2501 * of \a block_bref. Otherwise it's a B frame. | |
2502 */ | |
31177 | 2503 static void handle_video_bframes(demuxer_t *demuxer, mkv_track_t *track, |
2504 uint8_t *buffer, uint32_t size, | |
2505 int block_bref, int block_fref) | |
14054 | 2506 { |
31177 | 2507 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2508 demux_packet_t *dp; | |
2509 | |
2510 dp = new_demux_packet(size); | |
2511 memcpy(dp->buffer, buffer, size); | |
2512 dp->pos = demuxer->filepos; | |
2513 dp->pts = mkv_d->last_pts; | |
2514 if ((track->num_cached_dps > 0) && (dp->pts < track->max_pts)) | |
2515 block_fref = 1; | |
2516 if (block_fref == 0) /* I or P frame */ | |
2517 flush_cached_dps(demuxer, track); | |
2518 if (block_bref != 0) /* I frame, don't cache it */ | |
2519 dp->flags = 0x10; | |
2520 if ((track->num_cached_dps + 1) > track->num_allocated_dps) { | |
2521 track->cached_dps = (demux_packet_t **) | |
2522 realloc(track->cached_dps, | |
2523 (track->num_cached_dps + 10) * sizeof(demux_packet_t *)); | |
2524 track->num_allocated_dps += 10; | |
14054 | 2525 } |
31177 | 2526 track->cached_dps[track->num_cached_dps] = dp; |
2527 track->num_cached_dps++; | |
2528 if (dp->pts > track->max_pts) | |
2529 track->max_pts = dp->pts; | |
14054 | 2530 } |
2531 | |
31177 | 2532 static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length, |
2533 uint64_t block_duration, int64_t block_bref, | |
2534 int64_t block_fref, uint8_t simpleblock) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2535 { |
31177 | 2536 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2537 mkv_track_t *track = NULL; | |
2538 demux_stream_t *ds = NULL; | |
2539 uint64_t old_length; | |
2540 int64_t tc; | |
2541 uint32_t *lace_size; | |
2542 uint8_t laces, flags; | |
2543 int i, num, tmp, use_this_block = 1; | |
2544 float current_pts; | |
2545 int16_t time; | |
2546 | |
2547 /* first byte(s): track num */ | |
2548 num = ebml_read_vlen_uint(block, &tmp); | |
2549 block += tmp; | |
2550 /* time (relative to cluster time) */ | |
2551 time = block[0] << 8 | block[1]; | |
2552 block += 2; | |
2553 length -= tmp + 2; | |
2554 old_length = length; | |
2555 flags = block[0]; | |
2556 if (demux_mkv_read_block_lacing(block, &length, &laces, &lace_size)) | |
2557 return 0; | |
2558 block += old_length - length; | |
2559 | |
2560 tc = ((time * mkv_d->tc_scale + mkv_d->cluster_tc) / 1000000.0 - | |
2561 mkv_d->first_tc); | |
2562 if (tc < 0) | |
2563 tc = 0; | |
2564 if (mkv_d->stop_timecode > 0 && tc > mkv_d->stop_timecode) { | |
2565 free(lace_size); | |
2566 return -1; | |
12721
44895a7161c8
Do not dereference NULL if no track could be found for a block.
mosu
parents:
12550
diff
changeset
|
2567 } |
31177 | 2568 current_pts = tc / 1000.0; |
2569 | |
2570 for (i = 0; i < mkv_d->num_tracks; i++) | |
2571 if (mkv_d->tracks[i]->tnum == num) { | |
2572 track = mkv_d->tracks[i]; | |
2573 break; | |
19977 | 2574 } |
31177 | 2575 if (track == NULL) { |
2576 free(lace_size); | |
2577 return 1; | |
2578 } | |
2579 if (num == demuxer->audio->id) { | |
2580 ds = demuxer->audio; | |
2581 | |
2582 if (mkv_d->a_skip_to_keyframe) { | |
2583 if (simpleblock) { | |
2584 if (!(flags & 0x80)) /*current frame isn't a keyframe */ | |
2585 use_this_block = 0; | |
2586 } else if (block_bref != 0) | |
2587 use_this_block = 0; | |
2588 } else if (mkv_d->v_skip_to_keyframe) | |
2589 use_this_block = 0; | |
2590 | |
2591 if (track->fix_i_bps && use_this_block) { | |
2592 sh_audio_t *sh = (sh_audio_t *) ds->sh; | |
2593 | |
2594 if (block_duration != 0) { | |
2595 sh->i_bps = length * 1000 / block_duration; | |
2596 track->fix_i_bps = 0; | |
2597 } else if (track->qt_last_a_pts == 0.0) | |
2598 track->qt_last_a_pts = current_pts; | |
2599 else if (track->qt_last_a_pts != current_pts) { | |
2600 sh->i_bps = length / (current_pts - track->qt_last_a_pts); | |
2601 track->fix_i_bps = 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2602 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2603 } |
31177 | 2604 } else if (tc < mkv_d->skip_to_timecode) |
2605 use_this_block = 0; | |
2606 else if (num == demuxer->video->id) { | |
2607 ds = demuxer->video; | |
2608 if (mkv_d->v_skip_to_keyframe) { | |
2609 if (simpleblock) { | |
2610 if (!(flags & 0x80)) /*current frame isn't a keyframe */ | |
2611 use_this_block = 0; | |
2612 } else if (block_bref != 0 || block_fref != 0) | |
19977 | 2613 use_this_block = 0; |
31177 | 2614 } |
2615 } else if (num == demuxer->sub->id) { | |
2616 ds = demuxer->sub; | |
2617 if (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB) { | |
2618 if (!mkv_d->v_skip_to_keyframe) | |
2619 handle_subtitles(demuxer, track, block, length, block_duration, | |
2620 tc); | |
19977 | 2621 use_this_block = 0; |
2622 } | |
31177 | 2623 } else |
2624 use_this_block = 0; | |
2625 | |
2626 if (use_this_block) { | |
2627 mkv_d->last_pts = current_pts; | |
2628 mkv_d->last_filepos = demuxer->filepos; | |
2629 | |
2630 for (i = 0; i < laces; i++) { | |
2631 if (ds == demuxer->video && track->realmedia) | |
2632 handle_realvideo(demuxer, track, block, lace_size[i], | |
2633 block_bref); | |
2634 else if (ds == demuxer->audio && track->realmedia) | |
2635 handle_realaudio(demuxer, track, block, lace_size[i], | |
2636 block_bref); | |
2637 else if (ds == demuxer->video && track->reorder_timecodes) | |
2638 handle_video_bframes(demuxer, track, block, lace_size[i], | |
2639 block_bref, block_fref); | |
2640 else { | |
32220 | 2641 int modified; |
2642 size_t size = lace_size[i]; | |
31177 | 2643 demux_packet_t *dp; |
2644 uint8_t *buffer; | |
2645 modified = demux_mkv_decode(track, block, &buffer, &size, 1); | |
2646 if (buffer) { | |
2647 dp = new_demux_packet(size); | |
2648 memcpy(dp->buffer, buffer, size); | |
2649 if (modified) | |
2650 free(buffer); | |
2651 dp->flags = (block_bref == 0 | |
2652 && block_fref == 0) ? 0x10 : 0; | |
2653 /* If default_duration is 0, assume no pts value is known | |
2654 * for packets after the first one (rather than all pts | |
2655 * values being the same) */ | |
2656 if (i == 0 || track->default_duration) | |
2657 dp->pts = | |
2658 mkv_d->last_pts + i * track->default_duration; | |
2659 ds_add_packet(ds, dp); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2660 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2661 } |
31177 | 2662 block += lace_size[i]; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2663 } |
31177 | 2664 |
2665 if (ds == demuxer->video) { | |
2666 mkv_d->v_skip_to_keyframe = 0; | |
2667 mkv_d->skip_to_timecode = 0; | |
2668 } else if (ds == demuxer->audio) | |
2669 mkv_d->a_skip_to_keyframe = 0; | |
2670 | |
2671 free(lace_size); | |
2672 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2673 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2674 |
31177 | 2675 free(lace_size); |
2676 return 0; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2677 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2678 |
31177 | 2679 static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2680 { |
31177 | 2681 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2682 stream_t *s = demuxer->stream; | |
2683 uint64_t l; | |
2684 int il, tmp; | |
2685 | |
2686 while (1) { | |
2687 while (mkv_d->cluster_size > 0) { | |
2688 uint64_t block_duration = 0, block_length = 0; | |
2689 int64_t block_bref = 0, block_fref = 0; | |
2690 uint8_t *block = NULL; | |
2691 | |
2692 while (mkv_d->blockgroup_size > 0) { | |
2693 switch (ebml_read_id(s, &il)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2694 case MATROSKA_ID_BLOCKDURATION: |
31177 | 2695 block_duration = ebml_read_uint(s, &l); |
23704 | 2696 if (block_duration == EBML_UINT_INVALID) { |
31177 | 2697 free(block); |
2698 return 0; | |
23704 | 2699 } |
19810 | 2700 block_duration *= mkv_d->tc_scale / 1000000.0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2701 break; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2702 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2703 case MATROSKA_ID_BLOCK: |
31177 | 2704 block_length = ebml_read_length(s, &tmp); |
20155 | 2705 free(block); |
31177 | 2706 if (block_length > SIZE_MAX - AV_LZO_INPUT_PADDING) |
2707 return 0; | |
2708 block = malloc(block_length + AV_LZO_INPUT_PADDING); | |
2709 demuxer->filepos = stream_tell(s); | |
2710 if (stream_read(s, block, block_length) != | |
2711 (int) block_length) { | |
2712 free(block); | |
2713 return 0; | |
2714 } | |
2715 l = tmp + block_length; | |
2716 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2717 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2718 case MATROSKA_ID_REFERENCEBLOCK: |
31177 | 2719 { |
2720 int64_t num = ebml_read_int(s, &l); | |
23704 | 2721 if (num == EBML_INT_INVALID) { |
31177 | 2722 free(block); |
2723 return 0; | |
23704 | 2724 } |
14054 | 2725 if (num <= 0) |
31177 | 2726 block_bref = num; |
14054 | 2727 else |
31177 | 2728 block_fref = num; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2729 break; |
31177 | 2730 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2731 |
11934
bef061911390
Exit when an invalid EBML ID has been read (e.g. for files that have been cut off).
mosu
parents:
11901
diff
changeset
|
2732 case EBML_ID_INVALID: |
31177 | 2733 free(block); |
2734 return 0; | |
11934
bef061911390
Exit when an invalid EBML ID has been read (e.g. for files that have been cut off).
mosu
parents:
11901
diff
changeset
|
2735 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2736 default: |
31177 | 2737 ebml_read_skip(s, &l); |
2738 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2739 } |
31177 | 2740 mkv_d->blockgroup_size -= l + il; |
2741 mkv_d->cluster_size -= l + il; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2742 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2743 |
31177 | 2744 if (block) { |
2745 int res = handle_block(demuxer, block, block_length, | |
2746 block_duration, block_bref, block_fref, | |
2747 0); | |
2748 free(block); | |
2749 if (res < 0) | |
2750 return 0; | |
2751 if (res) | |
2752 return 1; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2753 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2754 |
31177 | 2755 if (mkv_d->cluster_size > 0) { |
2756 switch (ebml_read_id(s, &il)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2757 case MATROSKA_ID_CLUSTERTIMECODE: |
31177 | 2758 { |
2759 uint64_t num = ebml_read_uint(s, &l); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2760 if (num == EBML_UINT_INVALID) |
31177 | 2761 return 0; |
2762 if (!mkv_d->has_first_tc) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2763 mkv_d->first_tc = num * mkv_d->tc_scale / 1000000.0; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2764 mkv_d->has_first_tc = 1; |
31177 | 2765 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2766 mkv_d->cluster_tc = num * mkv_d->tc_scale; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2767 break; |
31177 | 2768 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2769 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2770 case MATROSKA_ID_BLOCKGROUP: |
31177 | 2771 mkv_d->blockgroup_size = ebml_read_length(s, &tmp); |
2772 l = tmp; | |
2773 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2774 |
19977 | 2775 case MATROSKA_ID_SIMPLEBLOCK: |
31177 | 2776 { |
19977 | 2777 int res; |
31177 | 2778 block_length = ebml_read_length(s, &tmp); |
32220 | 2779 if (block_length > SIZE_MAX) |
2780 return 0; | |
31177 | 2781 block = malloc(block_length); |
2782 demuxer->filepos = stream_tell(s); | |
2783 if (stream_read(s, block, block_length) != | |
2784 (int) block_length) { | |
2785 free(block); | |
2786 return 0; | |
20155 | 2787 } |
19977 | 2788 l = tmp + block_length; |
31177 | 2789 res = handle_block(demuxer, block, block_length, |
2790 block_duration, block_bref, | |
2791 block_fref, 1); | |
2792 free(block); | |
19977 | 2793 mkv_d->cluster_size -= l + il; |
2794 if (res < 0) | |
31177 | 2795 return 0; |
19977 | 2796 else if (res) |
31177 | 2797 return 1; |
2798 else | |
2799 mkv_d->cluster_size += l + il; | |
19977 | 2800 break; |
31177 | 2801 } |
11934
bef061911390
Exit when an invalid EBML ID has been read (e.g. for files that have been cut off).
mosu
parents:
11901
diff
changeset
|
2802 case EBML_ID_INVALID: |
31177 | 2803 return 0; |
11934
bef061911390
Exit when an invalid EBML ID has been read (e.g. for files that have been cut off).
mosu
parents:
11901
diff
changeset
|
2804 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2805 default: |
31177 | 2806 ebml_read_skip(s, &l); |
2807 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2808 } |
31177 | 2809 mkv_d->cluster_size -= l + il; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2810 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2811 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2812 |
31177 | 2813 if (ebml_read_id(s, &il) != MATROSKA_ID_CLUSTER) |
2814 return 0; | |
2815 add_cluster_position(mkv_d, stream_tell(s) - il); | |
2816 mkv_d->cluster_size = ebml_read_length(s, NULL); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2817 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2818 |
31177 | 2819 return 0; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2820 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2821 |
31177 | 2822 static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs, |
2823 float audio_delay, int flags) | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2824 { |
31177 | 2825 free_cached_dps(demuxer); |
2826 if (!(flags & SEEK_FACTOR)) { /* time in secs */ | |
2827 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; | |
2828 stream_t *s = demuxer->stream; | |
2829 int64_t target_timecode = 0, diff, min_diff = 0xFFFFFFFFFFFFFFFLL; | |
2830 int i; | |
2831 | |
2832 if (!(flags & SEEK_ABSOLUTE)) /* relative seek */ | |
2833 target_timecode = (int64_t) (mkv_d->last_pts * 1000.0); | |
2834 target_timecode += (int64_t) (rel_seek_secs * 1000.0); | |
2835 if (target_timecode < 0) | |
2836 target_timecode = 0; | |
2837 | |
2838 if (mkv_d->indexes == NULL) { /* no index was found */ | |
2839 uint64_t target_filepos, cluster_pos, max_pos; | |
2840 | |
2841 target_filepos = | |
2842 (uint64_t) (target_timecode * mkv_d->last_filepos / | |
2843 (mkv_d->last_pts * 1000.0)); | |
2844 | |
2845 max_pos = mkv_d->num_cluster_pos ? | |
2846 mkv_d->cluster_positions[mkv_d->num_cluster_pos - 1] : 0; | |
2847 if (target_filepos > max_pos) { | |
2848 if ((off_t) max_pos > stream_tell(s)) | |
2849 stream_seek(s, max_pos); | |
2850 else | |
2851 stream_seek(s, stream_tell(s) + mkv_d->cluster_size); | |
2852 /* parse all the clusters upto target_filepos */ | |
2853 while (!s->eof && stream_tell(s) < (off_t) target_filepos) { | |
2854 switch (ebml_read_id(s, &i)) { | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2855 case MATROSKA_ID_CLUSTER: |
31177 | 2856 add_cluster_position(mkv_d, |
2857 (uint64_t) stream_tell(s) - i); | |
2858 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2859 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2860 case MATROSKA_ID_CUES: |
31177 | 2861 demux_mkv_read_cues(demuxer); |
2862 break; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2863 } |
31177 | 2864 ebml_read_skip(s, NULL); |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2865 } |
31177 | 2866 if (s->eof) |
2867 stream_reset(s); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2868 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2869 |
31177 | 2870 if (mkv_d->indexes == NULL) { |
2871 cluster_pos = mkv_d->cluster_positions[0]; | |
2872 /* Let's find the nearest cluster */ | |
2873 for (i = 0; i < mkv_d->num_cluster_pos; i++) { | |
2874 diff = mkv_d->cluster_positions[i] - target_filepos; | |
2875 if (rel_seek_secs < 0 && diff < 0 && -diff < min_diff) { | |
2876 cluster_pos = mkv_d->cluster_positions[i]; | |
2877 min_diff = -diff; | |
2878 } else if (rel_seek_secs > 0 | |
2879 && (diff < 0 ? -1 * diff : diff) < min_diff) { | |
2880 cluster_pos = mkv_d->cluster_positions[i]; | |
2881 min_diff = diff < 0 ? -1 * diff : diff; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2882 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2883 } |
31177 | 2884 mkv_d->cluster_size = mkv_d->blockgroup_size = 0; |
2885 stream_seek(s, cluster_pos); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2886 } |
31177 | 2887 } else { |
2888 mkv_index_t *index = NULL; | |
2889 int seek_id = (demuxer->video->id < 0) ? | |
2890 demuxer->audio->id : demuxer->video->id; | |
2891 | |
2892 /* let's find the entry in the indexes with the smallest */ | |
2893 /* difference to the wanted timecode. */ | |
2894 for (i = 0; i < mkv_d->num_indexes; i++) | |
2895 if (mkv_d->indexes[i].tnum == seek_id) { | |
2896 diff = | |
2897 target_timecode + mkv_d->first_tc - | |
2898 (int64_t) mkv_d->indexes[i].timecode * | |
2899 mkv_d->tc_scale / 1000000.0; | |
2900 | |
2901 if ((flags & SEEK_ABSOLUTE | |
2902 || target_timecode <= mkv_d->last_pts * 1000)) { | |
2903 // Absolute seek or seek backward: find the last index | |
2904 // position before target time | |
2905 if (diff < 0 || diff >= min_diff) | |
2906 continue; | |
2907 } else { | |
2908 // Relative seek forward: find the first index position | |
2909 // after target time. If no such index exists, find last | |
2910 // position between current position and target time. | |
2911 if (diff <= 0) { | |
2912 if (min_diff <= 0 && diff <= min_diff) | |
2913 continue; | |
2914 } else if (diff >= | |
2915 FFMIN(target_timecode - mkv_d->last_pts, | |
2916 min_diff)) | |
22616 | 2917 continue; |
2918 } | |
31177 | 2919 min_diff = diff; |
2920 index = mkv_d->indexes + i; | |
22616 | 2921 } |
31177 | 2922 |
2923 if (index) { /* We've found an entry. */ | |
2924 mkv_d->cluster_size = mkv_d->blockgroup_size = 0; | |
2925 stream_seek(s, index->filepos); | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2926 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2927 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2928 |
31177 | 2929 if (demuxer->video->id >= 0) |
2930 mkv_d->v_skip_to_keyframe = 1; | |
2931 if (rel_seek_secs > 0.0) | |
2932 mkv_d->skip_to_timecode = target_timecode; | |
2933 mkv_d->a_skip_to_keyframe = 1; | |
2934 | |
2935 demux_mkv_fill_buffer(demuxer, NULL); | |
2936 } else if ((demuxer->movi_end <= 0) || !(flags & SEEK_ABSOLUTE)) | |
2937 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek unsupported flags\n"); | |
2938 else { | |
2939 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; | |
2940 stream_t *s = demuxer->stream; | |
2941 uint64_t target_filepos; | |
2942 mkv_index_t *index = NULL; | |
2943 int i; | |
2944 | |
2945 if (mkv_d->indexes == NULL) { /* no index was found *//* I'm lazy... */ | |
2946 mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] seek unsupported flags\n"); | |
2947 return; | |
12073 | 2948 } |
2949 | |
31177 | 2950 target_filepos = (uint64_t) (demuxer->movi_end * rel_seek_secs); |
2951 for (i = 0; i < mkv_d->num_indexes; i++) | |
2952 if (mkv_d->indexes[i].tnum == demuxer->video->id) | |
2953 if ((index == NULL) | |
2954 || ((mkv_d->indexes[i].filepos >= target_filepos) | |
2955 && ((index->filepos < target_filepos) | |
2956 || (mkv_d->indexes[i].filepos < index->filepos)))) | |
2957 index = &mkv_d->indexes[i]; | |
2958 | |
2959 if (!index) | |
2960 return; | |
2961 | |
2962 mkv_d->cluster_size = mkv_d->blockgroup_size = 0; | |
2963 stream_seek(s, index->filepos); | |
2964 | |
2965 if (demuxer->video->id >= 0) | |
2966 mkv_d->v_skip_to_keyframe = 1; | |
2967 mkv_d->skip_to_timecode = index->timecode; | |
2968 mkv_d->a_skip_to_keyframe = 1; | |
2969 | |
2970 demux_mkv_fill_buffer(demuxer, NULL); | |
12073 | 2971 } |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2972 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2973 |
31177 | 2974 static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg) |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2975 { |
31177 | 2976 mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; |
2977 | |
2978 switch (cmd) { | |
25919
382672c7480a
Allow demuxers to choose a default value for correct_pts
reimar
parents:
25883
diff
changeset
|
2979 case DEMUXER_CTRL_CORRECT_PTS: |
31177 | 2980 return DEMUXER_CTRL_OK; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2981 case DEMUXER_CTRL_GET_TIME_LENGTH: |
31177 | 2982 if (mkv_d->duration == 0) |
2983 return DEMUXER_CTRL_DONTKNOW; | |
2984 | |
2985 *((double *) arg) = (double) mkv_d->duration; | |
2986 return DEMUXER_CTRL_OK; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2987 |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2988 case DEMUXER_CTRL_GET_PERCENT_POS: |
31177 | 2989 if (mkv_d->duration == 0) { |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2990 return DEMUXER_CTRL_DONTKNOW; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2991 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2992 |
31177 | 2993 *((int *) arg) = (int) (100 * mkv_d->last_pts / mkv_d->duration); |
2994 return DEMUXER_CTRL_OK; | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
2995 |
15154
898f68adad2b
Online audio switching now supports Matroska too. Patch by Michael Behrisch
gpoirier
parents:
14843
diff
changeset
|
2996 case DEMUXER_CTRL_SWITCH_AUDIO: |
31177 | 2997 if (demuxer->audio && demuxer->audio->sh) { |
2998 sh_audio_t *sh = demuxer->a_streams[demuxer->audio->id]; | |
2999 int aid = *(int *) arg; | |
3000 if (aid < 0) | |
3001 aid = (sh->aid + 1) % mkv_d->last_aid; | |
3002 if (aid != sh->aid) { | |
3003 mkv_track_t *track = | |
3004 demux_mkv_find_track_by_num(mkv_d, aid, | |
3005 MATROSKA_TRACK_AUDIO); | |
3006 if (track) { | |
3007 demuxer->audio->id = track->tnum; | |
3008 sh = demuxer->a_streams[demuxer->audio->id]; | |
3009 ds_free_packs(demuxer->audio); | |
3010 } | |
3011 } | |
3012 *(int *) arg = sh->aid; | |
3013 } else | |
3014 *(int *) arg = -2; | |
3015 return DEMUXER_CTRL_OK; | |
15154
898f68adad2b
Online audio switching now supports Matroska too. Patch by Michael Behrisch
gpoirier
parents:
14843
diff
changeset
|
3016 |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
3017 default: |
31177 | 3018 return DEMUXER_CTRL_NOTIMPL; |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
3019 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
3020 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
diff
changeset
|
3021 |
25707
d4fe6e23283e
Make all demuxer_desc_t const, thus moving them to .rodata
reimar
parents:
25658
diff
changeset
|
3022 const demuxer_desc_t demuxer_desc_matroska = { |
31177 | 3023 "Matroska demuxer", |
3024 "mkv", | |
3025 "Matroska", | |
3026 "Aurelien Jacobs", | |
3027 "", | |
3028 DEMUXER_TYPE_MATROSKA, | |
3029 1, // safe autodetect | |
3030 demux_mkv_open, | |
3031 demux_mkv_fill_buffer, | |
3032 NULL, | |
3033 demux_close_mkv, | |
3034 demux_mkv_seek, | |
3035 demux_mkv_control | |
16175 | 3036 }; |