OLD | NEW |
1 /* | 1 /* |
2 * MOV demuxer | 2 * MOV demuxer |
3 * Copyright (c) 2001 Fabrice Bellard | 3 * Copyright (c) 2001 Fabrice Bellard |
4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot co
m> | 4 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot co
m> |
5 * | 5 * |
6 * This file is part of FFmpeg. | 6 * This file is part of FFmpeg. |
7 * | 7 * |
8 * FFmpeg is free software; you can redistribute it and/or | 8 * FFmpeg is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Lesser General Public | 9 * modify it under the terms of the GNU Lesser General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 | 86 |
87 get_be16(pb); // unknown | 87 get_be16(pb); // unknown |
88 snprintf(buf, sizeof(buf), "%d", get_be16(pb)); | 88 snprintf(buf, sizeof(buf), "%d", get_be16(pb)); |
89 av_metadata_set(&c->fc->metadata, "track", buf); | 89 av_metadata_set(&c->fc->metadata, "track", buf); |
90 | 90 |
91 get_be16(pb); // total tracks | 91 get_be16(pb); // total tracks |
92 | 92 |
93 return 0; | 93 return 0; |
94 } | 94 } |
95 | 95 |
| 96 static const uint32_t mac_to_unicode[128] = { |
| 97 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, |
| 98 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, |
| 99 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3, |
| 100 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC, |
| 101 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF, |
| 102 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8, |
| 103 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211, |
| 104 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8, |
| 105 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB, |
| 106 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153, |
| 107 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA, |
| 108 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02, |
| 109 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1, |
| 110 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4, |
| 111 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC, |
| 112 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7, |
| 113 }; |
| 114 |
| 115 static int mov_read_mac_string(MOVContext *c, ByteIOContext *pb, int len, |
| 116 char *dst, int dstlen) |
| 117 { |
| 118 char *p = dst; |
| 119 char *end = dst+dstlen-1; |
| 120 int i; |
| 121 |
| 122 for (i = 0; i < len; i++) { |
| 123 uint8_t t, c = get_byte(pb); |
| 124 if (c < 0x80 && p < end) |
| 125 *p++ = c; |
| 126 else |
| 127 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); |
| 128 } |
| 129 *p = 0; |
| 130 return p - dst; |
| 131 } |
| 132 |
96 static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom) | 133 static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
97 { | 134 { |
98 #ifdef MOV_EXPORT_ALL_METADATA | 135 #ifdef MOV_EXPORT_ALL_METADATA |
99 char tmp_key[5]; | 136 char tmp_key[5]; |
100 #endif | 137 #endif |
101 char str[1024], key2[16], language[4] = {0}; | 138 char str[1024], key2[16], language[4] = {0}; |
102 const char *key = NULL; | 139 const char *key = NULL; |
103 uint16_t str_size; | 140 uint16_t str_size, langcode = 0; |
| 141 uint32_t data_type = 0; |
104 int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL; | 142 int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL; |
105 | 143 |
106 switch (atom.type) { | 144 switch (atom.type) { |
107 case MKTAG(0xa9,'n','a','m'): key = "title"; break; | 145 case MKTAG(0xa9,'n','a','m'): key = "title"; break; |
108 case MKTAG(0xa9,'a','u','t'): | 146 case MKTAG(0xa9,'a','u','t'): |
109 case MKTAG(0xa9,'A','R','T'): key = "author"; break; | 147 case MKTAG(0xa9,'A','R','T'): key = "author"; break; |
110 case MKTAG(0xa9,'w','r','t'): key = "composer"; break; | 148 case MKTAG(0xa9,'w','r','t'): key = "composer"; break; |
111 case MKTAG( 'c','p','r','t'): | 149 case MKTAG( 'c','p','r','t'): |
112 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break; | 150 case MKTAG(0xa9,'c','p','y'): key = "copyright"; break; |
113 case MKTAG(0xa9,'c','m','t'): | 151 case MKTAG(0xa9,'c','m','t'): |
114 case MKTAG(0xa9,'i','n','f'): key = "comment"; break; | 152 case MKTAG(0xa9,'i','n','f'): key = "comment"; break; |
115 case MKTAG(0xa9,'a','l','b'): key = "album"; break; | 153 case MKTAG(0xa9,'a','l','b'): key = "album"; break; |
116 case MKTAG(0xa9,'d','a','y'): key = "date"; break; | 154 case MKTAG(0xa9,'d','a','y'): key = "date"; break; |
117 case MKTAG(0xa9,'g','e','n'): key = "genre"; break; | 155 case MKTAG(0xa9,'g','e','n'): key = "genre"; break; |
118 case MKTAG(0xa9,'t','o','o'): | 156 case MKTAG(0xa9,'t','o','o'): |
119 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; | 157 case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; |
120 case MKTAG( 'd','e','s','c'): key = "description";break; | 158 case MKTAG( 'd','e','s','c'): key = "description";break; |
121 case MKTAG( 'l','d','e','s'): key = "synopsis"; break; | 159 case MKTAG( 'l','d','e','s'): key = "synopsis"; break; |
122 case MKTAG( 't','v','s','h'): key = "show"; break; | 160 case MKTAG( 't','v','s','h'): key = "show"; break; |
123 case MKTAG( 't','v','e','n'): key = "episode_id";break; | 161 case MKTAG( 't','v','e','n'): key = "episode_id";break; |
124 case MKTAG( 't','v','n','n'): key = "network"; break; | 162 case MKTAG( 't','v','n','n'): key = "network"; break; |
125 case MKTAG( 't','r','k','n'): key = "track"; | 163 case MKTAG( 't','r','k','n'): key = "track"; |
126 parse = mov_metadata_trkn; break; | 164 parse = mov_metadata_trkn; break; |
127 } | 165 } |
128 | 166 |
129 if (c->itunes_metadata && atom.size > 8) { | 167 if (c->itunes_metadata && atom.size > 8) { |
130 int data_size = get_be32(pb); | 168 int data_size = get_be32(pb); |
131 int tag = get_le32(pb); | 169 int tag = get_le32(pb); |
132 if (tag == MKTAG('d','a','t','a')) { | 170 if (tag == MKTAG('d','a','t','a')) { |
133 get_be32(pb); // type | 171 data_type = get_be32(pb); // type |
134 get_be32(pb); // unknown | 172 get_be32(pb); // unknown |
135 str_size = data_size - 16; | 173 str_size = data_size - 16; |
136 atom.size -= 16; | 174 atom.size -= 16; |
137 } else return 0; | 175 } else return 0; |
138 } else if (atom.size > 4 && key && !c->itunes_metadata) { | 176 } else if (atom.size > 4 && key && !c->itunes_metadata) { |
139 str_size = get_be16(pb); // string length | 177 str_size = get_be16(pb); // string length |
140 ff_mov_lang_to_iso639(get_be16(pb), language); | 178 langcode = get_be16(pb); |
| 179 ff_mov_lang_to_iso639(langcode, language); |
141 atom.size -= 4; | 180 atom.size -= 4; |
142 } else | 181 } else |
143 str_size = atom.size; | 182 str_size = atom.size; |
144 | 183 |
145 #ifdef MOV_EXPORT_ALL_METADATA | 184 #ifdef MOV_EXPORT_ALL_METADATA |
146 if (!key) { | 185 if (!key) { |
147 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); | 186 snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); |
148 key = tmp_key; | 187 key = tmp_key; |
149 } | 188 } |
150 #endif | 189 #endif |
151 | 190 |
152 if (!key) | 191 if (!key) |
153 return 0; | 192 return 0; |
154 if (atom.size < 0) | 193 if (atom.size < 0) |
155 return -1; | 194 return -1; |
156 | 195 |
157 str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); | 196 str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); |
158 | 197 |
159 if (parse) | 198 if (parse) |
160 parse(c, pb, str_size); | 199 parse(c, pb, str_size); |
161 else { | 200 else { |
162 get_buffer(pb, str, str_size); | 201 if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Enc
oded |
163 str[str_size] = 0; | 202 mov_read_mac_string(c, pb, str_size, str, sizeof(str)); |
| 203 } else { |
| 204 get_buffer(pb, str, str_size); |
| 205 str[str_size] = 0; |
| 206 } |
164 av_metadata_set(&c->fc->metadata, key, str); | 207 av_metadata_set(&c->fc->metadata, key, str); |
165 if (*language && strcmp(language, "und")) { | 208 if (*language && strcmp(language, "und")) { |
166 snprintf(key2, sizeof(key2), "%s-%s", key, language); | 209 snprintf(key2, sizeof(key2), "%s-%s", key, language); |
167 av_metadata_set(&c->fc->metadata, key2, str); | 210 av_metadata_set(&c->fc->metadata, key2, str); |
168 } | 211 } |
169 } | 212 } |
170 #ifdef DEBUG_METADATA | 213 #ifdef DEBUG_METADATA |
171 av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language); | 214 av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language); |
172 av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n
", | 215 av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n
", |
173 key, str, (char*)&atom.type, str_size, atom.size); | 216 key, str, (char*)&atom.type, str_size, atom.size); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 int count = 4; | 434 int count = 4; |
392 while (count--) { | 435 while (count--) { |
393 int c = get_byte(pb); | 436 int c = get_byte(pb); |
394 len = (len << 7) | (c & 0x7f); | 437 len = (len << 7) | (c & 0x7f); |
395 if (!(c & 0x80)) | 438 if (!(c & 0x80)) |
396 break; | 439 break; |
397 } | 440 } |
398 return len; | 441 return len; |
399 } | 442 } |
400 | 443 |
401 int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag) | 444 static int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag) |
402 { | 445 { |
403 int len; | 446 int len; |
404 *tag = get_byte(pb); | 447 *tag = get_byte(pb); |
405 len = ff_mp4_read_descr_len(pb); | 448 len = ff_mp4_read_descr_len(pb); |
406 dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len); | 449 dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len); |
407 return len; | 450 return len; |
408 } | 451 } |
409 | 452 |
410 #define MP4ESDescrTag 0x03 | 453 #define MP4ESDescrTag 0x03 |
411 #define MP4DecConfigDescrTag 0x04 | 454 #define MP4DecConfigDescrTag 0x04 |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 if(id > 0) | 949 if(id > 0) |
907 st->codec->codec_type = CODEC_TYPE_SUBTITLE; | 950 st->codec->codec_type = CODEC_TYPE_SUBTITLE; |
908 } | 951 } |
909 } | 952 } |
910 | 953 |
911 dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, | 954 dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, |
912 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xf
f, | 955 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xf
f, |
913 (format >> 24) & 0xff, st->codec->codec_type); | 956 (format >> 24) & 0xff, st->codec->codec_type); |
914 | 957 |
915 if(st->codec->codec_type==CODEC_TYPE_VIDEO) { | 958 if(st->codec->codec_type==CODEC_TYPE_VIDEO) { |
916 uint8_t codec_name[32]; | 959 unsigned int color_depth, len; |
917 unsigned int color_depth; | |
918 int color_greyscale; | 960 int color_greyscale; |
919 | 961 |
920 st->codec->codec_id = id; | 962 st->codec->codec_id = id; |
921 get_be16(pb); /* version */ | 963 get_be16(pb); /* version */ |
922 get_be16(pb); /* revision level */ | 964 get_be16(pb); /* revision level */ |
923 get_be32(pb); /* vendor */ | 965 get_be32(pb); /* vendor */ |
924 get_be32(pb); /* temporal quality */ | 966 get_be32(pb); /* temporal quality */ |
925 get_be32(pb); /* spatial quality */ | 967 get_be32(pb); /* spatial quality */ |
926 | 968 |
927 st->codec->width = get_be16(pb); /* width */ | 969 st->codec->width = get_be16(pb); /* width */ |
928 st->codec->height = get_be16(pb); /* height */ | 970 st->codec->height = get_be16(pb); /* height */ |
929 | 971 |
930 get_be32(pb); /* horiz resolution */ | 972 get_be32(pb); /* horiz resolution */ |
931 get_be32(pb); /* vert resolution */ | 973 get_be32(pb); /* vert resolution */ |
932 get_be32(pb); /* data size, always 0 */ | 974 get_be32(pb); /* data size, always 0 */ |
933 get_be16(pb); /* frames per samples */ | 975 get_be16(pb); /* frames per samples */ |
934 | 976 |
935 get_buffer(pb, codec_name, 32); /* codec name, pascal string */ | 977 len = get_byte(pb); /* codec name, pascal string */ |
936 if (codec_name[0] <= 31) { | 978 if (len > 31) |
937 int i; | 979 len = 31; |
938 int pos = 0; | 980 mov_read_mac_string(c, pb, len, st->codec->codec_name, 32); |
939 for (i = 0; i < codec_name[0] && pos < sizeof(st->codec->codec_n
ame) - 3; i++) { | 981 if (len < 31) |
940 uint8_t tmp; | 982 url_fskip(pb, 31 - len); |
941 PUT_UTF8(codec_name[i+1], tmp, st->codec->codec_name[pos++]
= tmp;) | 983 /* codec_tag YV12 triggers an UV swap in rawdec.c */ |
942 } | 984 if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) |
943 st->codec->codec_name[pos] = 0; | 985 st->codec->codec_tag=MKTAG('I', '4', '2', '0'); |
944 /* codec_tag YV12 triggers an UV swap in rawdec.c */ | |
945 if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0",
25)) | |
946 st->codec->codec_tag=MKTAG('I', '4', '2', '0'); | |
947 } | |
948 | 986 |
949 st->codec->bits_per_coded_sample = get_be16(pb); /* depth */ | 987 st->codec->bits_per_coded_sample = get_be16(pb); /* depth */ |
950 st->codec->color_table_id = get_be16(pb); /* colortable id */ | 988 st->codec->color_table_id = get_be16(pb); /* colortable id */ |
951 dprintf(c->fc, "depth %d, ctab id %d\n", | 989 dprintf(c->fc, "depth %d, ctab id %d\n", |
952 st->codec->bits_per_coded_sample, st->codec->color_table_id); | 990 st->codec->bits_per_coded_sample, st->codec->color_table_id); |
953 /* figure out the palette situation */ | 991 /* figure out the palette situation */ |
954 color_depth = st->codec->bits_per_coded_sample & 0x1F; | 992 color_depth = st->codec->bits_per_coded_sample & 0x1F; |
955 color_greyscale = st->codec->bits_per_coded_sample & 0x20; | 993 color_greyscale = st->codec->bits_per_coded_sample & 0x20; |
956 | 994 |
957 /* if the depth is 2, 4, or 8 bpp, file is palettized */ | 995 /* if the depth is 2, 4, or 8 bpp, file is palettized */ |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1457 if (!(st->codec->codec_type == CODEC_TYPE_AUDIO && | 1495 if (!(st->codec->codec_type == CODEC_TYPE_AUDIO && |
1458 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { | 1496 sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { |
1459 unsigned int current_sample = 0; | 1497 unsigned int current_sample = 0; |
1460 unsigned int stts_sample = 0; | 1498 unsigned int stts_sample = 0; |
1461 unsigned int sample_size; | 1499 unsigned int sample_size; |
1462 unsigned int distance = 0; | 1500 unsigned int distance = 0; |
1463 int key_off = sc->keyframes && sc->keyframes[0] == 1; | 1501 int key_off = sc->keyframes && sc->keyframes[0] == 1; |
1464 | 1502 |
1465 current_dts -= sc->dts_shift; | 1503 current_dts -= sc->dts_shift; |
1466 | 1504 |
| 1505 if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries)) |
| 1506 return; |
| 1507 st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries
)); |
| 1508 if (!st->index_entries) |
| 1509 return; |
| 1510 st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_en
tries); |
| 1511 |
1467 for (i = 0; i < sc->chunk_count; i++) { | 1512 for (i = 0; i < sc->chunk_count; i++) { |
1468 current_offset = sc->chunk_offsets[i]; | 1513 current_offset = sc->chunk_offsets[i]; |
1469 if (stsc_index + 1 < sc->stsc_count && | 1514 if (stsc_index + 1 < sc->stsc_count && |
1470 i + 1 == sc->stsc_data[stsc_index + 1].first) | 1515 i + 1 == sc->stsc_data[stsc_index + 1].first) |
1471 stsc_index++; | 1516 stsc_index++; |
1472 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { | 1517 for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { |
1473 int keyframe = 0; | 1518 int keyframe = 0; |
1474 if (current_sample >= sc->sample_count) { | 1519 if (current_sample >= sc->sample_count) { |
1475 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); | 1520 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); |
1476 return; | 1521 return; |
1477 } | 1522 } |
1478 | 1523 |
1479 if (!sc->keyframe_count || current_sample+key_off == sc->keyfram
es[stss_index]) { | 1524 if (!sc->keyframe_count || current_sample+key_off == sc->keyfram
es[stss_index]) { |
1480 keyframe = 1; | 1525 keyframe = 1; |
1481 if (stss_index + 1 < sc->keyframe_count) | 1526 if (stss_index + 1 < sc->keyframe_count) |
1482 stss_index++; | 1527 stss_index++; |
1483 } else if (sc->stps_count && current_sample+key_off == sc->stps_
data[stps_index]) { | 1528 } else if (sc->stps_count && current_sample+key_off == sc->stps_
data[stps_index]) { |
1484 keyframe = 1; | 1529 keyframe = 1; |
1485 if (stps_index + 1 < sc->stps_count) | 1530 if (stps_index + 1 < sc->stps_count) |
1486 stps_index++; | 1531 stps_index++; |
1487 } | 1532 } |
1488 if (keyframe) | 1533 if (keyframe) |
1489 distance = 0; | 1534 distance = 0; |
1490 sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample
_sizes[current_sample]; | 1535 sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample
_sizes[current_sample]; |
1491 if(sc->pseudo_stream_id == -1 || | 1536 if(sc->pseudo_stream_id == -1 || |
1492 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { | 1537 sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { |
1493 av_add_index_entry(st, current_offset, current_dts, sample_s
ize, distance, | 1538 AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]
; |
1494 keyframe ? AVINDEX_KEYFRAME : 0); | 1539 e->pos = current_offset; |
| 1540 e->timestamp = current_dts; |
| 1541 e->size = sample_size; |
| 1542 e->min_distance = distance; |
| 1543 e->flags = keyframe ? AVINDEX_KEYFRAME : 0; |
1495 dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRI
x64", dts %"PRId64", " | 1544 dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRI
x64", dts %"PRId64", " |
1496 "size %d, distance %d, keyframe %d\n", st->index, cu
rrent_sample, | 1545 "size %d, distance %d, keyframe %d\n", st->index, cu
rrent_sample, |
1497 current_offset, current_dts, sample_size, distance,
keyframe); | 1546 current_offset, current_dts, sample_size, distance,
keyframe); |
1498 } | 1547 } |
1499 | 1548 |
1500 current_offset += sample_size; | 1549 current_offset += sample_size; |
1501 stream_size += sample_size; | 1550 stream_size += sample_size; |
1502 current_dts += sc->stts_data[stts_index].duration; | 1551 current_dts += sc->stts_data[stts_index].duration; |
1503 distance++; | 1552 distance++; |
1504 stts_sample++; | 1553 stts_sample++; |
1505 current_sample++; | 1554 current_sample++; |
1506 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_d
ata[stts_index].count) { | 1555 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_d
ata[stts_index].count) { |
1507 stts_sample = 0; | 1556 stts_sample = 0; |
1508 stts_index++; | 1557 stts_index++; |
1509 } | 1558 } |
1510 } | 1559 } |
1511 } | 1560 } |
1512 if (st->duration > 0) | 1561 if (st->duration > 0) |
1513 st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; | 1562 st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; |
1514 } else { | 1563 } else { |
| 1564 unsigned chunk_samples, total = 0; |
| 1565 |
| 1566 // compute total chunk count |
| 1567 for (i = 0; i < sc->stsc_count; i++) { |
| 1568 unsigned count, chunk_count; |
| 1569 |
| 1570 chunk_samples = sc->stsc_data[i].count; |
| 1571 if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame)
{ |
| 1572 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); |
| 1573 return; |
| 1574 } |
| 1575 |
| 1576 if (sc->samples_per_frame >= 160) { // gsm |
| 1577 count = chunk_samples / sc->samples_per_frame; |
| 1578 } else if (sc->samples_per_frame > 1) { |
| 1579 unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_
frame; |
| 1580 count = (chunk_samples+samples-1) / samples; |
| 1581 } else { |
| 1582 count = (chunk_samples+1023) / 1024; |
| 1583 } |
| 1584 |
| 1585 if (i < sc->stsc_count - 1) |
| 1586 chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; |
| 1587 else |
| 1588 chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); |
| 1589 total += chunk_count * count; |
| 1590 } |
| 1591 |
| 1592 dprintf(mov->fc, "chunk count %d\n", total); |
| 1593 if (total >= UINT_MAX / sizeof(*st->index_entries)) |
| 1594 return; |
| 1595 st->index_entries = av_malloc(total*sizeof(*st->index_entries)); |
| 1596 if (!st->index_entries) |
| 1597 return; |
| 1598 st->index_entries_allocated_size = total*sizeof(*st->index_entries); |
| 1599 |
| 1600 // populate index |
1515 for (i = 0; i < sc->chunk_count; i++) { | 1601 for (i = 0; i < sc->chunk_count; i++) { |
1516 unsigned chunk_samples; | |
1517 | |
1518 current_offset = sc->chunk_offsets[i]; | 1602 current_offset = sc->chunk_offsets[i]; |
1519 if (stsc_index + 1 < sc->stsc_count && | 1603 if (stsc_index + 1 < sc->stsc_count && |
1520 i + 1 == sc->stsc_data[stsc_index + 1].first) | 1604 i + 1 == sc->stsc_data[stsc_index + 1].first) |
1521 stsc_index++; | 1605 stsc_index++; |
1522 chunk_samples = sc->stsc_data[stsc_index].count; | 1606 chunk_samples = sc->stsc_data[stsc_index].count; |
1523 | 1607 |
1524 if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame)
{ | |
1525 av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); | |
1526 return; | |
1527 } | |
1528 | |
1529 while (chunk_samples > 0) { | 1608 while (chunk_samples > 0) { |
| 1609 AVIndexEntry *e; |
1530 unsigned size, samples; | 1610 unsigned size, samples; |
1531 | 1611 |
1532 if (sc->samples_per_frame >= 160) { // gsm | 1612 if (sc->samples_per_frame >= 160) { // gsm |
1533 samples = sc->samples_per_frame; | 1613 samples = sc->samples_per_frame; |
1534 size = sc->bytes_per_frame; | 1614 size = sc->bytes_per_frame; |
1535 } else { | 1615 } else { |
1536 if (sc->samples_per_frame > 1) { | 1616 if (sc->samples_per_frame > 1) { |
1537 samples = FFMIN((1024 / sc->samples_per_frame)* | 1617 samples = FFMIN((1024 / sc->samples_per_frame)* |
1538 sc->samples_per_frame, chunk_samples); | 1618 sc->samples_per_frame, chunk_samples); |
1539 size = (samples / sc->samples_per_frame) * sc->bytes_per
_frame; | 1619 size = (samples / sc->samples_per_frame) * sc->bytes_per
_frame; |
1540 } else { | 1620 } else { |
1541 samples = FFMIN(1024, chunk_samples); | 1621 samples = FFMIN(1024, chunk_samples); |
1542 size = samples * sc->sample_size; | 1622 size = samples * sc->sample_size; |
1543 } | 1623 } |
1544 } | 1624 } |
1545 | 1625 |
1546 av_add_index_entry(st, current_offset, current_dts, size, 0, AVI
NDEX_KEYFRAME); | 1626 if (st->nb_index_entries >= total) { |
| 1627 av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", tota
l); |
| 1628 return; |
| 1629 } |
| 1630 e = &st->index_entries[st->nb_index_entries++]; |
| 1631 e->pos = current_offset; |
| 1632 e->timestamp = current_dts; |
| 1633 e->size = size; |
| 1634 e->min_distance = 0; |
| 1635 e->flags = AVINDEX_KEYFRAME; |
1547 dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64",
dts %"PRId64", " | 1636 dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64",
dts %"PRId64", " |
1548 "size %d, duration %d\n", st->index, i, current_offset,
current_dts, | 1637 "size %d, duration %d\n", st->index, i, current_offset,
current_dts, |
1549 size, samples); | 1638 size, samples); |
1550 | 1639 |
1551 current_offset += size; | 1640 current_offset += size; |
1552 current_dts += samples; | 1641 current_dts += samples; |
1553 chunk_samples -= samples; | 1642 chunk_samples -= samples; |
1554 } | 1643 } |
1555 } | 1644 } |
1556 } | 1645 } |
1557 } | 1646 } |
1558 | 1647 |
1559 static int mov_open_dref(ByteIOContext **pb, char *src, MOVDref *ref) | 1648 static int mov_open_dref(ByteIOContext **pb, char *src, MOVDref *ref) |
1560 { | 1649 { |
1561 /* try absolute path */ | 1650 /* try relative path, we do not try the absolute because it can leak informa
tion about our |
1562 if (!url_fopen(pb, ref->path, URL_RDONLY)) | 1651 system to an attacker */ |
1563 return 0; | |
1564 | |
1565 /* try relative path */ | |
1566 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { | 1652 if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { |
1567 char filename[1024]; | 1653 char filename[1024]; |
1568 char *src_path; | 1654 char *src_path; |
1569 int i, l; | 1655 int i, l; |
1570 | 1656 |
1571 /* find a source dir */ | 1657 /* find a source dir */ |
1572 src_path = strrchr(src, '/'); | 1658 src_path = strrchr(src, '/'); |
1573 if (src_path) | 1659 if (src_path) |
1574 src_path++; | 1660 src_path++; |
1575 else | 1661 else |
1576 src_path = src; | 1662 src_path = src; |
1577 | 1663 |
1578 /* find a next level down to target */ | 1664 /* find a next level down to target */ |
1579 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) | 1665 for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) |
1580 if (ref->path[l] == '/') { | 1666 if (ref->path[l] == '/') { |
1581 if (i == ref->nlvl_to - 1) | 1667 if (i == ref->nlvl_to - 1) |
1582 break; | 1668 break; |
1583 else | 1669 else |
1584 i++; | 1670 i++; |
1585 } | 1671 } |
1586 | 1672 |
1587 /* compose filename if next level down to target was found */ | 1673 /* compose filename if next level down to target was found */ |
1588 if (i == ref->nlvl_to - 1) { | 1674 if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) { |
1589 memcpy(filename, src, src_path - src); | 1675 memcpy(filename, src, src_path - src); |
1590 filename[src_path - src] = 0; | 1676 filename[src_path - src] = 0; |
1591 | 1677 |
1592 for (i = 1; i < ref->nlvl_from; i++) | 1678 for (i = 1; i < ref->nlvl_from; i++) |
1593 av_strlcat(filename, "../", 1024); | 1679 av_strlcat(filename, "../", 1024); |
1594 | 1680 |
1595 av_strlcat(filename, ref->path + l + 1, 1024); | 1681 av_strlcat(filename, ref->path + l + 1, 1024); |
1596 | 1682 |
1597 if (!url_fopen(pb, filename, URL_RDONLY)) | 1683 if (!url_fopen(pb, filename, URL_RDONLY)) |
1598 return 0; | 1684 return 0; |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 AVInputFormat mov_demuxer = { | 2450 AVInputFormat mov_demuxer = { |
2365 "mov,mp4,m4a,3gp,3g2,mj2", | 2451 "mov,mp4,m4a,3gp,3g2,mj2", |
2366 NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"), | 2452 NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"), |
2367 sizeof(MOVContext), | 2453 sizeof(MOVContext), |
2368 mov_probe, | 2454 mov_probe, |
2369 mov_read_header, | 2455 mov_read_header, |
2370 mov_read_packet, | 2456 mov_read_packet, |
2371 mov_read_close, | 2457 mov_read_close, |
2372 mov_read_seek, | 2458 mov_read_seek, |
2373 }; | 2459 }; |
OLD | NEW |