diff --git a/GraphicsCapture/GraphicsCapture.cpp b/GraphicsCapture/GraphicsCapture.cpp index d24241e5..f33cb070 100644 --- a/GraphicsCapture/GraphicsCapture.cpp +++ b/GraphicsCapture/GraphicsCapture.cpp @@ -77,6 +77,10 @@ void RefreshWindowList(HWND hwndCombobox, ConfigDialogData &configData) RECT clientRect; GetClientRect(hwndCurrent, &clientRect); + String strWindowName; + strWindowName.SetLength(GetWindowTextLength(hwndCurrent)); + GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1); + HWND hwndParent = GetParent(hwndCurrent); DWORD exStyles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_EXSTYLE); @@ -84,9 +88,6 @@ void RefreshWindowList(HWND hwndCombobox, ConfigDialogData &configData) if((exStyles & WS_EX_TOOLWINDOW) == 0 && (styles & WS_CHILD) == 0 /*&& hwndParent == NULL*/) { - String strWindowName; - strWindowName.SetLength(GetWindowTextLength(hwndCurrent)); - GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1); //------- diff --git a/GraphicsCapture/GraphicsCapture.h b/GraphicsCapture/GraphicsCapture.h index c6f64b52..56d60008 100644 --- a/GraphicsCapture/GraphicsCapture.h +++ b/GraphicsCapture/GraphicsCapture.h @@ -58,4 +58,5 @@ inline BOOL Is64BitWindows() #include "MemoryCapture.h" #include "SharedTexCapture.h" +#include "WindowCapture.h" #include "GraphicsCaptureSource.h" diff --git a/GraphicsCapture/GraphicsCapture.vcxproj b/GraphicsCapture/GraphicsCapture.vcxproj index d612be17..48c3f782 100644 --- a/GraphicsCapture/GraphicsCapture.vcxproj +++ b/GraphicsCapture/GraphicsCapture.vcxproj @@ -215,6 +215,7 @@ + @@ -223,6 +224,7 @@ + diff --git a/GraphicsCapture/GraphicsCapture.vcxproj.filters b/GraphicsCapture/GraphicsCapture.vcxproj.filters index 6ffdbef9..3bdbb9f1 100644 --- a/GraphicsCapture/GraphicsCapture.vcxproj.filters +++ b/GraphicsCapture/GraphicsCapture.vcxproj.filters @@ -27,6 +27,9 @@ Source + + Source + @@ -47,6 +50,9 @@ Headers + + Headers + diff --git a/GraphicsCapture/GraphicsCaptureHook/D3D10.1Capture.cpp b/GraphicsCapture/GraphicsCaptureHook/D3D10.1Capture.cpp index 7f8487b6..14c96974 100644 --- a/GraphicsCapture/GraphicsCaptureHook/D3D10.1Capture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/D3D10.1Capture.cpp @@ -51,6 +51,9 @@ void ClearD3D101Data() DestroySharedMemory(); keepAliveTime = 0; + resetCount++; + + logOutput << "---------------------- Cleared D3D10.1 Capture ----------------------" << endl; } void SetupD3D101(IDXGISwapChain *swapChain) @@ -63,15 +66,20 @@ void SetupD3D101(IDXGISwapChain *swapChain) d3d101CaptureInfo.format = ConvertGIBackBufferFormat(scd.BufferDesc.Format); if(d3d101CaptureInfo.format != GS_UNKNOWNFORMAT) { - if( dxgiFormat != scd.BufferDesc.Format || - d3d101CaptureInfo.cx != scd.BufferDesc.Width || - d3d101CaptureInfo.cy != scd.BufferDesc.Height ) + if( dxgiFormat != scd.BufferDesc.Format || + d3d101CaptureInfo.cx != scd.BufferDesc.Width || + d3d101CaptureInfo.cy != scd.BufferDesc.Height || + d3d101CaptureInfo.hwndCapture != (DWORD)scd.OutputWindow) { dxgiFormat = FixCopyTextureFormat(scd.BufferDesc.Format); d3d101CaptureInfo.cx = scd.BufferDesc.Width; d3d101CaptureInfo.cy = scd.BufferDesc.Height; d3d101CaptureInfo.hwndCapture = (DWORD)scd.OutputWindow; bIsMultisampled = scd.SampleDesc.Count > 1; + + logOutput << "found dxgi format (dx10.1) of: " << UINT(dxgiFormat) << + ", size: {" << scd.BufferDesc.Width << ", " << scd.BufferDesc.Height << + "}, multisampled: " << (bIsMultisampled ? "true" : "false") << endl; } } } @@ -102,13 +110,13 @@ bool DoD3D101Hook(ID3D10Device *device) ID3D10Texture2D *d3d101Tex; if(FAILED(hErr = device->CreateTexture2D(&texGameDesc, NULL, &d3d101Tex))) { - RUNONCE logOutput << "DoD3D101Hook: failed to create intermediary texture, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D101Hook: failed to create intermediary texture, result = " << UINT(hErr) << endl; return false; } if(FAILED(hErr = d3d101Tex->QueryInterface(__uuidof(ID3D10Resource), (void**)©D3D101TextureGame))) { - RUNONCE logOutput << "DoD3D101Hook: d3d101Tex->QueryInterface(ID3D10Resource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D101Hook: d3d101Tex->QueryInterface(ID3D10Resource) failed, result = " << UINT(hErr) << endl; d3d101Tex->Release(); return false; } @@ -116,14 +124,14 @@ bool DoD3D101Hook(ID3D10Device *device) IDXGIResource *res; if(FAILED(hErr = d3d101Tex->QueryInterface(IID_IDXGIResource, (void**)&res))) { - RUNONCE logOutput << "DoD3D101Hook: d3d101Tex->QueryInterface(IDXGIResource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D101Hook: d3d101Tex->QueryInterface(IDXGIResource) failed, result = " << UINT(hErr) << endl; d3d101Tex->Release(); return false; } if(FAILED(res->GetSharedHandle(&sharedHandle))) { - RUNONCE logOutput << "DoD3D101Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D101Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; d3d101Tex->Release(); res->Release(); return false; diff --git a/GraphicsCapture/GraphicsCaptureHook/D3D10Capture.cpp b/GraphicsCapture/GraphicsCaptureHook/D3D10Capture.cpp index 96daac2b..68c3d889 100644 --- a/GraphicsCapture/GraphicsCaptureHook/D3D10Capture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/D3D10Capture.cpp @@ -52,6 +52,9 @@ void ClearD3D10Data() DestroySharedMemory(); keepAliveTime = 0; + resetCount++; + + logOutput << "---------------------- Cleared D3D10 Capture ----------------------" << endl; } void SetupD3D10(IDXGISwapChain *swapChain) @@ -64,15 +67,20 @@ void SetupD3D10(IDXGISwapChain *swapChain) d3d10CaptureInfo.format = ConvertGIBackBufferFormat(scd.BufferDesc.Format); if(d3d10CaptureInfo.format != GS_UNKNOWNFORMAT) { - if( dxgiFormat != scd.BufferDesc.Format || - d3d10CaptureInfo.cx != scd.BufferDesc.Width || - d3d10CaptureInfo.cy != scd.BufferDesc.Height ) + if( dxgiFormat != scd.BufferDesc.Format || + d3d10CaptureInfo.cx != scd.BufferDesc.Width || + d3d10CaptureInfo.cy != scd.BufferDesc.Height || + d3d10CaptureInfo.hwndCapture != (DWORD)scd.OutputWindow) { dxgiFormat = FixCopyTextureFormat(scd.BufferDesc.Format); d3d10CaptureInfo.cx = scd.BufferDesc.Width; d3d10CaptureInfo.cy = scd.BufferDesc.Height; d3d10CaptureInfo.hwndCapture = (DWORD)scd.OutputWindow; bIsMultisampled = scd.SampleDesc.Count > 1; + + logOutput << "found dxgi format (dx10) of: " << UINT(dxgiFormat) << + ", size: {" << scd.BufferDesc.Width << ", " << scd.BufferDesc.Height << + "}, multisampled: " << (bIsMultisampled ? "true" : "false") << endl; } } } @@ -103,13 +111,13 @@ bool DoD3D10Hook(ID3D10Device *device) ID3D10Texture2D *d3d10Tex; if(FAILED(hErr = device->CreateTexture2D(&texGameDesc, NULL, &d3d10Tex))) { - RUNONCE logOutput << "DoD3D10Hook: failed to create intermediary texture, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D10Hook: failed to create intermediary texture, result = " << UINT(hErr) << endl; return false; } if(FAILED(hErr = d3d10Tex->QueryInterface(__uuidof(ID3D10Resource), (void**)©D3D10TextureGame))) { - RUNONCE logOutput << "DoD3D10Hook: d3d10Tex->QueryInterface(ID3D10Resource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D10Hook: d3d10Tex->QueryInterface(ID3D10Resource) failed, result = " << UINT(hErr) << endl; d3d10Tex->Release(); return false; } @@ -117,14 +125,14 @@ bool DoD3D10Hook(ID3D10Device *device) IDXGIResource *res; if(FAILED(hErr = d3d10Tex->QueryInterface(IID_IDXGIResource, (void**)&res))) { - RUNONCE logOutput << "DoD3D10Hook: d3d10Tex->QueryInterface(IDXGIResource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D10Hook: d3d10Tex->QueryInterface(IDXGIResource) failed, result = " << UINT(hErr) << endl; d3d10Tex->Release(); return false; } if(FAILED(res->GetSharedHandle(&sharedHandle))) { - RUNONCE logOutput << "DoD3D10Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D10Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; d3d10Tex->Release(); res->Release(); return false; diff --git a/GraphicsCapture/GraphicsCaptureHook/D3D11Capture.cpp b/GraphicsCapture/GraphicsCaptureHook/D3D11Capture.cpp index a4f0b198..6dbeee8a 100644 --- a/GraphicsCapture/GraphicsCaptureHook/D3D11Capture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/D3D11Capture.cpp @@ -54,6 +54,9 @@ void ClearD3D11Data() DestroySharedMemory(); keepAliveTime = 0; + resetCount++; + + logOutput << "---------------------- Cleared D3D11 Capture ----------------------" << endl; } void SetupD3D11(IDXGISwapChain *swapChain) @@ -66,15 +69,20 @@ void SetupD3D11(IDXGISwapChain *swapChain) d3d11CaptureInfo.format = ConvertGIBackBufferFormat(scd.BufferDesc.Format); if(d3d11CaptureInfo.format != GS_UNKNOWNFORMAT) { - if( dxgiFormat != scd.BufferDesc.Format || - d3d11CaptureInfo.cx != scd.BufferDesc.Width || - d3d11CaptureInfo.cy != scd.BufferDesc.Height ) + if( dxgiFormat != scd.BufferDesc.Format || + d3d11CaptureInfo.cx != scd.BufferDesc.Width || + d3d11CaptureInfo.cy != scd.BufferDesc.Height || + d3d11CaptureInfo.hwndCapture != (DWORD)scd.OutputWindow) { dxgiFormat = FixCopyTextureFormat(scd.BufferDesc.Format); d3d11CaptureInfo.cx = scd.BufferDesc.Width; d3d11CaptureInfo.cy = scd.BufferDesc.Height; d3d11CaptureInfo.hwndCapture = (DWORD)scd.OutputWindow; bIsMultisampled = scd.SampleDesc.Count > 1; + + logOutput << "found dxgi format (dx11) of: " << UINT(dxgiFormat) << + ", size: {" << scd.BufferDesc.Width << ", " << scd.BufferDesc.Height << + "}, multisampled: " << (bIsMultisampled ? "true" : "false") << endl; } } } @@ -105,13 +113,13 @@ bool DoD3D11Hook(ID3D11Device *device) ID3D11Texture2D *d3d11Tex; if(FAILED(hErr = device->CreateTexture2D(&texGameDesc, NULL, &d3d11Tex))) { - RUNONCE logOutput << "DoD3D11Hook: creation of intermediary texture failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D11Hook: creation of intermediary texture failed, result = " << UINT(hErr) << endl; return false; } if(FAILED(hErr = d3d11Tex->QueryInterface(__uuidof(ID3D11Resource), (void**)©TextureGame))) { - RUNONCE logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(ID3D11Resource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(ID3D11Resource) failed, result = " << UINT(hErr) << endl; d3d11Tex->Release(); return false; } @@ -119,14 +127,14 @@ bool DoD3D11Hook(ID3D11Device *device) IDXGIResource *res; if(FAILED(hErr = d3d11Tex->QueryInterface(IID_IDXGIResource, (void**)&res))) { - RUNONCE logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(IID_IDXGIResource) failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(IID_IDXGIResource) failed, result = " << UINT(hErr) << endl; d3d11Tex->Release(); return false; } if(FAILED(hErr = res->GetSharedHandle(&sharedHandle))) { - RUNONCE logOutput << "DoD3D11Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D11Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl; d3d11Tex->Release(); res->Release(); return false; @@ -209,7 +217,7 @@ void DoD3D11Capture(IDXGISwapChain *swap) d3d11CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData); if(!d3d11CaptureInfo.mapID) { - RUNONCE logOutput << "SwapPresentHook: creation of shared memory failed" << endl; + RUNEVERYRESET logOutput << "SwapPresentHook: creation of shared memory failed" << endl; bSuccess = false; } } diff --git a/GraphicsCapture/GraphicsCaptureHook/D3D9Capture.cpp b/GraphicsCapture/GraphicsCaptureHook/D3D9Capture.cpp index df8da72f..bd63db67 100644 --- a/GraphicsCapture/GraphicsCaptureHook/D3D9Capture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/D3D9Capture.cpp @@ -203,7 +203,10 @@ void ClearD3D9Data() curCapture = 0; curCPUTexture = 0; keepAliveTime = 0; + resetCount++; pCopyData = NULL; + + logOutput << "---------------------- Cleared D3D9 Capture ----------------------" << endl; } GSColorFormat ConvertDX9BackBufferFormat(D3DFORMAT format) @@ -248,42 +251,42 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) HMODULE hD3D10_1 = LoadLibrary(TEXT("d3d10_1.dll")); if(!hD3D10_1) { - RUNONCE logOutput << "DoD3D9GPUHook: Could not load D3D10.1" << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: Could not load D3D10.1" << endl; goto finishGPUHook; } HMODULE hDXGI = LoadLibrary(TEXT("dxgi.dll")); if(!hDXGI) { - RUNONCE logOutput << "DoD3D9GPUHook: Could not load dxgi" << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: Could not load dxgi" << endl; goto finishGPUHook; } CREATEDXGIFACTORY1PROC createDXGIFactory1 = (CREATEDXGIFACTORY1PROC)GetProcAddress(hDXGI, "CreateDXGIFactory1"); if(!createDXGIFactory1) { - RUNONCE logOutput << "DoD3D9GPUHook: Could not load 'CreateDXGIFactory1'" << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: Could not load 'CreateDXGIFactory1'" << endl; goto finishGPUHook; } PFN_D3D10_CREATE_DEVICE1 d3d10CreateDevice1 = (PFN_D3D10_CREATE_DEVICE1)GetProcAddress(hD3D10_1, "D3D10CreateDevice1"); if(!d3d10CreateDevice1) { - RUNONCE logOutput << "DoD3D9GPUHook: Could not load 'D3D10CreateDevice1'" << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: Could not load 'D3D10CreateDevice1'" << endl; goto finishGPUHook; } IDXGIFactory1 *factory; if(FAILED(hErr = (*createDXGIFactory1)(__uuidof(IDXGIFactory1), (void**)&factory))) { - RUNONCE logOutput << "DoD3D9GPUHook: CreateDXGIFactory1 failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: CreateDXGIFactory1 failed, result = " << (UINT)hErr << endl; goto finishGPUHook; } IDXGIAdapter1 *adapter; if(FAILED(hErr = factory->EnumAdapters1(0, &adapter))) { - RUNONCE logOutput << "DoD3D9GPUHook: factory->EnumAdapters1 failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: factory->EnumAdapters1 failed, result = " << (UINT)hErr << endl; factory->Release(); goto finishGPUHook; } @@ -292,7 +295,7 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) { if(FAILED(hErr = (*d3d10CreateDevice1)(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_FEATURE_LEVEL_9_3, D3D10_1_SDK_VERSION, &shareDevice))) { - RUNONCE logOutput << "DoD3D9GPUHook: Could not create D3D10.1 device, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: Could not create D3D10.1 device, result = " << (UINT)hErr << endl; adapter->Release(); factory->Release(); goto finishGPUHook; @@ -318,13 +321,13 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) ID3D10Texture2D *d3d101Tex; if(FAILED(hErr = shareDevice->CreateTexture2D(&texGameDesc, NULL, &d3d101Tex))) { - RUNONCE logOutput << "DoD3D9GPUHook: shareDevice->CreateTexture2D failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: shareDevice->CreateTexture2D failed, result = " << (UINT)hErr << endl; goto finishGPUHook; } if(FAILED(hErr = d3d101Tex->QueryInterface(__uuidof(ID3D10Resource), (void**)©TextureIntermediary))) { - RUNONCE logOutput << "DoD3D9GPUHook: d3d101Tex->QueryInterface(ID3D10Resource) failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: d3d101Tex->QueryInterface(ID3D10Resource) failed, result = " << (UINT)hErr << endl; d3d101Tex->Release(); goto finishGPUHook; } @@ -332,14 +335,14 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) IDXGIResource *res; if(FAILED(hErr = d3d101Tex->QueryInterface(IID_IDXGIResource, (void**)&res))) { - RUNONCE logOutput << "DoD3D9GPUHook: d3d101Tex->QueryInterface(IDXGIResource) failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: d3d101Tex->QueryInterface(IDXGIResource) failed, result = " << (UINT)hErr << endl; d3d101Tex->Release(); goto finishGPUHook; } if(FAILED(res->GetSharedHandle(&sharedHandle))) { - RUNONCE logOutput << "DoD3D9GPUHook: res->GetSharedHandle failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: res->GetSharedHandle failed, result = " << (UINT)hErr << endl; d3d101Tex->Release(); res->Release(); goto finishGPUHook; @@ -364,7 +367,7 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) } else { - RUNONCE logOutput << "DoD3D9GPUHook: unable to change memory protection, result = " << GetLastError() << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: unable to change memory protection, result = " << GetLastError() << endl; goto finishGPUHook; } } @@ -372,7 +375,7 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) IDirect3DTexture9 *d3d9Tex; if(FAILED(hErr = device->CreateTexture(d3d9CaptureInfo.cx, d3d9CaptureInfo.cy, 1, D3DUSAGE_RENDERTARGET, (D3DFORMAT)d3d9Format, D3DPOOL_DEFAULT, &d3d9Tex, &sharedHandle))) { - RUNONCE logOutput << "DoD3D9GPUHook: opening intermediary texture failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: opening intermediary texture failed, result = " << (UINT)hErr << endl; goto finishGPUHook; } @@ -384,7 +387,7 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) if(FAILED(hErr = d3d9Tex->GetSurfaceLevel(0, ©D3D9TextureGame))) { - RUNONCE logOutput << "DoD3D9GPUHook: d3d9Tex->GetSurfaceLevel failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: d3d9Tex->GetSurfaceLevel failed, result = " << (UINT)hErr << endl; d3d9Tex->Release(); goto finishGPUHook; } @@ -394,7 +397,7 @@ void DoD3D9GPUHook(IDirect3DDevice9 *device) d3d9CaptureInfo.mapID = InitializeSharedMemoryGPUCapture(&texData); if(!d3d9CaptureInfo.mapID) { - RUNONCE logOutput << "DoD3D9GPUHook: failed to initialize shared memory" << endl; + RUNEVERYRESET logOutput << "DoD3D9GPUHook: failed to initialize shared memory" << endl; goto finishGPUHook; } @@ -410,9 +413,15 @@ finishGPUHook: texData->texHandle = (DWORD)sharedHandle; memcpy(infoMem, &d3d9CaptureInfo, sizeof(CaptureInfo)); - SetEvent(hSignalReady); + if (!SetEvent(hSignalReady)) + logOutput << "SetEvent(hSignalReady) failed, GetLastError = " << UINT(GetLastError()) << endl; - logOutput << "DoD3D9GPUHook: success" << endl; + logOutput << "DoD3D9GPUHook: success"; + + if (bD3D9Ex) + logOutput << " - d3d9ex"; + + logOutput << endl; } else ClearD3D9Data(); @@ -430,7 +439,7 @@ void DoD3D9CPUHook(IDirect3DDevice9 *device) { if(FAILED(hErr = device->CreateOffscreenPlainSurface(d3d9CaptureInfo.cx, d3d9CaptureInfo.cy, (D3DFORMAT)d3d9Format, D3DPOOL_SYSTEMMEM, &textures[i], NULL))) { - RUNONCE logOutput << "DoD3D9CPUHook: device->CreateOffscreenPlainSurface " << i << " failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: device->CreateOffscreenPlainSurface " << i << " failed, result = " << (UINT)hErr << endl; bSuccess = false; break; } @@ -440,7 +449,7 @@ void DoD3D9CPUHook(IDirect3DDevice9 *device) D3DLOCKED_RECT lr; if(FAILED(hErr = textures[i]->LockRect(&lr, NULL, D3DLOCK_READONLY))) { - RUNONCE logOutput << "DoD3D9CPUHook: textures[" << i << "]->LockRect failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: textures[" << i << "]->LockRect failed, result = " << (UINT)hErr << endl; bSuccess = false; break; } @@ -456,21 +465,21 @@ void DoD3D9CPUHook(IDirect3DDevice9 *device) { if(FAILED(hErr = device->CreateRenderTarget(d3d9CaptureInfo.cx, d3d9CaptureInfo.cy, (D3DFORMAT)d3d9Format, D3DMULTISAMPLE_NONE, 0, FALSE, ©D3D9Textures[i], NULL))) { - RUNONCE logOutput << "DoD3D9CPUHook: device->CreateTexture " << i << " failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: device->CreateTexture " << i << " failed, result = " << (UINT)hErr << endl; bSuccess = false; break; } if(FAILED(hErr = device->CreateQuery(D3DQUERYTYPE_EVENT, &queries[i]))) { - RUNONCE logOutput << "DoD3D9CPUHook: device->CreateQuery " << i << " failed, result = " << (UINT)hErr << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: device->CreateQuery " << i << " failed, result = " << (UINT)hErr << endl; bSuccess = false; break; } if(!(dataMutexes[i] = OSCreateMutex())) { - RUNONCE logOutput << "DoD3D9CPUHook: OSCreateMutex " << i << " failed, GetLastError = " << GetLastError() << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: OSCreateMutex " << i << " failed, GetLastError = " << GetLastError() << endl; bSuccess = false; break; } @@ -485,13 +494,13 @@ void DoD3D9CPUHook(IDirect3DDevice9 *device) { if(!(hCopyEvent = CreateEvent(NULL, FALSE, FALSE, NULL))) { - RUNONCE logOutput << "DoD3D9CPUHook: CreateEvent failed, GetLastError = " << GetLastError() << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: CreateEvent failed, GetLastError = " << GetLastError() << endl; bSuccess = false; } } else { - RUNONCE logOutput << "DoD3D9CPUHook: CreateThread failed, GetLastError = " << GetLastError() << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: CreateThread failed, GetLastError = " << GetLastError() << endl; bSuccess = false; } } @@ -501,7 +510,7 @@ void DoD3D9CPUHook(IDirect3DDevice9 *device) d3d9CaptureInfo.mapID = InitializeSharedMemoryCPUCapture(pitch*d3d9CaptureInfo.cy, &d3d9CaptureInfo.mapSize, ©Data, textureBuffers); if(!d3d9CaptureInfo.mapID) { - RUNONCE logOutput << "DoD3D9CPUHook: failed to initialize shared memory" << endl; + RUNEVERYRESET logOutput << "DoD3D9CPUHook: failed to initialize shared memory" << endl; bSuccess = false; } } @@ -574,7 +583,7 @@ DWORD CopyD3D9CPUTextureThread(LPVOID lpUseless) return 0; } - +void LogD3D9SurfaceInfo(IDirect3DSurface9 *surf); void DoD3D9DrawStuff(IDirect3DDevice9 *device) { @@ -590,8 +599,12 @@ void DoD3D9DrawStuff(IDirect3DDevice9 *device) if(!bCapturing && WaitForSingleObject(hSignalRestart, 0) == WAIT_OBJECT_0) { hwndOBS = FindWindow(OBS_WINDOW_CLASS, NULL); - if(hwndOBS) + if(hwndOBS) { + logOutput << "received restart event, capturing" << endl; bCapturing = true; + } else { + logOutput << "received restart event, but couldn't find window" << endl; + } } if(!bHasTextures && bCapturing) @@ -610,8 +623,6 @@ void DoD3D9DrawStuff(IDirect3DDevice9 *device) } } - //device->BeginScene(); - LONGLONG timeVal = OSGetTimeMicroseconds(); //check keep alive state, dumb but effective @@ -670,14 +681,26 @@ void DoD3D9DrawStuff(IDirect3DDevice9 *device) IDirect3DSurface9 *texture = textures[curCapture]; IDirect3DSurface9 *backBuffer = NULL; - if (SUCCEEDED(hErr = device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer))) { + if (FAILED(hErr = device->GetRenderTarget(0, &backBuffer))) { + RUNEVERYRESET logOutput << "D3D9DrawStuff: GetRenderTarget failed, result = " << unsigned int(hErr) << endl; + } + + if (!backBuffer) { + if (FAILED(hErr = device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer))) { + RUNEVERYRESET logOutput << "DoD3D9DrawStuff: device->GetBackBuffer failed, result = " << unsigned int(hErr) << endl; + } + } + + if (backBuffer) { + {RUNEVERYRESET LogD3D9SurfaceInfo(backBuffer);} + if (FAILED(hErr = device->StretchRect(backBuffer, NULL, copyD3D9TextureGame, NULL, D3DTEXF_NONE))) { - RUNONCE logOutput << "DoD3D9DrawStuff: device->StretchRect failed, result = " << unsigned int(hErr) << endl; + RUNEVERYRESET logOutput << "DoD3D9DrawStuff: device->StretchRect failed, result = " << unsigned int(hErr) << endl; + } else { + RUNEVERYRESET logOutput << "successfully capturing d3d9 frames via GPU" << endl; } backBuffer->Release(); - } else { - RUNONCE logOutput << "DoD3D9DrawStuff: device->GetBackBuffer failed, result = " << unsigned int(hErr) << endl; } curCapture = nextCapture; @@ -762,6 +785,8 @@ void DoD3D9DrawStuff(IDirect3DDevice9 *device) if(FAILED(hErr = device->GetRenderTargetData(prevSourceTexture, targetTexture))) { int test = 0; + } else { + RUNEVERYRESET logOutput << "successfully capturing d3d9 frames via CPU" << endl; } queries[nextCapture]->Issue(D3DISSUE_END); @@ -777,8 +802,6 @@ void DoD3D9DrawStuff(IDirect3DDevice9 *device) else ClearD3D9Data(); } - - //device->EndScene(); } @@ -793,6 +816,8 @@ ULONG STDMETHODCALLTYPE D3D9Release(IDirect3DDevice9 *device) { if(refVal == 15) { + logOutput << "d3d9 capture terminated by the application" << endl; + ClearD3D9Data(); lpCurrentDevice = NULL; bTargetAcquired = false; @@ -802,8 +827,6 @@ ULONG STDMETHODCALLTYPE D3D9Release(IDirect3DDevice9 *device) { lpCurrentDevice = NULL; bTargetAcquired = false; - - logOutput << "d3d9 capture terminated by the application" << endl; } return (*(RELEASEPROC)oldD3D9Release)(device); @@ -813,6 +836,8 @@ HRESULT STDMETHODCALLTYPE D3D9EndScene(IDirect3DDevice9 *device) { d3d9EndScene.Unhook(); + RUNEVERYRESET logOutput << "D3D9EndScene called" << endl; + if(lpCurrentDevice == NULL) { IDirect3D9 *d3d; @@ -842,6 +867,8 @@ HRESULT STDMETHODCALLTYPE D3D9Present(IDirect3DDevice9 *device, CONST RECT* pSou { d3d9Present.Unhook(); + RUNEVERYRESET logOutput << "D3D9Present called" << endl; + if(!presentRecurse) DoD3D9DrawStuff(device); @@ -859,6 +886,8 @@ HRESULT STDMETHODCALLTYPE D3D9PresentEx(IDirect3DDevice9Ex *device, CONST RECT* { d3d9PresentEx.Unhook(); + RUNEVERYRESET logOutput << "D3D9PresentEx called" << endl; + if(!presentRecurse) DoD3D9DrawStuff(device); @@ -876,6 +905,8 @@ HRESULT STDMETHODCALLTYPE D3D9SwapPresent(IDirect3DSwapChain9 *swap, CONST RECT* { d3d9SwapPresent.Unhook(); + RUNEVERYRESET logOutput << "D3D9SwapPresent called" << endl; + if(!presentRecurse) DoD3D9DrawStuff((IDirect3DDevice9*)lpCurrentDevice); @@ -893,6 +924,8 @@ HRESULT STDMETHODCALLTYPE D3D9Reset(IDirect3DDevice9 *device, D3DPRESENT_PARAMET { d3d9Reset.Unhook(); + RUNEVERYRESET logOutput << "D3D9Reset called" << endl; + ClearD3D9Data(); HRESULT hRes = device->Reset(params); @@ -916,6 +949,8 @@ HRESULT STDMETHODCALLTYPE D3D9ResetEx(IDirect3DDevice9Ex *device, D3DPRESENT_PAR d3d9ResetEx.Unhook(); d3d9Reset.Unhook(); + RUNEVERYRESET logOutput << "D3D9ResetEx called" << endl; + ClearD3D9Data(); HRESULT hRes = device->ResetEx(params, fullscreenData); @@ -936,6 +971,7 @@ HRESULT STDMETHODCALLTYPE D3D9ResetEx(IDirect3DDevice9Ex *device, D3DPRESENT_PAR return hRes; } +void LogPresentParams(D3DPRESENT_PARAMETERS &pp); void SetupD3D9(IDirect3DDevice9 *device) { @@ -950,10 +986,13 @@ void SetupD3D9(IDirect3DDevice9 *device) if(d3d9CaptureInfo.format != GS_UNKNOWNFORMAT) { - if( d3d9Format != pp.BackBufferFormat || - d3d9CaptureInfo.cx != pp.BackBufferWidth || - d3d9CaptureInfo.cy != pp.BackBufferHeight ) + if( d3d9Format != pp.BackBufferFormat || + d3d9CaptureInfo.cx != pp.BackBufferWidth || + d3d9CaptureInfo.cy != pp.BackBufferHeight || + d3d9CaptureInfo.hwndCapture != (DWORD)pp.hDeviceWindow) { + LogPresentParams(pp); + d3d9Format = pp.BackBufferFormat; d3d9CaptureInfo.cx = pp.BackBufferWidth; d3d9CaptureInfo.cy = pp.BackBufferHeight; @@ -971,30 +1010,36 @@ void SetupD3D9(IDirect3DDevice9 *device) d3d->Release(); } - /*FARPROC curRelease = GetVTable(device, (8/4)); + FARPROC curRelease = GetVTable(device, (8/4)); if(curRelease != newD3D9Release) { oldD3D9Release = curRelease; newD3D9Release = (FARPROC)D3D9Release; SetVTable(device, (8/4), newD3D9Release); - }*/ + } - FARPROC curPresent = GetVTable(device, (68/4)); - d3d9Present.Hook(curPresent, (FARPROC)D3D9Present); + d3d9Present.Hook(GetVTable(device, (68/4)), (FARPROC)D3D9Present); if(bD3D9Ex) { FARPROC curPresentEx = GetVTable(device, (484/4)); d3d9PresentEx.Hook(curPresentEx, (FARPROC)D3D9PresentEx); + d3d9ResetEx.Hook(GetVTable(device, (528/4)), (FARPROC)D3D9ResetEx); } - FARPROC curD3D9SwapPresent = GetVTable(swapChain, (12/4)); - d3d9SwapPresent.Hook(curD3D9SwapPresent, (FARPROC)D3D9SwapPresent); + d3d9Reset.Hook(GetVTable(device, (64/4)), (FARPROC)D3D9Reset); + + d3d9SwapPresent.Hook(GetVTable(swapChain, (12/4)), (FARPROC)D3D9SwapPresent); d3d9Present.Rehook(); d3d9SwapPresent.Rehook(); + d3d9Reset.Rehook(); - if(bD3D9Ex) + if(bD3D9Ex) { d3d9PresentEx.Rehook(); + d3d9ResetEx.Rehook(); + } + + logOutput << "successfully set up d3d9 hooks" << endl; swapChain->Release(); } @@ -1042,30 +1087,26 @@ bool InitD3D9Capture() UPARAM *vtable = *(UPARAM**)deviceEx; d3d9EndScene.Hook((FARPROC)*(vtable+(168/4)), (FARPROC)D3D9EndScene); - d3d9ResetEx.Hook((FARPROC)*(vtable+(528/4)), (FARPROC)D3D9ResetEx); - d3d9Reset.Hook((FARPROC)*(vtable+(64/4)), (FARPROC)D3D9Reset); deviceEx->Release(); d3d9EndScene.Rehook(); - d3d9Reset.Rehook(); - d3d9ResetEx.Rehook(); } else { - RUNONCE logOutput << "InitD3D9Capture: d3d9ex->CreateDeviceEx failed, result: " << (UINT)hRes << endl; + RUNEVERYRESET logOutput << "InitD3D9Capture: d3d9ex->CreateDeviceEx failed, result: " << (UINT)hRes << endl; } d3d9ex->Release(); } else { - RUNONCE logOutput << "InitD3D9Capture: Direct3DCreate9Ex failed, result: " << (UINT)hRes << endl; + RUNEVERYRESET logOutput << "InitD3D9Capture: Direct3DCreate9Ex failed, result: " << (UINT)hRes << endl; } } else { - RUNONCE logOutput << "InitD3D9Capture: could not load address of Direct3DCreate9Ex" << endl; + RUNEVERYRESET logOutput << "InitD3D9Capture: could not load address of Direct3DCreate9Ex" << endl; } } diff --git a/GraphicsCapture/GraphicsCaptureHook/D3D9LogStuff.cpp b/GraphicsCapture/GraphicsCaptureHook/D3D9LogStuff.cpp new file mode 100644 index 00000000..8f46ba20 --- /dev/null +++ b/GraphicsCapture/GraphicsCaptureHook/D3D9LogStuff.cpp @@ -0,0 +1,377 @@ +/******************************************************************************** + Copyright (C) 2012 Hugh Bailey + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +********************************************************************************/ + + +#include "GraphicsCaptureHook.h" + +#include + +static string GetD3D9FormatName(DWORD format) +{ + switch(format) { + case D3DFMT_UNKNOWN : return string("D3DFMT_UNKNOWN"); + case D3DFMT_R8G8B8 : return string("D3DFMT_R8G8B8"); + case D3DFMT_A8R8G8B8 : return string("D3DFMT_A8R8G8B8"); + case D3DFMT_X8R8G8B8 : return string("D3DFMT_X8R8G8B8"); + case D3DFMT_R5G6B5 : return string("D3DFMT_R5G6B5"); + case D3DFMT_X1R5G5B5 : return string("D3DFMT_X1R5G5B5"); + case D3DFMT_A1R5G5B5 : return string("D3DFMT_A1R5G5B5"); + case D3DFMT_A4R4G4B4 : return string("D3DFMT_A4R4G4B4"); + case D3DFMT_R3G3B2 : return string("D3DFMT_R3G3B2"); + case D3DFMT_A8 : return string("D3DFMT_A8"); + case D3DFMT_A8R3G3B2 : return string("D3DFMT_A8R3G3B2"); + case D3DFMT_X4R4G4B4 : return string("D3DFMT_X4R4G4B4"); + case D3DFMT_A2B10G10R10 : return string("D3DFMT_A2B10G10R10"); + case D3DFMT_A8B8G8R8 : return string("D3DFMT_A8B8G8R8"); + case D3DFMT_X8B8G8R8 : return string("D3DFMT_X8B8G8R8"); + case D3DFMT_G16R16 : return string("D3DFMT_G16R16"); + case D3DFMT_A2R10G10B10 : return string("D3DFMT_A2R10G10B10"); + case D3DFMT_A16B16G16R16 : return string("D3DFMT_A16B16G16R16"); + case D3DFMT_A8P8 : return string("D3DFMT_A8P8"); + case D3DFMT_P8 : return string("D3DFMT_P8"); + case D3DFMT_L8 : return string("D3DFMT_L8"); + case D3DFMT_A8L8 : return string("D3DFMT_A8L8"); + case D3DFMT_A4L4 : return string("D3DFMT_A4L4"); + case D3DFMT_V8U8 : return string("D3DFMT_V8U8"); + case D3DFMT_L6V5U5 : return string("D3DFMT_L6V5U5"); + case D3DFMT_X8L8V8U8 : return string("D3DFMT_X8L8V8U8"); + case D3DFMT_Q8W8V8U8 : return string("D3DFMT_Q8W8V8U8"); + case D3DFMT_V16U16 : return string("D3DFMT_V16U16"); + case D3DFMT_A2W10V10U10 : return string("D3DFMT_A2W10V10U10"); + case D3DFMT_UYVY : return string("D3DFMT_UYVY"); + case D3DFMT_R8G8_B8G8 : return string("D3DFMT_R8G8_B8G8"); + case D3DFMT_YUY2 : return string("D3DFMT_YUY2"); + case D3DFMT_G8R8_G8B8 : return string("D3DFMT_G8R8_G8B8"); + case D3DFMT_DXT1 : return string("D3DFMT_DXT1"); + case D3DFMT_DXT2 : return string("D3DFMT_DXT2"); + case D3DFMT_DXT3 : return string("D3DFMT_DXT3"); + case D3DFMT_DXT4 : return string("D3DFMT_DXT4"); + case D3DFMT_DXT5 : return string("D3DFMT_DXT5"); + case D3DFMT_D16_LOCKABLE : return string("D3DFMT_D16_LOCKABLE"); + case D3DFMT_D32 : return string("D3DFMT_D32"); + case D3DFMT_D15S1 : return string("D3DFMT_D15S1"); + case D3DFMT_D24S8 : return string("D3DFMT_D24S8"); + case D3DFMT_D24X8 : return string("D3DFMT_D24X8"); + case D3DFMT_D24X4S4 : return string("D3DFMT_D24X4S4"); + case D3DFMT_D16 : return string("D3DFMT_D16"); + case D3DFMT_D32F_LOCKABLE : return string("D3DFMT_D32F_LOCKABLE"); + case D3DFMT_D24FS8 : return string("D3DFMT_D24FS8"); + case D3DFMT_D32_LOCKABLE : return string("D3DFMT_D32_LOCKABLE"); + case D3DFMT_S8_LOCKABLE : return string("D3DFMT_S8_LOCKABLE"); + case D3DFMT_L16 : return string("D3DFMT_L16"); + case D3DFMT_VERTEXDATA : return string("D3DFMT_VERTEXDATA"); + case D3DFMT_INDEX16 : return string("D3DFMT_INDEX16"); + case D3DFMT_INDEX32 : return string("D3DFMT_INDEX32"); + case D3DFMT_Q16W16V16U16 : return string("D3DFMT_Q16W16V16U16"); + case D3DFMT_MULTI2_ARGB8 : return string("D3DFMT_MULTI2_ARGB8"); + case D3DFMT_R16F : return string("D3DFMT_R16F"); + case D3DFMT_G16R16F : return string("D3DFMT_G16R16F"); + case D3DFMT_A16B16G16R16F : return string("D3DFMT_A16B16G16R16F"); + case D3DFMT_R32F : return string("D3DFMT_R32F"); + case D3DFMT_G32R32F : return string("D3DFMT_G32R32F"); + case D3DFMT_A32B32G32R32F : return string("D3DFMT_A32B32G32R32F"); + case D3DFMT_CxV8U8 : return string("D3DFMT_CxV8U8"); + case D3DFMT_A1 : return string("D3DFMT_A1"); + case D3DFMT_A2B10G10R10_XR_BIAS : return string("D3DFMT_A2B10G10R10_XR_BIAS"); + case D3DFMT_BINARYBUFFER : return string("D3DFMT_BINARYBUFFER"); + } + + return IntString(format); +} + +static string GetD3D9MultiSampleTypeName(DWORD mst) +{ + switch(mst) { + case D3DMULTISAMPLE_NONE : return string("D3DMULTISAMPLE_NONE"); + case D3DMULTISAMPLE_NONMASKABLE : return string("D3DMULTISAMPLE_NONMASKABLE"); + case D3DMULTISAMPLE_2_SAMPLES : return string("D3DMULTISAMPLE_2_SAMPLES"); + case D3DMULTISAMPLE_3_SAMPLES : return string("D3DMULTISAMPLE_3_SAMPLES"); + case D3DMULTISAMPLE_4_SAMPLES : return string("D3DMULTISAMPLE_4_SAMPLES"); + case D3DMULTISAMPLE_5_SAMPLES : return string("D3DMULTISAMPLE_5_SAMPLES"); + case D3DMULTISAMPLE_6_SAMPLES : return string("D3DMULTISAMPLE_6_SAMPLES"); + case D3DMULTISAMPLE_7_SAMPLES : return string("D3DMULTISAMPLE_7_SAMPLES"); + case D3DMULTISAMPLE_8_SAMPLES : return string("D3DMULTISAMPLE_8_SAMPLES"); + case D3DMULTISAMPLE_9_SAMPLES : return string("D3DMULTISAMPLE_9_SAMPLES"); + case D3DMULTISAMPLE_10_SAMPLES : return string("D3DMULTISAMPLE_10_SAMPLES"); + case D3DMULTISAMPLE_11_SAMPLES : return string("D3DMULTISAMPLE_11_SAMPLES"); + case D3DMULTISAMPLE_12_SAMPLES : return string("D3DMULTISAMPLE_12_SAMPLES"); + case D3DMULTISAMPLE_13_SAMPLES : return string("D3DMULTISAMPLE_13_SAMPLES"); + case D3DMULTISAMPLE_14_SAMPLES : return string("D3DMULTISAMPLE_14_SAMPLES"); + case D3DMULTISAMPLE_15_SAMPLES : return string("D3DMULTISAMPLE_15_SAMPLES"); + case D3DMULTISAMPLE_16_SAMPLES : return string("D3DMULTISAMPLE_16_SAMPLES"); + } + + return IntString(mst); +} + +static string GetD3D9SwapEffectName(DWORD se) +{ + switch(se) { + case D3DSWAPEFFECT_DISCARD: return string("D3DSWAPEFFECT_DISCARD"); + case D3DSWAPEFFECT_FLIP : return string("D3DSWAPEFFECT_FLIP"); + case D3DSWAPEFFECT_COPY : return string("D3DSWAPEFFECT_COPY"); + case D3DSWAPEFFECT_OVERLAY: return string("D3DSWAPEFFECT_OVERLAY"); + case D3DSWAPEFFECT_FLIPEX : return string("D3DSWAPEFFECT_FLIPEX"); + } + + return IntString(se); +} + +static string GetD3D9D3DPPFlagsString(DWORD flags) +{ + if (!flags) + return string("None"); + + stringstream ss; + if (flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER) { + ss << "D3DPRESENTFLAG_LOCKABLE_BACKBUFFER "; + flags &= ~D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; + } + if (flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL) { + ss << "D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL "; + flags &= ~D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; + } + if (flags & D3DPRESENTFLAG_DEVICECLIP) { + ss << "D3DPRESENTFLAG_DEVICECLIP "; + flags &= ~D3DPRESENTFLAG_DEVICECLIP; + } + if (flags & D3DPRESENTFLAG_VIDEO) { + ss << "D3DPRESENTFLAG_VIDEO "; + flags &= ~D3DPRESENTFLAG_VIDEO; + } + if (flags & D3DPRESENTFLAG_NOAUTOROTATE) { + ss << "D3DPRESENTFLAG_NOAUTOROTATE "; + flags &= ~D3DPRESENTFLAG_NOAUTOROTATE; + } + if (flags & D3DPRESENTFLAG_UNPRUNEDMODE) { + ss << "D3DPRESENTFLAG_UNPRUNEDMODE "; + flags &= ~D3DPRESENTFLAG_UNPRUNEDMODE; + } + if (flags & D3DPRESENTFLAG_OVERLAY_LIMITEDRGB) { + ss << "D3DPRESENTFLAG_OVERLAY_LIMITEDRGB "; + flags &= ~D3DPRESENTFLAG_OVERLAY_LIMITEDRGB; + } + if (flags & D3DPRESENTFLAG_OVERLAY_YCbCr_BT709) { + ss << "D3DPRESENTFLAG_OVERLAY_YCbCr_BT709 "; + flags &= ~D3DPRESENTFLAG_OVERLAY_YCbCr_BT709; + } + if (flags & D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC) { + ss << "D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC "; + flags &= ~D3DPRESENTFLAG_OVERLAY_YCbCr_xvYCC; + } + if (flags & D3DPRESENTFLAG_RESTRICTED_CONTENT) { + ss << "D3DPRESENTFLAG_RESTRICTED_CONTENT "; + flags &= ~D3DPRESENTFLAG_RESTRICTED_CONTENT; + } + if (flags & D3DPRESENTFLAG_RESTRICT_SHARED_RESOURCE_DRIVER) { + ss << "D3DPRESENTFLAG_RESTRICT_SHARED_RESOURCE_DRIVER "; + flags &= ~D3DPRESENTFLAG_RESTRICT_SHARED_RESOURCE_DRIVER; + } + if (flags) + ss << IntString(flags) << " "; + + return ss.str(); +} + +static string GetD3D9ResourceTypeName(DWORD rt) +{ + switch(rt) { + case D3DRTYPE_SURFACE : return string("D3DRTYPE_SURFACE"); + case D3DRTYPE_VOLUME : return string("D3DRTYPE_VOLUME"); + case D3DRTYPE_TEXTURE : return string("D3DRTYPE_TEXTURE"); + case D3DRTYPE_VOLUMETEXTURE: return string("D3DRTYPE_VOLUMETEXTURE"); + case D3DRTYPE_CUBETEXTURE : return string("D3DRTYPE_CUBETEXTURE"); + case D3DRTYPE_VERTEXBUFFER : return string("D3DRTYPE_VERTEXBUFFER"); + case D3DRTYPE_INDEXBUFFER : return string("D3DRTYPE_INDEXBUFFER"); + } + + return IntString(rt); +} + +static string GetD3D9PoolName(DWORD pool) +{ + switch(pool) { + case D3DPOOL_DEFAULT : return string("D3DPOOL_DEFAULT"); + case D3DPOOL_MANAGED : return string("D3DPOOL_MANAGED"); + case D3DPOOL_SYSTEMMEM: return string("D3DPOOL_SYSTEMMEM"); + case D3DPOOL_SCRATCH : return string("D3DPOOL_SCRATCH"); + } + + return IntString(pool); +} + +static string GetD3D9UsageString(DWORD flags) +{ + if (!flags) + return string("None"); + + stringstream ss; + if (flags & D3DUSAGE_RENDERTARGET) { + ss << "D3DUSAGE_RENDERTARGET "; + flags &= ~D3DUSAGE_RENDERTARGET; + } + if (flags & D3DUSAGE_DEPTHSTENCIL) { + ss << "D3DUSAGE_DEPTHSTENCIL "; + flags &= ~D3DUSAGE_DEPTHSTENCIL; + } + if (flags & D3DUSAGE_DYNAMIC) { + ss << "D3DUSAGE_DYNAMIC "; + flags &= ~D3DUSAGE_DYNAMIC; + } + if (flags & D3DUSAGE_NONSECURE) { + ss << "D3DUSAGE_NONSECURE "; + flags &= ~D3DUSAGE_NONSECURE; + } + if (flags & D3DUSAGE_AUTOGENMIPMAP) { + ss << "D3DUSAGE_AUTOGENMIPMAP "; + flags &= ~D3DUSAGE_AUTOGENMIPMAP; + } + if (flags & D3DUSAGE_DMAP) { + ss << "D3DUSAGE_DMAP "; + flags &= ~D3DUSAGE_DMAP; + } + if (flags & D3DUSAGE_QUERY_LEGACYBUMPMAP) { + ss << "D3DUSAGE_QUERY_LEGACYBUMPMAP "; + flags &= ~D3DUSAGE_QUERY_LEGACYBUMPMAP; + } + if (flags & D3DUSAGE_QUERY_SRGBREAD) { + ss << "D3DUSAGE_QUERY_SRGBREAD "; + flags &= ~D3DUSAGE_QUERY_SRGBREAD; + } + if (flags & D3DUSAGE_QUERY_FILTER) { + ss << "D3DUSAGE_QUERY_FILTER "; + flags &= ~D3DUSAGE_QUERY_FILTER; + } + if (flags & D3DUSAGE_QUERY_SRGBWRITE) { + ss << "D3DUSAGE_QUERY_SRGBWRITE "; + flags &= ~D3DUSAGE_QUERY_SRGBWRITE; + } + if (flags & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) { + ss << "D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING "; + flags &= ~D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + if (flags & D3DUSAGE_QUERY_VERTEXTEXTURE) { + ss << "D3DUSAGE_QUERY_VERTEXTEXTURE "; + flags &= ~D3DUSAGE_QUERY_VERTEXTEXTURE; + } + if (flags & D3DUSAGE_QUERY_WRAPANDMIP) { + ss << "D3DUSAGE_QUERY_WRAPANDMIP "; + flags &= ~D3DUSAGE_QUERY_WRAPANDMIP; + } + if (flags & D3DUSAGE_DYNAMIC) { + ss << "D3DUSAGE_DYNAMIC "; + flags &= ~D3DUSAGE_DYNAMIC; + } + if (flags & D3DUSAGE_WRITEONLY) { + ss << "D3DUSAGE_WRITEONLY "; + flags &= ~D3DUSAGE_WRITEONLY; + } + if (flags & D3DUSAGE_SOFTWAREPROCESSING) { + ss << "D3DUSAGE_SOFTWAREPROCESSING "; + flags &= ~D3DUSAGE_SOFTWAREPROCESSING; + } + if (flags & D3DUSAGE_DONOTCLIP) { + ss << "D3DUSAGE_DONOTCLIP "; + flags &= ~D3DUSAGE_DONOTCLIP; + } + if (flags & D3DUSAGE_POINTS) { + ss << "D3DUSAGE_POINTS "; + flags &= ~D3DUSAGE_POINTS; + } + if (flags & D3DUSAGE_RTPATCHES) { + ss << "D3DUSAGE_RTPATCHES "; + flags &= ~D3DUSAGE_RTPATCHES; + } + if (flags & D3DUSAGE_NPATCHES) { + ss << "D3DUSAGE_NPATCHES "; + flags &= ~D3DUSAGE_NPATCHES; + } + if (flags & D3DUSAGE_TEXTAPI) { + ss << "D3DUSAGE_TEXTAPI "; + flags &= ~D3DUSAGE_TEXTAPI; + } + if (flags & D3DUSAGE_RESTRICTED_CONTENT) { + ss << "D3DUSAGE_RESTRICTED_CONTENT "; + flags &= ~D3DUSAGE_RESTRICTED_CONTENT; + } + if (flags & D3DUSAGE_RESTRICT_SHARED_RESOURCE) { + ss << "D3DUSAGE_RESTRICT_SHARED_RESOURCE "; + flags &= ~D3DUSAGE_RESTRICT_SHARED_RESOURCE; + } + if (flags & D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER) { + ss << "D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER "; + flags &= ~D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER; + } + if (flags) + ss << IntString(flags) << " "; + + return ss.str(); +} + +void LogPresentParams(D3DPRESENT_PARAMETERS &pp) +{ + if (pp.hDeviceWindow) { + UINT testLen = GetWindowTextLength(pp.hDeviceWindow); + testLen++; + + string strName; + strName.resize(testLen); + GetWindowTextA(pp.hDeviceWindow, (char*)strName.c_str(), testLen); + + logOutput << "found d3d9 present params for window: " << strName << endl; + } + + logOutput << "D3DPRESENT_PARAMETERS {" << endl; + logOutput << "\t" "BackBufferWidth: " << pp.BackBufferWidth << endl; + logOutput << "\t" "BackBufferHeight: " << pp.BackBufferHeight << endl; + logOutput << "\t" "BackBufferFormat: " << GetD3D9FormatName(pp.BackBufferFormat) << endl; + logOutput << "\t" "BackBufferCount: " << pp.BackBufferCount << endl; + logOutput << "\t" "MultiSampleType: " << GetD3D9MultiSampleTypeName(pp.MultiSampleType) << endl; + logOutput << "\t" "MultiSampleQuality: " << pp.MultiSampleQuality << endl; + logOutput << "\t" "SwapEffect: " << GetD3D9SwapEffectName(pp.SwapEffect) << endl; + logOutput << "\t" "hDeviceWindow: " << DWORD(pp.hDeviceWindow) << endl; + logOutput << "\t" "Windowed: " << (pp.Windowed ? "true" : "false") << endl; + logOutput << "\t" "EnableAutoDepthStencil: " << (pp.EnableAutoDepthStencil ? "true" : "false") << endl; + logOutput << "\t" "AutoDepthStencilFormat: " << GetD3D9FormatName(pp.AutoDepthStencilFormat) << endl; + logOutput << "\t" "Flags: " << GetD3D9D3DPPFlagsString(pp.Flags) << endl; + logOutput << "\t" "FullScreen_RefreshRateInHz: " << pp.FullScreen_RefreshRateInHz << endl; + logOutput << "\t" "PresentationInterval: " << pp.PresentationInterval << endl; + logOutput << "};" << endl; +} + +void LogD3D9SurfaceInfo(IDirect3DSurface9 *surf) +{ + if (!surf) return; + + D3DSURFACE_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + if (SUCCEEDED(surf->GetDesc(&sd))) { + logOutput << "D3DSURFACE_DESC {" << endl; + logOutput << "\t" "Format: " << GetD3D9FormatName(sd.Format) << endl; + logOutput << "\t" "Type: " << GetD3D9ResourceTypeName(sd.Type) << endl; + logOutput << "\t" "Usage: " << GetD3D9UsageString(sd.Usage) << endl; + logOutput << "\t" "Pool: " << GetD3D9PoolName(sd.Pool) << endl; + logOutput << "\t" "MultiSampleType: " << GetD3D9MultiSampleTypeName(sd.MultiSampleType) << endl; + logOutput << "\t" "MultiSampleQuality: " << sd.MultiSampleQuality << endl; + logOutput << "\t" "Width: " << sd.Width << endl; + logOutput << "\t" "Height: " << sd.Height << endl; + logOutput << "};" << endl; + } else { + logOutput << "could not get D3DSURFACE_DESC from backbuffer for some reason" << endl; + } +} diff --git a/GraphicsCapture/GraphicsCaptureHook/DXGICapture.cpp b/GraphicsCapture/GraphicsCaptureHook/DXGICapture.cpp index 86ced826..f82375fc 100644 --- a/GraphicsCapture/GraphicsCaptureHook/DXGICapture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/DXGICapture.cpp @@ -172,11 +172,11 @@ IDXGISwapChain* CreateDummySwap() return swap; } - RUNONCE logOutput << "CreateDummySwap: D3D10CreateDeviceAndSwapChain failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "CreateDummySwap: D3D10CreateDeviceAndSwapChain failed, result = " << UINT(hErr) << endl; } else { - RUNONCE logOutput << "CreateDummySwap: D3D10CreateDeviceAndSwapChain not found" << endl; + RUNEVERYRESET logOutput << "CreateDummySwap: D3D10CreateDeviceAndSwapChain not found" << endl; } } @@ -200,11 +200,11 @@ IDXGISwapChain* CreateDummySwap() return swap; } - RUNONCE logOutput << "CreateDummyDevice: D3D10CreateDeviceAndSwapChain1 failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "CreateDummyDevice: D3D10CreateDeviceAndSwapChain1 failed, result = " << UINT(hErr) << endl; } else { - RUNONCE logOutput << "CreateDummyDevice: D3D10CreateDeviceAndSwapChain1 not found" << endl; + RUNEVERYRESET logOutput << "CreateDummyDevice: D3D10CreateDeviceAndSwapChain1 not found" << endl; } } @@ -240,11 +240,11 @@ IDXGISwapChain* CreateDummySwap() return swap; } - RUNONCE logOutput << "CreateDummyDevice: D3D11CreateDeviceAndSwapChain failed, result = " << UINT(hErr) << endl; + RUNEVERYRESET logOutput << "CreateDummyDevice: D3D11CreateDeviceAndSwapChain failed, result = " << UINT(hErr) << endl; } else { - RUNONCE logOutput << "CreateDummyDevice: D3D11CreateDeviceAndSwapChain not found" << endl; + RUNEVERYRESET logOutput << "CreateDummyDevice: D3D11CreateDeviceAndSwapChain not found" << endl; } } diff --git a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.cpp b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.cpp index b4cae7d3..c65d40e4 100644 --- a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.cpp @@ -26,6 +26,7 @@ HANDLE hSignalReady=NULL, hSignalExit=NULL; HINSTANCE hinstMain = NULL; HWND hwndSender = NULL, hwndOBS = NULL; HANDLE textureMutexes[2] = {NULL, NULL}; +int resetCount = 1; bool bStopRequested = false; bool bCapturing = true; bool bTargetAcquired = false; @@ -265,12 +266,14 @@ DWORD WINAPI CaptureThread(HANDLE hDllMainThread) wcscat_s(lpLogPath, MAX_PATH, TEXT("\\OBS\\pluginData\\captureHookLog.txt")); if(!logOutput.is_open()) - logOutput.open(lpLogPath, ios_base::in | ios_base::out | ios_base::trunc); + logOutput.open(lpLogPath, ios_base::in | ios_base::out | ios_base::trunc, _SH_DENYNO); wstringstream str; - str << OBS_KEEPALIVE_EVENT << int(GetCurrentProcessId()); + str << OBS_KEEPALIVE_EVENT << UINT(GetCurrentProcessId()); strKeepAlive = str.str(); + logOutput << "we're booting up.." << endl; + WNDCLASS wc; ZeroMemory(&wc, sizeof(wc)); wc.hInstance = hinstMain; @@ -314,41 +317,47 @@ DWORD WINAPI CaptureThread(HANDLE hDllMainThread) return 0; } - if(RegisterClass(&wc)) - { + if (RegisterClass(&wc)) { hwndSender = CreateWindow(SENDER_WINDOWCLASS, NULL, 0, 0, 0, 0, 0, NULL, 0, hinstMain, 0); - if(hwndSender) - { + if (hwndSender) { textureMutexes[0] = OpenMutex(MUTEX_ALL_ACCESS, FALSE, TEXTURE_MUTEX1); - if(textureMutexes[0]) - { + if (textureMutexes[0]) { textureMutexes[1] = OpenMutex(MUTEX_ALL_ACCESS, FALSE, TEXTURE_MUTEX2); - if(textureMutexes[1]) - { - while(!AttemptToHookSomething()) - Sleep(50); + if (textureMutexes[1]) { + logOutput << "(half life scientist) everything.. seems to be in order" << endl; MSG msg; - while(GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - + while (1) { AttemptToHookSomething(); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + Sleep(50); } CloseHandle(textureMutexes[1]); textureMutexes[1] = NULL; + } else { + logOutput << "could not open texture mutex 2" << endl; } CloseHandle(textureMutexes[0]); textureMutexes[0] = NULL; + } else { + logOutput << "could not open texture mutex 1" << endl; } DestroyWindow(hwndSender); + } else { + logOutput << "could not create sender window" << endl; } } + logOutput << "exit out of the main thread loop somehow" << endl; + return 0; } diff --git a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.h b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.h index 8c1ed457..5880cb95 100644 --- a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.h +++ b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.h @@ -40,7 +40,9 @@ using namespace std; //arghh I hate defines like this -#define RUNONCE static bool bRunOnce = false; if(!bRunOnce && (bRunOnce = true)) +#define RUNONCE static bool bRunOnce = false; if(!bRunOnce && (bRunOnce = true)) +#define RUNEVERY(v) static int __runCount = 0; if(__runCount == 50) __runCount = 0; if(!__runCount++) +#define RUNEVERYRESET static int __resetCount = 0; if(__resetCount != resetCount && (__resetCount = resetCount)) #define SafeRelease(var) if(var) {var->Release(); var = NULL;} @@ -195,6 +197,14 @@ inline void SSECopy(void *lpDest, void *lpSource, UINT size) } } +inline string IntString(DWORD val) +{ + stringstream ss; + ss << val; + + return ss.str(); +} + typedef ULONG (WINAPI *RELEASEPROC)(LPVOID); #include "../GlobalCaptureStuff.h" @@ -204,6 +214,7 @@ enum GSColorFormat {GS_UNKNOWNFORMAT, GS_ALPHA, GS_GRAYSCALE, GS_RGB, GS_RGBA, G extern HINSTANCE hinstMain; extern HANDLE textureMutexes[2]; extern bool bCapturing; +extern int resetCount; extern bool bStopRequested; extern bool bTargetAcquired; diff --git a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj index cd18670d..dd6d6465 100644 --- a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj +++ b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj @@ -219,6 +219,7 @@ + diff --git a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj.filters b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj.filters index e85e2f69..db8e7c66 100644 --- a/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj.filters +++ b/GraphicsCapture/GraphicsCaptureHook/GraphicsCaptureHook.vcxproj.filters @@ -39,6 +39,9 @@ Source + + Source + diff --git a/GraphicsCapture/GraphicsCaptureHook/OpenGLCapture.cpp b/GraphicsCapture/GraphicsCaptureHook/OpenGLCapture.cpp index b844d400..ac6d9f62 100644 --- a/GraphicsCapture/GraphicsCaptureHook/OpenGLCapture.cpp +++ b/GraphicsCapture/GraphicsCaptureHook/OpenGLCapture.cpp @@ -217,7 +217,10 @@ void ClearGLData() curCapture = 0; curCPUTexture = 0; keepAliveTime = 0; + resetCount++; pCopyData = NULL; + + logOutput << "---------------------- Cleared OpenGL Capture ----------------------" << endl; } DWORD CopyGLCPUTextureThread(LPVOID lpUseless); diff --git a/GraphicsCapture/GraphicsCaptureSource.cpp b/GraphicsCapture/GraphicsCaptureSource.cpp index b566fd11..6c77d302 100644 --- a/GraphicsCapture/GraphicsCaptureSource.cpp +++ b/GraphicsCapture/GraphicsCaptureSource.cpp @@ -138,7 +138,7 @@ GraphicsCaptureSource::~GraphicsCaptureSource() static bool GetCaptureInfo(CaptureInfo &ci, DWORD processID) { - HANDLE hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, String() << INFO_MEMORY << int(processID)); + HANDLE hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, String() << INFO_MEMORY << UINT(processID)); if(hFileMap == NULL) { AppWarning(TEXT("GetCaptureInfo: Could not open file mapping")); @@ -168,6 +168,7 @@ void GraphicsCaptureSource::NewCapture() { if(capture) { + Log(TEXT("GraphicsCaptureSource::NewCapture: eliminating old capture")); capture->Destroy(); delete capture; capture = NULL; @@ -175,7 +176,7 @@ void GraphicsCaptureSource::NewCapture() if(!hSignalRestart) { - hSignalRestart = GetEvent(String() << RESTART_CAPTURE_EVENT << int(targetProcessID)); + hSignalRestart = GetEvent(String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID)); if(!hSignalRestart) { RUNONCE AppWarning(TEXT("GraphicsCaptureSource::NewCapture: Could not create restart event")); @@ -183,21 +184,21 @@ void GraphicsCaptureSource::NewCapture() } } - hSignalEnd = GetEvent(String() << END_CAPTURE_EVENT << int(targetProcessID)); + hSignalEnd = GetEvent(String() << END_CAPTURE_EVENT << UINT(targetProcessID)); if(!hSignalEnd) { RUNONCE AppWarning(TEXT("GraphicsCaptureSource::NewCapture: Could not create end event")); return; } - hSignalReady = GetEvent(String() << CAPTURE_READY_EVENT << int(targetProcessID)); + hSignalReady = GetEvent(String() << CAPTURE_READY_EVENT << UINT(targetProcessID)); if(!hSignalReady) { RUNONCE AppWarning(TEXT("GraphicsCaptureSource::NewCapture: Could not create ready event")); return; } - hSignalExit = GetEvent(String() << APP_EXIT_EVENT << int(targetProcessID)); + hSignalExit = GetEvent(String() << APP_EXIT_EVENT << UINT(targetProcessID)); if(!hSignalExit) { RUNONCE AppWarning(TEXT("GraphicsCaptureSource::NewCapture: Could not create exit event")); @@ -352,13 +353,13 @@ void GraphicsCaptureSource::AttemptCapture() //------------------------------------------- // load keepalive event - hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << int(targetProcessID)); + hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << UINT(targetProcessID)); //------------------------------------------- hwndCapture = hwndTarget; - hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << int(targetProcessID)); + hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID)); if(hSignalRestart) { SetEvent(hSignalRestart); @@ -517,14 +518,36 @@ void GraphicsCaptureSource::EndScene() void GraphicsCaptureSource::Tick(float fSeconds) { - if(hSignalExit && WaitForSingleObject(hSignalExit, 0) == WAIT_OBJECT_0) + if(hSignalExit && WaitForSingleObject(hSignalExit, 0) == WAIT_OBJECT_0) { + Log(TEXT("Exit signal received, terminating capture")); EndCapture(); + } if(bCapturing && !hSignalReady && targetProcessID) - hSignalReady = GetEvent(String() << CAPTURE_READY_EVENT << int(targetProcessID)); + hSignalReady = GetEvent(String() << CAPTURE_READY_EVENT << UINT(targetProcessID)); - if(hSignalReady && (WaitForSingleObject(hSignalReady, 0) == WAIT_OBJECT_0)) - NewCapture(); + if (hSignalReady) { + DWORD val = WaitForSingleObject(hSignalReady, 0); + if (val == WAIT_OBJECT_0) + NewCapture(); + /*else if (val != WAIT_TIMEOUT) + Log(TEXT("what the heck? val is 0x%08lX"), val);*/ + } + + /* static int floong = 0; + + if (floong++ == 30) { + Log(TEXT("valid, bCapturing = %s"), bCapturing ? TEXT("true") : TEXT("false")); + floong = 0; + } + } else { + static int floong = 0; + + if (floong++ == 30) { + Log(TEXT("not valid, bCapturing = %s"), bCapturing ? TEXT("true") : TEXT("false")); + floong = 0; + } + }*/ if(bCapturing && !capture) { @@ -546,10 +569,15 @@ void GraphicsCaptureSource::Tick(float fSeconds) } else { - if(!IsWindow(hwndCapture) || (bUseHotkey && hwndNextTarget && hwndNextTarget != hwndTarget)) + if(!IsWindow(hwndCapture)) { + Log(TEXT("Capture window 0x%08lX invalid or changing, terminating capture"), DWORD(hwndCapture)); EndCapture(); - else + } else if (bUseHotkey && hwndNextTarget && hwndNextTarget != hwndTarget) { + Log(TEXT("Capture hotkey triggered for new window, terminating capture")); + EndCapture(); + } else { hwndNextTarget = NULL; + } } } @@ -748,7 +776,7 @@ void GraphicsCaptureSource::SetInt(CTSTR lpName, int iVal) } } -void GraphicsCaptureSource::CaptureHotkey(DWORD hotkey, GraphicsCaptureSource *capture, bool bDown) +void STDCALL GraphicsCaptureSource::CaptureHotkey(DWORD hotkey, GraphicsCaptureSource *capture, bool bDown) { if (bDown) capture->hwndNextTarget = GetForegroundWindow(); diff --git a/GraphicsCapture/GraphicsCaptureSource.h b/GraphicsCapture/GraphicsCaptureSource.h index c7d3ebc5..2e42bd25 100644 --- a/GraphicsCapture/GraphicsCaptureSource.h +++ b/GraphicsCapture/GraphicsCaptureSource.h @@ -58,7 +58,7 @@ class GraphicsCaptureSource : public ImageSource void AttemptCapture(); - static void CaptureHotkey(DWORD hotkey, GraphicsCaptureSource *capture, bool bDown); + static void STDCALL CaptureHotkey(DWORD hotkey, GraphicsCaptureSource *capture, bool bDown); public: bool Init(XElement *data); diff --git a/GraphicsCapture/WindowCapture.cpp b/GraphicsCapture/WindowCapture.cpp new file mode 100644 index 00000000..8a270a39 --- /dev/null +++ b/GraphicsCapture/WindowCapture.cpp @@ -0,0 +1,66 @@ +/******************************************************************************** + Copyright (C) 2012 Hugh Bailey + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +********************************************************************************/ + + +#include "GraphicsCapture.h" + + +void WindowCapture::Destroy() +{ + delete sharedTexture; + sharedTexture = NULL; +} + +bool WindowCapture::Init(CaptureInfo &info) +{ + hwndTarget = (HWND)info.hwndCapture; + + cx = info.cx; + cy = info.cy; + + if (!cx || !cy) + return false; + + sharedTexture = CreateGDITexture(info.cx, info.cy); + + return true; +} + +Texture* WindowCapture::LockTexture() +{ + HDC hdcTarget = GetDC(hwndTarget); + if (!hdcTarget) return NULL; + + bool bSuccess = false; + HDC hDC; + if (sharedTexture->GetDC(hDC)) { + BitBlt(hDC, 0, 0, cx, cy, hdcTarget, 0, 0, SRCCOPY); + + sharedTexture->ReleaseDC(); + + bSuccess = true; + } + + ReleaseDC(hwndTarget, hdcTarget); + + return bSuccess ? sharedTexture : NULL; +} + +void WindowCapture::UnlockTexture() +{ +} diff --git a/GraphicsCapture/WindowCapture.h b/GraphicsCapture/WindowCapture.h new file mode 100644 index 00000000..e549f556 --- /dev/null +++ b/GraphicsCapture/WindowCapture.h @@ -0,0 +1,36 @@ +/******************************************************************************** + Copyright (C) 2012 Hugh Bailey + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +********************************************************************************/ + + +#pragma once + + +class WindowCapture : public GraphicsCaptureMethod +{ + Texture *sharedTexture; + HWND hwndTarget; + + UINT cx, cy; + +public: + void Destroy(); + virtual bool Init(CaptureInfo &info); + + virtual Texture* LockTexture(); + virtual void UnlockTexture(); +};