pgurenko / DXGICaptureSample

DXGICaptureSample
MIT License
97 stars 41 forks source link

Trying to capture sequential screen grabs; time depends on mouse movement #7

Open drcdr opened 4 years ago

drcdr commented 4 years ago

I would like to have a very fast screen capture in a loop, extracting a portion of this data to send to a server. To start, I made some small additions to your (great) code, to try and benchmark the capturing of multiple desktops.

CComQIPtr<ID3D11Texture2D> spTextureResource = CComQIPtr<ID3D11Texture2D>(spDXGIResource);
CComQIPtr<IDXGISurface1> spDXGISurface = CComQIPtr<IDXGISurface1>(spD3D11Texture2D);
CComQIPtr<IDXGIOutput1> spDXGIOutput1 = CComQIPtr<IDXGIOutput1>(*OutputIter); 
CComQIPtr<IDXGIDevice1> spDXGIDevice = CComQIPtr<IDXGIDevice1>(spD3D11Device);
for (int j = 0; j < 10; j++) {
    int i = 0;
    do {
        hr = g_DXGIManager.GetOutputBits(pBuf, rcDim);
        i++;
    } while (hr == DXGI_ERROR_WAIT_TIMEOUT || i < 2);
    if( FAILED(hr) ) {
        printf("GetOutputBits failed with hr=0x%08x\n", hr);
        return hr;
    }
}

When I run this, it takes a long time, if I don't move the mouse. With no mouse movement, it typically takes 3.6 - 4.2s. If I move the mouse continuously, then run, it takes 137 ms.

I don't need the mouse pointer graphics information in the screen grab. I've tried both leaving in the 'mouse pointer' code and commenting it out, but it doesn't seem to make a difference.

I've run this on both my PC (running virtual desktop) and laptop (single desktop), and the behavior is similar (~1.8s no movement; ~158 ms movement).

I've also tried both CSDesktopand CSMonitor1, the behavior is the same.

Questions:

drcdr commented 4 years ago

Here are the log files, for the two cases (added a time stamp). Moving mouse while running (capturing 3 buffers) (60 fps):

12:24:09.702 Display output found. DeviceName=\\.\DISPLAY4  AttachedToDesktop=1 Rotation=1 DesktopCoordinates={(0,0),(2560,1440)}
12:24:09.704 Display output found. DeviceName=\\.\DISPLAY5  AttachedToDesktop=1 Rotation=1 DesktopCoordinates={(2560,0),(5120,1440)}
12:24:09.789 tmain:beginning capture 0
12:24:09.791 PointerPosition Visible=1 x=2184 y=1312 w=32 h=32 type=2
12:24:09.810 PointerPosition Visible=1 x=1990 y=1214 w=-858993460 h=-858993460 type=-858993460

12:24:09.815 tmain:beginning capture 1
12:24:09.816 PointerPosition Visible=1 x=1908 y=1165 w=-858993460 h=-858993460 type=-858993460
12:24:09.821 PointerPosition Visible=1 x=1849 y=1123 w=-858993460 h=-858993460 type=-858993460

12:24:09.827 tmain:beginning capture 2
12:24:09.828 PointerPosition Visible=1 x=1819 y=1096 w=-858993460 h=-858993460 type=-858993460
12:24:09.834 PointerPosition Visible=1 x=1811 y=1083 w=-858993460 h=-858993460 type=-858993460

Still mouse while running (capturing 3 buffers):

12:23:48.970 Display output found. DeviceName=\\.\DISPLAY4  AttachedToDesktop=1 Rotation=1 DesktopCoordinates={(0,0),(2560,1440)}
12:23:48.975 Display output found. DeviceName=\\.\DISPLAY5  AttachedToDesktop=1 Rotation=1 DesktopCoordinates={(2560,0),(5120,1440)}
12:23:49.063 tmain:beginning capture 0
12:23:49.067 PointerPosition Visible=1 x=2226 y=1038 w=32 h=32 type=2

12:23:49.087 tmain:beginning capture 1
12:23:49.115 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.136 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027

12:23:49.144 tmain:beginning capture 2
12:23:49.166 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.186 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.207 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.228 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.249 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.270 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.291 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.312 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.333 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.354 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.375 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.396 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.417 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.438 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.460 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027
12:23:49.481 m_DXGIOutputDuplication->AcquireNextFrame failed with hr=0x887a0027

So, when the mouse is still, I'm getting a DXGI_ERROR_WAIT_TIMEOUT; "The timeout value has elapsed and the resource is not yet available." But why?

-->> OK, now I see this, which explains things - mostly.

If I play a Youtube video, or go to this website, and capture, I only capture at 30 fps, though it would appear the screen is updating at 60 fps.

pgurenko commented 4 years ago

Do you have any idea why the mouse might be holding up continuous acquisition?

It looks like if nothing changes, no frames get acquired, makes sense.

If I wanted to preprocess the screen-grab on the GPU card (e.g. with CUDA code) - is there a logical place to insert this? (I'm very new to Direct3D.)

Probably right after you have a texture object after acquiring the frame