我正在使用来自 NVIDIA CUDA 样本的 NVDEC H.264 解码器,我发现一件事是一旦帧被解码,它就会从 NV12 转换为分配在 CUDA 一侧的 BGRA 缓冲区,然后将该缓冲区复制到 D3D BGRA质地。
我发现这在内存使用方面效率不高,并希望使用此内核将 NV12 帧直接转换为 D3D 纹理:
void Nv12ToBgra32(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix)
因此,创建 D3D 纹理(BGRA、D3D11_USAGE_DEFAULT、D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS、D3D11_CPU_ACCESS_WRITE、1 个 mipmap),然后在 CUDA 端注册并写入:
//Register
ck(cuGraphicsD3D11RegisterResource(&cuTexResource, textureResource, CU_GRAPHICS_REGISTER_FLAGS_NONE));
...
//Write output:
CUarray retArray;
ck(cuGraphicsMapResources(1, &cuTexResource, 0));
ck(cuGraphicsSubResourceGetMappedArray(&retArray, cuTexResource, 0, 0));
/*
yuvFramePtr (NV12) is uint8_t* from decoded frame,
it's stored within CUDA memory I believe
*/
Nv12ToBgra32(yuvFramePtr, w, (uint8_t*)retArray, 4 * w, w, h);
ck(cuGraphicsUnmapResources(1, &cuTexResource, 0));
一旦调用内核,我就会崩溃。可能是因为滥用 CUarray,任何人都可以澄清如何使用 cuGraphicsSubResourceGetMappedArray 的输出从 CUDA 内核写入纹理内存?(由于只需要写入原始内存,因此无需处理正确的钳位、过滤和值缩放)