Comments (4)
The swap chain is only to display the contents of the frame, it's not part of capturing the screen. The texture is held in the Direct3D11CaptureFrame
object in its Surface property. You can see that the sample gets the ID3D11Texture2D
from the Surface property here:
auto surfaceTexture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
From there, you need to copy the texture to a staging texture (use D3D11_USAGE_STAGING and D3D11_CPU_ACCESS_READ flags during texture creation) and then map the staging texture. You'll be able to access the bits after that.
from win32capturesample.
Hello @robmikh
Sorry to bother. I have spent some time trying to figure it out based on your explanation. Can you look at the code see if am on the right track?
void SimpleCapture::OnFrameArrived(winrt::Direct3D11CaptureFramePool const& sender, winrt::IInspectable const&)
{
auto frame = sender.TryGetNextFrame();
winrt::com_ptr<ID3D11Texture2D> backBuffer;
winrt::check_hresult(m_swapChain->GetBuffer(0, winrt::guid_of<ID3D11Texture2D>(), backBuffer.put_void()));
auto surfaceTexture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
/* Prepare for accessing data bits */
// Get the device context
ID3D11Device* d3dDevice;
surfaceTexture->GetDevice(&d3dDevice);
ID3D11DeviceContext* d3dContext;
d3dDevice->GetImmediateContext(&d3dContext);
// map the texture
D3D11_MAPPED_SUBRESOURCE mapInfo;
mapInfo.RowPitch;
HRESULT hr = d3dContext->Map(
surfaceTexture.get(),
0, // Subresource
D3D11_MAP_READ,
0, // MapFlags
&mapInfo);
D3D11_TEXTURE2D_DESC desc;
surfaceTexture->GetDesc(&desc);
D3D11_TEXTURE2D_DESC desc2;
desc2.Width = desc.Width;
desc2.Height = desc.Height;
desc2.MipLevels = desc.MipLevels;
desc2.ArraySize = desc.ArraySize;
desc2.Format = desc.Format;
desc2.SampleDesc = desc.SampleDesc;
desc2.Usage = D3D11_USAGE_STAGING;
desc2.BindFlags = 0;
desc2.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
desc2.MiscFlags = 0;
ID3D11Texture2D* stagingTexture = NULL;
hr = d3dDevice->CreateTexture2D(&desc2, nullptr, &stagingTexture);
if (FAILED(hr)) {
// throw std::invalid_argument("received negative value");
std::cout << "Failed to create staging texture";
}
// copy the texture to a staging resource
d3dContext->CopyResource(stagingTexture, surfaceTexture.get());
// now, map the staging resource
hr = d3dContext->Map(stagingTexture, 0, D3D11_MAP_READ, 0, &mapInfo);
if (FAILED(hr)) {
// throw std::invalid_argument("received negative value");
std::cout << "Failed to map staging texture";
}
// Frame data is here??
mapInfo.pData;
}
from win32capturesample.
You're on the right track 🙂
Some things to consider:
- If you're doing this for more than one frame, I would suggest creating and caching 1 staging texture to use for this purpose. Then, every time a frame comes in you copy the frame to the staging texture and map it. You will know the dimensions ahead of time, because they will match what you used to set up the
Direct3D11CaptureFramePool
and will only change when you callRecreate
. That way you only have to create a new staging texture when/if you callRecreate
. - Make sure you call
Unmap
after you're done with the bits. I would suggest copying the bits if you need to pass this off to some other processing pipeline. - Textures may occupy more video memory than what you might expect given its dimensions and pixel format. Pay attention to the
RowPitch
field of theD3D11_MAPPED_SUBRESOURCE
struct. Copying out the bits would look something like this:
D3D11_MAPPED_SUBRESOURCE mapped = {};
winrt::check_hresult(d3dContext->Map(bitmap.get(), 0, D3D11_MAP_READ, 0, &mapped));
std::vector<byte> bits(desc.Width * desc.Height * bytesPerPixel, 0);
auto source = reinterpret_cast<byte*>(mapped.pData);
auto dest = bits.data();
for (auto i = 0; i < (int)desc.Height; i++)
{
memcpy(dest, source, desc.Width * bytesPerPixel);
source += mapped.RowPitch;
dest += desc.Width * bytesPerPixel;
}
d3dContext->Unmap(bitmap.get(), 0);
from win32capturesample.
Thanks alot! 🙂
from win32capturesample.
Related Issues (20)
- Graphics Capture doesn't work when running as different user? HOT 6
- Help: Clarification HOT 2
- Simple recorder is giving error in WinUI3 HOT 2
- The quality of the captured picture is worse than that of the window HOT 4
- how to capture child window? HOT 2
- The effect of Borderless will be reset when desktop resolution changed HOT 1
- The performance overhead of capturing the desktop is too high. HOT 1
- How reliable is Windows Graphics Desktop Capture in replicating the monitor frames ? HOT 9
- Possible Problem With Some Apps HOT 1
- How to convert Bgra to Rgba HOT 1
- Windows 11 22H2 OS build 10.0.22621.2428: CreateCaptureSession(item) does not return and hangs HOT 28
- winrt::windows::Graphics::Capture::GraphicsCaptureSession.Close() hangs on Windows 10 HOT 8
- C++ docs for winrt HOT 1
- no callable 'await_resume' function found for type 'winrt::Windows::System::DispatcherQueue' HOT 2
- check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Graphics::Capture::IDirect3D11CaptureFramePoolStatics)->Create(*(void**)(&device), static_cast<int32_t>(pixelFormat), numberOfBuffers, impl::bind_in(size), &result)); HOT 4
- some questions about threading model HOT 1
- How to copy the captured frame data to CUDA directly without copy to CPU first? HOT 1
- How to convert captured frames to opencv matrix? HOT 2
- additional requirement HOT 1
- DDA capture slow framerate on Windows 10 vs Windows 8.1 VMs HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from win32capturesample.