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