如何使用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();
         }
     }
 }

Intel showed up how using DirectX 12 can all to a 70% improvement in performance as well as using 50% less power

现在,我想使用DirectX11 / DirectX12处理/渲染YUV数据。从DirectX9到DirectX11 / DirectX12,渲染过程似乎非常不同。

任何帮助将不胜感激。预先感谢。

更新: 更具体:要执行DirectX9渲染,请遵循以下过程:

  1. 使用IDirect3DSurface9将YUV缓冲区复制到字节指针

  2. 创建IDirect3DDevice9设备,例如m_pDirect3DDevice。

  3. 执行m_pDirect3DDevice->清除

  4. m_pDirect3DDevice-> BeginScene()

  5. 获取缓冲区:m_pDirect3DDevice-> GetBackBuffer(...)

  6. 然后将StretchRect拉伸到预定义的曲面。 m_pDirect3DDevice-> StretchRect(....)

  7. 后执行EndScene和Present(...)

我想知道DirectX11或DirectX12的基本渲染过程

我已经检查了下面的链接,但仍然找不到任何YUV数据渲染的成果。

WPFDXInteropWPF DirectX ExtensionsGPUOpen Libraries & SDKs

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...