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