Opened 3 years ago

Last modified 2 months ago

#6602 new defect

Can't set or remove encoder metadata

Reported by: Psychonaut Owned by:
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: dev.rindeal+trac.ffmpeg.org@gmail.com Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug: According to the man page, the -metadata option can be used to set or remove the encoder tag on the output file. However, this doesn't work; ffmpeg always adds an encoder tag with the value "Lavf57.71.100".

How to reproduce:

% ffmpeg -i foo.ogg -acodec copy -metadata encoder='baz' bar.ogg
ffmpeg version 3.3.3 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 7 (SUSE Linux)
  configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include/ffmpeg --extra-cflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -g' --optflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -g' --disable-htmlpages --enable-pic --disable-stripping --enable-shared --disable-static --enable-gpl --disable-openssl --enable-avresample --enable-libcdio --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libcelt --enable-libcdio --enable-libdc1394 --enable-libfreetype --enable-libgsm --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-netcdf --enable-vaapi --enable-vdpau --enable-libfdk_aac --enable-nonfree --enable-libmp3lame --enable-libtwolame --enable-libx264 --enable-libx265 --enable-libxvid
  libavutil      55. 58.100 / 55. 58.100
  libavcodec     57. 89.100 / 57. 89.100
  libavformat    57. 71.100 / 57. 71.100
  libavdevice    57.  6.100 / 57.  6.100
  libavfilter     6. 82.100 /  6. 82.100
  libavresample   3.  5.  0 /  3.  5.  0
  libswscale      4.  6.100 /  4.  6.100
  libswresample   2.  7.100 /  2.  7.100
  libpostproc    54.  5.100 / 54.  5.100
Input #0, ogg, from 'foo.ogg':
  Duration: 00:02:42.54, start: 0.000000, bitrate: 107 kb/s
    Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      ARTIST          : Tristan Miller
      DATE            : 1997
      COMPOSER        : Roy Glover
      comment         : http://www.nothingisreal.com/
      GENRE           : C64 Remix
      LICENSE         : http://www.nothingisreal.com/
      PERFORMER       : Roy Glover
      REPLAYGAIN_ALBUM_GAIN: -6.73 dB
      REPLAYGAIN_ALBUM_PEAK: 1.12150097
      REPLAYGAIN_TRACK_GAIN: -6.73 dB
      REPLAYGAIN_TRACK_PEAK: 1.12150097
      TITLE           : M.U.L.E. (Boogie Addiction Mix)
    Side data:
      replaygain: track gain - -6.730000, track peak - 0.000026, album gain - -6.730000, album peak - 0.000026, 
Output #0, ogg, to 'bar.ogg':
  Metadata:
    encoder         : Lavf57.71.100
    Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      ARTIST          : Tristan Miller
      DATE            : 1997
      COMPOSER        : Roy Glover
      DESCRIPTION     : http://www.nothingisreal.com/
      GENRE           : C64 Remix
      LICENSE         : http://www.nothingisreal.com/
      PERFORMER       : Roy Glover
      REPLAYGAIN_ALBUM_GAIN: -6.73 dB
      REPLAYGAIN_ALBUM_PEAK: 1.12150097
      REPLAYGAIN_TRACK_GAIN: -6.73 dB
      REPLAYGAIN_TRACK_PEAK: 1.12150097
      TITLE           : M.U.L.E. (Boogie Addiction Mix)
      encoder         : Lavf57.71.100
    Side data:
      replaygain: track gain - -6.730000, track peak - 0.000026, album gain - -6.730000, album peak - 0.000026, 
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
size=    2132kB time=00:02:42.53 bitrate= 107.4kbits/s speed=6.35e+03x    
video:0kB audio:2106kB subtitle:0kB other streams:0kB global headers:4kB muxing overhead: 1.229537%

Attached is the console output of the above command with "-v 9 -loglevel 99".

Attachments (1)

out.log (1.4 MB) - added by Psychonaut 3 years ago.
Output of ffmpeg -v 9 -loglevel 99 -i foo.ogg -acodec copy -metadata encoder='baz' bar.ogg

Download all attachments as: .zip

Change History (9)

Changed 3 years ago by Psychonaut

Output of ffmpeg -v 9 -loglevel 99 -i foo.ogg -acodec copy -metadata encoder='baz' bar.ogg

comment:1 Changed 3 years ago by michelel

I suggest marking this ticket as invalid.

I debugged the issue and found that "encoder" metadata is flagged with "AV_DICT_DONT_OVERWRITE".

That means you cannot change the "encoder" label. However, you can provide a user-defined label if you're so inclined with the following command:

$ ffmpeg -i in.264 -metadata myEncoder=h265 -y out.h264

You'll get this output:

Metadata:

myEncoder : h265
encoder : Lavf57.78.100

Here's the code snippet I'm referring to:

ist = input_streams[output_streams[i]->source_index];
av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
if (!output_streams[i]->stream_copy) {

av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0);

}

comment:2 Changed 3 years ago by Psychonaut

I disagree that the issue is invalid, as the behaviour is at odds with what is written in the manual (which says that -metadata is used "to set metadata", not "to set metadata other than the encoder label"). If this is the intended behaviour, then the bug here is with the documentation, which should be updated. From doing some web searches, I see I'm not the only one who has been confused by this behaviour: https://stackoverflow.com/questions/22120041/prevent-libavformat-ffmpeg-from-adding-encoder-tag-to-output-help-strippin

Incidentally, I don't think that this should be the intended behaviour. Consider the command line in my original report, which uses -acodec copy on an audio file. Since FFmpeg is not changing the stream here, does it really make sense for it to add or replace the existing encoder label with its own? This sort of thing could hinder troubleshooting when FFmpeg is used to post-process files produced by another encoder.

Last edited 3 years ago by Psychonaut (previous) (diff)

comment:3 Changed 2 months ago by rindeal

  • Cc dev.rindeal+trac.ffmpeg.org@gmail.com added

comment:4 Changed 2 months ago by mkver

This metadata is added when muxing starts in init_muxer() in libavformat/mux.c:

    /* set muxer identification string */
    if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
        av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
    } else {
        av_dict_set(&s->metadata, "encoder", NULL, 0);
    }

You can set this AVFMT_FLAG_BITEXACT by using the -fflags +bitexact switch for the muxer.

comment:5 Changed 2 months ago by rindeal

"encoder" tag is also set by codecs and -bitexact doesn't help with that

> ffmpeg -hide_banner -f u8 -i /dev/zero -t 1 -bitexact -c:a pcm_u8 -f null -
<snip>
Output #0, null, to 'pipe:':
    Stream #0:0: Audio: pcm_u8, 44100 Hz, mono, u8, 352 kb/s
    Metadata:
      encoder         : Lavc pcm_u8
<snip>

comment:6 follow-up: Changed 2 months ago by mkver

av_dict_set() with a NULL parameter as value (like in the else branch of the code snippet I quoted above) deletes a tag of the name specified. In other words: It filters the libavcodec's encoder tag out. The metadata that you see comes from a stage before filtering it out. Write the output to an actual file and you'll see that it (normally) doesn't have this encoder tag.

(Some muxers also add something like this on their own. For e.g. Matroska this happens in lines 1842-1844 of matroskaenc.c.)

comment:7 in reply to: ↑ 6 Changed 2 months ago by rindeal

Replying to mkver:

av_dict_set() with a NULL parameter as value (like in the else branch of the code snippet I quoted above) deletes a tag of the name specified. In other words: It filters the libavcodec's encoder tag out. The metadata that you see comes from a stage before filtering it out. Write the output to an actual file and you'll see that it (normally) doesn't have this encoder tag.

Sadly, that is not the reality.

When using the same command as above, but writing it to Matroska, it produces this file:

+ EBML head
|+ EBML version: 1
|+ EBML read version: 1
|+ Maximum EBML ID length: 4
|+ Maximum EBML size length: 8
|+ Document type: matroska
|+ Document type version: 4
|+ Document type read version: 2
+ Segment: size 491
|+ Seek head (subentries will be skipped)
|+ EBML void: size 165
|+ Segment information
| + Timestamp scale: 1000000
| + Multiplexing application: Lavf
| + Writing application: Lavf
| + Duration: 00:00:00.000000000
|+ Tracks
| + Track
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
|  + Track UID: 1
|  + Lacing flag: 0
|  + Language: und
|  + Codec ID: A_PCM/INT/LIT
|  + Track type: audio
|  + Audio track
|   + Channels: 1
|   + Sampling frequency: 44100
|   + Bit depth: 8
|+ Tags
| + Tag
|  + Targets
|   + Track UID: 1
|  + Simple
|   + Name: ENCODER
|   + String: Lavc pcm_u8
| + Tag
|  + Targets
|   + Track UID: 1
|  + Simple
|   + Name: DURATION
|   + String: 00:00:00.000000000

Both tags are bloat.

(Some muxers also add something like this on their own. For e.g. Matroska this happens in lines 1842-1844 of matroskaenc.c.)

MATROSKA_ID_MUXINGAPP and MATROSKA_ID_WRITINGAPP are ok and per spec.

comment:8 Changed 2 months ago by mkver

You're right. Using bitexact at the muxing layer only removes the encoder tag of the AVFormatContext, not the ones from the AVStreams. (If you mux your pcm to wav, there won't be an encoder tag, but that is just because the wav muxer does not look at the AVStream's metadata.)

Note: See TracTickets for help on using tickets.