Я использую API дублирования рабочего стола Windows для записи своего экрана в Windows 10. У меня, однако, есть некоторые проблемы с производительностью.При воспроизведении видео с использованием Google Chrome и попытке записать время, необходимое для записи экрана, колеблется от 15 мс до 45 мс.Я хотел иметь возможность записывать как минимум 30 кадров в секунду, и я знаю, что 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;
}
Важно отметить, что это особый раздел, который занимает 15 мс-45 мс для завершения каждого цикла.Цикл memcpy в нижней части обычно занимает около 2 мс этого времени, поэтому я знаю, что он не отвечает за время, которое он занимает здесь.Также тайм-аут AcquireNextFrame установлен в ноль, поэтому он возвращается почти сразу.Любая помощь будет принята с благодарностью!Вставленный здесь код был адаптирован из этого: https://gist.github.com/Xirexel/a69ade44df0f70afd4a01c1c9d9e02cd