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