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