title: DirectX11 DXGI Capture Screen when in full screen
body: <p>I'm currently trying to develop a personal project where I will light up LEDs according to what's happening on the screen of my computer.</p>
  
  <p>I've tried several solutions to capture my screen, and DirectX11 with DXGI is the fastest way I found to have a good FPS Rate.</p>
  
  <p>My only issue is the following: When in full screen (for example, watching Netflix trogh Win10 App or playing any game in fullscreen), it seems that nothing is captured. I have two functions (one to set up and another one to capture a frame:</p>
  
  <p>Setup Up Function:</p>
  
  <pre><code> bool DXGIScreenCapturer::Init() {
      int lresult(-1);
  
      D3D_FEATURE_LEVEL lFeatureLevel;
  
      HRESULT hr(E_FAIL);
      hr = D3D11CreateDevice(
          nullptr,
          D3D_DRIVER_TYPE_HARDWARE,
          nullptr,
          0,
          gFeatureLevels,
          gNumFeatureLevels,
          D3D11_SDK_VERSION,
          &amp;_lDevice,
          &amp;lFeatureLevel,
          &amp;_lImmediateContext);
  
      if (FAILED(hr))
          return false;
  
      if (!_lDevice)
          return false;
  
      // Get DXGI device
      ComPtr&lt;IDXGIDevice&gt; lDxgiDevice;
      hr = _lDevice.As(&amp;lDxgiDevice);
  
      if (FAILED(hr))
          return false;
  
      // Get DXGI adapter
      ComPtr&lt;IDXGIAdapter&gt; lDxgiAdapter;
      hr = lDxgiDevice-&gt;GetParent(__uuidof(IDXGIAdapter), &amp;lDxgiAdapter);
  
      if (FAILED(hr))
          return false;
  
      lDxgiDevice.Reset();
  
      UINT Output = 0;
  
      // Get output
      ComPtr&lt;IDXGIOutput&gt; lDxgiOutput;
      hr = lDxgiAdapter-&gt;EnumOutputs(Output, &amp;lDxgiOutput);
  
      if (FAILED(hr))
          return false;
  
      lDxgiAdapter.Reset();
  
      hr = lDxgiOutput-&gt;GetDesc(&amp;_lOutputDesc);
  
      if (FAILED(hr))
          return false;
  
      // QI for Output 1
      ComPtr&lt;IDXGIOutput1&gt; lDxgiOutput1;
      hr = lDxgiOutput.As(&amp;lDxgiOutput1);
  
      if (FAILED(hr))
          return false;
  
      lDxgiOutput.Reset();
  
      // Create desktop duplication
      hr = lDxgiOutput1-&gt;DuplicateOutput(_lDevice.Get(), &amp;_lDeskDupl);
  
      if (FAILED(hr))
          return false;
  
      lDxgiOutput1.Reset();
  
      // Create GUI drawing texture
      _lDeskDupl-&gt;GetDesc(&amp;_lOutputDuplDesc);
      // Create CPU access texture
      _desc.Width = _lOutputDuplDesc.ModeDesc.Width;
      _desc.Height = _lOutputDuplDesc.ModeDesc.Height;
      _desc.Format = _lOutputDuplDesc.ModeDesc.Format;
      std::cout &lt;&lt; _desc.Width &lt;&lt; "x" &lt;&lt; _desc.Height &lt;&lt; "\n\n\n";
  
      _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_FLAG::D3D11_CPU_ACCESS_READ;
      _desc.Usage = D3D11_USAGE::D3D11_USAGE_STAGING;
  
      while (!CaptureScreen(_result));
      _result = cv::Mat(_desc.Height, _desc.Width, CV_8UC4, _resource.pData);
      return true;
  }
  </code></pre>
  
  <p>And the capture function:</p>
  
  <pre><code>bool DXGIScreenCapturer::CaptureScreen(cv::Mat&amp; output)
  {
      HRESULT hr(E_FAIL);
      ComPtr&lt;IDXGIResource&gt; lDesktopResource = nullptr;
      DXGI_OUTDUPL_FRAME_INFO lFrameInfo;
      ID3D11Texture2D* currTexture = NULL;
  
      hr = _lDeskDupl-&gt;AcquireNextFrame(999, &amp;lFrameInfo, &amp;lDesktopResource);
  
      if (FAILED(hr))
          return false;
  
      if (lFrameInfo.LastPresentTime.HighPart == 0) // not interested in just mouse updates, which can happen much faster than 60fps if you really shake the mouse
      {
          hr = _lDeskDupl-&gt;ReleaseFrame();
          return false;
      }
  
      //int accum_frames = lFrameInfo.AccumulatedFrames;
      //if (accum_frames &gt; 1) {// &amp;&amp; current_frame != 1) {
      //                     // TOO MANY OF THESE is the problem
      //                     // especially after having to wait &gt;17ms in AcquireNextFrame()
      //}
  
      // QI for ID3D11Texture2D
      hr = lDesktopResource.As(&amp;_lAcquiredDesktopImage);
  
      // Copy image into a newly created CPU access texture
      hr = _lDevice-&gt;CreateTexture2D(&amp;_desc, NULL, &amp;currTexture);
      if (FAILED(hr))
      {
          hr = _lDeskDupl-&gt;ReleaseFrame();
          return false;
      }
      if (!currTexture)
      {
          hr = _lDeskDupl-&gt;ReleaseFrame();
          return false;
      }
  
      _lImmediateContext-&gt;CopyResource(currTexture, _lAcquiredDesktopImage.Get());
      UINT subresource = D3D11CalcSubresource(0, 0, 0);
      _lImmediateContext-&gt;Map(currTexture, subresource, D3D11_MAP_READ, 0, &amp;_resource);
      _lImmediateContext-&gt;Unmap(currTexture, 0);
      currTexture-&gt;Release();
      hr = _lDeskDupl-&gt;ReleaseFrame();
  
      output = _result;
      return true;
  }
  </code></pre>