#include "Main.h"
const bool UseVideoForWindowsCapture = false;
ExternalWindowCapture::~ExternalWindowCapture()
{
}
void ExternalWindowCapture::FreeMemory()
{
if(_PlainSurface)
{
_PlainSurface->Release();
_PlainSurface = NULL;
}
if(_Device)
{
_Device->Release();
_Device = NULL;
}
if(_Compressor.Capturing())
{
_Compressor.FreeMemory();
}
}
void ExternalWindowCapture::LoadPresentationParameters(D3DPRESENT_PARAMETERS &PresentationParameters)
{
PresentationParameters.Windowed = TRUE;
PresentationParameters.BackBufferWidth = 0;
PresentationParameters.BackBufferHeight = 0;
PresentationParameters.BackBufferFormat = D3DFMT_UNKNOWN;
PresentationParameters.BackBufferCount = 0;
PresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
PresentationParameters.MultiSampleQuality = 0;
PresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresentationParameters.hDeviceWindow = NULL;
PresentationParameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
PresentationParameters.EnableAutoDepthStencil = FALSE;
PresentationParameters.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
PresentationParameters.Flags = 0;
}
UINT ExternalWindowCapture::Init(const String &Filename, HWND Window, UINT BitRate, UINT FrameRate, UINT AudioDeviceIndex)
{
_Window = Window;
if(!IsWindow(Window))
{
MessageBox(NULL, "The selected window is not valid.", "Invalid Window", MB_OK | MB_ICONERROR);
return 1;
}
if(UseVideoForWindowsCapture)
{
}
else
{
IDirect3D9* D3D = Direct3DCreate9(D3D_SDK_VERSION);
PersistentAssert(D3D != NULL, "Direct3DCreate9 failed");
D3DPRESENT_PARAMETERS PresentationParameters;
LoadPresentationParameters(PresentationParameters);
HRESULT hr = D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &PresentationParameters, &_Device);
if(FAILED(hr))
{
MessageBox(NULL, "The selected window is not valid.", "Invalid Window", MB_OK | MB_ICONERROR);
return 1;
}
D3D->Release();
}
RECT ClientRect;
GetClientRect(_Window, &ClientRect);
MapWindowPoints(_Window, HWND_DESKTOP, (LPPOINT)&ClientRect, 2);
_Dimensions = Rectangle2i(ClientRect).Dimensions();
while(_Dimensions.x % 4 != 0)
{
_Dimensions.x++;
}
while(_Dimensions.y % 4 != 0)
{
_Dimensions.y++;
}
_Clock = new Clock;
_Clock->Start();
return _Compressor.OpenFile(Filename, _Dimensions.x, _Dimensions.y, BitRate, FrameRate, AudioDeviceIndex, _Clock);
}
void ExternalWindowCapture::Capture()
{
HRESULT hr = _Device->TestCooperativeLevel();
if(FAILED(hr))
{
if(_PlainSurface)
{
_PlainSurface->Release();
_PlainSurface = NULL;
}
if(hr == D3DERR_DEVICENOTRESET)
{
D3DPRESENT_PARAMETERS PresentationParameters;
LoadPresentationParameters(PresentationParameters);
_Device->Reset(&PresentationParameters);
}
return;
}
if(_PlainSurface == NULL)
{
D3DDISPLAYMODE DisplayMode;
IDirect3DSwapChain9* SwapChain;
_Device->GetSwapChain(0, &SwapChain);
SwapChain->GetDisplayMode(&DisplayMode);
SwapChain->Release();
HRESULT hr = _Device->CreateOffscreenPlainSurface(DisplayMode.Width, DisplayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &_PlainSurface, NULL);
PersistentAssert(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed");
}
RECT ClientRect;
GetClientRect(_Window, &ClientRect);
MapWindowPoints(_Window, HWND_DESKTOP, (LPPOINT)&ClientRect, 2);
hr = _Device->GetFrontBufferData(0, _PlainSurface);
PersistentAssert(SUCCEEDED(hr), "GetFrontBufferData failed");
_Compressor.AddFrame(_PlainSurface, Rectangle2i(ClientRect).Min, 0.0);
}