diff --git a/.gitignore b/.gitignore index 2cb497fc..9c23f634 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.TMP # git ignore file AppPackages/ BundleArtifacts/ diff --git a/SpectatorView/Calibration/Calibration.sln b/SpectatorView/Calibration/Calibration.sln index d9b80fd2..2110c723 100644 --- a/SpectatorView/Calibration/Calibration.sln +++ b/SpectatorView/Calibration/Calibration.sln @@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 15.0.26430.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Calibration", "Calibration\Calibration.vcxproj", "{70239410-43FF-4F2B-ACBB-E640437F7289}" + ProjectSection(ProjectDependencies) = postProject + {16FA1D9F-8C62-4A94-9A47-EE2E153DC625} = {16FA1D9F-8C62-4A94-9A47-EE2E153DC625} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CA8BAF72-3FE7-4F0C-B0E0-0C53C4CB5CD5}" ProjectSection(SolutionItems) = preProject @@ -12,24 +15,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedHeaders", "..\Compositor\SharedHeaders\SharedHeaders.vcxitems", "{0C2DFF51-C769-460F-B9D6-05C82FC60F56}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompositorDLL", "..\Compositor\CompositorDLL\CompositorDLL.vcxproj", "{16FA1D9F-8C62-4A94-9A47-EE2E153DC625}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution ..\Compositor\SharedHeaders\SharedHeaders.vcxitems*{0c2dff51-c769-460f-b9d6-05c82fc60f56}*SharedItemsImports = 9 + ..\Compositor\SharedHeaders\SharedHeaders.vcxitems*{16fa1d9f-8c62-4a94-9a47-ee2e153dc625}*SharedItemsImports = 4 ..\Compositor\SharedHeaders\SharedHeaders.vcxitems*{70239410-43ff-4f2b-acbb-e640437f7289}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {70239410-43FF-4F2B-ACBB-E640437F7289}.Debug|x64.ActiveCfg = Debug|x64 {70239410-43FF-4F2B-ACBB-E640437F7289}.Debug|x64.Build.0 = Debug|x64 - {70239410-43FF-4F2B-ACBB-E640437F7289}.Debug|x86.ActiveCfg = Release|x64 {70239410-43FF-4F2B-ACBB-E640437F7289}.Release|x64.ActiveCfg = Release|x64 {70239410-43FF-4F2B-ACBB-E640437F7289}.Release|x64.Build.0 = Release|x64 - {70239410-43FF-4F2B-ACBB-E640437F7289}.Release|x86.ActiveCfg = Release|x64 + {16FA1D9F-8C62-4A94-9A47-EE2E153DC625}.Debug|x64.ActiveCfg = Debug|x64 + {16FA1D9F-8C62-4A94-9A47-EE2E153DC625}.Debug|x64.Build.0 = Debug|x64 + {16FA1D9F-8C62-4A94-9A47-EE2E153DC625}.Release|x64.ActiveCfg = Release|x64 + {16FA1D9F-8C62-4A94-9A47-EE2E153DC625}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SpectatorView/Calibration/Calibration/Calibration.vcxproj b/SpectatorView/Calibration/Calibration/Calibration.vcxproj index 66f9c90f..3f6507ce 100644 --- a/SpectatorView/Calibration/Calibration/Calibration.vcxproj +++ b/SpectatorView/Calibration/Calibration/Calibration.vcxproj @@ -78,8 +78,8 @@ NotSet true - d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib; - $(ProjectDir)\ + d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib;CompositorDLL.lib + $(ProjectDir)\;$(ProjectDir)\..\..\Compositor\x64\$(Configuration) xcopy /y "$(OpenCV_vc14)\bin\*.dll" "$(OutDir)" @@ -87,6 +87,7 @@ if EXIST "$(decklink_inc)" xcopy /y "$(decklink_inc)" xcopy /y "$(OpenCV_vc14)\bin\*.dll" +xcopy /y "$(ProjectDir)\..\..\Compositor\x64\$(Configuration)\CompositorDLL.dll" if EXIST "$(Elgato_Filter)" xcopy /y "$(Elgato_Filter)" ..\..\Compositor\CompositorDLL\ @@ -117,8 +118,8 @@ if EXIST "$(Elgato_Filter)" xcopy /y "$(Elgato_Filter)" ..\..\Compositor\Composi true true true - d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib; - $(ProjectDir)\ + d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;odbc32.lib;odbccp32.lib;CompositorDLL.lib + $(ProjectDir)\;$(ProjectDir)\..\..\Compositor\x64\$(Configuration) xcopy /y "$(OpenCV_vc14)\bin\*.dll" "$(OutDir)" @@ -126,6 +127,7 @@ if EXIST "$(Elgato_Filter)" xcopy /y "$(Elgato_Filter)" ..\..\Compositor\Composi if EXIST "$(decklink_inc)" xcopy /y "$(decklink_inc)" xcopy /y "$(OpenCV_vc14)\bin\*.dll" +xcopy /y "$(ProjectDir)\..\..\Compositor\x64\$(Configuration)\CompositorDLL.dll" if EXIST "$(Elgato_Filter)" xcopy /y "$(Elgato_Filter)" ..\..\Compositor\CompositorDLL\ diff --git a/SpectatorView/Calibration/Calibration/CalibrationApp.cpp b/SpectatorView/Calibration/Calibration/CalibrationApp.cpp index 45eaec5f..a493faba 100644 --- a/SpectatorView/Calibration/Calibration/CalibrationApp.cpp +++ b/SpectatorView/Calibration/Calibration/CalibrationApp.cpp @@ -21,7 +21,7 @@ CalibrationApp::CalibrationApp() : InitializeCriticalSection(&calibrationPictureCriticalSection); boardDimensions = cv::Size(GRID_CELLS_X - 1, GRID_CELLS_Y - 1); - colorBytes = new BYTE[FRAME_BUFSIZE]; + colorBytes = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; // Force 60fps timer.SetFixedTimeStep(true); @@ -79,11 +79,11 @@ void CalibrationApp::Initialize(HWND window, int width, int height) CreateWindowSizeDependentResources(); // Calibration Images. - colorImage_cam = cv::Mat(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC4); + colorImage_cam = cv::Mat(FrameProviderStaticConfig::height, FrameProviderStaticConfig::width, CV_8UC4); resizedColorImage_cam = cv::Mat(HOLO_HEIGHT, HOLO_WIDTH, CV_8UC4); colorImage_holo = cv::Mat(HOLO_HEIGHT, HOLO_WIDTH, CV_8UC4); - latestColorMat = cv::Mat(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC4); - cachedColorMat = cv::Mat(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC4); + latestColorMat = cv::Mat(FrameProviderStaticConfig::height, FrameProviderStaticConfig::width, CV_8UC4); + cachedColorMat = cv::Mat(FrameProviderStaticConfig::height, FrameProviderStaticConfig::width, CV_8UC4); // Create an http_client to use REST APIs on the Hololens. http_client_config client_config; @@ -97,7 +97,7 @@ void CalibrationApp::Initialize(HWND window, int width, int height) // Create textures, RT's and SRV's auto device = deviceResources->GetD3DDevice(); - CD3D11_TEXTURE2D_DESC rtDesc(DXGI_FORMAT_R8G8B8A8_UNORM, FRAME_WIDTH, FRAME_HEIGHT, + CD3D11_TEXTURE2D_DESC rtDesc(DXGI_FORMAT_R8G8B8A8_UNORM, FrameProviderStaticConfig::width, FrameProviderStaticConfig::height, 1, 1, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE); device->CreateTexture2D(&rtDesc, nullptr, &colorTexture); @@ -134,8 +134,8 @@ void CalibrationApp::Initialize(HWND window, int width, int height) } } - yuv2rgbParameters.width = FRAME_WIDTH; - yuv2rgbParameters.height = FRAME_HEIGHT; + yuv2rgbParameters.width = FrameProviderStaticConfig::width; + yuv2rgbParameters.height = FrameProviderStaticConfig::height; CD3D11_BUFFER_DESC cbDesc(sizeof(CONVERSION_PARAMETERS), D3D11_BIND_CONSTANT_BUFFER); device->CreateBuffer(&cbDesc, nullptr, conversionParamBuffer.ReleaseAndGetAddressOf()); @@ -218,7 +218,7 @@ void CalibrationApp::TakeCalibrationPicture() // Cache the latest color frame so we do not stall the UI thread while checking if there is a chess board in frame. EnterCriticalSection(&photoTextureCriticalSection); - memcpy(cachedColorMat.data, latestColorMat.data, FRAME_BUFSIZE); + memcpy(cachedColorMat.data, latestColorMat.data, FrameProviderStaticConfig::getFrameBuffSize()); LeaveCriticalSection(&photoTextureCriticalSection); if (!HasChessBoard(cachedColorMat, grayscaleImage, corners)) @@ -232,7 +232,7 @@ void CalibrationApp::TakeCalibrationPicture() // Lock the latest camera image immediately after the hololens picture has been taken. EnterCriticalSection(&photoTextureCriticalSection); - memcpy(cachedColorMat.data, latestColorMat.data, FRAME_BUFSIZE); + memcpy(cachedColorMat.data, latestColorMat.data, FrameProviderStaticConfig::getFrameBuffSize()); LeaveCriticalSection(&photoTextureCriticalSection); cv::imwrite(cv::String(StringHelper::ws2s(camPath)), cachedColorMat); @@ -653,8 +653,8 @@ void CalibrationApp::OnWindowSizeChanged(int width, int height) // Properties void CalibrationApp::GetDefaultSize(int& width, int& height) const { - width = FRAME_WIDTH; - height = FRAME_HEIGHT; + width = FrameProviderStaticConfig::width; + height = FrameProviderStaticConfig::height; } // These are the resources that depend on the device. @@ -667,8 +667,8 @@ void CalibrationApp::CreateDeviceDependentResources() // Camera colorSourceRect.left = 0; colorSourceRect.top = 0; - colorSourceRect.right = FRAME_WIDTH; - colorSourceRect.bottom = FRAME_HEIGHT; + colorSourceRect.right = FrameProviderStaticConfig::width; + colorSourceRect.bottom = FrameProviderStaticConfig::height; auto device = deviceResources->GetD3DDevice(); auto blob = DX::ReadData(L"YUV2RGB.cso"); diff --git a/SpectatorView/Calibration/Calibration/DeviceResources.cpp b/SpectatorView/Calibration/Calibration/DeviceResources.cpp index e47b6d7f..bbe7ddf5 100644 --- a/SpectatorView/Calibration/Calibration/DeviceResources.cpp +++ b/SpectatorView/Calibration/Calibration/DeviceResources.cpp @@ -3,6 +3,7 @@ #include "stdafx.h" #include "DeviceResources.h" +#include "FrameProviderStaticConfig.h" using namespace DirectX; @@ -226,8 +227,8 @@ void DX::DeviceResources::CreateWindowSizeDependentResources() // Determine the render target size in pixels. // Force backbuffer to captured image dimensions. - UINT backBufferWidth = FRAME_WIDTH;// std::max(m_outputSize.right - m_outputSize.left, 1); - UINT backBufferHeight = FRAME_HEIGHT;// std::max(m_outputSize.bottom - m_outputSize.top, 1); + UINT backBufferWidth = FrameProviderStaticConfig::width;// std::max(m_outputSize.right - m_outputSize.left, 1); + UINT backBufferHeight = FrameProviderStaticConfig::height;// std::max(m_outputSize.bottom - m_outputSize.top, 1); if (m_swapChain) { diff --git a/SpectatorView/Calibration/Calibration/Main.cpp b/SpectatorView/Calibration/Calibration/Main.cpp index 3328dd1b..f058fbaa 100644 --- a/SpectatorView/Calibration/Calibration/Main.cpp +++ b/SpectatorView/Calibration/Calibration/Main.cpp @@ -4,6 +4,11 @@ #include "stdafx.h" #include "CalibrationApp.h" +#define CAMERA_CFG_STATIC_IMPL +#include "CameraConfigurationFile.h" + +#include +using namespace std::string_literals; using namespace DirectX; namespace @@ -16,6 +21,30 @@ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Entry point int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { + + auto const filePath = CameraConfigurationFile::getMyDocumentPath() + "\\camera.cfg"s; + + OutputDebugStringA(filePath.c_str()); + + try + { + CameraConfigurationFile cfg(filePath); + cfg.readConfig(); + + FrameProviderStaticConfig::width = int(cfg.getWidth()); + FrameProviderStaticConfig::height = int(cfg.getHeight()); + FrameProviderStaticConfig::fps = float(cfg.getFrameRate()); + } + catch(const std::exception& e) + { + OutputDebugStringA(e.what()); + + //fallback to default values + FrameProviderStaticConfig::width = FRAME_WIDTH; + FrameProviderStaticConfig::height = FRAME_HEIGHT; + FrameProviderStaticConfig::fps = VIDEO_FPS; + } + UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); diff --git a/SpectatorView/Compositor/CompositorDLL/CompositorDLL.cpp b/SpectatorView/Compositor/CompositorDLL/CompositorDLL.cpp index 3e202dee..8f4a0369 100644 Binary files a/SpectatorView/Compositor/CompositorDLL/CompositorDLL.cpp and b/SpectatorView/Compositor/CompositorDLL/CompositorDLL.cpp differ diff --git a/SpectatorView/Compositor/CompositorDLL/CompositorInterface.cpp b/SpectatorView/Compositor/CompositorDLL/CompositorInterface.cpp index 2a36d647..b30d1bce 100644 --- a/SpectatorView/Compositor/CompositorDLL/CompositorInterface.cpp +++ b/SpectatorView/Compositor/CompositorDLL/CompositorInterface.cpp @@ -3,6 +3,7 @@ #include "stdafx.h" #include "CompositorInterface.h" +#include "FrameProviderStaticConfig.h" CompositorInterface::CompositorInterface() @@ -172,7 +173,7 @@ void CompositorInterface::TakePicture(ID3D11Texture2D* outputTexture) // Get bytes from texture because screengrab does not support texture format provided by Unity. DirectXHelper::GetBytesFromTexture(_device, outputTexture, FRAME_BPP, photoBytes); - ID3D11Texture2D* tex = DirectXHelper::CreateTexture(_device, photoBytes, FRAME_WIDTH, FRAME_HEIGHT, FRAME_BPP, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); + ID3D11Texture2D* tex = DirectXHelper::CreateTexture(_device, photoBytes, FrameProviderStaticConfig::width, FrameProviderStaticConfig::height, FRAME_BPP, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); photoIndex++; std::wstring photoPath = DirectoryHelper::FindUniqueFileName(outputPath, L"Photo", L".png", photoIndex); @@ -183,7 +184,7 @@ void CompositorInterface::TakePicture(ID3D11Texture2D* outputTexture) bool CompositorInterface::InitializeVideoEncoder(ID3D11Device* device) { - videoEncoder = new VideoEncoder(FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH * FRAME_BPP, VIDEO_FPS, + videoEncoder = new VideoEncoder(FrameProviderStaticConfig::width, FrameProviderStaticConfig::height, FrameProviderStaticConfig::width * FRAME_BPP, UINT(std::ceil(FrameProviderStaticConfig::fps)), AUDIO_BUFSIZE, AUDIO_SAMPLE_RATE, AUDIO_CHANNELS, AUDIO_BPS); return videoEncoder->Initialize(device); @@ -254,7 +255,7 @@ void CompositorInterface::AllocateVideoBuffers() for (int i = 0; i < NUM_VIDEO_BUFFERS; i++) { - videoBytes[i] = new byte[(int)(1.5f * FRAME_WIDTH * FRAME_HEIGHT)]; + videoBytes[i] = new byte[(int)(1.5f * FrameProviderStaticConfig::width * FrameProviderStaticConfig::height)]; } } diff --git a/SpectatorView/Compositor/CompositorDLL/CompositorInterface.h b/SpectatorView/Compositor/CompositorDLL/CompositorInterface.h index 02fa7ec1..541b532d 100644 --- a/SpectatorView/Compositor/CompositorDLL/CompositorInterface.h +++ b/SpectatorView/Compositor/CompositorDLL/CompositorInterface.h @@ -107,7 +107,7 @@ class CompositorInterface int lastVideoFrame = -1; BufferedTextureFetch VideoTextureBuffer; VideoEncoder* videoEncoder = nullptr; - byte* photoBytes = new byte[FRAME_BUFSIZE]; + byte* photoBytes = new byte[FrameProviderStaticConfig::getFrameBuffSize()]; byte** videoBytes = nullptr; int videoBufferIndex = 0; diff --git a/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.cpp b/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.cpp index 63fc27d9..d5db33dc 100644 --- a/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.cpp +++ b/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.cpp @@ -30,6 +30,8 @@ #include #include "DeckLinkDevice.h" +#include "FrameProviderStaticConfig.h" + using namespace std; @@ -44,7 +46,7 @@ DeckLinkDevice::DeckLinkDevice(IDeckLink* device) : { for (int i = 0; i < MAX_NUM_CACHED_BUFFERS; i++) { - bufferCache[i].buffer = new BYTE[FRAME_BUFSIZE]; + bufferCache[i].buffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; bufferCache[i].timeStamp = 0; } @@ -156,13 +158,13 @@ bool DeckLinkDevice::Init(ID3D11ShaderResourceView* colorSRV) IDeckLinkDisplayMode* displayMode = NULL; BSTR deviceNameBSTR = NULL; - ZeroMemory(rawBuffer, FRAME_BUFSIZE_RAW); - ZeroMemory(latestBuffer, FRAME_BUFSIZE); - ZeroMemory(outputBuffer, FRAME_BUFSIZE); + ZeroMemory(rawBuffer, FrameProviderStaticConfig::getFrameBuffSizeRaw()); + ZeroMemory(latestBuffer, FrameProviderStaticConfig::getFrameBuffSize()); + ZeroMemory(outputBuffer, FrameProviderStaticConfig::getFrameBuffSize()); for (int i = 0; i < MAX_NUM_CACHED_BUFFERS; i++) { - ZeroMemory(bufferCache[i].buffer, FRAME_BUFSIZE); + ZeroMemory(bufferCache[i].buffer, FrameProviderStaticConfig::getFrameBuffSize()); } captureFrameIndex = 0; @@ -200,7 +202,7 @@ bool DeckLinkDevice::Init(ID3D11ShaderResourceView* colorSRV) // 1080i output causes horizontal artifacts on screen. if (m_deckLinkOutput != NULL) { - m_deckLinkOutput->CreateVideoFrame(FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH * FRAME_BPP, bmdFormat8BitBGRA, bmdFrameFlagDefault, &outputFrame); + m_deckLinkOutput->CreateVideoFrame(FrameProviderStaticConfig::width, FrameProviderStaticConfig::height, FrameProviderStaticConfig::width * FRAME_BPP, bmdFormat8BitBGRA, bmdFrameFlagDefault, &outputFrame); outputFrame->GetBytes((void**)&outputBuffer); } @@ -294,7 +296,7 @@ HRESULT DeckLinkDevice::VideoInputFormatChanged(/* in */ BMDVideoInputFormatChan OutputDebugString(L"\n"); // If we do not have the correct dimension frames - loop until user changes camera settings. - if (newMode->GetWidth() != FRAME_WIDTH || newMode->GetHeight() != FRAME_HEIGHT) + if (newMode->GetWidth() != FrameProviderStaticConfig::width || newMode->GetHeight() != FrameProviderStaticConfig::height) { OutputDebugString(L"Invalid frame dimensions detected.\n"); OutputDebugString(L"Actual Frame Dimensions: "); @@ -304,9 +306,9 @@ HRESULT DeckLinkDevice::VideoInputFormatChanged(/* in */ BMDVideoInputFormatChan OutputDebugString(L"\n"); OutputDebugString(L"Expected Frame Dimensions: "); - OutputDebugString(std::to_wstring(FRAME_WIDTH).c_str()); + OutputDebugString(std::to_wstring(FrameProviderStaticConfig::width).c_str()); OutputDebugString(L", "); - OutputDebugString(std::to_wstring(FRAME_HEIGHT).c_str()); + OutputDebugString(std::to_wstring(FrameProviderStaticConfig::height).c_str()); OutputDebugString(L"\n"); LeaveCriticalSection(&m_captureCardCriticalSection); @@ -417,7 +419,7 @@ void DeckLinkDevice::Update(int compositeFrameIndex) const BufferCache& buffer = bufferCache[compositeFrameIndex % MAX_NUM_CACHED_BUFFERS]; if (buffer.buffer != nullptr) { - DirectXHelper::UpdateSRV(device, _colorSRV, buffer.buffer, FRAME_WIDTH * FRAME_BPP); + DirectXHelper::UpdateSRV(device, _colorSRV, buffer.buffer, FrameProviderStaticConfig::width * FRAME_BPP); } if (supportsOutput && device != nullptr && _outputTexture != nullptr) diff --git a/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.h b/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.h index a59a9cc3..94bf67e2 100644 --- a/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.h +++ b/SpectatorView/Compositor/CompositorDLL/DeckLinkDevice.h @@ -59,10 +59,10 @@ class DeckLinkDevice : public IDeckLinkInputCallback CRITICAL_SECTION m_outputCriticalSection; BYTE* localFrameBuffer; - BYTE* rawBuffer = new BYTE[FRAME_BUFSIZE_RAW]; + BYTE* rawBuffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSizeRaw()]; - BYTE* latestBuffer = new BYTE[FRAME_BUFSIZE]; - BYTE* outputBuffer = new BYTE[FRAME_BUFSIZE]; + BYTE* latestBuffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; + BYTE* outputBuffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; IDeckLinkMutableVideoFrame* outputFrame = NULL; diff --git a/SpectatorView/Compositor/CompositorDLL/DeckLinkManager.cpp b/SpectatorView/Compositor/CompositorDLL/DeckLinkManager.cpp index 8b0c0aea..79e9b45d 100644 --- a/SpectatorView/Compositor/CompositorDLL/DeckLinkManager.cpp +++ b/SpectatorView/Compositor/CompositorDLL/DeckLinkManager.cpp @@ -3,6 +3,8 @@ #include "stdafx.h" #include "DeckLinkManager.h" +#include "FrameProviderStaticConfig.h" + #if USE_DECKLINK || USE_DECKLINK_SHUTTLE @@ -52,25 +54,25 @@ HRESULT DeckLinkManager::Initialize(ID3D11ShaderResourceView* srv) // However, if you select a valid format that is less than your output format, your frames will be downsized. // Update the videoDisplayMode if your camera's output does not meet this selection criteria. BMDDisplayMode videoDisplayMode; - if (FRAME_HEIGHT < 1080) + if (FrameProviderStaticConfig::height < 1080) { videoDisplayMode = bmdModeHD720p5994; } - else if (FRAME_HEIGHT >= 1080 && FRAME_HEIGHT < 2160) + else if (FrameProviderStaticConfig::height >= 1080 && FrameProviderStaticConfig::height < 2160) { videoDisplayMode = bmdModeHD1080p5994; #if USE_DECKLINK_SHUTTLE videoDisplayMode = bmdModeHD1080p2398; #endif } - else if (FRAME_HEIGHT == 2160) + else if (FrameProviderStaticConfig::height == 2160) { videoDisplayMode = bmdMode4K2160p5994; #if USE_DECKLINK_SHUTTLE videoDisplayMode = bmdMode4K2160p2398; #endif } - else if (FRAME_HEIGHT > 2160) + else if (FrameProviderStaticConfig::height > 2160) { videoDisplayMode = bmdMode4kDCI2398; } diff --git a/SpectatorView/Compositor/CompositorDLL/ElgatoFrameProvider.cpp b/SpectatorView/Compositor/CompositorDLL/ElgatoFrameProvider.cpp index b6e93eeb..5e57d47c 100644 --- a/SpectatorView/Compositor/CompositorDLL/ElgatoFrameProvider.cpp +++ b/SpectatorView/Compositor/CompositorDLL/ElgatoFrameProvider.cpp @@ -3,6 +3,8 @@ #include "stdafx.h" #include "ElgatoFrameProvider.h" +#include "FrameProviderStaticConfig.h" + #if USE_ELGATO @@ -121,23 +123,23 @@ HRESULT ElgatoFrameProvider::InitGraph() hr = filter->GetSettingsEx(&settings); _ASSERT(SUCCEEDED(hr)); - if (FRAME_HEIGHT == 1080) + if (FrameProviderStaticConfig::height == 1080) { settings.Settings.profile = VIDEO_CAPTURE_FILTER_VID_ENC_PROFILE_1080; } - else if (FRAME_HEIGHT == 720) + else if (FrameProviderStaticConfig::height == 720) { settings.Settings.profile = VIDEO_CAPTURE_FILTER_VID_ENC_PROFILE_720; } - else if (FRAME_HEIGHT == 480) + else if (FrameProviderStaticConfig::height == 480) { settings.Settings.profile = VIDEO_CAPTURE_FILTER_VID_ENC_PROFILE_480; } - else if (FRAME_HEIGHT == 360) + else if (FrameProviderStaticConfig::height == 360) { settings.Settings.profile = VIDEO_CAPTURE_FILTER_VID_ENC_PROFILE_360; } - else if (FRAME_HEIGHT == 240) + else if (FrameProviderStaticConfig::height == 240) { settings.Settings.profile = VIDEO_CAPTURE_FILTER_VID_ENC_PROFILE_240; } @@ -245,17 +247,17 @@ HRESULT ElgatoFrameProvider::SetSampleGrabberParameters() amt.subtype = MEDIASUBTYPE_UYVY; amt.formattype = FORMAT_VideoInfo; amt.bFixedSizeSamples = TRUE; - amt.lSampleSize = FRAME_WIDTH * FRAME_HEIGHT * FRAME_BPP_RAW; + amt.lSampleSize = FrameProviderStaticConfig::width * FrameProviderStaticConfig::height * FRAME_BPP_RAW; amt.bTemporalCompression = FALSE; VIDEOINFOHEADER vih; ZeroMemory(&vih, sizeof(VIDEOINFOHEADER)); - vih.rcTarget.right = FRAME_WIDTH; - vih.rcTarget.bottom = FRAME_HEIGHT; + vih.rcTarget.right = FrameProviderStaticConfig::width; + vih.rcTarget.bottom = FrameProviderStaticConfig::height; vih.AvgTimePerFrame = (REFERENCE_TIME)((1.0f / 30.0f) * S2HNS); - vih.bmiHeader.biWidth = FRAME_WIDTH; - vih.bmiHeader.biHeight = FRAME_HEIGHT; - vih.bmiHeader.biSizeImage = FRAME_WIDTH * FRAME_HEIGHT * FRAME_BPP_RAW; + vih.bmiHeader.biWidth = FrameProviderStaticConfig::width; + vih.bmiHeader.biHeight = FrameProviderStaticConfig::height; + vih.bmiHeader.biSizeImage = FrameProviderStaticConfig::width * FrameProviderStaticConfig::height * FRAME_BPP_RAW; amt.pbFormat = (BYTE*)&vih; diff --git a/SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.cpp b/SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.cpp index 47fc5262..08b854a7 100644 --- a/SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.cpp +++ b/SpectatorView/Compositor/CompositorDLL/ElgatoSampleCallback.cpp @@ -12,7 +12,7 @@ ElgatoSampleCallback::ElgatoSampleCallback(ID3D11Device* device) : for (int i = 0; i < MAX_NUM_CACHED_BUFFERS; i++) { - bufferCache[i].buffer = new BYTE[FRAME_BUFSIZE]; + bufferCache[i].buffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; bufferCache[i].timeStamp = 0; } @@ -45,10 +45,10 @@ STDMETHODIMP ElgatoSampleCallback::BufferCB(double time, BYTE *pBuffer, long len } int copyLength = length; - if (copyLength > FRAME_BUFSIZE) + if (copyLength > FrameProviderStaticConfig::getFrameBuffSize()) { // This might happen if the camera is outputting 4K but the system is expecting 1080. - copyLength = FRAME_BUFSIZE; + copyLength = static_cast(FrameProviderStaticConfig::getFrameBuffSize()); } captureFrameIndex++; @@ -66,6 +66,6 @@ void ElgatoSampleCallback::UpdateSRV(ID3D11ShaderResourceView* srv, int composit const BufferCache& buffer = bufferCache[compositeFrameIndex % MAX_NUM_CACHED_BUFFERS]; if (buffer.buffer != nullptr) { - DirectXHelper::UpdateSRV(_device, srv, buffer.buffer, FRAME_WIDTH * FRAME_BPP); + DirectXHelper::UpdateSRV(_device, srv, buffer.buffer, FrameProviderStaticConfig::width * FRAME_BPP); } } diff --git a/SpectatorView/Compositor/CompositorDLL/OpenCVFrameProvider.cpp b/SpectatorView/Compositor/CompositorDLL/OpenCVFrameProvider.cpp index f216ab6b..fb0ac72c 100644 --- a/SpectatorView/Compositor/CompositorDLL/OpenCVFrameProvider.cpp +++ b/SpectatorView/Compositor/CompositorDLL/OpenCVFrameProvider.cpp @@ -3,13 +3,15 @@ #include "stdafx.h" #include "OpenCVFrameProvider.h" +#include "FrameProviderStaticConfig.h" + #if USE_OPENCV OpenCVFrameProvider::OpenCVFrameProvider() { QueryPerformanceFrequency(&freq); - rgbaFrame = cv::Mat(FRAME_HEIGHT, FRAME_WIDTH, CV_8UC4); + rgbaFrame = cv::Mat(FrameProviderStaticConfig::height, FrameProviderStaticConfig::width, CV_8UC4); for (int i = 0; i < 4; i++) { @@ -19,7 +21,7 @@ OpenCVFrameProvider::OpenCVFrameProvider() for (int i = 0; i < MAX_NUM_CACHED_BUFFERS; i++) { - bufferCache[i].buffer = new BYTE[FRAME_BUFSIZE]; + bufferCache[i].buffer = new BYTE[FrameProviderStaticConfig::getFrameBuffSize()]; bufferCache[i].timeStamp = 0; } @@ -52,7 +54,7 @@ HRESULT OpenCVFrameProvider::Initialize(ID3D11ShaderResourceView* srv) for (int i = 0; i < MAX_NUM_CACHED_BUFFERS; i++) { - ZeroMemory(bufferCache[i].buffer, FRAME_BUFSIZE); + ZeroMemory(bufferCache[i].buffer, FrameProviderStaticConfig::getFrameBuffSize()); } captureFrameIndex = 0; @@ -63,8 +65,8 @@ HRESULT OpenCVFrameProvider::Initialize(ID3D11ShaderResourceView* srv) // This must be called after opening. // Note: This may fail, and your capture will resume at the camera's native resolution. // In this case, the Update loop will print an error with the expected frame resolution. - videoCapture->set(cv::CAP_PROP_FRAME_WIDTH, FRAME_WIDTH); - videoCapture->set(cv::CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT); + videoCapture->set(cv::CAP_PROP_FRAME_WIDTH, FrameProviderStaticConfig::width); + videoCapture->set(cv::CAP_PROP_FRAME_HEIGHT, FrameProviderStaticConfig::height); if (IsEnabled()) { @@ -108,16 +110,16 @@ void OpenCVFrameProvider::Update(int compositeFrameIndex) double width = videoCapture->get(cv::CAP_PROP_FRAME_WIDTH); double height = videoCapture->get(cv::CAP_PROP_FRAME_HEIGHT); - if (width != FRAME_WIDTH) + if (width != FrameProviderStaticConfig::width) { - OutputDebugString(L"ERROR: captured width does not equal FRAME_WIDTH. Expecting: "); + OutputDebugString(L"ERROR: captured width does not equal FrameProviderStaticConfig::width. Expecting: "); OutputDebugString(std::to_wstring(width).c_str()); OutputDebugString(L"\n"); } - if (height != FRAME_HEIGHT) + if (height != FrameProviderStaticConfig::height) { - OutputDebugString(L"ERROR: captured height does not equal FRAME_HEIGHT. Expecting: "); + OutputDebugString(L"ERROR: captured height does not equal FrameProviderStaticConfig::height. Expecting: "); OutputDebugString(std::to_wstring(height).c_str()); OutputDebugString(L"\n"); } @@ -127,7 +129,7 @@ void OpenCVFrameProvider::Update(int compositeFrameIndex) captureFrameIndex++; BYTE* buffer = bufferCache[captureFrameIndex % MAX_NUM_CACHED_BUFFERS].buffer; - memcpy(buffer, rgbaFrame.data, FRAME_BUFSIZE); + memcpy(buffer, rgbaFrame.data, FrameProviderStaticConfig::getFrameBuffSize()); bufferCache[captureFrameIndex % MAX_NUM_CACHED_BUFFERS].timeStamp = (latestTimeStamp * S2HNS) / freq.QuadPart; } } @@ -136,7 +138,7 @@ void OpenCVFrameProvider::Update(int compositeFrameIndex) const BufferCache& buffer = bufferCache[compositeFrameIndex % MAX_NUM_CACHED_BUFFERS]; if (buffer.buffer != nullptr) { - DirectXHelper::UpdateSRV(_device, _colorSRV, buffer.buffer, FRAME_WIDTH * FRAME_BPP); + DirectXHelper::UpdateSRV(_device, _colorSRV, buffer.buffer, FrameProviderStaticConfig::width * FRAME_BPP); } } diff --git a/SpectatorView/Compositor/SharedHeaders/CameraConfigurationFile.h b/SpectatorView/Compositor/SharedHeaders/CameraConfigurationFile.h new file mode 100644 index 00000000..f02a7232 --- /dev/null +++ b/SpectatorView/Compositor/SharedHeaders/CameraConfigurationFile.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#include +#include +#include +#include + +class CameraConfigurationFile +{ + + std::string path; + std::unordered_map content{}; + + std::string getValue(const std::string& key) + { + const auto v = content.find(key); + if (v != std::end(content)) + return v->second; + + throw std::runtime_error("Value " + key + " doesn't exist in loaded config."); + } + + double get_double(const std::string& key) + { + return strtod(getValue(key).c_str(), nullptr); + } + + size_t get_size_t(const std::string& key) + { + return static_cast(strtoul(getValue(key).c_str(), nullptr, 10)); + } + + void loadFile() + { + std::ifstream file(path); + if (!file) + throw std::runtime_error("Could not open file " + path); + + static std::string buffer, key, val; + static const std::string whitespace{ " \t\r\n\v\f" }; + + while (std::getline(file, buffer)) + { + if (buffer.empty()) continue; //Dont evaluate empty lines + + const auto firstNotWhitespace = buffer.find_first_not_of(whitespace); + if (firstNotWhitespace == std::string::npos) continue; //don't evaluate lines that contains only whitespace + + if (buffer[firstNotWhitespace] == '#') continue; //comments starts with # + + //Load the key=value in the map + std::stringstream loadStream(buffer); + std::getline(loadStream, key, '='); + std::getline(loadStream, val); + content[key] = val; + } + + } + +public: + + static std::string getMyDocumentPath() + { + //Get Win32 string path to "My Documents" + TCHAR tchar_string[MAX_PATH]; + const auto result = SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, tchar_string); + if (result != S_OK) return ""; + + //Handle the bytestring convertion if we are using wide characters +#ifdef UNICODE + //Create an empty string with the right size reserved + auto string_string = std::string(static_cast(WideCharToMultiByte(CP_UTF8, 0, tchar_string, lstrlen(tchar_string), nullptr, 0, nullptr, + nullptr)), 0); + //Fill in the string + WideCharToMultiByte(CP_UTF8, 0, tchar_string, lstrlen(tchar_string), &string_string[0], static_cast(string_string.size()), nullptr, nullptr); + return string_string; +#else +return { tchar_string }; +#endif + + } + + size_t width, height; + double fps; + + CameraConfigurationFile(const std::string& filePath) : path{filePath} + { + loadFile(); + } + + size_t getWidth() + { + return get_size_t("width"); + } + + size_t getHeight() + { + return get_size_t("height"); + } + + double getFrameRate() + { + return get_double("FPS"); + } + + void readConfig() + { + width = getWidth(); + height = getHeight(); + fps = getFrameRate(); + } +}; + + diff --git a/SpectatorView/Compositor/SharedHeaders/DirectXHelper.h b/SpectatorView/Compositor/SharedHeaders/DirectXHelper.h index 3d49572c..1f2dd234 100644 --- a/SpectatorView/Compositor/SharedHeaders/DirectXHelper.h +++ b/SpectatorView/Compositor/SharedHeaders/DirectXHelper.h @@ -8,6 +8,8 @@ #include #include "CompositorConstants.h" #include +#include "FrameProviderStaticConfig.h" + class DirectXHelper { @@ -202,7 +204,7 @@ class DirectXHelper D3D11_MAPPED_SUBRESOURCE mapResource; d3d11DevCon->Map(tmpBuf, 0, D3D11_MAP_READ, NULL, &mapResource); - memcpy(bytes, mapResource.pData, (size_t)(FRAME_WIDTH * FRAME_HEIGHT * bpp)); + memcpy(bytes, mapResource.pData, (size_t)(FrameProviderStaticConfig::width * FrameProviderStaticConfig::height * bpp)); d3d11DevCon->Unmap(tmpBuf, 0); if (tmpBuf != nullptr) diff --git a/SpectatorView/Compositor/SharedHeaders/FrameProviderStaticConfig.h b/SpectatorView/Compositor/SharedHeaders/FrameProviderStaticConfig.h new file mode 100644 index 00000000..e008c0a9 --- /dev/null +++ b/SpectatorView/Compositor/SharedHeaders/FrameProviderStaticConfig.h @@ -0,0 +1,26 @@ +#pragma once + +#include "CompositorConstants.h" + +#ifdef COMPOSITORDLL_EXPORTS +#define EXPORT_STATIC_CONFIG __declspec(dllexport) +#else +#define EXPORT_STATIC_CONFIG __declspec(dllimport) +#endif + +struct FrameProviderStaticConfig +{ + EXPORT_STATIC_CONFIG static int width; + EXPORT_STATIC_CONFIG static int height; + EXPORT_STATIC_CONFIG static float fps; + + static size_t getFrameBuffSize() + { + return width * height * FRAME_BPP; + } + + static size_t getFrameBuffSizeRaw() + { + return width * height * FRAME_BPP_RAW; + } +}; \ No newline at end of file diff --git a/SpectatorView/Compositor/SharedHeaders/SharedHeaders.vcxitems b/SpectatorView/Compositor/SharedHeaders/SharedHeaders.vcxitems index 782c214e..4683984e 100644 --- a/SpectatorView/Compositor/SharedHeaders/SharedHeaders.vcxitems +++ b/SpectatorView/Compositor/SharedHeaders/SharedHeaders.vcxitems @@ -14,9 +14,11 @@ + + diff --git a/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.cpp b/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.cpp index 3fca595c..c02928ac 100644 Binary files a/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.cpp and b/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.cpp differ diff --git a/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.vcxproj b/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.vcxproj index d6a42fe1..672cf7f1 100644 --- a/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.vcxproj +++ b/SpectatorView/Compositor/UnityCompositorInterface/UnityCompositorInterface.vcxproj @@ -108,8 +108,7 @@ Windows true - - + Shell32.lib $(OutDir)$(TargetName)$(TargetExt) @@ -134,8 +133,7 @@ Windows true - - + Shell32.lib $(OutDir)$(TargetName)$(TargetExt) @@ -164,8 +162,7 @@ true true true - - + Shell32.lib $(OutDir)$(TargetName)$(TargetExt) @@ -194,8 +191,7 @@ true true true - - + Shell32.lib $(OutDir)$(TargetName)$(TargetExt) diff --git a/SpectatorView/README.md b/SpectatorView/README.md index c728874e..885471ef 100644 --- a/SpectatorView/README.md +++ b/SpectatorView/README.md @@ -213,7 +213,13 @@ If using a camera with a capture card, you must configure the camera to output c + Optionally plug an hdmi cable from the hdmi out port to a television or preview monitor. + This is the center port on the Blackmagic capture card. -Note: if you would like to capture images or video at a resolution other than 1080P (eg: Photo Mode, 720P, or 4K) update CompositorConstants.h to match the new resolution. +Note: if you would like to capture images or video at a resolution other than 1080P (eg: Photo Mode, 720P, or 4K) you can either update CompositorConstants.h to match the new resolution, or for more flexibility, create a file you your "Documents" folder called **`camera.cfg`** containing the following configuration values and sytax: + +```ini +width=1920 +height=1080 +FPS=30 +``` ## Network Setup + Some networking stacks require UDP broadcast to be enabled on your network.