[FFmpeg-devel] [PATCH 3/4] avformat/matroskaenc: Don't check twice whether to write tags

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Wed Jun 15 15:01:15 EEST 2022


Because not all metadata is written as tags, the Matroska muxer
filters out the tags that are not written as tags.
Therefore the code first checks whether a Tag master element
needs to be opened for a given stream/chapter/attachment/global
metadata. If the answer turns out to be yes, it is checked again
whether a given AVDictionaryEntry is written as a tag.
This commit changes this: The Tag element is opened unconditionally
and in case it turns out that it was unneeded, it is discarded again.
This is possible because the Tag element is written into its own
dynamic buffer.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
 libavformat/matroskaenc.c | 40 +++++++++++----------------------------
 1 file changed, 11 insertions(+), 29 deletions(-)

diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 404fbdf579..f1385c6b21 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1953,7 +1953,7 @@ static int mkv_write_tag(MatroskaMuxContext *mkv, const AVDictionary *m,
     const AVDictionaryEntry *t = NULL;
     AVIOContext *const tmp_bc = mkv->tmp_bc;
     uint8_t *buf;
-    int ret, size;
+    int ret = 0, size, tag_written = 0;
 
     mkv_write_tag_targets(mkv, tmp_bc, elementid, uid);
 
@@ -1962,10 +1962,13 @@ static int mkv_write_tag(MatroskaMuxContext *mkv, const AVDictionary *m,
             ret = mkv_write_simpletag(tmp_bc, t);
             if (ret < 0)
                 goto end;
+            tag_written = 1;
         }
     }
     if (reserved_size)
         put_ebml_void(tmp_bc, reserved_size);
+    else if (!tag_written)
+        goto end;
 
     size = avio_get_dyn_buf(tmp_bc, &buf);
     if (tmp_bc->error) {
@@ -1984,17 +1987,6 @@ end:
     return ret;
 }
 
-static int mkv_check_tag(const AVDictionary *m, uint32_t elementid)
-{
-    const AVDictionaryEntry *t = NULL;
-
-    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
-        if (mkv_check_tag_name(t->key, elementid))
-            return 1;
-
-    return 0;
-}
-
 static int mkv_write_tags(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
@@ -2004,11 +1996,9 @@ static int mkv_write_tags(AVFormatContext *s)
 
     ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
 
-    if (mkv_check_tag(s->metadata, 0)) {
-        ret = mkv_write_tag(mkv, s->metadata, &mkv->tags.bc, 0, 0, 0);
-        if (ret < 0)
-            return ret;
-    }
+    ret = mkv_write_tag(mkv, s->metadata, &mkv->tags.bc, 0, 0, 0);
+    if (ret < 0)
+        return ret;
 
     for (i = 0; i < s->nb_streams; i++) {
         const AVStream *st = s->streams[i];
@@ -2017,9 +2007,6 @@ static int mkv_write_tags(AVFormatContext *s)
         if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT)
             continue;
 
-        if (!seekable && !mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID))
-            continue;
-
         ret = mkv_write_tag(mkv, st->metadata, &mkv->tags.bc,
                             seekable ? DURATION_SIMPLETAG_SIZE : 0,
                             MATROSKA_ID_TAGTARGETS_TRACKUID, track->uid);
@@ -2037,9 +2024,6 @@ static int mkv_write_tags(AVFormatContext *s)
             if (st->codecpar->codec_type != AVMEDIA_TYPE_ATTACHMENT)
                 continue;
 
-            if (!mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID))
-                continue;
-
             ret = mkv_write_tag(mkv, st->metadata, &mkv->tags.bc, 0,
                                 MATROSKA_ID_TAGTARGETS_ATTACHUID, track->uid);
             if (ret < 0)
@@ -2124,12 +2108,10 @@ static int mkv_write_chapters(AVFormatContext *s)
         if (tags) {
             ff_metadata_conv(&c->metadata, ff_mkv_metadata_conv, NULL);
 
-            if (mkv_check_tag(c->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) {
-                ret = mkv_write_tag(mkv, c->metadata, tags, 0,
-                                    MATROSKA_ID_TAGTARGETS_CHAPTERUID, uid);
-                if (ret < 0)
-                    goto fail;
-            }
+            ret = mkv_write_tag(mkv, c->metadata, tags, 0,
+                                MATROSKA_ID_TAGTARGETS_CHAPTERUID, uid);
+            if (ret < 0)
+                goto fail;
         }
     }
     end_ebml_master(dyn_cp, editionentry);
-- 
2.34.1



More information about the ffmpeg-devel mailing list