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
---
 doc/APIchanges         |  3 +++
 libavformat/avformat.h | 14 ++++++++++++++
 libavformat/utils.c    | 27 +++++++++++++++++++++++++++
 libavformat/version.h  |  2 +-
 4 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index c1934a9..5a6f82c 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@ libavutil:     2013-12-xx
 
 API changes, most recent first:
 
+2014-06-xx - xxxxxxx - lavf 55.20.0 - avformat.h
+  Add av_metadata_updated to check if metadata has changed since the last check
+
 2014-06-xx - xxxxxxx - lavu 53.18.0 - opt.h
   Add av_opt_get_dict_val/set_dict_val with AV_OPT_TYPE_DICT to support
   dictionary types being set as options.
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;
diff --git a/libavformat/version.h b/libavformat/version.h
index 0a9cb06..cff7e65 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 19
+#define LIBAVFORMAT_VERSION_MINOR 20
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
-- 
2.0.0.rc2

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

Reply via email to