[FFmpeg-devel] [PATCH] Ignore duplicate ID3 tags if vorbis tags exist

wm4 nfxjfg at googlemail.com
Thu Jan 26 12:24:57 EET 2017


On Thu, 26 Jan 2017 11:08:45 +0100
Paul Arzelier <paul.arzelier at free.fr> wrote:

> From bb5dc73c42ad2e0bffd7e38fac18c6f01ec05ab3 Mon Sep 17 00:00:00 2001
> From: Paul Arzelier <paul.arzelier at free.fr>
> Date: Thu, 26 Jan 2017 11:04:44 +0100
> Subject: [PATCH] Fixed behavior when id3 tags were found on FLAC files
> Originally-by: Ben Boeckel <mathstuf at gmail.com>
> ---
>  libavformat/flacdec.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
> index 66baba5922..869936621b 100644
> --- a/libavformat/flacdec.c
> +++ b/libavformat/flacdec.c
> @@ -48,6 +48,7 @@ static int flac_read_header(AVFormatContext *s)
>      int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
>      uint8_t header[4];
>      uint8_t *buffer=NULL;
> +    int has_id3 = 0;
>      FLACDecContext *flac = s->priv_data;
>      AVStream *st = avformat_new_stream(s, NULL);
>      if (!st)
> @@ -63,6 +64,22 @@ static int flac_read_header(AVFormatContext *s)
>          return 0;
>      }
>  
> +    if (av_dict_count(s->metadata)) {
> +         /* XXX: Is there a better way to parse this out? ID3 parsing is done
> +         * all the way out in avformat_open_input. */
> +         has_id3 = 1;
> +    }
> +
> +    if (has_id3) {
> +         int level = AV_LOG_WARNING;
> +         if (s->error_recognition & AV_EF_COMPLIANT)
> +              level = AV_LOG_ERROR;
> +         av_log(s, level, "Spec-compliant flac files do not support ID3 tags.\n");
> +         if (s->error_recognition & AV_EF_EXPLODE)
> +              return AVERROR_INVALIDDATA;
> +    }
> +
> +
>      /* process metadata blocks */
>      while (!avio_feof(s->pb) && !metadata_last) {
>          if (avio_read(s->pb, header, 4) != 4)
> @@ -173,8 +190,16 @@ static int flac_read_header(AVFormatContext *s)
>              }
>              /* process supported blocks other than STREAMINFO */
>              if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
> +                AVDictionary *other_meta = NULL;
>                  AVDictionaryEntry *chmask;
>  
> +                if (has_id3) {
> +                    av_log(s, AV_LOG_VERBOSE, "FLAC found with ID3 and vorbis tags; ignoring ID3 tags also provided by vorbis.\n");
> +
> +                    other_meta = s->metadata;
> +                    s->metadata = NULL;
> +                }
> +
>                  ret = ff_vorbis_comment(s, &s->metadata, buffer, metadata_size, 1);
>                  if (ret < 0) {
>                      av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
> @@ -182,6 +207,11 @@ static int flac_read_header(AVFormatContext *s)
>                      s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
>                  }
>  
> +                if (other_meta) {
> +                    av_dict_copy(&s->metadata, other_meta, AV_DICT_DONT_OVERWRITE);
> +                    av_dict_free(&other_meta);
> +                }
> +
>                  /* parse the channels mask if present */
>                  chmask = av_dict_get(s->metadata, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0);
>                  if (chmask) {

I feel like there should be a more general solution.

ID3v2 tags are read by common code, and such tags are supported by
basically all file formats in libavformat due to the way it's
implemented.

This fixes it for FLAC only. Are we going to duplicate this for every
format?

I suggest reading id3 tags into a separate dict instead, and then
copying it in libavformat/utils.c after read_header if the demuxer
hasn't set any tags.


More information about the ffmpeg-devel mailing list