[FFmpeg-devel] [PATCH] id3v2enc: chapter support

Paul B Mahol onemda at gmail.com
Mon May 6 02:27:22 CEST 2013


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libavformat/id3v2enc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index a10d679..13b17ac 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -162,11 +162,54 @@ void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
     avio_wb32(pb, 0);
 }
 
+static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc)
+{
+    const AVRational time_base = {1, 1000};
+    AVChapter *ch = s->chapters[id];
+    AVDictionaryEntry *e = NULL;
+    uint8_t *dyn_buf = NULL;
+    AVIOContext *dyn_bc;
+    char *name;
+    int len, start, end;
+
+    if (avio_open_dyn_buf(&dyn_bc) < 0)
+        return AVERROR(ENOMEM);
+    name = av_asprintf("ch%d", id);
+    if (!name) {
+        av_freep(&dyn_buf);
+        return AVERROR(ENOMEM);
+    }
+
+    start = av_rescale_q(ch->start, ch->time_base, time_base);
+    end   = av_rescale_q(ch->end,   ch->time_base, time_base);
+
+    avio_put_str(dyn_bc, name);
+    avio_wb32(dyn_bc, start);
+    avio_wb32(dyn_bc, end);
+    avio_wb32(dyn_bc, 0xFFFFFFFFu);
+    avio_wb32(dyn_bc, 0xFFFFFFFFu);
+    e = av_dict_get(ch->metadata, "title", NULL, 0);
+    if (e)
+        id3v2_put_ttag(id3, dyn_bc, e->value, NULL, MKBETAG('T', 'I', 'T', '2'), enc);
+
+    len = avio_close_dyn_buf(dyn_bc, &dyn_buf);
+
+    avio_wb32(s->pb, MKBETAG('C', 'H', 'A', 'P'));
+    avio_wb32(s->pb, len);
+    avio_wb16(s->pb, 0);
+    avio_write(s->pb, dyn_buf, len);
+    av_freep(&dyn_buf);
+    av_freep(&name);
+
+    return len + ID3v2_HEADER_SIZE;
+}
+
 int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
 {
     AVDictionaryEntry *t = NULL;
     int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
                                   ID3v2_ENCODING_UTF8;
+    int i, ret;
 
     ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
     if (id3->version == 3)
@@ -175,8 +218,6 @@ int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
         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(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) {
             id3->len += ret;
             continue;
@@ -193,6 +234,12 @@ int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
         id3->len += ret;
     }
 
+    for (i = 0; i < s->nb_chapters; i++) {
+        if ((ret = write_chapter(s, id3, i, enc)) < 0)
+            return ret;
+        id3->len += ret;
+    }
+
     return 0;
 }
 
-- 
1.7.11.2



More information about the ffmpeg-devel mailing list