On Wed, 4 Jun 2014 14:33:03 -0400 Andrew Stone <[email protected]> wrote:
> 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; You somehow need this for AVStreams too. Ogg metadata is (for some reason) always per-stream. Note that ffmpeg has its own API for updating per-stream metadata (as packet side data), so it would be nice if we somehow could get an API that handles all cases well, instead of adding a new API every 3 months to make up for the failing of the previous API. _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
