// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

//! [windows]

    \section1 Configuring and building FFmpeg

    From the prepared MSYS2 shell, navigate to the \c{/c/FFmpeg} directory. In this
    directory, create a \c{build} directory which will contain the FFmpeg build
    artifacts, and navigate into it.

    \badcode
        cd /c/FFmpeg/build
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-configure} {../install}

    To configure FFmpeg for building with MSVC, specify the toolchain in addition to
    the other command line options:

    \badcode
        ../configure --prefix=../install --disable-doc --enable-network --enable-shared --toolchain=msvc
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-build} {C:\\FFmpeg\\install}

//! [windows]

//! [macos]

    \section1 Configuring and building FFmpeg

    Create a \c build directory inside the \c{~/ffmpeg} directory and navigate into it:

    \badcode
        mkdir ~/ffmpeg/build
        cd ~/ffmpeg/build
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-configure} {/usr/local/ffmpeg}

    In the previous code snippet, an absolute path was used for \c{--prefix} argument intentionally.
    If you specify a relative path (for example, \c{../install}), the dependencies will be referenced
    using this relative path and not the correct one using \c{@rpath}. Using absolute paths makes
    an FFmpeg build non-portable.
    To use relative paths and make FFmpeg build portable, you need to manually fix
    dependencies
    using \l{https://www.unix.com/man-page/osx/1/otool/}{otool}.

    \include building-FFmpeg-configure.qdocinc {common-build} {/usr/local/ffmpeg}

    \section2 Configuring and Building FFmpeg Universal Binaries

    To create universal binaries on macOS (for example, for both x86_64 and arm64 architectures),
    follow these steps:

    \list
        \li Configure and build FFmpeg for arm64 architecture:
            \badcode
                ../configure --prefix=/usr/local/ffmpeg/arm64 --disable-doc --enable-network \
                    --enable-shared --enable-cross-compile --arch=arm64 --cc="clang -arch arm64"
                make -j install
            \endcode
        \li Configure and build FFmpeg for x86_64 architecture:
            \badcode
                ../configure --prefix=/usr/local/ffmpeg/x86_64 --disable-doc --enable-network \
                    --enable-shared --enable-cross-compile --arch=x86_64 --cc="clang -arch x86_64"
                make -j install
            \endcode
        \li Combine the builds into a universal binary
            using \l{https://www.unix.com/man-page/osx/1/lipo/}{lipo}.
    \endlist

//! [macos]

//! [linux]

    \section1 Configuring and building FFmpeg

    Create a \c build directory inside the \c{~/ffmpeg} directory and navigate into it:

    \badcode
        mkdir ~/ffmpeg/build
        cd ~/ffmpeg/build
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-configure} {/usr/local/ffmpeg}

    If you're building FFmpeg with a security backend, choose the appropriate option:

    \badcode
        ../configure --enable-openssl # For OpenSSL
        ../configure --enable-gnutls # For GnuTLS
        ../configure --enable-libtls # For LibreSSL (libtls)
        ../configure --enable-mbedtls # For MbedTLS
    \endcode

    Make sure you have the corresponding developer package installed as mentioned earlier.

    \section2 Hardware Acceleration

    By default, FFmpeg is built without hardware acceleration unless the appropriate packages
    are installed. For better performance, especially on systems with GPU support, it’s
    recommended to install VAAPI development packages:

    \badcode
        apt-get install libva-dev
    \endcode

    This will enable FFmpeg to detect VAAPI support during configuration.

    If FFmpeg will be used with NVIDIA graphics cards, you should install the NVIDIA codec
    headers. These can be downloaded from the following repository:
    \l{https://github.com/FFmpeg/nv-codec-headers}{NVIDIA Codec Headers on GitHub}.

    To build and install the headers, run the following commands:

    \badcode
        mkdir ~/nv-codec-headers
        cd ~/nv-codec-headers
        git clone https://github.com/FFmpeg/nv-codec-headers.git
        mkdir build
        cd build
        make -j install
    \endcode

    Make sure to check the compatibility of the \c nv-codec-headers with your NVIDIA driver
    version, as newer \c nv-codec-headers may not be compatible with older driver versions.
    Refer to the official documentation for more details.

    \section1 Disabling Autodetect

    By default, FFmpeg attempts to automatically detect available dependencies on the build system.
    This includes hardware acceleration and security backends. If you want to disable autodetection
    (for example, to avoid compiling unnecessary dependencies), you can use:

    \badcode
        ../configure --disable-autodetect
    \endcode

    If you are building FFmpeg with any additional dependencies (like a security backend or
    hardware acceleration), ensure that the required libraries are installed on the target system.
    There are several ways to handle this:

    \list
        \li Deliver binaries of the dependencies together with FFmpeg.
        \li Ensure that the required binaries are installed on the target system.
        \li Implement library stubs that can look up the real libraries and return an error code if
        the real libraries aren't found.
    \endlist

    \section1 RPATH and RUNPATH on Linux

    On Linux, FFmpeg uses both RPATH and RUNPATH metadata sections to manage library paths.
    We recommend using the \c patchelf utility to set the correct runpath:

    \badcode
        patchelf --set-rpath "new/runpath" lib.so
    \endcode

    By default, \c patchelf modifies the RUNPATH, as RPATH is considered obsolete on Linux.
    To set a relative runpath, you can use the \c $ORIGIN variable, which makes the path relative
    to the location of the executable:

    \badcode
        patchelf --set-rpath "$ORIGIN/../lib" lib.so
    \endcode

    This approach ensures portability by linking libraries based on their relative locations.

    \section1 Building FFmpeg

    \include building-FFmpeg-configure.qdocinc {common-build} {/usr/local/ffmpeg}

//! [linux]

//! [android-windows]

    \section1 Configuring and building FFmpeg

    From the prepared MSYS2 shell, navigate to the \c{/c/FFmpeg} directory. In this
    directory, create a \c{build-android} directory which will contain the FFmpeg build
    artifacts, and navigate into it.

    \badcode
        cd /c/FFmpeg/build-android
    \endcode

    \include building-FFmpeg-configure.qdocinc {android-configure} {windows-x86_64}
    \include building-FFmpeg-configure.qdocinc {common-build} {C:\\FFmpeg\\install-android}

//! [android-windows]

//! [android-macos]

    \section1 Configuring and building FFmpeg

    Create a \c{build-android} directory inside the \c{~/ffmpeg} directory and navigate into it:

    \badcode
        mkdir ~/ffmpeg/build-android
        cd ~/ffmpeg/build-android
    \endcode

    \include building-FFmpeg-configure.qdocinc {android-configure} {darwin-x86_64}
    \include building-FFmpeg-configure.qdocinc {common-build} {../install-android}

//! [android-macos]

//! [android-linux]

    \section1 Configuring and building FFmpeg

    Create a \c{build-android} directory inside the \c{~/ffmpeg} directory and navigate into it:

    \badcode
        mkdir ~/ffmpeg/build-android
        cd ~/ffmpeg/build-android
    \endcode

    \include building-FFmpeg-configure.qdocinc {android-configure} {linux-x86_64}
    \include building-FFmpeg-configure.qdocinc {common-build} {../install-android}

//! [android-linux]

//! [common-arguments-explained]

    The \c{--prefix} argument specifies a path where the FFmpeg development
    libraries are installed after building. The documentation is not needed, but
    network features should be enabled. To build FFmpeg as static libraries, omit
    the \c{--enable-shared} option.

//! [common-arguments-explained]

// \1 is the FFmpeg install directory.
//! [common-build]

    Once the \c configure command finishes, build and install FFmpeg using the
    \c make command.

    \badcode
        make -j install
    \endcode

    If the build completes without errors, FFmpeg development libraries are
    installed in the \c \1 directory. If you build Qt Multimedia, this path is
    stored in the \c FFMPEG_DIR variable used when configuring Qt Multimedia.

//! [common-build]

// \1 is the FFmpeg install directory.
//! [common-configure]

    To configure FFmpeg, run:

    \badcode
        ../configure --prefix=\1 --disable-doc --enable-network --enable-shared
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-arguments-explained}

//! [common-configure]

// \1 is the host OS. Can be one of: "windows-x86_64", "linux-x86_64", "darwin-x86_64".
//! [android-configure]

    To configure FFmpeg, run:

    \badcode
        ../configure --prefix=../install-android --disable-doc --enable-network --enable-shared \
            --host-os=\1 --target-os=android \
            --enable-cross-compile --arch=${ARCH} --cpu=${CPU} \
            --enable-jni --enable-mediacodec \
            --sysroot=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/\1/sysroot \
            --sysinclude=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/\1/sysroot/usr/include/ \
            --cc=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/\1/bin/${TOOLCHAIN_ARCH}24-clang \
            --cxx=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/\1/bin/${TOOLCHAIN_ARCH}24-clang++ \
            --strip=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/\1/bin/llvm-strip
    \endcode

    \include building-FFmpeg-configure.qdocinc {common-arguments-explained}

    If you're building FFmpeg with a security backend, you have 4 options to choose from (the same
    as when building for Linux) but only OpenSSL is tested by QtMultimedia maintainers for now.
    Choose the appropriate option and add it during FFmpeg configuration:

    \badcode
        --enable-openssl # For OpenSSL
        --enable-gnutls # For GnuTLS
        --enable-libtls # For LibreSSL (libtls)
        --enable-mbedtls # For MbedTLS
    \endcode

    If you're using OpenSSL you also need to add following options during FFmpeg configuration.
    Don't forget to replace \c{<ANDROID_OPENSSL_INCLUDE_DIR>} and \c{<ANDROID_OPENSSL_LIBS_DIR>} with actual
    paths.

    \badcode
        --extra-cflags=-I<ANDROID_OPENSSL_INCLUDE_DIR> --extra-ldflags=-L<ANDROID_OPENSSL_LIBS_DIR>
    \endcode

    If security backend is included, you should take care about its delivery yourself, ensuring correct
    libraries are installed on target platform or using stubs. The OpenSSL libraries that are linked
    must be called \c{libssl.so} and \c{libcrypto.so}, without any versioning suffixes. The user has to
    guarantee that libraries are of the same ABI version as OpenSSL headers FFmpeg was compiled with.
    For more information, see \l{Adding OpenSSL Support for Android}.

    Google Play requires 16KB page sizes, to build compatible FFmpeg binaries, add the following
    configuration options to FFmpeg.

    \badcode
         --extra-ldflags=-Wl,-z,max-page-size=16384
    \endcode

    For Google Play requirements, see \l{Google Play 16 KB page size compatibility requirement}.

//! [android-configure]
