Index: patched-ffmpeg-mt/libavformat/asfdec.c |
=================================================================== |
--- patched-ffmpeg-mt/libavformat/asfdec.c (revision 41250) |
+++ patched-ffmpeg-mt/libavformat/asfdec.c (working copy) |
@@ -82,6 +82,7 @@ |
else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); |
else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); |
else PRINT_IF_GUID(g, ff_asf_metadata_header); |
+ else PRINT_IF_GUID(g, ff_asf_marker_header); |
else PRINT_IF_GUID(g, stream_bitrate_guid); |
else PRINT_IF_GUID(g, ff_asf_language_guid); |
else |
@@ -122,9 +123,12 @@ |
static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) |
{ |
char* q = buf; |
- for (; len > 1; len -= 2) { |
+ while (len > 1) { |
uint8_t tmp; |
- PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;) |
+ uint32_t ch; |
+ |
+ GET_UTF16(ch, (len -= 2) >= 0 ? get_le16(pb) : 0, break;) |
+ PUT_UTF8(ch, tmp, if (q - buf < buf_size - 1) *q++ = tmp;) |
} |
if (len > 0) |
url_fskip(pb, len); |
@@ -154,25 +158,26 @@ |
{ |
char *value; |
- if ((unsigned)len >= UINT_MAX) |
+ if ((unsigned)len >= (UINT_MAX - 1)/2) |
return; |
- value = av_malloc(len+1); |
+ value = av_malloc(2*len+1); |
if (!value) |
return; |
- if (type <= 1) { // unicode or byte |
- get_str16_nolen(s->pb, len, value, len); |
- } else if (type <= 5) { // boolean or DWORD or QWORD or WORD |
+ if (type == 0) { // UTF16-LE |
+ get_str16_nolen(s->pb, len, value, 2*len + 1); |
+ } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD |
uint64_t num = get_value(s->pb, type); |
snprintf(value, len, "%"PRIu64, num); |
} else { |
url_fskip(s->pb, len); |
+ av_freep(&value); |
+ av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key); |
return; |
} |
- if (!strncmp(key, "WM/", 3)) |
- key += 3; |
- av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL); |
+ av_metadata_set2(&s->metadata, key, value, 0); |
+ av_freep(&value); |
} |
static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) |
@@ -436,9 +441,13 @@ |
char name[1024]; |
name_len = get_le16(pb); |
+ if (name_len%2) // must be even, broken lavf versions wrote len-1 |
+ name_len += 1; |
get_str16_nolen(pb, name_len, name, sizeof(name)); |
value_type = get_le16(pb); |
value_len = get_le16(pb); |
+ if (!value_type && value_len%2) |
+ value_len += 1; |
get_tag(s, name, value_type, value_len); |
} |
} else if (!guidcmp(&g, &ff_asf_metadata_header)) { |
@@ -512,6 +521,32 @@ |
get_guid(pb, &g); |
v1 = get_le32(pb); |
v2 = get_le16(pb); |
+ } else if (!guidcmp(&g, &ff_asf_marker_header)) { |
+ int i, count, name_len; |
+ char name[1024]; |
+ |
+ get_le64(pb); // reserved 16 bytes |
+ get_le64(pb); // ... |
+ count = get_le32(pb); // markers count |
+ get_le16(pb); // reserved 2 bytes |
+ name_len = get_le16(pb); // name length |
+ for(i=0;i<name_len;i++){ |
+ get_byte(pb); // skip the name |
+ } |
+ |
+ for(i=0;i<count;i++){ |
+ int64_t pres_time; |
+ int name_len; |
+ |
+ get_le64(pb); // offset, 8 bytes |
+ pres_time = get_le64(pb); // presentation time |
+ get_le16(pb); // entry length |
+ get_le32(pb); // send time |
+ get_le32(pb); // flags |
+ name_len = get_le32(pb); // name length |
+ get_str16_nolen(pb, name_len * 2, name, sizeof(name)); |
+ ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name ); |
+ } |
#if 0 |
} else if (!guidcmp(&g, &ff_asf_codec_comment_header)) { |
int len, v1, n, num; |