OLD | NEW |
1 /* | 1 /* |
2 * ASF compatible demuxer | 2 * ASF compatible demuxer |
3 * Copyright (c) 2000, 2001 Fabrice Bellard | 3 * Copyright (c) 2000, 2001 Fabrice Bellard |
4 * | 4 * |
5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
6 * | 6 * |
7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 else PRINT_IF_GUID(g, ff_asf_data_header); | 75 else PRINT_IF_GUID(g, ff_asf_data_header); |
76 else PRINT_IF_GUID(g, index_guid); | 76 else PRINT_IF_GUID(g, index_guid); |
77 else PRINT_IF_GUID(g, ff_asf_head1_guid); | 77 else PRINT_IF_GUID(g, ff_asf_head1_guid); |
78 else PRINT_IF_GUID(g, ff_asf_head2_guid); | 78 else PRINT_IF_GUID(g, ff_asf_head2_guid); |
79 else PRINT_IF_GUID(g, ff_asf_my_guid); | 79 else PRINT_IF_GUID(g, ff_asf_my_guid); |
80 else PRINT_IF_GUID(g, ff_asf_ext_stream_header); | 80 else PRINT_IF_GUID(g, ff_asf_ext_stream_header); |
81 else PRINT_IF_GUID(g, ff_asf_extended_content_header); | 81 else PRINT_IF_GUID(g, ff_asf_extended_content_header); |
82 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); | 82 else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); |
83 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); | 83 else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); |
84 else PRINT_IF_GUID(g, ff_asf_metadata_header); | 84 else PRINT_IF_GUID(g, ff_asf_metadata_header); |
| 85 else PRINT_IF_GUID(g, ff_asf_marker_header); |
85 else PRINT_IF_GUID(g, stream_bitrate_guid); | 86 else PRINT_IF_GUID(g, stream_bitrate_guid); |
86 else PRINT_IF_GUID(g, ff_asf_language_guid); | 87 else PRINT_IF_GUID(g, ff_asf_language_guid); |
87 else | 88 else |
88 dprintf(NULL, "(GUID: unknown) "); | 89 dprintf(NULL, "(GUID: unknown) "); |
89 for(i=0;i<16;i++) | 90 for(i=0;i<16;i++) |
90 dprintf(NULL, " 0x%02x,", (*g)[i]); | 91 dprintf(NULL, " 0x%02x,", (*g)[i]); |
91 dprintf(NULL, "}\n"); | 92 dprintf(NULL, "}\n"); |
92 } | 93 } |
93 #undef PRINT_IF_GUID | 94 #undef PRINT_IF_GUID |
94 #else | 95 #else |
(...skipping 20 matching lines...) Expand all Loading... |
115 *q++ = c; | 116 *q++ = c; |
116 len--; | 117 len--; |
117 } | 118 } |
118 *q = '\0'; | 119 *q = '\0'; |
119 } | 120 } |
120 #endif | 121 #endif |
121 | 122 |
122 static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) | 123 static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) |
123 { | 124 { |
124 char* q = buf; | 125 char* q = buf; |
125 for (; len > 1; len -= 2) { | 126 while (len > 1) { |
126 uint8_t tmp; | 127 uint8_t tmp; |
127 PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;) | 128 uint32_t ch; |
| 129 |
| 130 GET_UTF16(ch, (len -= 2) >= 0 ? get_le16(pb) : 0, break;) |
| 131 PUT_UTF8(ch, tmp, if (q - buf < buf_size - 1) *q++ = tmp;) |
128 } | 132 } |
129 if (len > 0) | 133 if (len > 0) |
130 url_fskip(pb, len); | 134 url_fskip(pb, len); |
131 *q = '\0'; | 135 *q = '\0'; |
132 } | 136 } |
133 | 137 |
134 static int asf_probe(AVProbeData *pd) | 138 static int asf_probe(AVProbeData *pd) |
135 { | 139 { |
136 /* check file header */ | 140 /* check file header */ |
137 if (!guidcmp(pd->buf, &ff_asf_header)) | 141 if (!guidcmp(pd->buf, &ff_asf_header)) |
138 return AVPROBE_SCORE_MAX; | 142 return AVPROBE_SCORE_MAX; |
139 else | 143 else |
140 return 0; | 144 return 0; |
141 } | 145 } |
142 | 146 |
143 static int get_value(ByteIOContext *pb, int type){ | 147 static int get_value(ByteIOContext *pb, int type){ |
144 switch(type){ | 148 switch(type){ |
145 case 2: return get_le32(pb); | 149 case 2: return get_le32(pb); |
146 case 3: return get_le32(pb); | 150 case 3: return get_le32(pb); |
147 case 4: return get_le64(pb); | 151 case 4: return get_le64(pb); |
148 case 5: return get_le16(pb); | 152 case 5: return get_le16(pb); |
149 default:return INT_MIN; | 153 default:return INT_MIN; |
150 } | 154 } |
151 } | 155 } |
152 | 156 |
153 static void get_tag(AVFormatContext *s, const char *key, int type, int len) | 157 static void get_tag(AVFormatContext *s, const char *key, int type, int len) |
154 { | 158 { |
155 char *value; | 159 char *value; |
156 | 160 |
157 if ((unsigned)len >= UINT_MAX) | 161 if ((unsigned)len >= (UINT_MAX - 1)/2) |
158 return; | 162 return; |
159 | 163 |
160 value = av_malloc(len+1); | 164 value = av_malloc(2*len+1); |
161 if (!value) | 165 if (!value) |
162 return; | 166 return; |
163 | 167 |
164 if (type <= 1) { // unicode or byte | 168 if (type == 0) { // UTF16-LE |
165 get_str16_nolen(s->pb, len, value, len); | 169 get_str16_nolen(s->pb, len, value, 2*len + 1); |
166 } else if (type <= 5) { // boolean or DWORD or QWORD or WORD | 170 } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD |
167 uint64_t num = get_value(s->pb, type); | 171 uint64_t num = get_value(s->pb, type); |
168 snprintf(value, len, "%"PRIu64, num); | 172 snprintf(value, len, "%"PRIu64, num); |
169 } else { | 173 } else { |
170 url_fskip(s->pb, len); | 174 url_fskip(s->pb, len); |
| 175 av_freep(&value); |
| 176 av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type,
key); |
171 return; | 177 return; |
172 } | 178 } |
173 if (!strncmp(key, "WM/", 3)) | 179 av_metadata_set2(&s->metadata, key, value, 0); |
174 key += 3; | 180 av_freep(&value); |
175 av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL); | |
176 } | 181 } |
177 | 182 |
178 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | 183 static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) |
179 { | 184 { |
180 ASFContext *asf = s->priv_data; | 185 ASFContext *asf = s->priv_data; |
181 ff_asf_guid g; | 186 ff_asf_guid g; |
182 ByteIOContext *pb = s->pb; | 187 ByteIOContext *pb = s->pb; |
183 AVStream *st; | 188 AVStream *st; |
184 ASFStream *asf_st; | 189 ASFStream *asf_st; |
185 int size, i; | 190 int size, i; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 434 } |
430 } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { | 435 } else if (!guidcmp(&g, &ff_asf_extended_content_header)) { |
431 int desc_count, i; | 436 int desc_count, i; |
432 | 437 |
433 desc_count = get_le16(pb); | 438 desc_count = get_le16(pb); |
434 for(i=0;i<desc_count;i++) { | 439 for(i=0;i<desc_count;i++) { |
435 int name_len,value_type,value_len; | 440 int name_len,value_type,value_len; |
436 char name[1024]; | 441 char name[1024]; |
437 | 442 |
438 name_len = get_le16(pb); | 443 name_len = get_le16(pb); |
| 444 if (name_len%2) // must be even, broken lavf versions wr
ote len-1 |
| 445 name_len += 1; |
439 get_str16_nolen(pb, name_len, name, sizeof(name)); | 446 get_str16_nolen(pb, name_len, name, sizeof(name)); |
440 value_type = get_le16(pb); | 447 value_type = get_le16(pb); |
441 value_len = get_le16(pb); | 448 value_len = get_le16(pb); |
| 449 if (!value_type && value_len%2) |
| 450 value_len += 1; |
442 get_tag(s, name, value_type, value_len); | 451 get_tag(s, name, value_type, value_len); |
443 } | 452 } |
444 } else if (!guidcmp(&g, &ff_asf_metadata_header)) { | 453 } else if (!guidcmp(&g, &ff_asf_metadata_header)) { |
445 int n, stream_num, name_len, value_len, value_type, value_num; | 454 int n, stream_num, name_len, value_len, value_type, value_num; |
446 n = get_le16(pb); | 455 n = get_le16(pb); |
447 | 456 |
448 for(i=0;i<n;i++) { | 457 for(i=0;i<n;i++) { |
449 char name[1024]; | 458 char name[1024]; |
450 | 459 |
451 get_le16(pb); //lang_list_index | 460 get_le16(pb); //lang_list_index |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 url_fseek(pb, ext_len, SEEK_CUR); | 514 url_fseek(pb, ext_len, SEEK_CUR); |
506 } | 515 } |
507 | 516 |
508 // there could be a optional stream properties object to follow | 517 // there could be a optional stream properties object to follow |
509 // if so the next iteration will pick it up | 518 // if so the next iteration will pick it up |
510 } else if (!guidcmp(&g, &ff_asf_head1_guid)) { | 519 } else if (!guidcmp(&g, &ff_asf_head1_guid)) { |
511 int v1, v2; | 520 int v1, v2; |
512 get_guid(pb, &g); | 521 get_guid(pb, &g); |
513 v1 = get_le32(pb); | 522 v1 = get_le32(pb); |
514 v2 = get_le16(pb); | 523 v2 = get_le16(pb); |
| 524 } else if (!guidcmp(&g, &ff_asf_marker_header)) { |
| 525 int i, count, name_len; |
| 526 char name[1024]; |
| 527 |
| 528 get_le64(pb); // reserved 16 bytes |
| 529 get_le64(pb); // ... |
| 530 count = get_le32(pb); // markers count |
| 531 get_le16(pb); // reserved 2 bytes |
| 532 name_len = get_le16(pb); // name length |
| 533 for(i=0;i<name_len;i++){ |
| 534 get_byte(pb); // skip the name |
| 535 } |
| 536 |
| 537 for(i=0;i<count;i++){ |
| 538 int64_t pres_time; |
| 539 int name_len; |
| 540 |
| 541 get_le64(pb); // offset, 8 bytes |
| 542 pres_time = get_le64(pb); // presentation time |
| 543 get_le16(pb); // entry length |
| 544 get_le32(pb); // send time |
| 545 get_le32(pb); // flags |
| 546 name_len = get_le32(pb); // name length |
| 547 get_str16_nolen(pb, name_len * 2, name, sizeof(name)); |
| 548 ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NO
PTS_VALUE, name ); |
| 549 } |
515 #if 0 | 550 #if 0 |
516 } else if (!guidcmp(&g, &ff_asf_codec_comment_header)) { | 551 } else if (!guidcmp(&g, &ff_asf_codec_comment_header)) { |
517 int len, v1, n, num; | 552 int len, v1, n, num; |
518 char str[256], *q; | 553 char str[256], *q; |
519 char tag[16]; | 554 char tag[16]; |
520 | 555 |
521 get_guid(pb, &g); | 556 get_guid(pb, &g); |
522 print_guid(&g); | 557 print_guid(&g); |
523 | 558 |
524 n = get_le32(pb); | 559 n = get_le32(pb); |
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 NULL_IF_CONFIG_SMALL("ASF format"), | 1193 NULL_IF_CONFIG_SMALL("ASF format"), |
1159 sizeof(ASFContext), | 1194 sizeof(ASFContext), |
1160 asf_probe, | 1195 asf_probe, |
1161 asf_read_header, | 1196 asf_read_header, |
1162 asf_read_packet, | 1197 asf_read_packet, |
1163 asf_read_close, | 1198 asf_read_close, |
1164 asf_read_seek, | 1199 asf_read_seek, |
1165 asf_read_pts, | 1200 asf_read_pts, |
1166 .metadata_conv = ff_asf_metadata_conv, | 1201 .metadata_conv = ff_asf_metadata_conv, |
1167 }; | 1202 }; |
OLD | NEW |