]> git.sesse.net Git - casparcg/blob - shell/main.cpp
2.0.0.2: Added application icon.
[casparcg] / shell / main.cpp
1 /*\r
2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 *  This file is part of CasparCG.\r
5 *\r
6 *    CasparCG is free software: you can redistribute it and/or modify\r
7 *    it under the terms of the GNU General Public License as published by\r
8 *    the Free Software Foundation, either version 3 of the License, or\r
9 *    (at your option) any later version.\r
10 *\r
11 *    CasparCG is distributed in the hope that it will be useful,\r
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 *    GNU General Public License for more details.\r
15 \r
16 *    You should have received a copy of the GNU General Public License\r
17 *    along with CasparCG.  If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 */\r
20 \r
21 #include "resource.h"\r
22 \r
23 #include <windows.h>\r
24 #include <conio.h>\r
25 \r
26 #include <tbb/tbbmalloc_proxy.h>\r
27 #include <tbb/task_scheduler_observer.h>\r
28 \r
29 #ifdef _DEBUG\r
30         #define _CRTDBG_MAP_ALLOC\r
31         #include <stdlib.h>\r
32         #include <crtdbg.h>\r
33 #endif\r
34 \r
35 #include "bootstrapper.h"\r
36 \r
37 #include <modules/bluefish/bluefish.h>\r
38 \r
39 #include <modules/decklink/decklink.h>\r
40 #include <modules/flash/flash.h>\r
41 #include <modules/ffmpeg/ffmpeg.h>\r
42 #include <modules/image/image.h>\r
43 \r
44 #include <common/env.h>\r
45 #include <common/exception/win32_exception.h>\r
46 #include <common/exception/exceptions.h>\r
47 #include <common/log/log.h>\r
48 #include <common/utility/assert.h>\r
49 \r
50 #include <mixer/gpu/ogl_device.h>\r
51 \r
52 #include <protocol/amcp/AMCPProtocolStrategy.h>\r
53 \r
54 #include <boost/foreach.hpp>\r
55 \r
56 #include <Glee.h>\r
57 \r
58 using namespace caspar;\r
59 using namespace caspar::core;\r
60 using namespace caspar::protocol;\r
61 \r
62 #include <atlbase.h>\r
63 \r
64 // NOTE: This is needed in order to make CComObject work since this is not a real ATL project.\r
65 CComModule _AtlModule;\r
66 extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule;\r
67 \r
68 class win32_handler_tbb_installer : public tbb::task_scheduler_observer\r
69 {\r
70 public:\r
71         win32_handler_tbb_installer()   {observe(true);}\r
72         void on_scheduler_entry(bool is_worker) \r
73         {\r
74                 //CASPAR_LOG(debug) << L"Started TBB Worker Thread.";\r
75                 win32_exception::install_handler();\r
76         }\r
77         void on_scheduler_exit()\r
78         {\r
79                 //CASPAR_LOG(debug) << L"Stopped TBB Worker Thread.";\r
80         }\r
81 };\r
82 \r
83 void setup_console_window()\r
84 {        \r
85         auto hOut = GetStdHandle(STD_OUTPUT_HANDLE);\r
86 \r
87         EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED);\r
88         DrawMenuBar(GetConsoleWindow());\r
89 \r
90         auto coord = GetLargestConsoleWindowSize(hOut);\r
91         coord.X /= 2;\r
92 \r
93         SetConsoleScreenBufferSize(hOut, coord);\r
94 \r
95         SMALL_RECT DisplayArea = {0, 0, 0, 0};\r
96         DisplayArea.Right = coord.X-1;\r
97         DisplayArea.Bottom = coord.Y-1;\r
98         SetConsoleWindowInfo(hOut, TRUE, &DisplayArea);\r
99                 \r
100         std::wstringstream str;\r
101         str << "CasparCG Server " << env::version();\r
102         SetConsoleTitle(str.str().c_str());\r
103 }\r
104 \r
105 void print_version()\r
106 {\r
107         CASPAR_LOG(info) << L"Copyright (c) 2010 Sveriges Television AB, www.casparcg.com, <info@casparcg.com>";\r
108         CASPAR_LOG(info) << L"Starting CasparCG Video and Graphics Playout Server " << env::version();\r
109         CASPAR_LOG(info) << L"Flash " << get_flash_version();\r
110         CASPAR_LOG(info) << L"Flash-Template-Host " << get_cg_version();\r
111         CASPAR_LOG(info) << L"FreeImage " << get_image_version();\r
112         \r
113         std::wstring decklink_devices;\r
114         BOOST_FOREACH(auto& device, get_decklink_device_list())\r
115                 decklink_devices += L"\t" + device;\r
116         CASPAR_LOG(info) << L"Decklink " << get_decklink_version() << (decklink_devices.empty() ? L"" : L"\n\tDevices:\n" + decklink_devices);\r
117         \r
118         std::wstring bluefish_devices;\r
119         BOOST_FOREACH(auto& device, get_bluefish_device_list())\r
120                 bluefish_devices += L"\t" + device;\r
121         CASPAR_LOG(info) << L"Bluefish " << get_bluefish_version() << (bluefish_devices.empty() ? L"" : L"\n\tDevices:\n" + bluefish_devices);\r
122 \r
123         CASPAR_LOG(info) << L"FFMPEG-avcodec "  << get_avcodec_version();\r
124         CASPAR_LOG(info) << L"FFMPEG-swscale "  << get_avformat_version();\r
125         CASPAR_LOG(info) << L"FFMPEG-avformat " << get_swscale_version();\r
126         CASPAR_LOG(info) << L"OpenGL " << mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VERSION));})\r
127                                          << L" "           << mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VENDOR));});\r
128 \r
129         HKEY hkey; \r
130         DWORD dwType, dwSize;\r
131         if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)\r
132         {\r
133                 wchar_t p_name_str[1024];\r
134                 wchar_t csd_ver_str[1024];\r
135 \r
136                 dwType = REG_SZ;\r
137                 dwSize = sizeof(p_name_str);\r
138 \r
139                 if(RegQueryValueEx(hkey, TEXT("ProductName"), NULL, &dwType, (PBYTE)&p_name_str, &dwSize) == ERROR_SUCCESS &&\r
140                    RegQueryValueEx(hkey, TEXT("CSDVersion"), NULL, &dwType, (PBYTE)&csd_ver_str, &dwSize) == ERROR_SUCCESS)             \r
141                 {\r
142                         CASPAR_LOG(info) << p_name_str << L" " << csd_ver_str << L"." << L"\n";\r
143                 }\r
144                 else\r
145                         CASPAR_LOG(warning) << "Could not read OS info." << L"\n";\r
146                  \r
147                 RegCloseKey(hkey);\r
148         }\r
149 }\r
150  \r
151 int main(int argc, wchar_t* argv[])\r
152 {               \r
153         #ifdef _DEBUG\r
154                 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF );\r
155                 _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );\r
156                 _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG );\r
157                 _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );\r
158 \r
159                 if(env::properties().get("configuration.debugging.remote", false))\r
160                         MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);\r
161         #endif\r
162                 \r
163         // Increase time precision\r
164         timeBeginPeriod(1);\r
165         win32_handler_tbb_installer win32_handler_tbb_installer;\r
166         win32_exception::install_handler();\r
167 \r
168         try \r
169         {\r
170                 env::initialize("caspar.config");\r
171                 \r
172                 setup_console_window();                                                  \r
173                 log::add_file_sink(env::log_folder());\r
174 \r
175                 print_version();\r
176                                 \r
177                 bootstrapper caspar_device;\r
178                                 \r
179                 auto dummy = std::make_shared<IO::ConsoleClientInfo>();\r
180                 amcp::AMCPProtocolStrategy amcp(caspar_device.get_channels());\r
181                 bool is_running = true;\r
182                 while(is_running)\r
183                 {\r
184                         std::wstring wcmd;\r
185                         std::getline(std::wcin, wcmd); // TODO: It's blocking...\r
186                         is_running = wcmd != L"exit" && wcmd != L"q";\r
187                         if(wcmd.substr(0, 2) == L"12")\r
188                         {\r
189                                 wcmd = L"LOADBG 1-1 A LOOP \r\nPLAY 1-1\r\n";\r
190                                 amcp.Parse(wcmd.c_str(), wcmd.length(), dummy);\r
191                                 wcmd = L"LOADBG 1-2 DV LOOP AUTOPLAY\r\nnPLAY 1-1\r\n";\r
192                                 amcp.Parse(wcmd.c_str(), wcmd.length(), dummy);\r
193                                 wcmd = L"MIXER 1-1 VIDEO FIX_RECT 0.0 0.0 0.5 0.5\r\n";\r
194                                 amcp.Parse(wcmd.c_str(), wcmd.length(), dummy);\r
195                                 wcmd = L"MIXER 1-2 VIDEO FIX_RECT 0.5 0.0 0.5 0.5\r\n";\r
196                                 amcp.Parse(wcmd.c_str(), wcmd.length(), dummy);\r
197                         }\r
198                         else if(wcmd.substr(0, 2) == L"10")\r
199                                 wcmd = L"MIXER 1-1 VIDEO CLIP_RECT 0.4 0.4 0.5 0.5";\r
200                         if(wcmd.substr(0, 2) == L"11")\r
201                                 wcmd = L"MIXER 1-1 VIDEO FIX_RECT 0.4 0.4 0.5 0.5";\r
202                         else if(wcmd.substr(0, 1) == L"1")\r
203                                 wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" SLIDE 100 LOOP \r\nPLAY 1-1";\r
204                         else if(wcmd.substr(0, 1) == L"2")\r
205                                 wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" PUSH 100 LOOP \r\nPLAY 1-1";\r
206                         else if(wcmd.substr(0, 1) == L"3")\r
207                                 wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" MIX 100 LOOP \r\nPLAY 1-1";\r
208                         else if(wcmd.substr(0, 1) == L"4")\r
209                                 wcmd = L"LOADBG 1-1 " + wcmd.substr(1, wcmd.length()-1) + L" WIPE 100 LOOP \r\nPLAY 1-1";\r
210                         else if(wcmd.substr(0, 1) == L"5")\r
211                                 wcmd = L"LOADBG 1-2 " + wcmd.substr(1, wcmd.length()-1) + L" LOOP \r\nPLAY 1-2";\r
212                         else if(wcmd.substr(0, 1) == L"6")\r
213                                 wcmd = L"CG 1-2 ADD 1 BBTELEFONARE 1";\r
214                         else if(wcmd.substr(0, 1) == L"7")\r
215                                 wcmd = L"LOAD 1-1 720p2500";\r
216                         else if(wcmd.substr(0, 1) == L"8")\r
217                                 wcmd = L"LOAD 1-1 #FFFFFFFF AUTOPLAY";\r
218                         else if(wcmd.substr(0, 1) == L"9")\r
219                                 wcmd = L"LOADBG 1-2 " + wcmd.substr(1, wcmd.length()-1) + L" [1.0-2.0] LOOP AUTOPLAY";\r
220 \r
221                         wcmd += L"\r\n";\r
222                         amcp.Parse(wcmd.c_str(), wcmd.length(), dummy);\r
223                 }\r
224         }\r
225         catch(const std::exception&)\r
226         {\r
227                 CASPAR_LOG(fatal) << "UNHANDLED EXCEPTION in main thread.";\r
228                 CASPAR_LOG_CURRENT_EXCEPTION();\r
229                 std::wcout << L"Press Any Key To Exit\n";\r
230                 _getwch();\r
231         }       \r
232 \r
233         timeEndPeriod(1);\r
234 \r
235         CASPAR_LOG(info) << "Successfully shutdown CasparCG Server";\r
236         \r
237         return 0;\r
238 }