]> 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 "../processor/producer_frame.h"\r
6 #include "../producer/frame_producer.h"\r
7 \r
8 #include "../format/video_format.h"\r
9 \r
10 namespace caspar { namespace core {\r
11 \r
12 struct layer::implementation\r
13 {               \r
14         implementation() : foreground_(nullptr), background_(nullptr), last_frame_(producer_frame::empty()) {}\r
15         \r
16         void load(const frame_producer_ptr& frame_producer, load_option::type option)\r
17         {                       \r
18                 background_ = frame_producer;\r
19                 if(option == load_option::preview)              \r
20                 {\r
21                         foreground_ = nullptr;  \r
22                         last_frame_ = frame_producer->receive();\r
23                 }\r
24                 else if(option == load_option::auto_play)\r
25                         play();                 \r
26         }\r
27         \r
28         void play()\r
29         {                       \r
30                 if(background_ != nullptr)\r
31                 {\r
32                         background_->set_leading_producer(foreground_);\r
33                         foreground_ = std::move(background_);\r
34                 }\r
35 \r
36                 is_paused_ = false;\r
37         }\r
38 \r
39         void pause()\r
40         {\r
41                 is_paused_ = true;\r
42         }\r
43 \r
44         void stop()\r
45         {\r
46                 foreground_ = nullptr;\r
47                 last_frame_ = producer_frame::empty();\r
48         }\r
49 \r
50         void clear()\r
51         {\r
52                 foreground_ = nullptr;\r
53                 background_ = nullptr;\r
54                 last_frame_ = producer_frame::empty();\r
55         }\r
56         \r
57         producer_frame receive()\r
58         {               \r
59                 if(!foreground_ || is_paused_)\r
60                         return last_frame_;\r
61 \r
62                 try\r
63                 {\r
64                         last_frame_ = foreground_->receive();\r
65 \r
66                         if(last_frame_ == producer_frame::eof())\r
67                         {\r
68                                 CASPAR_LOG(info) << L"EOF: " << foreground_->print();\r
69                                 auto following = foreground_->get_following_producer();\r
70                                 following->set_leading_producer(foreground_);\r
71                                 foreground_ = following;\r
72                                 last_frame_ = receive();\r
73                         }\r
74                 }\r
75                 catch(...)\r
76                 {\r
77                         try\r
78                         {\r
79                                 CASPAR_LOG_CURRENT_EXCEPTION();\r
80                                 CASPAR_LOG(warning) << L"Removed " << (foreground_ ? foreground_->print() : L"empty") << L" from layer.";\r
81                                 foreground_ = nullptr;\r
82                                 last_frame_ = producer_frame::empty();\r
83                         }\r
84                         catch(...){}\r
85                 }\r
86 \r
87                 return last_frame_;\r
88         }       \r
89                 \r
90         tbb::atomic<bool>       is_paused_;\r
91         producer_frame          last_frame_;\r
92         frame_producer_ptr      foreground_;\r
93         frame_producer_ptr      background_;\r
94 };\r
95 \r
96 layer::layer() : impl_(new implementation()){}\r
97 layer::layer(layer&& other) : impl_(std::move(other.impl_)){other.impl_ = nullptr;}\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 void layer::load(const frame_producer_ptr& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}       \r
105 void layer::play(){impl_->play();}\r
106 void layer::pause(){impl_->pause();}\r
107 void layer::stop(){impl_->stop();}\r
108 void layer::clear(){impl_->clear();}\r
109 producer_frame layer::receive() {return impl_->receive();}\r
110 frame_producer_ptr layer::foreground() const { return impl_->foreground_;}\r
111 frame_producer_ptr layer::background() const { return impl_->background_;}\r
112 }}