Skip to content

Commit

Permalink
Change nvcuvid link to dyn + hint for FFmpeg (#370)
Browse files Browse the repository at this point in the history
* Change nvcuvid link to dyn + hint for FFmpeg

Signed-off-by: Serge Panev <[email protected]>

* Add enforce and error message for libnvcuvid dynlink

Signed-off-by: Serge Panev <[email protected]>

* Add missing CMake checks

Signed-off-by: Serge Panev <[email protected]>
  • Loading branch information
Kh4L authored and JanuszL committed Dec 15, 2018
1 parent 0a8503d commit c8d9d72
Show file tree
Hide file tree
Showing 10 changed files with 1,529 additions and 1,293 deletions.
34 changes: 22 additions & 12 deletions cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -154,26 +154,36 @@ list(APPEND DALI_EXCLUDES libprotobuf.a)
##################################################################
# FFmpeg
##################################################################

include(CheckStructHasMember)
include(CheckTypeSize)

set(FFMPEG_ROOT_DIR "" CACHE PATH "Folder contains FFmeg")

find_package(PkgConfig REQUIRED)
foreach(m avformat avcodec avfilter avutil)
string(TOUPPER ${m} M)
#pkg_check_modules(${m} REQUIRED IMPORTED_TARGET lib${m})
pkg_check_modules(${m} REQUIRED lib${m})
list(APPEND FFmpeg_LIBS ${m})
#list(APPEND FFmpeg_LIBS PkgConfig::${m})
# We do a find_library only if FFMPEG_ROOT_DIR is provided
if(NOT FFMPEG_ROOT_DIR)
string(TOUPPER ${m} M)
pkg_check_modules(${m} REQUIRED lib${m})
list(APPEND FFmpeg_LIBS ${m})
else()
find_library(FFmpeg_Lib ${m}
PATHS ${FFMPEG_ROOT_DIR}
PATH_SUFFIXES lib lib64
NO_DEFAULT_PATH)
list(APPEND FFmpeg_LIBS ${FFmpeg_Lib})
message(STATUS ${m})
endif()
endforeach(m)

# TODO check set(CMAKE_REQUIRED_INCLUDES ${avformat_INCLUDE_DIRS})
include_directories(${avformat_INCLUDE_DIRS})
# TODO check if set(CMAKE_REQUIRED_LIBRARIES ${avformat_LIBRARIES})
# optional?
list(APPEND DALI_LIBS ${avformat_LIBRARIES})
# CHECK_STRUCT_HAS_MEMBER("struct AVStream" codecpar libavformat/avformat.h HAVE_AVSTREAM_CODECPAR LANGUAGE C)
CHECK_STRUCT_HAS_MEMBER("struct AVStream" codecpar libavformat/avformat.h HAVE_AVSTREAM_CODECPAR LANGUAGE C)
set(CMAKE_EXTRA_INCLUDE_FILES libavcodec/avcodec.h)
#check_type_size("AVBSFContext" AVBSFCONTEXT LANGUAGE CXX)
CHECK_TYPE_SIZE("AVBSFContext" AVBSFCONTEXT LANGUAGE CXX)

# nvcuvid cuda and nvidia-ml from the driver
list(APPEND DALI_LIBS ${FFmpeg_LIBS} nvcuvid cuda)
list(APPEND DALI_LIBS ${FFmpeg_LIBS} cuda)

##################################################################
# Exclude stdlib
Expand Down
5 changes: 3 additions & 2 deletions cmake/lint.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ file(GLOB_RECURSE LINT_FILES ${CMAKE_SOURCE_DIR}/dali/*.cc ${CMAKE_SOURCE_DIR}/d

# Excluded files
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/util/json.h)
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/nvcuvid.h)
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/cuviddec.h)
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h)
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_cuviddec.h)
list(REMOVE_ITEM LINT_FILES ${CMAKE_SOURCE_DIR}/dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.cc)

execute_process(
COMMAND ${LINT_COMMAND} --linelength=100 ${LINT_FILES}
Expand Down
6 changes: 5 additions & 1 deletion dali/pipeline/operators/reader/loader/video_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern "C" {
#include "dali/pipeline/operators/reader/loader/loader.h"
#include "dali/pipeline/operators/reader/nvdecoder/nvdecoder.h"
#include "dali/pipeline/operators/reader/nvdecoder/sequencewrapper.h"
#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"

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

void init() {
DALI_ENFORCE(cuvidInitChecked(0),
"Failed to load libnvcuvid.so, needed by the VideoReader operator. "
"If you are running in a Docker container, please refer "
"to https://github.com/NVIDIA/nvidia-docker/wiki/Usage");
/* Required to use libavformat: Initialize libavformat and register all
* the muxers, demuxers and protocols.
*/
Expand Down
2 changes: 1 addition & 1 deletion dali/pipeline/operators/reader/nvdecoder/cuvideodecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#ifndef DALI_PIPELINE_OPERATORS_READER_NVDECODER_CUVIDEODECODER_H_
#define DALI_PIPELINE_OPERATORS_READER_NVDECODER_CUVIDEODECODER_H_

#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
#include "dali/error_handling.h"

namespace dali {
Expand Down
2 changes: 1 addition & 1 deletion dali/pipeline/operators/reader/nvdecoder/cuvideoparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <algorithm>
#include <cstring>

#include "dali/pipeline/operators/reader/nvdecoder/nvcuvid.h"
#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"
#include "dali/error_handling.h"


Expand Down

Large diffs are not rendered by default.

211 changes: 211 additions & 0 deletions dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright 1993-2017 NVIDIA Corporation. All rights reserved.
*
* Please refer to the NVIDIA end user license agreement (EULA) associated
* with this source code for terms and conditions that govern your use of
* this software. Any use, reproduction, disclosure, or distribution of
* this software and related documentation outside the terms of the EULA
* is strictly prohibited.
*
*/


#include <stdio.h>

#include "dali/pipeline/operators/reader/nvdecoder/dynlink_nvcuvid.h"

tcuvidCreateVideoSource *cuvidCreateVideoSource;
tcuvidCreateVideoSourceW *cuvidCreateVideoSourceW;
tcuvidDestroyVideoSource *cuvidDestroyVideoSource;
tcuvidSetVideoSourceState *cuvidSetVideoSourceState;
tcuvidGetVideoSourceState *cuvidGetVideoSourceState;
tcuvidGetSourceVideoFormat *cuvidGetSourceVideoFormat;
tcuvidGetSourceAudioFormat *cuvidGetSourceAudioFormat;

tcuvidCreateVideoParser *cuvidCreateVideoParser;
tcuvidParseVideoData *cuvidParseVideoData;
tcuvidDestroyVideoParser *cuvidDestroyVideoParser;

tcuvidGetDecoderCaps *cuvidGetDecoderCaps;
tcuvidCreateDecoder *cuvidCreateDecoder;
tcuvidDestroyDecoder *cuvidDestroyDecoder;
tcuvidDecodePicture *cuvidDecodePicture;

tcuvidMapVideoFrame *cuvidMapVideoFrame;
tcuvidUnmapVideoFrame *cuvidUnmapVideoFrame;

#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
tcuvidMapVideoFrame64 *cuvidMapVideoFrame64;
tcuvidUnmapVideoFrame64 *cuvidUnmapVideoFrame64;
#endif

//tcuvidGetVideoFrameSurface *cuvidGetVideoFrameSurface;
tcuvidCtxLockCreate *cuvidCtxLockCreate;
tcuvidCtxLockDestroy *cuvidCtxLockDestroy;
tcuvidCtxLock *cuvidCtxLock;
tcuvidCtxUnlock *cuvidCtxUnlock;


// Auto-lock helper for C++ applications
CCtxAutoLock::CCtxAutoLock(CUvideoctxlock ctx)
: m_ctx(ctx)
{
cuvidCtxLock(m_ctx, 0);
}
CCtxAutoLock::~CCtxAutoLock()
{
cuvidCtxUnlock(m_ctx, 0);
}



#define STRINGIFY(X) #X

#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#include <Windows.h>

#ifdef UNICODE
static LPCWSTR __DriverLibName = L"nvcuvid.dll";
#else
static LPCSTR __DriverLibName = "nvcuvid.dll";
#endif


typedef HMODULE DLLDRIVER;

static CUresult LOAD_LIBRARY(DLLDRIVER *pInstance)
{
*pInstance = LoadLibrary(__DriverLibName);

if (*pInstance == NULL)
{
printf("LoadLibrary \"%s\" failed!\n", __DriverLibName);
return CUDA_ERROR_UNKNOWN;
}

return CUDA_SUCCESS;
}

#define GET_PROC_EX(name, alias, required) \
alias = (t##name *)GetProcAddress(DriverLib, #name); \
if (alias == NULL && required) { \
printf("Failed to find required function \"%s\" in %s\n", \
#name, __DriverLibName); \
return CUDA_ERROR_UNKNOWN; \
}

#define GET_PROC_EX_V2(name, alias, required) \
alias = (t##name *)GetProcAddress(DriverLib, STRINGIFY(name##_v2));\
if (alias == NULL && required) { \
printf("Failed to find required function \"%s\" in %s\n", \
STRINGIFY(name##_v2), __DriverLibName); \
return CUDA_ERROR_UNKNOWN; \
}

#elif defined(__unix__) || defined(__APPLE__) || defined(__MACOSX)

#include <dlfcn.h>

static char __DriverLibName[] = "libnvcuvid.so";
static char __DriverLibName1[] = "libnvcuvid.so.1";

typedef void *DLLDRIVER;

static CUresult LOAD_LIBRARY(DLLDRIVER *pInstance)
{
*pInstance = dlopen(__DriverLibName, RTLD_NOW);

if (*pInstance == NULL)
{
*pInstance = dlopen(__DriverLibName1, RTLD_NOW);

if (*pInstance == NULL)
{
printf("dlopen \"%s\" failed!\n", __DriverLibName);
return CUDA_ERROR_UNKNOWN;
}
}

return CUDA_SUCCESS;
}

#define GET_PROC_EX(name, alias, required) \
alias = (t##name *)dlsym(DriverLib, #name); \
if (alias == NULL && required) { \
printf("Failed to find required function \"%s\" in %s\n", \
#name, __DriverLibName); \
return CUDA_ERROR_UNKNOWN; \
}

#define GET_PROC_EX_V2(name, alias, required) \
alias = (t##name *)dlsym(DriverLib, STRINGIFY(name##_v2)); \
if (alias == NULL && required) { \
printf("Failed to find required function \"%s\" in %s\n", \
STRINGIFY(name##_v2), __DriverLibName); \
return CUDA_ERROR_UNKNOWN; \
}

#else
#error unsupported platform
#endif

#define CHECKED_CALL(call) \
do { \
CUresult result = (call); \
if (CUDA_SUCCESS != result) { \
return result; \
} \
} while(0)

#define GET_PROC_REQUIRED(name) GET_PROC_EX(name,name,1)
#define GET_PROC_OPTIONAL(name) GET_PROC_EX(name,name,0)
#define GET_PROC(name) GET_PROC_REQUIRED(name)
#define GET_PROC_V2(name) GET_PROC_EX_V2(name,name,1)

CUresult CUDAAPI cuvidInit(unsigned int Flags)
{
DLLDRIVER DriverLib;

CHECKED_CALL(LOAD_LIBRARY(&DriverLib));

// fetch all function pointers
GET_PROC(cuvidCreateVideoSource);
GET_PROC(cuvidCreateVideoSourceW);
GET_PROC(cuvidDestroyVideoSource);
GET_PROC(cuvidSetVideoSourceState);
GET_PROC(cuvidGetVideoSourceState);
GET_PROC(cuvidGetSourceVideoFormat);
GET_PROC(cuvidGetSourceAudioFormat);

GET_PROC(cuvidCreateVideoParser);
GET_PROC(cuvidParseVideoData);
GET_PROC(cuvidDestroyVideoParser);

GET_PROC(cuvidGetDecoderCaps);
GET_PROC(cuvidCreateDecoder);
GET_PROC(cuvidDestroyDecoder);
GET_PROC(cuvidDecodePicture);

#if defined(WIN64) || defined(_WIN64) || defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
GET_PROC(cuvidMapVideoFrame64);
GET_PROC(cuvidUnmapVideoFrame64);
cuvidMapVideoFrame = cuvidMapVideoFrame64;
cuvidUnmapVideoFrame = cuvidUnmapVideoFrame64;
#else
GET_PROC(cuvidMapVideoFrame);
GET_PROC(cuvidUnmapVideoFrame);
#endif

// GET_PROC(cuvidGetVideoFrameSurface);
GET_PROC(cuvidCtxLockCreate);
GET_PROC(cuvidCtxLockDestroy);
GET_PROC(cuvidCtxLock);
GET_PROC(cuvidCtxUnlock);

return CUDA_SUCCESS;
}

bool cuvidInitChecked(unsigned int Flags) {
CUresult res = cuvidInit(Flags);
return res == CUDA_SUCCESS;
}
Loading

0 comments on commit c8d9d72

Please sign in to comment.