Exemplo n.º 1
0
void D3D10Grab(ID3D10Texture2D* pBackBuffer) {

    D3D10_TEXTURE2D_DESC tex_desc;
    pBackBuffer->GetDesc(&tex_desc);

    ID3D10Device *pDev;
    pBackBuffer->GetDevice(&pDev);

    ID3D10Texture2D * pTexture;
    D3D10_MAPPED_TEXTURE2D mappedTexture;
    tex_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
    tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    tex_desc.ArraySize = 1;
    tex_desc.MipLevels = 1;
    tex_desc.BindFlags = 0;
    tex_desc.SampleDesc.Count = 1;
    tex_desc.SampleDesc.Quality = 0;
    tex_desc.Usage = D3D10_USAGE_STAGING;
    tex_desc.MiscFlags = 0;

    HRESULT hr = pDev->CreateTexture2D(&tex_desc, NULL, &pTexture);
#ifdef DEBUG
    reportLog(EVENTLOG_INFORMATION_TYPE, L"pDev->CreateTexture2D 0x%x", hr);
#endif
    pDev->CopyResource(pTexture, pBackBuffer);
    D3D10_BOX box = {0, 0, tex_desc.Width, tex_desc.Height, 0, 1};
    pDev->CopySubresourceRegion(pTexture, 0, 0, 0, 0, pBackBuffer, 0, &box);

    DxgiFrameGrabber *dxgiFrameGrabber = DxgiFrameGrabber::getInstance();
    IPCContext *ipcContext = dxgiFrameGrabber->m_ipcContext;
    Logger *logger = dxgiFrameGrabber->m_logger;

    if (S_OK != (hr = pTexture->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ, 0, &mappedTexture))) {
        logger->reportLogError(L"d3d10 couldn't map texture, hresult = 0x%x", hr);
        goto end;
    }

    ipcContext->m_memDesc.width = tex_desc.Width;
    ipcContext->m_memDesc.height = tex_desc.Height;
    ipcContext->m_memDesc.rowPitch = mappedTexture.RowPitch;
    ipcContext->m_memDesc.format = BufferFormatAbgr;
    ipcContext->m_memDesc.frameId++;

//    reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 texture description. width: %u, height: %u, pitch: %u", tex_desc.Width, tex_desc.Height, mappedTexture.RowPitch);

    DWORD errorcode;
    if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) {
        //            __asm__("int $3");
//        reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing description to mem mapped file");
        memcpy(ipcContext->m_pMemMap, &ipcContext->m_memDesc, sizeof (ipcContext->m_memDesc));
//        reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing data to mem mapped file");
        PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc));
        if (mappedTexture.RowPitch == tex_desc.Width * 4) {
            memcpy(pMemDataMap, mappedTexture.pData, tex_desc.Width * tex_desc.Height * 4);
        } else {
            UINT cleanOffset = 0, pitchOffset = 0, i = 0;
            while (i < tex_desc.Height) {
                memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(mappedTexture.pData, pitchOffset), tex_desc.Width * 4);
                cleanOffset += tex_desc.Width * 4;
                pitchOffset += mappedTexture.RowPitch;
                i++;
            }
        }
        ReleaseMutex(ipcContext->m_hMutex);
        SetEvent(ipcContext->m_hFrameGrabbedEvent);
    } else {
        logger->reportLogError(L"d3d10 couldn't wait mutex. errocode = 0x%x", errorcode);
    }

    pTexture->Unmap(D3D10CalcSubresource(0, 0, 1));

end:
    pTexture->Release();
    pDev->Release();
}
Exemplo n.º 2
0
HRESULT WINAPI D3D9Present(IDirect3DDevice9 *pDev, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) {
    D3D9FrameGrabber *d3d9FrameGrabber = D3D9FrameGrabber::getInstance();
    Logger *logger = d3d9FrameGrabber->m_logger;
    DWORD errorcode;
    if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(d3d9FrameGrabber->m_syncRunMutex, 0))) {
        IPCContext *ipcContext = d3d9FrameGrabber->m_ipcContext;
        logger->reportLogDebug(L"D3D9Present");
        HRESULT hRes;

        RECT newRect = RECT();
        IDirect3DSurface9 *pBackBuffer = NULL;
        IDirect3DSurface9 *pDemultisampledSurf = NULL;
        IDirect3DSurface9 *pOffscreenSurf = NULL;
        IDirect3DSwapChain9 *pSc = NULL;
        D3DPRESENT_PARAMETERS params;

        if(FAILED( hRes = pDev->GetSwapChain(0, &pSc))) {
            logger->reportLogError(L"d3d9present couldn't get swapchain. result 0x%x", hRes);
            goto end;
        }

        hRes = pSc->GetPresentParameters(&params);
        if (FAILED(hRes) || params.Windowed) {
            goto end;
        }

        if(FAILED( hRes = pDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) {
            goto end;
        }

        D3DSURFACE_DESC surfDesc;
        pBackBuffer->GetDesc(&surfDesc);

        hRes = pDev->CreateRenderTarget(
            surfDesc.Width, surfDesc.Height,
            surfDesc.Format, D3DMULTISAMPLE_NONE, 0, false,
            &pDemultisampledSurf, NULL );
        if (FAILED(hRes))
        {
            logger->reportLogError(L"GetFramePrep: FAILED to create demultisampled render target. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format );
            goto end;
        }

        hRes = pDev->StretchRect(pBackBuffer, NULL, pDemultisampledSurf, NULL, D3DTEXF_LINEAR );
        if (FAILED(hRes))
        {
            logger->reportLogError(L"GetFramePrep: StretchRect FAILED for image surfacee. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format );
            goto end;
        }

        hRes = pDev->CreateOffscreenPlainSurface(
            surfDesc.Width, surfDesc.Height,
            surfDesc.Format, D3DPOOL_SYSTEMMEM,
            &pOffscreenSurf, NULL );
        if (FAILED(hRes))
        {
            logger->reportLogError(L"GetFramePrep: FAILED to create image surface. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format );
            goto end;
        }

        hRes = pDev->GetRenderTargetData(pDemultisampledSurf, pOffscreenSurf );
        if (FAILED(hRes))
        {
            logger->reportLogError(L"GetFramePrep: GetRenderTargetData() FAILED for image surfacee. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format );
            goto end;
        }

        D3DLOCKED_RECT lockedSrcRect;
        newRect.right = surfDesc.Width;
        newRect.bottom = surfDesc.Height;
        hRes = pOffscreenSurf->LockRect( &lockedSrcRect, &newRect, 0);
        if (FAILED(hRes))
        {
            logger->reportLogError(L"GetFramePrep: FAILED to lock source rect. (0x%x)", hRes );
            goto end;
        }

        ipcContext->m_memDesc.width = surfDesc.Width;
        ipcContext->m_memDesc.height = surfDesc.Height;
        ipcContext->m_memDesc.rowPitch = lockedSrcRect.Pitch;
        ipcContext->m_memDesc.frameId++;
        ipcContext->m_memDesc.format = getCompatibleBufferFormat(surfDesc.Format);

        DWORD errorcode;
        if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) {
    //        reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d9 writing description to mem mapped file");
            memcpy(ipcContext->m_pMemMap, &(ipcContext->m_memDesc), sizeof (ipcContext->m_memDesc));
    //        reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d9 writing data to mem mapped file");
            PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc));
            if (static_cast<UINT>(lockedSrcRect.Pitch) == surfDesc.Width * 4) {
                memcpy(pMemDataMap, lockedSrcRect.pBits, surfDesc.Width * surfDesc.Height * 4);
            } else {
                UINT i = 0, cleanOffset = 0, pitchOffset = 0;
                while (i < surfDesc.Height) {
                    memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(lockedSrcRect.pBits, pitchOffset), surfDesc.Width * 4);
                    cleanOffset += surfDesc.Width * 4;
                    pitchOffset += lockedSrcRect.Pitch;
                    i++;
                }
            }
            ReleaseMutex(ipcContext->m_hMutex);
            SetEvent(ipcContext->m_hFrameGrabbedEvent);
        } else {
            logger->reportLogError(L"d3d9 couldn't wait mutex. errocode = 0x%x", errorcode);
        }
        end:
        if(pOffscreenSurf) pOffscreenSurf->Release();
        if(pDemultisampledSurf) pDemultisampledSurf->Release();
        if(pBackBuffer) pBackBuffer->Release();
        if(pSc) pSc->Release();

        ProxyFuncJmp *d3d9PresentProxyFuncJmp = d3d9FrameGrabber->m_d3d9PresentProxyFuncJmp;
        if(!d3d9PresentProxyFuncJmp->removeHook()) {
            int i = GetLastError();
            logger->reportLogError(L"d3d9 error occured while trying to removeHook before original call0x%x", i);
        }
        HRESULT result = pDev->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);

        if(!d3d9PresentProxyFuncJmp->installHook()) {
            int i = GetLastError();
            logger->reportLogError(L"d3d9 error occured while trying to installHook after original call0x%x", i);
        }
        ReleaseMutex(d3d9FrameGrabber->m_syncRunMutex);

        return result;
    } else {
        logger->reportLogError(L"d3d9sc present is skipped because mutex is busy");
        return S_FALSE;
    }
}