问题
Good afternoon. I apologize in advance for my bad code, because I have not yet brought it into a good form. The bottom line is to take pixels from the desktop at 60 fps, but mine runs at 10 fps and also uses too much memory. Please help me understand where I was wrong, thanks.
I had an assumption that I was not resetting something, but I think have taken this into account by calling SAFE_RELEASE.
To get the pixels, I used this code: How to access pixels data from ID3D11Texture2D?
#include "D3D9.h"
#include <d3d11.h>
#include <dxgi1_2.h>
#include <windows.h>
#include <dxgi1_2.h>
#include <d3d11.h>
#include <iostream>
#pragma comment(lib, "D3D11.lib")
#pragma comment(lib, "D3d9.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "gdi32.lib")
//using namespace System;
#define EXIT(hr) { if (FAILED(hr)) \
{std::cout<<"ERROR"<<std::endl; return -1; } }
#if !defined(SAFE_RELEASE)
#define SAFE_RELEASE(X) if(X){X->Release(); X=nullptr;}
#endif
HBITMAP GetPix(ID3D11Texture2D* d3dtex, ID3D11Device* pDevice)
{
HRESULT hr;
DXGI_OUTDUPL_DESC OutputDuplDesc;
ID3D11Texture2D* pNewTexture = NULL;
D3D11_TEXTURE2D_DESC description;
d3dtex->GetDesc(&description);
description.BindFlags = 0;
description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
description.Usage = D3D11_USAGE_STAGING;
description.MiscFlags = 0;
if (FAILED(pDevice->CreateTexture2D(&description, NULL, &pNewTexture)))
{
return NULL;
}
ID3D11DeviceContext* ctx = NULL;
pDevice->GetImmediateContext(&ctx);
ctx->CopySubresourceRegion(pNewTexture, D3D11CalcSubresource(0, 0, 1), 0, 0, 0, d3dtex, 0, NULL);
D3D11_MAPPED_SUBRESOURCE resource;
ctx->Map(pNewTexture, D3D11CalcSubresource(0, 0, 0), D3D11_MAP_READ_WRITE, 0, &resource);
BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
std::cout << (int)sptr[2000] << " " << (int)sptr[2001] <<" " << (int)sptr[2002] << std::endl;
SAFE_RELEASE(pNewTexture);
SAFE_RELEASE(ctx);
}
int main()
{
HRESULT hr;
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
D3D_FEATURE_LEVEL d3dFeatLvl;
ID3D11Device* pDevice = nullptr;
ID3D11DeviceContext* pImmediateContext = nullptr;
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE,
NULL, 0, featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&pDevice,
&d3dFeatLvl,
&pImmediateContext);
EXIT(hr);
IDXGIDevice* DxgiDevice = nullptr;
hr = pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
IDXGIAdapter* DxgiAdapter = nullptr;
hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
EXIT(hr);
IDXGIOutput* DxgiOutput = nullptr;
hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
EXIT(hr);
DXGI_OUTPUT_DESC OutputDesc;
DxgiOutput->GetDesc(&OutputDesc);
IDXGIOutput1* DxgiOutput1 = nullptr;
hr = DxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&DxgiOutput1));
EXIT(hr);
IDXGIOutputDuplication* DeskDupl = nullptr;
hr = DxgiOutput1->DuplicateOutput(pDevice, &DeskDupl);
EXIT(hr);
DXGI_OUTDUPL_DESC OutputDuplDesc;
DeskDupl->GetDesc(&OutputDuplDesc);
ID3D11Texture2D* AcquiredDesktopImage = nullptr;
IDXGIResource* DesktopResource = nullptr;
DXGI_OUTDUPL_FRAME_INFO FrameInfo;
while (1) {
for (; ; )
{
hr = DeskDupl->AcquireNextFrame(60, &FrameInfo, &DesktopResource);
if (hr != 0) {
continue;
}
if (FrameInfo.LastPresentTime.QuadPart == 0)
{
hr = DesktopResource->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>
(&AcquiredDesktopImage));
DesktopResource->Release();
hr = DeskDupl->ReleaseFrame();
EXIT(hr);
continue;
}
GetPix(AcquiredDesktopImage, pDevice);
break;
}
DeskDupl->ReleaseFrame();
SAFE_RELEASE(DesktopResource);
SAFE_RELEASE(DeskDupl);
SAFE_RELEASE(pImmediateContext);
SAFE_RELEASE(pDevice);
SAFE_RELEASE(DxgiDevice);
SAFE_RELEASE(DxgiAdapter);
SAFE_RELEASE(DxgiOutput);
SAFE_RELEASE(DxgiOutput1);
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE,
NULL, D3D11_CREATE_DEVICE_DEBUG, featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
&pDevice,
&d3dFeatLvl,
&pImmediateContext);
EXIT(hr);
hr = pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&DxgiDevice));
EXIT(hr);
hr = DxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&DxgiAdapter));
EXIT(hr);
hr = DxgiAdapter->EnumOutputs(0, &DxgiOutput);
EXIT(hr);
DxgiOutput->GetDesc(&OutputDesc);
hr = DxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&DxgiOutput1));
EXIT(hr);
hr = DxgiOutput1->DuplicateOutput(pDevice, &DeskDupl);
EXIT(hr);
DeskDupl->GetDesc(&OutputDuplDesc);
}
//GetPix(AcquiredDesktopImage, pDevice);
//GETRGB(AcquiredDesktopImage, pDevice);
return 0;
}
来源:https://stackoverflow.com/questions/65066779/dxgi-scans-pixels-at-10-fps-and-uses-more-memory