Search code examples
ffmpegvp9

Cannot encode vp9 video with alpha to ivf container


I'm trying to convert a vp8/webm video with transparency to vp9 and ivf container. I can encode the video to vp9 into webm container with the following command which correctly produces a vp9 video with transparency:

ffmpeg -c:v libvpx -i dancer1.webm -c:v libvpx-vp9 dancer_vp9.webm

So basically forcing libvpx encoders instead of ffmpeg native ones to support alpha.

However if I try to use ivf container instead of webm the resulting video does not have transparency:

ffmpeg -c:v libvpx -i dancer1.webm -c:v libvpx-vp9 dancer_vp9.ivf

Does not have transparency when played with VLC, when converting frames to PNG using ffmpeg (ffmpeg -c:v libvpx-vp9 -i dancer_vp9.ivf -vf "select=eq(n\,0)" frame.png) and when played in Chrome (using webcodecs API). Does ivf not support alpha channel somehow or am I doing something wrong?

I also tried copying the stream with alpha from webm container to ivf (ffmpeg -i dancer1_vp9.webm -c copy dancer1_vp9_copy.ivf) which produces the same result, no transparency.

Curiously if I force or don't force libvpx decoder (which is required to support transparency, ffmpeg native one seems to just discard the alpha channel) when reading vp8/vp9 webm video it produces the same result when outputting to ivf container, while when outputting to webm container the resulting video has alpha when using libvpx decoder and not when using native ffmepg decoder.

ffprobe output of created ivf file:

ffprobe version 5.0.1 Copyright (c) 2007-2022 the FFmpeg developers
  built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
  configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/5.0.1_3 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-neon
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Input #0, ivf, from 'dancer_vp9.ivf':
  Duration: 00:01:02.87, start: 0.000000, bitrate: 249 kb/s
  Stream #0:0: Video: vp9 (Profile 0) (VP90 / 0x30395056), yuv420p(tv), 640x360, 30 tbr, 30 tbn

Solution

  • The alpha component is emitted separately by vpx encoders and stored adjacent to the main packet in the container. Only Matroska / WebM support writing this side data.