Skip to content

Commit c8d9d72

Browse files
Kh4LJanuszL
authored andcommitted
Change nvcuvid link to dyn + hint for FFmpeg (#370)
* Change nvcuvid link to dyn + hint for FFmpeg Signed-off-by: Serge Panev <spanev@nvidia.com> * Add enforce and error message for libnvcuvid dynlink Signed-off-by: Serge Panev <spanev@nvidia.com> * Add missing CMake checks Signed-off-by: Serge Panev <spanev@nvidia.com>
1 parent 0a8503d commit c8d9d72

File tree

10 files changed

+1529
-1293
lines changed

10 files changed

+1529
-1293
lines changed

cmake/Dependencies.cmake

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,26 +154,36 @@ list(APPEND DALI_EXCLUDES libprotobuf.a)
154154
##################################################################
155155
# FFmpeg
156156
##################################################################
157+
158+
include(CheckStructHasMember)
159+
include(CheckTypeSize)
160+
161+
set(FFMPEG_ROOT_DIR "" CACHE PATH "Folder contains FFmeg")
162+
157163
find_package(PkgConfig REQUIRED)
158164
foreach(m avformat avcodec avfilter avutil)
159-
string(TOUPPER ${m} M)
160-
#pkg_check_modules(${m} REQUIRED IMPORTED_TARGET lib${m})
161-
pkg_check_modules(${m} REQUIRED lib${m})
162-
list(APPEND FFmpeg_LIBS ${m})
163-
#list(APPEND FFmpeg_LIBS PkgConfig::${m})
165+
# We do a find_library only if FFMPEG_ROOT_DIR is provided
166+
if(NOT FFMPEG_ROOT_DIR)
167+
string(TOUPPER ${m} M)
168+
pkg_check_modules(${m} REQUIRED lib${m})
169+
list(APPEND FFmpeg_LIBS ${m})
170+
else()
171+
find_library(FFmpeg_Lib ${m}
172+
PATHS ${FFMPEG_ROOT_DIR}
173+
PATH_SUFFIXES lib lib64
174+
NO_DEFAULT_PATH)
175+
list(APPEND FFmpeg_LIBS ${FFmpeg_Lib})
176+
message(STATUS ${m})
177+
endif()
164178
endforeach(m)
165179

166-
# TODO check set(CMAKE_REQUIRED_INCLUDES ${avformat_INCLUDE_DIRS})
167180
include_directories(${avformat_INCLUDE_DIRS})
168-
# TODO check if set(CMAKE_REQUIRED_LIBRARIES ${avformat_LIBRARIES})
169-
# optional?
170181
list(APPEND DALI_LIBS ${avformat_LIBRARIES})
171-
# CHECK_STRUCT_HAS_MEMBER("struct AVStream" codecpar libavformat/avformat.h HAVE_AVSTREAM_CODECPAR LANGUAGE C)
182+
CHECK_STRUCT_HAS_MEMBER("struct AVStream" codecpar libavformat/avformat.h HAVE_AVSTREAM_CODECPAR LANGUAGE C)
172183
set(CMAKE_EXTRA_INCLUDE_FILES libavcodec/avcodec.h)
173-
#check_type_size("AVBSFContext" AVBSFCONTEXT LANGUAGE CXX)
184+
CHECK_TYPE_SIZE("AVBSFContext" AVBSFCONTEXT LANGUAGE CXX)
174185

175-
# nvcuvid cuda and nvidia-ml from the driver
176-
list(APPEND DALI_LIBS ${FFmpeg_LIBS} nvcuvid cuda)
186+
list(APPEND DALI_LIBS ${FFmpeg_LIBS} cuda)
177187

178188
##################################################################
179189
# Exclude stdlib

cmake/lint.cmake

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ file(GLOB_RECURSE LINT_FILES ${CMAKE_SOURCE_DIR}/dali/*.cc ${CMAKE_SOURCE_DIR}/d
55

66
# Excluded files
77
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/util/json.h)
8-
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/nvcuvid.h)
9-
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/cuviddec.h)
8+
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h)
9+
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_cuviddec.h)
10+
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.cc)
1011

1112
execute_process(
1213
COMMAND ${LINT_COMMAND} --linelength=100 ${LINT_FILES}

dali/pipeline/operators/reader/loader/video_loader.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern "C" {
3333
#include "dali/pipeline/operators/reader/loader/loader.h"
3434
#include "dali/pipeline/operators/reader/nvdecoder/nvdecoder.h"
3535
#include "dali/pipeline/operators/reader/nvdecoder/sequencewrapper.h"
36-
#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
36+
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
3737

3838
template<typename T>
3939
using av_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
@@ -114,6 +114,10 @@ class VideoLoader : public Loader<GPUBackend, SequenceWrapper> {
114114
}
115115

116116
void init() {
117+
DALI_ENFORCE(cuvidInitChecked(0),
118+
"Failed to load libnvcuvid.so, needed by the VideoReader operator. "
119+
"If you are running in a Docker container, please refer "
120+
"to https://github.com/NVIDIA/nvidia-docker/wiki/Usage");
117121
/* Required to use libavformat: Initialize libavformat and register all
118122
* the muxers, demuxers and protocols.
119123
*/

dali/pipeline/operators/reader/nvdecoder/cuvideodecoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#ifndef DALI_PIPELINE_OPERATORS_READER_NVDECODER_CUVIDEODECODER_H_
1616
#define DALI_PIPELINE_OPERATORS_READER_NVDECODER_CUVIDEODECODER_H_
1717

18-
#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
18+
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
1919
#include "dali/error_handling.h"
2020

2121
namespace dali {

dali/pipeline/operators/reader/nvdecoder/cuvideoparser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <algorithm>
1919
#include <cstring>
2020

21-
#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
21+
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
2222
#include "dali/error_handling.h"
2323

2424

dali/pipeline/operators/reader/nvdecoder/cuviddec.h renamed to dali/pipeline/operators/reader/nvdecoder/dynlink_cuviddec.h

Lines changed: 913 additions & 900 deletions
Large diffs are not rendered by default.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* Copyright 1993-2017 NVIDIA Corporation. All rights reserved.
3+
*
4+
* Please refer to the NVIDIA end user license agreement (EULA) associated
5+
* with this source code for terms and conditions that govern your use of
6+
* this software. Any use, reproduction, disclosure, or distribution of
7+
* this software and related documentation outside the terms of the EULA
8+
* is strictly prohibited.
9+
*
10+
*/
11+
12+
13+
#include <stdio.h>
14+
15+
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
16+
17+
tcuvidCreateVideoSource *cuvidCreateVideoSource;
18+
tcuvidCreateVideoSourceW *cuvidCreateVideoSourceW;
19+
tcuvidDestroyVideoSource *cuvidDestroyVideoSource;
20+
tcuvidSetVideoSourceState *cuvidSetVideoSourceState;
21+
tcuvidGetVideoSourceState *cuvidGetVideoSourceState;
22+
tcuvidGetSourceVideoFormat *cuvidGetSourceVideoFormat;
23+
tcuvidGetSourceAudioFormat *cuvidGetSourceAudioFormat;
24+
25+
tcuvidCreateVideoParser *cuvidCreateVideoParser;
26+
tcuvidParseVideoData *cuvidParseVideoData;
27+
tcuvidDestroyVideoParser *cuvidDestroyVideoParser;
28+
29+
tcuvidGetDecoderCaps *cuvidGetDecoderCaps;
30+
tcuvidCreateDecoder *cuvidCreateDecoder;
31+
tcuvidDestroyDecoder *cuvidDestroyDecoder;
32+
tcuvidDecodePicture *cuvidDecodePicture;
33+
34+
tcuvidMapVideoFrame *cuvidMapVideoFrame;
35+
tcuvidUnmapVideoFrame *cuvidUnmapVideoFrame;
36+
37+
#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
38+
tcuvidMapVideoFrame64 *cuvidMapVideoFrame64;
39+
tcuvidUnmapVideoFrame64 *cuvidUnmapVideoFrame64;
40+
#endif
41+
42+
//tcuvidGetVideoFrameSurface *cuvidGetVideoFrameSurface;
43+
tcuvidCtxLockCreate *cuvidCtxLockCreate;
44+
tcuvidCtxLockDestroy *cuvidCtxLockDestroy;
45+
tcuvidCtxLock *cuvidCtxLock;
46+
tcuvidCtxUnlock *cuvidCtxUnlock;
47+
48+
49+
// Auto-lock helper for C++ applications
50+
CCtxAutoLock::CCtxAutoLock(CUvideoctxlock ctx)
51+
: m_ctx(ctx)
52+
{
53+
cuvidCtxLock(m_ctx, 0);
54+
}
55+
CCtxAutoLock::~CCtxAutoLock()
56+
{
57+
cuvidCtxUnlock(m_ctx, 0);
58+
}
59+
60+
61+
62+
#define STRINGIFY(X) #X
63+
64+
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
65+
#include <Windows.h>
66+
67+
#ifdef UNICODE
68+
static LPCWSTR __DriverLibName = L"nvcuvid.dll";
69+
#else
70+
static LPCSTR __DriverLibName = "nvcuvid.dll";
71+
#endif
72+
73+
74+
typedef HMODULE DLLDRIVER;
75+
76+
static CUresult LOAD_LIBRARY(DLLDRIVER *pInstance)
77+
{
78+
*pInstance = LoadLibrary(__DriverLibName);
79+
80+
if (*pInstance == NULL)
81+
{
82+
printf("LoadLibrary \"%s\" failed!\n", __DriverLibName);
83+
return CUDA_ERROR_UNKNOWN;
84+
}
85+
86+
return CUDA_SUCCESS;
87+
}
88+
89+
#define GET_PROC_EX(name, alias, required) \
90+
alias = (t##name *)GetProcAddress(DriverLib, #name); \
91+
if (alias == NULL && required) { \
92+
printf("Failed to find required function \"%s\" in %s\n", \
93+
#name, __DriverLibName); \
94+
return CUDA_ERROR_UNKNOWN; \
95+
}
96+
97+
#define GET_PROC_EX_V2(name, alias, required) \
98+
alias = (t##name *)GetProcAddress(DriverLib, STRINGIFY(name##_v2));\
99+
if (alias == NULL && required) { \
100+
printf("Failed to find required function \"%s\" in %s\n", \
101+
STRINGIFY(name##_v2), __DriverLibName); \
102+
return CUDA_ERROR_UNKNOWN; \
103+
}
104+
105+
#elif defined(__unix__) || defined(__APPLE__) || defined(__MACOSX)
106+
107+
#include <dlfcn.h>
108+
109+
static char __DriverLibName[] = "libnvcuvid.so";
110+
static char __DriverLibName1[] = "libnvcuvid.so.1";
111+
112+
typedef void *DLLDRIVER;
113+
114+
static CUresult LOAD_LIBRARY(DLLDRIVER *pInstance)
115+
{
116+
*pInstance = dlopen(__DriverLibName, RTLD_NOW);
117+
118+
if (*pInstance == NULL)
119+
{
120+
*pInstance = dlopen(__DriverLibName1, RTLD_NOW);
121+
122+
if (*pInstance == NULL)
123+
{
124+
printf("dlopen \"%s\" failed!\n", __DriverLibName);
125+
return CUDA_ERROR_UNKNOWN;
126+
}
127+
}
128+
129+
return CUDA_SUCCESS;
130+
}
131+
132+
#define GET_PROC_EX(name, alias, required) \
133+
alias = (t##name *)dlsym(DriverLib, #name); \
134+
if (alias == NULL && required) { \
135+
printf("Failed to find required function \"%s\" in %s\n", \
136+
#name, __DriverLibName); \
137+
return CUDA_ERROR_UNKNOWN; \
138+
}
139+
140+
#define GET_PROC_EX_V2(name, alias, required) \
141+
alias = (t##name *)dlsym(DriverLib, STRINGIFY(name##_v2)); \
142+
if (alias == NULL && required) { \
143+
printf("Failed to find required function \"%s\" in %s\n", \
144+
STRINGIFY(name##_v2), __DriverLibName); \
145+
return CUDA_ERROR_UNKNOWN; \
146+
}
147+
148+
#else
149+
#error unsupported platform
150+
#endif
151+
152+
#define CHECKED_CALL(call) \
153+
do { \
154+
CUresult result = (call); \
155+
if (CUDA_SUCCESS != result) { \
156+
return result; \
157+
} \
158+
} while(0)
159+
160+
#define GET_PROC_REQUIRED(name) GET_PROC_EX(name,name,1)
161+
#define GET_PROC_OPTIONAL(name) GET_PROC_EX(name,name,0)
162+
#define GET_PROC(name) GET_PROC_REQUIRED(name)
163+
#define GET_PROC_V2(name) GET_PROC_EX_V2(name,name,1)
164+
165+
CUresult CUDAAPI cuvidInit(unsigned int Flags)
166+
{
167+
DLLDRIVER DriverLib;
168+
169+
CHECKED_CALL(LOAD_LIBRARY(&DriverLib));
170+
171+
// fetch all function pointers
172+
GET_PROC(cuvidCreateVideoSource);
173+
GET_PROC(cuvidCreateVideoSourceW);
174+
GET_PROC(cuvidDestroyVideoSource);
175+
GET_PROC(cuvidSetVideoSourceState);
176+
GET_PROC(cuvidGetVideoSourceState);
177+
GET_PROC(cuvidGetSourceVideoFormat);
178+
GET_PROC(cuvidGetSourceAudioFormat);
179+
180+
GET_PROC(cuvidCreateVideoParser);
181+
GET_PROC(cuvidParseVideoData);
182+
GET_PROC(cuvidDestroyVideoParser);
183+
184+
GET_PROC(cuvidGetDecoderCaps);
185+
GET_PROC(cuvidCreateDecoder);
186+
GET_PROC(cuvidDestroyDecoder);
187+
GET_PROC(cuvidDecodePicture);
188+
189+
#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
190+
GET_PROC(cuvidMapVideoFrame64);
191+
GET_PROC(cuvidUnmapVideoFrame64);
192+
cuvidMapVideoFrame = cuvidMapVideoFrame64;
193+
cuvidUnmapVideoFrame = cuvidUnmapVideoFrame64;
194+
#else
195+
GET_PROC(cuvidMapVideoFrame);
196+
GET_PROC(cuvidUnmapVideoFrame);
197+
#endif
198+
199+
// GET_PROC(cuvidGetVideoFrameSurface);
200+
GET_PROC(cuvidCtxLockCreate);
201+
GET_PROC(cuvidCtxLockDestroy);
202+
GET_PROC(cuvidCtxLock);
203+
GET_PROC(cuvidCtxUnlock);
204+
205+
return CUDA_SUCCESS;
206+
}
207+
208+
bool cuvidInitChecked(unsigned int Flags) {
209+
CUresult res = cuvidInit(Flags);
210+
return res == CUDA_SUCCESS;
211+
}

0 commit comments

Comments
 (0)