This patch is in reference to 
https://lists.libav.org/pipermail/libav-devel/2014-May/059933.html

Adding av_metadata_updated() to check for any metadata updates on the
stream. Adding av_dict_version() to help in identifying metadata changes
quickly. Since this data is usually only used for display, it should
be fine for an application just to go through all displayed metadata
and update as necessary rather than presenting all changes.

---
 libavformat/avformat.h | 14 ++++++++++++++
 libavformat/utils.c    | 27 +++++++++++++++++++++++++++
 libavutil/dict.c       |  8 ++++++++
 libavutil/dict.h       | 10 ++++++++++
 4 files changed, 59 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;
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 3b95aba..7e49bbe 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -27,6 +27,7 @@

 struct AVDictionary {
     int count;
+    uint64_t version;
     AVDictionaryEntry *elems;
 };

@@ -75,6 +76,8 @@ int av_dict_set(AVDictionary **pm, const char *key, const 
char *value,
     if (!m)
         m = *pm = av_mallocz(sizeof(*m));

+    m->version++;
+
     if (tag) {
         if (flags & AV_DICT_DONT_OVERWRITE)
             return 0;
@@ -117,6 +120,11 @@ int av_dict_set(AVDictionary **pm, const char *key, const 
char *value,
     return 0;
 }

+uint64_t av_dict_version(const AVDictionary *m)
+{
+    return m ? m->version : 0;
+}
+
 static int parse_key_value_pair(AVDictionary **pm, const char **buf,
                                 const char *key_val_sep, const char *pairs_sep,
                                 int flags)
diff --git a/libavutil/dict.h b/libavutil/dict.h
index e0a91ae..d7415c3 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -25,6 +25,8 @@
 #ifndef AVUTIL_DICT_H
 #define AVUTIL_DICT_H

+#include <stdint.h>
+
 /**
  * @addtogroup lavu_dict AVDictionary
  * @ingroup lavu_data
@@ -107,6 +109,14 @@ int av_dict_count(const AVDictionary *m);
 int av_dict_set(AVDictionary **pm, const char *key, const char *value, int 
flags);

 /**
+ * Get the version of number for the current state of the dictionary. Whenever
+ * an item is changed, this number is incremented.
+ *
+ * @return >= 0 for any changes, 0 for an empty dictionary
+ */
+uint64_t av_dict_version(const AVDictionary *m);
+
+/**
  * Parse the key/value pairs list and add to a dictionary.
  *
  * @param key_val_sep  a 0-terminated list of characters used to separate
--
2.0.0.rc2

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

Reply via email to