[FFmpeg-cvslog] id3v2enc: split ff_id3v2_write().

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


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Feb 27 22:08:50 2012 +0100| [411225aabce57411d1544a7bbc6f6bee6d8ef638] | committer: Anton Khirnov

id3v2enc: split ff_id3v2_write().

This will allow writing the tag in several steps, needed for writing
attached pictures.

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

 libavformat/id3v2.h    |   26 ++++++++++++++++++-
 libavformat/id3v2enc.c |   64 +++++++++++++++++++++++++++++++----------------
 libavformat/mp3enc.c   |    2 +-
 libavformat/omaenc.c   |    2 +-
 4 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index 5f3ec1b..f47abe9 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -46,6 +46,12 @@ enum ID3v2Encoding {
     ID3v2_ENCODING_UTF8     = 3,
 };
 
+typedef struct ID3v2EncContext {
+    int      version;       ///< ID3v2 minor version, either 3 or 4
+    int64_t size_pos;       ///< offset of the tag total size
+    int          len;       ///< size of the tag written so far
+} ID3v2EncContext;
+
 typedef struct ID3v2ExtraMeta {
     const char *tag;
     void *data;
@@ -91,12 +97,28 @@ int ff_id3v2_tag_len(const uint8_t *buf);
 void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta);
 
 /**
- * Write an ID3v2 tag.
+ * Initialize an ID3v2 tag.
+ */
+void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
+                    const char *magic);
+
+/**
+ * Convert and write all global metadata from s into an ID3v2 tag.
+ */
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3);
+
+/**
+ * Finalize an opened ID3v2 tag.
+ */
+void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb);
+
+/**
+ * Write an ID3v2 tag containing all global metadata from s.
  * @param id3v2_version Subversion of ID3v2; supported values are 3 and 4
  * @param magic magic bytes to identify the header
  * If in doubt, use ID3v2_DEFAULT_MAGIC.
  */
-int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version, const char *magic);
+int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version, const char *magic);
 
 /**
  * Free memory allocated parsing special (non-text) metadata.
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index 3a4d229..8666818 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -97,50 +97,70 @@ static int id3v2_check_write_tag(AVFormatContext *s, AVDictionaryEntry *t, const
     return -1;
 }
 
-int ff_id3v2_write(struct AVFormatContext *s, int id3v2_version,
-                   const char *magic)
+void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
+                    const char *magic)
 {
-    int64_t size_pos, cur_pos;
-    AVDictionaryEntry *t = NULL;
-
-    int totlen = 0, enc = id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
-                                               ID3v2_ENCODING_UTF8;
+    id3->version = id3v2_version;
 
-
-    avio_wb32(s->pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
-    avio_w8(s->pb, 0);
-    avio_w8(s->pb, 0); /* flags */
+    avio_wb32(pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
+    avio_w8(pb, 0);
+    avio_w8(pb, 0); /* flags */
 
     /* reserve space for size */
-    size_pos = avio_tell(s->pb);
-    avio_wb32(s->pb, 0);
+    id3->size_pos = avio_tell(pb);
+    avio_wb32(pb, 0);
+}
+
+int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
+{
+    AVDictionaryEntry *t = NULL;
+    int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
+                                  ID3v2_ENCODING_UTF8;
 
     ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
-    if (id3v2_version == 4)
+    if (id3->version == 4)
         ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
 
     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) {
-            totlen += ret;
+            id3->len += ret;
             continue;
         }
-        if ((ret = id3v2_check_write_tag(s, t, id3v2_version == 3 ?
+        if ((ret = id3v2_check_write_tag(s, t, id3->version == 3 ?
                                                ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
-            totlen += ret;
+            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)
             return ret;
-        totlen += ret;
+        id3->len += ret;
     }
 
-    cur_pos = avio_tell(s->pb);
-    avio_seek(s->pb, size_pos, SEEK_SET);
-    id3v2_put_size(s->pb, totlen);
-    avio_seek(s->pb, cur_pos, SEEK_SET);
+    return 0;
+}
+
+void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb)
+{
+    int64_t cur_pos = avio_tell(pb);
+    avio_seek(pb, id3->size_pos, SEEK_SET);
+    id3v2_put_size(pb, id3->len);
+    avio_seek(pb, cur_pos, SEEK_SET);
+}
+
+int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version,
+                          const char *magic)
+{
+    ID3v2EncContext id3 = { 0 };
+    int ret;
+
+    ff_id3v2_start(&id3, s->pb, id3v2_version, magic);
+    if ((ret = ff_id3v2_write_metadata(s, &id3)) < 0)
+        return ret;
+    ff_id3v2_finish(&id3, s->pb);
+
     return 0;
 }
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index ce547ea..ab20c29 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -187,7 +187,7 @@ static int mp3_write_header(struct AVFormatContext *s)
     MP3Context  *mp3 = s->priv_data;
     int ret;
 
-    ret = ff_id3v2_write(s, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
+    ret = ff_id3v2_write_simple(s, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
     if (ret < 0)
         return ret;
 
diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c
index e932b4b..c3ee0e8 100644
--- a/libavformat/omaenc.c
+++ b/libavformat/omaenc.c
@@ -49,7 +49,7 @@ static av_cold int oma_write_header(AVFormatContext *s)
     }
 
     /* Metadata; OpenMG does not support ID3v2.4 */
-    ff_id3v2_write(s, 3, ID3v2_EA3_MAGIC);
+    ff_id3v2_write_simple(s, 3, ID3v2_EA3_MAGIC);
 
     ffio_wfourcc(s->pb, "EA3\0");
     avio_w8(s->pb, EA3_HEADER_SIZE >> 7);



More information about the ffmpeg-cvslog mailing list