Error while using h264_cuvid decoder with ffmpeg

14.2k views Asked by At

I am trying to decode a video using the NVIDIA cuvid hardware acceleration with ffmpeg.

I am using a NVIDIA GeForce GT 745M Graphics card (GPU:GK107), which is compatible with cuvid as specified by NVIDIA here

I compiled ffmpeg with the following flags:

./configure --enable-cuda --enable-nvenc --enable-cuvid

Then, I used ffmpeg with the following command line:

ffmpeg.exe -hwaccel cuvid -c:v h264_cuvid -i video.mkv video.mkv

ffmpeg finishes and seems to be unable to open cuvid functions:

Cannot load cuvidGetDecoderCaps
[h264_cuvid @ 07047b80] Failed loading nvcuvid.
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (h264_cuvid) -> h264 (libx264))
  Stream #0:1 -> #0:1 (ac3 (native) -> vorbis (libvorbis))
  Stream #0:3 -> #0:2 (subrip (srt) -> ass (ssa))
Error while opening decoder for input stream #0:0 : Unknown error occurred

In ffmpeg source code, I can find out that this error message is printed by the following macro:

#define LOAD_SYMBOL(fun, tp, symbol)                                \
    do {                                                            \
        if (!((f->fun) = (tp*)dlsym(f->lib, symbol))) {             \
            av_log(NULL, AV_LOG_ERROR, "Cannot load %s\n", symbol); \
            ret = AVERROR_UNKNOWN;                                  \
            goto error;                                             \
        }                                                           \
        av_log(NULL, AV_LOG_TRACE, "Loaded sym: %s\n", symbol);     \
    } while (0)

Which is called by:

static inline int cuvid_load_functions(CuvidFunctions **functions)
{
    GENERIC_LOAD_FUNC_PREAMBLE(CuvidFunctions, cuvid, NVCUVID_LIBNAME);

    LOAD_SYMBOL(cuvidGetDecoderCaps, tcuvidGetDecoderCaps, "cuvidGetDecoderCaps");
    LOAD_SYMBOL(cuvidCreateDecoder, tcuvidCreateDecoder, "cuvidCreateDecoder");
    LOAD_SYMBOL(cuvidDestroyDecoder, tcuvidDestroyDecoder, "cuvidDestroyDecoder");
    LOAD_SYMBOL(cuvidDecodePicture, tcuvidDecodePicture, "cuvidDecodePicture");
#ifdef __CUVID_DEVPTR64
    LOAD_SYMBOL(cuvidMapVideoFrame, tcuvidMapVideoFrame, "cuvidMapVideoFrame64");
    LOAD_SYMBOL(cuvidUnmapVideoFrame, tcuvidUnmapVideoFrame, "cuvidUnmapVideoFrame64");
#else
    LOAD_SYMBOL(cuvidMapVideoFrame, tcuvidMapVideoFrame, "cuvidMapVideoFrame");
    LOAD_SYMBOL(cuvidUnmapVideoFrame, tcuvidUnmapVideoFrame, "cuvidUnmapVideoFrame");
#endif
    LOAD_SYMBOL(cuvidCtxLockCreate, tcuvidCtxLockCreate, "cuvidCtxLockCreate");
    LOAD_SYMBOL(cuvidCtxLockDestroy, tcuvidCtxLockDestroy, "cuvidCtxLockDestroy");
    LOAD_SYMBOL(cuvidCtxLock, tcuvidCtxLock, "cuvidCtxLock");
    LOAD_SYMBOL(cuvidCtxUnlock, tcuvidCtxUnlock, "cuvidCtxUnlock");

    LOAD_SYMBOL(cuvidCreateVideoSource, tcuvidCreateVideoSource, "cuvidCreateVideoSource");
    LOAD_SYMBOL(cuvidCreateVideoSourceW, tcuvidCreateVideoSourceW, "cuvidCreateVideoSourceW");
    LOAD_SYMBOL(cuvidDestroyVideoSource, tcuvidDestroyVideoSource, "cuvidDestroyVideoSource");
    LOAD_SYMBOL(cuvidSetVideoSourceState, tcuvidSetVideoSourceState, "cuvidSetVideoSourceState");
    LOAD_SYMBOL(cuvidGetVideoSourceState, tcuvidGetVideoSourceState, "cuvidGetVideoSourceState");
    LOAD_SYMBOL(cuvidGetSourceVideoFormat, tcuvidGetSourceVideoFormat, "cuvidGetSourceVideoFormat");
    LOAD_SYMBOL(cuvidGetSourceAudioFormat, tcuvidGetSourceAudioFormat, "cuvidGetSourceAudioFormat");
    LOAD_SYMBOL(cuvidCreateVideoParser, tcuvidCreateVideoParser, "cuvidCreateVideoParser");
    LOAD_SYMBOL(cuvidParseVideoData, tcuvidParseVideoData, "cuvidParseVideoData");
    LOAD_SYMBOL(cuvidDestroyVideoParser, tcuvidDestroyVideoParser, "cuvidDestroyVideoParser");

    GENERIC_LOAD_FUNC_FINALE(cuvid);
}

Does anybody know if a specific file is needed by cuvid to load its functions? Any clue to what is wrong here?

2

There are 2 answers

0
tthibalti On BEST ANSWER

I don't have the problem anymore.

I forgot to use libnpp during ffmpeg compilation.

My current configuration is :

./configure --enable-cuda --enable-nvenc --enable-cuvid --enable-libnpp --extra-cflags=-I<path_to_libnpp_headers> --extra-ldflags=-L<path_to_libnpp_libraries>
0
Zhanwen Chen On

If you compiled ffmpeg from source with NVIDIA Video Codec SDK following NVIDIA instructions, you need to manually include the associated ld library so your system can find the .so shared libraries:

sudo sh -c "echo '/usr/local/lib' >> /etc/ld.so.conf"
sudo ldconfig