tbb::concurrent_bounded_queue<std::function<void()>> execution_queue_;\r
public:\r
\r
- explicit executor(const std::wstring& name, bool auto_start = false) : name_(narrow(name)) // noexcept\r
+ explicit executor(const std::wstring& name) : name_(narrow(name)) // noexcept\r
{\r
is_running_ = false;\r
- if(auto_start)\r
- start();\r
}\r
\r
virtual ~executor() // noexcept\r
{\r
execution_queue_.set_capacity(capacity);\r
}\r
-\r
- void start() // noexcept\r
- {\r
- if(is_running_.fetch_and_store(true))\r
- return;\r
- clear();\r
- thread_ = boost::thread([this]{run();});\r
- }\r
\r
void stop() // noexcept\r
{\r
template<typename Func>\r
auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
{ \r
+ if(!is_running_)\r
+ start();\r
+\r
typedef boost::packaged_task<decltype(func())> task_type;\r
\r
auto task = task_type(std::forward<Func>(func));\r
template<typename Func>\r
auto invoke(Func&& func) -> decltype(func())\r
{\r
- if(!is_running_)\r
- start();\r
-\r
if(boost::this_thread::get_id() == thread_.get_id()) // Avoids potential deadlock.\r
return func();\r
\r
bool is_running() const { return is_running_; } \r
\r
private:\r
+\r
+ void start() // noexcept\r
+ {\r
+ if(is_running_.fetch_and_store(true))\r
+ return;\r
+ clear();\r
+ thread_ = boost::thread([this]{run();});\r
+ }\r
\r
void execute() // noexcept\r
{\r
private:\r
context() : executor_(L"diagnostics")\r
{\r
- executor_.start();\r
executor_.begin_invoke([this]\r
{\r
window_.Create(sf::VideoMode(600, 1000), "CasparCG Diagnostics");\r
, executor_(L"frame_consumer_device")\r
{ \r
executor_.set_capacity(2);\r
- executor_.start();\r
}\r
\r
void add(int index, safe_ptr<frame_consumer>&& consumer)\r
diag_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f));\r
diag_->set_color("input-buffer", diagnostics::color(1.0f, 1.0f, 0.0f)); \r
executor_.set_capacity(2); \r
- executor_.start();\r
CASPAR_LOG(info) << print() << L" Successfully initialized."; \r
}\r
\r
\r
ogl_device::ogl_device() : executor_(L"ogl_device")\r
{\r
- executor_.start();\r
invoke([=]\r
{\r
context_.reset(new sf::Context());\r
public:\r
implementation(const video_format_desc& format_desc) \r
: format_desc_(format_desc)\r
- , executor_(L"frame_producer_device")\r
- {\r
- executor_.start();\r
- }\r
+ , executor_(L"frame_producer_device"){}\r
\r
boost::signals2::connection connect(const output_t::slot_type& subscriber)\r
{\r
for(size_t n = 0; n < reserved_frames_.size(); ++n)\r
reserved_frames_[n] = std::make_shared<blue_dma_buffer>(format_desc_.size, n); \r
\r
- executor_.start();\r
active_ = executor_.begin_invoke([]{});\r
\r
CASPAR_LOG(info) << print() << TEXT(" Successfully initialized for ") << format_desc_ << TEXT(".");\r
\r
struct decklink_consumer::implementation\r
{\r
- std::unique_ptr<decklink_output> input_;\r
+ std::unique_ptr<decklink_output> output_;\r
size_t device_index_;\r
bool embed_audio_;\r
bool internal_key_;\r
: device_index_(device_index)\r
, embed_audio_(embed_audio)\r
, internal_key_(internal_key)\r
- , executor_(L"DECKLINK[" + boost::lexical_cast<std::wstring>(device_index) + L"]")\r
- {\r
- executor_.start();\r
- }\r
+ , executor_(L"DECKLINK[" + boost::lexical_cast<std::wstring>(device_index) + L"]"){}\r
\r
~implementation()\r
{\r
executor_.invoke([&]\r
{\r
- input_ = nullptr;\r
+ output_ = nullptr;\r
});\r
}\r
\r
{\r
executor_.invoke([&]\r
{\r
- input_.reset(new decklink_output(format_desc, device_index_, embed_audio_, internal_key_));\r
+ output_.reset(new decklink_output(format_desc, device_index_, embed_audio_, internal_key_));\r
});\r
}\r
\r
void send(const safe_ptr<const core::read_frame>& frame)\r
{\r
- input_->send(frame);\r
+ output_->send(frame);\r
}\r
\r
size_t buffer_depth() const\r
\r
std::wstring print() const\r
{\r
- return input_->print();\r
+ return output_->print();\r
}\r
};\r
\r
#include <tbb/atomic.h>\r
\r
#include <boost/algorithm/string.hpp>\r
+#include <boost/timer.hpp>\r
\r
#pragma warning(push)\r
#pragma warning(disable : 4996)\r
const size_t device_index_;\r
\r
std::shared_ptr<diagnostics::graph> graph_;\r
- timer perf_timer_;\r
+ boost::timer perf_timer_;\r
\r
CComPtr<IDeckLink> decklink_;\r
CComQIPtr<IDeckLinkInput> input_;\r
virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame* video, IDeckLinkAudioInputPacket* audio)\r
{ \r
graph_->update_value("tick-time", static_cast<float>(perf_timer_.elapsed()/format_desc_.interval*0.5));\r
- perf_timer_.reset();\r
+ perf_timer_.restart();\r
\r
if(!video)\r
return S_OK; \r
explicit decklink_producer(const safe_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index)\r
: format_desc_(format_desc) \r
, device_index_(device_index)\r
- , executor_(L"decklink_producer", true)\r
+ , executor_(L"decklink_producer")\r
{\r
executor_.invoke([=]\r
{\r
void initialize(const core::video_format_desc& format_desc)\r
{\r
format_desc_ = format_desc;\r
- executor_.start();\r
active_ = executor_.begin_invoke([]{});\r
\r
fmt_ = av_guess_format(nullptr, filename_.c_str(), nullptr);\r
#include <common/utility/timer.h>\r
#include <common/utility/assert.h>\r
\r
+#include <boost/timer.hpp>\r
+\r
#include <tbb/parallel_invoke.h>\r
\r
#include <deque>\r
const bool loop_;\r
\r
std::shared_ptr<diagnostics::graph> graph_;\r
- timer perf_timer_;\r
+ boost::timer perf_timer_;\r
\r
std::unique_ptr<audio_decoder> audio_decoder_;\r
std::unique_ptr<video_decoder> video_decoder_;\r
\r
virtual safe_ptr<core::basic_frame> receive()\r
{\r
- perf_timer_.reset();\r
+ perf_timer_.restart();\r
\r
while(ouput_channel_.size() < 2 && !input_->is_eof())\r
{ \r
source_info(narrow(print())) << \r
msg_info("No video or audio codec context found.")); \r
\r
- executor_.start();\r
executor_.begin_invoke([this]{read_file();});\r
CASPAR_LOG(info) << print() << " Started.";\r
}\r
, tail_(core::basic_frame::empty()) \r
, frame_factory_(frame_factory)\r
, format_desc_(frame_factory->get_video_format_desc())\r
- , executor_(L"flash_producer", true)\r
+ , executor_(L"flash_producer")\r
{ \r
if(!boost::filesystem::exists(filename))\r
BOOST_THROW_EXCEPTION(file_not_found() << boost::errinfo_file_name(narrow(filename))); \r
if(screen_index != 0)\r
CASPAR_LOG(warning) << print() << " only supports screen_index=0 for non-Win32";\r
#endif \r
- executor_.start();\r
executor_.invoke([=]\r
{\r
window_.Create(sf::VideoMode(screen_width_, screen_height_, 32), narrow(print()), windowed_ ? sf::Style::Resize : sf::Style::Fullscreen);\r
\r
silverlight_producer(const safe_ptr<core::frame_factory>& frame_factory) : executor_(L"silverlight")\r
{\r
- executor_.start();\r
executor_.invoke([=]\r
{\r
renderer_.reset(new silverlight_renderer(frame_factory));\r
const TCHAR CIIProtocolStrategy::TokenDelimiter = TEXT('\\');\r
\r
CIIProtocolStrategy::CIIProtocolStrategy(const std::vector<safe_ptr<core::channel>>& channels) : pChannel_(channels.at(0)), executor_(L"CIIProtocolStrategy")\r
-{\r
- executor_.start();\r
-}\r
+{}\r
\r
void CIIProtocolStrategy::Parse(const TCHAR* pData, int charCount, IO::ClientInfoPtr pClientInfo) \r
{\r