如何解决如何在Win7上将ID3D11Texture2D内容复制到IMFSample?
在win8及更高版本中,我可以直接使用MFCreateDXGISurfaceBufferWrapper,但是在Win7系统上不支持此接口,因此只能在CPU上复制它(“ _capture_texture_2D”是在Win7上使用D3D11_USAGE_STAGING创建的),但是显示的最终图像是斜。我觉得转换结果的长度或宽度不正确:
-
_capture_texture2d是为了与DXGI_FORMAT_B8G8R8A8_UNORM进行d2d互操作性而创建的,但MFVideoFormat_XXX没有看到相应的格式
-
也许“锁定”需要音高支持,但我找不到简介
HRESULT hr = E_NOTIMPL; CComPtr<IMFMediaBuffer> media_buffer; if (IsWindows8OrGreater()) { hr = MFCreateDXGISurfaceBufferWrapper(__uuidof(ID3D11Texture2D),_capture_texture2d,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); hr = immediate_context->Map(_capture_texture2d,subresource,D3D11_MAP_READ,&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);
解决方法
使用函数MFGetStrideForBitmapInfoHeader和MFCopyImage解决:
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,&dst_stride);
RETURN_ON_FAIL(hr);
D3D11_MAPPED_SUBRESOURCE resource;
UINT subresource = D3D11CalcSubresource(0,0);
hr = immediate_context->Map(_capture_texture2d,subresource,D3D11_MAP_READ,&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);
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。