PR #25225 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25225
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25225.patch


>From d13abb5f8d4ddd0ce66453c42010725cb3a059b1 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 19 Oct 2026 21:21:04 +0200
Subject: [PATCH 1/2] avformat/asfdec_f: pass the target dictionary to
 get_tag()

Allows storing tags in a dictionary other than the format metadata.

Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavformat/asfdec_f.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index d02c843ba6..158c70d295 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -217,7 +217,8 @@ static uint64_t get_value(AVIOContext *pb, int type)
     }
 }
 
-static void get_tag(AVFormatContext *s, const char *key, int type, int len)
+static void get_tag(AVFormatContext *s, AVDictionary **metadata,
+                    const char *key, int type, int len)
 {
     ASFContext *asf = s->priv_data;
     char *value = NULL;
@@ -264,7 +265,7 @@ static void get_tag(AVFormatContext *s, const char *key, 
int type, int len)
         goto finish;
     }
     if (*value)
-        av_dict_set(&s->metadata, key, value, 0);
+        av_dict_set(metadata, key, value, 0);
 
 finish:
     av_freep(&value);
@@ -536,10 +537,10 @@ static int asf_read_content_desc(AVFormatContext *s)
     len3 = avio_rl16(pb);
     len4 = avio_rl16(pb);
     len5 = avio_rl16(pb);
-    get_tag(s, "title", 0, len1);
-    get_tag(s, "author", 0, len2);
-    get_tag(s, "copyright", 0, len3);
-    get_tag(s, "comment", 0, len4);
+    get_tag(s, &s->metadata, "title", 0, len1);
+    get_tag(s, &s->metadata, "author", 0, len2);
+    get_tag(s, &s->metadata, "copyright", 0, len3);
+    get_tag(s, &s->metadata, "comment", 0, len4);
     avio_skip(pb, len5);
 
     return 0;
@@ -577,7 +578,7 @@ static int asf_read_ext_content_desc(AVFormatContext *s)
         else if (!strcmp(name, "AspectRatioY"))
             asf->dar[0].den = get_value(s->pb, value_type);
         else
-            get_tag(s, name, value_type, value_len);
+            get_tag(s, &s->metadata, name, value_type, value_len);
     }
 
     return 0;
@@ -644,7 +645,7 @@ static int asf_read_metadata(AVFormatContext *s)
             if(stream_num < 128)
                 asf->dar[stream_num].den = aspect_y;
         } else {
-            get_tag(s, name, value_type, value_len);
+            get_tag(s, &s->metadata, name, value_type, value_len);
         }
         av_freep(&name);
     }
@@ -775,17 +776,17 @@ static int asf_read_header(AVFormatContext *s)
                     len= avio_rl32(pb);
                     if (len > UINT16_MAX)
                         return AVERROR_INVALIDDATA;
-                    get_tag(s, "ASF_Protection_Type", -1, len);
+                    get_tag(s, &s->metadata, "ASF_Protection_Type", -1, len);
 
                     len= avio_rl32(pb);
                     if (len > UINT16_MAX)
                         return AVERROR_INVALIDDATA;
-                    get_tag(s, "ASF_Key_ID", -1, len);
+                    get_tag(s, &s->metadata, "ASF_Key_ID", -1, len);
 
                     len= avio_rl32(pb);
                     if (len > UINT16_MAX)
                         return AVERROR_INVALIDDATA;
-                    get_tag(s, "ASF_License_URL", -1, len);
+                    get_tag(s, &s->metadata, "ASF_License_URL", -1, len);
                 } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {
                     av_log(s, AV_LOG_WARNING,
                            "Ext DRM protected stream detected, decoding will 
likely fail!\n");
-- 
2.54.0


>From 78d04d9b4118de166caa139ba089a97d9928f45d Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Mon, 19 Oct 2026 21:21:04 +0200
Subject: [PATCH 2/2] avformat/asfdec_f: export stream-specific metadata in the
 stream

Store such entries in the metadata of the corresponding stream.

Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavformat/asfdec_f.c             | 15 ++++++++++++++-
 tests/fate/microsoft.mak           |  6 +++++-
 tests/ref/fate/asf-stream-metadata | 19 +++++++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 tests/ref/fate/asf-stream-metadata

diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c
index 158c70d295..4c9925bc39 100644
--- a/libavformat/asfdec_f.c
+++ b/libavformat/asfdec_f.c
@@ -70,6 +70,8 @@ typedef struct ASFStream {
 
     int payload_ext_ct;
     ASFPayload payload[8];
+
+    AVDictionary *metadata;
 } ASFStream;
 
 typedef struct ASFContext {
@@ -645,7 +647,9 @@ static int asf_read_metadata(AVFormatContext *s)
             if(stream_num < 128)
                 asf->dar[stream_num].den = aspect_y;
         } else {
-            get_tag(s, &s->metadata, name, value_type, value_len);
+            get_tag(s, stream_num > 0 && stream_num < 128 ? 
&asf->streams[stream_num].metadata
+                                                          : &s->metadata,
+                    name, value_type, value_len);
         }
         av_freep(&name);
     }
@@ -818,6 +822,10 @@ static int asf_read_header(AVFormatContext *s)
         int stream_num = asf->asfid2avid[i];
         if (stream_num >= 0) {
             AVStream *st = s->streams[stream_num];
+            int ret = av_dict_copy(&st->metadata, asf->streams[i].metadata, 0);
+            if (ret < 0)
+                return ret;
+            ff_metadata_conv(&st->metadata, NULL, ff_asf_metadata_conv);
             if (!st->codecpar->bit_rate)
                 st->codecpar->bit_rate = asf->stream_bitrates[i];
             if (asf->dar[i].num > 0 && asf->dar[i].den > 0) {
@@ -1431,7 +1439,11 @@ static void skip_to_key(AVFormatContext *s)
 
 static int asf_read_close(AVFormatContext *s)
 {
+    ASFContext *asf = s->priv_data;
+
     asf_reset_header(s);
+    for (int i = 0; i < 128; i++)
+        av_dict_free(&asf->streams[i].metadata);
 
     return 0;
 }
@@ -1618,6 +1630,7 @@ const FFInputFormat ff_asf_demuxer = {
     .p.flags        = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH,
     .p.priv_class   = &asf_class,
     .priv_data_size = sizeof(ASFContext),
+    .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
     .read_probe     = asf_probe,
     .read_header    = asf_read_header,
     .read_packet    = asf_read_packet,
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index 8d8e92575a..006ad34840 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -83,7 +83,11 @@ fate-vc1: $(FATE_VC1-yes)
 FATE_MICROSOFT-$(call ALLYES, PIPE_PROTOCOL ASF_DEMUXER FRAMECRC_MUXER) += 
fate-asf-repldata
 fate-asf-repldata: CMD = framecrc -i $(TARGET_SAMPLES)/asf/bug821-2.asf -c copy
 
+FATE_MICROSOFT_FFPROBE-$(CONFIG_ASF_DEMUXER) += fate-asf-stream-metadata
+fate-asf-stream-metadata: CMD = probe -show_entries format_tags:stream_tags 
$(TARGET_SAMPLES)/wmv8/wmv8_x8intra.wmv
+
 FATE_MICROSOFT += $(FATE_MICROSOFT-yes)
 
 FATE_SAMPLES_FFMPEG += $(FATE_MICROSOFT)
-fate-microsoft: $(FATE_MICROSOFT)
+FATE_SAMPLES_FFPROBE += $(FATE_MICROSOFT_FFPROBE-yes)
+fate-microsoft: $(FATE_MICROSOFT) $(FATE_MICROSOFT_FFPROBE-yes)
diff --git a/tests/ref/fate/asf-stream-metadata 
b/tests/ref/fate/asf-stream-metadata
new file mode 100644
index 0000000000..495a30ad64
--- /dev/null
+++ b/tests/ref/fate/asf-stream-metadata
@@ -0,0 +1,19 @@
+[STREAM]
+TAG:IsVBR=0
+TAG:DeviceConformanceTemplate=L2
+TAG:WM/WMADRCPeakReference=8322
+TAG:WM/WMADRCAverageReference=1228
+TAG:NumberOfFrames=110
+TAG:language=eng
+[/STREAM]
+[STREAM]
+TAG:IsVBR=0
+TAG:DeviceConformanceTemplate=@
+TAG:language=eng
+[/STREAM]
+[FORMAT]
+TAG:creation_time=2003-12-12T01:31:27.640000Z
+TAG:WMFSDKVersion=9.00.00.2980
+TAG:WMFSDKNeeded=0.0.0.0000
+TAG:IsVBR=0
+[/FORMAT]
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to