[FFmpeg-devel] [PATCH] libavformat/hls: Support metadata updates from subdemuxers

rshaffer at tunein.com rshaffer at tunein.com
Fri Feb 2 04:44:34 EET 2018


From: Richard Shaffer <rshaffer at tunein.com>

If a subdemuxer has the updated metadata event flag set, the metadata is copied
to the corresponding stream. The flag is cleared on the subdemuxer and the
appropriate event flag is set on the stream.
---
This is semi-related to a patch I recently sent to enable parsing ID3 tags from
.aac files between ADTS headers. However, it may be generically useful for
other segment formats that support metadata updates.

-Richard

 libavformat/hls.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/libavformat/hls.c b/libavformat/hls.c
index 9bd54c84cc..e48845de34 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1062,6 +1062,7 @@ static void handle_id3(AVIOContext *pb, struct playlist *pls)
             /* demuxer not yet opened, defer picture attachment */
             pls->id3_deferred_extra = extra_meta;
 
+        ff_id3v2_parse_priv_dict(&metadata, &extra_meta);
         av_dict_copy(&pls->ctx->metadata, metadata, 0);
         pls->id3_initial = metadata;
 
@@ -1589,6 +1590,34 @@ static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pl
     }
 }
 
+/* update metadata on main streams, if necessary */
+static void update_metadata_from_subdemuxer(struct playlist *pls, int ignore_flags) {
+    int i;
+
+    if (pls->n_main_streams) {
+        AVStream *st = pls->main_streams[0];
+        if (ignore_flags) {
+            av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
+        } else if (pls->ctx->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
+            av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
+            pls->ctx->event_flags &= ~AVFMT_EVENT_FLAG_METADATA_UPDATED;
+            st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
+        }
+    }
+
+    for (i = 0; i < pls->ctx->nb_streams; i++) {
+        AVStream *ist = pls->ctx->streams[i];
+        AVStream *st = pls->main_streams[i];
+        if (ignore_flags) {
+            av_dict_copy(&st->metadata, ist->metadata, 0);
+        } else if (ist->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
+            av_dict_copy(&st->metadata, ist->metadata, 0);
+            ist->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
+            st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
+        }
+    }
+}
+
 /* if timestamp was in valid range: returns 1 and sets seq_no
  * if not: returns 0 and sets seq_no to closest segment */
 static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
@@ -1960,6 +1989,7 @@ static int hls_read_header(AVFormatContext *s)
         if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
             ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
             avformat_queue_attached_pictures(pls->ctx);
+            ff_id3v2_parse_priv(pls->ctx, &pls->id3_deferred_extra);
             ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
             pls->id3_deferred_extra = NULL;
         }
@@ -1986,6 +2016,12 @@ static int hls_read_header(AVFormatContext *s)
         if (ret < 0)
             goto fail;
 
+        /*
+         * Copy any metadata from playlist to main streams, but do not set
+         * event flags.
+         */
+        update_metadata_from_subdemuxer(pls, 1);
+
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
         add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
@@ -2170,6 +2206,8 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
             return ret;
         }
 
+        update_metadata_from_subdemuxer(pls, 0);
+
         /* check if noheader flag has been cleared by the subdemuxer */
         if (pls->has_noheader_flag && !(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER)) {
             pls->has_noheader_flag = 0;
-- 
2.14.3 (Apple Git-98)



More information about the ffmpeg-devel mailing list