#include <core/mixer/write_frame.h>\r
\r
#include <common/env.h>\r
-#include <common/concurrency/com_context.h>\r
+#include <common/concurrency/executor.h>\r
+#include <common/concurrency/lock.h>\r
#include <common/diagnostics/graph.h>\r
#include <common/memory/memcpy.h>\r
#include <common/memory/memclr.h>\r
int width_;\r
int height_;\r
\r
- com_context<flash_renderer> context_; \r
+ std::unique_ptr<flash_renderer> renderer_;\r
\r
+ executor executor_; \r
public:\r
flash_producer(const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, size_t width, size_t height) \r
: filename_(filename) \r
, last_frame_(core::basic_frame::empty())\r
, width_(width > 0 ? width : frame_factory->get_video_format_desc().width)\r
, height_(height > 0 ? height : frame_factory->get_video_format_desc().height)\r
- , context_(L"flash_producer")\r
+ , executor_(L"flash_producer")\r
{ \r
fps_ = 0;\r
\r
\r
frame_buffer_.set_capacity(frame_factory_->get_video_format_desc().fps > 30.0 ? 2 : 1);\r
\r
- initialize(); \r
+ executor_.begin_invoke([]\r
+ {\r
+ ::CoInitialize(nullptr);\r
+ }); \r
}\r
\r
~flash_producer()\r
{\r
- frame_buffer_.clear();\r
+ safe_ptr<core::basic_frame> frame;\r
+ for(int n = 0; n < 3; ++n)\r
+ frame_buffer_.try_pop(frame);\r
+\r
+ executor_.invoke([]\r
+ {\r
+ ::CoUninitialize();\r
+ });\r
}\r
\r
// frame_producer\r
graph_->set_value("output-buffer-count", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity()));\r
\r
auto frame = core::basic_frame::late();\r
- if(!frame_buffer_.try_pop(frame) && context_)\r
+ if(!frame_buffer_.try_pop(frame) && renderer_)\r
graph_->set_tag("underflow");\r
\r
return frame;\r
\r
virtual safe_ptr<core::basic_frame> last_frame() const override\r
{\r
- tbb::spin_mutex::scoped_lock lock(last_frame_mutex_);\r
- return last_frame_;\r
+ return lock(last_frame_mutex_, [this]\r
+ {\r
+ return last_frame_;\r
+ });\r
} \r
\r
virtual boost::unique_future<std::wstring> call(const std::wstring& param) override\r
{ \r
- return context_.begin_invoke([=]() -> std::wstring\r
+ return executor_.begin_invoke([=]() -> std::wstring\r
{\r
- if(!context_)\r
- initialize();\r
+ if(!renderer_)\r
+ {\r
+ renderer_.reset(new flash_renderer(safe_ptr<diagnostics::graph>(graph_), frame_factory_, filename_, width_, height_));\r
+ render(renderer_.get());\r
+ }\r
\r
try\r
{\r
- return context_->call(param); \r
+ return renderer_->call(param); \r
\r
//const auto& format_desc = frame_factory_->get_video_format_desc();\r
//if(abs(context_->fps() - format_desc.fps) > 0.01 && abs(context_->fps()/2.0 - format_desc.fps) > 0.01)\r
catch(...)\r
{\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
- context_.reset(nullptr);\r
+ renderer_.reset(nullptr);\r
frame_buffer_.push(core::basic_frame::empty());\r
}\r
\r
return L"";\r
- });\r
+ }, high_priority);\r
}\r
\r
virtual std::wstring print() const override\r
}\r
\r
// flash_producer\r
-\r
- void initialize()\r
- {\r
- context_.reset([&]{return new flash_renderer(safe_ptr<diagnostics::graph>(graph_), frame_factory_, filename_, width_, height_);});\r
- while(frame_buffer_.try_push(core::basic_frame::empty())){} \r
- render(context_.get());\r
- }\r
-\r
+ \r
safe_ptr<core::basic_frame> render_frame()\r
{\r
- auto frame = context_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()); \r
- tbb::spin_mutex::scoped_lock lock(last_frame_mutex_);\r
- last_frame_ = make_safe<core::basic_frame>(frame);\r
+ auto frame = renderer_->render_frame(frame_buffer_.size() < frame_buffer_.capacity()); \r
+ lock(last_frame_mutex_, [&]\r
+ {\r
+ last_frame_ = make_safe<core::basic_frame>(frame);\r
+ });\r
return frame;\r
}\r
\r
void render(const flash_renderer* renderer)\r
{ \r
- context_.begin_invoke([=]\r
+ executor_.begin_invoke([=]\r
{\r
- if(context_.get() != renderer) // Since initialize will start a new recursive call make sure the recursive calls are only for a specific instance.\r
+ if(renderer_.get() != renderer) // Since initialize will start a new recursive call make sure the recursive calls are only for a specific instance.\r
return;\r
\r
try\r
{ \r
const auto& format_desc = frame_factory_->get_video_format_desc();\r
\r
- if(abs(context_->fps()/2.0 - format_desc.fps) < 2.0) // flash == 2 * format -> interlace\r
+ if(abs(renderer_->fps()/2.0 - format_desc.fps) < 2.0) // flash == 2 * format -> interlace\r
{\r
auto frame1 = render_frame();\r
auto frame2 = render_frame();\r
frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, format_desc.field_mode));\r
}\r
- else if(abs(context_->fps()- format_desc.fps/2.0) < 2.0) // format == 2 * flash -> duplicate\r
+ else if(abs(renderer_->fps()- format_desc.fps/2.0) < 2.0) // format == 2 * flash -> duplicate\r
{\r
auto frame = render_frame();\r
frame_buffer_.push(frame);\r
frame_buffer_.push(frame);\r
}\r
\r
- if(context_->is_empty())\r
+ if(renderer_->is_empty())\r
{\r
- context_.reset(nullptr);\r
+ renderer_.reset(nullptr);\r
return;\r
}\r
\r
graph_->set_value("output-buffer-count", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity())); \r
- fps_.fetch_and_store(static_cast<int>(context_->fps()*100.0)); \r
+ fps_.fetch_and_store(static_cast<int>(renderer_->fps()*100.0)); \r
graph_->set_text(print());\r
\r
render(renderer);\r
catch(...)\r
{\r
CASPAR_LOG_CURRENT_EXCEPTION();\r
- context_.reset(nullptr);\r
+ renderer_.reset(nullptr);\r
frame_buffer_.push(core::basic_frame::empty());\r
}\r
});\r