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

Reply via email to