]> git.sesse.net Git - casparcg/blob - core/producer/layer.cpp
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
[casparcg] / core / producer / layer.cpp
1 #include "../stdafx.h"\r
2 \r
3 #include "layer.h"\r
4 \r
5 #include "../producer/frame_producer.h"\r
6 \r
7 #include "../format/video_format.h"\r
8 \r
9 namespace caspar { namespace core {\r
10 \r
11 struct layer::implementation\r
12 {               \r
13         implementation() : foreground_(nullptr), background_(nullptr), last_frame_(nullptr) {}\r
14         \r
15         void load(const frame_producer_ptr& frame_producer, load_option::type option)\r
16         {\r
17                 if(frame_producer == nullptr) \r
18                         BOOST_THROW_EXCEPTION(null_argument() << arg_name_info("frame_producer"));\r
19                         \r
20                 background_ = frame_producer;\r
21                 if(option == load_option::preview)              \r
22                 {\r
23                         foreground_ = nullptr;  \r
24                         last_frame_ = frame_producer->render_frame();\r
25                         if(last_frame_ != nullptr)\r
26                                 last_frame_->get_audio_data().clear(); // No audio\r
27                 }\r
28                 else if(option == load_option::auto_play)\r
29                         play();                 \r
30         }\r
31         \r
32         void play()\r
33         {                       \r
34                 if(background_ != nullptr)\r
35                 {\r
36                         background_->set_leading_producer(foreground_);\r
37                         foreground_ = std::move(background_);\r
38                 }\r
39 \r
40                 is_paused_ = false;\r
41         }\r
42 \r
43         void pause()\r
44         {\r
45                 is_paused_ = true;\r
46         }\r
47 \r
48         void stop()\r
49         {\r
50                 foreground_ = nullptr;\r
51                 last_frame_ = nullptr;\r
52         }\r
53 \r
54         void clear()\r
55         {\r
56                 foreground_ = nullptr;\r
57                 background_ = nullptr;\r
58                 last_frame_ = nullptr;\r
59         }\r
60         \r
61         frame_ptr render_frame()\r
62         {               \r
63                 if(!foreground_ || is_paused_)\r
64                         return last_frame_;\r
65 \r
66                 try\r
67                 {\r
68                         last_frame_ = foreground_->render_frame();\r
69 \r
70                         if(last_frame_ == nullptr)\r
71                         {\r
72                                 foreground_ = foreground_->get_following_producer();\r
73                                 last_frame_ = render_frame();\r
74                         }\r
75                 }\r
76                 catch(...)\r
77                 {\r
78                         CASPAR_LOG_CURRENT_EXCEPTION();\r
79                         CASPAR_LOG(warning) << L"Removed " << (foreground_ ? foreground_->print() : L"null producer") << L" from layer.";\r
80                         foreground_ = nullptr;\r
81                         last_frame_ = nullptr;\r
82                 }\r
83 \r
84                 return last_frame_;\r
85         }       \r
86                 \r
87         tbb::atomic<bool> is_paused_;\r
88         frame_ptr last_frame_;\r
89         frame_producer_ptr foreground_;\r
90         frame_producer_ptr background_;\r
91 };\r
92 \r
93 layer::layer() : impl_(new implementation()){}\r
94 layer::layer(layer&& other) : impl_(std::move(other.impl_)){other.impl_ = nullptr;}\r
95 layer& layer::operator=(layer&& other)\r
96 {\r
97         impl_ = std::move(other.impl_); \r
98         other.impl_ = nullptr;\r
99         return *this;\r
100 }\r
101 void layer::load(const frame_producer_ptr& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}       \r
102 void layer::play(){impl_->play();}\r
103 void layer::pause(){impl_->pause();}\r
104 void layer::stop(){impl_->stop();}\r
105 void layer::clear(){impl_->clear();}\r
106 frame_ptr layer::render_frame() {return impl_->render_frame();}\r
107 frame_producer_ptr layer::foreground() const { return impl_->foreground_;}\r
108 frame_producer_ptr layer::background() const { return impl_->background_;}\r
109 }}