我正在尝试使用CUDA Decoder项目中的代码将解码后的图像文件保存为BMP图像。
if (g_bReadback && g_ReadbackSID)
{
CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3 / 2), g_ReadbackSID);
long padded_size = (nWidth * nHeight * 3 );
CString output_file;
output_file.Format(_T("image/sample_45.BMP"));
SaveBMP(g_bFrameData[active_field],nWidth,nHeight,padded_size,output_file );
if (result != CUDA_SUCCESS)
{
printf("cuMemAllocHost returned %d\n", (int)result);
}
}
但保存的图片看起来像
有人可以帮我解决我做错了什么..谢谢。
答案 0 :(得分:3)
在进一步调查之后,我对你的方法进行了一些修改。
pDecodedFrame
实际上是一些非RGB格式,我认为它是NV12格式,我认为是particular YUV variant。pDecodedFrame
使用特定的CUDA内核在GPU上转换为RGB格式g_bUseInterop
,则此转换的目标缓冲区将是OpenGL提供的表面,或者如果未指定interop,则由cudaMalloc
的驱动程序API版本分配的普通区域。< / LI>
上面提到的目标缓冲区是pInteropFrame
(即使在非互操作的情况下)。所以为了给你做一个例子,为了简单起见,我选择只使用非互操作的情况,因为在这种情况下抓取RGB缓冲区(pInteropFrame
)要容易得多。
此处的方法在pInteropFrame
填充了相应的RGB图像后,将cudaPostProcessFrame
复制回主机。还有一个例程将图像保存为位图文件。我的所有修改都使用包含RMC
的评论进行描述,因此如果您想查找我所做的所有更改/添加,请搜索该内容。
要使用,请将此文件放在cudaDecodeGL项目中,以替换videoDecodeGL.cpp
源文件。然后重建项目。然后正常运行可执行文件以显示视频。要捕获特定帧,请使用nointerop
命令行开关运行可执行文件,例如。 cudaDecodGL nointerop
并且视频不会显示,但会进行解码操作和帧捕获,帧将保存在framecap.bmp
文件中。如果要更改捕获的特定帧编号,请将g_FrameCapSelect = 37;
变量修改为37以外的其他数字,然后重新编译。
Here is the replacement videoDecodeGL.cpp
我使用了pastebin,因为SO对可在问题正文中输入的字符数有限制。
请注意,我的方法与是否指定了回读无关。我建议不要对这个序列使用回读。