如何解决如何使用DirectX11或DirectX12渲染YUV数据
我有一个C ++ dll项目,其中在IDirect3DSurface9中使用directX9处理了YUV数据。然后,此表面已通过回调函数传递到WPF一侧,以使用d3dimage从WPF一侧进行渲染。但是渲染FPS非常慢,接近或低于30 FPS。但是我们希望达到50〜60 FPS。
ComPtr<IDirect3D9Ex> m_pD3D9Ex;
ComPtr<IDirect3DDevice9Ex> m_pDeviceEx;
ComPtr<IDirect3DSurface9> m_pDirect3DSurfaceRender;
ComPtr<IDirect3DSurface9> m_pTargetSurface;
ComPtr<IDirect3DTexture9> m_pTexture;
ComPtr<IDirect3DVertexBuffer9> m_pVertexBuffer;
ComPtr<IDirect3DVertexShader9> m_pVertexShader;
ComPtr<ID3dxconstantTable> m_pVertexConstantTable;
ComPtr<ID3dxconstantTable> m_pPixelConstantTable;
ComPtr<IDirect3DPixelShader9> m_pPixelShader;
RESULT MyDirect3D9::Render(BYTE* pYplane,BYTE* pUplane,BYTE* pVplane)
{
HRESULT lRet;
//Necessary Checkings for buffer and other stuff
// fill buffer
if(m_pDirect3DSurfaceRender == NULL)
return -1;
D3DLOCKED_RECT d3d_rect;
lRet=m_pDirect3DSurfaceRender->LockRect(&d3d_rect,NULL,D3DLOCK_DONOTWAIT);
if(Failed(lRet))
return -1;
int newHeight = m_videoHeight;
int newWidth = m_videoWidth;
BYTE* pict = (BYTE*)d3drect.pBits;
BYTE* Y = pY;
BYTE* V = pV;
BYTE* U = pU;
//copy D3DFMT_YV12 Data
for (int y = 0 ; y < newHeight ; y++)
{
memcpy(pict,Y,newWidth);
pict += d3drect.Pitch;
Y += newWidth;
}
for (int y = 0 ; y < newHeight >> 1; y++)
{
memcpy(pict,V,newWidth >> 1);
pict += d3drect.Pitch >> 1;
V += newWidth >> 1;
}
for (int y = 0 ; y < newHeight >> 1; y++)
{
memcpy(pict,U,newWidth >> 1);
pict += d3drect.Pitch >> 1;
U += newWidth >> 1;
}
lRet=m_pDirect3DSurfaceRender->UnlockRect();
if(Failed(lRet))
return -1;
// create scene
if (m_pDirect3DDevice == NULL)
return -1;
//All kinds of HR check has been performed. For code simplicity,detail code has not been mensioned.
lRet = m_pDirect3DDevice->Clear(D3DADAPTER_DEFAULT,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0),1.0f,0);
lRet = m_pDirect3DDevice->BeginScene();
lRet = m_pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
lRet = m_pDirect3DDevice->SetVertexShader(m_pVertexShader);
lRet = m_pDirect3DDevice->SetPixelShader(m_pPixelShader);
lRet = m_pDirect3DDevice->SetStreamSource(0,m_pVertexBuffer,sizeof(VERTEX));
lRet = m_pDirect3DDevice->SetTexture(0,m_pTexture);
lRet = m_pDirect3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,2);
m_overlays.Draw();
m_pDirect3DDevice->EndScene();
//IDirect3DSurface9 * pBackBuffer = NULL;
//m_pDirect3DDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&pBackBuffer);
//m_pDirect3DDevice->StretchRect(m_pDirect3DSurfaceRender,pBackBuffer,&m_rtViewport,D3DTEXF_LINEAR);
//m_pDirect3DDevice->EndScene();
//m_pDirect3DDevice->Present( NULL,NULL );
//pBackBuffer->Release();
// present
lRet = m_pDirect3DDevice->ColorFill(m_pTargetSurface,D3DCOLOR_ARGB(0xFF,0));
lRet = m_pDirect3DDevice->StretchRect(m_pDirect3DSurfaceRender,m_pTargetSurface,D3DTEXF_LINEAR);
lRet = m_pDirect3DDevice->Present( NULL,NULL );
return lRet;
}
以下是WPF侧d3dimage渲染:
//WPF side code
public void OnRender(IntPtr pSurface)
{
if (d3dimg.IsFrontBufferAvailable)
{
if (pSurface != IntPtr.Zero)
{
PrintFPS();
d3dimg.Lock();
d3dimg.SetBackBuffer(D3DResourceType.IDirect3DSurface9,pSurface);
d3dimg.AddDirtyRect(new Int32Rect(0,d3dimg.PixelWidth,d3dimg.PixelHeight));
d3dimg.Unlock();
}
}
}
现在,我想使用DirectX11 / DirectX12处理/渲染YUV数据。从DirectX9到DirectX11 / DirectX12,渲染过程似乎非常不同。
任何帮助将不胜感激。预先感谢。
更新: 更具体:要执行DirectX9渲染,请遵循以下过程:
-
使用IDirect3DSurface9将YUV缓冲区复制到字节指针
-
创建IDirect3DDevice9设备,例如m_pDirect3DDevice。
-
执行m_pDirect3DDevice->清除
-
m_pDirect3DDevice-> BeginScene()
-
获取缓冲区:m_pDirect3DDevice-> GetBackBuffer(...)
-
然后将StretchRect拉伸到预定义的曲面。 m_pDirect3DDevice-> StretchRect(....)
-
最后执行EndScene和Present(...)
我想知道DirectX11或DirectX12的基本渲染过程
我已经检查了下面的链接,但仍然找不到任何YUV数据渲染的成果。
WPFDXInterop,WPF DirectX Extensions,GPUOpen Libraries & SDKs
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。