Opened 7 years ago
Last modified 2 years 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)
Change History (10)
by , 7 years ago
comment:1 by , 7 years ago
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 by , 7 years ago
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.
comment:3 by , 5 years ago
Cc: | added |
---|
comment:4 by , 5 years ago
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 by , 5 years ago
"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>
follow-up: 7 comment:6 by , 5 years ago
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 by , 5 years ago
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 by , 5 years ago
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.)
comment:9 by , 2 years ago
Hi, this behaviour still seems to be unchanged as of v5.1.2. Is there a way to suppress/override the encoder
metadata, both at the global and per-stream level? If not, is there intention to add/fix this? If this is wontfix, can anybody suggest a general way to remove encoder
tags from my files in lieu of using FFmpeg for this?
Many thanks
Output of ffmpeg -v 9 -loglevel 99 -i foo.ogg -acodec copy -metadata encoder='baz' bar.ogg