Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
95339827
Commit
95339827
authored
Sep 14, 2015
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5272 from avershov:opencl-vaapi-fallback
parents
21d06f5a
22bb5d1f
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
859 additions
and
406 deletions
+859
-406
CMakeLists.txt
CMakeLists.txt
+9
-4
OpenCVFindLibsVideo.cmake
cmake/OpenCVFindLibsVideo.cmake
+14
-6
OpenCVFindVA.cmake
cmake/OpenCVFindVA.cmake
+19
-0
OpenCVFindVA_INTEL.cmake
cmake/OpenCVFindVA_INTEL.cmake
+19
-19
cvconfig.h.in
cmake/templates/cvconfig.h.in
+5
-2
CMakeLists.txt
modules/core/CMakeLists.txt
+1
-1
va_intel.hpp
modules/core/include/opencv2/core/va_intel.hpp
+23
-20
precomp.hpp
modules/core/src/precomp.hpp
+1
-1
va_intel.cpp
modules/core/src/va_intel.cpp
+528
-0
vaapi.cpp
modules/core/src/vaapi.cpp
+0
-302
CMakeLists.txt
samples/CMakeLists.txt
+2
-2
CMakeLists.txt
samples/va_intel/CMakeLists.txt
+7
-7
display.cpp.inc
samples/va_intel/display.cpp.inc
+76
-13
va_intel_interop.cpp
samples/va_intel/va_intel_interop.cpp
+155
-29
No files found.
CMakeLists.txt
View file @
95339827
...
...
@@ -205,7 +205,8 @@ OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON
OCV_OPTION
(
WITH_DIRECTX
"Include DirectX support"
ON
IF
(
WIN32 AND NOT WINRT
)
)
OCV_OPTION
(
WITH_INTELPERC
"Include Intel Perceptual Computing support"
OFF
IF
(
WIN32 AND NOT WINRT
)
)
OCV_OPTION
(
WITH_IPP_A
"Include Intel IPP_A support"
OFF
IF
(
MSVC OR X86 OR X86_64
)
)
OCV_OPTION
(
WITH_VAAPI
"Include VA-API support"
OFF
IF
(
UNIX AND NOT ANDROID
)
)
OCV_OPTION
(
WITH_VA
"Include VA support"
OFF
IF
(
UNIX AND NOT ANDROID
)
)
OCV_OPTION
(
WITH_VA_INTEL
"Include Intel VA-API/OpenCL support"
OFF
IF
(
UNIX AND NOT ANDROID
)
)
OCV_OPTION
(
WITH_GDAL
"Include GDAL Support"
OFF
IF
(
NOT ANDROID AND NOT IOS AND NOT WINRT
)
)
OCV_OPTION
(
WITH_GPHOTO2
"Include gPhoto2 library support"
ON
IF
(
UNIX AND NOT ANDROID
)
)
...
...
@@ -1066,9 +1067,13 @@ if(DEFINED WITH_IPP_A)
status
(
" Use IPP Async:"
HAVE_IPP_A THEN
"YES"
ELSE NO
)
endif
(
DEFINED WITH_IPP_A
)
if
(
DEFINED WITH_VAAPI
)
status
(
" Use Intel VA-API:"
HAVE_VAAPI THEN
"YES (MSDK:
${
VAAPI_MSDK_ROOT
}
OpenCL:
${
VAAPI_IOCL_ROOT
}
)"
ELSE NO
)
endif
(
DEFINED WITH_VAAPI
)
if
(
DEFINED WITH_VA
)
status
(
" Use VA:"
HAVE_VA THEN
"YES"
ELSE NO
)
endif
(
DEFINED WITH_VA
)
if
(
DEFINED WITH_VA_INTEL
)
status
(
" Use Intel VA-API/OpenCL:"
HAVE_VA_INTEL THEN
"YES (MSDK:
${
VA_INTEL_MSDK_ROOT
}
OpenCL:
${
VA_INTEL_IOCL_ROOT
}
)"
ELSE NO
)
endif
(
DEFINED WITH_VA_INTEL
)
status
(
" Use Eigen:"
HAVE_EIGEN THEN
"YES (ver
${
EIGEN_WORLD_VERSION
}
.
${
EIGEN_MAJOR_VERSION
}
.
${
EIGEN_MINOR_VERSION
}
)"
ELSE NO
)
status
(
" Use Cuda:"
HAVE_CUDA THEN
"YES (ver
${
CUDA_VERSION_STRING
}
)"
ELSE NO
)
...
...
cmake/OpenCVFindLibsVideo.cmake
View file @
95339827
...
...
@@ -318,10 +318,18 @@ if(WITH_GPHOTO2)
CHECK_MODULE
(
libgphoto2 HAVE_GPHOTO2
)
endif
(
WITH_GPHOTO2
)
# --- VA
-API
---
if
(
WITH_VA
API
)
include
(
"
${
OpenCV_SOURCE_DIR
}
/cmake/OpenCVFindVA
API
.cmake"
)
if
(
VA
API
_IOCL_INCLUDE_DIR
)
ocv_include_directories
(
${
VA
API
_IOCL_INCLUDE_DIR
}
)
# --- VA
& VA_INTEL
---
if
(
WITH_VA
_INTEL
)
include
(
"
${
OpenCV_SOURCE_DIR
}
/cmake/OpenCVFindVA
_INTEL
.cmake"
)
if
(
VA
_INTEL
_IOCL_INCLUDE_DIR
)
ocv_include_directories
(
${
VA
_INTEL
_IOCL_INCLUDE_DIR
}
)
endif
()
endif
(
WITH_VAAPI
)
set
(
WITH_VA YES
)
endif
(
WITH_VA_INTEL
)
if
(
WITH_VA
)
include
(
"
${
OpenCV_SOURCE_DIR
}
/cmake/OpenCVFindVA.cmake"
)
if
(
VA_INCLUDE_DIR
)
ocv_include_directories
(
${
VA_INCLUDE_DIR
}
)
endif
()
endif
(
WITH_VA
)
cmake/OpenCVFindVA.cmake
0 → 100644
View file @
95339827
# Main variables:
# HAVE_VA for conditional compilation OpenCV with/without libva
if
(
UNIX AND NOT ANDROID
)
find_path
(
VA_INCLUDE_DIR
NAMES va/va.h
PATHS
"/usr/include"
PATH_SUFFIXES include
DOC
"Path to libva headers"
)
endif
()
if
(
VA_INCLUDE_DIR
)
set
(
HAVE_VA TRUE
)
set
(
VA_LIBRARIES
"-lva"
"-lva-x11"
)
else
()
set
(
HAVE_VA FALSE
)
message
(
WARNING
"libva installation is not found."
)
endif
()
cmake/OpenCVFindVA
API
.cmake
→
cmake/OpenCVFindVA
_INTEL
.cmake
View file @
95339827
# Main variables:
# VA
API_MSDK_INCLUDE_DIR and VAAPI_IOCL_INCLUDE_DIR to use VAAPI
# HAVE_VA
API for conditional compilation OpenCV with/without VAAPI
# VA
_INTEL_MSDK_INCLUDE_DIR and VA_INTEL_IOCL_INCLUDE_DIR to use VA_INTEL
# HAVE_VA
_INTEL for conditional compilation OpenCV with/without VA_INTEL
# VA
API
_MSDK_ROOT - root of Intel MSDK installation
# VA
API
_IOCL_ROOT - root of Intel OCL installation
# VA
_INTEL
_MSDK_ROOT - root of Intel MSDK installation
# VA
_INTEL
_IOCL_ROOT - root of Intel OCL installation
if
(
UNIX AND NOT ANDROID
)
if
(
$ENV{VA
API
_MSDK_ROOT}
)
set
(
VA
API_MSDK_ROOT $ENV{VAAPI
_MSDK_ROOT}
)
if
(
$ENV{VA
_INTEL
_MSDK_ROOT}
)
set
(
VA
_INTEL_MSDK_ROOT $ENV{VA_INTEL
_MSDK_ROOT}
)
else
()
set
(
VA
API
_MSDK_ROOT
"/opt/intel/mediasdk"
)
set
(
VA
_INTEL
_MSDK_ROOT
"/opt/intel/mediasdk"
)
endif
()
if
(
$ENV{VA
API
_IOCL_ROOT}
)
set
(
VA
API_IOCL_ROOT $ENV{VAAPI
_IOCL_ROOT}
)
if
(
$ENV{VA
_INTEL
_IOCL_ROOT}
)
set
(
VA
_INTEL_IOCL_ROOT $ENV{VA_INTEL
_IOCL_ROOT}
)
else
()
set
(
VA
API
_IOCL_ROOT
"/opt/intel/opencl"
)
set
(
VA
_INTEL
_IOCL_ROOT
"/opt/intel/opencl"
)
endif
()
find_path
(
VA
API
_MSDK_INCLUDE_DIR
VA
_INTEL
_MSDK_INCLUDE_DIR
NAMES mfxdefs.h
PATHS
${
VA
API
_MSDK_ROOT
}
PATHS
${
VA
_INTEL
_MSDK_ROOT
}
PATH_SUFFIXES include
DOC
"Path to Intel MSDK headers"
)
find_path
(
VA
API
_IOCL_INCLUDE_DIR
VA
_INTEL
_IOCL_INCLUDE_DIR
NAMES CL/va_ext.h
PATHS
${
VA
API
_IOCL_ROOT
}
PATHS
${
VA
_INTEL
_IOCL_ROOT
}
PATH_SUFFIXES include
DOC
"Path to Intel OpenCL headers"
)
endif
()
if
(
VA
API_MSDK_INCLUDE_DIR AND VAAPI
_IOCL_INCLUDE_DIR
)
set
(
HAVE_VA
API
TRUE
)
set
(
VA
API_EXTRA_LIB
S
"-lva"
"-lva-drm"
)
if
(
VA
_INTEL_MSDK_INCLUDE_DIR AND VA_INTEL
_IOCL_INCLUDE_DIR
)
set
(
HAVE_VA
_INTEL
TRUE
)
set
(
VA
_INTEL_LIBRARIE
S
"-lva"
"-lva-drm"
)
else
()
set
(
HAVE_VA
API
FALSE
)
set
(
HAVE_VA
_INTEL
FALSE
)
message
(
WARNING
"Intel MSDK & OpenCL installation is not found."
)
endif
()
mark_as_advanced
(
FORCE VA
API_MSDK_INCLUDE_DIR VAAPI
_IOCL_INCLUDE_DIR
)
mark_as_advanced
(
FORCE VA
_INTEL_MSDK_INCLUDE_DIR VA_INTEL
_IOCL_INCLUDE_DIR
)
cmake/templates/cvconfig.h.in
View file @
95339827
...
...
@@ -189,5 +189,8 @@
/* gPhoto2 library */
#cmakedefine HAVE_GPHOTO2
/* Intel VA-API */
#cmakedefine HAVE_VAAPI
/* VA library (libva) */
#cmakedefine HAVE_VA
/* Intel VA-API/OpenCL */
#cmakedefine HAVE_VA_INTEL
modules/core/CMakeLists.txt
View file @
95339827
set
(
the_description
"The Core Functionality"
)
ocv_add_module
(
core
opencv_hal
PRIVATE_REQUIRED
${
ZLIB_LIBRARIES
}
"
${
OPENCL_LIBRARIES
}
"
PRIVATE_REQUIRED
${
ZLIB_LIBRARIES
}
"
${
OPENCL_LIBRARIES
}
"
"
${
VA_LIBRARIES
}
"
OPTIONAL opencv_cudev
WRAP java python
)
...
...
modules/core/include/opencv2/core/va
api
.hpp
→
modules/core/include/opencv2/core/va
_intel
.hpp
View file @
95339827
...
...
@@ -5,36 +5,36 @@
// Copyright (C) 2015, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#ifndef __OPENCV_CORE_VA
API
_HPP__
#define __OPENCV_CORE_VA
API
_HPP__
#ifndef __OPENCV_CORE_VA
_INTEL
_HPP__
#define __OPENCV_CORE_VA
_INTEL
_HPP__
#ifndef __cplusplus
# error va
api
.hpp header must be compiled as C++
# error va
_intel
.hpp header must be compiled as C++
#endif
#include "opencv2/core.hpp"
#include "ocl.hpp"
#if defined(HAVE_VA
API
)
#if defined(HAVE_VA)
# include "va/va.h"
#else // HAVE_VA
API
#else // HAVE_VA
# if !defined(_VA_H_)
typedef
void
*
VADisplay
;
typedef
unsigned
int
VASurfaceID
;
# endif // !_VA_H_
#endif // HAVE_VA
API
#endif // HAVE_VA
namespace
cv
{
namespace
va
api
{
namespace
cv
{
namespace
va
_intel
{
/** @addtogroup core_va
api
This section describes
CL-VA (VA-API
) interoperability.
/** @addtogroup core_va
_intel
This section describes
Intel VA-API/OpenCL (CL-VA
) interoperability.
To enable CL-VA interoperability support, configure OpenCV using CMake with WITH_VA
API
=ON . Currently VA-API is
To enable CL-VA interoperability support, configure OpenCV using CMake with WITH_VA
_INTEL
=ON . Currently VA-API is
supported on Linux only. You should also install Intel Media Server Studio (MSS) to use this feature. You may
have to specify the path(s) to MSS components for cmake in environment variables: VA
API
_MSDK_ROOT for Media SDK
(default is "/opt/intel/mediasdk"), and VA
API
_IOCL_ROOT for Intel OpenCL (default is "/opt/intel/opencl").
have to specify the path(s) to MSS components for cmake in environment variables: VA
_INTEL
_MSDK_ROOT for Media SDK
(default is "/opt/intel/mediasdk"), and VA
_INTEL
_IOCL_ROOT for Intel OpenCL (default is "/opt/intel/opencl").
To use
VA-API
interoperability you should first create VADisplay (libva), and then call initializeContextFromVA()
To use
CL-VA
interoperability you should first create VADisplay (libva), and then call initializeContextFromVA()
function to create OpenCL context and set up interoperability.
*/
//! @{
...
...
@@ -46,29 +46,32 @@ using namespace cv::ocl;
// TODO static functions in the Context class
/** @brief Creates OpenCL context from VA.
@param display - VADisplay for which CL interop should be established.
@param display - VADisplay for which CL interop should be established.
@param tryInterop - try to set up for interoperability, if true; set up for use slow copy if false.
@return Returns reference to OpenCL Context
*/
CV_EXPORTS
Context
&
initializeContextFromVA
(
VADisplay
display
);
CV_EXPORTS
Context
&
initializeContextFromVA
(
VADisplay
display
,
bool
tryInterop
=
true
);
}
// namespace cv::va
api
::ocl
}
// namespace cv::va
_intel
::ocl
/** @brief Converts InputArray to VASurfaceID object.
@param display - VADisplay object.
@param src - source InputArray.
@param surface - destination VASurfaceID object.
@param size - size of image represented by VASurfaceID object.
*/
CV_EXPORTS
void
convertToVASurface
(
InputArray
src
,
VASurfaceID
surface
,
Size
size
);
CV_EXPORTS
void
convertToVASurface
(
VADisplay
display
,
InputArray
src
,
VASurfaceID
surface
,
Size
size
);
/** @brief Converts VASurfaceID object to OutputArray.
@param display - VADisplay object.
@param surface - source VASurfaceID object.
@param size - size of image represented by VASurfaceID object.
@param dst - destination OutputArray.
*/
CV_EXPORTS
void
convertFromVASurface
(
VASurfaceID
surface
,
Size
size
,
OutputArray
dst
);
CV_EXPORTS
void
convertFromVASurface
(
VA
Display
display
,
VA
SurfaceID
surface
,
Size
size
,
OutputArray
dst
);
//! @}
}}
// namespace cv::va
api
}}
// namespace cv::va
_intel
#endif
/* __OPENCV_CORE_VA
API
_HPP__ */
#endif
/* __OPENCV_CORE_VA
_INTEL
_HPP__ */
modules/core/src/precomp.hpp
View file @
95339827
...
...
@@ -50,7 +50,7 @@
#include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp"
#include "opencv2/core/opengl.hpp"
#include "opencv2/core/va
api
.hpp"
#include "opencv2/core/va
_intel
.hpp"
#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"
...
...
modules/core/src/va_intel.cpp
0 → 100644
View file @
95339827
// 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.
// Copyright (C) 2015, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "precomp.hpp"
#ifdef HAVE_VA
# include <va/va.h>
#else // HAVE_VA
# define NO_VA_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without VA support (libva)")
#endif // HAVE_VA
using
namespace
cv
;
////////////////////////////////////////////////////////////////////////
// CL-VA Interoperability
#ifdef HAVE_OPENCL
# include "opencv2/core/opencl/runtime/opencl_core.hpp"
# include "opencv2/core.hpp"
# include "opencv2/core/ocl.hpp"
# include "opencl_kernels_core.hpp"
#endif // HAVE_OPENCL
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)
# include <CL/va_ext.h>
#endif // HAVE_VA_INTEL && HAVE_OPENCL
namespace
cv
{
namespace
va_intel
{
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)
static
clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
=
NULL
;
static
clCreateFromVA_APIMediaSurfaceINTEL_fn
clCreateFromVA_APIMediaSurfaceINTEL
=
NULL
;
static
clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn
clEnqueueAcquireVA_APIMediaSurfacesINTEL
=
NULL
;
static
clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn
clEnqueueReleaseVA_APIMediaSurfacesINTEL
=
NULL
;
static
bool
contextInitialized
=
false
;
#endif // HAVE_VA_INTEL && HAVE_OPENCL
namespace
ocl
{
Context
&
initializeContextFromVA
(
VADisplay
display
,
bool
tryInterop
)
{
(
void
)
display
;
(
void
)
tryInterop
;
#if !defined(HAVE_VA)
NO_VA_SUPPORT_ERROR
;
#else // !HAVE_VA
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL))
contextInitialized
=
false
;
if
(
tryInterop
)
{
cl_uint
numPlatforms
;
cl_int
status
=
clGetPlatformIDs
(
0
,
NULL
,
&
numPlatforms
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Can't get number of platforms"
);
if
(
numPlatforms
==
0
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: No available platforms"
);
std
::
vector
<
cl_platform_id
>
platforms
(
numPlatforms
);
status
=
clGetPlatformIDs
(
numPlatforms
,
&
platforms
[
0
],
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Can't get platform Id list"
);
// For CL-VA interop, we must find platform/device with "cl_intel_va_api_media_sharing" extension.
// With standard initialization procedure, we should examine platform extension string for that.
// But in practice, the platform ext string doesn't contain it, while device ext string does.
// Follow Intel procedure (see tutorial), we should obtain device IDs by extension call.
// Note that we must obtain function pointers using specific platform ID, and can't provide pointers in advance.
// So, we iterate and select the first platform, for which we got non-NULL pointers, device, and CL context.
int
found
=
-
1
;
cl_context
context
=
0
;
cl_device_id
device
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
numPlatforms
;
++
i
)
{
// Get extension function pointers
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
=
(
clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clGetDeviceIDsFromVA_APIMediaAdapterINTEL"
);
clCreateFromVA_APIMediaSurfaceINTEL
=
(
clCreateFromVA_APIMediaSurfaceINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clCreateFromVA_APIMediaSurfaceINTEL"
);
clEnqueueAcquireVA_APIMediaSurfacesINTEL
=
(
clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clEnqueueAcquireVA_APIMediaSurfacesINTEL"
);
clEnqueueReleaseVA_APIMediaSurfacesINTEL
=
(
clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clEnqueueReleaseVA_APIMediaSurfacesINTEL"
);
if
(((
void
*
)
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
==
NULL
)
||
((
void
*
)
clCreateFromVA_APIMediaSurfaceINTEL
==
NULL
)
||
((
void
*
)
clEnqueueAcquireVA_APIMediaSurfacesINTEL
==
NULL
)
||
((
void
*
)
clEnqueueReleaseVA_APIMediaSurfacesINTEL
==
NULL
))
{
continue
;
}
// Query device list
cl_uint
numDevices
=
0
;
status
=
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
(
platforms
[
i
],
CL_VA_API_DISPLAY_INTEL
,
display
,
CL_PREFERRED_DEVICES_FOR_VA_API_INTEL
,
0
,
NULL
,
&
numDevices
);
if
((
status
!=
CL_SUCCESS
)
||
!
(
numDevices
>
0
))
continue
;
numDevices
=
1
;
// initializeContextFromHandle() expects only 1 device
status
=
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
(
platforms
[
i
],
CL_VA_API_DISPLAY_INTEL
,
display
,
CL_PREFERRED_DEVICES_FOR_VA_API_INTEL
,
numDevices
,
&
device
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
continue
;
// Creating CL-VA media sharing OpenCL context
cl_context_properties
props
[]
=
{
CL_CONTEXT_VA_API_DISPLAY_INTEL
,
(
cl_context_properties
)
display
,
CL_CONTEXT_INTEROP_USER_SYNC
,
CL_FALSE
,
// no explicit sync required
0
};
context
=
clCreateContext
(
props
,
numDevices
,
&
device
,
NULL
,
NULL
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
{
clReleaseDevice
(
device
);
}
else
{
found
=
i
;
break
;
}
}
if
(
found
>=
0
)
{
contextInitialized
=
true
;
Context
&
ctx
=
Context
::
getDefault
(
false
);
initializeContextFromHandle
(
ctx
,
platforms
[
found
],
context
,
device
);
return
ctx
;
}
}
# endif // HAVE_VA_INTEL && HAVE_OPENCL
{
Context
&
ctx
=
Context
::
getDefault
(
true
);
return
ctx
;
}
#endif // !HAVE_VA
}
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)
static
bool
ocl_convert_nv12_to_bgr
(
cl_mem
clImageY
,
cl_mem
clImageUV
,
cl_mem
clBuffer
,
int
step
,
int
cols
,
int
rows
)
{
ocl
::
Kernel
k
;
k
.
create
(
"YUV2BGR_NV12_8u"
,
cv
::
ocl
::
core
::
cvtclr_dx_oclsrc
,
""
);
if
(
k
.
empty
())
return
false
;
k
.
args
(
clImageY
,
clImageUV
,
clBuffer
,
step
,
cols
,
rows
);
size_t
globalsize
[]
=
{
cols
,
rows
};
return
k
.
run
(
2
,
globalsize
,
0
,
false
);
}
static
bool
ocl_convert_bgr_to_nv12
(
cl_mem
clBuffer
,
int
step
,
int
cols
,
int
rows
,
cl_mem
clImageY
,
cl_mem
clImageUV
)
{
ocl
::
Kernel
k
;
k
.
create
(
"BGR2YUV_NV12_8u"
,
cv
::
ocl
::
core
::
cvtclr_dx_oclsrc
,
""
);
if
(
k
.
empty
())
return
false
;
k
.
args
(
clBuffer
,
step
,
cols
,
rows
,
clImageY
,
clImageUV
);
size_t
globalsize
[]
=
{
cols
,
rows
};
return
k
.
run
(
2
,
globalsize
,
0
,
false
);
}
#endif // HAVE_VA_INTEL && HAVE_OPENCL
}
// namespace cv::va_intel::ocl
#if defined(HAVE_VA)
const
int
NCHANNELS
=
3
;
static
void
copy_convert_nv12_to_bgr
(
const
VAImage
&
image
,
const
unsigned
char
*
buffer
,
Mat
&
bgr
)
{
const
float
d1
=
16.0
f
;
const
float
d2
=
128.0
f
;
static
const
float
coeffs
[
5
]
=
{
1.163999557
f
,
2.017999649
f
,
-
0.390999794
f
,
-
0.812999725
f
,
1.5959997177
f
};
const
size_t
srcOffsetY
=
image
.
offsets
[
0
];
const
size_t
srcOffsetUV
=
image
.
offsets
[
1
];
const
size_t
srcStepY
=
image
.
pitches
[
0
];
const
size_t
srcStepUV
=
image
.
pitches
[
1
];
const
size_t
dstStep
=
bgr
.
step
;
const
unsigned
char
*
srcY0
=
buffer
+
srcOffsetY
;
const
unsigned
char
*
srcUV
=
buffer
+
srcOffsetUV
;
unsigned
char
*
dst0
=
bgr
.
data
;
for
(
int
y
=
0
;
y
<
bgr
.
rows
;
y
+=
2
)
{
const
unsigned
char
*
srcY1
=
srcY0
+
srcStepY
;
unsigned
char
*
dst1
=
dst0
+
dstStep
;
for
(
int
x
=
0
;
x
<
bgr
.
cols
;
x
+=
2
)
{
float
Y0
=
float
(
srcY0
[
x
+
0
]);
float
Y1
=
float
(
srcY0
[
x
+
1
]);
float
Y2
=
float
(
srcY1
[
x
+
0
]);
float
Y3
=
float
(
srcY1
[
x
+
1
]);
float
U
=
float
(
srcUV
[
2
*
(
x
/
2
)
+
0
])
-
d2
;
float
V
=
float
(
srcUV
[
2
*
(
x
/
2
)
+
1
])
-
d2
;
Y0
=
std
::
max
(
0.0
f
,
Y0
-
d1
)
*
coeffs
[
0
];
Y1
=
std
::
max
(
0.0
f
,
Y1
-
d1
)
*
coeffs
[
0
];
Y2
=
std
::
max
(
0.0
f
,
Y2
-
d1
)
*
coeffs
[
0
];
Y3
=
std
::
max
(
0.0
f
,
Y3
-
d1
)
*
coeffs
[
0
];
float
ruv
=
coeffs
[
4
]
*
V
;
float
guv
=
coeffs
[
3
]
*
V
+
coeffs
[
2
]
*
U
;
float
buv
=
coeffs
[
1
]
*
U
;
dst0
[(
x
+
0
)
*
NCHANNELS
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y0
+
buv
);
dst0
[(
x
+
0
)
*
NCHANNELS
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y0
+
guv
);
dst0
[(
x
+
0
)
*
NCHANNELS
+
2
]
=
saturate_cast
<
unsigned
char
>
(
Y0
+
ruv
);
dst0
[(
x
+
1
)
*
NCHANNELS
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y1
+
buv
);
dst0
[(
x
+
1
)
*
NCHANNELS
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y1
+
guv
);
dst0
[(
x
+
1
)
*
NCHANNELS
+
2
]
=
saturate_cast
<
unsigned
char
>
(
Y1
+
ruv
);
dst1
[(
x
+
0
)
*
NCHANNELS
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y2
+
buv
);
dst1
[(
x
+
0
)
*
NCHANNELS
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y2
+
guv
);
dst1
[(
x
+
0
)
*
NCHANNELS
+
2
]
=
saturate_cast
<
unsigned
char
>
(
Y2
+
ruv
);
dst1
[(
x
+
1
)
*
NCHANNELS
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y3
+
buv
);
dst1
[(
x
+
1
)
*
NCHANNELS
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y3
+
guv
);
dst1
[(
x
+
1
)
*
NCHANNELS
+
2
]
=
saturate_cast
<
unsigned
char
>
(
Y3
+
ruv
);
}
srcY0
=
srcY1
+
srcStepY
;
srcUV
+=
srcStepUV
;
dst0
=
dst1
+
dstStep
;
}
}
static
void
copy_convert_bgr_to_nv12
(
const
VAImage
&
image
,
const
Mat
&
bgr
,
unsigned
char
*
buffer
)
{
const
float
d1
=
16.0
f
;
const
float
d2
=
128.0
f
;
static
const
float
coeffs
[
8
]
=
{
0.256999969
f
,
0.50399971
f
,
0.09799957
f
,
-
0.1479988098
f
,
-
0.2909994125
f
,
0.438999176
f
,
-
0.3679990768
f
,
-
0.0709991455
f
};
const
size_t
dstOffsetY
=
image
.
offsets
[
0
];
const
size_t
dstOffsetUV
=
image
.
offsets
[
1
];
const
size_t
dstStepY
=
image
.
pitches
[
0
];
const
size_t
dstStepUV
=
image
.
pitches
[
1
];
const
size_t
srcStep
=
bgr
.
step
;
const
unsigned
char
*
src0
=
bgr
.
data
;
unsigned
char
*
dstY0
=
buffer
+
dstOffsetY
;
unsigned
char
*
dstUV
=
buffer
+
dstOffsetUV
;
for
(
int
y
=
0
;
y
<
bgr
.
rows
;
y
+=
2
)
{
const
unsigned
char
*
src1
=
src0
+
srcStep
;
unsigned
char
*
dstY1
=
dstY0
+
dstStepY
;
for
(
int
x
=
0
;
x
<
bgr
.
cols
;
x
+=
2
)
{
float
B0
=
float
(
src0
[(
x
+
0
)
*
NCHANNELS
+
0
]);
float
G0
=
float
(
src0
[(
x
+
0
)
*
NCHANNELS
+
1
]);
float
R0
=
float
(
src0
[(
x
+
0
)
*
NCHANNELS
+
2
]);
float
B1
=
float
(
src0
[(
x
+
1
)
*
NCHANNELS
+
0
]);
float
G1
=
float
(
src0
[(
x
+
1
)
*
NCHANNELS
+
1
]);
float
R1
=
float
(
src0
[(
x
+
1
)
*
NCHANNELS
+
2
]);
float
B2
=
float
(
src1
[(
x
+
0
)
*
NCHANNELS
+
0
]);
float
G2
=
float
(
src1
[(
x
+
0
)
*
NCHANNELS
+
1
]);
float
R2
=
float
(
src1
[(
x
+
0
)
*
NCHANNELS
+
2
]);
float
B3
=
float
(
src1
[(
x
+
1
)
*
NCHANNELS
+
0
]);
float
G3
=
float
(
src1
[(
x
+
1
)
*
NCHANNELS
+
1
]);
float
R3
=
float
(
src1
[(
x
+
1
)
*
NCHANNELS
+
2
]);
float
Y0
=
coeffs
[
0
]
*
R0
+
coeffs
[
1
]
*
G0
+
coeffs
[
2
]
*
B0
+
d1
;
float
Y1
=
coeffs
[
0
]
*
R1
+
coeffs
[
1
]
*
G1
+
coeffs
[
2
]
*
B1
+
d1
;
float
Y2
=
coeffs
[
0
]
*
R2
+
coeffs
[
1
]
*
G2
+
coeffs
[
2
]
*
B2
+
d1
;
float
Y3
=
coeffs
[
0
]
*
R3
+
coeffs
[
1
]
*
G3
+
coeffs
[
2
]
*
B3
+
d1
;
float
U
=
coeffs
[
3
]
*
R0
+
coeffs
[
4
]
*
G0
+
coeffs
[
5
]
*
B0
+
d2
;
float
V
=
coeffs
[
5
]
*
R0
+
coeffs
[
6
]
*
G0
+
coeffs
[
7
]
*
B0
+
d2
;
dstY0
[
x
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y0
);
dstY0
[
x
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y1
);
dstY1
[
x
+
0
]
=
saturate_cast
<
unsigned
char
>
(
Y2
);
dstY1
[
x
+
1
]
=
saturate_cast
<
unsigned
char
>
(
Y3
);
dstUV
[
2
*
(
x
/
2
)
+
0
]
=
saturate_cast
<
unsigned
char
>
(
U
);
dstUV
[
2
*
(
x
/
2
)
+
1
]
=
saturate_cast
<
unsigned
char
>
(
V
);
}
src0
=
src1
+
srcStep
;
dstY0
=
dstY1
+
dstStepY
;
dstUV
+=
dstStepUV
;
}
}
#endif // HAVE_VA
void
convertToVASurface
(
VADisplay
display
,
InputArray
src
,
VASurfaceID
surface
,
Size
size
)
{
(
void
)
display
;
(
void
)
src
;
(
void
)
surface
;
(
void
)
size
;
#if !defined(HAVE_VA)
NO_VA_SUPPORT_ERROR
;
#else // !HAVE_VA
const
int
stype
=
CV_8UC3
;
int
srcType
=
src
.
type
();
CV_Assert
(
srcType
==
stype
);
Size
srcSize
=
src
.
size
();
CV_Assert
(
srcSize
.
width
==
size
.
width
&&
srcSize
.
height
==
size
.
height
);
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL))
if
(
contextInitialized
)
{
UMat
u
=
src
.
getUMat
();
// TODO Add support for roi
CV_Assert
(
u
.
offset
==
0
);
CV_Assert
(
u
.
isContinuous
());
cl_mem
clBuffer
=
(
cl_mem
)
u
.
handle
(
ACCESS_READ
);
using
namespace
cv
::
ocl
;
Context
&
ctx
=
Context
::
getDefault
();
cl_context
context
=
(
cl_context
)
ctx
.
ptr
();
cl_int
status
=
0
;
cl_mem
clImageY
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_WRITE_ONLY
,
&
surface
,
0
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"
);
cl_mem
clImageUV
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_WRITE_ONLY
,
&
surface
,
1
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"
);
cl_command_queue
q
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
cl_mem
images
[
2
]
=
{
clImageY
,
clImageUV
};
status
=
clEnqueueAcquireVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"
);
if
(
!
ocl
::
ocl_convert_bgr_to_nv12
(
clBuffer
,
(
int
)
u
.
step
[
0
],
u
.
cols
,
u
.
rows
,
clImageY
,
clImageUV
))
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: ocl_convert_bgr_to_nv12 failed"
);
clEnqueueReleaseVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"
);
status
=
clFinish
(
q
);
// TODO Use events
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clFinish failed"
);
status
=
clReleaseMemObject
(
clImageY
);
// TODO RAII
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (Y plane)"
);
status
=
clReleaseMemObject
(
clImageUV
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (UV plane)"
);
}
else
# endif // HAVE_VA_INTEL && HAVE_OPENCL
{
Mat
m
=
src
.
getMat
();
// TODO Add support for roi
CV_Assert
(
m
.
data
==
m
.
datastart
);
CV_Assert
(
m
.
isContinuous
());
VAStatus
status
=
0
;
status
=
vaSyncSurface
(
display
,
surface
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaSyncSurface failed"
);
VAImage
image
;
status
=
vaDeriveImage
(
display
,
surface
,
&
image
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaDeriveImage failed"
);
unsigned
char
*
buffer
=
0
;
status
=
vaMapBuffer
(
display
,
image
.
buf
,
(
void
**
)
&
buffer
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaMapBuffer failed"
);
CV_Assert
(
image
.
format
.
fourcc
==
VA_FOURCC_NV12
);
copy_convert_bgr_to_nv12
(
image
,
m
,
buffer
);
status
=
vaUnmapBuffer
(
display
,
image
.
buf
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaUnmapBuffer failed"
);
status
=
vaDestroyImage
(
display
,
image
.
image_id
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaDestroyImage failed"
);
}
#endif // !HAVE_VA
}
void
convertFromVASurface
(
VADisplay
display
,
VASurfaceID
surface
,
Size
size
,
OutputArray
dst
)
{
(
void
)
display
;
(
void
)
surface
;
(
void
)
dst
;
(
void
)
size
;
#if !defined(HAVE_VA)
NO_VA_SUPPORT_ERROR
;
#else // !HAVE_VA
const
int
dtype
=
CV_8UC3
;
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
dst
.
create
(
size
,
dtype
);
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL))
if
(
contextInitialized
)
{
UMat
u
=
dst
.
getUMat
();
// TODO Add support for roi
CV_Assert
(
u
.
offset
==
0
);
CV_Assert
(
u
.
isContinuous
());
cl_mem
clBuffer
=
(
cl_mem
)
u
.
handle
(
ACCESS_WRITE
);
using
namespace
cv
::
ocl
;
Context
&
ctx
=
Context
::
getDefault
();
cl_context
context
=
(
cl_context
)
ctx
.
ptr
();
cl_int
status
=
0
;
cl_mem
clImageY
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_READ_ONLY
,
&
surface
,
0
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"
);
cl_mem
clImageUV
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_READ_ONLY
,
&
surface
,
1
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"
);
cl_command_queue
q
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
cl_mem
images
[
2
]
=
{
clImageY
,
clImageUV
};
status
=
clEnqueueAcquireVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"
);
if
(
!
ocl
::
ocl_convert_nv12_to_bgr
(
clImageY
,
clImageUV
,
clBuffer
,
(
int
)
u
.
step
[
0
],
u
.
cols
,
u
.
rows
))
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: ocl_convert_nv12_to_bgr failed"
);
status
=
clEnqueueReleaseVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"
);
status
=
clFinish
(
q
);
// TODO Use events
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clFinish failed"
);
status
=
clReleaseMemObject
(
clImageY
);
// TODO RAII
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (Y plane)"
);
status
=
clReleaseMemObject
(
clImageUV
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (UV plane)"
);
}
else
# endif // HAVE_VA_INTEL && HAVE_OPENCL
{
Mat
m
=
dst
.
getMat
();
// TODO Add support for roi
CV_Assert
(
m
.
data
==
m
.
datastart
);
CV_Assert
(
m
.
isContinuous
());
VAStatus
status
=
0
;
status
=
vaSyncSurface
(
display
,
surface
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaSyncSurface failed"
);
VAImage
image
;
status
=
vaDeriveImage
(
display
,
surface
,
&
image
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaDeriveImage failed"
);
unsigned
char
*
buffer
=
0
;
status
=
vaMapBuffer
(
display
,
image
.
buf
,
(
void
**
)
&
buffer
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaMapBuffer failed"
);
CV_Assert
(
image
.
format
.
fourcc
==
VA_FOURCC_NV12
);
copy_convert_nv12_to_bgr
(
image
,
buffer
,
m
);
status
=
vaUnmapBuffer
(
display
,
image
.
buf
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaUnmapBuffer failed"
);
status
=
vaDestroyImage
(
display
,
image
.
image_id
);
if
(
status
!=
VA_STATUS_SUCCESS
)
CV_Error
(
cv
::
Error
::
StsError
,
"VA-API: vaDestroyImage failed"
);
}
#endif // !HAVE_VA
}
}}
// namespace cv::va_intel
modules/core/src/vaapi.cpp
deleted
100644 → 0
View file @
21d06f5a
// 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.
// Copyright (C) 2015, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "precomp.hpp"
#ifdef HAVE_VAAPI
#else // HAVE_VAAPI
# define NO_VAAPI_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without VA-API support")
#endif // HAVE_VAAPI
using
namespace
cv
;
////////////////////////////////////////////////////////////////////////
// CL-VA Interoperability
#ifdef HAVE_OPENCL
# include "opencv2/core/opencl/runtime/opencl_core.hpp"
# include "opencv2/core.hpp"
# include "opencv2/core/ocl.hpp"
# include "opencl_kernels_core.hpp"
#else // HAVE_OPENCL
# define NO_OPENCL_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
#endif // HAVE_OPENCL
#if defined(HAVE_VAAPI) && defined(HAVE_OPENCL)
# include <CL/va_ext.h>
#endif // HAVE_VAAPI && HAVE_OPENCL
namespace
cv
{
namespace
vaapi
{
#if defined(HAVE_VAAPI) && defined(HAVE_OPENCL)
static
clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
=
NULL
;
static
clCreateFromVA_APIMediaSurfaceINTEL_fn
clCreateFromVA_APIMediaSurfaceINTEL
=
NULL
;
static
clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn
clEnqueueAcquireVA_APIMediaSurfacesINTEL
=
NULL
;
static
clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn
clEnqueueReleaseVA_APIMediaSurfacesINTEL
=
NULL
;
static
bool
contextInitialized
=
false
;
#endif // HAVE_VAAPI && HAVE_OPENCL
namespace
ocl
{
Context
&
initializeContextFromVA
(
VADisplay
display
)
{
(
void
)
display
;
#if !defined(HAVE_VAAPI)
NO_VAAPI_SUPPORT_ERROR
;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR
;
#else
contextInitialized
=
false
;
cl_uint
numPlatforms
;
cl_int
status
=
clGetPlatformIDs
(
0
,
NULL
,
&
numPlatforms
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Can't get number of platforms"
);
if
(
numPlatforms
==
0
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: No available platforms"
);
std
::
vector
<
cl_platform_id
>
platforms
(
numPlatforms
);
status
=
clGetPlatformIDs
(
numPlatforms
,
&
platforms
[
0
],
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Can't get platform Id list"
);
// For CL-VA interop, we must find platform/device with "cl_intel_va_api_media_sharing" extension.
// With standard initialization procedure, we should examine platform extension string for that.
// But in practice, the platform ext string doesn't contain it, while device ext string does.
// Follow Intel procedure (see tutorial), we should obtain device IDs by extension call.
// Note that we must obtain function pointers using specific platform ID, and can't provide pointers in advance.
// So, we iterate and select the first platform, for which we got non-NULL pointers, device, and CL context.
int
found
=
-
1
;
cl_context
context
=
0
;
cl_device_id
device
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
numPlatforms
;
++
i
)
{
// Get extension function pointers
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
=
(
clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clGetDeviceIDsFromVA_APIMediaAdapterINTEL"
);
clCreateFromVA_APIMediaSurfaceINTEL
=
(
clCreateFromVA_APIMediaSurfaceINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clCreateFromVA_APIMediaSurfaceINTEL"
);
clEnqueueAcquireVA_APIMediaSurfacesINTEL
=
(
clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clEnqueueAcquireVA_APIMediaSurfacesINTEL"
);
clEnqueueReleaseVA_APIMediaSurfacesINTEL
=
(
clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn
)
clGetExtensionFunctionAddressForPlatform
(
platforms
[
i
],
"clEnqueueReleaseVA_APIMediaSurfacesINTEL"
);
if
(((
void
*
)
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
==
NULL
)
||
((
void
*
)
clCreateFromVA_APIMediaSurfaceINTEL
==
NULL
)
||
((
void
*
)
clEnqueueAcquireVA_APIMediaSurfacesINTEL
==
NULL
)
||
((
void
*
)
clEnqueueReleaseVA_APIMediaSurfacesINTEL
==
NULL
))
{
continue
;
}
// Query device list
cl_uint
numDevices
=
0
;
status
=
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
(
platforms
[
i
],
CL_VA_API_DISPLAY_INTEL
,
display
,
CL_PREFERRED_DEVICES_FOR_VA_API_INTEL
,
0
,
NULL
,
&
numDevices
);
if
((
status
!=
CL_SUCCESS
)
||
!
(
numDevices
>
0
))
continue
;
numDevices
=
1
;
// initializeContextFromHandle() expects only 1 device
status
=
clGetDeviceIDsFromVA_APIMediaAdapterINTEL
(
platforms
[
i
],
CL_VA_API_DISPLAY_INTEL
,
display
,
CL_PREFERRED_DEVICES_FOR_VA_API_INTEL
,
numDevices
,
&
device
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
continue
;
// Creating CL-VA media sharing OpenCL context
cl_context_properties
props
[]
=
{
CL_CONTEXT_VA_API_DISPLAY_INTEL
,
(
cl_context_properties
)
display
,
CL_CONTEXT_INTEROP_USER_SYNC
,
CL_FALSE
,
// no explicit sync required
0
};
context
=
clCreateContext
(
props
,
numDevices
,
&
device
,
NULL
,
NULL
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
{
clReleaseDevice
(
device
);
}
else
{
found
=
i
;
break
;
}
}
if
(
found
<
0
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Can't create context for VA-API interop"
);
Context
&
ctx
=
Context
::
getDefault
(
false
);
initializeContextFromHandle
(
ctx
,
platforms
[
found
],
context
,
device
);
contextInitialized
=
true
;
return
ctx
;
#endif
}
#if defined(HAVE_VAAPI) && defined(HAVE_OPENCL)
static
bool
ocl_convert_nv12_to_bgr
(
cl_mem
clImageY
,
cl_mem
clImageUV
,
cl_mem
clBuffer
,
int
step
,
int
cols
,
int
rows
)
{
ocl
::
Kernel
k
;
k
.
create
(
"YUV2BGR_NV12_8u"
,
cv
::
ocl
::
core
::
cvtclr_dx_oclsrc
,
""
);
if
(
k
.
empty
())
return
false
;
k
.
args
(
clImageY
,
clImageUV
,
clBuffer
,
step
,
cols
,
rows
);
size_t
globalsize
[]
=
{
cols
,
rows
};
return
k
.
run
(
2
,
globalsize
,
0
,
false
);
}
static
bool
ocl_convert_bgr_to_nv12
(
cl_mem
clBuffer
,
int
step
,
int
cols
,
int
rows
,
cl_mem
clImageY
,
cl_mem
clImageUV
)
{
ocl
::
Kernel
k
;
k
.
create
(
"BGR2YUV_NV12_8u"
,
cv
::
ocl
::
core
::
cvtclr_dx_oclsrc
,
""
);
if
(
k
.
empty
())
return
false
;
k
.
args
(
clBuffer
,
step
,
cols
,
rows
,
clImageY
,
clImageUV
);
size_t
globalsize
[]
=
{
cols
,
rows
};
return
k
.
run
(
2
,
globalsize
,
0
,
false
);
}
#endif // HAVE_VAAPI && HAVE_OPENCL
}
// namespace cv::vaapi::ocl
void
convertToVASurface
(
InputArray
src
,
VASurfaceID
surface
,
Size
size
)
{
(
void
)
src
;
(
void
)
surface
;
(
void
)
size
;
#if !defined(HAVE_VAAPI)
NO_VAAPI_SUPPORT_ERROR
;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR
;
#else
if
(
!
contextInitialized
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Context for VA-API interop hasn't been created"
);
const
int
stype
=
CV_8UC4
;
int
srcType
=
src
.
type
();
CV_Assert
(
srcType
==
stype
);
Size
srcSize
=
src
.
size
();
CV_Assert
(
srcSize
.
width
==
size
.
width
&&
srcSize
.
height
==
size
.
height
);
UMat
u
=
src
.
getUMat
();
// TODO Add support for roi
CV_Assert
(
u
.
offset
==
0
);
CV_Assert
(
u
.
isContinuous
());
cl_mem
clBuffer
=
(
cl_mem
)
u
.
handle
(
ACCESS_READ
);
using
namespace
cv
::
ocl
;
Context
&
ctx
=
Context
::
getDefault
();
cl_context
context
=
(
cl_context
)
ctx
.
ptr
();
cl_int
status
=
0
;
cl_mem
clImageY
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_WRITE_ONLY
,
&
surface
,
0
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"
);
cl_mem
clImageUV
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_WRITE_ONLY
,
&
surface
,
1
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"
);
cl_command_queue
q
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
cl_mem
images
[
2
]
=
{
clImageY
,
clImageUV
};
status
=
clEnqueueAcquireVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"
);
if
(
!
ocl
::
ocl_convert_bgr_to_nv12
(
clBuffer
,
(
int
)
u
.
step
[
0
],
u
.
cols
,
u
.
rows
,
clImageY
,
clImageUV
))
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: ocl_convert_bgr_to_nv12 failed"
);
clEnqueueReleaseVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"
);
status
=
clFinish
(
q
);
// TODO Use events
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clFinish failed"
);
status
=
clReleaseMemObject
(
clImageY
);
// TODO RAII
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (Y plane)"
);
status
=
clReleaseMemObject
(
clImageUV
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (UV plane)"
);
#endif
}
void
convertFromVASurface
(
VASurfaceID
surface
,
Size
size
,
OutputArray
dst
)
{
(
void
)
surface
;
(
void
)
dst
;
(
void
)
size
;
#if !defined(HAVE_VAAPI)
NO_VAAPI_SUPPORT_ERROR
;
#elif !defined(HAVE_OPENCL)
NO_OPENCL_SUPPORT_ERROR
;
#else
if
(
!
contextInitialized
)
CV_Error
(
cv
::
Error
::
OpenCLInitError
,
"OpenCL: Context for VA-API interop hasn't been created"
);
const
int
dtype
=
CV_8UC4
;
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
dst
.
create
(
size
,
dtype
);
UMat
u
=
dst
.
getUMat
();
// TODO Add support for roi
CV_Assert
(
u
.
offset
==
0
);
CV_Assert
(
u
.
isContinuous
());
cl_mem
clBuffer
=
(
cl_mem
)
u
.
handle
(
ACCESS_WRITE
);
using
namespace
cv
::
ocl
;
Context
&
ctx
=
Context
::
getDefault
();
cl_context
context
=
(
cl_context
)
ctx
.
ptr
();
cl_int
status
=
0
;
cl_mem
clImageY
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_READ_ONLY
,
&
surface
,
0
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"
);
cl_mem
clImageUV
=
clCreateFromVA_APIMediaSurfaceINTEL
(
context
,
CL_MEM_READ_ONLY
,
&
surface
,
1
,
&
status
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"
);
cl_command_queue
q
=
(
cl_command_queue
)
Queue
::
getDefault
().
ptr
();
cl_mem
images
[
2
]
=
{
clImageY
,
clImageUV
};
status
=
clEnqueueAcquireVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"
);
if
(
!
ocl
::
ocl_convert_nv12_to_bgr
(
clImageY
,
clImageUV
,
clBuffer
,
(
int
)
u
.
step
[
0
],
u
.
cols
,
u
.
rows
))
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: ocl_convert_nv12_to_bgr failed"
);
status
=
clEnqueueReleaseVA_APIMediaSurfacesINTEL
(
q
,
2
,
images
,
0
,
NULL
,
NULL
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"
);
status
=
clFinish
(
q
);
// TODO Use events
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clFinish failed"
);
status
=
clReleaseMemObject
(
clImageY
);
// TODO RAII
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (Y plane)"
);
status
=
clReleaseMemObject
(
clImageUV
);
if
(
status
!=
CL_SUCCESS
)
CV_Error
(
cv
::
Error
::
OpenCLApiCallError
,
"OpenCL: clReleaseMem failed (UV plane)"
);
#endif
}
}}
// namespace cv::vaapi
samples/CMakeLists.txt
View file @
95339827
...
...
@@ -22,8 +22,8 @@ if((NOT ANDROID) AND HAVE_OPENGL)
add_subdirectory
(
opengl
)
endif
()
if
(
UNIX AND NOT ANDROID AND
HAVE_VAAPI
)
add_subdirectory
(
va
api
)
if
(
UNIX AND NOT ANDROID
AND
(
HAVE_VA OR HAVE_VA_INTEL
)
)
add_subdirectory
(
va
_intel
)
endif
()
if
(
ANDROID AND BUILD_ANDROID_EXAMPLES
)
...
...
samples/va
api
/CMakeLists.txt
→
samples/va
_intel
/CMakeLists.txt
View file @
95339827
SET
(
OPENCV_VA
API
_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_imgcodecs opencv_videoio opencv_highgui
)
SET
(
OPENCV_VA
_INTEL
_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_imgcodecs opencv_videoio opencv_highgui
)
ocv_check_dependencies
(
${
OPENCV_VA
API
_SAMPLES_REQUIRED_DEPS
}
)
ocv_check_dependencies
(
${
OPENCV_VA
_INTEL
_SAMPLES_REQUIRED_DEPS
}
)
if
(
BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND
)
set
(
project
"va
api
"
)
set
(
project
"va
_intel
"
)
string
(
TOUPPER
"
${
project
}
"
project_upper
)
project
(
"
${
project
}
_samples"
)
ocv_include_modules_recurse
(
${
OPENCV_VA
API
_SAMPLES_REQUIRED_DEPS
}
)
ocv_include_modules_recurse
(
${
OPENCV_VA
_INTEL
_SAMPLES_REQUIRED_DEPS
}
)
# ---------------------------------------------
# Define executable targets
# ---------------------------------------------
MACRO
(
OPENCV_DEFINE_VA
API
_EXAMPLE name srcs
)
MACRO
(
OPENCV_DEFINE_VA
_INTEL
_EXAMPLE name srcs
)
set
(
the_target
"example_
${
project
}
_
${
name
}
"
)
add_executable
(
${
the_target
}
${
srcs
}
)
ocv_target_link_libraries
(
${
the_target
}
${
OPENCV_LINKER_LIBS
}
${
OPENCV_VA
API_SAMPLES_REQUIRED_DEPS
}
${
VAAPI_EXTRA_LIB
S
}
)
ocv_target_link_libraries
(
${
the_target
}
${
OPENCV_LINKER_LIBS
}
${
OPENCV_VA
_INTEL_SAMPLES_REQUIRED_DEPS
}
${
VA_LIBRARIES
}
${
VA_INTEL_LIBRARIE
S
}
)
set_target_properties
(
${
the_target
}
PROPERTIES
OUTPUT_NAME
"
${
project
}
-example-
${
name
}
"
...
...
@@ -33,6 +33,6 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND)
foreach
(
sample_filename
${
all_samples
}
)
get_filename_component
(
sample
${
sample_filename
}
NAME_WE
)
file
(
GLOB sample_srcs RELATIVE
${
CMAKE_CURRENT_SOURCE_DIR
}
${
sample
}
.*
)
OPENCV_DEFINE_VA
API
_EXAMPLE
(
${
sample
}
${
sample_srcs
}
)
OPENCV_DEFINE_VA
_INTEL
_EXAMPLE
(
${
sample
}
${
sample_srcs
}
)
endforeach
()
endif
()
samples/va
api
/display.cpp.inc
→
samples/va
_intel
/display.cpp.inc
View file @
95339827
...
...
@@ -7,25 +7,39 @@
#include <sys/types.h>
#include <unistd.h>
#include <va/va.h>
#include <va/va_drm.h>
#include "cvconfig.h"
#define VAAPI_PCI_DIR "/sys/bus/pci/devices"
#define VAAPI_DRI_DIR "/dev/dri/"
#define VAAPI_PCI_DISPLAY_CONTROLLER_CLASS 0x03
#include <va/va.h>
#if defined(HAVE_VA_INTEL)
# include <va/va_drm.h>
#elif defined(HAVE_VA)
# include <va/va_x11.h>
# include <X11/Xlib.h>
#endif //HAVE_VA_INTEL / HAVE_VA
namespace
va
{
static
unsigned
readId
(
const
char
*
devName
,
const
char
*
idName
);
static
int
findAdapter
(
unsigned
desiredVendorId
);
#if defined(HAVE_VA_INTEL) || defined(HAVE_VA)
bool
openDisplay
();
void
closeDisplay
();
int
drmfd
=
-
1
;
VADisplay
display
=
NULL
;
bool
initialized
=
false
;
#endif //HAVE_VA_INTEL || HAVE_VA
#if defined(HAVE_VA_INTEL)
#define VA_INTEL_PCI_DIR "/sys/bus/pci/devices"
#define VA_INTEL_DRI_DIR "/dev/dri/"
#define VA_INTEL_PCI_DISPLAY_CONTROLLER_CLASS 0x03
static
unsigned
readId
(
const
char
*
devName
,
const
char
*
idName
);
static
int
findAdapter
(
unsigned
desiredVendorId
);
int
drmfd
=
-
1
;
class
Directory
{
typedef
int
(
*
fsort
)(
const
struct
dirent
**
,
const
struct
dirent
**
);
...
...
@@ -70,7 +84,7 @@ static unsigned readId(const char* devName, const char* idName)
long
int
id
=
0
;
char
fileName
[
256
];
snprintf
(
fileName
,
sizeof
(
fileName
),
"%s/%s/%s"
,
VA
API
_PCI_DIR
,
devName
,
idName
);
snprintf
(
fileName
,
sizeof
(
fileName
),
"%s/%s/%s"
,
VA
_INTEL
_PCI_DIR
,
devName
,
idName
);
FILE
*
file
=
fopen
(
fileName
,
"r"
);
if
(
file
)
...
...
@@ -88,14 +102,14 @@ static int findAdapter(unsigned desiredVendorId)
int
adapterIndex
=
-
1
;
int
numAdapters
=
0
;
Directory
dir
(
VA
API
_PCI_DIR
);
Directory
dir
(
VA
_INTEL
_PCI_DIR
);
for
(
int
i
=
0
;
i
<
dir
.
count
();
++
i
)
{
const
char
*
name
=
dir
[
i
]
->
d_name
;
unsigned
classId
=
readId
(
name
,
"class"
);
if
((
classId
>>
16
)
==
VA
API
_PCI_DISPLAY_CONTROLLER_CLASS
)
if
((
classId
>>
16
)
==
VA
_INTEL
_PCI_DISPLAY_CONTROLLER_CLASS
)
{
unsigned
vendorId
=
readId
(
name
,
"vendor"
);
if
(
vendorId
==
desiredVendorId
)
...
...
@@ -122,9 +136,9 @@ public:
numbers
[
1
]
=
adapterIndex
;
for
(
int
i
=
0
;
i
<
NUM_NODES
;
++
i
)
{
int
sz
=
sizeof
(
VA
API
_DRI_DIR
)
+
strlen
(
names
[
i
])
+
3
;
int
sz
=
sizeof
(
VA
_INTEL
_DRI_DIR
)
+
strlen
(
names
[
i
])
+
3
;
paths
[
i
]
=
new
char
[
sz
];
snprintf
(
paths
[
i
],
sz
,
"%s%s%d"
,
VA
API
_DRI_DIR
,
names
[
i
],
numbers
[
i
]);
snprintf
(
paths
[
i
],
sz
,
"%s%s%d"
,
VA
_INTEL
_DRI_DIR
,
names
[
i
],
numbers
[
i
]);
}
}
~
NodeInfo
()
...
...
@@ -205,4 +219,53 @@ void closeDisplay()
}
}
#elif defined(HAVE_VA)
static
Display
*
x11Display
=
0
;
bool
openDisplay
()
{
if
(
!
initialized
)
{
display
=
0
;
x11Display
=
XOpenDisplay
(
""
);
if
(
x11Display
!=
0
)
{
display
=
vaGetDisplay
(
x11Display
);
if
(
display
)
{
int
majorVersion
=
0
,
minorVersion
=
0
;
if
(
vaInitialize
(
display
,
&
majorVersion
,
&
minorVersion
)
==
VA_STATUS_SUCCESS
)
{
initialized
=
true
;
return
true
;
}
display
=
0
;
}
XCloseDisplay
(
x11Display
);
x11Display
=
0
;
}
return
false
;
// Can't initialize X11/VA display
}
return
true
;
}
void
closeDisplay
()
{
if
(
initialized
)
{
if
(
display
)
vaTerminate
(
display
);
if
(
x11Display
)
XCloseDisplay
(
x11Display
);
display
=
0
;
x11Display
=
0
;
initialized
=
false
;
}
}
#endif // HAVE_VA_INTEL / HAVE_VA
}
// namespace va
samples/va
api/vaapi
_interop.cpp
→
samples/va
_intel/va_intel
_interop.cpp
View file @
95339827
...
...
@@ -24,6 +24,8 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
...
...
@@ -39,11 +41,12 @@
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/vaapi.hpp"
#include "opencv2/core/va_intel.hpp"
#include "cvconfig.h"
#define CHECK_VASTATUS(va_status,func) \
if (va_status != VA_STATUS_SUCCESS) { \
fprintf(stderr,"%s:%s (%d) failed
,exit\n", __func__, func, __LINE__
); \
fprintf(stderr,"%s:%s (%d) failed
(status=0x%08x),exit\n", __func__, func, __LINE__, va_status
); \
exit(1); \
}
...
...
@@ -129,7 +132,55 @@ static VASliceParameterBufferMPEG2 slice_param={
#define CLIP_WIDTH 16
#define CLIP_HEIGHT 16
static
void
dumpSurface
(
VADisplay
display
,
VASurfaceID
surface_id
,
const
char
*
fileName
)
class
Timer
{
public
:
enum
UNITS
{
USEC
=
0
,
MSEC
,
SEC
};
Timer
()
:
m_t0
(
0
),
m_diff
(
0
)
{
m_tick_frequency
=
(
float
)
cv
::
getTickFrequency
();
m_unit_mul
[
USEC
]
=
1000000
;
m_unit_mul
[
MSEC
]
=
1000
;
m_unit_mul
[
SEC
]
=
1
;
}
void
clear
()
{
m_t0
=
m_diff
=
0
;
}
void
start
()
{
m_t0
=
cv
::
getTickCount
();
}
void
stop
()
{
m_diff
=
cv
::
getTickCount
()
-
m_t0
;
}
float
time
(
UNITS
u
=
MSEC
)
{
float
sec
=
m_diff
/
m_tick_frequency
;
return
sec
*
m_unit_mul
[
u
];
}
public
:
float
m_tick_frequency
;
int64
m_t0
;
int64
m_diff
;
int
m_unit_mul
[
3
];
};
static
void
dumpSurface
(
VADisplay
display
,
VASurfaceID
surface_id
,
const
char
*
fileName
,
bool
doInterop
)
{
VAStatus
va_status
;
...
...
@@ -153,7 +204,8 @@ static void dumpSurface(VADisplay display, VASurfaceID surface_id, const char* f
printf("image.pitches[0..2] = 0x%08x 0x%08x 0x%08x\n", image.pitches[0], image.pitches[1], image.pitches[2]);
printf("image.offsets[0..2] = 0x%08x 0x%08x 0x%08x\n", image.offsets[0], image.offsets[1], image.offsets[2]);
*/
FILE
*
out
=
fopen
(
fileName
,
"wb"
);
std
::
string
fn
=
std
::
string
(
fileName
)
+
std
::
string
(
doInterop
?
".on"
:
".off"
);
FILE
*
out
=
fopen
(
fn
.
c_str
(),
"wb"
);
if
(
!
out
)
{
perror
(
fileName
);
...
...
@@ -169,10 +221,8 @@ static void dumpSurface(VADisplay display, VASurfaceID surface_id, const char* f
CHECK_VASTATUS
(
va_status
,
"vaDestroyImage"
);
}
int
main
(
int
argc
,
char
**
argv
)
static
float
run
(
const
char
*
fn1
,
const
char
*
fn2
,
bool
doInterop
)
{
(
void
)
argc
;
(
void
)
argv
;
VAEntrypoint
entrypoints
[
5
];
int
num_entrypoints
,
vld_entrypoint
;
VAConfigAttrib
attrib
;
...
...
@@ -181,24 +231,9 @@ int main(int argc,char **argv)
VAContextID
context_id
;
VABufferID
pic_param_buf
,
iqmatrix_buf
,
slice_param_buf
,
slice_data_buf
;
VAStatus
va_status
;
Timer
t
;
if
(
argc
<
3
)
{
fprintf
(
stderr
,
"Usage: vaapi_interop file1 file2
\n\n
"
"where: file1 is to be created, contains original surface data (NV12)
\n
"
" file2 is to be created, contains processed surface data (NV12)
\n
"
);
exit
(
0
);
}
if
(
!
va
::
openDisplay
())
{
fprintf
(
stderr
,
"Failed to open VA display for CL-VA interoperability
\n
"
);
exit
(
1
);
}
fprintf
(
stderr
,
"VA display opened successfully
\n
"
);
cv
::
vaapi
::
ocl
::
initializeContextFromVA
(
va
::
display
);
cv
::
va_intel
::
ocl
::
initializeContextFromVA
(
va
::
display
,
doInterop
);
va_status
=
vaQueryConfigEntrypoints
(
va
::
display
,
VAProfileMPEG2Main
,
entrypoints
,
&
num_entrypoints
);
...
...
@@ -294,22 +329,113 @@ int main(int argc,char **argv)
va_status
=
vaSyncSurface
(
va
::
display
,
surface_id
);
CHECK_VASTATUS
(
va_status
,
"vaSyncSurface"
);
dumpSurface
(
va
::
display
,
surface_id
,
argv
[
1
]
);
dumpSurface
(
va
::
display
,
surface_id
,
fn1
,
doInterop
);
cv
::
Size
size
(
CLIP_WIDTH
,
CLIP_HEIGHT
);
cv
::
UMat
u
;
cv
::
vaapi
::
convertFromVASurface
(
surface_id
,
size
,
u
);
cv
::
va_intel
::
convertFromVASurface
(
va
::
display
,
surface_id
,
size
,
u
);
cv
::
blur
(
u
,
u
,
cv
::
Size
(
7
,
7
),
cv
::
Point
(
-
3
,
-
3
));
cv
::
va_intel
::
convertToVASurface
(
va
::
display
,
u
,
surface_id
,
size
);
t
.
start
();
cv
::
va_intel
::
convertFromVASurface
(
va
::
display
,
surface_id
,
size
,
u
);
cv
::
blur
(
u
,
u
,
cv
::
Size
(
7
,
7
),
cv
::
Point
(
-
3
,
-
3
));
cv
::
vaapi
::
convertToVASurface
(
u
,
surface_id
,
size
);
cv
::
va_intel
::
convertToVASurface
(
va
::
display
,
u
,
surface_id
,
size
);
t
.
stop
();
dumpSurface
(
va
::
display
,
surface_id
,
argv
[
2
]
);
dumpSurface
(
va
::
display
,
surface_id
,
fn2
,
doInterop
);
vaDestroySurfaces
(
va
::
display
,
&
surface_id
,
1
);
vaDestroyConfig
(
va
::
display
,
config_id
);
vaDestroyContext
(
va
::
display
,
context_id
);
vaTerminate
(
va
::
display
);
return
t
.
time
(
Timer
::
MSEC
);
}
class
CmdlineParser
{
public
:
CmdlineParser
(
int
argc
,
char
**
argv
)
:
m_argc
(
argc
),
m_argv
(
argv
)
{}
// true => go, false => usage/exit; extra args/unknown options are ignored for simplicity
bool
run
()
{
int
n
=
0
;
m_files
[
0
]
=
m_files
[
1
]
=
0
;
#if defined(HAVE_VA_INTEL)
m_interop
=
true
;
#elif defined(HAVE_VA)
m_interop
=
false
;
#endif //HAVE_VA_INTEL / HAVE_VA
for
(
int
i
=
1
;
i
<
m_argc
;
++
i
)
{
const
char
*
arg
=
m_argv
[
i
];
if
(
arg
[
0
]
==
'-'
)
// option
{
#if defined(HAVE_VA_INTEL)
if
(
!
strcmp
(
arg
,
"-f"
))
m_interop
=
false
;
#endif //HAVE_VA_INTEL
}
else
// parameter
{
if
(
n
<
2
)
m_files
[
n
++
]
=
arg
;
}
}
return
bool
(
n
>=
2
);
}
bool
isInterop
()
const
{
return
m_interop
;
}
const
char
*
getFile
(
int
n
)
const
{
return
((
n
>=
0
)
&&
(
n
<
2
))
?
m_files
[
n
]
:
0
;
}
private
:
int
m_argc
;
char
**
m_argv
;
const
char
*
m_files
[
2
];
bool
m_interop
;
};
int
main
(
int
argc
,
char
**
argv
)
{
CmdlineParser
cmd
(
argc
,
argv
);
if
(
!
cmd
.
run
())
{
fprintf
(
stderr
,
#if defined(HAVE_VA_INTEL)
"Usage: va_intel_interop [-f] file1 file2
\n\n
"
"Interop ON/OFF version
\n\n
"
"where: -f option indicates interop is off (fallback mode); interop is on by default
\n
"
#elif defined(HAVE_VA)
"Usage: va_intel_interop file1 file2
\n\n
"
"Interop OFF only version
\n\n
"
"where:
\n
"
#endif //HAVE_VA_INTEL / HAVE_VA
" file1 is to be created, contains original surface data (NV12)
\n
"
" file2 is to be created, contains processed surface data (NV12)
\n
"
);
exit
(
0
);
}
if
(
!
va
::
openDisplay
())
{
fprintf
(
stderr
,
"Failed to open VA display for CL-VA interoperability
\n
"
);
exit
(
1
);
}
fprintf
(
stderr
,
"VA display opened successfully
\n
"
);
const
char
*
file0
=
cmd
.
getFile
(
0
);
const
char
*
file1
=
cmd
.
getFile
(
1
);
bool
doInterop
=
cmd
.
isInterop
();
float
time
=
run
(
file0
,
file1
,
doInterop
);
fprintf
(
stderr
,
"Interop %s: processing time, msec: %7.3f
\n
"
,
(
doInterop
?
"ON "
:
"OFF"
),
time
);
va
::
closeDisplay
();
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment