#9649 closed defect (invalid)
filter_complex drops per-stream metadata
Reported by: | Arnon | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | undetermined |
Version: | 4.4.3 | Keywords: | filter_complex metadata |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
When applying a simple filter, ffmpeg by default correctly copies per-stream metadata. The equivalent complex filter however drops per-stream metadata. Adding -map_metadata 0 does not fix this behaviour.
Here is an example including language and title of a video stream in an mkv file:
From ffprobe input.mkv:
Stream #0:0(jpn): Video: h264 (High), yuv420p(tv, bt709/unknown/unknown, progressive), 720x480 [SAR 853:720 DAR 853:480], SAR 186:157 DAR 279:157, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default) Metadata: title : h.264
Running a simple filter on the video stream produces identical metadata, as expected:
ffmpeg -i input.mkv -map 0:v:0 -vf copy -t 10 output.mkv
From ffprobe output.mkv:
Stream #0:0(jpn): Video: h264 (High), yuv420p(tv, bt709/unknown/unknown, progressive), 720x480 [SAR 186:157 DAR 279:157], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default) Metadata: title : h.264 ENCODER : Lavc58.134.100 libx264 DURATION : 00:00:10.010000000
However, running the (I believe) equivalent complex filter does not:
ffmpeg -i input.mkv -map 0:v:0 -filter_complex "[v]copy" -t 10 output.mkv
From ffprobe output.mkv:
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709/unknown/unknown, progressive), 720x480 [SAR 186:157 DAR 279:157], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default) Metadata: ENCODER : Lavc58.134.100 libx264 DURATION : 00:00:10.010000000
Here is an example of language in an audio stream in an mp4 file:
From ffprobe input.mp4:
Stream #0:1(spa): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 134 kb/s (default) Metadata: handler_name : SoundHandler vendor_id : [0][0][0][0]
ffmpeg -i input.mp4 -map 0:a:0 -af acopy output.mp4
From ffprobe output.mp4, expected behaviour with simple filter:
Stream #0:0(spa): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 104 kb/s (default) Metadata: handler_name : SoundHandler vendor_id : [0][0][0][0]
ffmpeg -i input.mp4 -map 0:a:0 -filter_complex "[a]acopy" output.mp4
From ffprobe output.mp4, language is missing with complex filter (note that title is also missing, but is not listed because of https://trac.ffmpeg.org/ticket/7349):
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 104 kb/s (default) Metadata: handler_name : SoundHandler vendor_id : [0][0][0][0]
The problem appears robust across different filters, streams, and containers. Here is another report of this issue from over 2 years ago: https://www.reddit.com/r/ffmpeg/comments/hp7agi/metadata_is_not_copied_when_using_complex_filter/ I can reproduce it with ffmpeg 3.4.9 and ffmpeg 4.4.1.
For interest, here is the complete diff of the output from the previous 2 ffmpeg commands:
29c29,30 < Stream #0:1 -> #0:0 (aac (native) -> aac (native)) --- > Stream #0:1 (aac) -> acopy > acopy -> Stream #0:0 (aac) 37c38 < Stream #0:0(spa): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default) --- > Stream #0:0: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default) 39,40d39 < handler_name : SoundHandler < vendor_id : [0][0][0][0] 42c41 size= 131kB time=00:00:09.98 bitrate= 107.2kbits/s speed=35.5x --- size= 131kB time=00:00:09.98 bitrate= 107.2kbits/s speed= 33x 44c43 < [aac @ 0x55cdeb704e80] Qavg: 14367.665 --- > [aac @ 0x560ae8d33680] Qavg: 14367.665
ffmpeg information:
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 11 (GCC) configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ' --extra-cflags=' -I/usr/include/rav1e' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --enable-chromaprint --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libbs2b --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libilbc --enable-libmp3lame --enable-libmysofa --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librav1e --enable-librtmp --enable-librubberband --enable-libsmbclient --enable-version3 --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-version3 --enable-vapoursynth --enable-libvpx --enable-vulkan --enable-libglslang --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxml2 --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-avfilter --enable-avresample --enable-libmodplug --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-lto --enable-libmfx --enable-runtime-cpudetect libavutil 56. 70.100 / 56. 70.100 libavcodec 58.134.100 / 58.134.100 libavformat 58. 76.100 / 58. 76.100 libavdevice 58. 13.100 / 58. 13.100 libavfilter 7.110.100 / 7.110.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100
Change History (3)
follow-up: 2 comment:1 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
follow-up: 3 comment:2 by , 3 years ago
Replying to Nicolas George:
The point of
-filter_complex
is that there is no 1:1 map between input and output. Therefore there is no map to decide which metadata to copy. Therefore, not copying metadata unless explicitly specified is the expected behavior.
What's the command for explicitly copying metadata? It was already said that adding -map_metadata 0 doesn't fix the problem.
Michael
comment:3 by , 3 years ago
What's the command for explicitly copying metadata? It was already said that adding -map_metadata 0 doesn't fix the problem.
Nicolas is saying that the metadata map must be explicitly specified. For the first example above, this would be -map_metadata:s:v:0 0:s:v:0. For videos with multiple streams however, all output streams (regardless of whether or not they are filtered) would have to be specified this way to preserve all stream metadata (since a single map disables all mappings). Not great, but also not a bug if it's this way by design.
The point of
-filter_complex
is that there is no 1:1 map between input and output. Therefore there is no map to decide which metadata to copy. Therefore, not copying metadata unless explicitly specified is the expected behavior.