Index: patched-ffmpeg-mt/libavformat/asfenc.c |
=================================================================== |
--- patched-ffmpeg-mt/libavformat/asfenc.c (revision 41250) |
+++ patched-ffmpeg-mt/libavformat/asfenc.c (working copy) |
@@ -203,21 +203,36 @@ |
put_buffer(s, *g, sizeof(*g)); |
} |
-static void put_str16_nolen(ByteIOContext *s, const char *tag); |
-static void put_str16(ByteIOContext *s, const char *tag) |
+static int put_str16_nolen(ByteIOContext *s, const char *tag) |
{ |
- put_le16(s,strlen(tag) + 1); |
- put_str16_nolen(s, tag); |
+ const uint8_t *q = tag; |
+ int ret = 0; |
+ |
+ while (*q) { |
+ uint32_t ch; |
+ uint16_t tmp; |
+ |
+ GET_UTF8(ch, *q++, break;) |
+ PUT_UTF16(ch, tmp, put_le16(s, tmp);ret += 2;) |
+ } |
+ put_le16(s, 0); |
+ ret += 2; |
+ return ret; |
} |
-static void put_str16_nolen(ByteIOContext *s, const char *tag) |
+static void put_str16(ByteIOContext *s, const char *tag) |
{ |
- int c; |
+ int len; |
+ uint8_t *pb; |
+ ByteIOContext *dyn_buf; |
+ if (url_open_dyn_buf(&dyn_buf) < 0) |
+ return; |
- do{ |
- c = (uint8_t)*tag++; |
- put_le16(s, c); |
- }while(c); |
+ put_str16_nolen(dyn_buf, tag); |
+ len = url_close_dyn_buf(dyn_buf, &pb); |
+ put_le16(s, len); |
+ put_buffer(s, pb, len); |
+ av_freep(&pb); |
} |
static int64_t put_header(ByteIOContext *pb, const ff_asf_guid *g) |
@@ -272,7 +287,7 @@ |
{ |
ASFContext *asf = s->priv_data; |
ByteIOContext *pb = s->pb; |
- AVMetadataTag *title, *author, *copyright, *comment; |
+ AVMetadataTag *tags[5]; |
int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; |
int has_title; |
int metadata_count; |
@@ -281,13 +296,14 @@ |
int bit_rate; |
int64_t duration; |
- title = av_metadata_get(s->metadata, "title" , NULL, 0); |
- author = av_metadata_get(s->metadata, "author" , NULL, 0); |
- copyright = av_metadata_get(s->metadata, "copyright", NULL, 0); |
- comment = av_metadata_get(s->metadata, "comment" , NULL, 0); |
+ tags[0] = av_metadata_get(s->metadata, "title" , NULL, 0); |
+ tags[1] = av_metadata_get(s->metadata, "author" , NULL, 0); |
+ tags[2] = av_metadata_get(s->metadata, "copyright", NULL, 0); |
+ tags[3] = av_metadata_get(s->metadata, "comment" , NULL, 0); |
+ tags[4] = av_metadata_get(s->metadata, "rating" , NULL, 0); |
duration = asf->duration + PREROLL_TIME * 10000; |
- has_title = title || author || copyright || comment; |
+ has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4]; |
metadata_count = s->metadata ? s->metadata->count : 0; |
bit_rate = 0; |
@@ -335,16 +351,22 @@ |
/* title and other infos */ |
if (has_title) { |
+ int len; |
+ uint8_t *buf; |
+ ByteIOContext *dyn_buf; |
+ |
+ if (url_open_dyn_buf(&dyn_buf) < 0) |
+ return AVERROR(ENOMEM); |
+ |
hpos = put_header(pb, &ff_asf_comment_header); |
- put_le16(pb, title ? 2 * (strlen(title->value ) + 1) : 0); |
- put_le16(pb, author ? 2 * (strlen(author->value ) + 1) : 0); |
- put_le16(pb, copyright ? 2 * (strlen(copyright->value) + 1) : 0); |
- put_le16(pb, comment ? 2 * (strlen(comment->value ) + 1) : 0); |
- put_le16(pb, 0); |
- if (title ) put_str16_nolen(pb, title->value ); |
- if (author ) put_str16_nolen(pb, author->value ); |
- if (copyright) put_str16_nolen(pb, copyright->value); |
- if (comment ) put_str16_nolen(pb, comment->value ); |
+ |
+ for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) { |
+ len = tags[n] ? put_str16_nolen(dyn_buf, tags[n]->value) : 0; |
+ put_le16(pb, len); |
+ } |
+ len = url_close_dyn_buf(dyn_buf, &buf); |
+ put_buffer(pb, buf, len); |
+ av_freep(&buf); |
end_header(pb, hpos); |
} |
if (metadata_count) { |
@@ -352,14 +374,9 @@ |
hpos = put_header(pb, &ff_asf_extended_content_header); |
put_le16(pb, metadata_count); |
while ((tag = av_metadata_get(s->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) { |
- put_le16(pb, 2*(strlen(tag->key) + 3) + 1); |
- put_le16(pb, 'W'); |
- put_le16(pb, 'M'); |
- put_le16(pb, '/'); |
- put_str16_nolen(pb, tag->key); |
+ put_str16(pb, tag->key); |
put_le16(pb, 0); |
- put_le16(pb, 2*strlen(tag->value) + 1); |
- put_str16_nolen(pb, tag->value); |
+ put_str16(pb, tag->value); |
} |
end_header(pb, hpos); |
} |
@@ -449,6 +466,10 @@ |
put_le32(pb, s->nb_streams); |
for(n=0;n<s->nb_streams;n++) { |
AVCodec *p; |
+ const char *desc; |
+ int len; |
+ uint8_t *buf; |
+ ByteIOContext *dyn_buf; |
enc = s->streams[n]->codec; |
p = avcodec_find_encoder(enc->codec_id); |
@@ -461,9 +482,20 @@ |
put_le16(pb, -1); |
if(enc->codec_id == CODEC_ID_WMAV2) |
- put_str16(pb, "Windows Media Audio V8"); |
+ desc = "Windows Media Audio V8"; |
else |
- put_str16(pb, p ? p->name : enc->codec_name); |
+ desc = p ? p->name : enc->codec_name; |
+ |
+ if ( url_open_dyn_buf(&dyn_buf) < 0) |
+ return AVERROR(ENOMEM); |
+ |
+ put_str16_nolen(dyn_buf, desc); |
+ len = url_close_dyn_buf(dyn_buf, &buf); |
+ put_le16(pb, len / 2); // "number of characters" = length in bytes / 2 |
+ |
+ put_buffer(pb, buf, len); |
+ av_freep(&buf); |
+ |
put_le16(pb, 0); /* no parameters */ |