#ifdef HAVE_DIRECTX
#include <vector>
#include "directx.inc.hpp"
-#include "directx.hpp"
#else // HAVE_DIRECTX
#define NO_DIRECTX_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
#endif
#define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
#endif // HAVE_OPENCL
+using namespace cv::ocl;
+
namespace cv { namespace directx {
int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
}
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
-namespace internal {
-struct OpenCLDirectXImpl
-{
- cl_platform_id platform_;
-
- cl_platform_id initializedPlatform9 = NULL;
- cl_platform_id initializedPlatform10 = NULL;
- cl_platform_id initializedPlatform11 = NULL;
-public:
- OpenCLDirectXImpl()
- : platform_(0)
- {
- }
-
- bool isDirect3DDevice9Ex = false; // Direct3DDevice9Ex or Direct3DDevice9 was used
#ifdef HAVE_OPENCL_D3D11_NV
- clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV = NULL;
- clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV = NULL;
- clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV = NULL;
-#endif
- clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
- clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
- clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
-
- clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR = NULL;
- clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR = NULL;
- clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR = NULL;
-
- clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR = NULL;
- clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR = NULL;
- clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR = NULL;
-
- cl_platform_id getPlatform()
+class OpenCL_D3D11_NV : public ocl::Context::UserContext
+{
+public:
+ OpenCL_D3D11_NV(cl_platform_id platform, ID3D11Device*_device) : device(_device)
{
- if (!platform_)
+ clCreateFromD3D11Texture2DNV = (clCreateFromD3D11Texture2DNV_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DNV");
+ clEnqueueAcquireD3D11ObjectsNV = (clEnqueueAcquireD3D11ObjectsNV_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsNV");
+ clEnqueueReleaseD3D11ObjectsNV = (clEnqueueReleaseD3D11ObjectsNV_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsNV");
+ if (!clCreateFromD3D11Texture2DNV || !clEnqueueAcquireD3D11ObjectsNV || !clEnqueueReleaseD3D11ObjectsNV)
{
- CV_Assert(cv::ocl::haveOpenCL());
-
- cl_device_id device = (cl_device_id)ocl::Device::getDefault().ptr();
- CV_Assert(device);
- cl_int status = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform_), &platform_, NULL);
- if (status != CL_SUCCESS)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platform corresponding to device");
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11_NV");
}
-
- return platform_;
+ device->AddRef();
}
-
-
- bool initializeD3D11()
- {
- using namespace cv::ocl;
- cl_platform_id platform = getPlatform();
-
- bool useCLNVEXT = false;
- size_t exts_len;
- cl_int status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
- if (status != CL_SUCCESS)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
- cv::AutoBuffer<char> extensions(exts_len);
- status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
- if (status != CL_SUCCESS)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
- bool is_support_cl_khr_d3d11_sharing = false;
- if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
- is_support_cl_khr_d3d11_sharing = true;
-#ifdef HAVE_OPENCL_D3D11_NV
- bool is_support_cl_nv_d3d11_sharing = false;
- if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
- is_support_cl_nv_d3d11_sharing = true;
- if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
-#else
- if (!is_support_cl_khr_d3d11_sharing)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
+ ~OpenCL_D3D11_NV() {
+ device->Release();
+ }
+ ID3D11Device* device;
+ clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV;
+ clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV;
+ clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV;
+};
#endif
-#ifdef HAVE_OPENCL_D3D11_NV
- if (is_support_cl_nv_d3d11_sharing)
- {
- if (initializedPlatform11 != platform)
- {
- clCreateFromD3D11Texture2DNV = (clCreateFromD3D11Texture2DNV_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DNV");
- clEnqueueAcquireD3D11ObjectsNV = (clEnqueueAcquireD3D11ObjectsNV_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsNV");
- clEnqueueReleaseD3D11ObjectsNV = (clEnqueueReleaseD3D11ObjectsNV_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsNV");
- initializedPlatform11 = platform;
- }
- if (clCreateFromD3D11Texture2DNV && clEnqueueAcquireD3D11ObjectsNV && clEnqueueReleaseD3D11ObjectsNV)
- {
- useCLNVEXT = true;
- }
- }
- else
-#endif
+class OpenCL_D3D11 : public ocl::Context::UserContext
+{
+public:
+ OpenCL_D3D11(cl_platform_id platform, ID3D11Device* _device) : device(_device)
+ {
+ clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
+ clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
+ clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
+ if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
{
- if (is_support_cl_khr_d3d11_sharing)
- {
- if (initializedPlatform11 != platform)
- {
- clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
- clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
- clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
- initializedPlatform11 = platform;
- }
- if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
- {
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
- }
- }
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
}
- return useCLNVEXT;
+ device->AddRef();
+ }
+ ~OpenCL_D3D11() {
+ device->Release();
}
+ ID3D11Device* device;
+ clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR;
+ clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR;
+ clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR;
+};
- void initializeD3D9()
+class OpenCL_D3D9 : public ocl::Context::UserContext
+{
+public:
+ OpenCL_D3D9(cl_platform_id platform, IDirect3DDevice9* _device, IDirect3DDevice9Ex* _deviceEx)
+ : device(_device)
+ , deviceEx(_deviceEx)
{
- using namespace cv::ocl;
- cl_platform_id platform = getPlatform();
- if (initializedPlatform9 != platform)
- {
- clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
- clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
- clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
- initializedPlatform9 = platform;
- }
+ clCreateFromDX9MediaSurfaceKHR = (clCreateFromDX9MediaSurfaceKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromDX9MediaSurfaceKHR");
+ clEnqueueAcquireDX9MediaSurfacesKHR = (clEnqueueAcquireDX9MediaSurfacesKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireDX9MediaSurfacesKHR");
+ clEnqueueReleaseDX9MediaSurfacesKHR = (clEnqueueReleaseDX9MediaSurfacesKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseDX9MediaSurfacesKHR");
if (!clCreateFromDX9MediaSurfaceKHR || !clEnqueueAcquireDX9MediaSurfacesKHR || !clEnqueueReleaseDX9MediaSurfacesKHR)
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D9");
}
+ if (device)
+ device->AddRef();
+ if (deviceEx)
+ deviceEx->AddRef();
}
+ ~OpenCL_D3D9() {
+ if (device)
+ device->Release();
+ if (deviceEx)
+ deviceEx->Release();
+ }
+ IDirect3DDevice9* device;
+ IDirect3DDevice9Ex* deviceEx;
+ clCreateFromDX9MediaSurfaceKHR_fn clCreateFromDX9MediaSurfaceKHR;
+ clEnqueueAcquireDX9MediaSurfacesKHR_fn clEnqueueAcquireDX9MediaSurfacesKHR;
+ clEnqueueReleaseDX9MediaSurfacesKHR_fn clEnqueueReleaseDX9MediaSurfacesKHR;
+};
- void initializeD3D10()
+class OpenCL_D3D10 : public ocl::Context::UserContext
+{
+public:
+ OpenCL_D3D10(cl_platform_id platform, ID3D10Device* _device) : device(_device)
{
- using namespace cv::ocl;
- cl_platform_id platform = getPlatform();
- if (initializedPlatform10 != platform)
- {
- clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
- clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
- clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
- initializedPlatform10 = platform;
- }
+ clCreateFromD3D10Texture2DKHR = (clCreateFromD3D10Texture2DKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D10Texture2DKHR");
+ clEnqueueAcquireD3D10ObjectsKHR = (clEnqueueAcquireD3D10ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D10ObjectsKHR");
+ clEnqueueReleaseD3D10ObjectsKHR = (clEnqueueReleaseD3D10ObjectsKHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D10ObjectsKHR");
if (!clCreateFromD3D10Texture2DKHR || !clEnqueueAcquireD3D10ObjectsKHR || !clEnqueueReleaseD3D10ObjectsKHR)
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D10");
}
+ device->AddRef();
}
-};
-
-OpenCLDirectXImpl* createDirectXImpl()
-{
- return new OpenCLDirectXImpl();
-}
-void deleteDirectXImpl(OpenCLDirectXImpl** p)
-{
- if (*p)
- {
- delete (*p);
- *p = NULL;
+ ~OpenCL_D3D10() {
+ device->Release();
}
-}
-OpenCLDirectXImpl& getImpl()
-{
- OpenCLDirectXImpl* i = getDirectXImpl(ocl::Context::getDefault());
- CV_Assert(i);
- return *i;
-}
-}
-using namespace internal;
+ ID3D10Device* device;
+ clCreateFromD3D10Texture2DKHR_fn clCreateFromD3D10Texture2DKHR;
+ clEnqueueAcquireD3D10ObjectsKHR_fn clEnqueueAcquireD3D10ObjectsKHR;
+ clEnqueueReleaseD3D10ObjectsKHR_fn clEnqueueReleaseD3D10ObjectsKHR;
+};
#endif
namespace ocl {
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
- size_t exts_len;
- cv::AutoBuffer<char> extensions;
- bool is_support_cl_khr_d3d11_sharing = false;
-#ifdef HAVE_OPENCL_D3D11_NV
- bool is_support_cl_nv_d3d11_sharing = false;
-#endif
for (int i = 0; i < (int)numPlatforms; i++)
{
- status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
- if (status != CL_SUCCESS)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
- extensions.resize(exts_len);
- status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
- if (status != CL_SUCCESS)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
- if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
- is_support_cl_khr_d3d11_sharing = true;
-#ifdef HAVE_OPENCL_D3D11_NV
- if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
- is_support_cl_nv_d3d11_sharing = true;
-#endif
- }
-#ifdef HAVE_OPENCL_D3D11_NV
- if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
-#else
- if (!is_support_cl_khr_d3d11_sharing)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
-#endif
+ cl_platform_id platform = platforms[i];
+ std::string platformName = PlatformInfo(&platform).name();
- int found = -1;
- cl_device_id device = NULL;
- cl_uint numDevices = 0;
- cl_context context = NULL;
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
#ifdef HAVE_OPENCL_D3D11_NV
- if (is_support_cl_nv_d3d11_sharing)
- {
- // try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
- for (int i = 0; i < (int)numPlatforms; i++)
- {
- clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
- if (!clGetDeviceIDsFromD3D11NV)
- continue;
-
- device = NULL;
- numDevices = 0;
- status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
+ // Get extension function "clGetDeviceIDsFromD3D11NV" (part of OpenCL extension "cl_nv_d3d11_sharing")
+ clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
+ if (clGetDeviceIDsFromD3D11NV) {
+ // try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
+ do {
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
CL_PREFERRED_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
- if (status != CL_SUCCESS)
- continue;
- if (numDevices > 0)
- {
- cl_context_properties properties[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
- CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
- //CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
- 0
- };
-
- context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
- {
- clReleaseDevice(device);
- }
- else
- {
- found = i;
break;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
+ //CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ 0
+ };
+
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ }
}
- }
- }
- if (found < 0)
- {
+ } while (0);
// try with CL_ALL_DEVICES_FOR_D3D11_NV
- for (int i = 0; i < (int)numPlatforms; i++)
- {
- clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
- if (!clGetDeviceIDsFromD3D11NV)
- continue;
-
+ if (found < 0) do {
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
- CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
+ CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
else
{
found = i;
- break;
}
}
+ } while (0);
+ if (found >= 0) {
+ OpenCLExecutionContext clExecCtx;
+ try
+ {
+ clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
+ clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D11_NV>(platform, pD3D11Device));
+ }
+ catch (...)
+ {
+ clReleaseDevice(device);
+ clReleaseContext(context);
+ throw;
+ }
+ clExecCtx.bind();
+ return const_cast<Context&>(clExecCtx.getContext());
}
}
- }
#endif
- if (is_support_cl_khr_d3d11_sharing)
- {
- if (found < 0)
+ // Get extension function "clGetDeviceIDsFromD3D11KHR" (part of OpenCL extension "cl_khr_d3d11_sharing")
+ clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
+ if (clGetDeviceIDsFromD3D11KHR)
{
// try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
- for (int i = 0; i < (int)numPlatforms; i++)
- {
- clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
- if (!clGetDeviceIDsFromD3D11KHR)
- continue;
+ do {
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
- CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
+ CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
else
{
found = i;
- break;
}
}
- }
- }
- if (found < 0)
- {
+ } while (0);
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
- for (int i = 0; i < (int)numPlatforms; i++)
- {
- clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
- if (!clGetDeviceIDsFromD3D11KHR)
- continue;
-
+ if (found < 0) do {
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
- CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
+ CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
else
{
found = i;
- break;
}
}
+ } while (0);
+
+ if (found >= 0) {
+ OpenCLExecutionContext clExecCtx;
+ try
+ {
+ clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
+ clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D11>(platform, pD3D11Device));
+ }
+ catch (...)
+ {
+ clReleaseDevice(device);
+ clReleaseContext(context);
+ throw;
+ }
+ clExecCtx.bind();
+ return const_cast<Context&>(clExecCtx.getContext());
}
}
}
- if (found < 0)
- {
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
- }
- cl_platform_id platform = platforms[found];
- std::string platformName = PlatformInfo(&platform).name();
-
- OpenCLExecutionContext clExecCtx;
- try
- {
- clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
- }
- catch (...)
- {
- clReleaseDevice(device);
- clReleaseContext(context);
- throw;
- }
- clExecCtx.bind();
- return const_cast<Context&>(clExecCtx.getContext());
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
#endif
}
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
-
- int found = -1;
- cl_device_id device = NULL;
- cl_uint numDevices = 0;
- cl_context context = NULL;
-
- // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
for (int i = 0; i < (int)numPlatforms; i++)
{
+ cl_platform_id platform = platforms[i];
+ std::string platformName = PlatformInfo(&platform).name();
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
if (!clGetDeviceIDsFromD3D10KHR)
continue;
- device = NULL;
- numDevices = 0;
- status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
+ // try with CL_PREFERRED_DEVICES_FOR_D3D10_KHR
+ do {
+ device = NULL;
+ numDevices = 0;
+ status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
CL_PREFERRED_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
- if (status != CL_SUCCESS)
- continue;
- if (numDevices > 0)
- {
- cl_context_properties properties[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
- CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
- CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
- NULL, NULL
- };
- context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
- {
- clReleaseDevice(device);
- }
- else
- {
- found = i;
break;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_D3D10_DEVICE_KHR, (cl_context_properties)(pD3D10Device),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ }
}
- }
- }
- if (found < 0)
- {
+ } while (0);
// try with CL_ALL_DEVICES_FOR_D3D10_KHR
- for (int i = 0; i < (int)numPlatforms; i++)
+ if (found < 0) do
{
- clGetDeviceIDsFromD3D10KHR_fn clGetDeviceIDsFromD3D10KHR = (clGetDeviceIDsFromD3D10KHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D10KHR");
- if (!clGetDeviceIDsFromD3D10KHR)
- continue;
-
device = NULL;
numDevices = 0;
status = clGetDeviceIDsFromD3D10KHR(platforms[i], CL_D3D10_DEVICE_KHR, pD3D10Device,
- CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
+ CL_ALL_DEVICES_FOR_D3D10_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
else
{
found = i;
- break;
}
}
- }
- if (found < 0)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
- }
-
- cl_platform_id platform = platforms[found];
- std::string platformName = PlatformInfo(&platform).name();
+ } while (0);
- OpenCLExecutionContext clExecCtx;
- try
- {
- clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
- }
- catch (...)
- {
- clReleaseDevice(device);
- clReleaseContext(context);
- throw;
+ if (found >= 0) {
+ OpenCLExecutionContext clExecCtx;
+ try
+ {
+ clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
+ clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D10>(platform, pD3D10Device));
+ }
+ catch (...)
+ {
+ clReleaseDevice(device);
+ clReleaseContext(context);
+ throw;
+ }
+ clExecCtx.bind();
+ return const_cast<Context&>(clExecCtx.getContext());
+ }
}
- clExecCtx.bind();
- return const_cast<Context&>(clExecCtx.getContext());
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
#endif
}
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
-
- int found = -1;
- cl_device_id device = NULL;
- cl_uint numDevices = 0;
- cl_context context = NULL;
-
- // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
for (int i = 0; i < (int)numPlatforms; i++)
{
+ cl_platform_id platform = platforms[i];
+ std::string platformName = PlatformInfo(&platform).name();
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
continue;
- device = NULL;
- numDevices = 0;
- cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
- status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
+ // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ do {
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
- if (status != CL_SUCCESS)
- continue;
- if (numDevices > 0)
- {
- cl_context_properties properties[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
- CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
- CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
- NULL, NULL
- };
- context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
- {
- clReleaseDevice(device);
- }
- else
- {
- found = i;
break;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9EX_KHR, (cl_context_properties)(pDirect3DDevice9Ex),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ }
}
- }
- }
- if (found < 0)
- {
+ } while (0);
// try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
- for (int i = 0; i < (int)numPlatforms; i++)
+ if (found < 0) do
{
- clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
- if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
- continue;
-
device = NULL;
numDevices = 0;
cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9EX_KHR;
status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9Ex,
- CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
else
{
found = i;
- break;
}
}
- }
- if (found < 0)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
- }
+ } while (0);
- cl_platform_id platform = platforms[found];
- std::string platformName = PlatformInfo(&platform).name();
-
- OpenCLExecutionContext clExecCtx;
- try
- {
- clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
- }
- catch (...)
- {
- clReleaseDevice(device);
- clReleaseContext(context);
- throw;
+ if (found >= 0) {
+ OpenCLExecutionContext clExecCtx;
+ try
+ {
+ clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
+ clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D9>(platform, nullptr, pDirect3DDevice9Ex));
+ }
+ catch (...)
+ {
+ clReleaseDevice(device);
+ clReleaseContext(context);
+ throw;
+ }
+ clExecCtx.bind();
+ return const_cast<Context&>(clExecCtx.getContext());
+ }
}
- clExecCtx.bind();
- getImpl().isDirect3DDevice9Ex = true;
- return const_cast<Context&>(clExecCtx.getContext());
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
#endif
}
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platforms");
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
-
- int found = -1;
- cl_device_id device = NULL;
- cl_uint numDevices = 0;
- cl_context context = NULL;
-
- // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
for (int i = 0; i < (int)numPlatforms; i++)
{
+ cl_platform_id platform = platforms[i];
+ std::string platformName = PlatformInfo(&platform).name();
+ int found = -1;
+ cl_device_id device = NULL;
+ cl_uint numDevices = 0;
+ cl_context context = NULL;
+
clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
+ clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
continue;
- device = NULL;
- numDevices = 0;
- cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
- status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
+ // try with CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
+ do {
+ device = NULL;
+ numDevices = 0;
+ cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
+ status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
- if (status != CL_SUCCESS)
- continue;
- if (numDevices > 0)
- {
- cl_context_properties properties[] = {
- CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
- CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
- CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
- NULL, NULL
- };
- context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
if (status != CL_SUCCESS)
- {
- clReleaseDevice(device);
- }
- else
- {
- found = i;
break;
+ if (numDevices > 0)
+ {
+ cl_context_properties properties[] = {
+ CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
+ CL_CONTEXT_ADAPTER_D3D9_KHR, (cl_context_properties)(pDirect3DDevice9),
+ CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
+ NULL, NULL
+ };
+ context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
+ if (status != CL_SUCCESS)
+ {
+ clReleaseDevice(device);
+ }
+ else
+ {
+ found = i;
+ break;
+ }
}
- }
- }
- if (found < 0)
- {
+ } while (0);
// try with CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR
- for (int i = 0; i < (int)numPlatforms; i++)
+ if (found < 0) do
{
- clGetDeviceIDsFromDX9MediaAdapterKHR_fn clGetDeviceIDsFromDX9MediaAdapterKHR = (clGetDeviceIDsFromDX9MediaAdapterKHR_fn)
- clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromDX9MediaAdapterKHR");
- if (!clGetDeviceIDsFromDX9MediaAdapterKHR)
- continue;
-
device = NULL;
numDevices = 0;
cl_dx9_media_adapter_type_khr type = CL_ADAPTER_D3D9_KHR;
status = clGetDeviceIDsFromDX9MediaAdapterKHR(platforms[i], 1, &type, &pDirect3DDevice9,
- CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
+ CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR, 1, &device, &numDevices);
if (status != CL_SUCCESS)
- continue;
+ break;
if (numDevices > 0)
{
cl_context_properties properties[] = {
break;
}
}
- }
- if (found < 0)
- CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
- }
+ } while (0);
- cl_platform_id platform = platforms[found];
- std::string platformName = PlatformInfo(&platform).name();
-
- OpenCLExecutionContext clExecCtx;
- try
- {
- clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
- }
- catch (...)
- {
- clReleaseDevice(device);
- clReleaseContext(context);
- throw;
+ if (found >= 0) {
+ OpenCLExecutionContext clExecCtx;
+ try
+ {
+ clExecCtx = OpenCLExecutionContext::create(platformName, platform, context, device);
+ clExecCtx.getContext().setUserContext(std::make_shared<OpenCL_D3D9>(platform, pDirect3DDevice9, nullptr));
+ }
+ catch (...)
+ {
+ clReleaseDevice(device);
+ clReleaseContext(context);
+ throw;
+ }
+ clExecCtx.bind();
+ return const_cast<Context&>(clExecCtx.getContext());
+ }
}
- clExecCtx.bind();
- getImpl().isDirect3DDevice9Ex = false;
- return const_cast<Context&>(clExecCtx.getContext());
+ CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
#endif
}
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
cl_context context = (cl_context)ctx.ptr();
- OpenCLDirectXImpl& impl = getImpl();
+ OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
cl_int status = 0;
cl_mem clImage = 0;
#ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0;
#endif
- clImage = impl.clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
+ clImage = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
- clImageUV = impl.clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
+ clImageUV = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
}
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
- status = impl.clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
- status = impl.clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
}
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
}
- status = impl.clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
cl_context context = (cl_context)ctx.ptr();
- OpenCLDirectXImpl& impl = getImpl();
+ OpenCL_D3D11_NV* impl = ctx.getUserContext<OpenCL_D3D11_NV>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
cl_int status = 0;
cl_mem clImage = 0;
#ifdef HAVE_DIRECTX_NV12
cl_mem clImageUV = 0;
#endif
- clImage = impl.clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
+ clImage = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
#ifdef HAVE_DIRECTX_NV12
if (DXGI_FORMAT_NV12 == desc.Format)
{
- clImageUV = impl.clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
+ clImageUV = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
}
#endif
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
- status = impl.clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
- status = impl.clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
}
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
}
- status = impl.clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
cl_context context = (cl_context)ctx.ptr();
- OpenCLDirectXImpl& impl = getImpl();
+ OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
cl_int status = 0;
cl_mem clImage = 0;
- clImage = impl.clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
+ clImage = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
cl_mem clImageUV = 0;
if(DXGI_FORMAT_NV12 == desc.Format)
{
- clImageUV = impl.clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
+ clImageUV = impl->clCreateFromD3D11Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
}
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
#ifdef HAVE_DIRECTX_NV12
if(DXGI_FORMAT_NV12 == desc.Format)
{
- status = impl.clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsKHR failed");
if(!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
- status = impl.clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
}
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
}
- status = impl.clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
cl_context context = (cl_context)ctx.ptr();
- OpenCLDirectXImpl& impl = getImpl();
+ OpenCL_D3D11_NV* impl = ctx.getUserContext<OpenCL_D3D11_NV>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
cl_int status = 0;
cl_mem clImage = 0;
- clImage = impl.clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
+ clImage = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
cl_mem clImageUV = 0;
if(DXGI_FORMAT_NV12 == desc.Format)
{
- clImageUV = impl.clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
+ clImageUV = impl->clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
}
#endif
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
#ifdef HAVE_DIRECTX_NV12
if (DXGI_FORMAT::DXGI_FORMAT_NV12 == desc.Format)
{
- status = impl.clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
if (!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
- status = impl.clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
}
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
}
- status = impl.clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
NO_OPENCL_SUPPORT_ERROR;
#else
- bool useCLNVEXT = getImpl().initializeD3D11();
- if(!useCLNVEXT){
- __convertToD3D11Texture2DKHR(src,pD3D11Texture2D);
- }
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
#ifdef HAVE_OPENCL_D3D11_NV
- else
- {
+ OpenCL_D3D11_NV* impl_nv = ctx.getUserContext<OpenCL_D3D11_NV>().get();
+ if (impl_nv) {
__convertToD3D11Texture2DNV(src,pD3D11Texture2D);
+ return;
}
#endif
+ OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
+ if (impl) {
+ __convertToD3D11Texture2DKHR(src, pD3D11Texture2D);
+ }
+ else {
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
+ }
#endif
}
NO_OPENCL_SUPPORT_ERROR;
#else
- bool useCLNVEXT = getImpl().initializeD3D11();
- if(!useCLNVEXT){
- __convertFromD3D11Texture2DKHR(pD3D11Texture2D,dst);
- }
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
#ifdef HAVE_OPENCL_D3D11_NV
- else
- {
+ OpenCL_D3D11_NV* impl_nv = ctx.getUserContext<OpenCL_D3D11_NV>().get();
+ if (impl_nv) {
__convertFromD3D11Texture2DNV(pD3D11Texture2D,dst);
}
#endif
+ OpenCL_D3D11* impl = ctx.getUserContext<OpenCL_D3D11>().get();
+ if (impl) {
+ __convertFromD3D11Texture2DKHR(pD3D11Texture2D, dst);
+ }
+ else {
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
+ }
#endif
}
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
- OpenCLDirectXImpl& impl = getImpl();
- impl.initializeD3D10();
+
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
+ OpenCL_D3D10* impl = ctx.getUserContext<OpenCL_D3D10>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
D3D10_TEXTURE2D_DESC desc = { 0 };
pD3D10Texture2D->GetDesc(&desc);
Size srcSize = src.size();
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
UMat u = src.getUMat();
CV_Assert(u.isContinuous());
cl_int status = 0;
- cl_mem clImage = impl.clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
+ cl_mem clImage = impl->clCreateFromD3D10Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D10Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
size_t offset = 0; // TODO
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
- status = impl.clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
NO_OPENCL_SUPPORT_ERROR;
#endif
}
+
void convertFromD3D10Texture2D(ID3D10Texture2D* pD3D10Texture2D, OutputArray dst)
{
CV_UNUSED(pD3D10Texture2D); CV_UNUSED(dst);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
- OpenCLDirectXImpl& impl = getImpl();
- impl.initializeD3D10();
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
+ OpenCL_D3D10* impl = ctx.getUserContext<OpenCL_D3D10>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
D3D10_TEXTURE2D_DESC desc = { 0 };
pD3D10Texture2D->GetDesc(&desc);
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
CV_Assert(textureType >= 0);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
CV_Assert(u.isContinuous());
cl_int status = 0;
- cl_mem clImage = impl.clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
+ cl_mem clImage = impl->clCreateFromD3D10Texture2DKHR(context, CL_MEM_READ_ONLY, pD3D10Texture2D, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D10Texture2DKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D10ObjectsKHR failed");
size_t offset = 0; // TODO
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
- status = impl.clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseD3D10ObjectsKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D10ObjectsKHR failed");
#endif
}
-
void convertToDirect3DSurface9(InputArray src, IDirect3DSurface9* pDirect3DSurface9, void* surfaceSharedHandle)
{
CV_UNUSED(src); CV_UNUSED(pDirect3DSurface9); CV_UNUSED(surfaceSharedHandle);
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
- OpenCLDirectXImpl& impl = getImpl();
- impl.initializeD3D9();
+
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
+ OpenCL_D3D9* impl = ctx.getUserContext<OpenCL_D3D9>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
D3DSURFACE_DESC desc;
if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
Size srcSize = src.size();
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
UMat u = src.getUMat();
cl_int status = 0;
cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
- cl_mem clImage = impl.clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
- impl.isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
+ cl_mem clImage = impl->clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_WRITE_ONLY,
+ impl->deviceEx ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
&surfaceInfo, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
size_t offset = 0; // TODO
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, dst_origin, region, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
- status = impl.clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
#if !defined(HAVE_DIRECTX)
NO_DIRECTX_SUPPORT_ERROR;
#elif defined(HAVE_OPENCL)
- OpenCLDirectXImpl& impl = getImpl();
- impl.initializeD3D9();
+
+ ocl::Context& ctx = ocl::OpenCLExecutionContext::getCurrent().getContext();
+ OpenCL_D3D9* impl = ctx.getUserContext<OpenCL_D3D9>().get();
+ if (nullptr == impl)
+ CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: Context initilized without DirectX interoperability");
D3DSURFACE_DESC desc;
if (FAILED(pDirect3DSurface9->GetDesc(&desc)))
int surfaceType = getTypeFromD3DFORMAT(desc.Format);
CV_Assert(surfaceType >= 0);
- using namespace cv::ocl;
- Context& ctx = Context::getDefault();
cl_context context = (cl_context)ctx.ptr();
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
cl_int status = 0;
cl_dx9_surface_info_khr surfaceInfo = {pDirect3DSurface9, (HANDLE)surfaceSharedHandle};
- cl_mem clImage = impl.clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
- impl.isDirect3DDevice9Ex ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
+ cl_mem clImage = impl->clCreateFromDX9MediaSurfaceKHR(context, CL_MEM_READ_ONLY,
+ impl->deviceEx ? CL_ADAPTER_D3D9EX_KHR : CL_ADAPTER_D3D9_KHR,
&surfaceInfo, 0, &status);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromDX9MediaSurfaceKHR failed");
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE);
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
- status = impl.clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueAcquireDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireDX9MediaSurfacesKHR failed");
size_t offset = 0; // TODO
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, src_origin, region, offset, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
- status = impl.clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
+ status = impl->clEnqueueReleaseDX9MediaSurfacesKHR(q, 1, &clImage, 0, NULL, NULL);
if (status != CL_SUCCESS)
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseDX9MediaSurfacesKHR failed");
// Copyright (C) 2020-2021 Intel Corporation
#include "opencv2/videoio.hpp"
-#if defined(__OPENCV_BUILD) || defined(OPENCV_HAVE_CVCONFIG_H) // TODO Properly detect and add D3D11 / LIBVA dependencies for standalone plugins
+#ifdef HAVE_OPENCL
+#include "opencv2/core/ocl.hpp"
+#endif
+#if defined(__OPENCV_BUILD) && !defined(BUILD_PLUGIN) // TODO Properly detect and add D3D11 / LIBVA dependencies for standalone plugins
#include "cvconfig.h"
#endif
#include <sstream>
#define D3D11_NO_HELPERS
#include <d3d11.h>
#include <codecvt>
+#include "opencv2/core/directx.hpp"
+#ifdef HAVE_OPENCL
+#include <CL/cl_d3d11.h>
#endif
+#endif // HAVE_D3D11
#ifdef HAVE_VA
#include <va/va_backend.h>
+#ifdef HAVE_VA_INTEL
+#include "opencv2/core/va_intel.hpp"
+#ifndef CL_TARGET_OPENCL_VERSION
+#define CL_TARGET_OPENCL_VERSION 120
+#endif
+#ifdef HAVE_VA_INTEL_OLD_HEADER
+#include <CL/va_ext.h>
+#else
+#include <CL/cl_va_api_media_sharing_intel.h>
+#endif
#endif
+#endif // HAVE_VA
+// FFMPEG "C" headers
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
-
#include <libavutil/hwcontext.h>
#ifdef HAVE_D3D11
#include <libavutil/hwcontext_d3d11va.h>
#ifdef HAVE_VA
#include <libavutil/hwcontext_vaapi.h>
#endif
+#ifdef HAVE_MFX // dependency only on MFX header files, no linkage dependency
+#include <libavutil/hwcontext_qsv.h>
+#endif
}
+#define HW_DEFAULT_POOL_SIZE 32
+#define HW_DEFAULT_SW_FORMAT AV_PIX_FMT_NV12
+
+using namespace cv;
+
+static AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_category)(const AVCodec *),
+ const char *disabled_codecs, AVPixelFormat *hw_pix_fmt);
+static AVBufferRef* hw_create_device(AVHWDeviceType hw_type, int hw_device, const std::string& device_subname, bool use_opencl);
+static AVBufferRef* hw_create_frames(struct AVCodecContext* ctx, AVBufferRef *hw_device_ctx, int width, int height, AVPixelFormat hw_format);
+static AVPixelFormat hw_get_format_callback(struct AVCodecContext *ctx, const enum AVPixelFormat * fmt);
+static VideoAccelerationType hw_type_to_va_type(AVHWDeviceType hw_type);
+
static
const char* getVideoAccelerationName(VideoAccelerationType va_type)
{
case VIDEO_ACCELERATION_ANY: return "d3d11va";
case VIDEO_ACCELERATION_D3D11: return "d3d11va";
case VIDEO_ACCELERATION_VAAPI: return "";
- case VIDEO_ACCELERATION_MFX: return "";
+ case VIDEO_ACCELERATION_MFX: return ""; // "qsv" fails if non-Intel D3D11 device
}
return "";
#else
case VIDEO_ACCELERATION_ANY: return "vaapi.iHD";
case VIDEO_ACCELERATION_D3D11: return "";
case VIDEO_ACCELERATION_VAAPI: return "vaapi.iHD";
- case VIDEO_ACCELERATION_MFX: return "";
+ case VIDEO_ACCELERATION_MFX: return "qsv.iHD";
}
return "";
#endif
#endif
}
-
static
std::string getDecoderDisabledCodecs(AVDictionary *dict)
{
#endif
}
-
-#define HW_DEFAULT_POOL_SIZE 32
-#define HW_DEFAULT_SW_FORMAT AV_PIX_FMT_NV12
-
-using namespace cv;
-
-static AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_category)(const AVCodec *),
- const char *disabled_codecs, AVPixelFormat *hw_pix_fmt);
-static AVBufferRef* hw_create_device(AVHWDeviceType hw_type, int hw_device, const std::string& device_subname);
-static AVBufferRef* hw_create_frames(struct AVCodecContext* ctx, AVBufferRef *hw_device_ctx, int width, int height, AVPixelFormat hw_format);
-static AVPixelFormat hw_get_format_callback(struct AVCodecContext *ctx, const enum AVPixelFormat * fmt);
-static VideoAccelerationType hw_type_to_va_type(AVHWDeviceType hw_type);
-
static
bool hw_check_device(AVBufferRef* ctx, AVHWDeviceType hw_type, const std::string& device_subname) {
if (!ctx)
}
static
-AVBufferRef* hw_create_device(AVHWDeviceType hw_type, int hw_device, const std::string& device_subname) {
- if (AV_HWDEVICE_TYPE_NONE == hw_type)
+AVBufferRef* hw_create_derived_context(AVHWDeviceType hw_type, AVBufferRef* hw_device_ctx) {
+ AVBufferRef* derived_ctx = NULL;
+ const char* hw_name = av_hwdevice_get_type_name(hw_type);
+ int err = av_hwdevice_ctx_create_derived(&derived_ctx, hw_type, hw_device_ctx, 0);
+ if (!derived_ctx || err < 0)
+ {
+ if (derived_ctx)
+ av_buffer_unref(&derived_ctx);
+ CV_LOG_INFO(NULL, "FFMPEG: Failed to create derived video acceleration (av_hwdevice_ctx_create_derived) for " << hw_name << ". Error=" << err);
return NULL;
+ }
+ else
+ {
+ // Store child context in 'user_opaque' field of parent context.
+ struct FreeChildContext {
+ static void free(struct AVHWDeviceContext* ctx) {
+ AVBufferRef* child_ctx = (AVBufferRef*)ctx->user_opaque;
+ if (child_ctx)
+ av_buffer_unref(&child_ctx);
+ }
+ };
+ AVHWDeviceContext* ctx = (AVHWDeviceContext*)derived_ctx->data;
+ ctx->user_opaque = av_buffer_ref(hw_device_ctx);
+ ctx->free = FreeChildContext::free;
+ CV_LOG_INFO(NULL, "FFMPEG: Created derived video acceleration context (av_hwdevice_ctx_create_derived) for " << hw_name);
+ return derived_ctx;
+ }
+}
- AVHWDeviceType child_type = hw_type;
- if (hw_type == AV_HWDEVICE_TYPE_QSV) {
-#ifdef _WIN32
- child_type = AV_HWDEVICE_TYPE_DXVA2;
-#else
- child_type = AV_HWDEVICE_TYPE_VAAPI;
+#ifdef HAVE_OPENCL // GPU buffer interop with cv::UMat
+
+// FFmpeg context attached to OpenCL context
+class OpenCL_FFMPEG_Context : public ocl::Context::UserContext {
+public:
+ OpenCL_FFMPEG_Context(AVBufferRef* ctx) {
+ ctx_ = av_buffer_ref(ctx);
+ }
+ virtual ~OpenCL_FFMPEG_Context() {
+ av_buffer_unref(&ctx_);
+ }
+ AVBufferRef* GetAVHWDevice() {
+ return ctx_;
+ }
+private:
+ AVBufferRef* ctx_;
+};
+
+#ifdef HAVE_MFX
+static
+int hw_find_qsv_surface_index(AVFrame* hw_frame)
+{
+ if (AV_PIX_FMT_QSV != hw_frame->format)
+ return -1;
+ mfxFrameSurface1* surface = (mfxFrameSurface1*)hw_frame->data[3]; // As defined by AV_PIX_FMT_QSV
+ AVHWFramesContext* frames_ctx = (AVHWFramesContext*)hw_frame->hw_frames_ctx->data;
+ AVQSVFramesContext* qsv_ctx = (AVQSVFramesContext*)frames_ctx->hwctx;
+ for (int i = 0; i < qsv_ctx->nb_surfaces; i++) {
+ if (surface == qsv_ctx->surfaces + i) {
+ return i;
+ }
+ }
+ return -1;
+}
+#endif
+
+#ifdef HAVE_VA
+static
+VADisplay hw_get_va_display(AVHWDeviceContext* hw_device_ctx)
+{
+ if (hw_device_ctx->type == AV_HWDEVICE_TYPE_QSV) { // we stored pointer to child context in 'user_opaque' field
+ AVBufferRef* ctx = (AVBufferRef*)hw_device_ctx->user_opaque;
+ hw_device_ctx = (AVHWDeviceContext*)ctx->data;
+ }
+ if (hw_device_ctx && hw_device_ctx->type == AV_HWDEVICE_TYPE_VAAPI) {
+ return ((AVVAAPIDeviceContext*)hw_device_ctx->hwctx)->display;
+ }
+ return NULL;
+}
+#endif // HAVE_VA
+
+#ifdef HAVE_VA_INTEL
+static
+VASurfaceID hw_get_va_surface(AVFrame* hw_frame) {
+ if (AV_PIX_FMT_VAAPI == hw_frame->format) {
+ return (VASurfaceID)(size_t)hw_frame->data[3]; // As defined by AV_PIX_FMT_VAAPI
+ }
+#ifdef HAVE_MFX
+ else if (AV_PIX_FMT_QSV == hw_frame->format) {
+ int frame_idx = hw_find_qsv_surface_index(hw_frame);
+ if (frame_idx >= 0) { // frame index is same in parent (QSV) and child (VAAPI) frame context
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext *) hw_frame->hw_frames_ctx->data;
+ AVHWFramesContext *child_ctx = (AVHWFramesContext *) frames_ctx->user_opaque;
+ if (child_ctx && AV_HWDEVICE_TYPE_VAAPI == child_ctx->device_ctx->type) {
+ AVVAAPIFramesContext *vaapi_ctx = (AVVAAPIFramesContext *) child_ctx->hwctx;
+ CV_Assert(frame_idx < vaapi_ctx->nb_surfaces);
+ return vaapi_ctx->surface_ids[frame_idx];
+ }
+ }
+ }
+#endif // HAVE_MFX
+ return VA_INVALID_SURFACE;
+}
+#endif // HAVE_VA_INTEL
+
+#ifdef HAVE_D3D11
+static
+AVD3D11VADeviceContext* hw_get_d3d11_device_ctx(AVHWDeviceContext* hw_device_ctx) {
+ if (AV_HWDEVICE_TYPE_QSV == hw_device_ctx->type) { // we stored pointer to child context in 'user_opaque' field
+ AVBufferRef* ctx = (AVBufferRef*)hw_device_ctx->user_opaque;
+ hw_device_ctx = (AVHWDeviceContext*)ctx->data;
+ }
+ if (AV_HWDEVICE_TYPE_D3D11VA == hw_device_ctx->type) {
+ return (AVD3D11VADeviceContext*)hw_device_ctx->hwctx;
+ }
+ return NULL;
+}
+
+ID3D11Texture2D* hw_get_d3d11_texture(AVFrame* hw_frame, int* subresource) {
+ ID3D11Texture2D* texture = NULL;
+ if (AV_PIX_FMT_D3D11 == hw_frame->format) {
+ texture = (ID3D11Texture2D*)hw_frame->data[0]; // As defined by AV_PIX_FMT_D3D11
+ *subresource = (intptr_t)hw_frame->data[1]; // As defined by AV_PIX_FMT_D3D11
+ }
+#ifdef HAVE_MFX
+ else if (AV_PIX_FMT_QSV == hw_frame->format) {
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext *) hw_frame->hw_frames_ctx->data;
+ AVHWFramesContext *child_ctx = (AVHWFramesContext *) frames_ctx->user_opaque;
+ if (child_ctx && AV_HWDEVICE_TYPE_D3D11VA == child_ctx->device_ctx->type) {
+ texture = ((AVD3D11VAFramesContext*)child_ctx->hwctx)->texture;
+ }
+ *subresource = hw_find_qsv_surface_index(hw_frame);
+ CV_Assert(*subresource >= 0);
+ }
+#endif
+ return texture;
+}
+
+// In D3D11 case we allocate additional texture as single texture (not texture array) because
+// OpenCL interop with D3D11 doesn't support/work with NV12 sub-texture of texture array.
+ID3D11Texture2D* hw_get_d3d11_single_texture(AVFrame* hw_frame, AVD3D11VADeviceContext* d3d11_device_ctx, ID3D11Texture2D* texture) {
+ AVHWFramesContext* frames_ctx = (AVHWFramesContext*)hw_frame->hw_frames_ctx->data;
+ if (AV_HWDEVICE_TYPE_QSV == frames_ctx->device_ctx->type) {
+ frames_ctx = (AVHWFramesContext*)frames_ctx->user_opaque; // we stored pointer to child context in 'user_opaque' field
+ }
+ if (!frames_ctx || AV_HWDEVICE_TYPE_D3D11VA != frames_ctx->device_ctx->type) {
+ return NULL;
+ }
+ ID3D11Texture2D* singleTexture = (ID3D11Texture2D*)frames_ctx->user_opaque;
+ if (!singleTexture && d3d11_device_ctx && texture) {
+ D3D11_TEXTURE2D_DESC desc = {};
+ texture->GetDesc(&desc);
+ desc.ArraySize = 1;
+ desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+ desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED;
+ if (SUCCEEDED(d3d11_device_ctx->device->CreateTexture2D(&desc, NULL, &singleTexture))) {
+ frames_ctx->user_opaque = singleTexture;
+ }
+ }
+ return singleTexture;
+}
+#endif // HAVE_D3D11
+
+static
+AVHWDeviceType hw_check_opencl_context(AVHWDeviceContext* ctx) {
+ ocl::OpenCLExecutionContext& ocl_context = ocl::OpenCLExecutionContext::getCurrentRef();
+ if (!ctx || ocl_context.empty())
+ return AV_HWDEVICE_TYPE_NONE;
+#ifdef HAVE_VA_INTEL
+ VADisplay vadisplay_ocl = ocl_context.getContext().getOpenCLContextProperty(CL_CONTEXT_VA_API_DISPLAY_INTEL);
+ VADisplay vadisplay_ctx = hw_get_va_display(ctx);
+ if (vadisplay_ocl && vadisplay_ocl == vadisplay_ctx)
+ return AV_HWDEVICE_TYPE_VAAPI;
+#endif
+#ifdef HAVE_D3D11
+ ID3D11Device* d3d11device_ocl = (ID3D11Device*)ocl_context.getContext().getOpenCLContextProperty(CL_CONTEXT_D3D11_DEVICE_KHR);
+ AVD3D11VADeviceContext* d3d11_device_ctx = hw_get_d3d11_device_ctx(ctx);
+ if (d3d11_device_ctx && d3d11device_ocl && d3d11_device_ctx->device == d3d11device_ocl)
+ return AV_HWDEVICE_TYPE_D3D11VA;
#endif
+ return AV_HWDEVICE_TYPE_NONE;
+}
+
+static
+void hw_init_opencl(AVBufferRef* ctx) {
+ if (!ctx)
+ return;
+ AVHWDeviceContext* hw_device_ctx = (AVHWDeviceContext*)ctx->data;
+ if (!hw_device_ctx)
+ return;
+#ifdef HAVE_VA_INTEL
+ VADisplay va_display = hw_get_va_display(hw_device_ctx);
+ if (va_display) {
+ va_intel::ocl::initializeContextFromVA(va_display);
+ }
+#endif
+#ifdef HAVE_D3D11
+ AVD3D11VADeviceContext* d3d11_device_ctx = hw_get_d3d11_device_ctx(hw_device_ctx);
+ if (d3d11_device_ctx) {
+ directx::ocl::initializeContextFromD3D11Device(d3d11_device_ctx->device);
+ }
+#endif
+ if (hw_check_opencl_context(hw_device_ctx) != AV_HWDEVICE_TYPE_NONE) {
+ // Attach AVHWDeviceContext to OpenCL context
+ ocl::Context &ocl_context = ocl::OpenCLExecutionContext::getCurrent().getContext();
+ ocl_context.setUserContext(std::make_shared<OpenCL_FFMPEG_Context>(ctx));
+ }
+}
+
+static
+AVBufferRef* hw_create_context_from_opencl(ocl::OpenCLExecutionContext& ocl_context, AVHWDeviceType hw_type) {
+ if (ocl_context.empty())
+ return NULL;
+ auto ocl_ffmpeg_context = ocl_context.getContext().getUserContext<OpenCL_FFMPEG_Context>();
+ if (!ocl_ffmpeg_context)
+ return NULL;
+ AVBufferRef* ctx = ocl_ffmpeg_context->GetAVHWDevice();
+ if (hw_type != ((AVHWDeviceContext*)ctx->data)->type) {
+ ctx = hw_create_derived_context(hw_type, ctx);
+ }
+ else {
+ ctx = av_buffer_ref(ctx);
}
+ if (ctx)
+ CV_LOG_INFO(NULL, "FFMPEG: Using " << av_hwdevice_get_type_name(hw_type) << " video acceleration context attached to OpenCL context");
+ return ctx;
+}
+
+#endif // HAVE_OPENCL
+static
+AVBufferRef* hw_create_device(AVHWDeviceType hw_type, int hw_device, const std::string& device_subname, bool use_opencl) {
AVBufferRef* hw_device_ctx = NULL;
- char device[128] = "";
- char* pdevice = NULL;
- if (hw_device >= 0 && hw_device < 100000) {
- if (child_type == AV_HWDEVICE_TYPE_VAAPI) {
- snprintf(device, sizeof(device), "/dev/dri/renderD%d", 128 + hw_device);
- } else {
- snprintf(device, sizeof(device), "%d", hw_device);
+ if (AV_HWDEVICE_TYPE_NONE == hw_type)
+ return NULL;
+
+#ifdef HAVE_OPENCL
+ // Check if OpenCL context has AVHWDeviceContext attached to it
+ ocl::OpenCLExecutionContext& ocl_context = ocl::OpenCLExecutionContext::getCurrentRef();
+ try {
+ hw_device_ctx = hw_create_context_from_opencl(ocl_context, hw_type);
+ if (hw_device_ctx) {
+ if (hw_device >= 0)
+ CV_LOG_ERROR(NULL, "VIDEOIO/FFMPEG: ignoring property HW_DEVICE as device context already created and attached to OpenCL context");
+ return hw_device_ctx;
}
- pdevice = device;
}
- const char *hw_child_name = av_hwdevice_get_type_name(child_type);
- const char *device_name = pdevice ? pdevice : "'default'";
- int err = av_hwdevice_ctx_create(&hw_device_ctx, child_type, pdevice, NULL, 0);
- if (hw_device_ctx && err >= 0)
- {
- CV_LOG_DEBUG(NULL, "FFMPEG: Created video acceleration context (av_hwdevice_ctx_create) for " << hw_child_name << " on device " << device_name);
- if (!hw_check_device(hw_device_ctx, hw_type, device_subname)) {
- av_buffer_unref(&hw_device_ctx);
- return NULL;
+ catch (...) {
+ CV_LOG_INFO(NULL, "FFMPEG: Exception creating Video Acceleration context using current OpenCL context");
+ }
+#endif
+
+ // Create new media context. In QSV case, first create 'child' context.
+ std::vector<AVHWDeviceType> child_types = { hw_type };
+ if (hw_type == AV_HWDEVICE_TYPE_QSV) {
+#ifdef _WIN32
+ child_types = { AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2 };
+#else
+ child_types = { AV_HWDEVICE_TYPE_VAAPI };
+#endif
+ }
+ for (AVHWDeviceType child_type : child_types) {
+ char device[128] = "";
+ char* pdevice = NULL;
+ if (hw_device >= 0 && hw_device < 100000) {
+ if (child_type == AV_HWDEVICE_TYPE_VAAPI) {
+ snprintf(device, sizeof(device), "/dev/dri/renderD%d", 128 + hw_device);
+ }
+ else {
+ snprintf(device, sizeof(device), "%d", hw_device);
+ }
+ pdevice = device;
}
- if (hw_type != child_type) {
- AVBufferRef *derived_ctx = NULL;
- const char *hw_name = av_hwdevice_get_type_name(hw_type);
- err = av_hwdevice_ctx_create_derived(&derived_ctx, hw_type, hw_device_ctx, 0);
- if (!derived_ctx || err < 0)
- {
- if (derived_ctx)
- av_buffer_unref(&derived_ctx);
- CV_LOG_INFO(NULL, "FFMPEG: Failed to create derived video acceleration (av_hwdevice_ctx_create_derived) for " << hw_name << ". Error=" << err);
+ const char* hw_child_name = av_hwdevice_get_type_name(child_type);
+ const char* device_name = pdevice ? pdevice : "'default'";
+ int err = av_hwdevice_ctx_create(&hw_device_ctx, child_type, pdevice, NULL, 0);
+ if (hw_device_ctx && err >= 0)
+ {
+ if (!hw_check_device(hw_device_ctx, hw_type, device_subname)) {
+ av_buffer_unref(&hw_device_ctx);
+ continue;
}
- else
- {
- CV_LOG_DEBUG(NULL, "FFMPEG: Created derived video acceleration context (av_hwdevice_ctx_create_derived) for " << hw_name);
+ CV_LOG_INFO(NULL, "FFMPEG: Created video acceleration context (av_hwdevice_ctx_create) for " << hw_child_name << " on device " << device_name);
+#ifdef HAVE_OPENCL
+ // if OpenCL context not created yet or property HW_ACCELERATION_USE_OPENCL set, create OpenCL context with binding to video acceleration context
+ if (ocl::haveOpenCL()) {
+ if (ocl_context.empty() || use_opencl) {
+ try {
+ hw_init_opencl(hw_device_ctx);
+ ocl_context = ocl::OpenCLExecutionContext::getCurrentRef();
+ if (!ocl_context.empty()) {
+ CV_LOG_INFO(NULL, "FFMPEG: Created OpenCL context with " << hw_child_name <<
+ " video acceleration on OpenCL device: " << ocl_context.getDevice().name());
+ }
+ } catch (...) {
+ CV_LOG_INFO(NULL, "FFMPEG: Exception creating OpenCL context with " << hw_child_name << " video acceleration");
+ }
+ }
+ else {
+ CV_LOG_INFO(NULL, "FFMPEG: Can't bind " << hw_child_name << " video acceleration context to already created OpenCL context");
+ }
+ }
+#else
+ CV_UNUSED(use_opencl);
+#endif
+ if (hw_type != child_type) {
+ AVBufferRef* derived_ctx = hw_create_derived_context(hw_type, hw_device_ctx);
+ av_buffer_unref(&hw_device_ctx);
+ return derived_ctx;
+ } else {
+ return hw_device_ctx;
}
- av_buffer_unref(&hw_device_ctx);
- return derived_ctx;
- } else {
- return hw_device_ctx;
+ }
+ else
+ {
+ const char* hw_name = hw_child_name;
+ CV_LOG_INFO(NULL, "FFMPEG: Failed to create " << hw_name << " video acceleration (av_hwdevice_ctx_create) on device " << device_name);
}
}
- else
- {
- const char *hw_name = hw_child_name;
- CV_LOG_INFO(NULL, "FFMPEG: Failed to create " << hw_name << " video acceleration (av_hwdevice_ctx_create) on device " << device_name);
- return NULL;
- }
+ return NULL;
}
static
-AVBufferRef* hw_create_frames(struct AVCodecContext* ctx, AVBufferRef *hw_device_ctx, int width, int height, AVPixelFormat hw_format)
+AVBufferRef* hw_create_frames(struct AVCodecContext* codec_ctx, AVBufferRef *hw_device_ctx, int width, int height, AVPixelFormat hw_format)
{
+ AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)hw_device_ctx->data;
+ AVBufferRef* child_ctx = hw_device_ctx;
+ // In QSV case we first allocate child D3D11/VAAPI frames (except DXVA2 as no OpenCL interop), then derive to parent QSV frames
+ if (AV_HWDEVICE_TYPE_QSV == device_ctx->type) {
+ AVBufferRef *ctx = (AVBufferRef *) device_ctx->user_opaque; // child context stored during creation of derived context
+ if (ctx && AV_HWDEVICE_TYPE_DXVA2 != ((AVHWDeviceContext *) ctx->data)->type) {
+ child_ctx = ctx;
+ }
+ }
AVBufferRef *hw_frames_ref = nullptr;
- if (ctx)
+ if (codec_ctx)
{
- int res = avcodec_get_hw_frames_parameters(ctx, hw_device_ctx, hw_format, &hw_frames_ref);
+ int res = avcodec_get_hw_frames_parameters(codec_ctx, child_ctx, hw_format, &hw_frames_ref);
if (res < 0)
{
CV_LOG_DEBUG(NULL, "FFMPEG: avcodec_get_hw_frames_parameters() call failed: " << res)
}
if (!hw_frames_ref)
{
- hw_frames_ref = av_hwframe_ctx_alloc(hw_device_ctx);
+ hw_frames_ref = av_hwframe_ctx_alloc(child_ctx);
}
if (!hw_frames_ref)
{
AVHWFramesContext *frames_ctx = (AVHWFramesContext *)(hw_frames_ref->data);
frames_ctx->width = width;
frames_ctx->height = height;
- if (frames_ctx->format == AV_PIX_FMT_NONE)
- frames_ctx->format = hw_format;
+ if (frames_ctx->format == AV_PIX_FMT_NONE) {
+ if (child_ctx == hw_device_ctx) {
+ frames_ctx->format = hw_format;
+ }
+ else {
+ AVHWFramesConstraints* constraints = av_hwdevice_get_hwframe_constraints(child_ctx, NULL);
+ if (constraints) {
+ frames_ctx->format = constraints->valid_hw_formats[0];
+ av_hwframe_constraints_free(&constraints);
+ }
+ }
+ }
if (frames_ctx->sw_format == AV_PIX_FMT_NONE)
frames_ctx->sw_format = HW_DEFAULT_SW_FORMAT;
if (frames_ctx->initial_pool_size == 0)
frames_ctx->initial_pool_size = HW_DEFAULT_POOL_SIZE;
+
+#ifdef HAVE_D3D11
+ if (frames_ctx->device_ctx && AV_HWDEVICE_TYPE_D3D11VA == frames_ctx->device_ctx->type) {
+ // BindFlags
+ AVD3D11VAFramesContext* frames_hwctx = (AVD3D11VAFramesContext*)frames_ctx->hwctx;
+ frames_hwctx->BindFlags |= D3D11_BIND_DECODER | D3D11_BIND_VIDEO_ENCODER;
+ // See function hw_get_d3d11_single_texture(), it allocates additional ID3D11Texture2D texture and
+ // attaches it as 'user_opaque' field. We have to set free() callback before av_hwframe_ctx_init() call.
+ struct D3D11SingleTexture {
+ static void free(struct AVHWFramesContext* ctx) {
+ ID3D11Texture2D* singleTexture = (ID3D11Texture2D*)ctx->user_opaque;
+ if (ctx->user_opaque)
+ singleTexture->Release();
+ }
+ };
+ frames_ctx->free = D3D11SingleTexture::free;
+ }
+#endif
+
int res = av_hwframe_ctx_init(hw_frames_ref);
if (res < 0)
{
av_buffer_unref(&hw_frames_ref);
return NULL;
}
- return hw_frames_ref;
+
+ if (child_ctx != hw_device_ctx) {
+ AVBufferRef* derived_frame_ctx = NULL;
+ int flags = AV_HWFRAME_MAP_READ | AV_HWFRAME_MAP_WRITE;
+ res = av_hwframe_ctx_create_derived(&derived_frame_ctx, hw_format, hw_device_ctx, hw_frames_ref, flags);
+ av_buffer_unref(&hw_frames_ref);
+ if (res < 0)
+ {
+ CV_LOG_INFO(NULL, "FFMPEG: Failed to create derived HW frame context (av_hwframe_ctx_create_derived): " << res);
+ return NULL;
+ }
+ else {
+ ((AVHWFramesContext*)derived_frame_ctx->data)->user_opaque = frames_ctx;
+ return derived_frame_ctx;
+ }
+ }
+ else {
+ return hw_frames_ref;
+ }
}
static
return fmt[0];
}
+// GPU color conversion NV12->BGRA via OpenCL extensions
+static bool
+hw_copy_frame_to_umat(AVBufferRef* ctx, AVFrame* hw_frame, cv::OutputArray output) {
+ CV_UNUSED(hw_frame);
+ CV_UNUSED(output);
+ if (!ctx)
+ return false;
+
+#ifdef HAVE_OPENCL
+ try {
+ // check that current OpenCL context initilized with binding to same VAAPI/D3D11 context
+ AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext *) ctx->data;
+ AVHWDeviceType child_type = hw_check_opencl_context(hw_device_ctx);
+ if (child_type == AV_HWDEVICE_TYPE_NONE)
+ return false;
+
+#ifdef HAVE_VA_INTEL
+ if (child_type == AV_HWDEVICE_TYPE_VAAPI) {
+ VADisplay va_display = hw_get_va_display(hw_device_ctx);
+ VASurfaceID va_surface = hw_get_va_surface(hw_frame);
+ if (va_display && va_surface != VA_INVALID_SURFACE) {
+ va_intel::convertFromVASurface(va_display, va_surface, {hw_frame->width, hw_frame->height}, output);
+ return true;
+ }
+ }
+#endif
+
+#ifdef HAVE_D3D11
+ if (child_type == AV_HWDEVICE_TYPE_D3D11VA) {
+ AVD3D11VADeviceContext* d3d11_device_ctx = hw_get_d3d11_device_ctx(hw_device_ctx);
+ int subresource = 0;
+ ID3D11Texture2D* texture = hw_get_d3d11_texture(hw_frame, &subresource);
+ ID3D11Texture2D* singleTexture = hw_get_d3d11_single_texture(hw_frame, d3d11_device_ctx, texture);
+ if (texture && singleTexture) {
+ // Copy D3D11 sub-texture to D3D11 single texture
+ d3d11_device_ctx->device_context->CopySubresourceRegion(singleTexture, 0, 0, 0, 0, texture, subresource, NULL);
+ // Copy D3D11 single texture to cv::UMat
+ directx::convertFromD3D11Texture2D(singleTexture, output);
+ return true;
+ }
+ }
+#endif
+ }
+ catch (...)
+ {
+ return false;
+ }
+#endif // HAVE_OPENCL
+
+ return false;
+}
+
+// GPU color conversion BGRA->NV12 via OpenCL extensions
+static bool
+hw_copy_umat_to_frame(AVBufferRef* ctx, cv::InputArray input, AVFrame* hw_frame) {
+ CV_UNUSED(input);
+ CV_UNUSED(hw_frame);
+ if (!ctx)
+ return false;
+
+#ifdef HAVE_OPENCL
+ try {
+ // check that current OpenCL context initilized with binding to same VAAPI/D3D11 context
+ AVHWDeviceContext *hw_device_ctx = (AVHWDeviceContext *) ctx->data;
+ AVHWDeviceType child_type = hw_check_opencl_context(hw_device_ctx);
+ if (child_type == AV_HWDEVICE_TYPE_NONE)
+ return false;
+
+#ifdef HAVE_VA_INTEL
+ if (child_type == AV_HWDEVICE_TYPE_VAAPI) {
+ VADisplay va_display = hw_get_va_display(hw_device_ctx);
+ VASurfaceID va_surface = hw_get_va_surface(hw_frame);
+ if (va_display != NULL && va_surface != VA_INVALID_SURFACE) {
+ va_intel::convertToVASurface(va_display, input, va_surface, {hw_frame->width, hw_frame->height});
+ return true;
+ }
+ }
+#endif
+
+#ifdef HAVE_D3D11
+ if (child_type == AV_HWDEVICE_TYPE_D3D11VA) {
+ AVD3D11VADeviceContext* d3d11_device_ctx = hw_get_d3d11_device_ctx(hw_device_ctx);
+ int subresource = 0;
+ ID3D11Texture2D* texture = hw_get_d3d11_texture(hw_frame, &subresource);
+ ID3D11Texture2D* singleTexture = hw_get_d3d11_single_texture(hw_frame, d3d11_device_ctx, texture);
+ if (texture && singleTexture) {
+ // Copy cv::UMat to D3D11 single texture
+ directx::convertToD3D11Texture2D(input, singleTexture);
+ // Copy D3D11 single texture to D3D11 sub-texture
+ d3d11_device_ctx->device_context->CopySubresourceRegion(texture, subresource, 0, 0, 0, singleTexture, 0, NULL);
+ return true;
+ }
+ }
+#endif
+ }
+ catch (...)
+ {
+ return false;
+ }
+#endif // HAVE_OPENCL
+
+ return false;
+}
+
static
VideoAccelerationType hw_type_to_va_type(AVHWDeviceType hw_type) {
struct HWTypeFFMPEG {