]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: - Cleanup and improvements in main.cpp.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Apr 2011 08:49:52 +0000 (08:49 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 28 Apr 2011 08:49:52 +0000 (08:49 +0000)
         - Added sse optimized memcpy and memclr in flash_producer.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@648 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

15 files changed:
common/common.vcxproj
common/common.vcxproj.filters
common/env.cpp
common/env.h
common/memory/memclr.h [new file with mode: 0644]
common/memory/memcpy.h [new file with mode: 0644]
common/os/windows/current_version.h [new file with mode: 0644]
common/os/windows/system_info.h [new file with mode: 0644]
modules/flash/producer/flash_producer.cpp
shell/caspar.config
shell/main.cpp
shell/server.cpp [moved from shell/boostrapper.cpp with 92% similarity]
shell/server.h [moved from shell/bootstrapper.h with 74% similarity]
shell/shell.vcxproj
shell/shell.vcxproj.filters

index da1b1d6129d2e3d17aa6efeb54aec4c69646be7b..4432c2f0d6e60069b1d111384c84816688c90a74 100644 (file)
     <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
index a34c1be6ec936c4483c201938e8a967f39b4bbb2..65a703a9a9ccb99efbd0bbc1514a42e52bc63c99 100644 (file)
     <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
index ecefb0b7182b7d23c55c65f917f5e8aec1280e09..d424f824f58415ce38ce13a91e22998b36e2450e 100644 (file)
@@ -4,6 +4,7 @@
 \r
 #include "../version.h"\r
 \r
+#include "exception\exceptions.h"\r
 #include "utility/string.h"\r
 \r
 #include <boost/property_tree/ptree.hpp>\r
@@ -13,8 +14,7 @@
 \r
 #include <functional>\r
 \r
-namespace caspar\r
-{\r
+namespace caspar { namespace env {\r
 \r
 std::wstring media;\r
 std::wstring log;\r
@@ -23,7 +23,13 @@ std::wstring ftemplate_host;
 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
@@ -37,41 +43,46 @@ void env::initialize(const std::string& filename)
        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
index 25a4e503386df91f18e4583eea5d42da91654be9..da44e04b9b2d4067f8633abee64b2cea79b6d946 100644 (file)
@@ -2,19 +2,19 @@
 \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
diff --git a/common/memory/memclr.h b/common/memory/memclr.h
new file mode 100644 (file)
index 0000000..1687ca2
--- /dev/null
@@ -0,0 +1,39 @@
+#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
diff --git a/common/memory/memcpy.h b/common/memory/memcpy.h
new file mode 100644 (file)
index 0000000..7168878
--- /dev/null
@@ -0,0 +1,67 @@
+#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
diff --git a/common/os/windows/current_version.h b/common/os/windows/current_version.h
new file mode 100644 (file)
index 0000000..7753e3d
--- /dev/null
@@ -0,0 +1,50 @@
+#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
diff --git a/common/os/windows/system_info.h b/common/os/windows/system_info.h
new file mode 100644 (file)
index 0000000..938fb99
--- /dev/null
@@ -0,0 +1,61 @@
+#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
index 308e54de81f76d4547e99f766821a8cc0b05f1c5..8e3cb3e40f0a6f965bc915ea1128f2cd0d10b551 100644 (file)
@@ -35,6 +35,8 @@
 \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
@@ -185,11 +187,11 @@ private:
 \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
index 8bbde2e6e206550acaedaf4002547389cb4d92fb..ff3414eefb608958d711b1b53e6f4fd073da8621 100644 (file)
@@ -1,10 +1,10 @@
 <?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
index 4c8764d1cdd8cab566400d417de7e73d73dd18b8..d234c3e7e23e25e4c582224985ded87ec8f3402c 100644 (file)
 \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
@@ -97,92 +89,108 @@ void setup_console_window()
        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
@@ -226,13 +234,11 @@ int main(int argc, wchar_t* argv[])
        {\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
similarity index 92%
rename from shell/boostrapper.cpp
rename to shell/server.cpp
index fc28f14630580fe2751b9edaeaf5a8a0dfd42bbf..68b77ab235265064c6969f272fa85b5e474f00c2 100644 (file)
@@ -1,4 +1,4 @@
-#include "bootstrapper.h"\r
+#include "server.h"\r
 \r
 #include <common/env.h>\r
 #include <common/exception/exceptions.h>\r
@@ -38,7 +38,7 @@ namespace caspar {
 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
@@ -155,9 +155,9 @@ struct bootstrapper::implementation : boost::noncopyable
        }\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
similarity index 74%
rename from shell/bootstrapper.h
rename to shell/server.h
index 9946d842c85699df47b7e16059d4c0ab5dcf7919..43edc98dd18754ac5273b36bfbbdd8e0477989cf 100644 (file)
@@ -9,13 +9,15 @@
 #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
index b7b95fc8b46bd3f8171ef51fb22985c18ceee8cb..e19dc19704ed76051ccb9dc9c25a2d44971f6e56 100644 (file)
@@ -19,7 +19,7 @@
     </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
@@ -72,7 +72,7 @@
     <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
index ac101144b6011ba3491630c25761d4cc693ab110..3e3f7f652b7f0dbd30c6238aa5d4e9329d6fddf6 100644 (file)
@@ -2,15 +2,15 @@
 <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