va_buffersharing让gpu与cpu访问同一块内存,从而减少开销

源文件放到opencv/samples/va_intel/目录下

使用下面的命令进行测试。
opencv/build/bin/va_intel-example-va_intel_interop fish-bike.jpg out1 out2

/* origin: libva-1.3.1/test/decode/mpeg2vldemo.cpp *//** Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.** Permission is hereby granted, free of charge, to any person obtaining a* copy of this software and associated documentation files (the* "Software"), to deal in the Software without restriction, including* without limitation the rights to use, copy, modify, merge, publish,* distribute, sub license, and/or sell copies of the Software, and to* permit persons to whom the Software is furnished to do so, subject to* the following conditions:** The above copyright notice and this permission notice (including the* next paragraph) shall be included in all copies or substantial portions* of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/#include <iostream>
#include <stdexcept>
#include <string>#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <va/va.h>#include "display.cpp.inc"#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/va_intel.hpp"
#include "cvconfig.h"#define CHECK_VASTATUS(_status,_func) \if (_status != VA_STATUS_SUCCESS) \{ \char str[256]; \snprintf(str, sizeof(str)-1, "%s:%s (%d) failed(status=0x%08x),exit\n", __func__, _func, __LINE__, _status); \throw std::runtime_error(str); \}class CmdlineParser
{
public:enum { fnInput=0, fnOutput1, fnOutput2, _fnNumFiles }; // file name indicesCmdlineParser(int argc, char** argv):m_argc(argc), m_argv(argv){}void usage(){fprintf(stderr,
#if defined(HAVE_VA_INTEL)"Usage: va_intel_interop [-f] infile outfile1 outfile2\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 infile outfile1 outfile2\n\n""Interop OFF only version\n\n""where:\n"
#endif //HAVE_VA_INTEL / HAVE_VA"        infile   is to be existing, contains input image data (bmp, jpg, png, tiff, etc)\n""        outfile1 is to be created, contains original surface data (NV12)\n""        outfile2 is to be created, contains processed surface data (NV12)\n");}// true => go, false => usage/exit; extra args/unknown options are ignored for simplicitybool run(){int n = 0;for (int i = 0; i < _fnNumFiles; ++i)m_files[i] = 0;
#if defined(HAVE_VA_INTEL)m_interop = true;
#elif defined(HAVE_VA)m_interop = false;
#endif //HAVE_VA_INTEL / HAVE_VAfor (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 < _fnNumFiles)m_files[n++] = arg;}}return bool(n >= _fnNumFiles);}bool isInterop() const{return m_interop;}const char* getFile(int n) const{return ((n >= 0) && (n < _fnNumFiles)) ? m_files[n] : 0;}
private:int m_argc;char** m_argv;const char* m_files[_fnNumFiles];bool m_interop;
};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 checkIfAvailableYUV420()
{VAEntrypoint entrypoints[5];int num_entrypoints,vld_entrypoint;VAConfigAttrib attrib;VAStatus status;status = vaQueryConfigEntrypoints(va::display, VAProfileMPEG2Main, entrypoints, &num_entrypoints);CHECK_VASTATUS(status, "vaQueryConfigEntrypoints");for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; ++vld_entrypoint){if (entrypoints[vld_entrypoint] == VAEntrypointVLD)break;}if (vld_entrypoint == num_entrypoints)throw std::runtime_error("Failed to find VLD entry point");attrib.type = VAConfigAttribRTFormat;vaGetConfigAttributes(va::display, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1);if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)throw std::runtime_error("Desired YUV420 RT format not found");
}static cv::UMat readImage(const char* fileName)
{cv::Mat m = cv::imread(fileName);if (m.empty())throw std::runtime_error("Failed to load image: " + std::string(fileName));return m.getUMat(cv::ACCESS_RW);
}static void writeImage(const cv::UMat& u, const char* fileName, bool doInterop)
{std::string fn = std::string(fileName) + std::string(doInterop ? ".on" : ".off") + std::string(".jpg");cv::imwrite(fn, u);
}static float run(const char* infile, const char* outfile1, const char* outfile2, bool doInterop)
{VASurfaceID surface;VAStatus status;Timer t;// initialize CL context for CL/VA interopcv::va_intel::ocl::initializeContextFromVA(va::display, doInterop);// load input imagecv::UMat u1 = readImage(infile);cv::Size size2 = u1.size();status = vaCreateSurfaces(va::display, VA_RT_FORMAT_YUV420, size2.width, size2.height, &surface, 1, NULL, 0);CHECK_VASTATUS(status, "vaCreateSurfaces");// transfer image into VA surface, make sure all CL initialization is done (kernels etc)cv::va_intel::convertToVASurface(va::display, u1, surface, size2);cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);cv::UMat u2;cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));// measure performance on some image processingwriteImage(u1, outfile1, doInterop);t.start();cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);//cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));//cv::va_intel::convertToVASurface(va::display, u2, surface, size2);cv::rectangle(u1,cvPoint(10,10),cvPoint(200,200),cv::Scalar(255, 242, 35));cv::rectangle(u1,cvPoint(15,15),cvPoint(203,205),cv::Scalar(255, 242, 35));cv::rectangle(u1,cvPoint(20,20),cvPoint(210,210),cv::Scalar(255, 242, 35));cv::rectangle(u1,cvPoint(25,25),cvPoint(215,215),cv::Scalar(255, 242, 35));cv::va_intel::convertToVASurface(va::display, u1, surface, size2);cv::va_intel::convertFromVASurface(va::display, surface, size2, u2);t.stop();writeImage(u2, outfile2, doInterop);vaDestroySurfaces(va::display, &surface,1);return t.time(Timer::MSEC);
}int main(int argc, char** argv)
{try{CmdlineParser cmd(argc, argv);if (!cmd.run()){cmd.usage();return 0;}if (!va::openDisplay())throw std::runtime_error("Failed to open VA display for CL-VA interoperability");std::cout << "VA display opened successfully" << std::endl;checkIfAvailableYUV420();const char* infile = cmd.getFile(CmdlineParser::fnInput);const char* outfile1 = cmd.getFile(CmdlineParser::fnOutput1);const char* outfile2 = cmd.getFile(CmdlineParser::fnOutput2);bool doInterop = cmd.isInterop();float time = run(infile, outfile1, outfile2, doInterop);std::cout << "Interop " << (doInterop ? "ON " : "OFF") << ": processing time, msec: " << time << std::endl;}catch (std::exception& ex){std::cerr << "ERROR: " << ex.what() << std::endl;}va::closeDisplay();return 0;
}

重点看run这个函数。
buffersharing的过程是

initializeContextFromVA & vaCreateSurfaces

初始化和创造VASurface

convertToVASurface

void cv::va_intel::convertToVASurface   (   VADisplay   display,
InputArray  src,
VASurfaceID     surface,
Size    size
)
Converts InputArray to VASurfaceID object.Parameters
display - VADisplay object.
src - source InputArray.
surface - destination VASurfaceID object.
size    - size of image represented by VASurfaceID object.

convertFromVASurface

Converts VASurfaceID object to OutputArray.Parameters
display - VADisplay object.
surface - source VASurfaceID object.
size    - size of image represented by VASurfaceID object.
dst - destination OutputArray.

vaDestroySurfaces

销毁VASurface

如果和VAAPI,FFmpeg结合处理视频,可以先通过

convertFromVASurface(s->display, (VASurfaceID)(uintptr_t)in->data[3], cv::Size(width, height), va_img);

获取UMat,处理后再通过

 cv::va_intel::convertToVASurface(s->display, va_img, (VASurfaceID)(uintptr_t)in->data[3], cv::Size(width, height));

写回

最新文章

  1. 我竟然被“双亲委派”给虐了
  2. 谷歌某程序员抱怨“招人难”:招了小半年,8个岗位才招到1个,现在又空出6个岗位!...
  3. ORACLE数据库备份
  4. not optimal php,php环境配置 配置
  5. Android11模拟定位开发,Android 11 中的位置信息更新
  6. mysql数据库实验3查询_MySQL数据库实验:任务三 数据库的单表查询设计
  7. 数组中求子数组和最大
  8. 【百战GAN】自动增强图像对比度和颜色美感,GAN如何做?
  9. rhino6.0安装教程
  10. DOTA2:IG实力不如Nigma?解说:错了,让门票给他们自己回家训练
  11. java溢出怎么处理_java数据溢出怎么处理?
  12. 前后端分离必备的接口规范,十分接地气
  13. bash下输入命令的几个常用快捷键
  14. stl 优先队列(堆)
  15. Crust Network将于1月14日12点开始暂停HTTP版本应用
  16. es6 let和const命令(1)
  17. pygame放大图片_使用Pygame进行游戏开发(3)--绘图
  18. 这几天可能是长时间关注电脑,眼睛没有得到休息,所以就早上起来眼睛有点通...
  19. 十大排序算法-桶排序(c语言实现)
  20. 《红色警戒3》简体中文完美整合版下载

热门文章

  1. CQI的解释(完整版)
  2. X在苍茫大地 闻一达(闻大嘴) 闻明远
  3. 【linux内核分析与应用-陈莉君】中断机制概述
  4. python学习笔记(七) os模块与窗体控制
  5. [经验]iOS开发-记录下在开发过程中遇到的问题的解决方案及经验总结-1
  6. Kotlin自定义android 控件
  7. Unity SetFromToRotation和FromToRotation的区别
  8. 单片机——A/D数模转换篇
  9. 这么简单的道理,猩猩都懂,我们却忘了
  10. 如何使用FSMC让OLED屏幕刷新率飞起来?