#include "layer.h"\r
#include "frame_producer.h"\r
\r
-#include <common/concurrency/executor.h>\r
-#include <common/exception/exceptions.h>\r
-#include <common/utility/assert.h>\r
-\r
#include "../producer/frame/basic_frame.h"\r
#include "../producer/frame/audio_transform.h"\r
\r
-#include <tbb/spin_mutex.h>\r
-\r
namespace caspar { namespace core {\r
-\r
-class frame_producer_remover\r
-{\r
- executor executor_;\r
-\r
- void do_remove(safe_ptr<frame_producer>& producer)\r
- {\r
- auto name = producer->print();\r
- producer = frame_producer::empty();\r
- CASPAR_LOG(info) << name << L" Removed.";\r
- }\r
-\r
-public:\r
-\r
- frame_producer_remover() : executor_(L"frame_producer_remover")\r
- {\r
- executor_.start();\r
- }\r
-\r
- void remove(safe_ptr<frame_producer>&& producer)\r
- {\r
- if(producer != frame_producer::empty() && !producer.unique())\r
- CASPAR_LOG(debug) << producer->print() << L" was not destroyed on dedicated destruction thread.";\r
- executor_.begin_invoke(std::bind(&frame_producer_remover::do_remove, this, std::move(producer)));\r
- }\r
-};\r
-\r
-frame_producer_remover g_remover;\r
-\r
+ \r
struct layer::implementation : boost::noncopyable\r
{ \r
- tbb::atomic<int> index_;\r
- \r
+ int index_; \r
safe_ptr<frame_producer> foreground_;\r
safe_ptr<frame_producer> background_;\r
safe_ptr<basic_frame> last_frame_;\r
bool is_paused_;\r
public:\r
implementation(int index) \r
- : foreground_(frame_producer::empty())\r
+ : index_(index)\r
+ , foreground_(frame_producer::empty())\r
, background_(frame_producer::empty())\r
, last_frame_(basic_frame::empty())\r
- , is_paused_(false)\r
+ , is_paused_(false){}\r
+ \r
+ void pause() \r
{\r
- index_ = index;\r
+ is_paused_ = true; \r
}\r
- \r
- void load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load, bool preview)\r
- { \r
- background_ = frame_producer;\r
+\r
+ void resume()\r
+ {\r
+ if(is_paused_)\r
+ CASPAR_LOG(info) << foreground_->print() << L" Resumed.";\r
is_paused_ = false;\r
+ }\r
+\r
+ void load(const safe_ptr<frame_producer>& producer, bool play_on_load, bool preview)\r
+ { \r
+ background_ = producer;\r
\r
- if(preview)\r
+ if(play_on_load)\r
+ play(); \r
+ else if(preview)\r
{\r
play();\r
receive();\r
pause();\r
}\r
\r
- if(play_on_load)\r
- play(); \r
+ CASPAR_LOG(info) << producer->print() << L" Loaded.";\r
}\r
-\r
+ \r
void play()\r
{ \r
- if(!is_paused_) \r
+ if(background_ != frame_producer::empty())\r
{\r
background_->set_leading_producer(foreground_);\r
foreground_ = background_;\r
- CASPAR_LOG(info) << foreground_->print() << L" Added.";\r
background_ = frame_producer::empty();\r
+ CASPAR_LOG(info) << foreground_->print() << L" Active.";\r
}\r
- is_paused_ = false;\r
+ resume();\r
}\r
-\r
- void pause()\r
- {\r
- is_paused_ = true;\r
- }\r
-\r
+ \r
void stop()\r
{\r
pause();\r
\r
safe_ptr<basic_frame> receive()\r
{ \r
- if(is_paused_)\r
- {\r
- last_frame_->get_audio_transform().set_gain(0.0);\r
- return last_frame_;\r
- }\r
-\r
- auto keep_alive = foreground_;\r
- last_frame_ = core::receive(foreground_);\r
-\r
- if(keep_alive != foreground_)\r
- g_remover.remove(std::move(keep_alive));\r
+ if(is_paused_) \r
+ last_frame_->get_audio_transform().set_has_audio(false); \r
+ else\r
+ last_frame_ = core::receive(foreground_);\r
\r
return last_frame_;\r
}\r
return *this;\r
}\r
void layer::swap(layer& other)\r
-{\r
- impl_.swap(other.impl_);\r
- // Printer state is not swapped.\r
- std::swap(impl_->index_, other.impl_->index_);\r
+{ \r
+ std::swap(impl_->foreground_, other.impl_->foreground_);\r
+ std::swap(impl_->background_, other.impl_->background_);\r
+ std::swap(impl_->last_frame_, other.impl_->last_frame_);\r
+ std::swap(impl_->is_paused_ , other.impl_->is_paused_ );\r
}\r
void layer::load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load, bool preview){return impl_->load(frame_producer, play_on_load, preview);} \r
void layer::play(){impl_->play();}\r