簡體   English   中英

Windows桌面復制API需要很長時間

[英]Windows Desktop Duplication API taking a long time

我正在使用Windows桌面復制API在Windows 10中記錄我的屏幕。但是,我在性能方面遇到了一些問題。 使用谷歌瀏覽器播放視頻並嘗試記錄屏幕錄制時間從15毫秒波動到45毫秒。 我希望能夠至少以30fps的速度錄制,並且我知道桌面復制api能夠做到這一點。 無論如何,這里是我用來實際捕獲屏幕的代碼:

processor->hr = processor->lDeskDupl->AcquireNextFrame(0, &processor->lFrameInfo, &processor->lDesktopResource);

    if (processor->hr == DXGI_ERROR_WAIT_TIMEOUT) {
        processor->lDeskDupl->ReleaseFrame();
        return false;
    }

    if (FAILED(processor->hr)) {
        processor->lDeskDupl->ReleaseFrame();
        return false;
    }

    // QI for ID3D11Texture2D
    processor->hr = processor->lDesktopResource->QueryInterface(IID_PPV_ARGS(&processor->lAcquiredDesktopImage));
    if (FAILED(processor->hr)) {
        processor->lDeskDupl->ReleaseFrame();
        return false;
    }

    processor->lDesktopResource.Release();
    if (processor->lAcquiredDesktopImage == nullptr) {
        processor->lDeskDupl->ReleaseFrame();
        return false;
    }

    processor->lImmediateContext->CopyResource(processor->lGDIImage, processor->lAcquiredDesktopImage);

    processor->lAcquiredDesktopImage.Release();
    processor->lDeskDupl->ReleaseFrame();

    // Copy image into CPU access texture
    processor->lImmediateContext->CopyResource(processor->lDestImage, processor->lGDIImage);

    // Copy from CPU access texture to bitmap buffer
    D3D11_MAPPED_SUBRESOURCE resource;
    processor->subresource = D3D11CalcSubresource(0, 0, 0);
    processor->lImmediateContext->Map(processor->lDestImage, processor->subresource, D3D11_MAP_READ_WRITE, 0, &resource);

    BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
    BYTE* dptr = processor->pBuf;
    UINT lRowPitch = min(processor->lBmpRowPitch, resource.RowPitch);

    for (int i = 0; i < processor->lOutputDuplDesc.ModeDesc.Height; i++) {
        memcpy_s(dptr, processor->lBmpRowPitch, sptr, lRowPitch);
        sptr += resource.RowPitch;
        dptr += processor->lBmpRowPitch;
    }

重要的是要注意,這是一個特定的部分,每個周期需要15ms-45ms的時間來完成。 底部的memcpy循環通常占該時間的2毫秒左右,因此我知道這並不占用這里的時間。 另外AcquireNextFrame的超時設置為零,因此幾乎立即返回。 任何幫助將不勝感激! 粘貼在此處的代碼改編自此: https : //gist.github.com/Xirexel/a69ade44df0f70afd4a01c1c9d9e02cd

您沒有以最佳方式使用API​​。 閱讀 ReleaseFrame API文檔中的備注

出於性能原因,我們建議您在調用IDXGIOutputDuplication :: AcquireNextFrame方法以獲取下一個幀之前釋放該幀。 當客戶端不擁有框架時,操作系統會將所有桌面更新復制到表面。 如果操作系統為每個出現的幀更新相同的區域,則可能導致GPU周期浪費。

您沒有執行此處寫的內容,而是在復制后立即釋放框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM