1. 程式人生 > >基於FFmpeg的Dxva2硬解碼及Direct3D顯示(四)

基於FFmpeg的Dxva2硬解碼及Direct3D顯示(四)

rect c++ buffer 解碼 nds != 忽略 mono enc

顯示及資源清理

  1. 顯示

    關於D3D顯示的大概步驟是解碼數據放在緩沖區,也就是這裏離屏的概念,然後將離屏數據拷貝到後臺緩沖表面,後臺表面和前臺表面不停的交替實現顯示。

    // 離屏
    LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)pFrame->data[3];
    
    // D3DCLEAR_TARGET       清除要渲染目標(幀緩存)的顏色為D3DCOLOR_XRGB(0, 0, 0)的值
    // D3DCLEAR_ZBUFFER      清除深度緩沖(確定像素遮擋關系)的值為1.0f
    // D3DCLEAR_STENCIL     清除模板緩沖區(用於特效)為0
    // 此時1.0f和0均會被忽略
    m_pD3d9Dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    m_pD3d9Dev->BeginScene();
    
    IDirect3DSurface9 *  pBackBuffer = nullptr;
    if (pBackBuffer)
    {
        pBackBuffer->Release();
        pBackBuffer = NULL;
    }
    
    // 獲取第1個交換鏈上的第一個後臺緩沖表面
    m_pD3d9Dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    m_pD3d9Dev->StretchRect(surface, NULL, pBackBuffer, &m_renderRect, D3DTEXF_LINEAR);
    m_pD3d9Dev->EndScene();
    m_pD3d9Dev->Present(NULL, NULL, NULL, NULL);
    
    #if !CAMERA
    Sleep(1000 / m_frameRate);
    #endif
  2. 資源清理

    if (m_hD3dDll)
    {
        FreeLibrary(m_hD3dDll);
        m_hD3dDll = nullptr;
    }
    
    if (m_hDxva2Dll)
    {
        FreeLibrary(m_hDxva2Dll);
        m_hDxva2Dll = nullptr;
    }
    
    if (m_pD3d9Dev)
    {
        m_pD3d9Dev->Release();
    }
    
    if (m_pD3d9DevMgr && m_hDev != INVALID_HANDLE_VALUE)
    {
        m_pD3d9DevMgr->CloseDeviceHandle(m_hDev);
    }
    
    if (m_pDecoderService)
    {
        m_pDecoderService->Release();
    }
    
    if (m_pD3d9DevMgr)
    {
        m_pD3d9DevMgr->Release();
    }
    
    // 釋放緩沖區
    if (m_pSurface)
    {
        for (uint32_t i = 0; i < m_surfaceNums; i++)
        {
            if (m_pSurface[i])
                m_pSurface[i]->Release();
        }
    }
    
    // 釋放DirectX解碼器
    if (m_pDecoder)
    {
        m_pDecoder->Release();
        m_pDecoder = nullptr;
    }
    
    av_freep(&pCodecCtx->hwaccel_context);

基於FFmpeg的Dxva2硬解碼及Direct3D顯示(四)