ffmpeg - rgb32 数据资源映射。使用directx memcpy
问题描述
我一直在尝试通过谷歌搜索解决这个问题一个月。但现在我不得不在这里寻求帮助。
我想使用 ffmpeg 解码帧进行渲染。并使用帧(它转换为 RGB32 格式),我尝试用 DX2D 纹理渲染帧。
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Height = pFrame->height;
TextureDesc.Width = pFrame->width;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; //size 16
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DYNAMIC;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
TextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
TextureDesc.MiscFlags = 0;
result = m_device->CreateTexture2D(&TextureDesc, NULL, &m_2DTex);
if (FAILED(result)) return false;
ShaderResourceViewDesc.Format = TextureDesc.Format;
ShaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
ShaderResourceViewDesc.Texture2D.MipLevels = 1;
D3D11_MAPPED_SUBRESOURCE S_mappedResource_tt = { 0, };
ZeroMemory(&S_mappedResource_tt, sizeof(D3D11_MAPPED_SUBRESOURCE));
result = m_deviceContext->Map(m_2DTex, 0, D3D11_MAP_WRITE_DISCARD, 0, &S_mappedResource_tt);
if (FAILED(result)) return false;
BYTE* mappedData = reinterpret_cast<BYTE *>(S_mappedResource_tt.pData);
for (auto i = 0; i < pFrame->height; ++i) {
memcpy(mappedData, pFrame->data, pFrame->linesize[0]);
mappedData += S_mappedResource_tt.RowPitch;
pFrame->data[0] += pFrame->linesize[0];
}
m_deviceContext->Unmap(m_2DTex, 0);
result = m_device->CreateShaderResourceView(m_2DTex, &ShaderResourceViewDesc, &m_ShaderResourceView);
if (FAILED(result)) return false;
m_deviceContext->PSSetShaderResources(0, 1, &m_ShaderResourceView);
但它只显示黑屏(没有渲染)。我猜这是错误的 memcpy 大小。最大的问题是我不知道是什么问题。
问题 1:为贴图创建 2D 纹理有什么问题吗?
问题 2:memcpy 参数应该输入多大的参数(与格式化有关)?
我基于下面的链接。
[1] https://www.gamedev.net/forums/topic/667097-copy-2d-array-into-texture2d/ [2] https://www.gamedev.net/forums/topic/645514-directx- 11-mapping-id3d11texture2d/ [3] https://www.gamedev.net/forums/topic/606100-solved-dx11-updating-texture-data/
感谢您的观看,请回复。
解决方案
没人回复。我解决了我的问题。我修改了一些代码,我不确定它是否能解决问题。黑屏原因的问题是我的矩阵。
D3D11_TEXTURE2D_DESC TextureDesc;
D3D11_RENDER_TARGET_VIEW_DESC RenderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC ShaderResourceViewDesc;
ZeroMemory(&TextureDesc, sizeof(TextureDesc));
TextureDesc.Height = pFrame->height;
TextureDesc.Width = pFrame->width;
TextureDesc.MipLevels = 1;
TextureDesc.ArraySize = 1;
TextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;/*DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;*/ //size 32bit
TextureDesc.SampleDesc.Count = 1;
TextureDesc.SampleDesc.Quality = 0;
TextureDesc.Usage = D3D11_USAGE_DYNAMIC;
TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
TextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
TextureDesc.MiscFlags = 0;
DWORD* pInitImage = new DWORD[pFrame->width*pFrame->height];
memset(pInitImage, 0, sizeof(DWORD)*pFrame->width*pFrame->height);
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = pInitImage;
InitData.SysMemPitch = pFrame->width*sizeof(DWORD);
InitData.SysMemSlicePitch = 0;
result = m_device->CreateTexture2D(&TextureDesc, &InitData, &m_2DTex);
if (FAILED(result)) return false;
ShaderResourceViewDesc.Format = TextureDesc.Format;
ShaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
ShaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
ShaderResourceViewDesc.Texture2D.MipLevels = 1;
result = m_device->CreateShaderResourceView(m_2DTex, &ShaderResourceViewDesc, &m_ShaderResourceView);
if (FAILED(result)) return false;
D3D11_MAPPED_SUBRESOURCE S_mappedResource_tt;
ZeroMemory(&S_mappedResource_tt, sizeof(S_mappedResource_tt));
DWORD Stride = pFrame->linesize[0];
result = m_deviceContext->Map(m_2DTex, 0, D3D11_MAP_WRITE_DISCARD, 0, &S_mappedResource_tt);
if (FAILED(result)) return false;
BYTE * pFrameData = pFrame->data[0]; // now we have a pointer that points to begin of the destination buffer
BYTE* mappedData = (BYTE *)S_mappedResource_tt.pData;// +S_mappedResource_tt.RowPitch;
for (auto i = 0; i < pFrame->height; i++) {
memcpy(mappedData, pFrameData, Stride);
mappedData += S_mappedResource_tt.RowPitch;
pFrameData += Stride;
}
m_deviceContext->Unmap(m_2DTex, 0);
它工作得很好。我希望它对那些和我做同样事情的人有所帮助。
推荐阅读
- html - 如何将元素与附加到其父元素底部的表格顶部对齐?
- python - 使用 ElementTree 提取
- algorithm - “Exact Cover”维基百科详细示例,关于最后一步的问题
- ruby-on-rails - 意外标记:使用 Uglifier 时 ES6 类上的运算符 (=)
- css - 如何一键多次更改按钮的背景颜色?
- c# - 从控制器下载 zip 文件不显示下载或任何错误
- php - 如何使用 PHP 打印 CSV 文件的行?
- css - CSS 未应用于单独的 ejs 文件
- javascript - 我重构的香草 JS 按钮单击不起作用
- ios - 在 SwiftUI 中创建表格的适当方法