m-ab-s / media-autobuild_suite

This Windows Batchscript helps setup a Mingw-w64 compiler environment for building ffmpeg and other media tools under Windows.
GNU General Public License v3.0
1.55k stars 266 forks source link

Help required: Compile ffmpeg with "cuda-sdk" #972

Closed lars18th closed 6 years ago

lars18th commented 6 years ago

Hi,

I readed the info about how to enable the compilation with "cuda-sdk", but I don't have success:

I edited the file media-autobuild_suite.bat with this simple change:

@echo off
color 80
title media-autobuild_suite

call "c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
SET CUDA_PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\

setlocal
...

So, I added the VC to the PATH and set the CUDA directory. After this, the command cl.exe is available in the PATH.

But I also edited the file media-suite_helper.sh with:

get_cl_path() {
    local vswhere="$(cygpath -u "$(cygpath -F 0x002a)/Microsoft Visual Studio/Installer/vswhere.exe")"
    if [[ -f "$vswhere" ]]; then
        local installationpath="$("$vswhere" -legacy -version 14 -property installationPath | tail -n1)"
        [[ -z "$installationpath" ]] && return 1
        local basepath="$(cygpath -u "$installationpath/VC/Tools/MSVC/14.15.26726/bin")"
        if [[ "$bits" = 32bit && -f "$basepath/Hostx86/x86/cl.exe" ]]; then
            export PATH="$basepath":$PATH
        elif [[ "$bits" = 64bit && -f "$basepath/Hostx64/x64/cl.exe" ]]; then
            export PATH="$basepath/amd64":$PATH
        else
            return 1
        fi
    else
...

Because the cl.exe is inside a different directory.

But, even with these modifications the builded ffmpeg.exe doesn't have "--enable-cuda-sdk".

Any help, please?

lars18th commented 6 years ago

Hi,

I don't commented it, but for sure my ffmpeg_options.txt has enabled cuda-sdk:

# Lines starting with this character are ignored

# Basic built-in options, can be removed if you delete "--disable-autodetect"
--disable-autodetect
--enable-amf
--enable-bzlib
--enable-cuda
--enable-cuvid
--enable-d3d11va
--enable-dxva2
--enable-iconv
--enable-lzma
--enable-nvenc
--enable-schannel
--enable-zlib
--enable-sdl2
--disable-debug
--enable-ffnvcodec
--enable-nvdec

# Common options
--enable-gmp
--enable-libmp3lame
--enable-libopus
--enable-libvorbis
--enable-libvpx
--enable-libx264
--enable-libx265
#--enable-libdav1d

# Zeranoe
--enable-fontconfig
--enable-gnutls
--enable-libass
--enable-libbluray
--enable-libfreetype
--enable-libmfx
--enable-libmysofa
--enable-libopencore-amrnb
--enable-libopencore-amrwb
--enable-libopenjpeg
--enable-libsnappy
--enable-libsoxr
--enable-libspeex
--enable-libtheora
--enable-libtwolame
--enable-libvidstab
--enable-libvo-amrwbenc
--enable-libwavpack
--enable-libwebp
--enable-libxml2
--enable-libzimg
--enable-libshine
--enable-gpl
--enable-openssl
--enable-libtls
--enable-avisynth
--enable-mbedtls
--enable-libxvid
--enable-libaom
--enable-version3

# Full
--enable-chromaprint
--enable-cuda-sdk
--enable-decklink
--enable-frei0r
--enable-libbs2b
--enable-libcaca
--enable-libcdio
--enable-libfdk-aac
--enable-libflite
--enable-libfribidi
--enable-libgme
--enable-libgsm
--enable-libilbc
--enable-libkvazaar
--enable-libmodplug
--enable-libnpp
--enable-libopenh264
--enable-libopenmpt
--enable-librtmp
--enable-librubberband
--enable-libssh
--enable-libtesseract
--enable-libxavs
--enable-libzmq
--enable-libzvbi
--enable-opencl
--enable-opengl
--enable-libvmaf
--enable-libcodec2
--enable-libsrt
--enable-ladspa
#--enable-vapoursynth
#--enable-liblensfun
--enable-libndi_newtek

And the compiled binary has --enable-nonfree active.

So the problem is the configuration/compilation/linking with the CUDA SDK.

Any ideas?

wiiaboo commented 6 years ago

Well, might bea very many things wrong. The methods to enable cuda in MinGW are hacky at best, since Nvidia doesn't support it directly. When I have time I'll look into it.

If FFmpeg compilation isn't broken with --enable-cuda-sdk, it means the option is being removed by the suite.

if [[ $license = "nonfree" && $bits = 64bit ]] && enabled_any libnpp cuda-sdk &&
        [[ -n "$CUDA_PATH" && -f "$CUDA_PATH/include/cuda.h" ]] &&
        [[ -f "$CUDA_PATH/lib/x64/cuda.lib" ]] && get_cl_path; then

All these checks need to pass for cuda-sdk to not get disabled.

  1. license needs to be non-free
  2. only 64-bits is supported
  3. any of libnpp or cuda-sdk need to be enabled (this one is true at least)
  4. %CUDA_PATH% environment variable needs to be defined somewhere in your system, either globally in your system or exported in a custom script in $HOME/custom_build_options
  5. if it is defined, the main cuda.h header needs to exist
  6. if it is defined and there's the cuda.h header, the cuda.lib import lib needs to also exist

Do you fullfill all of these conditions?

wiiaboo commented 6 years ago

Also, a seventh condition: cl.exe is needed to compile the .cu source files in FFmpeg, because Nvidia's compiler only works with MSVC's cl.exe, not MinGW gcc.

wiiaboo commented 6 years ago

Finally, that modification you did to get_cl_path, I'm pretty fucking sure that'll break in 5 minutes when MS releases a minor upgrade to MSVC. Either find a way to get the proper path in a future-compatible way or I'm making you personally responsible on keeping that path up-to-date.

lars18th commented 6 years ago

Hi @wiiaboo ,

Thank you for the tips! I'll try and write here the results.

lars18th commented 6 years ago

Hi @wiiaboo ,

Checking list:

  1. license needs to be non-free
    • YES. Inside build\media-autobuild_suite.ini is license2=1 (aka "license2=nonfree")
  2. only 64-bits is supported
    • YES. Inside build\media-autobuild_suite.ini is arch=3 (aka "64bit only")
  3. any of libnpp or cuda-sdk need to be enabled (this one is true at least)
    • YES. Both enabled in build/ffmpeg_options.txt
  4. %CUDA_PATH% environment variable needs to be defined somewhere in your system, either globally in your system or exported in a custom script in $HOME/custom_build_options
    • YES. I put in at the start of the .BAT file.
    • Regarding the "custom_build_options", I don't have sufficient info. Why use $HOME (in the MSYS2 environment) and not a parameter, or a "local" directory? For example inside the same build directory. Futhermore, what parameters we can include in this file?
  5. if it is defined, the main cuda.h header needs to exist
    • YES. The CUDA SDK is installed with all defaults, so C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include\cuda.h exists.
  6. if it is defined and there's the cuda.h header, the cuda.lib import lib needs to also exist
    • YES. It's at C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\lib\x64\cuda.lib
  7. cl.exe is needed to compile the .cu source files in FFmpeg, because Nvidia's compiler only works with MSVC's cl.exe, not MinGW gcc.
    • YES. As commented running "c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 the cl.exe is in the PATH. So irrelevant to search for it with get_cl_path().

But, the result does not include the cuda-sdk !

lars18th commented 6 years ago

Hi,

Last update:

├ Running configure...
Likely error:
CFLAGS: -mthreads -mtune=generic -O2 -pipe
LDFLAGS: -pipe -static-libgcc -static-libstdc++ -L/local64/lib -L/mingw64/lib
../configure --prefix=/local64 --bindir=/local64/bin-video --pkg-config-flags=--static --disable-autodetect --enable-amf --enable-bzlib --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-iconv --enable-lzma --enable-nvenc --enable-zlib --enable-sdl2 --disable-debug --enable-ffnvcodec --enable-nvdec --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libx264 --enable-fontconfig --enable-libass --enable-libbluray --enable-libfreetype --enable-libmfx --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libwavpack --enable-libwebp --enable-libxml2 --enable-libzimg --enable-libshine --enable-gpl --enable-avisynth --enable-libxvid --enable-libaom --enable-version3 --enable-chromaprint --enable-cuda-sdk --enable-decklink --enable-frei0r --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libfdk-aac --enable-libflite --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libkvazaar --enable-libmodplug --enable-libnpp --enable-libopenh264 --enable-libopenmpt --enable-librtmp --enable-librubberband --enable-libssh --enable-libtesseract --enable-libxavs --enable-libzmq --enable-libzvbi --enable-opencl --enable-opengl --enable-libvmaf --enable-libcodec2 --enable-libsrt --enable-ladspa --enable-openssl --extra-cflags=-fopenmp --extra-libs=-lgomp --extra-cflags=-DLIBTWOLAME_STATIC --extra-libs=-lstdc++ --extra-cflags=-DLIBSSH_STATIC --extra-ldflags=-Wl,--allow-multiple-definition --extra-cflags=-DCACA_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCHROMAPRINT_NODLL --extra-libs=-lstdc++ --extra-cflags=-DZMQ_STATIC --extra-libs=-lpsapi --extra-cflags=-DLIBXML_STATIC --extra-libs=-liconv --disable-w32threads --extra-cflags=-DKVZ_STATIC_LIB --enable-nonfree
ERROR: cuda_sdk not found

So, I feel the problem is: the flags doesn't contain the CUDA path and then it fails to compile with it.

I'll try to fix it.

wiiaboo commented 6 years ago

Regarding the "custom_build_options", I don't have sufficient info. Why use $HOME (in the MSYS2 environment) and not a parameter, or a "local" directory? For example inside the same build directory. Futhermore, what parameters we can include in this file?

It's a bash script. See /local64/etc/profile2.local for examples of what you can do and export.

Futhermore, before starting media-autobuild_suite.bat I call the vcvarsall.bat amd64 and set the CUDA_PATH environment var.

That's not an acceptable workaround. We don't expect people to open the suite using MSVC command prompt or run MSVC stuff that they might not have. We don't use MSVC for anything, nvcc does. And the suite shouldn't be setting CUDA_PATH. The installer for the SDK should be setting it globally.

See in ffbuild/config.log for what caused the errors in configuring.

lars18th commented 6 years ago

Hi @wiiaboo ,

Work done! :v: I compiled ffmpeg with --enable-cuda-sdk.

However, I do it with a hack. I post here for reference to other users. And I hope you (@wiiaboo) can get relevant info to improve this tool.

Guide:

  1. First install in you Windows machine the MSVS2017 Community and the CUDA SDK v10.
  2. Download the tool and before execute it, copy/create the file media-autobuild_suite-master\local64\etc\custom_profile:
    ###################################
    # Custom profile to enable CUDA-SDK
    ###################################
    #
    #  adds include of headers of "CUDA_PATH/include"
    CFLAGS="${CFLAGS} -I$(cygpath -sm "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include")"
    #
    #  adds linking to libs in "CUDA_PATH/lib/x64"
    LDFLAGS="${LDFLAGS} -L$(cygpath -sm "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\lib\x64")"
    #
    #  adds to the $PATH the directory of "cl.exe"
    export PATH=$PATH:$(dirname "$(cygpath -u "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726\bin\Hostx64\x64\cl.exe")")
    #
    #  adds to the $PATH the directory of "nvcc.exe"
    export PATH=$PATH:$(dirname "$(cygpath -u "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin\nvcc.exe")")
    #
    #
    #  Warning! Until an upgrade appears, edit and comment-out the file "media-suite_helper.sh" in this way:
    #
    # cuda-only workarounds
    #   if [[ $license = "nonfree" && $bits = 64bit ]] && enabled_any libnpp cuda-sdk &&
    #       [[ -n "$CUDA_PATH" && -f "$CUDA_PATH/include/cuda.h" ]] &&
    #       [[ -f "$CUDA_PATH/lib/x64/cuda.lib" ]] && get_cl_path; then
    #           if enabled libnpp && [[ ! -f "$CUDA_PATH/lib/x64/nppc.lib" ]]; then
    #               do_removeOption "--enable-libnpp"
    #           elif enabled libnpp; then
    #               echo -e "${orange}FFmpeg and related apps will depend on CUDA SDK!${reset}"
    #           fi
    #           local fixed_CUDA_PATH="$(cygpath -sm "$CUDA_PATH")"
    #           do_addOption "--extra-cflags=-I$fixed_CUDA_PATH/include"
    #           do_addOption "--extra-ldflags=-L$fixed_CUDA_PATH/lib/x64"
    #           echo -e "${orange}FFmpeg and related apps will depend on Nvidia drivers!${reset}"
    #   else
    #       do_removeOption "--enable-(libnpp|cuda-sdk)"
    #   fi
  3. As indicated comment-out the section # cuda-only workarounds in the file build\media-suite_helper.sh
  4. Then launch the tool media-autobuild_suite.bat and select "non-free" compilation.

Additional comments:

I hope this helps others. :wink: And thank you @wiiaboo for this good tool! :+1: Regards.

lars18th commented 6 years ago

Final comment:

wiiaboo commented 6 years ago

That's what echo -e "${orange}FFmpeg and related apps will depend on CUDA SDK!${reset}" already warned about.

lars18th commented 6 years ago

That's what echo -e "${orange}FFmpeg and related apps will depend on CUDA SDK!${reset}" already warned about.

Yes! I know it. However, it's true only when using --enable-libnpp. And this is not a requirement when using --enable-cuda-sdk. So, you can compile with cuda and not with libnpp (recommended as vf_scale_cuda replaces the vf_scale_npp). Remember that the nvidia driver installs the cuda dlls, but not the libnpp's. So you only need to care when the libnpp is enabled.

In any case, I hope you can upgrade/enhance the tool. Or almost update the wiki for use this hack. Regards!

wiiaboo commented 6 years ago

Yes, that warning is only shown if libnpp is enabled. I remember because it's been there for months when cuda-sdk was added to FFmpeg.

Try https://github.com/jb-alvarado/media-autobuild_suite/commit/a7c4510b450a94feab6e822b61412e441a3bd4af to see if it fixed anything. It still needs CUDA_PATH to be set by something.

wiiaboo commented 6 years ago

And with 05eec87 it should skip trying to find cl.exe if it's already in PATH.

wiiaboo commented 6 years ago

Had to restart for system $CUDA_PATH to get updated with v10.0 for some reason, but it worked on my side.

wiiaboo commented 6 years ago

Btw, I forgot about this one

Regarding the "custom_build_options", I don't have sufficient info. Why use $HOME (in the MSYS2 environment) and not a parameter, or a "local" directory?

Because $CUDA_PATH can be globally set for both 32-bit and 64-bit. But there's also /local(32|64)/etc/custom_profile which is sourced for either 32-bit or 64-bit if you want specific options or variables for each arch.

For example inside the same build directory.

There's also a possible /build/ffmpeg-git/ffmpeg_extra.sh which can be sourced right before the configure is run.

lars18th commented 6 years ago

Hi @wiiaboo ,

And with 05eec87 it should skip trying to find cl.exe if it's already in PATH.

:+1:

lars18th commented 6 years ago

Hi @wiiaboo ,

Please, reopen the issue, as the $CUDA_PATH isn't totally resolved.

Because $CUDA_PATH can be globally set for both 32-bit and 64-bit. But there's also /local(32|64)/etc/custom_profile which is sourced for either 32-bit or 64-bit if you want specific options or variables for each arch.

Please, take note of:

  1. $CUDA_PATH has sense only in 64bit. No option for 32bit.
  2. The current code of # cuda-only workarounds inside media-suite_helper.sh doesn't set the path of nvcc.exe. Please, see my recommended media-autobuild_suite-master\local64\etc\custom_profile. It includes hacks to CFLAGS & LDFLAGS (almost resolved with last commits); cl.exe path (now working, if you previously add it to the path); but the path for nvcc.exe it's not set. So I recommand a similar which nvcc.exe &>/dev/null && return 0
  3. I recommend to document (in the Wiki) to use some custom configuration file (like media-autobuild_suite-master\local64\etc\custom_profile or custom_build_options) to add your custom paths. I noticed that the media-autobuild_suite.bat doesn't use the path set when calling to vcvarsall.bat. So including two lines like export PATH=$PATH:$(dirname "$(cygpath -u ... for cl.exe & nvcc.exe will be simplier.

What you think?

And.. thank you for your good job! :+1:

wiiaboo commented 6 years ago

$CUDA_PATH has sense only in 64bit. No option for 32bit.

No. $CUDA_PATH works for both, it's the base installation of cuda sdk. --enable-libnpp and --enable-cuda-sdk only work for 64-bit.

The current code of # cuda-only workarounds inside media-suite_helper.sh doesn't set the path of nvcc.exe.

I'm pretty sure it does as I've successfully compiled with both cuda-sdk and libnpp yesterday. If it doesn't work for you, that's another thing.

As long as you have VS 2017 with vswhere.exe available, or the correct cl.exe already in PATH, you can find cl.exe, and as long as you have CUDA_PATH environment variable set somewhere (cuda sdk installation sets it for the system), the suite will find nvcc.exe and add it to PATH.

I recommend to document (in the Wiki) to use some custom configuration file (like media-autobuild_suite-master\local64\etc\custom_profile or custom_build_options) to add your custom paths. I noticed that the media-autobuild_suite.bat doesn't use the path set when calling to vcvarsall.bat. So including two lines like export PATH=$PATH:$(dirname "$(cygpath -u ... for cl.exe & nvcc.exe will be simplier.

I've already told you or someone else recently that you're not supposed to run vcvarsall.bat. We only care about cl.exe because of nvcc.exe. There's absolutely no point in polluting the environment with MSVC's variables and the suite's .bat's variables. That leads to broken configure scripts everywhere.

Requiring people to use those scripts for normal usage is not reasonable and that's why I don't document it. You're welcome to document how to use those files and document how to simplify the suite's search with it.

lars18th commented 6 years ago

Hi @wiiaboo ,

Requiring people to use those scripts for normal usage is not reasonable and that's why I don't document it. You're welcome to document how to use those files and document how to simplify the suite's search with it.

Done! https://github.com/jb-alvarado/media-autobuild_suite/pull/975 Glad to be able to collaborate! I hope you agree and merge it! :wink:

Just one personal comment: In my environment the CUDA_PATH isn't set; and nvcc.exe & cl.exe aren't in the PATH. Why? Because I hate to pollute the Windows environment with a lot of environment vars. However, with the last commit and with my recomendation in the README, I fully compiled ffmpeg with cuda without any trouble. Everything perfect on the first try.

Thank you!

Murmur commented 5 years ago

This is an old thread but would still ask a specific question here. Do NVIDIA codec use(cuda-sdk for ffmepg) need VisualStudio2015/2017 compiler? This cannot be done with a default mingw compiler tools? What is the preferred VisualStudio be used year 2019 and is Visual Studio Express enough? thx.

RiCONfru commented 5 years ago

https://github.com/jb-alvarado/media-autobuild_suite#notes-about-cuda-sdk

RiCONfru commented 5 years ago

This is an old thread but would still ask a specific question here.

Do try to check if the Readme doesn't cover your question, or else you're just wasting time for everyone and yourself.

Do NVIDIA codec use(cuda-sdk for ffmepg) need VisualStudio2015/2017 compiler?

Yes.

This cannot be done with a default mingw compiler tools?

No. Complain Nvidia for not supporting other compilers on Windows.

What is the preferred VisualStudio be used year 2019 and is Visual Studio Express enough? thx.

Whatever is supported by nvcc. Check their readme as well. 2017 is known to work. No idea what VS Express is, but no.

lars18th commented 5 years ago

Hi @Murmur ,

I use only Visual Studio COMMUNITY 2017 for this pourpose, and it compiles FFmpeg with NVidia support. So I confirm that the nvcc.exe works with it.

Regards.