| 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 |