Jump to content
  • Advertisement
Jack Fu

DX11 [DirectX11]How to capture the rendered scene D3D11?

This topic is 439 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am writing code for capturing Skype video call for windows 10, I am facing an issue as following:

1). Skype use Directx11, and I am able to hook into the IDXGISwapChain::Present, and use code as below to capture the screenshot:

ID3D11Device *device = NULL;
	HRESULT hr = pswap->GetDevice(__uuidof(ID3D11Device), (void**)&device);
	if (hr != S_OK)
	{
		OutputDebugStringA("++++++++ GetDevice failed ++++++");
		return;
	}
	ID3D11DeviceContext *context;
	device->GetImmediateContext(&context);

	ID3D11Texture2D* backBuffer = nullptr;
	hr = pswap->GetBuffer(0, __uuidof(*backBuffer), (LPVOID*)&backBuffer);
	if (hr != S_OK)
	{
		OutputDebugStringA("++++++++ IDXGISwapChain::GetBuffer failed++++++");
		return;
	}

	//Save to a JPG file
    hr = SaveWICTextureToFile(context, backBuffer,
			GUID_ContainerFormatJpeg, strScreenPath);


	SafeRelease(device);
	SafeRelease(context);
	SafeRelease(backBuffer);

The problem is what I captured is either the local video frame(camera) or the remote video frame, what I want to capture is synthetic image, just like I see on the Skype window during a video call, I remember that in D3D9, there is a GetRenderTargetData() to retrieve the raw data from the back buffer, and it contains the rendered scene which is the same as I see on the Skype window during the video call, but I can't find a way to do this in D3D11....

Any advise is appreciated.

 

Share this post


Link to post
Share on other sites
Advertisement

HI!

Doesn't Skype have like a floating window to show the remote camera? Maybe they are rendering to two different windows and you should have to do some compositing.

Share this post


Link to post
Share on other sites

Hi piluve, 

Thanks for your reply, I checked the OutputWindow in the DXGI_SWAP_CHAIN_DESC, the value is NULL.

And there is only one swap chain instance as well.


 

Share this post


Link to post
Share on other sites

You could also try to use the ID3D11DeviceContext::OMGetRenderTargets() and then get the resource from the returned view.

Edited by piluve

Share this post


Link to post
Share on other sites

Yes, actually I tried this as well, see the code below:

	ID3D11Texture2D* pbackBuffer = nullptr;
	hr = pswap->GetBuffer(0, __uuidof(*pbackBuffer), (LPVOID*)&pbackBuffer);
	if (hr != S_OK)
	{
		OutputDebugStringA("++++++++ IDXGISwapChain::GetBuffer failed++++++");
		SafeRelease(device);
		SafeRelease(pcontext);
		return hr;
	}

	ID3D11RenderTargetView *pRenderTargetView = NULL;
	// use the back buffer address to create the render target
	hr = device->CreateRenderTargetView(pbackBuffer, NULL, &pRenderTargetView);
	if (hr != S_OK)
	{
		OutputDebugStringA("++++++++ IDXGISwapChain::CreateRenderTargetView failed++++++");
		SafeRelease(device);
		SafeRelease(pcontext);
		return hr;
	}

	pcontext->OMSetRenderTargets(1, &pRenderTargetView, NULL);

	ID3D11Resource* pRenderTRes = NULL;
	pRenderTargetView->GetResource(&pRenderTRes);

    hr = SaveWICTextureToFile(pcontext, pRenderTRes,
			GUID_ContainerFormatJpeg, strScreenPath);

The image captured is still either the local camera or the remote camera, not the mixing finial image show in the call window..

 

Share this post


Link to post
Share on other sites

Its strange that there is only one window. If you check this:

screen_shot_2014-10-08_at_8.19.12_pm.jpg

It looks like the local camera is in a second window ...

Share this post


Link to post
Share on other sites

Oh, sorry, the "Skype" means the "Skype UWP"/"Skype For Windows 10" version instead of the desktop version.

The strange thing is the "OutputWindow" is NULL.

Edited by Jack Fu

Share this post


Link to post
Share on other sites

Yeah that is strange, the spec says...

 
OutputWindow
Type: HWND
An HWND handle to the output window. This member must not be NULL.

 

Maybe that swap chain is invalid but then how you are able to get the surface...

 

 

Edited by piluve

Share this post


Link to post
Share on other sites

You're looking at a DComp app. Yes, there are swapchains involved, but no individual surface in the app contains the entire contents of the window. The reason the HWND is null is because it's a composition swapchain, not a standard HWND swapchain. See the IDXGIFactory2 CreateSwapChain methods.

The only way to capture the contents of the app is to capture the desktop and isolate the app, or to capture the individual pieces of the app and re-composite them.

Share this post


Link to post
Share on other sites

Hi SoldierOfLight, thanks for your reply.

Skype UWP doesn't use DComp libary since there is no according .dll found in the process.

Besides, it doesn't use  IDXGIFactory2 CreateSwapChain methods either, since I have hooked all the methods of IDXGIFactory2/IDXGISwapChainX, it just never called, only IDXGISwapChain is created.

Any ideas?

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!