]> 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                 }\r
26                 else if(option == load_option::auto_play)\r
27                         play();                 \r
28         }\r
29         \r
30         void play()\r
31         {                       \r
32                 if(background_ != nullptr)\r
33                 {\r
34                         background_->set_leading_producer(foreground_);\r
35                         foreground_ = std::move(background_);\r
36                 }\r
37 \r
38                 is_paused_ = false;\r
39         }\r
40 \r
41         void pause()\r
42         {\r
43                 is_paused_ = true;\r
44         }\r
45 \r
46         void stop()\r
47         {\r
48                 foreground_ = nullptr;\r
49                 last_frame_ = nullptr;\r
50         }\r
51 \r
52         void clear()\r
53         {\r
54                 foreground_ = nullptr;\r
55                 background_ = nullptr;\r
56                 last_frame_ = nullptr;\r
57         }\r
58         \r
59         gpu_frame_ptr render_frame()\r
60         {               \r
61                 if(!foreground_ || is_paused_)\r
62                         return last_frame_;\r
63 \r
64                 try\r
65                 {\r
66                         last_frame_ = foreground_->render_frame();\r
67 \r
68                         if(last_frame_ == nullptr)\r
69                         {\r
70                                 CASPAR_LOG(info) << L"EOF: " << foreground_->print();\r
71                                 auto following = foreground_->get_following_producer();\r
72                                 following->set_leading_producer(foreground_);\r
73                                 foreground_ = following;\r
74                                 last_frame_ = render_frame();\r
75                         }\r
76                 }\r
77                 catch(...)\r
78                 {\r
79                         try\r
80                         {\r
81                                 CASPAR_LOG_CURRENT_EXCEPTION();\r
82                                 CASPAR_LOG(warning) << L"Removed " << (foreground_ ? foreground_->print() : L"empty") << L" from layer.";\r
83                                 foreground_ = nullptr;\r
84                                 last_frame_ = nullptr;\r
85                         }\r
86                         catch(...){}\r
87                 }\r
88 \r
89                 return last_frame_;\r
90         }       \r
91                 \r
92         tbb::atomic<bool>       is_paused_;\r
93         gpu_frame_ptr                   last_frame_;\r
94         frame_producer_ptr      foreground_;\r
95         frame_producer_ptr      background_;\r
96 };\r
97 \r
98 layer::layer() : impl_(new implementation()){}\r
99 layer::layer(layer&& other) : impl_(std::move(other.impl_)){other.impl_ = nullptr;}\r
100 layer& layer::operator=(layer&& other)\r
101 {\r
102         impl_ = std::move(other.impl_); \r
103         other.impl_ = nullptr;\r
104         return *this;\r
105 }\r
106 void layer::load(const frame_producer_ptr& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}       \r
107 void layer::play(){impl_->play();}\r
108 void layer::pause(){impl_->pause();}\r
109 void layer::stop(){impl_->stop();}\r
110 void layer::clear(){impl_->clear();}\r
111 gpu_frame_ptr layer::render_frame() {return impl_->render_frame();}\r
112 frame_producer_ptr layer::foreground() const { return impl_->foreground_;}\r
113 frame_producer_ptr layer::background() const { return impl_->background_;}\r
114 }}