[FFmpeg-cvslog] id3v2enc: fix writing frame sizes for ID3v2.3

Anton Khirnov git at videolan.org
Thu Mar 1 03:20:19 CET 2012


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Tue Feb 28 11:45:07 2012 +0100| [24fe1a3b1662652df076804fdbfd8b2fd089497e] | committer: Anton Khirnov

id3v2enc: fix writing frame sizes for ID3v2.3

Frame sizes in ID3v2.3 are not synchsafe, they are simply 32be numbers.

In practice this bug is not noticeable unless the frame size takes more
than 7 bits (which is almost never for text frames).

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=24fe1a3b1662652df076804fdbfd8b2fd089497e
---

 libavformat/id3v2enc.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index 8666818..58f7797 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -45,7 +45,7 @@ static int string_is_ascii(const uint8_t *str)
  * according to encoding (only UTF-8 or UTF-16+BOM supported).
  * @return number of bytes written or a negative error code.
  */
-static int id3v2_put_ttag(AVFormatContext *s, const char *str1, const char *str2,
+static int id3v2_put_ttag(ID3v2EncContext *id3, AVIOContext *avioc, const char *str1, const char *str2,
                           uint32_t tag, enum ID3v2Encoding enc)
 {
     int len;
@@ -73,17 +73,21 @@ static int id3v2_put_ttag(AVFormatContext *s, const char *str1, const char *str2
         put(dyn_buf, str2);
     len = avio_close_dyn_buf(dyn_buf, &pb);
 
-    avio_wb32(s->pb, tag);
-    id3v2_put_size(s->pb, len);
-    avio_wb16(s->pb, 0);
-    avio_write(s->pb, pb, len);
+    avio_wb32(avioc, tag);
+    /* ID3v2.3 frame size is not synchsafe */
+    if (id3->version == 3)
+        avio_wb32(avioc, len);
+    else
+        id3v2_put_size(avioc, len);
+    avio_wb16(avioc, 0);
+    avio_write(avioc, pb, len);
 
     av_freep(&pb);
     return len + ID3v2_HEADER_SIZE;
 }
 
-static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const char table[][4],
-                                 enum ID3v2Encoding enc)
+static int id3v2_check_write_tag(ID3v2EncContext *id3, AVIOContext *pb, AVDictionaryEntry *t,
+                                 const char table[][4], enum ID3v2Encoding enc)
 {
     uint32_t tag;
     int i;
@@ -93,7 +97,7 @@ static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const
     tag = AV_RB32(t->key);
     for (i = 0; *table[i]; i++)
         if (tag == AV_RB32(table[i]))
-            return id3v2_put_ttag(s, t->value, NULL, tag, enc);
+            return id3v2_put_ttag(id3, pb, t->value, NULL, tag, enc);
     return -1;
 }
 
@@ -124,18 +128,18 @@ int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
     while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
         int ret;
 
-        if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
+        if ((ret = id3v2_check_write_tag(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) {
             id3->len += ret;
             continue;
         }
-        if ((ret = id3v2_check_write_tag(s, t, id3->version == 3 ?
+        if ((ret = id3v2_check_write_tag(id3, s->pb, t, id3->version == 3 ?
                                                ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
             id3->len += ret;
             continue;
         }
 
         /* unknown tag, write as TXXX frame */
-        if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
+        if ((ret = id3v2_put_ttag(id3, s->pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
             return ret;
         id3->len += ret;
     }



More information about the ffmpeg-cvslog mailing list