Opened 10 months ago

Closed 10 months ago

Last modified 10 months ago

#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)

comment:1 by Cigaes, 10 months ago

Resolution: invalid
Status: newclosed

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.

in reply to:  1 ; comment:2 by Michael Koch, 10 months 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

in reply to:  2 comment:3 by Arnon, 10 months 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.

Note: See TracTickets for help on using tickets.