2017-04-26 1 views
1

저는 Windows Desktop Duplication API를 사용하여 자체 미러링 프로토콜을 사용하고 있습니다. 어떻게에을 추출합니다 BYTE * 또는 unsigned char * 및 수ID3D11Texture2D에서 픽셀 데이터에 액세스하는 방법은 무엇입니까?

`typedef struct _FRAME_DATA { 
ID3D11Texture2D* Frame; 
DXGI_OUTDUPL_FRAME_INFO FrameInfo; 
_Field_size_bytes_((MoveCount * sizeof(DXGI_OUTDUPL_MOVE_RECT)) + (DirtyCount * sizeof(RECT))) BYTE* MetaData; 
UINT DirtyCount; 
UINT MoveCount; 
} FRAME_DATA;` 

내가 ID3D11Texture2D* Frame; 에서 픽셀 버퍼를 추출하고 싶습니다 :

여기
// Get new frame 
HRESULT hr = m_DeskDupl->AcquireNextFrame(500, &FrameInfo, &DesktopResource); 
if (hr == DXGI_ERROR_WAIT_TIMEOUT) 
{ 
    *Timeout = true; 
    return DUPL_RETURN_SUCCESS; 
} 

FrameInfo 구조 : 나는이 코드 조각이 RGB 시퀀스? 감사합니다.

답변

3

당신은, ID3D11Device::CreateTexture2D를 사용하여 CPU 읽기 액세스와 같은 크기의 두 번째 텍스처를 만들 필요가 ID3D11DeviceContext::CopyResource 또는 ID3D11DeviceContext::CopySubresourceRegion를 사용하여 GPU에이 텍스처 전체 프레임하거나 업데이트 된 부분을 복사 (IDXGIOutputDuplication::GetFrameDirtyRects를 사용하여 업데이트 된 부품을 검색 할 수있다 및 IDXGIOutputDuplication::GetFrameMoveRects) 두 번째 텍스처를 ID3D11DeviceContext::Map을 사용하여 CPU에서 액세스 할 수 있도록 매핑하면 D3D11_MAPPED_SUBRESOURCE 프레임 데이터와 버퍼의 포인터를 포함하는 구조체와 크기를 찾고 있습니다.

Microsoft는 위에 언급 된 모든 단계를 rather detailed Desktop Duplication API usage sample에 제공합니다.

straight sample demonstrating how to save ID3D11Texture2D data to file도 있습니다.

1

안녕하세요. 귀하의 요구 사항에 도움이되는 코드는 다음과 같습니다. 출력은 UCHAR 버퍼에 있습니다 g_iMageBuffer

//Variable Declaration 
IDXGIOutputDuplication* IDeskDupl; 
IDXGIResource*   lDesktopResource = nullptr; 
DXGI_OUTDUPL_FRAME_INFO IFrameInfo; 
ID3D11Texture2D*  IAcquiredDesktopImage; 
ID3D11Texture2D*  lDestImage; 
ID3D11DeviceContext* lImmediateContext; 
UCHAR*     g_iMageBuffer=nullptr; 

//Screen capture start here 
hr = lDeskDupl->AcquireNextFrame(20, &lFrameInfo, &lDesktopResource); 

// >QueryInterface for ID3D11Texture2D 
hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&lAcquiredDesktopImage)); 
lDesktopResource.Release(); 

// Copy image into GDI drawing texture 
lImmediateContext->CopyResource(lDestImage,lAcquiredDesktopImage); 
lAcquiredDesktopImage.Release(); 
lDeskDupl->ReleaseFrame(); 

// Copy GPU Resource to CPU 
D3D11_TEXTURE2D_DESC desc; 
lDestImage->GetDesc(&desc); 
D3D11_MAPPED_SUBRESOURCE resource; 
UINT subresource = D3D11CalcSubresource(0, 0, 0); 
lImmediateContext->Map(lDestImage, subresource, D3D11_MAP_READ_WRITE, 0, &resource); 

std::unique_ptr<BYTE> pBuf(new BYTE[resource.RowPitch*desc.Height]); 
UINT lBmpRowPitch = lOutputDuplDesc.ModeDesc.Width * 4; 
BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData); 
BYTE* dptr = pBuf.get() + resource.RowPitch*desc.Height - lBmpRowPitch; 
UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch); 

for (size_t h = 0; h < lOutputDuplDesc.ModeDesc.Height; ++h) 
{ 
    memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch); 
    sptr += resource.RowPitch; 
    dptr -= lBmpRowPitch; 
} 

lImmediateContext->Unmap(lDestImage, subresource); 
long g_captureSize=lRowPitch*desc.Height; 
g_iMageBuffer= new UCHAR[g_captureSize]; 
g_iMageBuffer = (UCHAR*)malloc(g_captureSize); 

//Copying to UCHAR buffer 
memcpy(g_iMageBuffer,pBuf,g_captureSize); 
관련 문제