c++windowsdesktop-duplicationdda

High CPU usage, with different timeouts interval, between frames acquiring in Desktop Duplication API


I'm trying to capture the screen with 16ms of the timeout, and i'm getting 60-65 FPS when the capture is tested on full screen 4k 60fps video. CPU usage, in this case, is approximately 0-1%. But when the mouse cursor is moving on the screen, the FPS and CPU usage are rasing up to 100+ frames and 25-30%, respectively. So, there is the question: why can i get FPS greater than 70, if the timeout is set to 16?

If the timeout is set to 0: amount of FPS are captured with the same value, but CPU usage is remained stable at 20-30%, even with a static image on the screen. Amout of timeouts error, in this case, significantly increased. Does this somehow related to the previous question?

do
{
    hr = lDeskDupl->AcquireNextFrame(
        TimeoutMS,
        &lFrameInfo,
        &lDesktopResource);

    if (SUCCEEDED(hr)) {
        accumFramesCount += lFrameInfo.AccumulatedFrames;
        break;
    }

    if (hr == DXGI_ERROR_INVALID_CALL) 
    {
        lDeskDupl->ReleaseFrame();
    }

    if (hr == DXGI_ERROR_WAIT_TIMEOUT)
    {
        timeoutsCount++;
    }
} 
while (true);

Solution

  • The answer is in AcquireNextFrame documentation:

    AcquireNextFrame acquires a new desktop frame when the operating system either updates the desktop bitmap image or changes the shape or position of a hardware pointer. The new frame that AcquireNextFrame acquires might have only the desktop image updated, only the pointer shape or position updated, or both.

    When you move mouse, you get an update from Desktop Duplication API before timeout elapses. This way you have more updates than the timeout value implies.

    As for abnormal high CPU load, it is highly likely that it is a problem with the API: yes mouse moves are associated with excessive CPU consumption for no apparent reason. Perhaps some spin lock related issue.