# FFVPX This directory contains files used in gecko builds from FFmpeg (http://ffmpeg.org). The current files are from FFmpeg as of revision 252fc2e047297697dea78e63aa908377b47c2136 git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg git checkout 252fc2e047297697dea78e63aa908377b47c2136 All source files match their path from the library's source archive. Currently, we only use the vp8, vp9, av1 (via libdav1d), mp3, flac, vorbis (via libvorbis), opus (via libopus) and PCM portion of the library. If this changes, configuration files will most likely need to be updated. On Windows, we use d3d11va for vp9 and av1. Decoding AV1 via libdav1d and libvorbis is supported, although the decoder libraries are vendored separately, `ffvpx` only contains the code to use those libraries through the `ffmpeg` API. The ffmpeg project recommends to use ffmpeg's tip, not a particular release. ## Source files This library only uses a small part of `ffmpeg`. To update the source tree run: > rsync -av --existing ffmpeg-upstream/* ffmpeg-mozilla-dir If the new version of ffmpeg requires source files we don't already package, they will not be copied over by this rsync command and will have to be added manually. Then, make sure the files: - `libavcodec/codec_list.c` - `libavcodec/bsf_list.c` - `libavcodec/parser_list.c` include conditional compilation directives, by probably reverting them (or reverting and adjusting them if new codecs are added). Revert and adjust libavcodec `dovi_rpu.h` and `lcevcdec.h` so that they contain just the necessary stubs to compile. We do this to avoid patent and other restrictions. When ffmpeg is being upgraded, be on the lookout for other files that may need to be stubbed out as well. ## Add headers for a new major ffmpeg version For historical reasons, we package ffmpeg according to the libavcodec version. Check `libavcodec/version_major.h`. The version number defined by `LIBAVCODEC_VERSION_MAJOR` is the version number we will be using. If a new major version of ffmpeg is being imported in the tree, it's necessary to manually copy the new ffmpeg headers into `dom/media/platforms/ffmpeg/ffmpegxx` where xx is the new ffmpeg major version number. Copy only the header files necessary to compile. Then, modify the dynamic linker wrapper in `dom/media/platforms/dom/media/platforms/ffmpeg/{FFmpegLibWrapper.cpp,FFmpegRungtimeLinker.cpp}` with the new version and the new API in this new version. ## `config.{h,asm}` generation Each platform needs its own `config.h` file and some need a `config.asm` file as well. For example, x86_64 Linux uses `config_unix64.h` and `config_unix64.asm`. Ideally, the existing configuration files should be usable without any changes. If changes are needed, it is preferable to update these files by hand. If this is not possible and the files need to be regenerated entirely, the `configure` script in the ffmpeg source directory can be used. The arguments used to create them can be found in the `FFMPEG_CONFIGURATION` define in the existing header files. For example, create `config.h` and `config.asm` for x86_64 Linux desktop by running `./configure` with the arguments from `config_unix64.h`. Then, copy the generated `config.h` and `config.asm` files over `config_unix64.h` and `config_unix64.asm`. For Linux Desktop, there are a number of overrides in `config_common.h` for VAAPI. We can't put them in `config_components.h` because this breaks the build. `config_components.h` is common to all platforms, and then a specific config file is included, based on the platform and architecture. macOS and Android are similar to Linux Desktop. Windows needs a bit more setup. # Windows The general idea is to get an msys prompt with an msvc toolchain configured, so that the configure script for ffmpeg can run successfully with the thread flavor Gecko prefers on Windows (win32, not pthreads). - Open Visual Studio (2019 when writing this) - Tools → Command Line → Developer command prompt - Check that compiling a small C program with cl.exe works - Install msys2 from https://www.msys2.org/ - From the Visual Studio Developer Command Prompt, run the following: > C:\msys64\msys2_shell.cmd -msys2 -use-full-path - This pops up a new shell window, with a 32-bits build environment - Check that compiling a small C program with `cl.exe` works. You may need to install additional packages by running `pacman`, such as: `pacman -S nasm`, `pacman -S pkgconf`, `pacman -S diffutils`. - Run ffmpeg's ./configure with the options needed from `config_win32.h`. - Copy `config.h` and `config.asm` as `config_win32.h` and `config_win32.asm` in this directory - Close the `msys2` window, go back to the `cmd.exe` window - Run this command, maybe substituting the Visual Studio version: > "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 - This pops up a new shell window, now with a 64-bits build environment - Check that compiling a small C program with `cl.exe` works - Run ffmpeg's `./configure` with the options needed from `config_win64.h`. - Copy `config.h` and `config.asm` as `config_win64.h` and `config_win64.asm`. For `config_aarch64_win64.h`: You will need to install cpp (either using msys or wsl), then run `configure` with the arguments from `config_aarch64_win64.h`. Once all of the config files have been generated, run the following command: > sed -i -E '/HAVE_(MALLOC_H|ARC4RANDOM|LOCALTIME_R|MEMALIGN|POSIX_MEMALIGN)/d' config.* to avoid redefined macros. # Build, fix errors Missing files need to be added, and the patch to rename `time.h` to `fftime.h` might need to be reapplied or extended to other files including `time.h`. The issue being that it's included instead of the system header, causing all sorts of issues. Additionally, `jni.h` and `jni.c` in ffmpeg sources need to be renamed to `fffjni.h` and `fffjni.c`, and `#include` to those files need to be updated. This is because there are header collisions with the JDK. `moz.build` files might need to be modified as well, in light of compilation and link errors. There are going to be a lot of changes in terms of symbols exported. Adjust `libavutil/avutil.symbols` and `libavcodec/avcodec.symbols` by removing and adding symbols until the build passes. You may also need to modify `/config/external/gkcodecs/gkcodecs.symbols`. Finally, apply the patches: - no-unicode-stdio.patch to avoid passing the infity symbol in unicode to an stdio.h function, that causes bug 1879740 issue on Windows. - opusenc-dtx.patch to allow enabling DTX in the opus encoder. - libaomenc-svc.patch to allow configuring SVC in the libaom encoder.