C++ 如何在win7上将ID3D11Texture2D内容复制到IMFSample?
在win8及以上版本中,我可以直接使用MFCreateDXGISurfaceBufferWrapper,但在Win7系统上不支持此接口,因此我只能在CPU上复制它(“在Win7上使用D3D11创建了_capture_texture_2D”),但显示的最终图像是倾斜的。我觉得转换结果的长度或宽度不正确:C++ 如何在win7上将ID3D11Texture2D内容复制到IMFSample?,c++,video,ms-media-foundation,direct3d11,C++,Video,Ms Media Foundation,Direct3d11,在win8及以上版本中,我可以直接使用MFCreateDXGISurfaceBufferWrapper,但在Win7系统上不支持此接口,因此我只能在CPU上复制它(“在Win7上使用D3D11创建了_capture_texture_2D”),但显示的最终图像是倾斜的。我觉得转换结果的长度或宽度不正确: _capture_texture2d是为与DXGI_格式_B8G8R8A8_UNORM的d2d互操作性而创建的,但MFVideoFormat_XXX没有看到相应的格式 也许“锁”需要投球支持,
- _capture_texture2d是为与DXGI_格式_B8G8R8A8_UNORM的d2d互操作性而创建的,但MFVideoFormat_XXX没有看到相应的格式
- 也许“锁”需要投球支持,但我找不到引子
HRESULT hr = E_NOTIMPL; CComPtr<IMFMediaBuffer> media_buffer; if (IsWindows8OrGreater()) { hr = MFCreateDXGISurfaceBufferWrapper(__uuidof(ID3D11Texture2D), _capture_texture2d, 0, FALSE, &media_buffer); CComPtr<IMF2DBuffer> twod_buffer; hr = media_buffer->QueryInterface(&twod_buffer); RETURN_ON_FAIL(hr); DWORD length = 0; hr = twod_buffer->GetContiguousLength(&length); RETURN_ON_FAIL(hr); hr = media_buffer->SetCurrentLength(length); RETURN_ON_FAIL(hr); } else { D3D11_TEXTURE2D_DESC desc; _capture_texture2d->GetDesc(&desc); UINT32 img_size = 0; hr = MFCalculateImageSize(MFVideoFormat_RGB32, desc.Width, desc.Height, &img_size); RETURN_ON_FAIL(hr); D3D11_MAPPED_SUBRESOURCE resource; UINT subresource = D3D11CalcSubresource(0, 0, 0); hr = immediate_context->Map(_capture_texture2d, subresource, D3D11_MAP_READ, 0, &resource); RETURN_ON_FAIL(hr); hr = MFCreateMemoryBuffer(img_size, &media_buffer); if (SUCCEEDED(hr)) { BYTE *dst = NULL; hr = media_buffer->Lock(&dst, NULL, NULL); if (SUCCEEDED(hr)) { BYTE* src = (BYTE*)resource.pData; for (size_t i = 0; i < desc.Height; i++) { memcpy(dst, src, desc.Width * 4); src += resource.RowPitch; dst += desc.Width * 4; } media_buffer->Unlock(); } } immediate_context->Unmap(_capture_texture2d, subresource); RETURN_ON_FAIL(hr); hr = media_buffer->SetCurrentLength(img_size); } RETURN_ON_FAIL(hr); CComPtr<IMFSample> sample; hr = MFCreateSample(sample); RETURN_ON_FAIL(hr); hr = sample->AddBuffer(media_buffer); RETURN_ON_FAIL(hr);
HRESULT hr=E_NOTIMPL; CComPtr媒体缓冲区; 如果(isWindows8OrCreater()) { hr=MFCreateDXGISurfaceBufferWrapper(u_uidof(ID3D11Texture2D),_capture_texture2d,0,FALSE和media_buffer); CComPtr-twodu缓冲区; hr=媒体缓冲区->查询接口(&twod\U缓冲区); 失败时返回(hr); DWORD长度=0; hr=twodu缓冲区->获取连续长度(&length); 失败时返回(hr); hr=媒体缓冲区->设置当前长度(长度); 失败时返回(hr); } 其他的 { D3D11_纹理2 d_描述; _捕捉纹理2d->GetDesc(&desc); UINT32 img_尺寸=0; hr=MFCalculateImageSize(MFVideoFormat_RGB32、描述宽度、描述高度和图像大小); 失败时返回(hr); D3D11_映射_子资源; UINT subresource=d3d11calsubresource(0,0,0); hr=即时上下文->映射(捕获纹理2d、子资源、D3D11、映射读取、0和资源); 失败时返回(hr); hr=MFCreateMoryBuffer(img_大小和媒体_缓冲区); 如果(成功(hr)) { 字节*dst=NULL; hr=媒体缓冲区->锁定(&dst,NULL,NULL); 如果(成功(hr)) { 字节*src=(字节*)resource.pData; 用于(尺寸i=0;i
解锁(); } } 即时上下文->取消映射(捕获纹理2D,子资源); 失败时返回(hr); hr=媒体缓冲区->设置当前长度(img\u大小); } 失败时返回(hr); 买方样品; hr=MFCreateSample(样本); 失败时返回(hr); hr=样本->添加缓冲区(介质缓冲区); 失败时返回(hr);
D3D11_TEXTURE2D_DESC desc;
_capture_texture2d->GetDesc(&desc);
UINT32 img_size = 0;
GUID dst_format = MFVideoFormat_RGB32;
hr = MFCalculateImageSize(dst_format, desc.Width, desc.Height, &img_size);
RETURN_ON_FAIL(hr);
LONG dst_stride = 0;
hr = MFGetStrideForBitmapInfoHeader(dst_format.Data1, desc.Width, &dst_stride);
RETURN_ON_FAIL(hr);
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0, 0, 0);
hr = immediate_context->Map(_capture_texture2d, subresource, D3D11_MAP_READ, 0, &resource);
RETURN_ON_FAIL(hr);
hr = MFCreateMemoryBuffer(img_size, &media_buffer);
if (SUCCEEDED(hr))
{
BYTE *dst_data = NULL;
hr = media_buffer->Lock(&dst_data, NULL, NULL);
if (SUCCEEDED(hr))
{
if (dst_stride >= 0)
{
hr = MFCopyImage(dst_data, dst_stride, (BYTE*)resource.pData, resource.RowPitch, desc.Width * 4, desc.Height);
}
else
{
BYTE *src_ptr = (BYTE*)resource.pData;
BYTE *dst_ptr = dst_data - dst_stride * (desc.Height - 1);
size_t copy_bytes = min(resource.RowPitch, (UINT)-dst_stride);
for (size_t i = 0; i < desc.Height; i++)
{
memcpy(dst_ptr, src_ptr, copy_bytes);
src_ptr += resource.RowPitch;
dst_ptr += dst_stride;
}
}
media_buffer->SetCurrentLength(img_size);
media_buffer->Unlock();
}
}
immediate_context->Unmap(_capture_texture2d, subresource);
...
D3D11_TEXTURE2D_DESC DESC;
_捕捉纹理2d->GetDesc(&desc);
UINT32 img_尺寸=0;
GUID dst_format=MFVideoFormat_RGB32;
hr=MFCalculateImageSize(dst_格式、描述宽度、描述高度和图像大小);
失败时返回(hr);
长dst_步幅=0;
hr=MFGetStripForBitMapInfo标题(dst_格式.Data1、描述宽度和dst_步长);
失败时返回(hr);
D3D11_映射_子资源;
UINT subresource=d3d11calsubresource(0,0,0);
hr=即时上下文->映射(捕获纹理2d、子资源、D3D11、映射读取、0和资源);
失败时返回(hr);
hr=MFCreateMoryBuffer(img_大小和媒体_缓冲区);
如果(成功(hr))
{
字节*dst_数据=NULL;
hr=媒体缓冲区->锁定(&dst_数据,NULL,NULL);
如果(成功(hr))
{
如果(dst_跨步>=0)
{
hr=MFCopyImage(dst_数据,dst_跨距,(字节*)resource.pData,resource.RowPitch,desc.Width*4,desc.Height);
}
其他的
{
字节*src_ptr=(字节*)resource.pData;
字节*dst_ptr=dst_数据-dst_步幅*(描述高度-1);
size\u t copy\u bytes=min(resource.RowPitch,(UINT)-dst\u步长);
用于(尺寸i=0;i设置当前长度(img\u大小);
媒体缓冲区->解锁();
}
}
即时上下文->取消映射(捕获纹理2D,子资源);
...