av_metadata_updated checks all metadata dictionaries and checks to see
if any option named "metadata" was set inside the context; if it was,
the value is merged into current context metadata.

Rather than maintaining a list of metadata changes and presenting them to
applications, applications must poll the changes to show updates. Typically,
this data is only used for display, so updating displayed information with
identical information should be acceptable.

References: https://lists.libav.org/pipermail/libav-devel/2014-May/059933.html
---
 libavformat/avformat.h | 14 ++++++++++++++
 libavformat/utils.c    | 27 +++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index b17c791..e4db20a 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1217,6 +1217,13 @@ typedef struct AVFormatContext {
      * Must not be accessed in any way by callers.
      */
     AVFormatInternal *internal;
+
+    /**
+     * For checking if metadata has changed anywhere in the stream. This
+     * value is a sum of all metadata dictionary versions. It's only
+     * updated from av_metadata_updated().
+     */
+    uint64_t metadata_version;
 } AVFormatContext;
 
 typedef struct AVPacketList {
@@ -1561,6 +1568,13 @@ int av_read_play(AVFormatContext *s);
 int av_read_pause(AVFormatContext *s);
 
 /**
+ * Determine if the metadata in the stream has changed.
+ *
+ * @return 0 if nothing has changed since last check; 1 otherwise.
+ */
+int av_metadata_updated(AVFormatContext *s);
+
+/**
  * Close an opened input AVFormatContext. Free it and all its contents
  * and set *s to NULL.
  */
diff --git a/libavformat/utils.c b/libavformat/utils.c
index de66c6b..41d9c1d 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2570,6 +2570,33 @@ int av_read_pause(AVFormatContext *s)
     return AVERROR(ENOSYS);
 }
 
+int av_metadata_updated(AVFormatContext *s)
+{
+    unsigned i;
+    uint64_t version;
+    AVDictionary *md = NULL;
+    uint64_t current = s->metadata_version;
+
+    av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &md);
+    if (md) {
+        av_dict_copy(&s->metadata, md, 0);
+        av_dict_free(&md);
+        av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+    }
+
+    version = av_dict_version(s->metadata);
+    for (i = 0; i < s->nb_streams; i++)
+        version += av_dict_version(s->streams[i]->metadata);
+    for (i = 0; i < s->nb_chapters; i++)
+        version += av_dict_version(s->chapters[i]->metadata);
+    for (i = 0; i < s->nb_programs; i++)
+        version += av_dict_version(s->programs[i]->metadata);
+
+    s->metadata_version = version;
+
+    return version != current;
+}
+
 void avformat_free_context(AVFormatContext *s)
 {
     int i, j;
-- 
2.0.0.rc2

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to