lDesktopResource->QueryInterface(I&lAcquiredDesktopImage); is stopping the second loop

116 views Asked by At

I am using this code to take a series of screen shot using desktop duplication api.

The code is only for a single shot. Thus I am looping over it. However looping the entire code gives fps of 3-4. So I am not looping over the declarations and stuff.

hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&lAcquiredDesktopImage)); this line only executes once. On the second loop it breaks. in other words, 2nd loop executes fine until it hits this line, after which the program terminates automatically. Commenting this line out makes 2nd and further loops work, however the image generated is black. Looping over the entire code in main() fixes the issue but gives terrible performance. I have tried to replace it with hr = lDesktopResource->QueryInterface(&lAcquiredDesktopImage); It does not remove the issue.

I have looked into other similar codes like this. But this code does not work either. It is suppose to do screen capture for 10 seconds, however the program terminates immediately. The output file cant be opened.

I have tried comparing my code with the code given in this question. But i can't figure out the issue.

I have searched for similar codes on the internet, however they are mostly for single shot, not series of shots in quick succession using desktop duplication.

I have tried adding a Sleep(100) in the loop. It does not help. How can I fix this?

int main()
{
int lresult(-1);
D3D_FEATURE_LEVEL lFeatureLevel;
HRESULT hr(E_FAIL);
// Create device
for (UINT DriverTypeIndex = 0; DriverTypeIndex < gNumDriverTypes; ++DriverTypeIndex){
    hr = D3D11CreateDevice(
    nullptr,
    gDriverTypes[DriverTypeIndex],
    nullptr,
    0,
    gFeatureLevels,
    gNumFeatureLevels,
    D3D11_SDK_VERSION,
    &lDevice,
    &lFeatureLevel,
    &lImmediateContext);
    if (SUCCEEDED(hr)){
        // Device creation success, no need to loop anymore
        break;
        }

    lDevice.Release();
    lImmediateContext.Release();
        }
    Sleep(100);
// Get DXGI device
    CComPtrCustom<IDXGIDevice> lDxgiDevice;
    hr = lDevice->QueryInterface(IID_PPV_ARGS(&lDxgiDevice));
// Get DXGI adapter
    CComPtrCustom<IDXGIAdapter> lDxgiAdapter;
    hr = lDxgiDevice->GetParent(
         __uuidof(IDXGIAdapter),
    reinterpret_cast<void**>(&lDxgiAdapter));
    lDxgiDevice.Release();

    UINT Output = 0;

    // Get output
    CComPtrCustom<IDXGIOutput> lDxgiOutput;
    hr = lDxgiAdapter->EnumOutputs(
            Output,
            &lDxgiOutput);


    lDxgiAdapter.Release();

    hr = lDxgiOutput->GetDesc(
            &lOutputDesc);

        

    // QI for Output 1
    CComPtrCustom<IDXGIOutput1> lDxgiOutput1;

    hr = lDxgiOutput->QueryInterface(IID_PPV_ARGS(&lDxgiOutput1));

    lDxgiOutput.Release();

    // Create desktop duplication
    hr = lDxgiOutput1->DuplicateOutput(
            lDevice,
            &lDeskDupl);


    lDxgiOutput1.Release();

    // Create GUI drawing texture
    lDeskDupl->GetDesc(&lOutputDuplDesc);

    D3D11_TEXTURE2D_DESC desc;

    desc.Width = lOutputDuplDesc.ModeDesc.Width;

    desc.Height = lOutputDuplDesc.ModeDesc.Height;

    desc.Format = lOutputDuplDesc.ModeDesc.Format;

    desc.ArraySize = 1;

    desc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_RENDER_TARGET;

    desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;

    desc.SampleDesc.Count = 1;

    desc.SampleDesc.Quality = 0;

    desc.MipLevels = 1;

    desc.CPUAccessFlags = 0;

    desc.Usage = D3D11_USAGE_DEFAULT;

    hr = lDevice->CreateTexture2D(&desc, NULL, &lGDIImage);

    // Create CPU access texture

    desc.Width = lOutputDuplDesc.ModeDesc.Width;

    desc.Height = lOutputDuplDesc.ModeDesc.Height;

    desc.Format = lOutputDuplDesc.ModeDesc.Format;

    desc.ArraySize = 1;

    desc.BindFlags = 0;

    desc.MiscFlags = 0;

    desc.SampleDesc.Count = 1;

    desc.SampleDesc.Quality = 0;

    desc.MipLevels = 1;

    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    desc.Usage = D3D11_USAGE_STAGING;

    hr = lDevice->CreateTexture2D(&desc, NULL, &lDestImage);


    int index_main = 0;
    while (index_main< 10) {
            

        CComPtrCustom<IDXGIResource> lDesktopResource;
        DXGI_OUTDUPL_FRAME_INFO lFrameInfo;

        int lTryCount = 4;
            
        do
            {
            Sleep(100);

            // Get new frame
            hr = lDeskDupl->AcquireNextFrame(
            0,
            &lFrameInfo,
            &lDesktopResource);

            if (SUCCEEDED(hr))
                    break;

            if (hr == DXGI_ERROR_WAIT_TIMEOUT)
                {
                    continue;
                }
            else if (FAILED(hr))
                    break;

            } while (--lTryCount > 0);
            
            // QI for ID3D11Texture2D
            std::cout << index_main;
            hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&lAcquiredDesktopImage));
//this is beaking the loop
        
        

    lDesktopResource.Release();
    // Copy image into GDI drawing texture
            
    lImmediateContext->CopyResource(lGDIImage, lAcquiredDesktopImage);

        
    // Draw cursor image into GDI drawing texture

    CComPtrCustom<IDXGISurface1> lIDXGISurface1;

    hr = lGDIImage->QueryInterface(IID_PPV_ARGS(&lIDXGISurface1));

            
    CURSORINFO lCursorInfo = { 0 };

    lCursorInfo.cbSize = sizeof(lCursorInfo);

    auto lBoolres = GetCursorInfo(&lCursorInfo);
            
    if (lBoolres == TRUE)
            {
                if (lCursorInfo.flags == CURSOR_SHOWING)
                {
                    auto lCursorPosition = lCursorInfo.ptScreenPos;

                    auto lCursorSize = lCursorInfo.cbSize;

                    HDC  lHDC;

                    lIDXGISurface1->GetDC(FALSE, &lHDC);

                    DrawIconEx(
                        lHDC,
                        lCursorPosition.x,
                        lCursorPosition.y,
                        lCursorInfo.hCursor,
                        0,
                        0,
                        0,
                        0,
                        DI_NORMAL | DI_DEFAULTSIZE);

                    lIDXGISurface1->ReleaseDC(nullptr);
                }

            }

            // Copy image into CPU access texture

            lImmediateContext->CopyResource(lDestImage, lGDIImage);


            // Copy from CPU access texture to bitmap buffer

            D3D11_MAPPED_SUBRESOURCE resource;
            UINT subresource = D3D11CalcSubresource(0, 0, 0);
            lImmediateContext->Map(lDestImage, subresource, D3D11_MAP_READ_WRITE, 0, &resource);
            index_main = index_main + 1;
        }
    
    
    return lresult;
}
0

There are 0 answers