mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 20:42:53 +08:00
Merge pull request #19562 from alalek:libva_dynamic
This commit is contained in:
commit
db2cefd12b
@ -395,10 +395,10 @@ OCV_OPTION(WITH_OPENCL_D3D11_NV "Include NVIDIA OpenCL D3D11 support" WITH_DIREC
|
|||||||
OCV_OPTION(WITH_LIBREALSENSE "Include Intel librealsense support" OFF
|
OCV_OPTION(WITH_LIBREALSENSE "Include Intel librealsense support" OFF
|
||||||
VISIBLE_IF NOT WITH_INTELPERC
|
VISIBLE_IF NOT WITH_INTELPERC
|
||||||
VERIFY HAVE_LIBREALSENSE)
|
VERIFY HAVE_LIBREALSENSE)
|
||||||
OCV_OPTION(WITH_VA "Include VA support" OFF
|
OCV_OPTION(WITH_VA "Include VA support" ON
|
||||||
VISIBLE_IF UNIX AND NOT ANDROID
|
VISIBLE_IF UNIX AND NOT ANDROID
|
||||||
VERIFY HAVE_VA)
|
VERIFY HAVE_VA)
|
||||||
OCV_OPTION(WITH_VA_INTEL "Include Intel VA-API/OpenCL support" OFF
|
OCV_OPTION(WITH_VA_INTEL "Include Intel VA-API/OpenCL support" ON
|
||||||
VISIBLE_IF UNIX AND NOT ANDROID
|
VISIBLE_IF UNIX AND NOT ANDROID
|
||||||
VERIFY HAVE_VA_INTEL)
|
VERIFY HAVE_VA_INTEL)
|
||||||
OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF
|
OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF
|
||||||
|
@ -2,21 +2,20 @@
|
|||||||
# HAVE_VA - libva is available
|
# HAVE_VA - libva is available
|
||||||
# HAVE_VA_INTEL - OpenCL/libva Intel interoperability extension is available
|
# HAVE_VA_INTEL - OpenCL/libva Intel interoperability extension is available
|
||||||
|
|
||||||
if(UNIX AND NOT ANDROID)
|
find_path(
|
||||||
find_path(
|
|
||||||
VA_INCLUDE_DIR
|
VA_INCLUDE_DIR
|
||||||
NAMES va/va.h
|
NAMES va/va.h
|
||||||
PATHS "/usr/include"
|
PATHS ${VA_ROOT_DIR}
|
||||||
PATH_SUFFIXES include
|
PATH_SUFFIXES include
|
||||||
DOC "Path to libva headers")
|
DOC "Path to libva headers"
|
||||||
endif()
|
)
|
||||||
|
|
||||||
if(VA_INCLUDE_DIR)
|
if(VA_INCLUDE_DIR)
|
||||||
set(HAVE_VA TRUE)
|
set(HAVE_VA TRUE)
|
||||||
if(NOT DEFINED VA_LIBRARIES)
|
if(NOT DEFINED VA_LIBRARIES AND NOT OPENCV_LIBVA_LINK)
|
||||||
set(VA_LIBRARIES "va" "va-drm")
|
set(VA_LIBRARIES "va" "va-drm")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(HAVE_VA FALSE)
|
set(HAVE_VA FALSE)
|
||||||
message(WARNING "libva installation is not found.")
|
message(STATUS "libva: missing va.h header (VA_INCLUDE_DIR)")
|
||||||
endif()
|
endif()
|
||||||
|
@ -99,6 +99,9 @@ endif()
|
|||||||
if(HAVE_VA_INTEL_OLD_HEADER)
|
if(HAVE_VA_INTEL_OLD_HEADER)
|
||||||
ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "HAVE_VA_INTEL_OLD_HEADER")
|
ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "HAVE_VA_INTEL_OLD_HEADER")
|
||||||
endif()
|
endif()
|
||||||
|
if(OPENCV_LIBVA_LINK)
|
||||||
|
ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "OPENCV_LIBVA_LINK=1")
|
||||||
|
endif()
|
||||||
|
|
||||||
option(OPENCV_ENABLE_ALLOCATOR_STATS "Enable Allocator metrics" ON)
|
option(OPENCV_ENABLE_ALLOCATOR_STATS "Enable Allocator metrics" ON)
|
||||||
|
|
||||||
|
@ -33,6 +33,17 @@ using namespace cv;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_VA
|
||||||
|
#ifndef OPENCV_LIBVA_LINK
|
||||||
|
#include "va_wrapper.impl.hpp"
|
||||||
|
#else
|
||||||
|
namespace cv { namespace detail {
|
||||||
|
static void init_libva() { /* nothing */ }
|
||||||
|
}} // namespace
|
||||||
|
#endif
|
||||||
|
using namespace cv::detail;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cv { namespace va_intel {
|
namespace cv { namespace va_intel {
|
||||||
|
|
||||||
#ifdef HAVE_VA_INTEL
|
#ifdef HAVE_VA_INTEL
|
||||||
@ -54,6 +65,8 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop)
|
|||||||
#if !defined(HAVE_VA)
|
#if !defined(HAVE_VA)
|
||||||
NO_VA_SUPPORT_ERROR;
|
NO_VA_SUPPORT_ERROR;
|
||||||
#else // !HAVE_VA
|
#else // !HAVE_VA
|
||||||
|
init_libva();
|
||||||
|
|
||||||
# ifdef HAVE_VA_INTEL
|
# ifdef HAVE_VA_INTEL
|
||||||
contextInitialized = false;
|
contextInitialized = false;
|
||||||
if (tryInterop)
|
if (tryInterop)
|
||||||
@ -507,6 +520,8 @@ void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface,
|
|||||||
#if !defined(HAVE_VA)
|
#if !defined(HAVE_VA)
|
||||||
NO_VA_SUPPORT_ERROR;
|
NO_VA_SUPPORT_ERROR;
|
||||||
#else // !HAVE_VA
|
#else // !HAVE_VA
|
||||||
|
init_libva();
|
||||||
|
|
||||||
const int stype = CV_8UC3;
|
const int stype = CV_8UC3;
|
||||||
|
|
||||||
int srcType = src.type();
|
int srcType = src.type();
|
||||||
@ -611,6 +626,8 @@ void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, Out
|
|||||||
#if !defined(HAVE_VA)
|
#if !defined(HAVE_VA)
|
||||||
NO_VA_SUPPORT_ERROR;
|
NO_VA_SUPPORT_ERROR;
|
||||||
#else // !HAVE_VA
|
#else // !HAVE_VA
|
||||||
|
init_libva();
|
||||||
|
|
||||||
const int dtype = CV_8UC3;
|
const int dtype = CV_8UC3;
|
||||||
|
|
||||||
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
|
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
|
||||||
|
85
modules/core/src/va_wrapper.impl.hpp
Normal file
85
modules/core/src/va_wrapper.impl.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// This file is part of OpenCV project.
|
||||||
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not a standalone header, part of va_intel.cpp
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "opencv2/core/utils/plugin_loader.private.hpp" // DynamicLib
|
||||||
|
|
||||||
|
namespace cv { namespace detail {
|
||||||
|
|
||||||
|
typedef VAStatus (*FN_vaDeriveImage)(VADisplay dpy, VASurfaceID surface, VAImage *image);
|
||||||
|
typedef VAStatus (*FN_vaDestroyImage)(VADisplay dpy, VAImageID image);
|
||||||
|
typedef VAStatus (*FN_vaMapBuffer)(VADisplay dpy, VABufferID buf_id, void **pbuf);
|
||||||
|
typedef VAStatus (*FN_vaSyncSurface)(VADisplay dpy, VASurfaceID render_target);
|
||||||
|
typedef VAStatus (*FN_vaUnmapBuffer)(VADisplay dpy, VABufferID buf_id);
|
||||||
|
|
||||||
|
static FN_vaDeriveImage fn_vaDeriveImage = NULL;
|
||||||
|
static FN_vaDestroyImage fn_vaDestroyImage = NULL;
|
||||||
|
static FN_vaMapBuffer fn_vaMapBuffer = NULL;
|
||||||
|
static FN_vaSyncSurface fn_vaSyncSurface = NULL;
|
||||||
|
static FN_vaUnmapBuffer fn_vaUnmapBuffer = NULL;
|
||||||
|
|
||||||
|
#define vaDeriveImage fn_vaDeriveImage
|
||||||
|
#define vaDestroyImage fn_vaDestroyImage
|
||||||
|
#define vaMapBuffer fn_vaMapBuffer
|
||||||
|
#define vaSyncSurface fn_vaSyncSurface
|
||||||
|
#define vaUnmapBuffer fn_vaUnmapBuffer
|
||||||
|
|
||||||
|
|
||||||
|
static std::shared_ptr<cv::plugin::impl::DynamicLib> loadLibVA()
|
||||||
|
{
|
||||||
|
std::shared_ptr<cv::plugin::impl::DynamicLib> lib;
|
||||||
|
const char* envPath = getenv("OPENCV_LIBVA_RUNTIME");
|
||||||
|
if (envPath)
|
||||||
|
{
|
||||||
|
lib = std::make_shared<cv::plugin::impl::DynamicLib>(envPath);
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
static const char* const candidates[] = {
|
||||||
|
"libva.so",
|
||||||
|
"libva.so.2",
|
||||||
|
"libva.so.1",
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
lib = std::make_shared<cv::plugin::impl::DynamicLib>(candidates[i]);
|
||||||
|
if (lib->isLoaded())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
static void init_libva()
|
||||||
|
{
|
||||||
|
static bool initialized = false;
|
||||||
|
static auto library = loadLibVA();
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
if (!library || !library->isLoaded())
|
||||||
|
{
|
||||||
|
library.reset();
|
||||||
|
CV_Error(cv::Error::StsBadFunc, "OpenCV can't load VA library (libva)");
|
||||||
|
}
|
||||||
|
auto& lib = *library.get();
|
||||||
|
#define VA_LOAD_SYMBOL(name) fn_ ## name = reinterpret_cast<FN_ ## name>(lib.getSymbol(#name)); \
|
||||||
|
if (!fn_ ## name) \
|
||||||
|
{ \
|
||||||
|
library.reset(); \
|
||||||
|
initialized = true; \
|
||||||
|
CV_Error_(cv::Error::StsBadFunc, ("OpenCV can't load VA library (libva), missing symbol: %s", #name)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
VA_LOAD_SYMBOL(vaDeriveImage);
|
||||||
|
VA_LOAD_SYMBOL(vaDestroyImage);
|
||||||
|
VA_LOAD_SYMBOL(vaMapBuffer);
|
||||||
|
VA_LOAD_SYMBOL(vaSyncSurface);
|
||||||
|
VA_LOAD_SYMBOL(vaUnmapBuffer);
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
if (!library)
|
||||||
|
CV_Error(cv::Error::StsBadFunc, "OpenCV can't load/initialize VA library (libva)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace
|
@ -10,6 +10,8 @@
|
|||||||
#include <va/va.h>
|
#include <va/va.h>
|
||||||
# include <va/va_drm.h>
|
# include <va/va_drm.h>
|
||||||
|
|
||||||
|
#include "opencv2/core.hpp" // cv::format()
|
||||||
|
|
||||||
namespace va {
|
namespace va {
|
||||||
|
|
||||||
bool openDisplay();
|
bool openDisplay();
|
||||||
@ -70,10 +72,9 @@ static unsigned readId(const char* devName, const char* idName)
|
|||||||
{
|
{
|
||||||
long int id = 0;
|
long int id = 0;
|
||||||
|
|
||||||
char fileName[256];
|
std::string fileName = cv::format("%s/%s/%s", VA_INTEL_PCI_DIR, devName, idName);
|
||||||
snprintf(fileName, sizeof(fileName), "%s/%s/%s", VA_INTEL_PCI_DIR, devName, idName);
|
|
||||||
|
|
||||||
FILE* file = fopen(fileName, "r");
|
FILE* file = fopen(fileName.c_str(), "r");
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
char str[16] = "";
|
char str[16] = "";
|
||||||
@ -100,9 +101,8 @@ static int findAdapter(unsigned desiredVendorId)
|
|||||||
unsigned vendorId = readId(name, "vendor");
|
unsigned vendorId = readId(name, "vendor");
|
||||||
if (vendorId == desiredVendorId)
|
if (vendorId == desiredVendorId)
|
||||||
{
|
{
|
||||||
char subdirName[256];
|
std::string subdirName = cv::format("%s/%s/%s", VA_INTEL_PCI_DIR, name, "drm");
|
||||||
snprintf(subdirName, sizeof(subdirName), "%s/%s/%s", VA_INTEL_PCI_DIR, name, "drm");
|
Directory subdir(subdirName.c_str());
|
||||||
Directory subdir(subdirName);
|
|
||||||
for (int j = 0; j < subdir.count(); ++j)
|
for (int j = 0; j < subdir.count(); ++j)
|
||||||
{
|
{
|
||||||
if (!strncmp(subdir[j]->d_name, "card", 4))
|
if (!strncmp(subdir[j]->d_name, "card", 4))
|
||||||
@ -130,18 +130,12 @@ public:
|
|||||||
numbers[1] = adapterIndex;
|
numbers[1] = adapterIndex;
|
||||||
for (int i = 0; i < NUM_NODES; ++i)
|
for (int i = 0; i < NUM_NODES; ++i)
|
||||||
{
|
{
|
||||||
int sz = sizeof(VA_INTEL_DRI_DIR) + strlen(names[i]) + 3;
|
paths[i] = cv::format("%s%s%d", VA_INTEL_DRI_DIR, names[i], numbers[i]);
|
||||||
paths[i] = new char [sz];
|
|
||||||
snprintf(paths[i], sz, "%s%s%d", VA_INTEL_DRI_DIR, names[i], numbers[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~NodeInfo()
|
~NodeInfo()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_NODES; ++i)
|
// nothing
|
||||||
{
|
|
||||||
delete paths[i];
|
|
||||||
paths[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int count() const
|
int count() const
|
||||||
{
|
{
|
||||||
@ -149,10 +143,10 @@ public:
|
|||||||
}
|
}
|
||||||
const char* path(int index) const
|
const char* path(int index) const
|
||||||
{
|
{
|
||||||
return ((index >= 0) && (index < NUM_NODES)) ? paths[index] : 0;
|
return ((index >= 0) && (index < NUM_NODES)) ? paths[index].c_str() : 0;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
char* paths[NUM_NODES];
|
std::string paths[NUM_NODES];
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool openDeviceIntel();
|
static bool openDeviceIntel();
|
||||||
|
Loading…
Reference in New Issue
Block a user