<ClInclude Include="exception\win32_exception.h" />\r
<ClInclude Include="gl\gl_check.h" />\r
<ClInclude Include="log\log.h" />\r
+ <ClInclude Include="memory\memclr.h" />\r
+ <ClInclude Include="memory\memcpy.h" />\r
<ClInclude Include="memory\page_locked_allocator.h" />\r
<ClInclude Include="memory\safe_ptr.h" />\r
<ClInclude Include="env.h" />\r
+ <ClInclude Include="os\windows\current_version.h" />\r
+ <ClInclude Include="os\windows\system_info.h" />\r
<ClInclude Include="stdafx.h" />\r
<ClInclude Include="utility\assert.h" />\r
<ClInclude Include="utility\string.h" />\r
<Filter Include="utility">\r
<UniqueIdentifier>{11860e2d-8adf-4573-956b-785e59aef2b0}</UniqueIdentifier>\r
</Filter>\r
+ <Filter Include="os">\r
+ <UniqueIdentifier>{49ed2765-f23e-4a1b-9d6a-f80d510b92e1}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="os\windows">\r
+ <UniqueIdentifier>{1f3002ae-ebb8-4195-8cf3-1a5b87822f38}</UniqueIdentifier>\r
+ </Filter>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="exception\win32_exception.cpp">\r
<ClInclude Include="utility\tweener.h">\r
<Filter>utility</Filter>\r
</ClInclude>\r
+ <ClInclude Include="memory\memcpy.h">\r
+ <Filter>memory</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="memory\memclr.h">\r
+ <Filter>memory</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="os\windows\current_version.h">\r
+ <Filter>os\windows</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="os\windows\system_info.h">\r
+ <Filter>os\windows</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
\r
#include "../version.h"\r
\r
+#include "exception\exceptions.h"\r
#include "utility/string.h"\r
\r
#include <boost/property_tree/ptree.hpp>\r
\r
#include <functional>\r
\r
-namespace caspar\r
-{\r
+namespace caspar { namespace env {\r
\r
std::wstring media;\r
std::wstring log;\r
std::wstring data;\r
boost::property_tree::ptree pt;\r
\r
-void env::initialize(const std::string& filename)\r
+void check_is_configured()\r
+{\r
+ if(pt.empty())\r
+ BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Enviroment properties has not been configured"));\r
+}\r
+\r
+void configure(const std::string& filename)\r
{\r
std::string initialPath = boost::filesystem::initial_path().file_string();\r
\r
data = widen(paths.get("data-path", initialPath + "\\data\\"));\r
}\r
\r
-const std::wstring& env::media_folder()\r
+const std::wstring& media_folder()\r
{\r
+ check_is_configured();\r
return media;\r
}\r
\r
-const std::wstring& env::log_folder()\r
+const std::wstring& log_folder()\r
{\r
+ check_is_configured();\r
return log;\r
}\r
\r
-const std::wstring& env::template_folder()\r
+const std::wstring& template_folder()\r
{\r
+ check_is_configured();\r
return ftemplate;\r
}\r
\r
-const std::wstring& env::template_host()\r
+const std::wstring& template_host()\r
{\r
+ check_is_configured();\r
return ftemplate_host;\r
}\r
\r
-\r
-const std::wstring& env::data_folder()\r
+const std::wstring& data_folder()\r
{\r
+ check_is_configured();\r
return data;\r
}\r
\r
-const std::wstring& env::version()\r
+const std::wstring& version()\r
{\r
static std::wstring ver = std::wstring(L"") + CASPAR_GEN + L"." + CASPAR_MAYOR + L"." + CASPAR_MINOR + L"." + CASPAR_REV;\r
return ver;\r
}\r
\r
-const boost::property_tree::ptree& env::properties()\r
+const boost::property_tree::ptree& properties()\r
{\r
+ check_is_configured();\r
return pt;\r
}\r
\r
-}
\ No newline at end of file
+}}
\ No newline at end of file
\r
#include <boost/property_tree/ptree.hpp>\r
\r
-namespace caspar{\r
+#include <string>\r
\r
-struct env\r
-{\r
- static void initialize(const std::string& filename);\r
- static const std::wstring& media_folder();\r
- static const std::wstring& log_folder();\r
- static const std::wstring& template_folder();\r
- static const std::wstring& template_host();\r
- static const std::wstring& data_folder();\r
- static const std::wstring& version();\r
+namespace caspar { namespace env {\r
\r
- static const boost::property_tree::ptree& properties();\r
-};\r
+void configure(const std::string& filename);\r
\r
-};
\ No newline at end of file
+const std::wstring& media_folder();\r
+const std::wstring& log_folder();\r
+const std::wstring& template_folder();\r
+const std::wstring& template_host();\r
+const std::wstring& data_folder();\r
+const std::wstring& version();\r
+\r
+const boost::property_tree::ptree& properties();\r
+\r
+} }
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <assert.h>\r
+\r
+namespace caspar {\r
+\r
+static void* fast_memclr(void* dest, size_t count)\r
+{\r
+ assert(count % (16*4) == 0);\r
+ assert(dest != nullptr);\r
+ assert(source != nullptr);\r
+\r
+ __asm \r
+ { \r
+ mov edi, dest; \r
+ mov ebx, count; \r
+ shr ebx, 7;\r
+ pxor xmm0, xmm0; \r
+\r
+ clr: \r
+ movntdq [edi+00h], xmm0;\r
+ movntdq [edi+10h], xmm0;\r
+ movntdq [edi+20h], xmm0; \r
+ movntdq [edi+30h], xmm0;\r
+ \r
+ movntdq [edi+40h], xmm0; \r
+ movntdq [edi+50h], xmm0; \r
+ movntdq [edi+60h], xmm0; \r
+ movntdq [edi+70h], xmm0; \r
+\r
+ lea edi, [edi+80h]; \r
+\r
+ dec ebx; \r
+ jnz clr; \r
+ } \r
+ return dest;\r
+}\r
+\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <assert.h>\r
+\r
+#include <tbb/parallel_for.h>\r
+\r
+namespace caspar {\r
+\r
+namespace internal {\r
+\r
+static void* fast_memcpy(void* dest, const void* source, size_t count)\r
+{\r
+ assert(count % (16*8) == 0);\r
+ assert(dest != nullptr);\r
+ assert(source != nullptr);\r
+\r
+ __asm \r
+ { \r
+ mov esi, source; \r
+ mov edi, dest; \r
+ mov ebx, count; \r
+ shr ebx, 7;\r
+\r
+ cpy: \r
+ movdqa xmm0, [esi+00h]; \r
+ movdqa xmm1, [esi+10h]; \r
+ movdqa xmm2, [esi+20h]; \r
+ movdqa xmm3, [esi+30h]; \r
+\r
+ movntdq [edi+00h], xmm0;\r
+ movntdq [edi+10h], xmm1;\r
+ movntdq [edi+20h], xmm2; \r
+ movntdq [edi+30h], xmm3;\r
+\r
+ movdqa xmm4, [esi+40h];\r
+ movdqa xmm5, [esi+50h];\r
+ movdqa xmm6, [esi+60h];\r
+ movdqa xmm7, [esi+70h]; \r
+\r
+ movntdq [edi+40h], xmm4; \r
+ movntdq [edi+50h], xmm5; \r
+ movntdq [edi+60h], xmm6; \r
+ movntdq [edi+70h], xmm7; \r
+\r
+ lea edi, [edi+80h]; \r
+ lea esi, [esi+80h]; \r
+\r
+ dec ebx; \r
+ jnz cpy; \r
+ } \r
+ return dest;\r
+}\r
+\r
+}\r
+\r
+static void* fast_memcpy(void* dest, const void* source, size_t num)\r
+{ \r
+ tbb::affinity_partitioner partitioner;\r
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, num/128), [&](const tbb::blocked_range<size_t>& r)\r
+ { \r
+ internal::fast_memcpy(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128); \r
+ }, partitioner); \r
+ return dest;\r
+}\r
+\r
+\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+\r
+#include <windows.h>\r
+\r
+#include <string>\r
+\r
+namespace caspar {\r
+\r
+static std::wstring get_win_product_name()\r
+{\r
+ std::wstring result = L"Unknown Windows Product Name.";\r
+ HKEY hkey; \r
+ DWORD dwType, dwSize;\r
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
+ {\r
+ wchar_t p_name_str[1024];\r
+\r
+ dwType = REG_SZ;\r
+ dwSize = sizeof(p_name_str);\r
+\r
+ if(RegQueryValueEx(hkey, TEXT("ProductName"), NULL, &dwType, (PBYTE)&p_name_str, &dwSize) == ERROR_SUCCESS) \r
+ result = p_name_str; \r
+ \r
+ RegCloseKey(hkey);\r
+ }\r
+ return result;\r
+}\r
+\r
+static std::wstring get_win_sp_version()\r
+{\r
+ std::wstring result = L"";\r
+ HKEY hkey; \r
+ DWORD dwType, dwSize;\r
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
+ {\r
+ wchar_t csd_ver_str[1024];\r
+\r
+ dwType = REG_SZ;\r
+ dwSize = sizeof(csd_ver_str);\r
+\r
+ if(RegQueryValueEx(hkey, TEXT("CSDVersion"), NULL, &dwType, (PBYTE)&csd_ver_str, &dwSize) == ERROR_SUCCESS) \r
+ result = csd_ver_str;\r
+ \r
+ RegCloseKey(hkey);\r
+ }\r
+ return result;\r
+}\r
+\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <windows.h>\r
+\r
+#include <string>\r
+#include <sstream>\r
+\r
+namespace caspar {\r
+ \r
+static std::wstring get_cpu_info()\r
+{\r
+ std::wstring cpu_name = L"Unknown CPU";\r
+ HKEY hkey; \r
+ DWORD dwType, dwSize;\r
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
+ {\r
+ wchar_t p_name_str[1024];\r
+\r
+ dwType = REG_SZ;\r
+ dwSize = sizeof(p_name_str);\r
+\r
+ if(RegQueryValueEx(hkey, TEXT("ProcessorNameString"), NULL, &dwType, (PBYTE)&p_name_str, &dwSize) == ERROR_SUCCESS) \r
+ cpu_name = p_name_str; \r
+ \r
+ RegCloseKey(hkey);\r
+ }\r
+\r
+\r
+ SYSTEM_INFO sysinfo;\r
+ GetSystemInfo(&sysinfo);\r
+\r
+ std::wstringstream s;\r
+\r
+ s << cpu_name << L" Physical Threads: " << sysinfo.dwNumberOfProcessors;\r
+\r
+ return s.str();\r
+}\r
+\r
+static std::wstring get_system_product_name()\r
+{\r
+ std::wstring system_product_name = L"Unknown System";\r
+ HKEY hkey; \r
+ DWORD dwType, dwSize;\r
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\BIOS"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
+ {\r
+ wchar_t p_name_str[1024];\r
+\r
+ dwType = REG_SZ;\r
+ dwSize = sizeof(p_name_str);\r
+\r
+ if(RegQueryValueEx(hkey, TEXT("SystemProductName"), NULL, &dwType, (PBYTE)&p_name_str, &dwSize) == ERROR_SUCCESS) \r
+ system_product_name = p_name_str; \r
+ \r
+ RegCloseKey(hkey);\r
+ }\r
+\r
+ return system_product_name;\r
+}\r
+\r
+\r
+}
\ No newline at end of file
\r
#include <common/env.h>\r
#include <common/concurrency/executor.h>\r
+#include <common/memory/memcpy.h>\r
+#include <common/memory/memclr.h>\r
#include <common/utility/timer.h>\r
#include <common/diagnostics/graph.h>\r
\r
\r
if(ax_->InvalidRect())\r
{ \r
- std::fill_n(bmp_data_, format_desc_.size, 0);\r
+ fast_memclr(bmp_data_, format_desc_.size);\r
ax_->DrawControl(static_cast<HDC>(hdc_.get()));\r
\r
auto frame = frame_factory_->create_frame(this);\r
- std::copy_n(bmp_data_, format_desc_.size, frame->image_data().begin());\r
+ fast_memcpy(frame->image_data().begin(), bmp_data_, format_desc_.size);\r
head_ = frame;\r
} \r
\r
<?xml version="1.0" encoding="utf-8"?>\r
<configuration>\r
<paths>\r
- <media-path>F:\\Casparcg\\_media\\</media-path>\r
- <log-path>F:\\Casparcg\\_log\\</log-path>\r
- <data-path>F:\\Casparcg\\_data\\</data-path>\r
- <template-path>F:\\Casparcg\\_templates\\</template-path>\r
+ <media-path>L:\\Casparcg\\_media\\</media-path>\r
+ <log-path>L:\\Casparcg\\_log\\</log-path>\r
+ <data-path>L:\\Casparcg\\_data\\</data-path>\r
+ <template-path>L:\\Casparcg\\_templates\\</template-path>\r
<template-host>cg.fth.18</template-host>\r
</paths>\r
<diagnostics>\r
<channel>\r
<videomode>1080i5000</videomode>\r
<consumers>\r
- <!-- <decklink>\r
+ <decklink>\r
<device>1</device>\r
<embedded-audio>false</embedded-audio>\r
<internal-key>false</internal-key>\r
- </decklink>-->\r
+ </decklink>\r
<ogl>\r
<device>0</device>\r
<stretch>uniform</stretch>\r
\r
#include "resource.h"\r
\r
-#include <windows.h>\r
-#include <conio.h>\r
-\r
-#include <tbb/tbbmalloc_proxy.h>\r
-#include <tbb/task_scheduler_observer.h>\r
+#include "server.h"\r
\r
#ifdef _DEBUG\r
#define _CRTDBG_MAP_ALLOC\r
#include <crtdbg.h>\r
#endif\r
\r
-#include "bootstrapper.h"\r
+#define NOMINMAX\r
+\r
+#include <windows.h>\r
+#include <conio.h>\r
+\r
+// tbbmalloc_proxy:
+// Replace the standard memory allocation routines in Microsoft* C/C++ RTL
+// (malloc/free, global new/delete, etc.) with the TBB memory allocator. \r
+#include <tbb/tbbmalloc_proxy.h>\r
\r
#include <modules/bluefish/bluefish.h>\r
\r
#include <common/exception/win32_exception.h>\r
#include <common/exception/exceptions.h>\r
#include <common/log/log.h>\r
+#include <common/os/windows/current_version.h>\r
+#include <common/os/windows/system_info.h>\r
#include <common/utility/assert.h>\r
\r
#include <mixer/gpu/ogl_device.h>\r
\r
#include <protocol/amcp/AMCPProtocolStrategy.h>\r
\r
+#include <tbb/task_scheduler_observer.h>\r
+#include <tbb/task_scheduler_init.h>\r
+\r
#include <boost/foreach.hpp>\r
\r
#include <Glee.h>\r
\r
-using namespace caspar;\r
-using namespace caspar::core;\r
-using namespace caspar::protocol;\r
-\r
#include <atlbase.h>\r
\r
// NOTE: This is needed in order to make CComObject work since this is not a real ATL project.\r
CComModule _AtlModule;\r
extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule;\r
\r
-class win32_handler_tbb_installer : public tbb::task_scheduler_observer\r
-{\r
-public:\r
- win32_handler_tbb_installer() {observe(true);}\r
- void on_scheduler_entry(bool is_worker) \r
- {\r
- //CASPAR_LOG(debug) << L"Started TBB Worker Thread.";\r
- win32_exception::install_handler();\r
- }\r
- void on_scheduler_exit()\r
- {\r
- //CASPAR_LOG(debug) << L"Stopped TBB Worker Thread.";\r
- }\r
-};\r
-\r
void setup_console_window()\r
{ \r
auto hOut = GetStdHandle(STD_OUTPUT_HANDLE);\r
\r
+ // Disable close button in console to avoid shutdown without cleanup.\r
EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED);\r
DrawMenuBar(GetConsoleWindow());\r
\r
+ // Configure console size and position.\r
auto coord = GetLargestConsoleWindowSize(hOut);\r
coord.X /= 2;\r
\r
DisplayArea.Bottom = coord.Y-1;\r
SetConsoleWindowInfo(hOut, TRUE, &DisplayArea);\r
\r
+ // Set console title.\r
std::wstringstream str;\r
- str << "CasparCG Server " << env::version();\r
+ str << "CasparCG Server " << caspar::env::version();\r
SetConsoleTitle(str.str().c_str());\r
}\r
\r
-void print_version()\r
+void print_info()\r
{\r
CASPAR_LOG(info) << L"Copyright (c) 2010 Sveriges Television AB, www.casparcg.com, <info@casparcg.com>";\r
- CASPAR_LOG(info) << L"Starting CasparCG Video and Graphics Playout Server " << env::version();\r
- CASPAR_LOG(info) << L"Flash " << get_flash_version();\r
- CASPAR_LOG(info) << L"Flash-Template-Host " << get_cg_version();\r
- CASPAR_LOG(info) << L"FreeImage " << get_image_version();\r
+ CASPAR_LOG(info) << L"Starting CasparCG Video and Graphics Playout Server " << caspar::env::version();\r
+ CASPAR_LOG(info) << L"on " << caspar::get_win_product_name() << L" " << caspar::get_win_sp_version();\r
+ CASPAR_LOG(info) << caspar::get_cpu_info();\r
+ CASPAR_LOG(info) << caspar::get_system_product_name();\r
+ CASPAR_LOG(info) << L"Flash " << caspar::get_flash_version();\r
+ CASPAR_LOG(info) << L"Flash-Template-Host " << caspar::get_cg_version();\r
+ CASPAR_LOG(info) << L"FreeImage " << caspar::get_image_version();\r
\r
std::wstring decklink_devices;\r
- BOOST_FOREACH(auto& device, get_decklink_device_list())\r
+ BOOST_FOREACH(auto& device, caspar::get_decklink_device_list())\r
decklink_devices += L"\t" + device;\r
- CASPAR_LOG(info) << L"Decklink " << get_decklink_version() << (decklink_devices.empty() ? L"" : L"\n\tDevices:\n" + decklink_devices);\r
+ CASPAR_LOG(info) << L"Decklink " << caspar::get_decklink_version() << (decklink_devices.empty() ? L"" : L"\n\tDevices:\n" + decklink_devices);\r
\r
std::wstring bluefish_devices;\r
- BOOST_FOREACH(auto& device, get_bluefish_device_list())\r
+ BOOST_FOREACH(auto& device, caspar::get_bluefish_device_list())\r
bluefish_devices += L"\t" + device;\r
- CASPAR_LOG(info) << L"Bluefish " << get_bluefish_version() << (bluefish_devices.empty() ? L"" : L"\n\tDevices:\n" + bluefish_devices);\r
-\r
- CASPAR_LOG(info) << L"FFMPEG-avcodec " << get_avcodec_version();\r
- CASPAR_LOG(info) << L"FFMPEG-swscale " << get_avformat_version();\r
- CASPAR_LOG(info) << L"FFMPEG-avformat " << get_swscale_version();\r
- CASPAR_LOG(info) << L"OpenGL " << mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VERSION));})\r
- << L" " << mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VENDOR));});\r
-\r
- HKEY hkey; \r
- DWORD dwType, dwSize;\r
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
- {\r
- wchar_t p_name_str[1024];\r
- wchar_t csd_ver_str[1024];\r
-\r
- dwType = REG_SZ;\r
- dwSize = sizeof(p_name_str);\r
-\r
- if(RegQueryValueEx(hkey, TEXT("ProductName"), NULL, &dwType, (PBYTE)&p_name_str, &dwSize) == ERROR_SUCCESS &&\r
- RegQueryValueEx(hkey, TEXT("CSDVersion"), NULL, &dwType, (PBYTE)&csd_ver_str, &dwSize) == ERROR_SUCCESS) \r
- {\r
- CASPAR_LOG(info) << p_name_str << L" " << csd_ver_str << L"." << L"\n";\r
- }\r
- else\r
- CASPAR_LOG(warning) << "Could not read OS info." << L"\n";\r
- \r
- RegCloseKey(hkey);\r
- }\r
+ CASPAR_LOG(info) << L"Bluefish " << caspar::get_bluefish_version() << (bluefish_devices.empty() ? L"" : L"\n\tDevices:\n" + bluefish_devices);\r
+\r
+ CASPAR_LOG(info) << L"FFMPEG-avcodec " << caspar::get_avcodec_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-swscale " << caspar::get_avformat_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-avformat " << caspar::get_swscale_version();\r
+ CASPAR_LOG(info) << L"OpenGL " << caspar::mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VERSION));})\r
+ << L" " << caspar::mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VENDOR));});\r
+ CASPAR_LOG(info) << L"\n\n";\r
}\r
\r
int main(int argc, wchar_t* argv[])\r
-{ \r
+{ \r
+ // Install unstructured exception handler.\r
+ caspar::win32_exception::install_handler();\r
+\r
+ // Create atleast two threads to avoid async issues with legacy code running on unicore systems.\r
+ tbb::task_scheduler_init init(std::max(tbb::task_scheduler_init::default_num_threads(), 2));\r
+\r
+ // Set debug mode.\r
#ifdef _DEBUG\r
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );\r
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );\r
_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG );\r
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );\r
-\r
- if(env::properties().get("configuration.debugging.remote", false))\r
- MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);\r
#endif\r
\r
- // Increase time precision\r
- timeBeginPeriod(1);\r
- win32_handler_tbb_installer win32_handler_tbb_installer;\r
- win32_exception::install_handler();\r
+ // Increase time precision. This will increase accuracy of function like Sleep(1) from 10 ms to 1 ms.\r
+ struct inc_prec\r
+ {\r
+ inc_prec(){timeBeginPeriod(1);}\r
+ ~inc_prec(){timeEndPeriod(1);}\r
+ } inc_prec; \r
\r
+ // Install unstructured exception handlers into all tbb threads.\r
+ struct tbb_thread_installer : public tbb::task_scheduler_observer\r
+ {\r
+ tbb_thread_installer(){observe(true);}\r
+ void on_scheduler_entry(bool is_worker)\r
+ {\r
+ caspar::win32_exception::install_handler(); \r
+ }\r
+ } tbb_thread_installer;\r
+ \r
try \r
{\r
- env::initialize("caspar.config");\r
+ // Configure environment properties from configuration.\r
+ caspar::env::configure("caspar.config");\r
+\r
+ #ifdef _DEBUG\r
+ if(env::properties().get("configuration.debugging.remote", false))\r
+ MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);\r
+ #endif \r
+\r
+ // Start logging to file.\r
+ caspar::log::add_file_sink(caspar::env::log_folder());\r
\r
- setup_console_window(); \r
- log::add_file_sink(env::log_folder());\r
+ // Setup console window.\r
+ setup_console_window();\r
\r
- print_version();\r
+ // Print environment information.\r
+ print_info();\r
\r
- bootstrapper caspar_device;\r
+ // Create server object which initializes channels, protocols and controllers.\r
+ caspar::server caspar_server;\r
\r
- auto dummy = std::make_shared<IO::ConsoleClientInfo>();\r
- amcp::AMCPProtocolStrategy amcp(caspar_device.get_channels());\r
+ // Create a amcp parser for console commands.\r
+ caspar::protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.get_channels());\r
+\r
+ // Create a dummy client which prints amcp responses to console.\r
+ auto dummy = std::make_shared<caspar::IO::ConsoleClientInfo>();\r
+\r
bool is_running = true;\r
while(is_running)\r
{\r
std::wstring wcmd;\r
std::getline(std::wcin, wcmd); // TODO: It's blocking...\r
+\r
is_running = wcmd != L"exit" && wcmd != L"q";\r
if(wcmd.substr(0, 2) == L"12")\r
{\r
{\r
CASPAR_LOG(fatal) << "UNHANDLED EXCEPTION in main thread.";\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
- std::wcout << L"Press Any Key To Exit\n";\r
+ std::wcout << L"Press Any Key To Exit.\n";\r
_getwch();\r
} \r
-\r
- timeEndPeriod(1);\r
-\r
- CASPAR_LOG(info) << "Successfully shutdown CasparCG Server";\r
+ \r
+ CASPAR_LOG(info) << "Successfully shutdown CasparCG Server.";\r
\r
return 0;\r
}
\ No newline at end of file
-#include "bootstrapper.h"\r
+#include "server.h"\r
\r
#include <common/env.h>\r
#include <common/exception/exceptions.h>\r
using namespace core;\r
using namespace protocol;\r
\r
-struct bootstrapper::implementation : boost::noncopyable\r
+struct server::implementation : boost::noncopyable\r
{\r
std::vector<safe_ptr<IO::AsyncEventServer>> async_servers_; \r
std::vector<safe_ptr<channel>> channels_;\r
}\r
};\r
\r
-bootstrapper::bootstrapper() : impl_(new implementation()){}\r
+server::server() : impl_(new implementation()){}\r
\r
-const std::vector<safe_ptr<channel>> bootstrapper::get_channels() const\r
+const std::vector<safe_ptr<channel>> server::get_channels() const\r
{\r
return impl_->channels_;\r
}\r
#include <vector>\r
\r
namespace caspar {\r
+\r
+std::vector<safe_ptr<core::channel>> initialize_channels();\r
\r
struct invalid_bootstrapper : virtual boost::exception, virtual std::exception {};\r
\r
-class bootstrapper : boost::noncopyable\r
+class server : boost::noncopyable\r
{\r
public:\r
- bootstrapper();\r
+ server();\r
\r
const std::vector<safe_ptr<core::channel>> get_channels() const;\r
\r
</ProjectConfiguration>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClCompile Include="boostrapper.cpp" />\r
+ <ClCompile Include="server.cpp" />\r
<ClCompile Include="main.cpp">\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">NotUsing</PrecompiledHeader>\r
<None Include="CasparCG.ico" />\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="bootstrapper.h" />\r
+ <ClInclude Include="server.h" />\r
<ClInclude Include="resource.h" />\r
</ItemGroup>\r
<ItemGroup>\r
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
<ItemGroup>\r
<ClCompile Include="main.cpp" />\r
- <ClCompile Include="boostrapper.cpp" />\r
+ <ClCompile Include="server.cpp" />\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="caspar.config" />\r
<None Include="CasparCG.ico" />\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="bootstrapper.h" />\r
<ClInclude Include="resource.h" />\r
+ <ClInclude Include="server.h" />\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="shell.rc" />\r