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