Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * MOV demuxer |
||
3 | * Copyright (c) 2001 Fabrice Bellard |
||
4 | * Copyright (c) 2009 Baptiste Coudurier |
||
5 | * |
||
6 | * first version by Francois Revol |
||
7 | * seek function by Gael Chardon |
||
8 | * |
||
9 | * This file is part of FFmpeg. |
||
10 | * |
||
11 | * FFmpeg is free software; you can redistribute it and/or |
||
12 | * modify it under the terms of the GNU Lesser General Public |
||
13 | * License as published by the Free Software Foundation; either |
||
14 | * version 2.1 of the License, or (at your option) any later version. |
||
15 | * |
||
16 | * FFmpeg is distributed in the hope that it will be useful, |
||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
19 | * Lesser General Public License for more details. |
||
20 | * |
||
21 | * You should have received a copy of the GNU Lesser General Public |
||
22 | * License along with FFmpeg; if not, write to the Free Software |
||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||
24 | */ |
||
25 | |||
26 | #include |
||
27 | |||
28 | //#define MOV_EXPORT_ALL_METADATA |
||
29 | |||
30 | #include "libavutil/attributes.h" |
||
31 | #include "libavutil/channel_layout.h" |
||
32 | #include "libavutil/intreadwrite.h" |
||
33 | #include "libavutil/intfloat.h" |
||
34 | #include "libavutil/mathematics.h" |
||
35 | #include "libavutil/avstring.h" |
||
36 | #include "libavutil/dict.h" |
||
37 | #include "libavutil/opt.h" |
||
38 | #include "libavutil/timecode.h" |
||
39 | #include "libavcodec/ac3tab.h" |
||
40 | #include "avformat.h" |
||
41 | #include "internal.h" |
||
42 | #include "avio_internal.h" |
||
43 | #include "riff.h" |
||
44 | #include "isom.h" |
||
45 | #include "libavcodec/get_bits.h" |
||
46 | #include "id3v1.h" |
||
47 | #include "mov_chan.h" |
||
48 | |||
49 | #if CONFIG_ZLIB |
||
50 | #include |
||
51 | #endif |
||
52 | |||
53 | #include "qtpalette.h" |
||
54 | |||
55 | |||
56 | #undef NDEBUG |
||
57 | #include |
||
58 | |||
59 | /* those functions parse an atom */ |
||
60 | /* links atom IDs to parse functions */ |
||
61 | typedef struct MOVParseTableEntry { |
||
62 | uint32_t type; |
||
63 | int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom); |
||
64 | } MOVParseTableEntry; |
||
65 | |||
66 | static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom); |
||
67 | |||
68 | static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, |
||
69 | unsigned len, const char *key) |
||
70 | { |
||
71 | char buf[16]; |
||
72 | |||
73 | short current, total = 0; |
||
74 | avio_rb16(pb); // unknown |
||
75 | current = avio_rb16(pb); |
||
76 | if (len >= 6) |
||
77 | total = avio_rb16(pb); |
||
78 | if (!total) |
||
79 | snprintf(buf, sizeof(buf), "%d", current); |
||
80 | else |
||
81 | snprintf(buf, sizeof(buf), "%d/%d", current, total); |
||
82 | av_dict_set(&c->fc->metadata, key, buf, 0); |
||
83 | |||
84 | return 0; |
||
85 | } |
||
86 | |||
87 | static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, |
||
88 | unsigned len, const char *key) |
||
89 | { |
||
90 | char buf[16]; |
||
91 | |||
92 | /* bypass padding bytes */ |
||
93 | avio_r8(pb); |
||
94 | avio_r8(pb); |
||
95 | avio_r8(pb); |
||
96 | |||
97 | snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); |
||
98 | av_dict_set(&c->fc->metadata, key, buf, 0); |
||
99 | |||
100 | return 0; |
||
101 | } |
||
102 | |||
103 | static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, |
||
104 | unsigned len, const char *key) |
||
105 | { |
||
106 | char buf[16]; |
||
107 | |||
108 | snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); |
||
109 | av_dict_set(&c->fc->metadata, key, buf, 0); |
||
110 | |||
111 | return 0; |
||
112 | } |
||
113 | |||
114 | static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, |
||
115 | unsigned len, const char *key) |
||
116 | { |
||
117 | short genre; |
||
118 | char buf[20]; |
||
119 | |||
120 | avio_r8(pb); // unknown |
||
121 | |||
122 | genre = avio_r8(pb); |
||
123 | if (genre < 1 || genre > ID3v1_GENRE_MAX) |
||
124 | return 0; |
||
125 | snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]); |
||
126 | av_dict_set(&c->fc->metadata, key, buf, 0); |
||
127 | |||
128 | return 0; |
||
129 | } |
||
130 | |||
131 | static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
132 | { |
||
133 | char key[1024]={0}, data[1024]={0}; |
||
134 | int i; |
||
135 | AVStream *st; |
||
136 | MOVStreamContext *sc; |
||
137 | |||
138 | if (c->fc->nb_streams < 1) |
||
139 | return 0; |
||
140 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
141 | sc = st->priv_data; |
||
142 | |||
143 | if (atom.size <= 8) return 0; |
||
144 | |||
145 | for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data. |
||
146 | int data_size = avio_rb32(pb); |
||
147 | int tag = avio_rl32(pb); |
||
148 | int str_size = 0, skip_size = 0; |
||
149 | char *target = NULL; |
||
150 | |||
151 | switch (tag) { |
||
152 | case MKTAG('n','a','m','e'): |
||
153 | avio_rb32(pb); // version/flags |
||
154 | str_size = skip_size = data_size - 12; |
||
155 | atom.size -= 12; |
||
156 | target = key; |
||
157 | break; |
||
158 | case MKTAG('d','a','t','a'): |
||
159 | avio_rb32(pb); // version/flags |
||
160 | avio_rb32(pb); // reserved (zero) |
||
161 | str_size = skip_size = data_size - 16; |
||
162 | atom.size -= 16; |
||
163 | target = data; |
||
164 | break; |
||
165 | default: |
||
166 | skip_size = data_size - 8; |
||
167 | str_size = 0; |
||
168 | break; |
||
169 | } |
||
170 | |||
171 | if (target) { |
||
172 | str_size = FFMIN3(sizeof(data)-1, str_size, atom.size); |
||
173 | avio_read(pb, target, str_size); |
||
174 | target[str_size] = 0; |
||
175 | } |
||
176 | atom.size -= skip_size; |
||
177 | |||
178 | // If we didn't read the full data chunk for the sub-atom, skip to the end of it. |
||
179 | if (skip_size > str_size) avio_skip(pb, skip_size - str_size); |
||
180 | } |
||
181 | |||
182 | if (*key && *data) { |
||
183 | if (strcmp(key, "iTunSMPB") == 0) { |
||
184 | int priming, remainder, samples; |
||
185 | if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){ |
||
186 | if(priming>0 && priming<16384) |
||
187 | sc->start_pad = priming; |
||
188 | return 1; |
||
189 | } |
||
190 | } |
||
191 | if (strcmp(key, "cdec") == 0) { |
||
192 | // av_dict_set(&st->metadata, key, data, 0); |
||
193 | return 1; |
||
194 | } |
||
195 | } |
||
196 | return 0; |
||
197 | } |
||
198 | |||
199 | static const uint32_t mac_to_unicode[128] = { |
||
200 | 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, |
||
201 | 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, |
||
202 | 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3, |
||
203 | 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC, |
||
204 | 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF, |
||
205 | 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8, |
||
206 | 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211, |
||
207 | 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8, |
||
208 | 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB, |
||
209 | 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153, |
||
210 | 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA, |
||
211 | 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02, |
||
212 | 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1, |
||
213 | 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4, |
||
214 | 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC, |
||
215 | 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7, |
||
216 | }; |
||
217 | |||
218 | static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, |
||
219 | char *dst, int dstlen) |
||
220 | { |
||
221 | char *p = dst; |
||
222 | char *end = dst+dstlen-1; |
||
223 | int i; |
||
224 | |||
225 | for (i = 0; i < len; i++) { |
||
226 | uint8_t t, c = avio_r8(pb); |
||
227 | if (c < 0x80 && p < end) |
||
228 | *p++ = c; |
||
229 | else if (p < end) |
||
230 | PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); |
||
231 | } |
||
232 | *p = 0; |
||
233 | return p - dst; |
||
234 | } |
||
235 | |||
236 | static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) |
||
237 | { |
||
238 | AVPacket pkt; |
||
239 | AVStream *st; |
||
240 | MOVStreamContext *sc; |
||
241 | enum AVCodecID id; |
||
242 | int ret; |
||
243 | |||
244 | switch (type) { |
||
245 | case 0xd: id = AV_CODEC_ID_MJPEG; break; |
||
246 | case 0xe: id = AV_CODEC_ID_PNG; break; |
||
247 | case 0x1b: id = AV_CODEC_ID_BMP; break; |
||
248 | default: |
||
249 | av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type); |
||
250 | avio_skip(pb, len); |
||
251 | return 0; |
||
252 | } |
||
253 | |||
254 | st = avformat_new_stream(c->fc, NULL); |
||
255 | if (!st) |
||
256 | return AVERROR(ENOMEM); |
||
257 | sc = av_mallocz(sizeof(*sc)); |
||
258 | if (!sc) |
||
259 | return AVERROR(ENOMEM); |
||
260 | st->priv_data = sc; |
||
261 | |||
262 | ret = av_get_packet(pb, &pkt, len); |
||
263 | if (ret < 0) |
||
264 | return ret; |
||
265 | |||
266 | st->disposition |= AV_DISPOSITION_ATTACHED_PIC; |
||
267 | |||
268 | st->attached_pic = pkt; |
||
269 | st->attached_pic.stream_index = st->index; |
||
270 | st->attached_pic.flags |= AV_PKT_FLAG_KEY; |
||
271 | |||
272 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
||
273 | st->codec->codec_id = id; |
||
274 | |||
275 | return 0; |
||
276 | } |
||
277 | |||
278 | static int mov_metadata_raw(MOVContext *c, AVIOContext *pb, |
||
279 | unsigned len, const char *key) |
||
280 | { |
||
281 | char *value = av_malloc(len + 1); |
||
282 | if (!value) |
||
283 | return AVERROR(ENOMEM); |
||
284 | avio_read(pb, value, len); |
||
285 | value[len] = 0; |
||
286 | return av_dict_set(&c->fc->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); |
||
287 | } |
||
288 | |||
289 | static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
290 | { |
||
291 | #ifdef MOV_EXPORT_ALL_METADATA |
||
292 | char tmp_key[5]; |
||
293 | #endif |
||
294 | char str[1024], key2[16], language[4] = {0}; |
||
295 | const char *key = NULL; |
||
296 | uint16_t langcode = 0; |
||
297 | uint32_t data_type = 0, str_size; |
||
298 | int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL; |
||
299 | |||
300 | if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-')) |
||
301 | return mov_read_custom_metadata(c, pb, atom); |
||
302 | |||
303 | switch (atom.type) { |
||
304 | case MKTAG(0xa9,'n','a','m'): key = "title"; break; |
||
305 | case MKTAG(0xa9,'a','u','t'): |
||
306 | case MKTAG(0xa9,'A','R','T'): key = "artist"; break; |
||
307 | case MKTAG( 'a','A','R','T'): key = "album_artist"; break; |
||
308 | case MKTAG(0xa9,'w','r','t'): key = "composer"; break; |
||
309 | case MKTAG( 'c','p','r','t'): |
||
310 | case MKTAG(0xa9,'c','p','y'): key = "copyright"; break; |
||
311 | case MKTAG(0xa9,'g','r','p'): key = "grouping"; break; |
||
312 | case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break; |
||
313 | case MKTAG(0xa9,'c','m','t'): |
||
314 | case MKTAG(0xa9,'i','n','f'): key = "comment"; break; |
||
315 | case MKTAG(0xa9,'a','l','b'): key = "album"; break; |
||
316 | case MKTAG(0xa9,'d','a','y'): key = "date"; break; |
||
317 | case MKTAG(0xa9,'g','e','n'): key = "genre"; break; |
||
318 | case MKTAG( 'g','n','r','e'): key = "genre"; |
||
319 | parse = mov_metadata_gnre; break; |
||
320 | case MKTAG(0xa9,'t','o','o'): |
||
321 | case MKTAG(0xa9,'s','w','r'): key = "encoder"; break; |
||
322 | case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; |
||
323 | case MKTAG(0xa9,'m','a','k'): key = "make"; break; |
||
324 | case MKTAG(0xa9,'m','o','d'): key = "model"; break; |
||
325 | case MKTAG(0xa9,'x','y','z'): key = "location"; break; |
||
326 | case MKTAG( 'd','e','s','c'): key = "description";break; |
||
327 | case MKTAG( 'l','d','e','s'): key = "synopsis"; break; |
||
328 | case MKTAG( 't','v','s','h'): key = "show"; break; |
||
329 | case MKTAG( 't','v','e','n'): key = "episode_id";break; |
||
330 | case MKTAG( 't','v','n','n'): key = "network"; break; |
||
331 | case MKTAG( 't','r','k','n'): key = "track"; |
||
332 | parse = mov_metadata_track_or_disc_number; break; |
||
333 | case MKTAG( 'd','i','s','k'): key = "disc"; |
||
334 | parse = mov_metadata_track_or_disc_number; break; |
||
335 | case MKTAG( 't','v','e','s'): key = "episode_sort"; |
||
336 | parse = mov_metadata_int8_bypass_padding; break; |
||
337 | case MKTAG( 't','v','s','n'): key = "season_number"; |
||
338 | parse = mov_metadata_int8_bypass_padding; break; |
||
339 | case MKTAG( 's','t','i','k'): key = "media_type"; |
||
340 | parse = mov_metadata_int8_no_padding; break; |
||
341 | case MKTAG( 'h','d','v','d'): key = "hd_video"; |
||
342 | parse = mov_metadata_int8_no_padding; break; |
||
343 | case MKTAG( 'p','g','a','p'): key = "gapless_playback"; |
||
344 | parse = mov_metadata_int8_no_padding; break; |
||
345 | case MKTAG( '@','P','R','M'): |
||
346 | return mov_metadata_raw(c, pb, atom.size, "premiere_version"); |
||
347 | case MKTAG( '@','P','R','Q'): |
||
348 | return mov_metadata_raw(c, pb, atom.size, "quicktime_version"); |
||
349 | } |
||
350 | |||
351 | if (c->itunes_metadata && atom.size > 8) { |
||
352 | int data_size = avio_rb32(pb); |
||
353 | int tag = avio_rl32(pb); |
||
354 | if (tag == MKTAG('d','a','t','a')) { |
||
355 | data_type = avio_rb32(pb); // type |
||
356 | avio_rb32(pb); // unknown |
||
357 | str_size = data_size - 16; |
||
358 | atom.size -= 16; |
||
359 | |||
360 | if (atom.type == MKTAG('c', 'o', 'v', 'r')) { |
||
361 | int ret = mov_read_covr(c, pb, data_type, str_size); |
||
362 | if (ret < 0) { |
||
363 | av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n"); |
||
364 | return ret; |
||
365 | } |
||
366 | } |
||
367 | } else return 0; |
||
368 | } else if (atom.size > 4 && key && !c->itunes_metadata) { |
||
369 | str_size = avio_rb16(pb); // string length |
||
370 | langcode = avio_rb16(pb); |
||
371 | ff_mov_lang_to_iso639(langcode, language); |
||
372 | atom.size -= 4; |
||
373 | } else |
||
374 | str_size = atom.size; |
||
375 | |||
376 | #ifdef MOV_EXPORT_ALL_METADATA |
||
377 | if (!key) { |
||
378 | snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); |
||
379 | key = tmp_key; |
||
380 | } |
||
381 | #endif |
||
382 | |||
383 | if (!key) |
||
384 | return 0; |
||
385 | if (atom.size < 0) |
||
386 | return AVERROR_INVALIDDATA; |
||
387 | |||
388 | str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); |
||
389 | |||
390 | if (parse) |
||
391 | parse(c, pb, str_size, key); |
||
392 | else { |
||
393 | if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded |
||
394 | mov_read_mac_string(c, pb, str_size, str, sizeof(str)); |
||
395 | } else { |
||
396 | avio_read(pb, str, str_size); |
||
397 | str[str_size] = 0; |
||
398 | } |
||
399 | av_dict_set(&c->fc->metadata, key, str, 0); |
||
400 | if (*language && strcmp(language, "und")) { |
||
401 | snprintf(key2, sizeof(key2), "%s-%s", key, language); |
||
402 | av_dict_set(&c->fc->metadata, key2, str, 0); |
||
403 | } |
||
404 | } |
||
405 | av_dlog(c->fc, "lang \"%3s\" ", language); |
||
406 | av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n", |
||
407 | key, str, (char*)&atom.type, str_size, atom.size); |
||
408 | |||
409 | return 0; |
||
410 | } |
||
411 | |||
412 | static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
413 | { |
||
414 | int64_t start; |
||
415 | int i, nb_chapters, str_len, version; |
||
416 | char str[256+1]; |
||
417 | |||
418 | if ((atom.size -= 5) < 0) |
||
419 | return 0; |
||
420 | |||
421 | version = avio_r8(pb); |
||
422 | avio_rb24(pb); |
||
423 | if (version) |
||
424 | avio_rb32(pb); // ??? |
||
425 | nb_chapters = avio_r8(pb); |
||
426 | |||
427 | for (i = 0; i < nb_chapters; i++) { |
||
428 | if (atom.size < 9) |
||
429 | return 0; |
||
430 | |||
431 | start = avio_rb64(pb); |
||
432 | str_len = avio_r8(pb); |
||
433 | |||
434 | if ((atom.size -= 9+str_len) < 0) |
||
435 | return 0; |
||
436 | |||
437 | avio_read(pb, str, str_len); |
||
438 | str[str_len] = 0; |
||
439 | avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str); |
||
440 | } |
||
441 | return 0; |
||
442 | } |
||
443 | |||
444 | #define MIN_DATA_ENTRY_BOX_SIZE 12 |
||
445 | static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
446 | { |
||
447 | AVStream *st; |
||
448 | MOVStreamContext *sc; |
||
449 | int entries, i, j; |
||
450 | |||
451 | if (c->fc->nb_streams < 1) |
||
452 | return 0; |
||
453 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
454 | sc = st->priv_data; |
||
455 | |||
456 | avio_rb32(pb); // version + flags |
||
457 | entries = avio_rb32(pb); |
||
458 | if (entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 || |
||
459 | entries >= UINT_MAX / sizeof(*sc->drefs)) |
||
460 | return AVERROR_INVALIDDATA; |
||
461 | av_free(sc->drefs); |
||
462 | sc->drefs_count = 0; |
||
463 | sc->drefs = av_mallocz(entries * sizeof(*sc->drefs)); |
||
464 | if (!sc->drefs) |
||
465 | return AVERROR(ENOMEM); |
||
466 | sc->drefs_count = entries; |
||
467 | |||
468 | for (i = 0; i < sc->drefs_count; i++) { |
||
469 | MOVDref *dref = &sc->drefs[i]; |
||
470 | uint32_t size = avio_rb32(pb); |
||
471 | int64_t next = avio_tell(pb) + size - 4; |
||
472 | |||
473 | if (size < 12) |
||
474 | return AVERROR_INVALIDDATA; |
||
475 | |||
476 | dref->type = avio_rl32(pb); |
||
477 | avio_rb32(pb); // version + flags |
||
478 | av_dlog(c->fc, "type %.4s size %d\n", (char*)&dref->type, size); |
||
479 | |||
480 | if (dref->type == MKTAG('a','l','i','s') && size > 150) { |
||
481 | /* macintosh alias record */ |
||
482 | uint16_t volume_len, len; |
||
483 | int16_t type; |
||
484 | |||
485 | avio_skip(pb, 10); |
||
486 | |||
487 | volume_len = avio_r8(pb); |
||
488 | volume_len = FFMIN(volume_len, 27); |
||
489 | avio_read(pb, dref->volume, 27); |
||
490 | dref->volume[volume_len] = 0; |
||
491 | av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len); |
||
492 | |||
493 | avio_skip(pb, 12); |
||
494 | |||
495 | len = avio_r8(pb); |
||
496 | len = FFMIN(len, 63); |
||
497 | avio_read(pb, dref->filename, 63); |
||
498 | dref->filename[len] = 0; |
||
499 | av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len); |
||
500 | |||
501 | avio_skip(pb, 16); |
||
502 | |||
503 | /* read next level up_from_alias/down_to_target */ |
||
504 | dref->nlvl_from = avio_rb16(pb); |
||
505 | dref->nlvl_to = avio_rb16(pb); |
||
506 | av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n", |
||
507 | dref->nlvl_from, dref->nlvl_to); |
||
508 | |||
509 | avio_skip(pb, 16); |
||
510 | |||
511 | for (type = 0; type != -1 && avio_tell(pb) < next; ) { |
||
512 | if(url_feof(pb)) |
||
513 | return AVERROR_EOF; |
||
514 | type = avio_rb16(pb); |
||
515 | len = avio_rb16(pb); |
||
516 | av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len); |
||
517 | if (len&1) |
||
518 | len += 1; |
||
519 | if (type == 2) { // absolute path |
||
520 | av_free(dref->path); |
||
521 | dref->path = av_mallocz(len+1); |
||
522 | if (!dref->path) |
||
523 | return AVERROR(ENOMEM); |
||
524 | avio_read(pb, dref->path, len); |
||
525 | if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) { |
||
526 | len -= volume_len; |
||
527 | memmove(dref->path, dref->path+volume_len, len); |
||
528 | dref->path[len] = 0; |
||
529 | } |
||
530 | for (j = 0; j < len; j++) |
||
531 | if (dref->path[j] == ':') |
||
532 | dref->path[j] = '/'; |
||
533 | av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path); |
||
534 | } else if (type == 0) { // directory name |
||
535 | av_free(dref->dir); |
||
536 | dref->dir = av_malloc(len+1); |
||
537 | if (!dref->dir) |
||
538 | return AVERROR(ENOMEM); |
||
539 | avio_read(pb, dref->dir, len); |
||
540 | dref->dir[len] = 0; |
||
541 | for (j = 0; j < len; j++) |
||
542 | if (dref->dir[j] == ':') |
||
543 | dref->dir[j] = '/'; |
||
544 | av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir); |
||
545 | } else |
||
546 | avio_skip(pb, len); |
||
547 | } |
||
548 | } |
||
549 | avio_seek(pb, next, SEEK_SET); |
||
550 | } |
||
551 | return 0; |
||
552 | } |
||
553 | |||
554 | static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
555 | { |
||
556 | AVStream *st; |
||
557 | uint32_t type; |
||
558 | uint32_t av_unused ctype; |
||
559 | int title_size; |
||
560 | char *title_str; |
||
561 | |||
562 | if (c->fc->nb_streams < 1) // meta before first trak |
||
563 | return 0; |
||
564 | |||
565 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
566 | |||
567 | avio_r8(pb); /* version */ |
||
568 | avio_rb24(pb); /* flags */ |
||
569 | |||
570 | /* component type */ |
||
571 | ctype = avio_rl32(pb); |
||
572 | type = avio_rl32(pb); /* component subtype */ |
||
573 | |||
574 | av_dlog(c->fc, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype); |
||
575 | av_dlog(c->fc, "stype= %.4s\n", (char*)&type); |
||
576 | |||
577 | if (type == MKTAG('v','i','d','e')) |
||
578 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
||
579 | else if (type == MKTAG('s','o','u','n')) |
||
580 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
||
581 | else if (type == MKTAG('m','1','a',' ')) |
||
582 | st->codec->codec_id = AV_CODEC_ID_MP2; |
||
583 | else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p'))) |
||
584 | st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; |
||
585 | |||
586 | avio_rb32(pb); /* component manufacture */ |
||
587 | avio_rb32(pb); /* component flags */ |
||
588 | avio_rb32(pb); /* component flags mask */ |
||
589 | |||
590 | title_size = atom.size - 24; |
||
591 | if (title_size > 0) { |
||
592 | title_str = av_malloc(title_size + 1); /* Add null terminator */ |
||
593 | if (!title_str) |
||
594 | return AVERROR(ENOMEM); |
||
595 | avio_read(pb, title_str, title_size); |
||
596 | title_str[title_size] = 0; |
||
597 | if (title_str[0]) |
||
598 | av_dict_set(&st->metadata, "handler_name", title_str + |
||
599 | (!c->isom && title_str[0] == title_size - 1), 0); |
||
600 | av_freep(&title_str); |
||
601 | } |
||
602 | |||
603 | return 0; |
||
604 | } |
||
605 | |||
606 | int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom) |
||
607 | { |
||
608 | AVStream *st; |
||
609 | int tag; |
||
610 | |||
611 | if (fc->nb_streams < 1) |
||
612 | return 0; |
||
613 | st = fc->streams[fc->nb_streams-1]; |
||
614 | |||
615 | avio_rb32(pb); /* version + flags */ |
||
616 | ff_mp4_read_descr(fc, pb, &tag); |
||
617 | if (tag == MP4ESDescrTag) { |
||
618 | ff_mp4_parse_es_descr(pb, NULL); |
||
619 | } else |
||
620 | avio_rb16(pb); /* ID */ |
||
621 | |||
622 | ff_mp4_read_descr(fc, pb, &tag); |
||
623 | if (tag == MP4DecConfigDescrTag) |
||
624 | ff_mp4_read_dec_config_descr(fc, st, pb); |
||
625 | return 0; |
||
626 | } |
||
627 | |||
628 | static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
629 | { |
||
630 | return ff_mov_read_esds(c->fc, pb, atom); |
||
631 | } |
||
632 | |||
633 | static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
634 | { |
||
635 | AVStream *st; |
||
636 | int ac3info, acmod, lfeon, bsmod; |
||
637 | |||
638 | if (c->fc->nb_streams < 1) |
||
639 | return 0; |
||
640 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
641 | |||
642 | ac3info = avio_rb24(pb); |
||
643 | bsmod = (ac3info >> 14) & 0x7; |
||
644 | acmod = (ac3info >> 11) & 0x7; |
||
645 | lfeon = (ac3info >> 10) & 0x1; |
||
646 | st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; |
||
647 | st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; |
||
648 | if (lfeon) |
||
649 | st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; |
||
650 | st->codec->audio_service_type = bsmod; |
||
651 | if (st->codec->channels > 1 && bsmod == 0x7) |
||
652 | st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; |
||
653 | |||
654 | return 0; |
||
655 | } |
||
656 | |||
657 | static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
658 | { |
||
659 | AVStream *st; |
||
660 | int eac3info, acmod, lfeon, bsmod; |
||
661 | |||
662 | if (c->fc->nb_streams < 1) |
||
663 | return 0; |
||
664 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
665 | |||
666 | /* No need to parse fields for additional independent substreams and its |
||
667 | * associated dependent substreams since libavcodec's E-AC-3 decoder |
||
668 | * does not support them yet. */ |
||
669 | avio_rb16(pb); /* data_rate and num_ind_sub */ |
||
670 | eac3info = avio_rb24(pb); |
||
671 | bsmod = (eac3info >> 12) & 0x1f; |
||
672 | acmod = (eac3info >> 9) & 0x7; |
||
673 | lfeon = (eac3info >> 8) & 0x1; |
||
674 | st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; |
||
675 | if (lfeon) |
||
676 | st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; |
||
677 | st->codec->channels = av_get_channel_layout_nb_channels(st->codec->channel_layout); |
||
678 | st->codec->audio_service_type = bsmod; |
||
679 | if (st->codec->channels > 1 && bsmod == 0x7) |
||
680 | st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; |
||
681 | |||
682 | return 0; |
||
683 | } |
||
684 | |||
685 | static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
686 | { |
||
687 | AVStream *st; |
||
688 | |||
689 | if (c->fc->nb_streams < 1) |
||
690 | return 0; |
||
691 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
692 | |||
693 | if (atom.size < 16) |
||
694 | return 0; |
||
695 | |||
696 | /* skip version and flags */ |
||
697 | avio_skip(pb, 4); |
||
698 | |||
699 | ff_mov_read_chan(c->fc, pb, st, atom.size - 4); |
||
700 | |||
701 | return 0; |
||
702 | } |
||
703 | |||
704 | static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
705 | { |
||
706 | AVStream *st; |
||
707 | |||
708 | if (c->fc->nb_streams < 1) |
||
709 | return 0; |
||
710 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
711 | |||
712 | if (ff_get_wav_header(pb, st->codec, atom.size) < 0) { |
||
713 | av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n"); |
||
714 | } |
||
715 | |||
716 | return 0; |
||
717 | } |
||
718 | |||
719 | static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
720 | { |
||
721 | const int num = avio_rb32(pb); |
||
722 | const int den = avio_rb32(pb); |
||
723 | AVStream *st; |
||
724 | |||
725 | if (c->fc->nb_streams < 1) |
||
726 | return 0; |
||
727 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
728 | |||
729 | if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default |
||
730 | (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) { |
||
731 | av_log(c->fc, AV_LOG_WARNING, |
||
732 | "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n", |
||
733 | st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, |
||
734 | num, den); |
||
735 | } else if (den != 0) { |
||
736 | st->sample_aspect_ratio.num = num; |
||
737 | st->sample_aspect_ratio.den = den; |
||
738 | } |
||
739 | return 0; |
||
740 | } |
||
741 | |||
742 | /* this atom contains actual media data */ |
||
743 | static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
744 | { |
||
745 | if (atom.size == 0) /* wrong one (MP4) */ |
||
746 | return 0; |
||
747 | c->found_mdat=1; |
||
748 | return 0; /* now go for moov */ |
||
749 | } |
||
750 | |||
751 | /* read major brand, minor version and compatible brands and store them as metadata */ |
||
752 | static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
753 | { |
||
754 | uint32_t minor_ver; |
||
755 | int comp_brand_size; |
||
756 | char minor_ver_str[11]; /* 32 bit integer -> 10 digits + null */ |
||
757 | char* comp_brands_str; |
||
758 | uint8_t type[5] = {0}; |
||
759 | |||
760 | avio_read(pb, type, 4); |
||
761 | if (strcmp(type, "qt ")) |
||
762 | c->isom = 1; |
||
763 | av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type); |
||
764 | av_dict_set(&c->fc->metadata, "major_brand", type, 0); |
||
765 | minor_ver = avio_rb32(pb); /* minor version */ |
||
766 | snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver); |
||
767 | av_dict_set(&c->fc->metadata, "minor_version", minor_ver_str, 0); |
||
768 | |||
769 | comp_brand_size = atom.size - 8; |
||
770 | if (comp_brand_size < 0) |
||
771 | return AVERROR_INVALIDDATA; |
||
772 | comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */ |
||
773 | if (!comp_brands_str) |
||
774 | return AVERROR(ENOMEM); |
||
775 | avio_read(pb, comp_brands_str, comp_brand_size); |
||
776 | comp_brands_str[comp_brand_size] = 0; |
||
777 | av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0); |
||
778 | av_freep(&comp_brands_str); |
||
779 | |||
780 | return 0; |
||
781 | } |
||
782 | |||
783 | /* this atom should contain all header atoms */ |
||
784 | static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
785 | { |
||
786 | int ret; |
||
787 | |||
788 | if (c->found_moov) { |
||
789 | av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n"); |
||
790 | avio_skip(pb, atom.size); |
||
791 | return 0; |
||
792 | } |
||
793 | |||
794 | if ((ret = mov_read_default(c, pb, atom)) < 0) |
||
795 | return ret; |
||
796 | /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */ |
||
797 | /* so we don't parse the whole file if over a network */ |
||
798 | c->found_moov=1; |
||
799 | return 0; /* now go for mdat */ |
||
800 | } |
||
801 | |||
802 | static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
803 | { |
||
804 | c->fragment.moof_offset = avio_tell(pb) - 8; |
||
805 | av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset); |
||
806 | return mov_read_default(c, pb, atom); |
||
807 | } |
||
808 | |||
809 | static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time) |
||
810 | { |
||
811 | char buffer[32]; |
||
812 | if (time) { |
||
813 | struct tm *ptm; |
||
814 | time_t timet; |
||
815 | if(time >= 2082844800) |
||
816 | time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ |
||
817 | timet = time; |
||
818 | ptm = gmtime(&timet); |
||
819 | if (!ptm) return; |
||
820 | strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm); |
||
821 | av_dict_set(metadata, "creation_time", buffer, 0); |
||
822 | } |
||
823 | } |
||
824 | |||
825 | static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
826 | { |
||
827 | AVStream *st; |
||
828 | MOVStreamContext *sc; |
||
829 | int version; |
||
830 | char language[4] = {0}; |
||
831 | unsigned lang; |
||
832 | int64_t creation_time; |
||
833 | |||
834 | if (c->fc->nb_streams < 1) |
||
835 | return 0; |
||
836 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
837 | sc = st->priv_data; |
||
838 | |||
839 | if (sc->time_scale) { |
||
840 | av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n"); |
||
841 | return AVERROR_INVALIDDATA; |
||
842 | } |
||
843 | |||
844 | version = avio_r8(pb); |
||
845 | if (version > 1) { |
||
846 | avpriv_request_sample(c->fc, "Version %d", version); |
||
847 | return AVERROR_PATCHWELCOME; |
||
848 | } |
||
849 | avio_rb24(pb); /* flags */ |
||
850 | if (version == 1) { |
||
851 | creation_time = avio_rb64(pb); |
||
852 | avio_rb64(pb); |
||
853 | } else { |
||
854 | creation_time = avio_rb32(pb); |
||
855 | avio_rb32(pb); /* modification time */ |
||
856 | } |
||
857 | mov_metadata_creation_time(&st->metadata, creation_time); |
||
858 | |||
859 | sc->time_scale = avio_rb32(pb); |
||
860 | st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ |
||
861 | |||
862 | lang = avio_rb16(pb); /* language */ |
||
863 | if (ff_mov_lang_to_iso639(lang, language)) |
||
864 | av_dict_set(&st->metadata, "language", language, 0); |
||
865 | avio_rb16(pb); /* quality */ |
||
866 | |||
867 | return 0; |
||
868 | } |
||
869 | |||
870 | static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
871 | { |
||
872 | int64_t creation_time; |
||
873 | int version = avio_r8(pb); /* version */ |
||
874 | avio_rb24(pb); /* flags */ |
||
875 | |||
876 | if (version == 1) { |
||
877 | creation_time = avio_rb64(pb); |
||
878 | avio_rb64(pb); |
||
879 | } else { |
||
880 | creation_time = avio_rb32(pb); |
||
881 | avio_rb32(pb); /* modification time */ |
||
882 | } |
||
883 | mov_metadata_creation_time(&c->fc->metadata, creation_time); |
||
884 | c->time_scale = avio_rb32(pb); /* time scale */ |
||
885 | |||
886 | av_dlog(c->fc, "time scale = %i\n", c->time_scale); |
||
887 | |||
888 | c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ |
||
889 | // set the AVCodecContext duration because the duration of individual tracks |
||
890 | // may be inaccurate |
||
891 | if (c->time_scale > 0 && !c->trex_data) |
||
892 | c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale); |
||
893 | avio_rb32(pb); /* preferred scale */ |
||
894 | |||
895 | avio_rb16(pb); /* preferred volume */ |
||
896 | |||
897 | avio_skip(pb, 10); /* reserved */ |
||
898 | |||
899 | avio_skip(pb, 36); /* display matrix */ |
||
900 | |||
901 | avio_rb32(pb); /* preview time */ |
||
902 | avio_rb32(pb); /* preview duration */ |
||
903 | avio_rb32(pb); /* poster time */ |
||
904 | avio_rb32(pb); /* selection time */ |
||
905 | avio_rb32(pb); /* selection duration */ |
||
906 | avio_rb32(pb); /* current time */ |
||
907 | avio_rb32(pb); /* next track ID */ |
||
908 | return 0; |
||
909 | } |
||
910 | |||
911 | static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
912 | { |
||
913 | AVStream *st; |
||
914 | int little_endian; |
||
915 | |||
916 | if (c->fc->nb_streams < 1) |
||
917 | return 0; |
||
918 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
919 | |||
920 | little_endian = avio_rb16(pb) & 0xFF; |
||
921 | av_dlog(c->fc, "enda %d\n", little_endian); |
||
922 | if (little_endian == 1) { |
||
923 | switch (st->codec->codec_id) { |
||
924 | case AV_CODEC_ID_PCM_S24BE: |
||
925 | st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; |
||
926 | break; |
||
927 | case AV_CODEC_ID_PCM_S32BE: |
||
928 | st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; |
||
929 | break; |
||
930 | case AV_CODEC_ID_PCM_F32BE: |
||
931 | st->codec->codec_id = AV_CODEC_ID_PCM_F32LE; |
||
932 | break; |
||
933 | case AV_CODEC_ID_PCM_F64BE: |
||
934 | st->codec->codec_id = AV_CODEC_ID_PCM_F64LE; |
||
935 | break; |
||
936 | default: |
||
937 | break; |
||
938 | } |
||
939 | } |
||
940 | return 0; |
||
941 | } |
||
942 | |||
943 | static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
944 | { |
||
945 | AVStream *st; |
||
946 | unsigned mov_field_order; |
||
947 | enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN; |
||
948 | |||
949 | if (c->fc->nb_streams < 1) // will happen with jp2 files |
||
950 | return 0; |
||
951 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
952 | if (atom.size < 2) |
||
953 | return AVERROR_INVALIDDATA; |
||
954 | mov_field_order = avio_rb16(pb); |
||
955 | if ((mov_field_order & 0xFF00) == 0x0100) |
||
956 | decoded_field_order = AV_FIELD_PROGRESSIVE; |
||
957 | else if ((mov_field_order & 0xFF00) == 0x0200) { |
||
958 | switch (mov_field_order & 0xFF) { |
||
959 | case 0x01: decoded_field_order = AV_FIELD_TT; |
||
960 | break; |
||
961 | case 0x06: decoded_field_order = AV_FIELD_BB; |
||
962 | break; |
||
963 | case 0x09: decoded_field_order = AV_FIELD_TB; |
||
964 | break; |
||
965 | case 0x0E: decoded_field_order = AV_FIELD_BT; |
||
966 | break; |
||
967 | } |
||
968 | } |
||
969 | if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) { |
||
970 | av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order); |
||
971 | } |
||
972 | st->codec->field_order = decoded_field_order; |
||
973 | |||
974 | return 0; |
||
975 | } |
||
976 | |||
977 | /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */ |
||
978 | static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, |
||
979 | enum AVCodecID codec_id) |
||
980 | { |
||
981 | AVStream *st; |
||
982 | uint64_t size; |
||
983 | uint8_t *buf; |
||
984 | int err; |
||
985 | |||
986 | if (c->fc->nb_streams < 1) // will happen with jp2 files |
||
987 | return 0; |
||
988 | st= c->fc->streams[c->fc->nb_streams-1]; |
||
989 | |||
990 | if (st->codec->codec_id != codec_id) |
||
991 | return 0; /* unexpected codec_id - don't mess with extradata */ |
||
992 | |||
993 | size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE; |
||
994 | if (size > INT_MAX || (uint64_t)atom.size > INT_MAX) |
||
995 | return AVERROR_INVALIDDATA; |
||
996 | if ((err = av_reallocp(&st->codec->extradata, size)) < 0) { |
||
997 | st->codec->extradata_size = 0; |
||
998 | return err; |
||
999 | } |
||
1000 | buf = st->codec->extradata + st->codec->extradata_size; |
||
1001 | st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE; |
||
1002 | AV_WB32( buf , atom.size + 8); |
||
1003 | AV_WL32( buf + 4, atom.type); |
||
1004 | avio_read(pb, buf + 8, atom.size); |
||
1005 | return 0; |
||
1006 | } |
||
1007 | |||
1008 | /* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */ |
||
1009 | static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1010 | { |
||
1011 | return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC); |
||
1012 | } |
||
1013 | |||
1014 | static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1015 | { |
||
1016 | return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS); |
||
1017 | } |
||
1018 | |||
1019 | static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1020 | { |
||
1021 | return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000); |
||
1022 | } |
||
1023 | |||
1024 | static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1025 | { |
||
1026 | return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI); |
||
1027 | } |
||
1028 | |||
1029 | static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1030 | { |
||
1031 | int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216); |
||
1032 | |||
1033 | if (!ret && c->fc->nb_streams >= 1) { |
||
1034 | AVCodecContext *avctx = c->fc->streams[c->fc->nb_streams-1]->codec; |
||
1035 | if (avctx->extradata_size >= 40) { |
||
1036 | avctx->height = AV_RB16(&avctx->extradata[36]); |
||
1037 | avctx->width = AV_RB16(&avctx->extradata[38]); |
||
1038 | } |
||
1039 | } |
||
1040 | return ret; |
||
1041 | } |
||
1042 | |||
1043 | static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1044 | { |
||
1045 | AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec; |
||
1046 | if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') && |
||
1047 | codec->codec_id == AV_CODEC_ID_H264 && |
||
1048 | atom.size > 11) { |
||
1049 | avio_skip(pb, 10); |
||
1050 | /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */ |
||
1051 | if (avio_rb16(pb) == 0xd4d) |
||
1052 | codec->width = 1440; |
||
1053 | return 0; |
||
1054 | } |
||
1055 | |||
1056 | return mov_read_avid(c, pb, atom); |
||
1057 | } |
||
1058 | |||
1059 | static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1060 | { |
||
1061 | return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3); |
||
1062 | } |
||
1063 | |||
1064 | static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1065 | { |
||
1066 | AVStream *st; |
||
1067 | |||
1068 | if (c->fc->nb_streams < 1) |
||
1069 | return 0; |
||
1070 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1071 | |||
1072 | if ((uint64_t)atom.size > (1<<30)) |
||
1073 | return AVERROR_INVALIDDATA; |
||
1074 | |||
1075 | if (st->codec->codec_id == AV_CODEC_ID_QDM2 || |
||
1076 | st->codec->codec_id == AV_CODEC_ID_QDMC || |
||
1077 | st->codec->codec_id == AV_CODEC_ID_SPEEX) { |
||
1078 | // pass all frma atom to codec, needed at least for QDMC and QDM2 |
||
1079 | av_free(st->codec->extradata); |
||
1080 | if (ff_alloc_extradata(st->codec, atom.size)) |
||
1081 | return AVERROR(ENOMEM); |
||
1082 | avio_read(pb, st->codec->extradata, atom.size); |
||
1083 | } else if (atom.size > 8) { /* to read frma, esds atoms */ |
||
1084 | int ret; |
||
1085 | if ((ret = mov_read_default(c, pb, atom)) < 0) |
||
1086 | return ret; |
||
1087 | } else |
||
1088 | avio_skip(pb, atom.size); |
||
1089 | return 0; |
||
1090 | } |
||
1091 | |||
1092 | /** |
||
1093 | * This function reads atom content and puts data in extradata without tag |
||
1094 | * nor size unlike mov_read_extradata. |
||
1095 | */ |
||
1096 | static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1097 | { |
||
1098 | AVStream *st; |
||
1099 | |||
1100 | if (c->fc->nb_streams < 1) |
||
1101 | return 0; |
||
1102 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1103 | |||
1104 | if ((uint64_t)atom.size > (1<<30)) |
||
1105 | return AVERROR_INVALIDDATA; |
||
1106 | |||
1107 | if (atom.size >= 10) { |
||
1108 | // Broken files created by legacy versions of libavformat will |
||
1109 | // wrap a whole fiel atom inside of a glbl atom. |
||
1110 | unsigned size = avio_rb32(pb); |
||
1111 | unsigned type = avio_rl32(pb); |
||
1112 | avio_seek(pb, -8, SEEK_CUR); |
||
1113 | if (type == MKTAG('f','i','e','l') && size == atom.size) |
||
1114 | return mov_read_default(c, pb, atom); |
||
1115 | } |
||
1116 | av_free(st->codec->extradata); |
||
1117 | if (ff_alloc_extradata(st->codec, atom.size)) |
||
1118 | return AVERROR(ENOMEM); |
||
1119 | avio_read(pb, st->codec->extradata, atom.size); |
||
1120 | return 0; |
||
1121 | } |
||
1122 | |||
1123 | static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1124 | { |
||
1125 | AVStream *st; |
||
1126 | uint8_t profile_level; |
||
1127 | |||
1128 | if (c->fc->nb_streams < 1) |
||
1129 | return 0; |
||
1130 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1131 | |||
1132 | if (atom.size >= (1<<28) || atom.size < 7) |
||
1133 | return AVERROR_INVALIDDATA; |
||
1134 | |||
1135 | profile_level = avio_r8(pb); |
||
1136 | if ((profile_level & 0xf0) != 0xc0) |
||
1137 | return 0; |
||
1138 | |||
1139 | av_free(st->codec->extradata); |
||
1140 | if (ff_alloc_extradata(st->codec, atom.size - 7)) |
||
1141 | return AVERROR(ENOMEM); |
||
1142 | avio_seek(pb, 6, SEEK_CUR); |
||
1143 | avio_read(pb, st->codec->extradata, st->codec->extradata_size); |
||
1144 | return 0; |
||
1145 | } |
||
1146 | |||
1147 | /** |
||
1148 | * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself, |
||
1149 | * but can have extradata appended at the end after the 40 bytes belonging |
||
1150 | * to the struct. |
||
1151 | */ |
||
1152 | static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1153 | { |
||
1154 | AVStream *st; |
||
1155 | |||
1156 | if (c->fc->nb_streams < 1) |
||
1157 | return 0; |
||
1158 | if (atom.size <= 40) |
||
1159 | return 0; |
||
1160 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1161 | |||
1162 | if ((uint64_t)atom.size > (1<<30)) |
||
1163 | return AVERROR_INVALIDDATA; |
||
1164 | |||
1165 | av_free(st->codec->extradata); |
||
1166 | if (ff_alloc_extradata(st->codec, atom.size - 40)) |
||
1167 | return AVERROR(ENOMEM); |
||
1168 | avio_skip(pb, 40); |
||
1169 | avio_read(pb, st->codec->extradata, atom.size - 40); |
||
1170 | return 0; |
||
1171 | } |
||
1172 | |||
1173 | static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1174 | { |
||
1175 | AVStream *st; |
||
1176 | MOVStreamContext *sc; |
||
1177 | unsigned int i, entries; |
||
1178 | |||
1179 | if (c->fc->nb_streams < 1) |
||
1180 | return 0; |
||
1181 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1182 | sc = st->priv_data; |
||
1183 | |||
1184 | avio_r8(pb); /* version */ |
||
1185 | avio_rb24(pb); /* flags */ |
||
1186 | |||
1187 | entries = avio_rb32(pb); |
||
1188 | |||
1189 | if (!entries) |
||
1190 | return 0; |
||
1191 | if (entries >= UINT_MAX/sizeof(int64_t)) |
||
1192 | return AVERROR_INVALIDDATA; |
||
1193 | |||
1194 | sc->chunk_offsets = av_malloc(entries * sizeof(int64_t)); |
||
1195 | if (!sc->chunk_offsets) |
||
1196 | return AVERROR(ENOMEM); |
||
1197 | sc->chunk_count = entries; |
||
1198 | |||
1199 | if (atom.type == MKTAG('s','t','c','o')) |
||
1200 | for (i = 0; i < entries && !pb->eof_reached; i++) |
||
1201 | sc->chunk_offsets[i] = avio_rb32(pb); |
||
1202 | else if (atom.type == MKTAG('c','o','6','4')) |
||
1203 | for (i = 0; i < entries && !pb->eof_reached; i++) |
||
1204 | sc->chunk_offsets[i] = avio_rb64(pb); |
||
1205 | else |
||
1206 | return AVERROR_INVALIDDATA; |
||
1207 | |||
1208 | sc->chunk_count = i; |
||
1209 | |||
1210 | if (pb->eof_reached) |
||
1211 | return AVERROR_EOF; |
||
1212 | |||
1213 | return 0; |
||
1214 | } |
||
1215 | |||
1216 | /** |
||
1217 | * Compute codec id for 'lpcm' tag. |
||
1218 | * See CoreAudioTypes and AudioStreamBasicDescription at Apple. |
||
1219 | */ |
||
1220 | enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags) |
||
1221 | { |
||
1222 | /* lpcm flags: |
||
1223 | * 0x1 = float |
||
1224 | * 0x2 = big-endian |
||
1225 | * 0x4 = signed |
||
1226 | */ |
||
1227 | return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0); |
||
1228 | } |
||
1229 | |||
1230 | static int mov_codec_id(AVStream *st, uint32_t format) |
||
1231 | { |
||
1232 | int id = ff_codec_get_id(ff_codec_movaudio_tags, format); |
||
1233 | |||
1234 | if (id <= 0 && |
||
1235 | ((format & 0xFFFF) == 'm' + ('s' << 8) || |
||
1236 | (format & 0xFFFF) == 'T' + ('S' << 8))) |
||
1237 | id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF); |
||
1238 | |||
1239 | if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) { |
||
1240 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
||
1241 | } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && |
||
1242 | /* skip old asf mpeg4 tag */ |
||
1243 | format && format != MKTAG('m','p','4','s')) { |
||
1244 | id = ff_codec_get_id(ff_codec_movvideo_tags, format); |
||
1245 | if (id <= 0) |
||
1246 | id = ff_codec_get_id(ff_codec_bmp_tags, format); |
||
1247 | if (id > 0) |
||
1248 | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
||
1249 | else if (st->codec->codec_type == AVMEDIA_TYPE_DATA || |
||
1250 | (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && |
||
1251 | st->codec->codec_id == AV_CODEC_ID_NONE)) { |
||
1252 | id = ff_codec_get_id(ff_codec_movsubtitle_tags, format); |
||
1253 | if (id > 0) |
||
1254 | st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; |
||
1255 | } |
||
1256 | } |
||
1257 | |||
1258 | st->codec->codec_tag = format; |
||
1259 | |||
1260 | return id; |
||
1261 | } |
||
1262 | |||
1263 | static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb, |
||
1264 | AVStream *st, MOVStreamContext *sc) |
||
1265 | { |
||
1266 | unsigned int color_depth, len, j; |
||
1267 | int color_greyscale; |
||
1268 | int color_table_id; |
||
1269 | |||
1270 | avio_rb16(pb); /* version */ |
||
1271 | avio_rb16(pb); /* revision level */ |
||
1272 | avio_rb32(pb); /* vendor */ |
||
1273 | avio_rb32(pb); /* temporal quality */ |
||
1274 | avio_rb32(pb); /* spatial quality */ |
||
1275 | |||
1276 | st->codec->width = avio_rb16(pb); /* width */ |
||
1277 | st->codec->height = avio_rb16(pb); /* height */ |
||
1278 | |||
1279 | avio_rb32(pb); /* horiz resolution */ |
||
1280 | avio_rb32(pb); /* vert resolution */ |
||
1281 | avio_rb32(pb); /* data size, always 0 */ |
||
1282 | avio_rb16(pb); /* frames per samples */ |
||
1283 | |||
1284 | len = avio_r8(pb); /* codec name, pascal string */ |
||
1285 | if (len > 31) |
||
1286 | len = 31; |
||
1287 | mov_read_mac_string(c, pb, len, st->codec->codec_name, 32); |
||
1288 | if (len < 31) |
||
1289 | avio_skip(pb, 31 - len); |
||
1290 | /* codec_tag YV12 triggers an UV swap in rawdec.c */ |
||
1291 | if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) { |
||
1292 | st->codec->codec_tag = MKTAG('I', '4', '2', '0'); |
||
1293 | st->codec->width &= ~1; |
||
1294 | st->codec->height &= ~1; |
||
1295 | } |
||
1296 | /* Flash Media Server uses tag H263 with Sorenson Spark */ |
||
1297 | if (st->codec->codec_tag == MKTAG('H','2','6','3') && |
||
1298 | !memcmp(st->codec->codec_name, "Sorenson H263", 13)) |
||
1299 | st->codec->codec_id = AV_CODEC_ID_FLV1; |
||
1300 | |||
1301 | st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */ |
||
1302 | color_table_id = avio_rb16(pb); /* colortable id */ |
||
1303 | av_dlog(c->fc, "depth %d, ctab id %d\n", |
||
1304 | st->codec->bits_per_coded_sample, color_table_id); |
||
1305 | /* figure out the palette situation */ |
||
1306 | color_depth = st->codec->bits_per_coded_sample & 0x1F; |
||
1307 | color_greyscale = st->codec->bits_per_coded_sample & 0x20; |
||
1308 | |||
1309 | /* if the depth is 2, 4, or 8 bpp, file is palettized */ |
||
1310 | if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) { |
||
1311 | /* for palette traversal */ |
||
1312 | unsigned int color_start, color_count, color_end; |
||
1313 | unsigned char a, r, g, b; |
||
1314 | |||
1315 | if (color_greyscale) { |
||
1316 | int color_index, color_dec; |
||
1317 | /* compute the greyscale palette */ |
||
1318 | st->codec->bits_per_coded_sample = color_depth; |
||
1319 | color_count = 1 << color_depth; |
||
1320 | color_index = 255; |
||
1321 | color_dec = 256 / (color_count - 1); |
||
1322 | for (j = 0; j < color_count; j++) { |
||
1323 | if (st->codec->codec_id == AV_CODEC_ID_CINEPAK){ |
||
1324 | r = g = b = color_count - 1 - color_index; |
||
1325 | } else |
||
1326 | r = g = b = color_index; |
||
1327 | sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); |
||
1328 | color_index -= color_dec; |
||
1329 | if (color_index < 0) |
||
1330 | color_index = 0; |
||
1331 | } |
||
1332 | } else if (color_table_id) { |
||
1333 | const uint8_t *color_table; |
||
1334 | /* if flag bit 3 is set, use the default palette */ |
||
1335 | color_count = 1 << color_depth; |
||
1336 | if (color_depth == 2) |
||
1337 | color_table = ff_qt_default_palette_4; |
||
1338 | else if (color_depth == 4) |
||
1339 | color_table = ff_qt_default_palette_16; |
||
1340 | else |
||
1341 | color_table = ff_qt_default_palette_256; |
||
1342 | |||
1343 | for (j = 0; j < color_count; j++) { |
||
1344 | r = color_table[j * 3 + 0]; |
||
1345 | g = color_table[j * 3 + 1]; |
||
1346 | b = color_table[j * 3 + 2]; |
||
1347 | sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); |
||
1348 | } |
||
1349 | } else { |
||
1350 | /* load the palette from the file */ |
||
1351 | color_start = avio_rb32(pb); |
||
1352 | color_count = avio_rb16(pb); |
||
1353 | color_end = avio_rb16(pb); |
||
1354 | if ((color_start <= 255) && (color_end <= 255)) { |
||
1355 | for (j = color_start; j <= color_end; j++) { |
||
1356 | /* each A, R, G, or B component is 16 bits; |
||
1357 | * only use the top 8 bits */ |
||
1358 | a = avio_r8(pb); |
||
1359 | avio_r8(pb); |
||
1360 | r = avio_r8(pb); |
||
1361 | avio_r8(pb); |
||
1362 | g = avio_r8(pb); |
||
1363 | avio_r8(pb); |
||
1364 | b = avio_r8(pb); |
||
1365 | avio_r8(pb); |
||
1366 | sc->palette[j] = (a << 24 ) | (r << 16) | (g << 8) | (b); |
||
1367 | } |
||
1368 | } |
||
1369 | } |
||
1370 | sc->has_palette = 1; |
||
1371 | } |
||
1372 | } |
||
1373 | |||
1374 | static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, |
||
1375 | AVStream *st, MOVStreamContext *sc) |
||
1376 | { |
||
1377 | int bits_per_sample, flags; |
||
1378 | uint16_t version = avio_rb16(pb); |
||
1379 | AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE); |
||
1380 | |||
1381 | avio_rb16(pb); /* revision level */ |
||
1382 | avio_rb32(pb); /* vendor */ |
||
1383 | |||
1384 | st->codec->channels = avio_rb16(pb); /* channel count */ |
||
1385 | st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */ |
||
1386 | av_dlog(c->fc, "audio channels %d\n", st->codec->channels); |
||
1387 | |||
1388 | sc->audio_cid = avio_rb16(pb); |
||
1389 | avio_rb16(pb); /* packet size = 0 */ |
||
1390 | |||
1391 | st->codec->sample_rate = ((avio_rb32(pb) >> 16)); |
||
1392 | |||
1393 | // Read QT version 1 fields. In version 0 these do not exist. |
||
1394 | av_dlog(c->fc, "version =%d, isom =%d\n", version, c->isom); |
||
1395 | if (!c->isom || |
||
1396 | (compatible_brands && strstr(compatible_brands->value, "qt "))) { |
||
1397 | |||
1398 | if (version == 1) { |
||
1399 | sc->samples_per_frame = avio_rb32(pb); |
||
1400 | avio_rb32(pb); /* bytes per packet */ |
||
1401 | sc->bytes_per_frame = avio_rb32(pb); |
||
1402 | avio_rb32(pb); /* bytes per sample */ |
||
1403 | } else if (version == 2) { |
||
1404 | avio_rb32(pb); /* sizeof struct only */ |
||
1405 | st->codec->sample_rate = av_int2double(avio_rb64(pb)); |
||
1406 | st->codec->channels = avio_rb32(pb); |
||
1407 | avio_rb32(pb); /* always 0x7F000000 */ |
||
1408 | st->codec->bits_per_coded_sample = avio_rb32(pb); |
||
1409 | |||
1410 | flags = avio_rb32(pb); /* lpcm format specific flag */ |
||
1411 | sc->bytes_per_frame = avio_rb32(pb); |
||
1412 | sc->samples_per_frame = avio_rb32(pb); |
||
1413 | if (st->codec->codec_tag == MKTAG('l','p','c','m')) |
||
1414 | st->codec->codec_id = |
||
1415 | ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, |
||
1416 | flags); |
||
1417 | } |
||
1418 | } |
||
1419 | |||
1420 | switch (st->codec->codec_id) { |
||
1421 | case AV_CODEC_ID_PCM_S8: |
||
1422 | case AV_CODEC_ID_PCM_U8: |
||
1423 | if (st->codec->bits_per_coded_sample == 16) |
||
1424 | st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; |
||
1425 | break; |
||
1426 | case AV_CODEC_ID_PCM_S16LE: |
||
1427 | case AV_CODEC_ID_PCM_S16BE: |
||
1428 | if (st->codec->bits_per_coded_sample == 8) |
||
1429 | st->codec->codec_id = AV_CODEC_ID_PCM_S8; |
||
1430 | else if (st->codec->bits_per_coded_sample == 24) |
||
1431 | st->codec->codec_id = |
||
1432 | st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ? |
||
1433 | AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; |
||
1434 | break; |
||
1435 | /* set values for old format before stsd version 1 appeared */ |
||
1436 | case AV_CODEC_ID_MACE3: |
||
1437 | sc->samples_per_frame = 6; |
||
1438 | sc->bytes_per_frame = 2 * st->codec->channels; |
||
1439 | break; |
||
1440 | case AV_CODEC_ID_MACE6: |
||
1441 | sc->samples_per_frame = 6; |
||
1442 | sc->bytes_per_frame = 1 * st->codec->channels; |
||
1443 | break; |
||
1444 | case AV_CODEC_ID_ADPCM_IMA_QT: |
||
1445 | sc->samples_per_frame = 64; |
||
1446 | sc->bytes_per_frame = 34 * st->codec->channels; |
||
1447 | break; |
||
1448 | case AV_CODEC_ID_GSM: |
||
1449 | sc->samples_per_frame = 160; |
||
1450 | sc->bytes_per_frame = 33; |
||
1451 | break; |
||
1452 | default: |
||
1453 | break; |
||
1454 | } |
||
1455 | |||
1456 | bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); |
||
1457 | if (bits_per_sample) { |
||
1458 | st->codec->bits_per_coded_sample = bits_per_sample; |
||
1459 | sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; |
||
1460 | } |
||
1461 | } |
||
1462 | |||
1463 | static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, |
||
1464 | AVStream *st, MOVStreamContext *sc, |
||
1465 | int size) |
||
1466 | { |
||
1467 | // ttxt stsd contains display flags, justification, background |
||
1468 | // color, fonts, and default styles, so fake an atom to read it |
||
1469 | MOVAtom fake_atom = { .size = size }; |
||
1470 | // mp4s contains a regular esds atom |
||
1471 | if (st->codec->codec_tag != AV_RL32("mp4s")) |
||
1472 | mov_read_glbl(c, pb, fake_atom); |
||
1473 | st->codec->width = sc->width; |
||
1474 | st->codec->height = sc->height; |
||
1475 | } |
||
1476 | |||
1477 | static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, |
||
1478 | AVStream *st, MOVStreamContext *sc, |
||
1479 | int size) |
||
1480 | { |
||
1481 | if (st->codec->codec_tag == MKTAG('t','m','c','d')) { |
||
1482 | if (ff_alloc_extradata(st->codec, size)) |
||
1483 | return AVERROR(ENOMEM); |
||
1484 | avio_read(pb, st->codec->extradata, size); |
||
1485 | if (size > 16) { |
||
1486 | MOVStreamContext *tmcd_ctx = st->priv_data; |
||
1487 | int val; |
||
1488 | val = AV_RB32(st->codec->extradata + 4); |
||
1489 | tmcd_ctx->tmcd_flags = val; |
||
1490 | if (val & 1) |
||
1491 | st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE; |
||
1492 | st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */ |
||
1493 | st->codec->time_base.num = 1; |
||
1494 | } |
||
1495 | } else { |
||
1496 | /* other codec type, just skip (rtp, mp4s ...) */ |
||
1497 | avio_skip(pb, size); |
||
1498 | } |
||
1499 | return 0; |
||
1500 | } |
||
1501 | |||
1502 | static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb, |
||
1503 | AVStream *st, MOVStreamContext *sc) |
||
1504 | { |
||
1505 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && |
||
1506 | !st->codec->sample_rate && sc->time_scale > 1) |
||
1507 | st->codec->sample_rate = sc->time_scale; |
||
1508 | |||
1509 | /* special codec parameters handling */ |
||
1510 | switch (st->codec->codec_id) { |
||
1511 | #if CONFIG_DV_DEMUXER |
||
1512 | case AV_CODEC_ID_DVAUDIO: |
||
1513 | c->dv_fctx = avformat_alloc_context(); |
||
1514 | c->dv_demux = avpriv_dv_init_demux(c->dv_fctx); |
||
1515 | if (!c->dv_demux) { |
||
1516 | av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n"); |
||
1517 | return AVERROR(ENOMEM); |
||
1518 | } |
||
1519 | sc->dv_audio_container = 1; |
||
1520 | st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; |
||
1521 | break; |
||
1522 | #endif |
||
1523 | /* no ifdef since parameters are always those */ |
||
1524 | case AV_CODEC_ID_QCELP: |
||
1525 | st->codec->channels = 1; |
||
1526 | // force sample rate for qcelp when not stored in mov |
||
1527 | if (st->codec->codec_tag != MKTAG('Q','c','l','p')) |
||
1528 | st->codec->sample_rate = 8000; |
||
1529 | break; |
||
1530 | case AV_CODEC_ID_AMR_NB: |
||
1531 | st->codec->channels = 1; |
||
1532 | /* force sample rate for amr, stsd in 3gp does not store sample rate */ |
||
1533 | st->codec->sample_rate = 8000; |
||
1534 | break; |
||
1535 | case AV_CODEC_ID_AMR_WB: |
||
1536 | st->codec->channels = 1; |
||
1537 | st->codec->sample_rate = 16000; |
||
1538 | break; |
||
1539 | case AV_CODEC_ID_MP2: |
||
1540 | case AV_CODEC_ID_MP3: |
||
1541 | /* force type after stsd for m1a hdlr */ |
||
1542 | st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
||
1543 | st->need_parsing = AVSTREAM_PARSE_FULL; |
||
1544 | break; |
||
1545 | case AV_CODEC_ID_GSM: |
||
1546 | case AV_CODEC_ID_ADPCM_MS: |
||
1547 | case AV_CODEC_ID_ADPCM_IMA_WAV: |
||
1548 | case AV_CODEC_ID_ILBC: |
||
1549 | case AV_CODEC_ID_MACE3: |
||
1550 | case AV_CODEC_ID_MACE6: |
||
1551 | case AV_CODEC_ID_QDM2: |
||
1552 | st->codec->block_align = sc->bytes_per_frame; |
||
1553 | break; |
||
1554 | case AV_CODEC_ID_ALAC: |
||
1555 | if (st->codec->extradata_size == 36) { |
||
1556 | st->codec->channels = AV_RB8 (st->codec->extradata + 21); |
||
1557 | st->codec->sample_rate = AV_RB32(st->codec->extradata + 32); |
||
1558 | } |
||
1559 | break; |
||
1560 | case AV_CODEC_ID_AC3: |
||
1561 | st->need_parsing = AVSTREAM_PARSE_FULL; |
||
1562 | break; |
||
1563 | case AV_CODEC_ID_MPEG1VIDEO: |
||
1564 | st->need_parsing = AVSTREAM_PARSE_FULL; |
||
1565 | break; |
||
1566 | case AV_CODEC_ID_VC1: |
||
1567 | st->need_parsing = AVSTREAM_PARSE_FULL; |
||
1568 | break; |
||
1569 | default: |
||
1570 | break; |
||
1571 | } |
||
1572 | return 0; |
||
1573 | } |
||
1574 | |||
1575 | static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb, |
||
1576 | int codec_tag, int format, |
||
1577 | int size) |
||
1578 | { |
||
1579 | int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format); |
||
1580 | |||
1581 | if (codec_tag && |
||
1582 | (codec_tag != format && |
||
1583 | (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id |
||
1584 | : codec_tag != MKTAG('j','p','e','g')))) { |
||
1585 | /* Multiple fourcc, we skip JPEG. This is not correct, we should |
||
1586 | * export it as a separate AVStream but this needs a few changes |
||
1587 | * in the MOV demuxer, patch welcome. */ |
||
1588 | |||
1589 | av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n"); |
||
1590 | avio_skip(pb, size); |
||
1591 | return 1; |
||
1592 | } |
||
1593 | if ( codec_tag == AV_RL32("avc1") || |
||
1594 | codec_tag == AV_RL32("hvc1") || |
||
1595 | codec_tag == AV_RL32("hev1") |
||
1596 | ) |
||
1597 | av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 or H.265 might not play correctly.\n"); |
||
1598 | |||
1599 | return 0; |
||
1600 | } |
||
1601 | |||
1602 | int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) |
||
1603 | { |
||
1604 | AVStream *st; |
||
1605 | MOVStreamContext *sc; |
||
1606 | int pseudo_stream_id; |
||
1607 | |||
1608 | if (c->fc->nb_streams < 1) |
||
1609 | return 0; |
||
1610 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1611 | sc = st->priv_data; |
||
1612 | |||
1613 | for (pseudo_stream_id = 0; |
||
1614 | pseudo_stream_id < entries && !pb->eof_reached; |
||
1615 | pseudo_stream_id++) { |
||
1616 | //Parsing Sample description table |
||
1617 | enum AVCodecID id; |
||
1618 | int ret, dref_id = 1; |
||
1619 | MOVAtom a = { AV_RL32("stsd") }; |
||
1620 | int64_t start_pos = avio_tell(pb); |
||
1621 | int64_t size = avio_rb32(pb); /* size */ |
||
1622 | uint32_t format = avio_rl32(pb); /* data format */ |
||
1623 | |||
1624 | if (size >= 16) { |
||
1625 | avio_rb32(pb); /* reserved */ |
||
1626 | avio_rb16(pb); /* reserved */ |
||
1627 | dref_id = avio_rb16(pb); |
||
1628 | }else if (size <= 7){ |
||
1629 | av_log(c->fc, AV_LOG_ERROR, "invalid size %"PRId64" in stsd\n", size); |
||
1630 | return AVERROR_INVALIDDATA; |
||
1631 | } |
||
1632 | |||
1633 | if (mov_skip_multiple_stsd(c, pb, st->codec->codec_tag, format, |
||
1634 | size - (avio_tell(pb) - start_pos))) |
||
1635 | continue; |
||
1636 | |||
1637 | sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id; |
||
1638 | sc->dref_id= dref_id; |
||
1639 | |||
1640 | id = mov_codec_id(st, format); |
||
1641 | |||
1642 | av_dlog(c->fc, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size, |
||
1643 | (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, |
||
1644 | (format >> 24) & 0xff, st->codec->codec_type); |
||
1645 | |||
1646 | if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) { |
||
1647 | st->codec->codec_id = id; |
||
1648 | mov_parse_stsd_video(c, pb, st, sc); |
||
1649 | } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { |
||
1650 | st->codec->codec_id = id; |
||
1651 | mov_parse_stsd_audio(c, pb, st, sc); |
||
1652 | } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){ |
||
1653 | st->codec->codec_id = id; |
||
1654 | mov_parse_stsd_subtitle(c, pb, st, sc, |
||
1655 | size - (avio_tell(pb) - start_pos)); |
||
1656 | } else { |
||
1657 | ret = mov_parse_stsd_data(c, pb, st, sc, |
||
1658 | size - (avio_tell(pb) - start_pos)); |
||
1659 | if (ret < 0) |
||
1660 | return ret; |
||
1661 | } |
||
1662 | /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */ |
||
1663 | a.size = size - (avio_tell(pb) - start_pos); |
||
1664 | if (a.size > 8) { |
||
1665 | if ((ret = mov_read_default(c, pb, a)) < 0) |
||
1666 | return ret; |
||
1667 | } else if (a.size > 0) |
||
1668 | avio_skip(pb, a.size); |
||
1669 | } |
||
1670 | |||
1671 | if (pb->eof_reached) |
||
1672 | return AVERROR_EOF; |
||
1673 | |||
1674 | return mov_finalize_stsd_codec(c, pb, st, sc); |
||
1675 | } |
||
1676 | |||
1677 | static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1678 | { |
||
1679 | int entries; |
||
1680 | |||
1681 | avio_r8(pb); /* version */ |
||
1682 | avio_rb24(pb); /* flags */ |
||
1683 | entries = avio_rb32(pb); |
||
1684 | |||
1685 | return ff_mov_read_stsd_entries(c, pb, entries); |
||
1686 | } |
||
1687 | |||
1688 | static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1689 | { |
||
1690 | AVStream *st; |
||
1691 | MOVStreamContext *sc; |
||
1692 | unsigned int i, entries; |
||
1693 | |||
1694 | if (c->fc->nb_streams < 1) |
||
1695 | return 0; |
||
1696 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1697 | sc = st->priv_data; |
||
1698 | |||
1699 | avio_r8(pb); /* version */ |
||
1700 | avio_rb24(pb); /* flags */ |
||
1701 | |||
1702 | entries = avio_rb32(pb); |
||
1703 | |||
1704 | av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); |
||
1705 | |||
1706 | if (!entries) |
||
1707 | return 0; |
||
1708 | if (entries >= UINT_MAX / sizeof(*sc->stsc_data)) |
||
1709 | return AVERROR_INVALIDDATA; |
||
1710 | sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data)); |
||
1711 | if (!sc->stsc_data) |
||
1712 | return AVERROR(ENOMEM); |
||
1713 | |||
1714 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1715 | sc->stsc_data[i].first = avio_rb32(pb); |
||
1716 | sc->stsc_data[i].count = avio_rb32(pb); |
||
1717 | sc->stsc_data[i].id = avio_rb32(pb); |
||
1718 | } |
||
1719 | |||
1720 | sc->stsc_count = i; |
||
1721 | |||
1722 | if (pb->eof_reached) |
||
1723 | return AVERROR_EOF; |
||
1724 | |||
1725 | return 0; |
||
1726 | } |
||
1727 | |||
1728 | static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1729 | { |
||
1730 | AVStream *st; |
||
1731 | MOVStreamContext *sc; |
||
1732 | unsigned i, entries; |
||
1733 | |||
1734 | if (c->fc->nb_streams < 1) |
||
1735 | return 0; |
||
1736 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1737 | sc = st->priv_data; |
||
1738 | |||
1739 | avio_rb32(pb); // version + flags |
||
1740 | |||
1741 | entries = avio_rb32(pb); |
||
1742 | if (entries >= UINT_MAX / sizeof(*sc->stps_data)) |
||
1743 | return AVERROR_INVALIDDATA; |
||
1744 | sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); |
||
1745 | if (!sc->stps_data) |
||
1746 | return AVERROR(ENOMEM); |
||
1747 | |||
1748 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1749 | sc->stps_data[i] = avio_rb32(pb); |
||
1750 | //av_dlog(c->fc, "stps %d\n", sc->stps_data[i]); |
||
1751 | } |
||
1752 | |||
1753 | sc->stps_count = i; |
||
1754 | |||
1755 | if (pb->eof_reached) |
||
1756 | return AVERROR_EOF; |
||
1757 | |||
1758 | return 0; |
||
1759 | } |
||
1760 | |||
1761 | static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1762 | { |
||
1763 | AVStream *st; |
||
1764 | MOVStreamContext *sc; |
||
1765 | unsigned int i, entries; |
||
1766 | |||
1767 | if (c->fc->nb_streams < 1) |
||
1768 | return 0; |
||
1769 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1770 | sc = st->priv_data; |
||
1771 | |||
1772 | avio_r8(pb); /* version */ |
||
1773 | avio_rb24(pb); /* flags */ |
||
1774 | |||
1775 | entries = avio_rb32(pb); |
||
1776 | |||
1777 | av_dlog(c->fc, "keyframe_count = %d\n", entries); |
||
1778 | |||
1779 | if (!entries) |
||
1780 | { |
||
1781 | sc->keyframe_absent = 1; |
||
1782 | if (!st->need_parsing) |
||
1783 | st->need_parsing = AVSTREAM_PARSE_HEADERS; |
||
1784 | return 0; |
||
1785 | } |
||
1786 | if (entries >= UINT_MAX / sizeof(int)) |
||
1787 | return AVERROR_INVALIDDATA; |
||
1788 | sc->keyframes = av_malloc(entries * sizeof(int)); |
||
1789 | if (!sc->keyframes) |
||
1790 | return AVERROR(ENOMEM); |
||
1791 | |||
1792 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1793 | sc->keyframes[i] = avio_rb32(pb); |
||
1794 | //av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]); |
||
1795 | } |
||
1796 | |||
1797 | sc->keyframe_count = i; |
||
1798 | |||
1799 | if (pb->eof_reached) |
||
1800 | return AVERROR_EOF; |
||
1801 | |||
1802 | return 0; |
||
1803 | } |
||
1804 | |||
1805 | static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1806 | { |
||
1807 | AVStream *st; |
||
1808 | MOVStreamContext *sc; |
||
1809 | unsigned int i, entries, sample_size, field_size, num_bytes; |
||
1810 | GetBitContext gb; |
||
1811 | unsigned char* buf; |
||
1812 | |||
1813 | if (c->fc->nb_streams < 1) |
||
1814 | return 0; |
||
1815 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1816 | sc = st->priv_data; |
||
1817 | |||
1818 | avio_r8(pb); /* version */ |
||
1819 | avio_rb24(pb); /* flags */ |
||
1820 | |||
1821 | if (atom.type == MKTAG('s','t','s','z')) { |
||
1822 | sample_size = avio_rb32(pb); |
||
1823 | if (!sc->sample_size) /* do not overwrite value computed in stsd */ |
||
1824 | sc->sample_size = sample_size; |
||
1825 | sc->stsz_sample_size = sample_size; |
||
1826 | field_size = 32; |
||
1827 | } else { |
||
1828 | sample_size = 0; |
||
1829 | avio_rb24(pb); /* reserved */ |
||
1830 | field_size = avio_r8(pb); |
||
1831 | } |
||
1832 | entries = avio_rb32(pb); |
||
1833 | |||
1834 | av_dlog(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries); |
||
1835 | |||
1836 | sc->sample_count = entries; |
||
1837 | if (sample_size) |
||
1838 | return 0; |
||
1839 | |||
1840 | if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) { |
||
1841 | av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size); |
||
1842 | return AVERROR_INVALIDDATA; |
||
1843 | } |
||
1844 | |||
1845 | if (!entries) |
||
1846 | return 0; |
||
1847 | if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size) |
||
1848 | return AVERROR_INVALIDDATA; |
||
1849 | sc->sample_sizes = av_malloc(entries * sizeof(int)); |
||
1850 | if (!sc->sample_sizes) |
||
1851 | return AVERROR(ENOMEM); |
||
1852 | |||
1853 | num_bytes = (entries*field_size+4)>>3; |
||
1854 | |||
1855 | buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE); |
||
1856 | if (!buf) { |
||
1857 | av_freep(&sc->sample_sizes); |
||
1858 | return AVERROR(ENOMEM); |
||
1859 | } |
||
1860 | |||
1861 | if (avio_read(pb, buf, num_bytes) < num_bytes) { |
||
1862 | av_freep(&sc->sample_sizes); |
||
1863 | av_free(buf); |
||
1864 | return AVERROR_INVALIDDATA; |
||
1865 | } |
||
1866 | |||
1867 | init_get_bits(&gb, buf, 8*num_bytes); |
||
1868 | |||
1869 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1870 | sc->sample_sizes[i] = get_bits_long(&gb, field_size); |
||
1871 | sc->data_size += sc->sample_sizes[i]; |
||
1872 | } |
||
1873 | |||
1874 | sc->sample_count = i; |
||
1875 | |||
1876 | if (pb->eof_reached) |
||
1877 | return AVERROR_EOF; |
||
1878 | |||
1879 | av_free(buf); |
||
1880 | return 0; |
||
1881 | } |
||
1882 | |||
1883 | static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1884 | { |
||
1885 | AVStream *st; |
||
1886 | MOVStreamContext *sc; |
||
1887 | unsigned int i, entries; |
||
1888 | int64_t duration=0; |
||
1889 | int64_t total_sample_count=0; |
||
1890 | |||
1891 | if (c->fc->nb_streams < 1) |
||
1892 | return 0; |
||
1893 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1894 | sc = st->priv_data; |
||
1895 | |||
1896 | avio_r8(pb); /* version */ |
||
1897 | avio_rb24(pb); /* flags */ |
||
1898 | entries = avio_rb32(pb); |
||
1899 | |||
1900 | av_dlog(c->fc, "track[%i].stts.entries = %i\n", |
||
1901 | c->fc->nb_streams-1, entries); |
||
1902 | |||
1903 | if (entries >= UINT_MAX / sizeof(*sc->stts_data)) |
||
1904 | return -1; |
||
1905 | |||
1906 | sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data)); |
||
1907 | if (!sc->stts_data) |
||
1908 | return AVERROR(ENOMEM); |
||
1909 | |||
1910 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1911 | int sample_duration; |
||
1912 | int sample_count; |
||
1913 | |||
1914 | sample_count=avio_rb32(pb); |
||
1915 | sample_duration = avio_rb32(pb); |
||
1916 | |||
1917 | /* sample_duration < 0 is invalid based on the spec */ |
||
1918 | if (sample_duration < 0) { |
||
1919 | av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d\n", sample_duration); |
||
1920 | sample_duration = 1; |
||
1921 | } |
||
1922 | if (sample_count < 0) { |
||
1923 | av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count); |
||
1924 | return AVERROR_INVALIDDATA; |
||
1925 | } |
||
1926 | sc->stts_data[i].count= sample_count; |
||
1927 | sc->stts_data[i].duration= sample_duration; |
||
1928 | |||
1929 | av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n", |
||
1930 | sample_count, sample_duration); |
||
1931 | |||
1932 | duration+=(int64_t)sample_duration*sample_count; |
||
1933 | total_sample_count+=sample_count; |
||
1934 | } |
||
1935 | |||
1936 | sc->stts_count = i; |
||
1937 | |||
1938 | if (pb->eof_reached) |
||
1939 | return AVERROR_EOF; |
||
1940 | |||
1941 | st->nb_frames= total_sample_count; |
||
1942 | if (duration) |
||
1943 | st->duration= duration; |
||
1944 | sc->track_end = duration; |
||
1945 | return 0; |
||
1946 | } |
||
1947 | |||
1948 | static void mov_update_dts_shift(MOVStreamContext *sc, int duration) |
||
1949 | { |
||
1950 | if (duration < 0) { |
||
1951 | sc->dts_shift = FFMAX(sc->dts_shift, -duration); |
||
1952 | } |
||
1953 | } |
||
1954 | |||
1955 | static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
1956 | { |
||
1957 | AVStream *st; |
||
1958 | MOVStreamContext *sc; |
||
1959 | unsigned int i, entries; |
||
1960 | |||
1961 | if (c->fc->nb_streams < 1) |
||
1962 | return 0; |
||
1963 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
1964 | sc = st->priv_data; |
||
1965 | |||
1966 | avio_r8(pb); /* version */ |
||
1967 | avio_rb24(pb); /* flags */ |
||
1968 | entries = avio_rb32(pb); |
||
1969 | |||
1970 | av_dlog(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries); |
||
1971 | |||
1972 | if (!entries) |
||
1973 | return 0; |
||
1974 | if (entries >= UINT_MAX / sizeof(*sc->ctts_data)) |
||
1975 | return AVERROR_INVALIDDATA; |
||
1976 | sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data)); |
||
1977 | if (!sc->ctts_data) |
||
1978 | return AVERROR(ENOMEM); |
||
1979 | |||
1980 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
1981 | int count =avio_rb32(pb); |
||
1982 | int duration =avio_rb32(pb); |
||
1983 | |||
1984 | sc->ctts_data[i].count = count; |
||
1985 | sc->ctts_data[i].duration= duration; |
||
1986 | |||
1987 | av_dlog(c->fc, "count=%d, duration=%d\n", |
||
1988 | count, duration); |
||
1989 | |||
1990 | if (FFABS(duration) > (1<<28) && i+2 |
||
1991 | av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n"); |
||
1992 | av_freep(&sc->ctts_data); |
||
1993 | sc->ctts_count = 0; |
||
1994 | return 0; |
||
1995 | } |
||
1996 | |||
1997 | if (i+2 |
||
1998 | mov_update_dts_shift(sc, duration); |
||
1999 | } |
||
2000 | |||
2001 | sc->ctts_count = i; |
||
2002 | |||
2003 | if (pb->eof_reached) |
||
2004 | return AVERROR_EOF; |
||
2005 | |||
2006 | av_dlog(c->fc, "dts shift %d\n", sc->dts_shift); |
||
2007 | |||
2008 | return 0; |
||
2009 | } |
||
2010 | |||
2011 | static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2012 | { |
||
2013 | AVStream *st; |
||
2014 | MOVStreamContext *sc; |
||
2015 | unsigned int i, entries; |
||
2016 | uint8_t version; |
||
2017 | uint32_t grouping_type; |
||
2018 | |||
2019 | if (c->fc->nb_streams < 1) |
||
2020 | return 0; |
||
2021 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
2022 | sc = st->priv_data; |
||
2023 | |||
2024 | version = avio_r8(pb); /* version */ |
||
2025 | avio_rb24(pb); /* flags */ |
||
2026 | grouping_type = avio_rl32(pb); |
||
2027 | if (grouping_type != MKTAG( 'r','a','p',' ')) |
||
2028 | return 0; /* only support 'rap ' grouping */ |
||
2029 | if (version == 1) |
||
2030 | avio_rb32(pb); /* grouping_type_parameter */ |
||
2031 | |||
2032 | entries = avio_rb32(pb); |
||
2033 | if (!entries) |
||
2034 | return 0; |
||
2035 | if (entries >= UINT_MAX / sizeof(*sc->rap_group)) |
||
2036 | return AVERROR_INVALIDDATA; |
||
2037 | sc->rap_group = av_malloc(entries * sizeof(*sc->rap_group)); |
||
2038 | if (!sc->rap_group) |
||
2039 | return AVERROR(ENOMEM); |
||
2040 | |||
2041 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
2042 | sc->rap_group[i].count = avio_rb32(pb); /* sample_count */ |
||
2043 | sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */ |
||
2044 | } |
||
2045 | |||
2046 | sc->rap_group_count = i; |
||
2047 | |||
2048 | return pb->eof_reached ? AVERROR_EOF : 0; |
||
2049 | } |
||
2050 | |||
2051 | static void mov_build_index(MOVContext *mov, AVStream *st) |
||
2052 | { |
||
2053 | MOVStreamContext *sc = st->priv_data; |
||
2054 | int64_t current_offset; |
||
2055 | int64_t current_dts = 0; |
||
2056 | unsigned int stts_index = 0; |
||
2057 | unsigned int stsc_index = 0; |
||
2058 | unsigned int stss_index = 0; |
||
2059 | unsigned int stps_index = 0; |
||
2060 | unsigned int i, j; |
||
2061 | uint64_t stream_size = 0; |
||
2062 | |||
2063 | /* adjust first dts according to edit list */ |
||
2064 | if ((sc->empty_duration || sc->start_time) && mov->time_scale > 0) { |
||
2065 | if (sc->empty_duration) |
||
2066 | sc->empty_duration = av_rescale(sc->empty_duration, sc->time_scale, mov->time_scale); |
||
2067 | sc->time_offset = sc->start_time - sc->empty_duration; |
||
2068 | current_dts = -sc->time_offset; |
||
2069 | if (sc->ctts_count>0 && sc->stts_count>0 && |
||
2070 | sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) { |
||
2071 | /* more than 16 frames delay, dts are likely wrong |
||
2072 | this happens with files created by iMovie */ |
||
2073 | sc->wrong_dts = 1; |
||
2074 | st->codec->has_b_frames = 1; |
||
2075 | } |
||
2076 | } |
||
2077 | |||
2078 | /* only use old uncompressed audio chunk demuxing when stts specifies it */ |
||
2079 | if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && |
||
2080 | sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { |
||
2081 | unsigned int current_sample = 0; |
||
2082 | unsigned int stts_sample = 0; |
||
2083 | unsigned int sample_size; |
||
2084 | unsigned int distance = 0; |
||
2085 | unsigned int rap_group_index = 0; |
||
2086 | unsigned int rap_group_sample = 0; |
||
2087 | int rap_group_present = sc->rap_group_count && sc->rap_group; |
||
2088 | int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0); |
||
2089 | |||
2090 | current_dts -= sc->dts_shift; |
||
2091 | |||
2092 | if (!sc->sample_count || st->nb_index_entries) |
||
2093 | return; |
||
2094 | if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) |
||
2095 | return; |
||
2096 | if (av_reallocp_array(&st->index_entries, |
||
2097 | st->nb_index_entries + sc->sample_count, |
||
2098 | sizeof(*st->index_entries)) < 0) { |
||
2099 | st->nb_index_entries = 0; |
||
2100 | return; |
||
2101 | } |
||
2102 | st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); |
||
2103 | |||
2104 | for (i = 0; i < sc->chunk_count; i++) { |
||
2105 | int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX; |
||
2106 | current_offset = sc->chunk_offsets[i]; |
||
2107 | while (stsc_index + 1 < sc->stsc_count && |
||
2108 | i + 1 == sc->stsc_data[stsc_index + 1].first) |
||
2109 | stsc_index++; |
||
2110 | |||
2111 | if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size && |
||
2112 | sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) { |
||
2113 | av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size); |
||
2114 | sc->stsz_sample_size = sc->sample_size; |
||
2115 | } |
||
2116 | if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) { |
||
2117 | av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size); |
||
2118 | sc->stsz_sample_size = sc->sample_size; |
||
2119 | } |
||
2120 | |||
2121 | for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { |
||
2122 | int keyframe = 0; |
||
2123 | if (current_sample >= sc->sample_count) { |
||
2124 | av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); |
||
2125 | return; |
||
2126 | } |
||
2127 | |||
2128 | if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) { |
||
2129 | keyframe = 1; |
||
2130 | if (stss_index + 1 < sc->keyframe_count) |
||
2131 | stss_index++; |
||
2132 | } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) { |
||
2133 | keyframe = 1; |
||
2134 | if (stps_index + 1 < sc->stps_count) |
||
2135 | stps_index++; |
||
2136 | } |
||
2137 | if (rap_group_present && rap_group_index < sc->rap_group_count) { |
||
2138 | if (sc->rap_group[rap_group_index].index > 0) |
||
2139 | keyframe = 1; |
||
2140 | if (++rap_group_sample == sc->rap_group[rap_group_index].count) { |
||
2141 | rap_group_sample = 0; |
||
2142 | rap_group_index++; |
||
2143 | } |
||
2144 | } |
||
2145 | if (keyframe) |
||
2146 | distance = 0; |
||
2147 | sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample]; |
||
2148 | if (sc->pseudo_stream_id == -1 || |
||
2149 | sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { |
||
2150 | AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; |
||
2151 | e->pos = current_offset; |
||
2152 | e->timestamp = current_dts; |
||
2153 | e->size = sample_size; |
||
2154 | e->min_distance = distance; |
||
2155 | e->flags = keyframe ? AVINDEX_KEYFRAME : 0; |
||
2156 | av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " |
||
2157 | "size %d, distance %d, keyframe %d\n", st->index, current_sample, |
||
2158 | current_offset, current_dts, sample_size, distance, keyframe); |
||
2159 | } |
||
2160 | |||
2161 | current_offset += sample_size; |
||
2162 | stream_size += sample_size; |
||
2163 | current_dts += sc->stts_data[stts_index].duration; |
||
2164 | distance++; |
||
2165 | stts_sample++; |
||
2166 | current_sample++; |
||
2167 | if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) { |
||
2168 | stts_sample = 0; |
||
2169 | stts_index++; |
||
2170 | } |
||
2171 | } |
||
2172 | } |
||
2173 | if (st->duration > 0) |
||
2174 | st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; |
||
2175 | } else { |
||
2176 | unsigned chunk_samples, total = 0; |
||
2177 | |||
2178 | // compute total chunk count |
||
2179 | for (i = 0; i < sc->stsc_count; i++) { |
||
2180 | unsigned count, chunk_count; |
||
2181 | |||
2182 | chunk_samples = sc->stsc_data[i].count; |
||
2183 | if (i != sc->stsc_count - 1 && |
||
2184 | sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { |
||
2185 | av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); |
||
2186 | return; |
||
2187 | } |
||
2188 | |||
2189 | if (sc->samples_per_frame >= 160) { // gsm |
||
2190 | count = chunk_samples / sc->samples_per_frame; |
||
2191 | } else if (sc->samples_per_frame > 1) { |
||
2192 | unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame; |
||
2193 | count = (chunk_samples+samples-1) / samples; |
||
2194 | } else { |
||
2195 | count = (chunk_samples+1023) / 1024; |
||
2196 | } |
||
2197 | |||
2198 | if (i < sc->stsc_count - 1) |
||
2199 | chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; |
||
2200 | else |
||
2201 | chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); |
||
2202 | total += chunk_count * count; |
||
2203 | } |
||
2204 | |||
2205 | av_dlog(mov->fc, "chunk count %d\n", total); |
||
2206 | if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) |
||
2207 | return; |
||
2208 | if (av_reallocp_array(&st->index_entries, |
||
2209 | st->nb_index_entries + total, |
||
2210 | sizeof(*st->index_entries)) < 0) { |
||
2211 | st->nb_index_entries = 0; |
||
2212 | return; |
||
2213 | } |
||
2214 | st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries); |
||
2215 | |||
2216 | // populate index |
||
2217 | for (i = 0; i < sc->chunk_count; i++) { |
||
2218 | current_offset = sc->chunk_offsets[i]; |
||
2219 | if (stsc_index + 1 < sc->stsc_count && |
||
2220 | i + 1 == sc->stsc_data[stsc_index + 1].first) |
||
2221 | stsc_index++; |
||
2222 | chunk_samples = sc->stsc_data[stsc_index].count; |
||
2223 | |||
2224 | while (chunk_samples > 0) { |
||
2225 | AVIndexEntry *e; |
||
2226 | unsigned size, samples; |
||
2227 | |||
2228 | if (sc->samples_per_frame >= 160) { // gsm |
||
2229 | samples = sc->samples_per_frame; |
||
2230 | size = sc->bytes_per_frame; |
||
2231 | } else { |
||
2232 | if (sc->samples_per_frame > 1) { |
||
2233 | samples = FFMIN((1024 / sc->samples_per_frame)* |
||
2234 | sc->samples_per_frame, chunk_samples); |
||
2235 | size = (samples / sc->samples_per_frame) * sc->bytes_per_frame; |
||
2236 | } else { |
||
2237 | samples = FFMIN(1024, chunk_samples); |
||
2238 | size = samples * sc->sample_size; |
||
2239 | } |
||
2240 | } |
||
2241 | |||
2242 | if (st->nb_index_entries >= total) { |
||
2243 | av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); |
||
2244 | return; |
||
2245 | } |
||
2246 | e = &st->index_entries[st->nb_index_entries++]; |
||
2247 | e->pos = current_offset; |
||
2248 | e->timestamp = current_dts; |
||
2249 | e->size = size; |
||
2250 | e->min_distance = 0; |
||
2251 | e->flags = AVINDEX_KEYFRAME; |
||
2252 | av_dlog(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " |
||
2253 | "size %d, duration %d\n", st->index, i, current_offset, current_dts, |
||
2254 | size, samples); |
||
2255 | |||
2256 | current_offset += size; |
||
2257 | current_dts += samples; |
||
2258 | chunk_samples -= samples; |
||
2259 | } |
||
2260 | } |
||
2261 | } |
||
2262 | } |
||
2263 | |||
2264 | static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref, |
||
2265 | AVIOInterruptCB *int_cb, int use_absolute_path, AVFormatContext *fc) |
||
2266 | { |
||
2267 | /* try relative path, we do not try the absolute because it can leak information about our |
||
2268 | system to an attacker */ |
||
2269 | if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { |
||
2270 | char filename[1024]; |
||
2271 | const char *src_path; |
||
2272 | int i, l; |
||
2273 | |||
2274 | /* find a source dir */ |
||
2275 | src_path = strrchr(src, '/'); |
||
2276 | if (src_path) |
||
2277 | src_path++; |
||
2278 | else |
||
2279 | src_path = src; |
||
2280 | |||
2281 | /* find a next level down to target */ |
||
2282 | for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) |
||
2283 | if (ref->path[l] == '/') { |
||
2284 | if (i == ref->nlvl_to - 1) |
||
2285 | break; |
||
2286 | else |
||
2287 | i++; |
||
2288 | } |
||
2289 | |||
2290 | /* compose filename if next level down to target was found */ |
||
2291 | if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) { |
||
2292 | memcpy(filename, src, src_path - src); |
||
2293 | filename[src_path - src] = 0; |
||
2294 | |||
2295 | for (i = 1; i < ref->nlvl_from; i++) |
||
2296 | av_strlcat(filename, "../", 1024); |
||
2297 | |||
2298 | av_strlcat(filename, ref->path + l + 1, 1024); |
||
2299 | |||
2300 | if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL)) |
||
2301 | return 0; |
||
2302 | } |
||
2303 | } else if (use_absolute_path) { |
||
2304 | av_log(fc, AV_LOG_WARNING, "Using absolute path on user request, " |
||
2305 | "this is a possible security issue\n"); |
||
2306 | if (!avio_open2(pb, ref->path, AVIO_FLAG_READ, int_cb, NULL)) |
||
2307 | return 0; |
||
2308 | } |
||
2309 | |||
2310 | return AVERROR(ENOENT); |
||
2311 | } |
||
2312 | |||
2313 | static void fix_timescale(MOVContext *c, MOVStreamContext *sc) |
||
2314 | { |
||
2315 | if (sc->time_scale <= 0) { |
||
2316 | av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex); |
||
2317 | sc->time_scale = c->time_scale; |
||
2318 | if (sc->time_scale <= 0) |
||
2319 | sc->time_scale = 1; |
||
2320 | } |
||
2321 | } |
||
2322 | |||
2323 | static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2324 | { |
||
2325 | AVStream *st; |
||
2326 | MOVStreamContext *sc; |
||
2327 | int ret; |
||
2328 | |||
2329 | st = avformat_new_stream(c->fc, NULL); |
||
2330 | if (!st) return AVERROR(ENOMEM); |
||
2331 | st->id = c->fc->nb_streams; |
||
2332 | sc = av_mallocz(sizeof(MOVStreamContext)); |
||
2333 | if (!sc) return AVERROR(ENOMEM); |
||
2334 | |||
2335 | st->priv_data = sc; |
||
2336 | st->codec->codec_type = AVMEDIA_TYPE_DATA; |
||
2337 | sc->ffindex = st->index; |
||
2338 | |||
2339 | if ((ret = mov_read_default(c, pb, atom)) < 0) |
||
2340 | return ret; |
||
2341 | |||
2342 | /* sanity checks */ |
||
2343 | if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count || |
||
2344 | (!sc->sample_size && !sc->sample_count))) { |
||
2345 | av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n", |
||
2346 | st->index); |
||
2347 | return 0; |
||
2348 | } |
||
2349 | |||
2350 | fix_timescale(c, sc); |
||
2351 | |||
2352 | avpriv_set_pts_info(st, 64, 1, sc->time_scale); |
||
2353 | |||
2354 | mov_build_index(c, st); |
||
2355 | |||
2356 | if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { |
||
2357 | MOVDref *dref = &sc->drefs[sc->dref_id - 1]; |
||
2358 | if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback, |
||
2359 | c->use_absolute_path, c->fc) < 0) |
||
2360 | av_log(c->fc, AV_LOG_ERROR, |
||
2361 | "stream %d, error opening alias: path='%s', dir='%s', " |
||
2362 | "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", |
||
2363 | st->index, dref->path, dref->dir, dref->filename, |
||
2364 | dref->volume, dref->nlvl_from, dref->nlvl_to); |
||
2365 | } else { |
||
2366 | sc->pb = c->fc->pb; |
||
2367 | sc->pb_is_copied = 1; |
||
2368 | } |
||
2369 | |||
2370 | if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { |
||
2371 | if (!st->sample_aspect_ratio.num && |
||
2372 | (st->codec->width != sc->width || st->codec->height != sc->height)) { |
||
2373 | st->sample_aspect_ratio = av_d2q(((double)st->codec->height * sc->width) / |
||
2374 | ((double)st->codec->width * sc->height), INT_MAX); |
||
2375 | } |
||
2376 | |||
2377 | if (st->duration > 0) |
||
2378 | av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, |
||
2379 | sc->time_scale*st->nb_frames, st->duration, INT_MAX); |
||
2380 | |||
2381 | #if FF_API_R_FRAME_RATE |
||
2382 | if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1)) |
||
2383 | av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, |
||
2384 | sc->time_scale, sc->stts_data[0].duration, INT_MAX); |
||
2385 | #endif |
||
2386 | } |
||
2387 | |||
2388 | // done for ai5q, ai52, ai55, ai1q, ai12 and ai15. |
||
2389 | if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 && |
||
2390 | st->codec->codec_tag != MKTAG('a', 'v', 'c', '1')) { |
||
2391 | ff_generate_avci_extradata(st); |
||
2392 | } |
||
2393 | |||
2394 | switch (st->codec->codec_id) { |
||
2395 | #if CONFIG_H261_DECODER |
||
2396 | case AV_CODEC_ID_H261: |
||
2397 | #endif |
||
2398 | #if CONFIG_H263_DECODER |
||
2399 | case AV_CODEC_ID_H263: |
||
2400 | #endif |
||
2401 | #if CONFIG_MPEG4_DECODER |
||
2402 | case AV_CODEC_ID_MPEG4: |
||
2403 | #endif |
||
2404 | st->codec->width = 0; /* let decoder init width/height */ |
||
2405 | st->codec->height= 0; |
||
2406 | break; |
||
2407 | } |
||
2408 | |||
2409 | /* Do not need those anymore. */ |
||
2410 | av_freep(&sc->chunk_offsets); |
||
2411 | av_freep(&sc->stsc_data); |
||
2412 | av_freep(&sc->sample_sizes); |
||
2413 | av_freep(&sc->keyframes); |
||
2414 | av_freep(&sc->stts_data); |
||
2415 | av_freep(&sc->stps_data); |
||
2416 | av_freep(&sc->rap_group); |
||
2417 | |||
2418 | return 0; |
||
2419 | } |
||
2420 | |||
2421 | static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2422 | { |
||
2423 | int ret; |
||
2424 | c->itunes_metadata = 1; |
||
2425 | ret = mov_read_default(c, pb, atom); |
||
2426 | c->itunes_metadata = 0; |
||
2427 | return ret; |
||
2428 | } |
||
2429 | |||
2430 | static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2431 | { |
||
2432 | while (atom.size > 8) { |
||
2433 | uint32_t tag = avio_rl32(pb); |
||
2434 | atom.size -= 4; |
||
2435 | if (tag == MKTAG('h','d','l','r')) { |
||
2436 | avio_seek(pb, -8, SEEK_CUR); |
||
2437 | atom.size += 8; |
||
2438 | return mov_read_default(c, pb, atom); |
||
2439 | } |
||
2440 | } |
||
2441 | return 0; |
||
2442 | } |
||
2443 | |||
2444 | static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2445 | { |
||
2446 | int i; |
||
2447 | int width; |
||
2448 | int height; |
||
2449 | int64_t disp_transform[2]; |
||
2450 | int display_matrix[3][2]; |
||
2451 | AVStream *st; |
||
2452 | MOVStreamContext *sc; |
||
2453 | int version; |
||
2454 | int flags; |
||
2455 | |||
2456 | if (c->fc->nb_streams < 1) |
||
2457 | return 0; |
||
2458 | st = c->fc->streams[c->fc->nb_streams-1]; |
||
2459 | sc = st->priv_data; |
||
2460 | |||
2461 | version = avio_r8(pb); |
||
2462 | flags = avio_rb24(pb); |
||
2463 | st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0; |
||
2464 | |||
2465 | if (version == 1) { |
||
2466 | avio_rb64(pb); |
||
2467 | avio_rb64(pb); |
||
2468 | } else { |
||
2469 | avio_rb32(pb); /* creation time */ |
||
2470 | avio_rb32(pb); /* modification time */ |
||
2471 | } |
||
2472 | st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/ |
||
2473 | avio_rb32(pb); /* reserved */ |
||
2474 | |||
2475 | /* highlevel (considering edits) duration in movie timebase */ |
||
2476 | (version == 1) ? avio_rb64(pb) : avio_rb32(pb); |
||
2477 | avio_rb32(pb); /* reserved */ |
||
2478 | avio_rb32(pb); /* reserved */ |
||
2479 | |||
2480 | avio_rb16(pb); /* layer */ |
||
2481 | avio_rb16(pb); /* alternate group */ |
||
2482 | avio_rb16(pb); /* volume */ |
||
2483 | avio_rb16(pb); /* reserved */ |
||
2484 | |||
2485 | //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2) |
||
2486 | // they're kept in fixed point format through all calculations |
||
2487 | // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio |
||
2488 | for (i = 0; i < 3; i++) { |
||
2489 | display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point |
||
2490 | display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point |
||
2491 | avio_rb32(pb); // 2.30 fixed point (not used) |
||
2492 | } |
||
2493 | |||
2494 | width = avio_rb32(pb); // 16.16 fixed point track width |
||
2495 | height = avio_rb32(pb); // 16.16 fixed point track height |
||
2496 | sc->width = width >> 16; |
||
2497 | sc->height = height >> 16; |
||
2498 | |||
2499 | //Assign clockwise rotate values based on transform matrix so that |
||
2500 | //we can compensate for iPhone orientation during capture. |
||
2501 | |||
2502 | if (display_matrix[1][0] == -65536 && display_matrix[0][1] == 65536) { |
||
2503 | av_dict_set(&st->metadata, "rotate", "90", 0); |
||
2504 | } |
||
2505 | |||
2506 | if (display_matrix[0][0] == -65536 && display_matrix[1][1] == -65536) { |
||
2507 | av_dict_set(&st->metadata, "rotate", "180", 0); |
||
2508 | } |
||
2509 | |||
2510 | if (display_matrix[1][0] == 65536 && display_matrix[0][1] == -65536) { |
||
2511 | av_dict_set(&st->metadata, "rotate", "270", 0); |
||
2512 | } |
||
2513 | |||
2514 | // transform the display width/height according to the matrix |
||
2515 | // skip this if the display matrix is the default identity matrix |
||
2516 | // or if it is rotating the picture, ex iPhone 3GS |
||
2517 | // to keep the same scale, use [width height 1<<16] |
||
2518 | if (width && height && |
||
2519 | ((display_matrix[0][0] != 65536 || |
||
2520 | display_matrix[1][1] != 65536) && |
||
2521 | !display_matrix[0][1] && |
||
2522 | !display_matrix[1][0] && |
||
2523 | !display_matrix[2][0] && !display_matrix[2][1])) { |
||
2524 | for (i = 0; i < 2; i++) |
||
2525 | disp_transform[i] = |
||
2526 | (int64_t) width * display_matrix[0][i] + |
||
2527 | (int64_t) height * display_matrix[1][i] + |
||
2528 | ((int64_t) display_matrix[2][i] << 16); |
||
2529 | |||
2530 | //sample aspect ratio is new width/height divided by old width/height |
||
2531 | st->sample_aspect_ratio = av_d2q( |
||
2532 | ((double) disp_transform[0] * height) / |
||
2533 | ((double) disp_transform[1] * width), INT_MAX); |
||
2534 | } |
||
2535 | return 0; |
||
2536 | } |
||
2537 | |||
2538 | static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2539 | { |
||
2540 | MOVFragment *frag = &c->fragment; |
||
2541 | MOVTrackExt *trex = NULL; |
||
2542 | int flags, track_id, i; |
||
2543 | |||
2544 | avio_r8(pb); /* version */ |
||
2545 | flags = avio_rb24(pb); |
||
2546 | |||
2547 | track_id = avio_rb32(pb); |
||
2548 | if (!track_id) |
||
2549 | return AVERROR_INVALIDDATA; |
||
2550 | frag->track_id = track_id; |
||
2551 | for (i = 0; i < c->trex_count; i++) |
||
2552 | if (c->trex_data[i].track_id == frag->track_id) { |
||
2553 | trex = &c->trex_data[i]; |
||
2554 | break; |
||
2555 | } |
||
2556 | if (!trex) { |
||
2557 | av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n"); |
||
2558 | return AVERROR_INVALIDDATA; |
||
2559 | } |
||
2560 | |||
2561 | frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ? |
||
2562 | avio_rb64(pb) : frag->moof_offset; |
||
2563 | frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id; |
||
2564 | |||
2565 | frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ? |
||
2566 | avio_rb32(pb) : trex->duration; |
||
2567 | frag->size = flags & MOV_TFHD_DEFAULT_SIZE ? |
||
2568 | avio_rb32(pb) : trex->size; |
||
2569 | frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ? |
||
2570 | avio_rb32(pb) : trex->flags; |
||
2571 | av_dlog(c->fc, "frag flags 0x%x\n", frag->flags); |
||
2572 | return 0; |
||
2573 | } |
||
2574 | |||
2575 | static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2576 | { |
||
2577 | c->chapter_track = avio_rb32(pb); |
||
2578 | return 0; |
||
2579 | } |
||
2580 | |||
2581 | static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2582 | { |
||
2583 | MOVTrackExt *trex; |
||
2584 | int err; |
||
2585 | |||
2586 | if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data)) |
||
2587 | return AVERROR_INVALIDDATA; |
||
2588 | if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1, |
||
2589 | sizeof(*c->trex_data))) < 0) { |
||
2590 | c->trex_count = 0; |
||
2591 | return err; |
||
2592 | } |
||
2593 | |||
2594 | c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used. |
||
2595 | |||
2596 | trex = &c->trex_data[c->trex_count++]; |
||
2597 | avio_r8(pb); /* version */ |
||
2598 | avio_rb24(pb); /* flags */ |
||
2599 | trex->track_id = avio_rb32(pb); |
||
2600 | trex->stsd_id = avio_rb32(pb); |
||
2601 | trex->duration = avio_rb32(pb); |
||
2602 | trex->size = avio_rb32(pb); |
||
2603 | trex->flags = avio_rb32(pb); |
||
2604 | return 0; |
||
2605 | } |
||
2606 | |||
2607 | static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2608 | { |
||
2609 | MOVFragment *frag = &c->fragment; |
||
2610 | AVStream *st = NULL; |
||
2611 | MOVStreamContext *sc; |
||
2612 | MOVStts *ctts_data; |
||
2613 | uint64_t offset; |
||
2614 | int64_t dts; |
||
2615 | int data_offset = 0; |
||
2616 | unsigned entries, first_sample_flags = frag->flags; |
||
2617 | int flags, distance, i, found_keyframe = 0, err; |
||
2618 | |||
2619 | for (i = 0; i < c->fc->nb_streams; i++) { |
||
2620 | if (c->fc->streams[i]->id == frag->track_id) { |
||
2621 | st = c->fc->streams[i]; |
||
2622 | break; |
||
2623 | } |
||
2624 | } |
||
2625 | if (!st) { |
||
2626 | av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id); |
||
2627 | return AVERROR_INVALIDDATA; |
||
2628 | } |
||
2629 | sc = st->priv_data; |
||
2630 | if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1) |
||
2631 | return 0; |
||
2632 | avio_r8(pb); /* version */ |
||
2633 | flags = avio_rb24(pb); |
||
2634 | entries = avio_rb32(pb); |
||
2635 | av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries); |
||
2636 | |||
2637 | /* Always assume the presence of composition time offsets. |
||
2638 | * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following. |
||
2639 | * 1) in the initial movie, there are no samples. |
||
2640 | * 2) in the first movie fragment, there is only one sample without composition time offset. |
||
2641 | * 3) in the subsequent movie fragments, there are samples with composition time offset. */ |
||
2642 | if (!sc->ctts_count && sc->sample_count) |
||
2643 | { |
||
2644 | /* Complement ctts table if moov atom doesn't have ctts atom. */ |
||
2645 | ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data)); |
||
2646 | if (!ctts_data) |
||
2647 | return AVERROR(ENOMEM); |
||
2648 | sc->ctts_data = ctts_data; |
||
2649 | sc->ctts_data[sc->ctts_count].count = sc->sample_count; |
||
2650 | sc->ctts_data[sc->ctts_count].duration = 0; |
||
2651 | sc->ctts_count++; |
||
2652 | } |
||
2653 | if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) |
||
2654 | return AVERROR_INVALIDDATA; |
||
2655 | if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count, |
||
2656 | sizeof(*sc->ctts_data))) < 0) { |
||
2657 | sc->ctts_count = 0; |
||
2658 | return err; |
||
2659 | } |
||
2660 | if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb); |
||
2661 | if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb); |
||
2662 | dts = sc->track_end - sc->time_offset; |
||
2663 | offset = frag->base_data_offset + data_offset; |
||
2664 | distance = 0; |
||
2665 | av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags); |
||
2666 | for (i = 0; i < entries && !pb->eof_reached; i++) { |
||
2667 | unsigned sample_size = frag->size; |
||
2668 | int sample_flags = i ? frag->flags : first_sample_flags; |
||
2669 | unsigned sample_duration = frag->duration; |
||
2670 | int keyframe = 0; |
||
2671 | |||
2672 | if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb); |
||
2673 | if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb); |
||
2674 | if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb); |
||
2675 | sc->ctts_data[sc->ctts_count].count = 1; |
||
2676 | sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ? |
||
2677 | avio_rb32(pb) : 0; |
||
2678 | mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration); |
||
2679 | sc->ctts_count++; |
||
2680 | if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) |
||
2681 | keyframe = 1; |
||
2682 | else if (!found_keyframe) |
||
2683 | keyframe = found_keyframe = |
||
2684 | !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC | |
||
2685 | MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES)); |
||
2686 | if (keyframe) |
||
2687 | distance = 0; |
||
2688 | av_add_index_entry(st, offset, dts, sample_size, distance, |
||
2689 | keyframe ? AVINDEX_KEYFRAME : 0); |
||
2690 | av_dlog(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " |
||
2691 | "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i, |
||
2692 | offset, dts, sample_size, distance, keyframe); |
||
2693 | distance++; |
||
2694 | dts += sample_duration; |
||
2695 | offset += sample_size; |
||
2696 | sc->data_size += sample_size; |
||
2697 | } |
||
2698 | |||
2699 | if (pb->eof_reached) |
||
2700 | return AVERROR_EOF; |
||
2701 | |||
2702 | frag->moof_offset = offset; |
||
2703 | st->duration = sc->track_end = dts + sc->time_offset; |
||
2704 | return 0; |
||
2705 | } |
||
2706 | |||
2707 | /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */ |
||
2708 | /* like the files created with Adobe Premiere 5.0, for samples see */ |
||
2709 | /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */ |
||
2710 | static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2711 | { |
||
2712 | int err; |
||
2713 | |||
2714 | if (atom.size < 8) |
||
2715 | return 0; /* continue */ |
||
2716 | if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ |
||
2717 | avio_skip(pb, atom.size - 4); |
||
2718 | return 0; |
||
2719 | } |
||
2720 | atom.type = avio_rl32(pb); |
||
2721 | atom.size -= 8; |
||
2722 | if (atom.type != MKTAG('m','d','a','t')) { |
||
2723 | avio_skip(pb, atom.size); |
||
2724 | return 0; |
||
2725 | } |
||
2726 | err = mov_read_mdat(c, pb, atom); |
||
2727 | return err; |
||
2728 | } |
||
2729 | |||
2730 | static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2731 | { |
||
2732 | #if CONFIG_ZLIB |
||
2733 | AVIOContext ctx; |
||
2734 | uint8_t *cmov_data; |
||
2735 | uint8_t *moov_data; /* uncompressed data */ |
||
2736 | long cmov_len, moov_len; |
||
2737 | int ret = -1; |
||
2738 | |||
2739 | avio_rb32(pb); /* dcom atom */ |
||
2740 | if (avio_rl32(pb) != MKTAG('d','c','o','m')) |
||
2741 | return AVERROR_INVALIDDATA; |
||
2742 | if (avio_rl32(pb) != MKTAG('z','l','i','b')) { |
||
2743 | av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n"); |
||
2744 | return AVERROR_INVALIDDATA; |
||
2745 | } |
||
2746 | avio_rb32(pb); /* cmvd atom */ |
||
2747 | if (avio_rl32(pb) != MKTAG('c','m','v','d')) |
||
2748 | return AVERROR_INVALIDDATA; |
||
2749 | moov_len = avio_rb32(pb); /* uncompressed size */ |
||
2750 | cmov_len = atom.size - 6 * 4; |
||
2751 | |||
2752 | cmov_data = av_malloc(cmov_len); |
||
2753 | if (!cmov_data) |
||
2754 | return AVERROR(ENOMEM); |
||
2755 | moov_data = av_malloc(moov_len); |
||
2756 | if (!moov_data) { |
||
2757 | av_free(cmov_data); |
||
2758 | return AVERROR(ENOMEM); |
||
2759 | } |
||
2760 | avio_read(pb, cmov_data, cmov_len); |
||
2761 | if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK) |
||
2762 | goto free_and_return; |
||
2763 | if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0) |
||
2764 | goto free_and_return; |
||
2765 | atom.type = MKTAG('m','o','o','v'); |
||
2766 | atom.size = moov_len; |
||
2767 | ret = mov_read_default(c, &ctx, atom); |
||
2768 | free_and_return: |
||
2769 | av_free(moov_data); |
||
2770 | av_free(cmov_data); |
||
2771 | return ret; |
||
2772 | #else |
||
2773 | av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n"); |
||
2774 | return AVERROR(ENOSYS); |
||
2775 | #endif |
||
2776 | } |
||
2777 | |||
2778 | /* edit list atom */ |
||
2779 | static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2780 | { |
||
2781 | MOVStreamContext *sc; |
||
2782 | int i, edit_count, version, edit_start_index = 0; |
||
2783 | int unsupported = 0; |
||
2784 | |||
2785 | if (c->fc->nb_streams < 1 || c->ignore_editlist) |
||
2786 | return 0; |
||
2787 | sc = c->fc->streams[c->fc->nb_streams-1]->priv_data; |
||
2788 | |||
2789 | version = avio_r8(pb); /* version */ |
||
2790 | avio_rb24(pb); /* flags */ |
||
2791 | edit_count = avio_rb32(pb); /* entries */ |
||
2792 | |||
2793 | if ((uint64_t)edit_count*12+8 > atom.size) |
||
2794 | return AVERROR_INVALIDDATA; |
||
2795 | |||
2796 | av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count); |
||
2797 | for (i=0; i |
||
2798 | int64_t time; |
||
2799 | int64_t duration; |
||
2800 | int rate; |
||
2801 | if (version == 1) { |
||
2802 | duration = avio_rb64(pb); |
||
2803 | time = avio_rb64(pb); |
||
2804 | } else { |
||
2805 | duration = avio_rb32(pb); /* segment duration */ |
||
2806 | time = (int32_t)avio_rb32(pb); /* media time */ |
||
2807 | } |
||
2808 | rate = avio_rb32(pb); |
||
2809 | if (i == 0 && time == -1) { |
||
2810 | sc->empty_duration = duration; |
||
2811 | edit_start_index = 1; |
||
2812 | } else if (i == edit_start_index && time >= 0) |
||
2813 | sc->start_time = time; |
||
2814 | else |
||
2815 | unsupported = 1; |
||
2816 | |||
2817 | av_dlog(c->fc, "duration=%"PRId64" time=%"PRId64" rate=%f\n", |
||
2818 | duration, time, rate / 65536.0); |
||
2819 | } |
||
2820 | |||
2821 | if (unsupported) |
||
2822 | av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, " |
||
2823 | "a/v desync might occur, patch welcome\n"); |
||
2824 | |||
2825 | return 0; |
||
2826 | } |
||
2827 | |||
2828 | static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2829 | { |
||
2830 | MOVStreamContext *sc; |
||
2831 | |||
2832 | if (c->fc->nb_streams < 1) |
||
2833 | return AVERROR_INVALIDDATA; |
||
2834 | sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data; |
||
2835 | sc->timecode_track = avio_rb32(pb); |
||
2836 | return 0; |
||
2837 | } |
||
2838 | |||
2839 | static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2840 | { |
||
2841 | int ret; |
||
2842 | uint8_t uuid[16]; |
||
2843 | static const uint8_t uuid_isml_manifest[] = { |
||
2844 | 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd, |
||
2845 | 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 |
||
2846 | }; |
||
2847 | |||
2848 | if (atom.size < sizeof(uuid) || atom.size == INT64_MAX) |
||
2849 | return AVERROR_INVALIDDATA; |
||
2850 | |||
2851 | ret = avio_read(pb, uuid, sizeof(uuid)); |
||
2852 | if (ret < 0) { |
||
2853 | return ret; |
||
2854 | } else if (ret != sizeof(uuid)) { |
||
2855 | return AVERROR_INVALIDDATA; |
||
2856 | } |
||
2857 | if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) { |
||
2858 | uint8_t *buffer, *ptr; |
||
2859 | char *endptr; |
||
2860 | size_t len = atom.size - sizeof(uuid); |
||
2861 | |||
2862 | if (len < 4) { |
||
2863 | return AVERROR_INVALIDDATA; |
||
2864 | } |
||
2865 | ret = avio_skip(pb, 4); // zeroes |
||
2866 | len -= 4; |
||
2867 | |||
2868 | buffer = av_mallocz(len + 1); |
||
2869 | if (!buffer) { |
||
2870 | return AVERROR(ENOMEM); |
||
2871 | } |
||
2872 | ret = avio_read(pb, buffer, len); |
||
2873 | if (ret < 0) { |
||
2874 | av_free(buffer); |
||
2875 | return ret; |
||
2876 | } else if (ret != len) { |
||
2877 | av_free(buffer); |
||
2878 | return AVERROR_INVALIDDATA; |
||
2879 | } |
||
2880 | |||
2881 | ptr = buffer; |
||
2882 | while ((ptr = av_stristr(ptr, "systemBitrate=\"")) != NULL) { |
||
2883 | ptr += sizeof("systemBitrate=\"") - 1; |
||
2884 | c->bitrates_count++; |
||
2885 | c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates)); |
||
2886 | if (!c->bitrates) { |
||
2887 | c->bitrates_count = 0; |
||
2888 | av_free(buffer); |
||
2889 | return AVERROR(ENOMEM); |
||
2890 | } |
||
2891 | errno = 0; |
||
2892 | ret = strtol(ptr, &endptr, 10); |
||
2893 | if (ret < 0 || errno || *endptr != '"') { |
||
2894 | c->bitrates[c->bitrates_count - 1] = 0; |
||
2895 | } else { |
||
2896 | c->bitrates[c->bitrates_count - 1] = ret; |
||
2897 | } |
||
2898 | } |
||
2899 | |||
2900 | av_free(buffer); |
||
2901 | } |
||
2902 | return 0; |
||
2903 | } |
||
2904 | |||
2905 | static const MOVParseTableEntry mov_default_parse_table[] = { |
||
2906 | { MKTAG('A','C','L','R'), mov_read_avid }, |
||
2907 | { MKTAG('A','P','R','G'), mov_read_avid }, |
||
2908 | { MKTAG('A','A','L','P'), mov_read_avid }, |
||
2909 | { MKTAG('A','R','E','S'), mov_read_ares }, |
||
2910 | { MKTAG('a','v','s','s'), mov_read_avss }, |
||
2911 | { MKTAG('c','h','p','l'), mov_read_chpl }, |
||
2912 | { MKTAG('c','o','6','4'), mov_read_stco }, |
||
2913 | { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ |
||
2914 | { MKTAG('d','i','n','f'), mov_read_default }, |
||
2915 | { MKTAG('d','r','e','f'), mov_read_dref }, |
||
2916 | { MKTAG('e','d','t','s'), mov_read_default }, |
||
2917 | { MKTAG('e','l','s','t'), mov_read_elst }, |
||
2918 | { MKTAG('e','n','d','a'), mov_read_enda }, |
||
2919 | { MKTAG('f','i','e','l'), mov_read_fiel }, |
||
2920 | { MKTAG('f','t','y','p'), mov_read_ftyp }, |
||
2921 | { MKTAG('g','l','b','l'), mov_read_glbl }, |
||
2922 | { MKTAG('h','d','l','r'), mov_read_hdlr }, |
||
2923 | { MKTAG('i','l','s','t'), mov_read_ilst }, |
||
2924 | { MKTAG('j','p','2','h'), mov_read_jp2h }, |
||
2925 | { MKTAG('m','d','a','t'), mov_read_mdat }, |
||
2926 | { MKTAG('m','d','h','d'), mov_read_mdhd }, |
||
2927 | { MKTAG('m','d','i','a'), mov_read_default }, |
||
2928 | { MKTAG('m','e','t','a'), mov_read_meta }, |
||
2929 | { MKTAG('m','i','n','f'), mov_read_default }, |
||
2930 | { MKTAG('m','o','o','f'), mov_read_moof }, |
||
2931 | { MKTAG('m','o','o','v'), mov_read_moov }, |
||
2932 | { MKTAG('m','v','e','x'), mov_read_default }, |
||
2933 | { MKTAG('m','v','h','d'), mov_read_mvhd }, |
||
2934 | { MKTAG('S','M','I',' '), mov_read_svq3 }, |
||
2935 | { MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */ |
||
2936 | { MKTAG('a','v','c','C'), mov_read_glbl }, |
||
2937 | { MKTAG('p','a','s','p'), mov_read_pasp }, |
||
2938 | { MKTAG('s','t','b','l'), mov_read_default }, |
||
2939 | { MKTAG('s','t','c','o'), mov_read_stco }, |
||
2940 | { MKTAG('s','t','p','s'), mov_read_stps }, |
||
2941 | { MKTAG('s','t','r','f'), mov_read_strf }, |
||
2942 | { MKTAG('s','t','s','c'), mov_read_stsc }, |
||
2943 | { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */ |
||
2944 | { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ |
||
2945 | { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */ |
||
2946 | { MKTAG('s','t','t','s'), mov_read_stts }, |
||
2947 | { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */ |
||
2948 | { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */ |
||
2949 | { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */ |
||
2950 | { MKTAG('t','r','a','k'), mov_read_trak }, |
||
2951 | { MKTAG('t','r','a','f'), mov_read_default }, |
||
2952 | { MKTAG('t','r','e','f'), mov_read_default }, |
||
2953 | { MKTAG('t','m','c','d'), mov_read_tmcd }, |
||
2954 | { MKTAG('c','h','a','p'), mov_read_chap }, |
||
2955 | { MKTAG('t','r','e','x'), mov_read_trex }, |
||
2956 | { MKTAG('t','r','u','n'), mov_read_trun }, |
||
2957 | { MKTAG('u','d','t','a'), mov_read_default }, |
||
2958 | { MKTAG('w','a','v','e'), mov_read_wave }, |
||
2959 | { MKTAG('e','s','d','s'), mov_read_esds }, |
||
2960 | { MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */ |
||
2961 | { MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */ |
||
2962 | { MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */ |
||
2963 | { MKTAG('w','f','e','x'), mov_read_wfex }, |
||
2964 | { MKTAG('c','m','o','v'), mov_read_cmov }, |
||
2965 | { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */ |
||
2966 | { MKTAG('d','v','c','1'), mov_read_dvc1 }, |
||
2967 | { MKTAG('s','b','g','p'), mov_read_sbgp }, |
||
2968 | { MKTAG('h','v','c','C'), mov_read_glbl }, |
||
2969 | { MKTAG('u','u','i','d'), mov_read_uuid }, |
||
2970 | { MKTAG('C','i','n', 0x8e), mov_read_targa_y216 }, |
||
2971 | { 0, NULL } |
||
2972 | }; |
||
2973 | |||
2974 | static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) |
||
2975 | { |
||
2976 | int64_t total_size = 0; |
||
2977 | MOVAtom a; |
||
2978 | int i; |
||
2979 | |||
2980 | if (atom.size < 0) |
||
2981 | atom.size = INT64_MAX; |
||
2982 | while (total_size + 8 <= atom.size && !url_feof(pb)) { |
||
2983 | int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL; |
||
2984 | a.size = atom.size; |
||
2985 | a.type=0; |
||
2986 | if (atom.size >= 8) { |
||
2987 | a.size = avio_rb32(pb); |
||
2988 | a.type = avio_rl32(pb); |
||
2989 | if (atom.type != MKTAG('r','o','o','t') && |
||
2990 | atom.type != MKTAG('m','o','o','v')) |
||
2991 | { |
||
2992 | if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) |
||
2993 | { |
||
2994 | av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); |
||
2995 | avio_skip(pb, -8); |
||
2996 | return 0; |
||
2997 | } |
||
2998 | } |
||
2999 | total_size += 8; |
||
3000 | if (a.size == 1) { /* 64 bit extended size */ |
||
3001 | a.size = avio_rb64(pb) - 8; |
||
3002 | total_size += 8; |
||
3003 | } |
||
3004 | } |
||
3005 | av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", |
||
3006 | a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); |
||
3007 | if (a.size == 0) { |
||
3008 | a.size = atom.size - total_size + 8; |
||
3009 | } |
||
3010 | a.size -= 8; |
||
3011 | if (a.size < 0) |
||
3012 | break; |
||
3013 | a.size = FFMIN(a.size, atom.size - total_size); |
||
3014 | |||
3015 | for (i = 0; mov_default_parse_table[i].type; i++) |
||
3016 | if (mov_default_parse_table[i].type == a.type) { |
||
3017 | parse = mov_default_parse_table[i].parse; |
||
3018 | break; |
||
3019 | } |
||
3020 | |||
3021 | // container is user data |
||
3022 | if (!parse && (atom.type == MKTAG('u','d','t','a') || |
||
3023 | atom.type == MKTAG('i','l','s','t'))) |
||
3024 | parse = mov_read_udta_string; |
||
3025 | |||
3026 | if (!parse) { /* skip leaf atoms data */ |
||
3027 | avio_skip(pb, a.size); |
||
3028 | } else { |
||
3029 | int64_t start_pos = avio_tell(pb); |
||
3030 | int64_t left; |
||
3031 | int err = parse(c, pb, a); |
||
3032 | if (err < 0) |
||
3033 | return err; |
||
3034 | if (c->found_moov && c->found_mdat && |
||
3035 | ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || |
||
3036 | start_pos + a.size == avio_size(pb))) { |
||
3037 | if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) |
||
3038 | c->next_root_atom = start_pos + a.size; |
||
3039 | return 0; |
||
3040 | } |
||
3041 | left = a.size - avio_tell(pb) + start_pos; |
||
3042 | if (left > 0) /* skip garbage at atom end */ |
||
3043 | avio_skip(pb, left); |
||
3044 | else if (left < 0) { |
||
3045 | av_log(c->fc, AV_LOG_WARNING, |
||
3046 | "overread end of atom '%.4s' by %"PRId64" bytes\n", |
||
3047 | (char*)&a.type, -left); |
||
3048 | avio_seek(pb, left, SEEK_CUR); |
||
3049 | } |
||
3050 | } |
||
3051 | |||
3052 | total_size += a.size; |
||
3053 | } |
||
3054 | |||
3055 | if (total_size < atom.size && atom.size < 0x7ffff) |
||
3056 | avio_skip(pb, atom.size - total_size); |
||
3057 | |||
3058 | return 0; |
||
3059 | } |
||
3060 | |||
3061 | static int mov_probe(AVProbeData *p) |
||
3062 | { |
||
3063 | int64_t offset; |
||
3064 | uint32_t tag; |
||
3065 | int score = 0; |
||
3066 | int moov_offset = -1; |
||
3067 | |||
3068 | /* check file header */ |
||
3069 | offset = 0; |
||
3070 | for (;;) { |
||
3071 | /* ignore invalid offset */ |
||
3072 | if ((offset + 8) > (unsigned int)p->buf_size) |
||
3073 | break; |
||
3074 | tag = AV_RL32(p->buf + offset + 4); |
||
3075 | switch(tag) { |
||
3076 | /* check for obvious tags */ |
||
3077 | case MKTAG('m','o','o','v'): |
||
3078 | moov_offset = offset + 4; |
||
3079 | case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */ |
||
3080 | case MKTAG('m','d','a','t'): |
||
3081 | case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ |
||
3082 | case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ |
||
3083 | case MKTAG('f','t','y','p'): |
||
3084 | if (AV_RB32(p->buf+offset) < 8 && |
||
3085 | (AV_RB32(p->buf+offset) != 1 || |
||
3086 | offset + 12 > (unsigned int)p->buf_size || |
||
3087 | AV_RB64(p->buf+offset + 8) == 0)) { |
||
3088 | score = FFMAX(score, AVPROBE_SCORE_EXTENSION); |
||
3089 | } else { |
||
3090 | score = AVPROBE_SCORE_MAX; |
||
3091 | } |
||
3092 | offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; |
||
3093 | break; |
||
3094 | /* those are more common words, so rate then a bit less */ |
||
3095 | case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ |
||
3096 | case MKTAG('w','i','d','e'): |
||
3097 | case MKTAG('f','r','e','e'): |
||
3098 | case MKTAG('j','u','n','k'): |
||
3099 | case MKTAG('p','i','c','t'): |
||
3100 | score = FFMAX(score, AVPROBE_SCORE_MAX - 5); |
||
3101 | offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; |
||
3102 | break; |
||
3103 | case MKTAG(0x82,0x82,0x7f,0x7d): |
||
3104 | case MKTAG('s','k','i','p'): |
||
3105 | case MKTAG('u','u','i','d'): |
||
3106 | case MKTAG('p','r','f','l'): |
||
3107 | /* if we only find those cause probedata is too small at least rate them */ |
||
3108 | score = FFMAX(score, AVPROBE_SCORE_EXTENSION); |
||
3109 | offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; |
||
3110 | break; |
||
3111 | default: |
||
3112 | offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; |
||
3113 | } |
||
3114 | } |
||
3115 | if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { |
||
3116 | /* moov atom in the header - we should make sure that this is not a |
||
3117 | * MOV-packed MPEG-PS */ |
||
3118 | offset = moov_offset; |
||
3119 | |||
3120 | while(offset < (p->buf_size - 16)){ /* Sufficient space */ |
||
3121 | /* We found an actual hdlr atom */ |
||
3122 | if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && |
||
3123 | AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && |
||
3124 | AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){ |
||
3125 | av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n"); |
||
3126 | /* We found a media handler reference atom describing an |
||
3127 | * MPEG-PS-in-MOV, return a |
||
3128 | * low score to force expanding the probe window until |
||
3129 | * mpegps_probe finds what it needs */ |
||
3130 | return 5; |
||
3131 | }else |
||
3132 | /* Keep looking */ |
||
3133 | offset+=2; |
||
3134 | } |
||
3135 | } |
||
3136 | |||
3137 | return score; |
||
3138 | } |
||
3139 | |||
3140 | // must be done after parsing all trak because there's no order requirement |
||
3141 | static void mov_read_chapters(AVFormatContext *s) |
||
3142 | { |
||
3143 | MOVContext *mov = s->priv_data; |
||
3144 | AVStream *st = NULL; |
||
3145 | MOVStreamContext *sc; |
||
3146 | int64_t cur_pos; |
||
3147 | int i; |
||
3148 | |||
3149 | for (i = 0; i < s->nb_streams; i++) |
||
3150 | if (s->streams[i]->id == mov->chapter_track) { |
||
3151 | st = s->streams[i]; |
||
3152 | break; |
||
3153 | } |
||
3154 | if (!st) { |
||
3155 | av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); |
||
3156 | return; |
||
3157 | } |
||
3158 | |||
3159 | st->discard = AVDISCARD_ALL; |
||
3160 | sc = st->priv_data; |
||
3161 | cur_pos = avio_tell(sc->pb); |
||
3162 | |||
3163 | for (i = 0; i < st->nb_index_entries; i++) { |
||
3164 | AVIndexEntry *sample = &st->index_entries[i]; |
||
3165 | int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration; |
||
3166 | uint8_t *title; |
||
3167 | uint16_t ch; |
||
3168 | int len, title_len; |
||
3169 | |||
3170 | if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { |
||
3171 | av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i); |
||
3172 | goto finish; |
||
3173 | } |
||
3174 | |||
3175 | // the first two bytes are the length of the title |
||
3176 | len = avio_rb16(sc->pb); |
||
3177 | if (len > sample->size-2) |
||
3178 | continue; |
||
3179 | title_len = 2*len + 1; |
||
3180 | if (!(title = av_mallocz(title_len))) |
||
3181 | goto finish; |
||
3182 | |||
3183 | // The samples could theoretically be in any encoding if there's an encd |
||
3184 | // atom following, but in practice are only utf-8 or utf-16, distinguished |
||
3185 | // instead by the presence of a BOM |
||
3186 | if (!len) { |
||
3187 | title[0] = 0; |
||
3188 | } else { |
||
3189 | ch = avio_rb16(sc->pb); |
||
3190 | if (ch == 0xfeff) |
||
3191 | avio_get_str16be(sc->pb, len, title, title_len); |
||
3192 | else if (ch == 0xfffe) |
||
3193 | avio_get_str16le(sc->pb, len, title, title_len); |
||
3194 | else { |
||
3195 | AV_WB16(title, ch); |
||
3196 | if (len == 1 || len == 2) |
||
3197 | title[len] = 0; |
||
3198 | else |
||
3199 | avio_get_str(sc->pb, INT_MAX, title + 2, len - 1); |
||
3200 | } |
||
3201 | } |
||
3202 | |||
3203 | avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title); |
||
3204 | av_freep(&title); |
||
3205 | } |
||
3206 | finish: |
||
3207 | avio_seek(sc->pb, cur_pos, SEEK_SET); |
||
3208 | } |
||
3209 | |||
3210 | static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, |
||
3211 | uint32_t value, int flags) |
||
3212 | { |
||
3213 | AVTimecode tc; |
||
3214 | char buf[AV_TIMECODE_STR_SIZE]; |
||
3215 | AVRational rate = {st->codec->time_base.den, |
||
3216 | st->codec->time_base.num}; |
||
3217 | int ret = av_timecode_init(&tc, rate, flags, 0, s); |
||
3218 | if (ret < 0) |
||
3219 | return ret; |
||
3220 | av_dict_set(&st->metadata, "timecode", |
||
3221 | av_timecode_make_string(&tc, buf, value), 0); |
||
3222 | return 0; |
||
3223 | } |
||
3224 | |||
3225 | static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) |
||
3226 | { |
||
3227 | MOVStreamContext *sc = st->priv_data; |
||
3228 | int flags = 0; |
||
3229 | int64_t cur_pos = avio_tell(sc->pb); |
||
3230 | uint32_t value; |
||
3231 | |||
3232 | if (!st->nb_index_entries) |
||
3233 | return -1; |
||
3234 | |||
3235 | avio_seek(sc->pb, st->index_entries->pos, SEEK_SET); |
||
3236 | value = avio_rb32(s->pb); |
||
3237 | |||
3238 | if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME; |
||
3239 | if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX; |
||
3240 | if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE; |
||
3241 | |||
3242 | /* Assume Counter flag is set to 1 in tmcd track (even though it is likely |
||
3243 | * not the case) and thus assume "frame number format" instead of QT one. |
||
3244 | * No sample with tmcd track can be found with a QT timecode at the moment, |
||
3245 | * despite what the tmcd track "suggests" (Counter flag set to 0 means QT |
||
3246 | * format). */ |
||
3247 | parse_timecode_in_framenum_format(s, st, value, flags); |
||
3248 | |||
3249 | avio_seek(sc->pb, cur_pos, SEEK_SET); |
||
3250 | return 0; |
||
3251 | } |
||
3252 | |||
3253 | static int mov_read_close(AVFormatContext *s) |
||
3254 | { |
||
3255 | MOVContext *mov = s->priv_data; |
||
3256 | int i, j; |
||
3257 | |||
3258 | for (i = 0; i < s->nb_streams; i++) { |
||
3259 | AVStream *st = s->streams[i]; |
||
3260 | MOVStreamContext *sc = st->priv_data; |
||
3261 | |||
3262 | av_freep(&sc->ctts_data); |
||
3263 | for (j = 0; j < sc->drefs_count; j++) { |
||
3264 | av_freep(&sc->drefs[j].path); |
||
3265 | av_freep(&sc->drefs[j].dir); |
||
3266 | } |
||
3267 | av_freep(&sc->drefs); |
||
3268 | if (!sc->pb_is_copied) |
||
3269 | avio_close(sc->pb); |
||
3270 | sc->pb = NULL; |
||
3271 | av_freep(&sc->chunk_offsets); |
||
3272 | av_freep(&sc->keyframes); |
||
3273 | av_freep(&sc->sample_sizes); |
||
3274 | av_freep(&sc->stps_data); |
||
3275 | av_freep(&sc->stsc_data); |
||
3276 | av_freep(&sc->stts_data); |
||
3277 | } |
||
3278 | |||
3279 | if (mov->dv_demux) { |
||
3280 | for (i = 0; i < mov->dv_fctx->nb_streams; i++) { |
||
3281 | av_freep(&mov->dv_fctx->streams[i]->codec); |
||
3282 | av_freep(&mov->dv_fctx->streams[i]); |
||
3283 | } |
||
3284 | av_freep(&mov->dv_fctx); |
||
3285 | av_freep(&mov->dv_demux); |
||
3286 | } |
||
3287 | |||
3288 | av_freep(&mov->trex_data); |
||
3289 | av_freep(&mov->bitrates); |
||
3290 | |||
3291 | return 0; |
||
3292 | } |
||
3293 | |||
3294 | static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id) |
||
3295 | { |
||
3296 | int i; |
||
3297 | |||
3298 | for (i = 0; i < s->nb_streams; i++) { |
||
3299 | AVStream *st = s->streams[i]; |
||
3300 | MOVStreamContext *sc = st->priv_data; |
||
3301 | |||
3302 | if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && |
||
3303 | sc->timecode_track == tmcd_id) |
||
3304 | return 1; |
||
3305 | } |
||
3306 | return 0; |
||
3307 | } |
||
3308 | |||
3309 | /* look for a tmcd track not referenced by any video track, and export it globally */ |
||
3310 | static void export_orphan_timecode(AVFormatContext *s) |
||
3311 | { |
||
3312 | int i; |
||
3313 | |||
3314 | for (i = 0; i < s->nb_streams; i++) { |
||
3315 | AVStream *st = s->streams[i]; |
||
3316 | |||
3317 | if (st->codec->codec_tag == MKTAG('t','m','c','d') && |
||
3318 | !tmcd_is_referenced(s, i + 1)) { |
||
3319 | AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0); |
||
3320 | if (tcr) { |
||
3321 | av_dict_set(&s->metadata, "timecode", tcr->value, 0); |
||
3322 | break; |
||
3323 | } |
||
3324 | } |
||
3325 | } |
||
3326 | } |
||
3327 | |||
3328 | static int mov_read_header(AVFormatContext *s) |
||
3329 | { |
||
3330 | MOVContext *mov = s->priv_data; |
||
3331 | AVIOContext *pb = s->pb; |
||
3332 | int i, j, err; |
||
3333 | MOVAtom atom = { AV_RL32("root") }; |
||
3334 | |||
3335 | mov->fc = s; |
||
3336 | /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */ |
||
3337 | if (pb->seekable) |
||
3338 | atom.size = avio_size(pb); |
||
3339 | else |
||
3340 | atom.size = INT64_MAX; |
||
3341 | |||
3342 | /* check MOV header */ |
||
3343 | if ((err = mov_read_default(mov, pb, atom)) < 0) { |
||
3344 | av_log(s, AV_LOG_ERROR, "error reading header: %d\n", err); |
||
3345 | mov_read_close(s); |
||
3346 | return err; |
||
3347 | } |
||
3348 | if (!mov->found_moov) { |
||
3349 | av_log(s, AV_LOG_ERROR, "moov atom not found\n"); |
||
3350 | mov_read_close(s); |
||
3351 | return AVERROR_INVALIDDATA; |
||
3352 | } |
||
3353 | av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); |
||
3354 | |||
3355 | if (pb->seekable) { |
||
3356 | if (mov->chapter_track > 0) |
||
3357 | mov_read_chapters(s); |
||
3358 | for (i = 0; i < s->nb_streams; i++) |
||
3359 | if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd")) |
||
3360 | mov_read_timecode_track(s, s->streams[i]); |
||
3361 | } |
||
3362 | |||
3363 | /* copy timecode metadata from tmcd tracks to the related video streams */ |
||
3364 | for (i = 0; i < s->nb_streams; i++) { |
||
3365 | AVStream *st = s->streams[i]; |
||
3366 | MOVStreamContext *sc = st->priv_data; |
||
3367 | if (sc->timecode_track > 0) { |
||
3368 | AVDictionaryEntry *tcr; |
||
3369 | int tmcd_st_id = -1; |
||
3370 | |||
3371 | for (j = 0; j < s->nb_streams; j++) |
||
3372 | if (s->streams[j]->id == sc->timecode_track) |
||
3373 | tmcd_st_id = j; |
||
3374 | |||
3375 | if (tmcd_st_id < 0 || tmcd_st_id == i) |
||
3376 | continue; |
||
3377 | tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0); |
||
3378 | if (tcr) |
||
3379 | av_dict_set(&st->metadata, "timecode", tcr->value, 0); |
||
3380 | } |
||
3381 | } |
||
3382 | export_orphan_timecode(s); |
||
3383 | |||
3384 | for (i = 0; i < s->nb_streams; i++) { |
||
3385 | AVStream *st = s->streams[i]; |
||
3386 | MOVStreamContext *sc = st->priv_data; |
||
3387 | fix_timescale(mov, sc); |
||
3388 | if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) { |
||
3389 | st->skip_samples = sc->start_pad; |
||
3390 | } |
||
3391 | } |
||
3392 | |||
3393 | if (mov->trex_data) { |
||
3394 | for (i = 0; i < s->nb_streams; i++) { |
||
3395 | AVStream *st = s->streams[i]; |
||
3396 | MOVStreamContext *sc = st->priv_data; |
||
3397 | if (st->duration > 0) |
||
3398 | st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration; |
||
3399 | } |
||
3400 | } |
||
3401 | |||
3402 | for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) { |
||
3403 | if (mov->bitrates[i]) { |
||
3404 | s->streams[i]->codec->bit_rate = mov->bitrates[i]; |
||
3405 | } |
||
3406 | } |
||
3407 | |||
3408 | return 0; |
||
3409 | } |
||
3410 | |||
3411 | static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) |
||
3412 | { |
||
3413 | AVIndexEntry *sample = NULL; |
||
3414 | int64_t best_dts = INT64_MAX; |
||
3415 | int i; |
||
3416 | for (i = 0; i < s->nb_streams; i++) { |
||
3417 | AVStream *avst = s->streams[i]; |
||
3418 | MOVStreamContext *msc = avst->priv_data; |
||
3419 | if (msc->pb && msc->current_sample < avst->nb_index_entries) { |
||
3420 | AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; |
||
3421 | int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); |
||
3422 | av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); |
||
3423 | if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) || |
||
3424 | (s->pb->seekable && |
||
3425 | ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && |
||
3426 | ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || |
||
3427 | (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { |
||
3428 | sample = current_sample; |
||
3429 | best_dts = dts; |
||
3430 | *st = avst; |
||
3431 | } |
||
3432 | } |
||
3433 | } |
||
3434 | return sample; |
||
3435 | } |
||
3436 | |||
3437 | static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) |
||
3438 | { |
||
3439 | MOVContext *mov = s->priv_data; |
||
3440 | MOVStreamContext *sc; |
||
3441 | AVIndexEntry *sample; |
||
3442 | AVStream *st = NULL; |
||
3443 | int ret; |
||
3444 | mov->fc = s; |
||
3445 | retry: |
||
3446 | sample = mov_find_next_sample(s, &st); |
||
3447 | if (!sample) { |
||
3448 | mov->found_mdat = 0; |
||
3449 | if (!mov->next_root_atom) |
||
3450 | return AVERROR_EOF; |
||
3451 | avio_seek(s->pb, mov->next_root_atom, SEEK_SET); |
||
3452 | mov->next_root_atom = 0; |
||
3453 | if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 || |
||
3454 | url_feof(s->pb)) |
||
3455 | return AVERROR_EOF; |
||
3456 | av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb)); |
||
3457 | goto retry; |
||
3458 | } |
||
3459 | sc = st->priv_data; |
||
3460 | /* must be done just before reading, to avoid infinite loop on sample */ |
||
3461 | sc->current_sample++; |
||
3462 | |||
3463 | if (mov->next_root_atom) { |
||
3464 | sample->pos = FFMIN(sample->pos, mov->next_root_atom); |
||
3465 | sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos)); |
||
3466 | } |
||
3467 | |||
3468 | if (st->discard != AVDISCARD_ALL) { |
||
3469 | if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { |
||
3470 | av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n", |
||
3471 | sc->ffindex, sample->pos); |
||
3472 | return AVERROR_INVALIDDATA; |
||
3473 | } |
||
3474 | ret = av_get_packet(sc->pb, pkt, sample->size); |
||
3475 | if (ret < 0) |
||
3476 | return ret; |
||
3477 | if (sc->has_palette) { |
||
3478 | uint8_t *pal; |
||
3479 | |||
3480 | pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); |
||
3481 | if (!pal) { |
||
3482 | av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n"); |
||
3483 | } else { |
||
3484 | memcpy(pal, sc->palette, AVPALETTE_SIZE); |
||
3485 | sc->has_palette = 0; |
||
3486 | } |
||
3487 | } |
||
3488 | #if CONFIG_DV_DEMUXER |
||
3489 | if (mov->dv_demux && sc->dv_audio_container) { |
||
3490 | avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); |
||
3491 | av_free(pkt->data); |
||
3492 | pkt->size = 0; |
||
3493 | ret = avpriv_dv_get_packet(mov->dv_demux, pkt); |
||
3494 | if (ret < 0) |
||
3495 | return ret; |
||
3496 | } |
||
3497 | #endif |
||
3498 | } |
||
3499 | |||
3500 | pkt->stream_index = sc->ffindex; |
||
3501 | pkt->dts = sample->timestamp; |
||
3502 | if (sc->ctts_data && sc->ctts_index < sc->ctts_count) { |
||
3503 | pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration; |
||
3504 | /* update ctts context */ |
||
3505 | sc->ctts_sample++; |
||
3506 | if (sc->ctts_index < sc->ctts_count && |
||
3507 | sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) { |
||
3508 | sc->ctts_index++; |
||
3509 | sc->ctts_sample = 0; |
||
3510 | } |
||
3511 | if (sc->wrong_dts) |
||
3512 | pkt->dts = AV_NOPTS_VALUE; |
||
3513 | } else { |
||
3514 | int64_t next_dts = (sc->current_sample < st->nb_index_entries) ? |
||
3515 | st->index_entries[sc->current_sample].timestamp : st->duration; |
||
3516 | pkt->duration = next_dts - pkt->dts; |
||
3517 | pkt->pts = pkt->dts; |
||
3518 | } |
||
3519 | if (st->discard == AVDISCARD_ALL) |
||
3520 | goto retry; |
||
3521 | pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0; |
||
3522 | pkt->pos = sample->pos; |
||
3523 | av_dlog(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n", |
||
3524 | pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration); |
||
3525 | return 0; |
||
3526 | } |
||
3527 | |||
3528 | static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags) |
||
3529 | { |
||
3530 | MOVStreamContext *sc = st->priv_data; |
||
3531 | int sample, time_sample; |
||
3532 | int i; |
||
3533 | |||
3534 | sample = av_index_search_timestamp(st, timestamp, flags); |
||
3535 | av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample); |
||
3536 | if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) |
||
3537 | sample = 0; |
||
3538 | if (sample < 0) /* not sure what to do */ |
||
3539 | return AVERROR_INVALIDDATA; |
||
3540 | sc->current_sample = sample; |
||
3541 | av_dlog(s, "stream %d, found sample %d\n", st->index, sc->current_sample); |
||
3542 | /* adjust ctts index */ |
||
3543 | if (sc->ctts_data) { |
||
3544 | time_sample = 0; |
||
3545 | for (i = 0; i < sc->ctts_count; i++) { |
||
3546 | int next = time_sample + sc->ctts_data[i].count; |
||
3547 | if (next > sc->current_sample) { |
||
3548 | sc->ctts_index = i; |
||
3549 | sc->ctts_sample = sc->current_sample - time_sample; |
||
3550 | break; |
||
3551 | } |
||
3552 | time_sample = next; |
||
3553 | } |
||
3554 | } |
||
3555 | return sample; |
||
3556 | } |
||
3557 | |||
3558 | static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) |
||
3559 | { |
||
3560 | AVStream *st; |
||
3561 | int64_t seek_timestamp, timestamp; |
||
3562 | int sample; |
||
3563 | int i; |
||
3564 | |||
3565 | if (stream_index >= s->nb_streams) |
||
3566 | return AVERROR_INVALIDDATA; |
||
3567 | |||
3568 | st = s->streams[stream_index]; |
||
3569 | sample = mov_seek_stream(s, st, sample_time, flags); |
||
3570 | if (sample < 0) |
||
3571 | return sample; |
||
3572 | |||
3573 | /* adjust seek timestamp to found sample timestamp */ |
||
3574 | seek_timestamp = st->index_entries[sample].timestamp; |
||
3575 | |||
3576 | for (i = 0; i < s->nb_streams; i++) { |
||
3577 | MOVStreamContext *sc = s->streams[i]->priv_data; |
||
3578 | st = s->streams[i]; |
||
3579 | st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; |
||
3580 | |||
3581 | if (stream_index == i) |
||
3582 | continue; |
||
3583 | |||
3584 | timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); |
||
3585 | mov_seek_stream(s, st, timestamp, flags); |
||
3586 | } |
||
3587 | return 0; |
||
3588 | } |
||
3589 | |||
3590 | static const AVOption options[] = { |
||
3591 | {"use_absolute_path", |
||
3592 | "allow using absolute path when opening alias, this is a possible security issue", |
||
3593 | offsetof(MOVContext, use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0}, |
||
3594 | 0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM}, |
||
3595 | {"ignore_editlist", "", offsetof(MOVContext, ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0}, |
||
3596 | 0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM}, |
||
3597 | {NULL} |
||
3598 | }; |
||
3599 | |||
3600 | static const AVClass mov_class = { |
||
3601 | .class_name = "mov,mp4,m4a,3gp,3g2,mj2", |
||
3602 | .item_name = av_default_item_name, |
||
3603 | .option = options, |
||
3604 | .version = LIBAVUTIL_VERSION_INT, |
||
3605 | }; |
||
3606 | |||
3607 | AVInputFormat ff_mov_demuxer = { |
||
3608 | .name = "mov,mp4,m4a,3gp,3g2,mj2", |
||
3609 | .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"), |
||
3610 | .priv_data_size = sizeof(MOVContext), |
||
3611 | .read_probe = mov_probe, |
||
3612 | .read_header = mov_read_header, |
||
3613 | .read_packet = mov_read_packet, |
||
3614 | .read_close = mov_read_close, |
||
3615 | .read_seek = mov_read_seek, |
||
3616 | .priv_class = &mov_class, |
||
3617 | .flags = AVFMT_NO_BYTE_SEEK, |
||
3618 | };=>>>>>>>>>>>>>>>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>=>>>>>>>>>>>>>>>><>>16] |