Skip to content

Instantly share code, notes, and snippets.

@captain-bugs
Forked from TinDang97/build_ffmpeg_cuda_debian
Created December 15, 2022 04:12
Show Gist options
  • Select an option

  • Save captain-bugs/f24df8ae70be0283b966f3b925fbd1b7 to your computer and use it in GitHub Desktop.

Select an option

Save captain-bugs/f24df8ae70be0283b966f3b925fbd1b7 to your computer and use it in GitHub Desktop.

Revisions

  1. @TinDang97 TinDang97 revised this gist Oct 24, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion build_ffmpeg_cuda_debian
    Original file line number Diff line number Diff line change
    @@ -233,7 +233,7 @@ echo "Installing prerequisites"
    sudo apt-get update
    sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev libgpac-dev \
    libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
    libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev cmake nasm gcc-7 g++-7
    libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev cmake nasm gcc-8 g++-8

    sudo ln -s $(which gcc-8) /usr/local/bin/gcc
    sudo ln -s $(which g++-8) /usr/local/bin/g++
  2. @TinDang97 TinDang97 renamed this gist Oct 24, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. @TinDang97 TinDang97 renamed this gist Oct 24, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. @TinDang97 TinDang97 created this gist Oct 24, 2020.
    603 changes: 603 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,603 @@
    #!/bin/bash

    # https://github.com/markus-perl/ffmpeg-build-script

    PROGNAME=$(basename $0)
    VERSION=1.18
    CWD=$(pwd)
    PACKAGES="$CWD/packages"
    WORKSPACE="$CWD/workspace"
    CFLAGS="-I$WORKSPACE/include"
    LDFLAGS="-L$WORKSPACE/lib"
    LDEXEFLAGS=""
    EXTRALIBS="-lpthread -lm -lz"
    CONFIGURE_OPTIONS=()

    # Speed up the process
    # Env Var NUMJOBS overrides automatic detection
    if [[ -n $NUMJOBS ]]; then
    MJOBS=$NUMJOBS
    elif [[ -f /proc/cpuinfo ]]; then
    MJOBS=$(grep -c processor /proc/cpuinfo)
    elif [[ "$OSTYPE" == "darwin"* ]]; then
    MJOBS=$(sysctl -n machdep.cpu.thread_count)
    CONFIGURE_OPTIONS=("--enable-videotoolbox")
    else
    MJOBS=4
    fi

    make_dir () {
    remove_dir "$1"
    if ! mkdir "$1"; then
    printf "\n Failed to create dir %s" "$1";
    exit 1
    fi
    }

    remove_dir () {
    if [ -d "$1" ]; then
    rm -r "$1"
    fi
    }

    download () {
    # download url [filename[dirname]]

    DOWNLOAD_PATH="$PACKAGES"
    DOWNLOAD_FILE=${2:-"${1##*/}"}

    if [[ "$DOWNLOAD_FILE" =~ "tar." ]]; then
    TARGETDIR="${DOWNLOAD_FILE%.*}"
    TARGETDIR=${3:-"${TARGETDIR%.*}"}
    else
    TARGETDIR=${3:-"${DOWNLOAD_FILE%.*}"}
    fi

    if [ ! -f "$DOWNLOAD_PATH/$DOWNLOAD_FILE" ]; then
    echo "Downloading $1"
    curl -L --silent -o "$DOWNLOAD_PATH/$DOWNLOAD_FILE" "$1"

    EXITCODE=$?
    if [ $EXITCODE -ne 0 ]; then
    echo ""
    echo "Failed to download $1. Exitcode $EXITCODE. Retrying in 10 seconds";
    sleep 10
    curl -L --silent -o "$DOWNLOAD_PATH/$DOWNLOAD_FILE" "$1"
    fi

    EXITCODE=$?
    if [ $EXITCODE -ne 0 ]; then
    echo ""
    echo "Failed to download $1. Exitcode $EXITCODE";
    exit 1
    fi

    echo "... Done"
    else
    echo "$DOWNLOAD_FILE has already downloaded."
    fi

    make_dir "$DOWNLOAD_PATH/$TARGETDIR"

    if [ -n "$3" ]; then
    if ! tar -xvf "$DOWNLOAD_PATH/$DOWNLOAD_FILE" -C "$DOWNLOAD_PATH/$TARGETDIR" 2>/dev/null >/dev/null; then
    echo "Failed to extract $DOWNLOAD_FILE";
    exit 1
    fi
    else
    if ! tar -xvf "$DOWNLOAD_PATH/$DOWNLOAD_FILE" -C "$DOWNLOAD_PATH/$TARGETDIR" --strip-components 1 2>/dev/null >/dev/null; then
    echo "Failed to extract $DOWNLOAD_FILE";
    exit 1
    fi
    fi

    echo "Extracted $DOWNLOAD_FILE";

    cd "$DOWNLOAD_PATH/$TARGETDIR" || (echo "Error has occurred." ; exit 1)
    }

    execute () {
    echo "$ $*"

    OUTPUT=$("$@" 2>&1)

    # shellcheck disable=SC2181
    if [ $? -ne 0 ]; then
    echo "$OUTPUT"
    echo ""
    echo "Failed to Execute $*" >&2
    exit 1
    fi
    }

    build () {
    echo ""
    echo "building $1"
    echo "======================="

    if [ -f "$PACKAGES/$1.done" ]; then
    echo "$1 already built. Remove $PACKAGES/$1.done lockfile to rebuild it."
    return 1
    fi

    return 0
    }

    command_exists() {
    if ! [[ -x $(command -v "$1") ]]; then
    return 1
    fi

    return 0
    }


    build_done () {
    touch "$PACKAGES/$1.done"
    }

    cleanup () {
    remove_dir "$PACKAGES"
    remove_dir "$WORKSPACE"
    echo "Cleanup done."
    echo ""
    }

    usage () {
    echo "Usage: $PROGNAME [OPTIONS]"
    echo "Options:"
    echo " -h, --help Display usage information"
    echo " --version Display version information"
    echo " -b, --build Starts the build process"
    echo " -c, --cleanup Remove all working dirs"
    echo " -f, --full-static Complete static build of ffmpeg (eg. glibc, pthreads etc...) **not recommend**"
    echo " Note: Because of the NSS (Name Service Switch), glibc does not recommend static links."
    echo ""
    }

    while (( $# > 0 )); do
    case $1 in
    -h | --help)
    usage
    exit 0
    ;;
    --version)
    echo $VERSION
    exit 0
    ;;
    -*)
    if [[ "$1" == "--build" || "$1" =~ 'b' ]]; then
    bflag='-b'
    fi
    if [[ "$1" == "--cleanup" || "$1" =~ 'c' ]]; then
    cflag='-c'
    cleanup
    fi
    if [[ "$1" == "--full-static" || "$1" =~ 'f' ]]; then
    LDEXEFLAGS="-static"
    fi
    shift
    ;;
    *)
    usage
    exit 1
    ;;
    esac
    done

    if [ -z $bflag ]; then
    if [ -z $cflag ]; then
    usage
    exit 1
    fi
    exit 0
    fi

    echo "ffmpeg-build-script v$VERSION"
    echo "========================="
    echo ""

    echo "Using $MJOBS make jobs simultaneously."

    if [[ -n $LDEXEFLAGS ]]; then
    echo "Start the build in full static mode."
    fi

    mkdir -p "$PACKAGES"
    mkdir -p "$WORKSPACE"

    export PATH="${WORKSPACE}/bin:$PATH"

    if ! command_exists "make"; then
    echo "make not installed.";
    exit 1
    fi

    if ! command_exists "g++"; then
    echo "g++ not installed.";
    exit 1
    fi

    if ! command_exists "curl"; then
    echo "curl not installed.";
    exit 1
    fi


    ##
    ## Pre-requirement
    ##


    echo "Installing prerequisites"
    sudo apt-get update
    sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev libgpac-dev \
    libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
    libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev cmake nasm gcc-7 g++-7

    sudo ln -s $(which gcc-8) /usr/local/bin/gcc
    sudo ln -s $(which g++-8) /usr/local/bin/g++

    if build "yasm"; then
    download "https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz"
    execute ./configure --prefix="${WORKSPACE}"
    execute make -j $MJOBS
    execute make install
    build_done "yasm"
    fi

    if build "nasm"; then
    download "https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install
    build_done "nasm"
    fi

    if build "pkg-config"; then
    download "https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz"
    execute ./configure --silent --prefix="${WORKSPACE}" --with-pc-path="${WORKSPACE}"/lib/pkgconfig --with-internal-glib
    execute make -j $MJOBS
    execute make install
    build_done "pkg-config"
    fi

    #if build "cmake"; then
    # download "https://cmake.org/files/v3.15/cmake-3.15.4.tar.gz"
    # rm Modules/FindJava.cmake
    # perl -p -i -e "s/get_filename_component.JNIPATH/#get_filename_component(JNIPATH/g" Tests/CMakeLists.txt
    # perl -p -i -e "s/get_filename_component.JNIPATH/#get_filename_component(JNIPATH/g" Tests/CMakeLists.txt
    # execute ./configure --prefix="${WORKSPACE}"
    # execute make -j $MJOBS
    # execute make install
    # build_done "cmake"
    #fi


    ##
    ## video library
    ##

    if build "x264"; then
    download "https://code.videolan.org/videolan/x264/-/archive/stable/x264-stable.tar.bz2"

    if [[ "$OSTYPE" == "linux-gnu" ]]; then
    execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic CXXFLAGS="-fPIC"
    else
    execute ./configure --prefix="${WORKSPACE}" --enable-static --enable-pic
    fi

    execute make -j $MJOBS
    execute make install
    execute make install-lib-static

    build_done "x264"
    fi
    CONFIGURE_OPTIONS+=("--enable-libx264")

    if build "x265"; then
    download "https://github.com/videolan/x265/archive/Release_3.5.tar.gz" "x265-3.5.tar.gz"
    cd source || exit
    execute cmake -DCMAKE_INSTALL_PREFIX:PATH="${WORKSPACE}" -DENABLE_SHARED:bool=off -DSTATIC_LINK_CRT:BOOL=ON -DENABLE_CLI:BOOL=OFF .
    execute make -j $MJOBS
    execute make install
    sed -i 's/-lgcc_s/-lgcc_eh/g' "$WORKSPACE/lib/pkgconfig/x265.pc"
    build_done "x265"
    fi
    CONFIGURE_OPTIONS+=("--enable-libx265")

    if build "libvpx"; then
    download "https://github.com/webmproject/libvpx/archive/v1.9.0.tar.gz" "libvpx-1.9.0.tar.gz"

    if [[ "$OSTYPE" == "darwin"* ]]; then
    echo "Applying Darwin patch"
    sed "s/,--version-script//g" build/make/Makefile > build/make/Makefile.patched
    sed "s/-Wl,--no-undefined -Wl,-soname/-Wl,-undefined,error -Wl,-install_name/g" build/make/Makefile.patched > build/make/Makefile
    fi

    execute ./configure --prefix="${WORKSPACE}" --disable-unit-tests --disable-shared
    execute make -j $MJOBS
    execute make install

    build_done "libvpx"
    fi
    CONFIGURE_OPTIONS+=("--enable-libvpx")

    if build "xvidcore"; then
    download "https://downloads.xvid.com/downloads/xvidcore-1.3.7.tar.gz"
    cd build/generic || exit
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install

    if [[ -f ${WORKSPACE}/lib/libxvidcore.4.dylib ]]; then
    execute rm "${WORKSPACE}/lib/libxvidcore.4.dylib"
    fi

    if [[ -f ${WORKSPACE}/lib/libxvidcore.so ]]; then
    execute rm "${WORKSPACE}"/lib/libxvidcore.so*
    fi

    build_done "xvidcore"
    fi
    CONFIGURE_OPTIONS+=("--enable-libxvid")

    if build "vid_stab"; then
    download "https://github.com/georgmartius/vid.stab/archive/v1.1.0.tar.gz" "vid.stab-1.1.0.tar.gz"
    execute cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH="${WORKSPACE}" -DUSE_OMP=OFF -DENABLE_SHARED:bool=off .
    execute make
    execute make install

    build_done "vid_stab"
    fi
    CONFIGURE_OPTIONS+=("--enable-libvidstab")


    if build "av1"; then
    download "https://aomedia.googlesource.com/aom/+archive/430d58446e1f71ec2283af0d6c1879bc7a3553dd.tar.gz" "av1.tar.gz" "av1"
    make_dir "$PACKAGES"/aom_build
    cd "$PACKAGES"/aom_build || exit
    execute cmake -DENABLE_TESTS=0 -DCMAKE_INSTALL_PREFIX:PATH="${WORKSPACE}" "$PACKAGES"/av1
    execute make -j $MJOBS
    execute make install

    build_done "av1"
    fi
    CONFIGURE_OPTIONS+=("--enable-libaom")


    ##
    ## audio library
    ##

    if build "opencore"; then
    download "https://deac-riga.dl.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-0.1.5.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install

    build_done "opencore"
    fi
    CONFIGURE_OPTIONS+=("--enable-libopencore_amrnb" "--enable-libopencore_amrwb")

    if build "lame"; then
    download "https://netcologne.dl.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install

    build_done "lame"
    fi
    CONFIGURE_OPTIONS+=("--enable-libmp3lame")

    if build "opus"; then
    download "https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install

    build_done "opus"
    fi
    CONFIGURE_OPTIONS+=("--enable-libopus")

    if build "libogg"; then
    download "https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install
    build_done "libogg"
    fi

    if build "libvorbis"; then
    download "https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest
    execute make -j $MJOBS
    execute make install

    build_done "libvorbis"
    fi
    CONFIGURE_OPTIONS+=("--enable-libvorbis")

    if build "libtheora"; then
    download "https://ftp.osuosl.org/pub/xiph/releases/theora/libtheora-1.1.1.tar.gz"
    sed "s/-fforce-addr//g" configure > configure.patched
    chmod +x configure.patched
    mv configure.patched configure
    execute ./configure --prefix="${WORKSPACE}" --with-ogg-libraries="${WORKSPACE}"/lib --with-ogg-includes="${WORKSPACE}"/include/ --with-vorbis-libraries="${WORKSPACE}"/lib --with-vorbis-includes="${WORKSPACE}"/include/ --enable-static --disable-shared --disable-oggtest --disable-vorbistest --disable-examples --disable-asm --disable-spec
    execute make -j $MJOBS
    execute make install

    build_done "libtheora"
    fi
    CONFIGURE_OPTIONS+=("--enable-libtheora")

    if build "fdk_aac"; then
    download "https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-2.0.1.tar.gz/download?use_mirror=gigenet" "fdk-aac-2.0.1.tar.gz"
    execute ./configure --prefix="${WORKSPACE}" --disable-shared --enable-static
    execute make -j $MJOBS
    execute make install

    build_done "fdk_aac"
    fi
    CONFIGURE_OPTIONS+=("--enable-libfdk-aac")


    ##
    ## other library
    ##

    if build "zlib"; then
    download "https://www.zlib.net/zlib-1.2.11.tar.gz"
    execute ./configure --static --prefix="${WORKSPACE}"
    execute make -j $MJOBS
    execute make install
    build_done "zlib"
    fi

    if build "openssl"; then
    download "https://www.openssl.org/source/openssl-1.1.1h.tar.gz"
    execute ./config --prefix="${WORKSPACE}" --openssldir="${WORKSPACE}" --with-zlib-include="${WORKSPACE}"/include/ --with-zlib-lib="${WORKSPACE}"/lib no-shared zlib
    execute make -j $MJOBS
    execute make install

    build_done "openssl"
    fi
    CONFIGURE_OPTIONS+=("--enable-openssl")

    if build "srt"; then
    download "https://github.com/Haivision/srt/archive/v1.4.1.tar.gz" "srt-1.4.1.tar.gz"
    export OPENSSL_ROOT_DIR="${WORKSPACE}"
    export OPENSSL_LIB_DIR="${WORKSPACE}"/lib
    export OPENSSL_INCLUDE_DIR="${WORKSPACE}"/include/
    execute cmake . -DCMAKE_INSTALL_PREFIX:PATH="${WORKSPACE}" -DENABLE_SHARED=OFF -DENABLE_STATIC=ON -DENABLE_APPS=OFF -DUSE_STATIC_LIBSTDCXX=ON
    execute make install
    sed -i 's/-lgcc_s/-lgcc_eh/g' "$WORKSPACE/lib/pkgconfig/srt.pc"

    build_done "srt"
    fi
    CONFIGURE_OPTIONS+=("--enable-libsrt")

    ##
    ## HWaccel library
    ##

    if command -V nvcc > /dev/null ; then
    if build "nv-codec"; then
    download "https://github.com/FFmpeg/nv-codec-headers/releases/download/n10.0.26.0/nv-codec-headers-10.0.26.0.tar.gz"
    sed -i "s#PREFIX = /usr/local#PREFIX = ${WORKSPACE}#g" Makefile
    execute make install
    build_done "nv-codec"
    fi
    CFLAGS+=" -I/usr/local/cuda/include"
    LDFLAGS+=" -L/usr/local/cuda/lib64"
    CONFIGURE_OPTIONS+=("--enable-cuda-nvcc" "--enable-cuvid" "--enable-nvenc" "--enable-cuda-llvm")

    if [ -z $LDEXEFLAGS ]; then
    CONFIGURE_OPTIONS+=("--enable-libnpp") # Only libnpp cannot be static link.
    fi

    echo ""
    if [[ -z "$CUDA_ARCH" ]]; then

    echo "Please give me your CUDA_ARCH at https://developer.nvidia.com/cuda-gpus."
    echo "Pre-setup by \"export CUDA_ARCH=XX\""
    echo "Example: \"50\" if compute capability version is 5.0"
    read -r -p "> CUDA_ARC=" cuda_arch

    re='^[0-9]+$'
    if ! [[ $cuda_arch =~ $re ]] ; then
    echo "Verion not supported!"
    fi

    CUDA_ARCH="$cuda_arch"
    else
    echo "> CUDA_ARC=$CUDA_ARCH"
    fi

    # check at https://developer.nvidia.com/cuda-gpus
    CONFIGURE_OPTIONS+=("--nvccflags=-gencode arch=compute_$CUDA_ARCH,code=sm_$CUDA_ARCH -O2")
    echo "======================="
    fi


    ##
    ## FFmpeg
    ##

    build "ffmpeg"
    download "https://ffmpeg.org/releases/ffmpeg-4.3.1.tar.bz2"

    echo "./configure \\"
    for lib in "${CONFIGURE_OPTIONS[@]}"
    do
    echo "$lib \\"
    done

    echo "--disable-debug \\"
    echo "--disable-shared \\"
    echo "--enable-gpl \\"
    echo "--enable-nonfree \\"
    echo "--enable-pthreads \\"
    echo "--enable-static \\"
    echo "--enable-small \\"
    echo "--enable-version3 \\"
    echo "--extra-cflags=\"${CFLAGS}\" \\"
    echo "--extra-ldflags=\"${LDFLAGS}\" \\"
    echo "--extra-libs=\"${EXTRALIBS}\" \\"
    echo "--pkgconfigdir=\"$WORKSPACE/lib/pkgconfig\" \\"
    echo "--pkg-config-flags=\"--static\" \\"
    echo "--prefix=\"${WORKSPACE}\""
    echo "======================="

    ./configure "${CONFIGURE_OPTIONS[@]}" \
    --disable-debug \
    --disable-doc \
    --disable-shared \
    --enable-gpl \
    --enable-nonfree \
    --enable-pthreads \
    --enable-static \
    --enable-small \
    --enable-version3 \
    --extra-cflags="${CFLAGS}" \
    --extra-ldexeflags="${LDEXEFLAGS}" \
    --extra-ldflags="${LDFLAGS}" \
    --extra-libs="${EXTRALIBS}" \
    --pkgconfigdir="$WORKSPACE/lib/pkgconfig" \
    --pkg-config-flags="--static" \
    --prefix="${WORKSPACE}"

    execute make -j $MJOBS
    execute make install

    INSTALL_FOLDER="/usr/bin"
    if [[ "$OSTYPE" == "darwin"* ]]; then
    INSTALL_FOLDER="/usr/local/bin"
    fi

    echo ""
    echo "Building done. The binary can be found here: $WORKSPACE/bin/ffmpeg"
    echo ""


    if [[ $AUTOINSTALL == "yes" ]]; then
    sudo cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg"
    sudo cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe"
    sudo cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay"
    echo "Done. ffmpeg is now installed to your system"
    elif [[ ! $SKIPINSTALL == "yes" ]]; then
    read -r -p "Install the binary to your $INSTALL_FOLDER folder? [Y/n] " response
    case $response in
    [yY][eE][sS]|[yY])
    sudo cp "$WORKSPACE/bin/ffmpeg" "$INSTALL_FOLDER/ffmpeg"
    sudo cp "$WORKSPACE/bin/ffprobe" "$INSTALL_FOLDER/ffprobe"
    sudo cp "$WORKSPACE/bin/ffplay" "$INSTALL_FOLDER/ffplay"
    echo "Done. ffmpeg is now installed to your system"
    ;;
    esac
    fi

    sudo rm /usr/local/bin/gcc /usr/local/bin/g++
    hash -r

    exit 0