2 * copyright (c) 2010 Sveriges Television AB <info@casparcg.com>
\r
4 * This file is part of CasparCG.
\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
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
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
21 #include "../stdafx.h"
\r
23 #if defined(_MSC_VER)
\r
24 #pragma warning (disable : 4714) // marked as __forceinline not inlined
\r
25 #pragma warning (disable : 4146)
\r
28 #include "silverlight_producer.h"
\r
30 #include "../interop/XcpControlHost.h"
\r
32 #include <core/video_format.h>
\r
34 #include <core/producer/frame/write_frame.h>
\r
35 #include <core/producer/frame/frame_factory.h>
\r
37 #include <common/concurrency/executor.h>
\r
38 #include <common/env.h>
\r
40 #include <boost/filesystem.hpp>
\r
42 #include <SFML/Graphics.hpp>
\r
46 class silverlight_renderer
\r
50 co_init(){CoInitialize(nullptr);}
\r
51 ~co_init(){CoUninitialize();}
\r
56 const std::shared_ptr<core::frame_factory> frame_factory_;
\r
57 const core::video_format_desc format_desc_;
\r
59 CComObject<XcpControlHost>* host_;
\r
60 tbb::spin_mutex mutex_;
\r
61 safe_ptr<core::basic_frame> last_frame_;
\r
63 sf::RenderWindow window_;
\r
68 unsigned char* bmp_data_;
\r
71 silverlight_renderer(const std::shared_ptr<core::frame_factory>& frame_factory)
\r
72 : frame_factory_(frame_factory)
\r
73 , format_desc_(frame_factory->get_video_format_desc())
\r
74 , last_frame_(core::basic_frame::empty())
\r
77 , window_(sf::VideoMode(format_desc_.width, format_desc_.height, 32), boost::lexical_cast<std::string>(id_), sf::Style::None)
\r
79 if(FAILED(CComObject<XcpControlHost>::CreateInstance(&host_)))
\r
80 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to create XcpControlHost"));
\r
82 HWND hWnd = ::FindWindow(L"SFML_Window", boost::lexical_cast<std::wstring>(id_).c_str());
\r
83 if(FAILED(host_->CreateXcpControl(hWnd)))
\r
84 BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to Create XcpControl"));
\r
86 screen_= ::GetDC(hWnd);
\r
87 mem_ = ::CreateCompatibleDC(screen_);
\r
90 memset(&info, 0, sizeof(BITMAPINFO));
\r
91 info.bmiHeader.biBitCount = 32;
\r
92 info.bmiHeader.biCompression = BI_RGB;
\r
93 info.bmiHeader.biHeight = -static_cast<int>(format_desc_.height);
\r
94 info.bmiHeader.biPlanes = 1;
\r
95 info.bmiHeader.biSize = sizeof(BITMAPINFO);
\r
96 info.bmiHeader.biWidth = format_desc_.width;
\r
98 bmp_ = ::CreateDIBSection(screen_, &info, DIB_RGB_COLORS, reinterpret_cast<void**>(&bmp_data_), 0, 0);
\r
99 SelectObject(mem_, bmp_);
\r
102 ~silverlight_renderer()
\r
104 DeleteObject(bmp_);
\r
110 host_->DestroyXcpControl();
\r
118 while (window_.GetEvent(Event)){}
\r
121 auto frame = frame_factory_->create_frame();
\r
122 ::BitBlt(mem_, 0, 0, format_desc_.width, format_desc_.height, screen_, 0, 0, SRCCOPY);
\r
123 std::copy_n(bmp_data_, format_desc_.size, frame->image_data().begin());
\r
125 tbb::spin_mutex::scoped_lock lock(mutex_);
\r
126 last_frame_ = frame;
\r
129 safe_ptr<core::basic_frame> get_frame()
\r
131 tbb::spin_mutex::scoped_lock lock(mutex_);
\r
132 return last_frame_;
\r
136 struct silverlight_producer : public core::frame_producer
\r
138 std::wstring print() const{ return L"silverlight[]"; }
\r
140 std::unique_ptr<silverlight_renderer> renderer_;
\r
142 executor executor_;
\r
146 silverlight_producer() : executor_(print())
\r
149 virtual void initialize(const safe_ptr<core::frame_factory>& frame_factory)
\r
152 executor_.invoke([=]
\r
154 renderer_.reset(new silverlight_renderer(frame_factory));
\r
158 void set_parent_printer(const printer& parent_printer)
\r
163 virtual safe_ptr<core::basic_frame> receive()
\r
165 executor_.begin_invoke([=]
\r
167 renderer_->render();
\r
170 return renderer_->get_frame();
\r
174 safe_ptr<core::frame_producer> create_silverlight_producer(const std::vector<std::wstring>& params)
\r
176 //std::wstring filename = env::template_folder() + L"\\" + params[0] + L".xap";
\r
177 //if(!boost::filesystem::exists(filename))
\r
178 // return frame_producer::empty();
\r
179 if(params[0] != L"SILVER")
\r
180 return core::frame_producer::empty();
\r
182 return make_safe<silverlight_producer>();
\r