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

Set AVFMT_EVENT_FLAG_METADATA_UPDATED so applications can detect
mid-stream metadata changes without inspecting packet side data.



>From 7424b29f8340f9c4a5b3ef28f9691397b267ea53 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <[email protected]>
Date: Wed, 22 Apr 2026 20:50:33 -0500
Subject: [PATCH 1/3] avformat/mpegts: add FATE test for timed ID3 packet
 demuxing

---
 tests/fate/mpegts.mak               | 19 +++++++++++++++++++
 tests/ref/fate/mpegts-timed-id3     |  9 +++++++++
 tests/ref/fate/mpegts-timed-id3-hls |  8 ++++++++
 3 files changed, 36 insertions(+)
 create mode 100644 tests/ref/fate/mpegts-timed-id3
 create mode 100644 tests/ref/fate/mpegts-timed-id3-hls

diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak
index eaca8ec289..b4546969eb 100644
--- a/tests/fate/mpegts.mak
+++ b/tests/fate/mpegts.mak
@@ -20,6 +20,25 @@ fate-mpegts-probe-pmt-merge: SRC = 
$(TARGET_SAMPLES)/mpegts/pmtchange.ts
 fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) 
-merge_pmt_versions 1 -i "$(SRC)"
 
 
+FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-timed-id3
+fate-mpegts-timed-id3: SRC = $(TARGET_SAMPLES)/mpegts/timed-id3.ts
+fate-mpegts-timed-id3: CMD = run ffprobe$(PROGSSUF)$(EXESUF) \
+    -show_packets -select_streams 1 \
+    -show_entries packet=pts_time,size,flags:packet_side_data=type:format_tags 
\
+    -print_format default -bitexact -v 0 "$(SRC)"
+
+
+tests/data/timed-id3.m3u8: | tests/data
+       $(Q)printf 
'#EXTM3U\n#EXT-X-TARGETDURATION:2\n#EXTINF:2,\n$(TARGET_SAMPLES)/mpegts/timed-id3.ts\n#EXT-X-ENDLIST\n'
 > $@
+
+FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS HLS) += fate-mpegts-timed-id3-hls
+fate-mpegts-timed-id3-hls: tests/data/timed-id3.m3u8
+fate-mpegts-timed-id3-hls: CMD = run ffprobe$(PROGSSUF)$(EXESUF) \
+    -show_entries stream_tags:format_tags \
+    -print_format default -bitexact -v 0 \
+    "$(TARGET_PATH)/tests/data/timed-id3.m3u8"
+
+
 FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes)
 
 fate-mpegts: $(FATE_MPEGTS_PROBE-yes)
diff --git a/tests/ref/fate/mpegts-timed-id3 b/tests/ref/fate/mpegts-timed-id3
new file mode 100644
index 0000000000..25a5d291e4
--- /dev/null
+++ b/tests/ref/fate/mpegts-timed-id3
@@ -0,0 +1,9 @@
+[PACKET]
+pts_time=2.103222
+size=53
+flags=K__
+[SIDE_DATA]
+[/SIDE_DATA]
+[/PACKET]
+[FORMAT]
+[/FORMAT]
diff --git a/tests/ref/fate/mpegts-timed-id3-hls 
b/tests/ref/fate/mpegts-timed-id3-hls
new file mode 100644
index 0000000000..72cb432d7b
--- /dev/null
+++ b/tests/ref/fate/mpegts-timed-id3-hls
@@ -0,0 +1,8 @@
+[STREAM]
+TAG:variant_bitrate=0
+[/STREAM]
+[STREAM]
+TAG:variant_bitrate=0
+[/STREAM]
+[FORMAT]
+[/FORMAT]
-- 
2.52.0


>From d2450f75ae2610322294214276ab918bc5623b95 Mon Sep 17 00:00:00 2001
From: Romain Beauxis <[email protected]>
Date: Wed, 22 Apr 2026 20:51:17 -0500
Subject: [PATCH 2/3] avformat/mpegts: attach ID3 metadata from timed_id3
 packets as side data

Parse the ID3v2 tag carried in timed_id3 PES packets and attach the
resulting key/value pairs as AV_PKT_DATA_STRINGS_METADATA side data,
keeping the raw packet data intact.
---
 libavformat/mpegts.c            | 35 +++++++++++++++++++++++++++++++++
 tests/ref/fate/mpegts-timed-id3 |  4 ++++
 2 files changed, 39 insertions(+)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8eb3bae720..54a2e58c04 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -43,6 +43,7 @@
 #include "demux.h"
 #include "mpeg.h"
 #include "isom.h"
+#include "id3v2.h"
 #if CONFIG_ICONV
 #include <iconv.h>
 #endif
@@ -1026,6 +1027,34 @@ static void new_data_packet(const uint8_t *buffer, int 
len, AVPacket *pkt)
     pkt->size = len;
 }
 
+static int timed_id3_attach_metadata(AVFormatContext *s, AVPacket *pkt)
+{
+    FFIOContext id3_buf;
+    AVDictionary *metadata = NULL;
+    uint8_t *packed;
+    size_t packed_size;
+    int ret;
+
+    ffio_init_read_context(&id3_buf, pkt->data, pkt->size);
+    ff_id3v2_read_dict(&id3_buf.pub, &metadata, ID3v2_DEFAULT_MAGIC, NULL);
+
+    if (!av_dict_count(metadata)) {
+        av_dict_free(&metadata);
+        return 0;
+    }
+
+    packed = av_packet_pack_dictionary(metadata, &packed_size);
+    av_dict_free(&metadata);
+    if (!packed)
+        return AVERROR(ENOMEM);
+
+    ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA,
+                                  packed, packed_size);
+    if (ret < 0)
+        av_freep(&packed);
+    return ret;
+}
+
 static int new_pes_packet(PESContext *pes, AVPacket *pkt)
 {
     uint8_t *sd;
@@ -1080,6 +1109,12 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt)
         return AVERROR(ENOMEM);
     *sd = pes->stream_id;
 
+    if (pes->st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
+        int ret = timed_id3_attach_metadata(pes->stream, pkt);
+        if (ret < 0)
+            return ret;
+    }
+
     return 0;
 }
 
diff --git a/tests/ref/fate/mpegts-timed-id3 b/tests/ref/fate/mpegts-timed-id3
index 25a5d291e4..bb77fbf0dc 100644
--- a/tests/ref/fate/mpegts-timed-id3
+++ b/tests/ref/fate/mpegts-timed-id3
@@ -2,6 +2,10 @@
 pts_time=2.103222
 size=53
 flags=K__
+TAG:artist=test artist
+TAG:title=test title
+[SIDE_DATA]
+[/SIDE_DATA]
 [SIDE_DATA]
 [/SIDE_DATA]
 [/PACKET]
-- 
2.52.0


>From 70550bffa24e3a5680dcddf30a610d74d8afbdba Mon Sep 17 00:00:00 2001
From: Romain Beauxis <[email protected]>
Date: Wed, 22 Apr 2026 21:00:52 -0500
Subject: [PATCH 3/3] avformat/mpegts: update format metadata from timed_id3
 packets

Set AVFMT_EVENT_FLAG_METADATA_UPDATED so applications can detect
mid-stream metadata changes without inspecting packet side data.
---
 libavformat/mpegts.c                | 3 +++
 tests/ref/fate/mpegts-timed-id3     | 2 ++
 tests/ref/fate/mpegts-timed-id3-hls | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 54a2e58c04..bf624404c0 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1043,6 +1043,9 @@ static int timed_id3_attach_metadata(AVFormatContext *s, 
AVPacket *pkt)
         return 0;
     }
 
+    av_dict_copy(&s->metadata, metadata, 0);
+    s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+
     packed = av_packet_pack_dictionary(metadata, &packed_size);
     av_dict_free(&metadata);
     if (!packed)
diff --git a/tests/ref/fate/mpegts-timed-id3 b/tests/ref/fate/mpegts-timed-id3
index bb77fbf0dc..774e7e9a77 100644
--- a/tests/ref/fate/mpegts-timed-id3
+++ b/tests/ref/fate/mpegts-timed-id3
@@ -10,4 +10,6 @@ TAG:title=test title
 [/SIDE_DATA]
 [/PACKET]
 [FORMAT]
+TAG:artist=test artist
+TAG:title=test title
 [/FORMAT]
diff --git a/tests/ref/fate/mpegts-timed-id3-hls 
b/tests/ref/fate/mpegts-timed-id3-hls
index 72cb432d7b..afb5f729c7 100644
--- a/tests/ref/fate/mpegts-timed-id3-hls
+++ b/tests/ref/fate/mpegts-timed-id3-hls
@@ -1,5 +1,7 @@
 [STREAM]
 TAG:variant_bitrate=0
+TAG:artist=test artist
+TAG:title=test title
 [/STREAM]
 [STREAM]
 TAG:variant_bitrate=0
-- 
2.52.0

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

Reply via email to