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