[FFmpeg-devel] [PATCH] matroskaenc: write tags.

Anton Khirnov wyskas
Fri Mar 19 08:29:21 CET 2010


---
 libavformat/matroskaenc.c |   83 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 4263079..3def185 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -674,6 +674,86 @@ static int mkv_write_chapters(AVFormatContext *s)
     return 0;
 }
 
+static int mkv_write_tag(AVFormatContext *s, AVMetadataTag *t, unsigned int element_id,
+                         unsigned int uid)
+{
+    ebml_master tag, targets, simpletag;
+
+    tag     = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0);
+    targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0);
+    if (element_id)
+        put_ebml_uint(s->pb, element_id, uid);
+    end_ebml_master(s->pb, targets);
+
+    simpletag = start_ebml_master(s->pb, MATROSKA_ID_SIMPLETAG, 0);
+    put_ebml_string(s->pb, MATROSKA_ID_TAGNAME, t->key);
+    put_ebml_string(s->pb, MATROSKA_ID_TAGLANG, "und");
+    put_ebml_uint(  s->pb, MATROSKA_ID_TAGDEFAULT, 1);
+    put_ebml_string(s->pb, MATROSKA_ID_TAGSTRING, t->value);
+
+    end_ebml_master(s->pb, simpletag);
+    end_ebml_master(s->pb, tag);
+    return 0;
+}
+
+static int mkv_write_tags(AVFormatContext *s)
+{
+    MatroskaMuxContext *mkv = s->priv_data;
+    AVMetadataTag *t = NULL;
+    ebml_master        tags;
+    int              i, ret;
+
+    if (av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX)) {
+        ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, url_ftell(s->pb));
+        if (ret < 0) return ret;
+
+        tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
+
+        while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
+            if ((ret = mkv_write_tag(s, t, 0 , 0)) < 0)
+                return ret;
+
+        end_ebml_master(s->pb, tags);
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+
+        if (!av_metadata_get(st->metadata, "", 0, AV_METADATA_IGNORE_SUFFIX))
+            continue;
+
+        ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, url_ftell(s->pb));
+        if (ret < 0) return ret;
+
+        tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
+
+        while ((t = av_metadata_get(st->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
+            if ((ret = mkv_write_tag(s, t, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1)) < 0)
+                return ret;
+
+        end_ebml_master(s->pb, tags);
+    }
+
+    for (i = 0; i < s->nb_chapters; i++) {
+        AVChapter *ch = s->chapters[i];
+
+        if (!av_metadata_get(ch->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
+            continue;
+
+        ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, url_ftell(s->pb));
+        if (ret < 0) return ret;
+
+        tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0);
+
+        while ((t = av_metadata_get(ch->metadata, "", t, AV_METADATA_IGNORE_SUFFIX)))
+            if ((ret = mkv_write_tag(s, t, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id)) < 0)
+                return ret;
+
+        end_ebml_master(s->pb, tags);
+    }
+    return 0;
+}
+
 static int mkv_write_header(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
@@ -737,6 +817,9 @@ static int mkv_write_header(AVFormatContext *s)
     ret = mkv_write_chapters(s);
     if (ret < 0) return ret;
 
+    ret = mkv_write_tags(s);
+    if (ret < 0) return ret;
+
     if (url_is_streamed(s->pb))
         mkv_write_seekhead(pb, mkv->main_seekhead);
 
-- 
1.7.0




More information about the ffmpeg-devel mailing list