dx11硬件解码传递给opencl并行处理

2024-05-28 15:44

本文主要是介绍dx11硬件解码传递给opencl并行处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

directx11 解码

使用ffmpeg进行directx11 解码
将解码后的NV12格式数据从D3D11 Texture中通过OpenCL处理需要经过几个步骤:首先,确保D3D11 Texture正确设置并与OpenCL上下文关联;然后,将NV12数据分两个步骤处理(Y平面和UV平面);最后,在OpenCL内核中处理这些数据。

将d3d11 texture转换成opencl对象

opencl本身是可以和dx9 dx11 等进行互操作,就是利用这一点来使用opencl来并行处理数据

bool CreateSharedSurface(void* data,  int nView, bool bIsReadOnly,cl_mem* y, cl_mem* uv)
{mfxHDLPair mid_pair = { 0 };mfxStatus sts = m_pAlloc->GetHDL(m_pAlloc->pthis, mid, reinterpret_cast<mfxHDL*>(&mid_pair));if (sts) return 0;ID3D11Texture2D *surf = (ID3D11Texture2D*)data;cl_int error = CL_SUCCESS;cl_mem memY = clCreateFromD3D11Texture2DKHR(m_clcontext, bIsReadOnly ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE,data, 0, &error);if (error) {log.error() << "clCreateFromD3D11Texture2DKHR failed. Error code: " << error << endl;return -1;}cl_mem memUV = clCreateFromD3D11Texture2DKHR(m_clcontext, bIsReadOnly ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE,data, 1, &error);if (error) {log.error() << "clCreateFromD3D11Texture2DKHR failed. Error code: " << error << endl;return -1;}*y = memY;*uv = memUV;return 0;
}

以上是转换过程

编写OpenCL内核处理NV12数据

和cuda一样,需要写核函数来处理

__kernel void processNV12(__read_only image2d_t yImage, __read_only image2d_t uvImage, __write_only image2d_t outputImage) {// 这里只是一个示例,实际处理逻辑根据需求编写int2 pos = (int2)(get_global_id(0), get_global_id(1));uchar4 yPixel = read_imageui(yImage, pos); // 读取Y平面像素uchar2 uvPixel = read_imageui(uvImage, pos / 2); // UV平面是Y的一半大小,因此坐标除以2// 这里简单地将YUV转换为RGB,实际应用中会有更复杂的处理float y = yPixel.x;float u = uvPixel.x - 128.0f;float v = uvPixel.y - 128.0f;float r = y + 1.14f * v;float g = y - 0.395f * u - 0.581f * v;float b = y + 2.032f * u;uchar4 outPixel = (uchar4)(saturate(r), saturate(g), saturate(b), 255);write_imageui(outputImage, pos, outPixel);
}

cpp执行OpenCL内核

// 假设outputImage是目标OpenCL图像对象,已根据需要创建
size_t globalWorkSize[2] = { width, height }; // width和height分别为处理图像的宽度和高度
cl_kernel kernel = clCreateKernel(program, "processNV12", &err); // program为编译好的OpenCL程序
clSetKernelArg(kernel, 0, sizeof(cl_mem), &clYImage);
clSetKernelArg(kernel, 1, sizeof(cl_mem), &clUVImage);
clSetKernelArg(kernel, 2, sizeof(cl_mem), &outputImage);err = clEnqueueNDRangeKernel(commandQueue, kernel, 2, nullptr, globalWorkSize, nullptr, 0, nullptr, nullptr);
if (err != CL_SUCCESS) { /* 处理错误 */ }// 同步、读回数据、清理等操作

初始化过程

void initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
{
CV_UNUSED(pD3D11Device);
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 number of platforms");// TODO Filter platforms by name from OPENCV_OPENCL_DEVICEint found = -1;
cl_device_id device = NULL;
cl_uint numDevices = 0;
cl_context context = NULL;// 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,CL_PREFERRED_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);//CL_PREFERRED_DEVICES_FOR_D3D11_NVif (status != CL_SUCCESS)continue;if (numDevices > 0){cl_context_properties properties[] ={CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)pD3D11Device,CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],//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 (found < 0)
{// try with CL_ALL_DEVICES_FOR_D3D11_NVfor (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,CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);//CL_ALL_DEVICES_FOR_D3D11_NVif (status != CL_SUCCESS)continue;if (numDevices > 0){cl_context_properties properties[] ={CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)pD3D11Device,CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],//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 (found < 0)CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
}//cv::ocl::Context& ctx = cv::ocl::Context::getDefault(false);
//cv::ocl::initializeContextFromHandle(ctx, platforms[found], context, device);
///As you say,`initializeContextFromHandle()` symbol is not in the exported list. So I use attachContext() instead for test.
cv::ocl::attachContext("NVIDIA CUDA", platforms[found], context, device);//Test passed//return ctx;}

这篇关于dx11硬件解码传递给opencl并行处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010993

相关文章

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

JAVA基础:值传递和址传递

1 值传递和址传递 值传递 方法调用时,传递的实参是一个基本类型的数据 形参改变,实参不变 public static void doSum(int num1,int num2){}main(){doSum(10,20);int i = 10 ;int j = 20 ;doSum(i,j) ;}   public static void t1(int num){num = 20

六、Maven依赖管理、依赖传递和依赖冲突

1.Maven依赖管理 Maven 依赖管理是 Maven 软件中最重要的功能之一。Maven 的依赖管理能够帮助开发人员自动解决软件包依赖问题,使得开发人员能够轻松地将其他开发人员开发的模块或第三方框架集成到自己的应用程序或模块中,避免出现版本冲突和依赖缺失等问题。 我们通过定义 POM 文件,Maven 能够自动解析项目的依赖关系,并通过 Maven 仓库自动下载和管理依赖,从而避免了手动

FFmpeg系列-视频解码后保存帧图片为ppm

在正常开发中遇到花屏时怎么处理呢?可以把解码后的数据直接保存成帧图片保存起来,然后直接看图片有没有花屏来排除是否是显示的问题,如果花屏,则代表显示无问题,如果图片中没有花屏,则可以往显示的方向去排查了。 void saveFrame(AVFrame* pFrame, int width, int height, int iFrame){FILE *pFile;char szFilename[

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数 一、环境说明二、页面之间相互传参 一、环境说明 DevEco Studio 版本: API版本:以12为主 二、页面之间相互传参 说明: 页面间的导航可以通过页面路由router模块来实现。页面路由模块根据页面url找到目标页面,从而实现跳转。通过页面路由模块,可以使用不同的url访问不同的页面,包括跳转到U

机器视觉硬件选型根据某项目相机镜头

一 项目总需求 1、大视野检测需求: (1)大视野: ①产品尺寸15.6寸屏幕,产品大小:350mm x 225mm; ②产品料盘尺寸大小:565mm x 425mm; ③工作距离:880mm;检测精度:500μm; 1、大视野检测需求: (1)大视野: ①产品尺寸15.6寸屏幕,产品大小:350mm x 225mm; ②产品料盘尺寸大小:565mm x 425mm; 工作距离:

xml数据作为表单参数在网络传递也需要用urlencode处理

xml数据作为表单参数在网络传递也需要用urlencode处理。才能确保数据被正确的传递和解析。需要加深对数据在web上传递的理解。

url参数中带有号,需要用先把url做个解析,使其方便在网络上传递

需求:提交异步通知地址给宝付的投标接口,发现投标成功后,异步通知地址没有被调用 排查:通过和宝付技术对接,发现是203,地址重定向错误。深入排查,发现异步通知返回的地址中&号之后的参数宝付没有收到 结论:表单提交的参数中的异步通知地址中的&号没有做urlencode()处理导致传递丢失参数。 地址参数中带有&号,java在做提交的时候,不能正确传递&,导致地址中&之后的内容丢失。故此需要ur

【Hot100】LeetCode—394. 字符串解码

目录 1- 思路栈实现+四种情况处理 2- 实现⭐394. 字符串解码——题解思路 3- ACM 实现 原题链接:394. 字符串解码 1- 思路 栈实现+四种情况处理 ① 遇到数字,进行倍数相加 、②遇到左括号,压栈之前的元素、③遇到右括号弹出,栈进行拼接、④否则遇到字母,直接拼接在 res通过栈,实现先进后出的思想 对于输入 3[a2[c]] 的输入,在读到 3[得