diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a7c730bc0..01d49ab84a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,7 @@ OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O" ON IF IOS) OCV_OPTION(WITH_CARBON "Use Carbon for UI instead of Cocoa" OFF IF APPLE ) OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) +OCV_OPTION(DYNAMIC_CUDA_SUPPORT "Make CUDA support dynamic" OFF IF (WITH_CUDA) AND NOT IOS AND NOT WINDOWS) OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" ON IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BLAS) library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT IOS) ) OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF IF (CMAKE_VERSION VERSION_GREATER "2.8" AND NOT ANDROID AND NOT IOS AND NOT APPLE) ) @@ -853,6 +854,7 @@ if(HAVE_CUDA) status("") status(" NVIDIA CUDA") + status(" Dynamic CUDA support:" DYNAMIC_CUDA_SUPPORT THEN YES ELSE NO) status(" Use CUFFT:" HAVE_CUFFT THEN YES ELSE NO) status(" Use CUBLAS:" HAVE_CUBLAS THEN YES ELSE NO) status(" USE NVCUVID:" HAVE_NVCUVID THEN YES ELSE NO) diff --git a/modules/core/cuda/CMakeLists.txt b/modules/core/cuda/CMakeLists.txt index 72ecea7a4c..828e13b80c 100644 --- a/modules/core/cuda/CMakeLists.txt +++ b/modules/core/cuda/CMakeLists.txt @@ -7,4 +7,8 @@ include_directories(${CUDA_INCLUDE_DIRS} ) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) cuda_add_library(opencv_core_cuda SHARED main.cpp ../src/cuda/matrix_operations.cu) -target_link_libraries(opencv_core_cuda ${CUDA_LIBRARIES}) \ No newline at end of file +if(BUILD_FAT_JAVA_LIB) + target_link_libraries(opencv_core_cuda ${OPENCV_BUILD_DIR}/${LIBRARY_OUTPUT_PATH}/libopencv_java.so ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) +else() + target_link_libraries(opencv_core_cuda ${OPENCV_BUILD_DIR}/${LIBRARY_OUTPUT_PATH}/libopencv_core.so ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) +endif() \ No newline at end of file diff --git a/modules/core/src/gpumat.cpp b/modules/core/src/gpumat.cpp index dc24b6e821..c8d1d058b1 100644 --- a/modules/core/src/gpumat.cpp +++ b/modules/core/src/gpumat.cpp @@ -43,7 +43,6 @@ #include "precomp.hpp" #include "opencv2/core/gpumat.hpp" #include -#include #if defined(HAVE_CUDA) || defined(DYNAMIC_CUDA_SUPPORT) #include @@ -61,6 +60,22 @@ #endif #endif +#ifdef DYNAMIC_CUDA_SUPPORT +#include +#include +#include +#include +#endif + +#ifdef ANDROID +# include + +# define LOG_TAG "OpenCV::CUDA" +# define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) +# define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +# define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) +#endif + using namespace std; using namespace cv; using namespace cv::gpu; @@ -69,16 +84,90 @@ using namespace cv::gpu; #include "gpumat_cuda.hpp" +#ifdef DYNAMIC_CUDA_SUPPORT + typedef GpuFuncTable* (*GpuFactoryType)(); typedef DeviceInfoFuncTable* (*DeviceInfoFactoryType)(); static GpuFactoryType gpuFactory = NULL; static DeviceInfoFactoryType deviceInfoFactory = NULL; +# if defined(__linux__) || defined(__APPLE__) || defined (ANDROID) +# ifdef ANDROID +static const std::string getCudaSupportLibName() +{ + Dl_info dl_info; + if(0 != dladdr((void *)getCudaSupportLibName, &dl_info)) + { + LOGD("Library name: %s", dl_info.dli_fname); + LOGD("Library base address: %p", dl_info.dli_fbase); + + const char* libName=dl_info.dli_fname; + while( ((*libName)=='/') || ((*libName)=='.') ) + libName++; + + char lineBuf[2048]; + FILE* file = fopen("/proc/self/smaps", "rt"); + + if(file) + { + while (fgets(lineBuf, sizeof lineBuf, file) != NULL) + { + //verify that line ends with library name + int lineLength = strlen(lineBuf); + int libNameLength = strlen(libName); + + //trim end + for(int i = lineLength - 1; i >= 0 && isspace(lineBuf[i]); --i) + { + lineBuf[i] = 0; + --lineLength; + } + + if (0 != strncmp(lineBuf + lineLength - libNameLength, libName, libNameLength)) + { + //the line does not contain the library name + continue; + } + + //extract path from smaps line + char* pathBegin = strchr(lineBuf, '/'); + if (0 == pathBegin) + { + LOGE("Strange error: could not find path beginning in lin \"%s\"", lineBuf); + continue; + } + + char* pathEnd = strrchr(pathBegin, '/'); + pathEnd[1] = 0; + + LOGD("Libraries folder found: %s", pathBegin); + + fclose(file); + return std::string(pathBegin) + "/libopencv_core_cuda.so"; + } + fclose(file); + LOGE("Could not find library path"); + } + else + { + LOGE("Could not read /proc/self/smaps"); + } + } + else + { + LOGE("Could not get library name and base address"); + } + + return string(); +} + +# else static const std::string getCudaSupportLibName() { return "libopencv_core_cuda.so"; } +# endif static bool loadCudaSupportLib() { @@ -102,11 +191,15 @@ static bool loadCudaSupportLib() return false; } - dlclose(handle); - return true; } +# else +# error "Dynamic CUDA support is not implemented for this platform!" +# endif + +#endif + static GpuFuncTable* gpuFuncTable() { #ifdef DYNAMIC_CUDA_SUPPORT