Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
va_intel.cpp
00001 // This file is part of OpenCV project. 00002 // It is subject to the license terms in the LICENSE file found in the top-level directory 00003 // of this distribution and at http://opencv.org/license.html. 00004 00005 // Copyright (C) 2015, Itseez, Inc., all rights reserved. 00006 // Third party copyrights are property of their respective owners. 00007 00008 #include "precomp.hpp" 00009 00010 #ifdef HAVE_VA 00011 # include <va/va.h> 00012 #else // HAVE_VA 00013 # define NO_VA_SUPPORT_ERROR CV_ErrorNoReturn(cv::Error::StsBadFunc, "OpenCV was build without VA support (libva)") 00014 #endif // HAVE_VA 00015 00016 using namespace cv; 00017 00018 //////////////////////////////////////////////////////////////////////// 00019 // CL-VA Interoperability 00020 00021 #ifdef HAVE_OPENCL 00022 # include "opencv2/core/opencl/runtime/opencl_core.hpp" 00023 # include "opencv2/core.hpp" 00024 # include "opencv2/core/ocl.hpp" 00025 # include "opencl_kernels_core.hpp" 00026 #endif // HAVE_OPENCL 00027 00028 #if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) 00029 # include <CL/va_ext.h> 00030 #endif // HAVE_VA_INTEL && HAVE_OPENCL 00031 00032 namespace cv { namespace va_intel { 00033 00034 #if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) 00035 00036 static clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn clGetDeviceIDsFromVA_APIMediaAdapterINTEL = NULL; 00037 static clCreateFromVA_APIMediaSurfaceINTEL_fn clCreateFromVA_APIMediaSurfaceINTEL = NULL; 00038 static clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn clEnqueueAcquireVA_APIMediaSurfacesINTEL = NULL; 00039 static clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn clEnqueueReleaseVA_APIMediaSurfacesINTEL = NULL; 00040 00041 static bool contextInitialized = false; 00042 00043 #endif // HAVE_VA_INTEL && HAVE_OPENCL 00044 00045 namespace ocl { 00046 00047 cv::ocl::Context& initializeContextFromVA(VADisplay display, bool tryInterop) 00048 { 00049 (void)display; (void)tryInterop; 00050 #if !defined(HAVE_VA) 00051 NO_VA_SUPPORT_ERROR; 00052 #else // !HAVE_VA 00053 # if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) 00054 contextInitialized = false; 00055 if (tryInterop) 00056 { 00057 cl_uint numPlatforms; 00058 cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); 00059 if (status != CL_SUCCESS) 00060 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms"); 00061 if (numPlatforms == 0) 00062 CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms"); 00063 00064 std::vector<cl_platform_id> platforms(numPlatforms); 00065 status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL); 00066 if (status != CL_SUCCESS) 00067 CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get platform Id list"); 00068 00069 // For CL-VA interop, we must find platform/device with "cl_intel_va_api_media_sharing" extension. 00070 // With standard initialization procedure, we should examine platform extension string for that. 00071 // But in practice, the platform ext string doesn't contain it, while device ext string does. 00072 // Follow Intel procedure (see tutorial), we should obtain device IDs by extension call. 00073 // Note that we must obtain function pointers using specific platform ID, and can't provide pointers in advance. 00074 // So, we iterate and select the first platform, for which we got non-NULL pointers, device, and CL context. 00075 00076 int found = -1; 00077 cl_context context = 0; 00078 cl_device_id device = 0; 00079 00080 for (int i = 0; i < (int)numPlatforms; ++i) 00081 { 00082 // Get extension function pointers 00083 00084 clGetDeviceIDsFromVA_APIMediaAdapterINTEL = (clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn) 00085 clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromVA_APIMediaAdapterINTEL"); 00086 clCreateFromVA_APIMediaSurfaceINTEL = (clCreateFromVA_APIMediaSurfaceINTEL_fn) 00087 clGetExtensionFunctionAddressForPlatform(platforms[i], "clCreateFromVA_APIMediaSurfaceINTEL"); 00088 clEnqueueAcquireVA_APIMediaSurfacesINTEL = (clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn) 00089 clGetExtensionFunctionAddressForPlatform(platforms[i], "clEnqueueAcquireVA_APIMediaSurfacesINTEL"); 00090 clEnqueueReleaseVA_APIMediaSurfacesINTEL = (clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn) 00091 clGetExtensionFunctionAddressForPlatform(platforms[i], "clEnqueueReleaseVA_APIMediaSurfacesINTEL"); 00092 00093 if (((void*)clGetDeviceIDsFromVA_APIMediaAdapterINTEL == NULL) || 00094 ((void*)clCreateFromVA_APIMediaSurfaceINTEL == NULL) || 00095 ((void*)clEnqueueAcquireVA_APIMediaSurfacesINTEL == NULL) || 00096 ((void*)clEnqueueReleaseVA_APIMediaSurfacesINTEL == NULL)) 00097 { 00098 continue; 00099 } 00100 00101 // Query device list 00102 00103 cl_uint numDevices = 0; 00104 00105 status = clGetDeviceIDsFromVA_APIMediaAdapterINTEL(platforms[i], CL_VA_API_DISPLAY_INTEL, display, 00106 CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, 0, NULL, &numDevices); 00107 if ((status != CL_SUCCESS) || !(numDevices > 0)) 00108 continue; 00109 numDevices = 1; // initializeContextFromHandle() expects only 1 device 00110 status = clGetDeviceIDsFromVA_APIMediaAdapterINTEL(platforms[i], CL_VA_API_DISPLAY_INTEL, display, 00111 CL_PREFERRED_DEVICES_FOR_VA_API_INTEL, numDevices, &device, NULL); 00112 if (status != CL_SUCCESS) 00113 continue; 00114 00115 // Creating CL-VA media sharing OpenCL context 00116 00117 cl_context_properties props[] = { 00118 CL_CONTEXT_VA_API_DISPLAY_INTEL, (cl_context_properties) display, 00119 CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, // no explicit sync required 00120 0 00121 }; 00122 00123 context = clCreateContext(props, numDevices, &device, NULL, NULL, &status); 00124 if (status != CL_SUCCESS) 00125 { 00126 clReleaseDevice(device); 00127 } 00128 else 00129 { 00130 found = i; 00131 break; 00132 } 00133 } 00134 00135 if (found >= 0) 00136 { 00137 contextInitialized = true; 00138 Context& ctx = Context::getDefault(false); 00139 initializeContextFromHandle(ctx, platforms[found], context, device); 00140 return ctx; 00141 } 00142 } 00143 # endif // HAVE_VA_INTEL && HAVE_OPENCL 00144 { 00145 Context& ctx = Context::getDefault(true); 00146 return ctx; 00147 } 00148 #endif // !HAVE_VA 00149 } 00150 00151 #if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) 00152 static bool ocl_convert_nv12_to_bgr(cl_mem clImageY, cl_mem clImageUV, cl_mem clBuffer, int step, int cols, int rows) 00153 { 00154 ocl::Kernel k; 00155 k.create("YUV2BGR_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, ""); 00156 if (k.empty()) 00157 return false; 00158 00159 k.args(clImageY, clImageUV, clBuffer, step, cols, rows); 00160 00161 size_t globalsize[] = { (size_t)cols, (size_t)rows }; 00162 return k.run(2, globalsize, 0, false); 00163 } 00164 00165 static bool ocl_convert_bgr_to_nv12(cl_mem clBuffer, int step, int cols, int rows, cl_mem clImageY, cl_mem clImageUV) 00166 { 00167 ocl::Kernel k; 00168 k.create("BGR2YUV_NV12_8u", cv::ocl::core::cvtclr_dx_oclsrc, ""); 00169 if (k.empty()) 00170 return false; 00171 00172 k.args(clBuffer, step, cols, rows, clImageY, clImageUV); 00173 00174 size_t globalsize[] = { (size_t)cols, (size_t)rows }; 00175 return k.run(2, globalsize, 0, false); 00176 } 00177 #endif // HAVE_VA_INTEL && HAVE_OPENCL 00178 00179 } // namespace cv::va_intel::ocl 00180 00181 #if defined(HAVE_VA) 00182 const int NCHANNELS = 3; 00183 00184 static void copy_convert_nv12_to_bgr(const VAImage& image, const unsigned char* buffer, Mat& bgr) 00185 { 00186 const float d1 = 16.0f; 00187 const float d2 = 128.0f; 00188 00189 static const float coeffs[5] = 00190 { 00191 1.163999557f, 00192 2.017999649f, 00193 -0.390999794f, 00194 -0.812999725f, 00195 1.5959997177f 00196 }; 00197 00198 const size_t srcOffsetY = image.offsets[0]; 00199 const size_t srcOffsetUV = image.offsets[1]; 00200 00201 const size_t srcStepY = image.pitches[0]; 00202 const size_t srcStepUV = image.pitches[1]; 00203 00204 const size_t dstStep = bgr.step; 00205 00206 const unsigned char* srcY0 = buffer + srcOffsetY; 00207 const unsigned char* srcUV = buffer + srcOffsetUV; 00208 00209 unsigned char* dst0 = bgr.data; 00210 00211 for (int y = 0; y < bgr.rows; y += 2) 00212 { 00213 const unsigned char* srcY1 = srcY0 + srcStepY; 00214 unsigned char *dst1 = dst0 + dstStep; 00215 00216 for (int x = 0; x < bgr.cols; x += 2) 00217 { 00218 float Y0 = float(srcY0[x+0]); 00219 float Y1 = float(srcY0[x+1]); 00220 float Y2 = float(srcY1[x+0]); 00221 float Y3 = float(srcY1[x+1]); 00222 00223 float U = float(srcUV[2*(x/2)+0]) - d2; 00224 float V = float(srcUV[2*(x/2)+1]) - d2; 00225 00226 Y0 = std::max(0.0f, Y0 - d1) * coeffs[0]; 00227 Y1 = std::max(0.0f, Y1 - d1) * coeffs[0]; 00228 Y2 = std::max(0.0f, Y2 - d1) * coeffs[0]; 00229 Y3 = std::max(0.0f, Y3 - d1) * coeffs[0]; 00230 00231 float ruv = coeffs[4]*V; 00232 float guv = coeffs[3]*V + coeffs[2]*U; 00233 float buv = coeffs[1]*U; 00234 00235 dst0[(x+0)*NCHANNELS+0] = saturate_cast<unsigned char>(Y0 + buv); 00236 dst0[(x+0)*NCHANNELS+1] = saturate_cast<unsigned char>(Y0 + guv); 00237 dst0[(x+0)*NCHANNELS+2] = saturate_cast<unsigned char>(Y0 + ruv); 00238 00239 dst0[(x+1)*NCHANNELS+0] = saturate_cast<unsigned char>(Y1 + buv); 00240 dst0[(x+1)*NCHANNELS+1] = saturate_cast<unsigned char>(Y1 + guv); 00241 dst0[(x+1)*NCHANNELS+2] = saturate_cast<unsigned char>(Y1 + ruv); 00242 00243 dst1[(x+0)*NCHANNELS+0] = saturate_cast<unsigned char>(Y2 + buv); 00244 dst1[(x+0)*NCHANNELS+1] = saturate_cast<unsigned char>(Y2 + guv); 00245 dst1[(x+0)*NCHANNELS+2] = saturate_cast<unsigned char>(Y2 + ruv); 00246 00247 dst1[(x+1)*NCHANNELS+0] = saturate_cast<unsigned char>(Y3 + buv); 00248 dst1[(x+1)*NCHANNELS+1] = saturate_cast<unsigned char>(Y3 + guv); 00249 dst1[(x+1)*NCHANNELS+2] = saturate_cast<unsigned char>(Y3 + ruv); 00250 } 00251 00252 srcY0 = srcY1 + srcStepY; 00253 srcUV += srcStepUV; 00254 dst0 = dst1 + dstStep; 00255 } 00256 } 00257 00258 static void copy_convert_bgr_to_nv12(const VAImage& image, const Mat& bgr, unsigned char* buffer) 00259 { 00260 const float d1 = 16.0f; 00261 const float d2 = 128.0f; 00262 00263 static const float coeffs[8] = 00264 { 00265 0.256999969f, 0.50399971f, 0.09799957f, -0.1479988098f, 00266 -0.2909994125f, 0.438999176f, -0.3679990768f, -0.0709991455f 00267 }; 00268 00269 const size_t dstOffsetY = image.offsets[0]; 00270 const size_t dstOffsetUV = image.offsets[1]; 00271 00272 const size_t dstStepY = image.pitches[0]; 00273 const size_t dstStepUV = image.pitches[1]; 00274 00275 const size_t srcStep = bgr.step; 00276 00277 const unsigned char* src0 = bgr.data; 00278 00279 unsigned char* dstY0 = buffer + dstOffsetY; 00280 unsigned char* dstUV = buffer + dstOffsetUV; 00281 00282 for (int y = 0; y < bgr.rows; y += 2) 00283 { 00284 const unsigned char *src1 = src0 + srcStep; 00285 unsigned char* dstY1 = dstY0 + dstStepY; 00286 00287 for (int x = 0; x < bgr.cols; x += 2) 00288 { 00289 float B0 = float(src0[(x+0)*NCHANNELS+0]); 00290 float G0 = float(src0[(x+0)*NCHANNELS+1]); 00291 float R0 = float(src0[(x+0)*NCHANNELS+2]); 00292 00293 float B1 = float(src0[(x+1)*NCHANNELS+0]); 00294 float G1 = float(src0[(x+1)*NCHANNELS+1]); 00295 float R1 = float(src0[(x+1)*NCHANNELS+2]); 00296 00297 float B2 = float(src1[(x+0)*NCHANNELS+0]); 00298 float G2 = float(src1[(x+0)*NCHANNELS+1]); 00299 float R2 = float(src1[(x+0)*NCHANNELS+2]); 00300 00301 float B3 = float(src1[(x+1)*NCHANNELS+0]); 00302 float G3 = float(src1[(x+1)*NCHANNELS+1]); 00303 float R3 = float(src1[(x+1)*NCHANNELS+2]); 00304 00305 float Y0 = coeffs[0]*R0 + coeffs[1]*G0 + coeffs[2]*B0 + d1; 00306 float Y1 = coeffs[0]*R1 + coeffs[1]*G1 + coeffs[2]*B1 + d1; 00307 float Y2 = coeffs[0]*R2 + coeffs[1]*G2 + coeffs[2]*B2 + d1; 00308 float Y3 = coeffs[0]*R3 + coeffs[1]*G3 + coeffs[2]*B3 + d1; 00309 00310 float U = coeffs[3]*R0 + coeffs[4]*G0 + coeffs[5]*B0 + d2; 00311 float V = coeffs[5]*R0 + coeffs[6]*G0 + coeffs[7]*B0 + d2; 00312 00313 dstY0[x+0] = saturate_cast<unsigned char>(Y0); 00314 dstY0[x+1] = saturate_cast<unsigned char>(Y1); 00315 dstY1[x+0] = saturate_cast<unsigned char>(Y2); 00316 dstY1[x+1] = saturate_cast<unsigned char>(Y3); 00317 00318 dstUV[2*(x/2)+0] = saturate_cast<unsigned char>(U); 00319 dstUV[2*(x/2)+1] = saturate_cast<unsigned char>(V); 00320 } 00321 00322 src0 = src1 + srcStep; 00323 dstY0 = dstY1 + dstStepY; 00324 dstUV += dstStepUV; 00325 } 00326 } 00327 #endif // HAVE_VA 00328 00329 void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface, Size size) 00330 { 00331 (void)display; (void)src; (void)surface; (void)size; 00332 #if !defined(HAVE_VA) 00333 NO_VA_SUPPORT_ERROR; 00334 #else // !HAVE_VA 00335 const int stype = CV_8UC3; 00336 00337 int srcType = src.type(); 00338 CV_Assert(srcType == stype); 00339 00340 Size srcSize = src.size(); 00341 CV_Assert(srcSize.width == size.width && srcSize.height == size.height); 00342 00343 # if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) 00344 if (contextInitialized) 00345 { 00346 UMat u = src.getUMat(); 00347 00348 // TODO Add support for roi 00349 CV_Assert(u.offset == 0); 00350 CV_Assert(u.isContinuous()); 00351 00352 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ); 00353 00354 using namespace cv::ocl; 00355 Context& ctx = Context::getDefault(); 00356 cl_context context = (cl_context)ctx.ptr(); 00357 00358 cl_int status = 0; 00359 00360 cl_mem clImageY = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_WRITE_ONLY, &surface, 0, &status); 00361 if (status != CL_SUCCESS) 00362 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"); 00363 cl_mem clImageUV = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_WRITE_ONLY, &surface, 1, &status); 00364 if (status != CL_SUCCESS) 00365 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"); 00366 00367 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 00368 00369 cl_mem images[2] = { clImageY, clImageUV }; 00370 status = clEnqueueAcquireVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); 00371 if (status != CL_SUCCESS) 00372 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"); 00373 if (!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImageY, clImageUV)) 00374 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed"); 00375 clEnqueueReleaseVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); 00376 if (status != CL_SUCCESS) 00377 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"); 00378 00379 status = clFinish(q); // TODO Use events 00380 if (status != CL_SUCCESS) 00381 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 00382 00383 status = clReleaseMemObject(clImageY); // TODO RAII 00384 if (status != CL_SUCCESS) 00385 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (Y plane)"); 00386 status = clReleaseMemObject(clImageUV); 00387 if (status != CL_SUCCESS) 00388 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)"); 00389 } 00390 else 00391 # endif // HAVE_VA_INTEL && HAVE_OPENCL 00392 { 00393 Mat m = src.getMat(); 00394 00395 // TODO Add support for roi 00396 CV_Assert(m.data == m.datastart); 00397 CV_Assert(m.isContinuous()); 00398 00399 VAStatus status = 0; 00400 00401 status = vaSyncSurface(display, surface); 00402 if (status != VA_STATUS_SUCCESS) 00403 CV_Error(cv::Error::StsError, "VA-API: vaSyncSurface failed"); 00404 00405 VAImage image; 00406 status = vaDeriveImage(display, surface, &image); 00407 if (status != VA_STATUS_SUCCESS) 00408 CV_Error(cv::Error::StsError, "VA-API: vaDeriveImage failed"); 00409 00410 unsigned char* buffer = 0; 00411 status = vaMapBuffer(display, image.buf, (void **)&buffer); 00412 if (status != VA_STATUS_SUCCESS) 00413 CV_Error(cv::Error::StsError, "VA-API: vaMapBuffer failed"); 00414 00415 CV_Assert(image.format.fourcc == VA_FOURCC_NV12); 00416 00417 copy_convert_bgr_to_nv12(image, m, buffer); 00418 00419 status = vaUnmapBuffer(display, image.buf); 00420 if (status != VA_STATUS_SUCCESS) 00421 CV_Error(cv::Error::StsError, "VA-API: vaUnmapBuffer failed"); 00422 00423 status = vaDestroyImage(display, image.image_id); 00424 if (status != VA_STATUS_SUCCESS) 00425 CV_Error(cv::Error::StsError, "VA-API: vaDestroyImage failed"); 00426 } 00427 #endif // !HAVE_VA 00428 } 00429 00430 void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, OutputArray dst) 00431 { 00432 (void)display; (void)surface; (void)dst; (void)size; 00433 #if !defined(HAVE_VA) 00434 NO_VA_SUPPORT_ERROR; 00435 #else // !HAVE_VA 00436 const int dtype = CV_8UC3; 00437 00438 // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! 00439 dst.create(size, dtype); 00440 00441 # if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) 00442 if (contextInitialized) 00443 { 00444 UMat u = dst.getUMat(); 00445 00446 // TODO Add support for roi 00447 CV_Assert(u.offset == 0); 00448 CV_Assert(u.isContinuous()); 00449 00450 cl_mem clBuffer = (cl_mem)u.handle(ACCESS_WRITE); 00451 00452 using namespace cv::ocl; 00453 Context& ctx = Context::getDefault(); 00454 cl_context context = (cl_context)ctx.ptr(); 00455 00456 cl_int status = 0; 00457 00458 cl_mem clImageY = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_READ_ONLY, &surface, 0, &status); 00459 if (status != CL_SUCCESS) 00460 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (Y plane)"); 00461 cl_mem clImageUV = clCreateFromVA_APIMediaSurfaceINTEL(context, CL_MEM_READ_ONLY, &surface, 1, &status); 00462 if (status != CL_SUCCESS) 00463 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromVA_APIMediaSurfaceINTEL failed (UV plane)"); 00464 00465 cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr(); 00466 00467 cl_mem images[2] = { clImageY, clImageUV }; 00468 status = clEnqueueAcquireVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); 00469 if (status != CL_SUCCESS) 00470 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireVA_APIMediaSurfacesINTEL failed"); 00471 if (!ocl::ocl_convert_nv12_to_bgr(clImageY, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows)) 00472 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed"); 00473 status = clEnqueueReleaseVA_APIMediaSurfacesINTEL(q, 2, images, 0, NULL, NULL); 00474 if (status != CL_SUCCESS) 00475 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseVA_APIMediaSurfacesINTEL failed"); 00476 00477 status = clFinish(q); // TODO Use events 00478 if (status != CL_SUCCESS) 00479 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed"); 00480 00481 status = clReleaseMemObject(clImageY); // TODO RAII 00482 if (status != CL_SUCCESS) 00483 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (Y plane)"); 00484 status = clReleaseMemObject(clImageUV); 00485 if (status != CL_SUCCESS) 00486 CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)"); 00487 } 00488 else 00489 # endif // HAVE_VA_INTEL && HAVE_OPENCL 00490 { 00491 Mat m = dst.getMat(); 00492 00493 // TODO Add support for roi 00494 CV_Assert(m.data == m.datastart); 00495 CV_Assert(m.isContinuous()); 00496 00497 VAStatus status = 0; 00498 00499 status = vaSyncSurface(display, surface); 00500 if (status != VA_STATUS_SUCCESS) 00501 CV_Error(cv::Error::StsError, "VA-API: vaSyncSurface failed"); 00502 00503 VAImage image; 00504 status = vaDeriveImage(display, surface, &image); 00505 if (status != VA_STATUS_SUCCESS) 00506 CV_Error(cv::Error::StsError, "VA-API: vaDeriveImage failed"); 00507 00508 unsigned char* buffer = 0; 00509 status = vaMapBuffer(display, image.buf, (void **)&buffer); 00510 if (status != VA_STATUS_SUCCESS) 00511 CV_Error(cv::Error::StsError, "VA-API: vaMapBuffer failed"); 00512 00513 CV_Assert(image.format.fourcc == VA_FOURCC_NV12); 00514 00515 copy_convert_nv12_to_bgr(image, buffer, m); 00516 00517 status = vaUnmapBuffer(display, image.buf); 00518 if (status != VA_STATUS_SUCCESS) 00519 CV_Error(cv::Error::StsError, "VA-API: vaUnmapBuffer failed"); 00520 00521 status = vaDestroyImage(display, image.image_id); 00522 if (status != VA_STATUS_SUCCESS) 00523 CV_Error(cv::Error::StsError, "VA-API: vaDestroyImage failed"); 00524 } 00525 #endif // !HAVE_VA 00526 } 00527 00528 }} // namespace cv::va_intel 00529
Generated on Tue Jul 12 2022 14:47:51 by
1.7.2
