# HG changeset patch # User benoit # Date 1267117195 0 # Node ID d833557e72871f9ed53ef5164950f2f7edfcaa98 # Parent 65b13165daaf5a1cdce4db934c649612ac18dcdd asfenc: write tags in proper UTF-16. Patch by Anton Khirnov wyskas gmail com diff -r 65b13165daaf -r d833557e7287 asfenc.c --- a/asfenc.c Thu Feb 25 16:50:26 2010 +0000 +++ b/asfenc.c Thu Feb 25 16:59:55 2010 +0000 @@ -203,14 +203,36 @@ put_buffer(s, *g, sizeof(*g)); } -static void put_str16_nolen(ByteIOContext *s, const char *tag) +static int put_str16_nolen(ByteIOContext *s, const char *tag) { - int c; + const uint8_t *q = tag; + int ret = 0; + + while (*q) { + uint32_t ch; + uint16_t tmp; - do{ - c = (uint8_t)*tag++; - put_le16(s, c); - }while(c); + 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(ByteIOContext *s, const char *tag) +{ + int len; + uint8_t *pb; + ByteIOContext *dyn_buf; + if (url_open_dyn_buf(&dyn_buf) < 0) + return; + + 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) @@ -329,12 +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); - for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) - put_le16(pb, tags[n] ? 2*(strlen(tags[n]->value) + 1) : 0); - for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) - if (tags[n]) - put_str16_nolen(pb, tags[n]->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) { @@ -342,11 +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) + 1)); - 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); } @@ -437,6 +467,9 @@ for(n=0;nnb_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); @@ -452,8 +485,17 @@ desc = "Windows Media Audio V8"; else desc = p ? p->name : enc->codec_name; - put_le16(pb, strlen(desc) + 1); // "number of characters" = length in bytes / 2 - put_str16_nolen(pb, desc); + + 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 */