]> git.sesse.net Git - casparcg/blob - core/producer/scene/scene_producer.h
* Merged chroma key feature, but removed unsupported parameters and color names....
[casparcg] / core / producer / scene / scene_producer.h
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Helge Norberg, helge.norberg@svt.se
20 */
21
22 #pragma once
23
24 #include <common/log.h>
25
26 #include "../frame_producer.h"
27
28 #include "../binding.h"
29 #include "../variable.h"
30
31 namespace caspar { namespace core {
32
33 class frame_factory;
34
35 namespace scene {
36
37 struct coord
38 {
39         binding<double> x;
40         binding<double> y;
41 };
42
43 struct rect
44 {
45         coord upper_left;
46         coord lower_right;
47 };
48
49 struct corners
50 {
51         coord upper_left;
52         coord upper_right;
53         coord lower_right;
54         coord lower_left;
55 };
56
57 struct adjustments
58 {
59         binding<double> opacity;
60
61         adjustments();
62 };
63
64 struct chroma_key
65 {
66         binding<core::chroma::type>     key;
67         binding<double>                         threshold;
68         binding<double>                         softness;
69         binding<double>                         spill;
70 };
71
72 struct layer
73 {
74         binding<std::wstring>                                           name;
75         scene::coord                                                            anchor;
76         scene::coord                                                            position;
77         scene::rect                                                                     crop;
78         scene::corners                                                          perspective;
79         binding<double>                                                         rotation;
80         scene::adjustments                                                      adjustments;
81         binding<spl::shared_ptr<frame_producer>>        producer;
82         binding<bool>                                                           hidden;
83         binding<bool>                                                           is_key;
84         binding<bool>                                                           use_mipmap;
85         binding<core::blend_mode>                                       blend_mode;
86         scene::chroma_key                                                       chroma_key;
87
88         explicit layer(const std::wstring& name, const spl::shared_ptr<frame_producer>& producer);
89 };
90
91 struct keyframe
92 {
93         std::function<void ()>                                                                                          on_start_animate;
94         std::function<void (int64_t start_frame, int64_t current_frame)>        on_animate_to;
95         std::function<void ()>                                                                                          on_destination_frame;
96         int64_t                                                                                                                         destination_frame;
97 public:
98         keyframe(int64_t destination_frame)
99                 : destination_frame(destination_frame)
100         {
101         }
102 };
103
104 class scene_producer : public frame_producer_base
105 {
106 public:
107         scene_producer(int width, int height);
108         ~scene_producer();
109
110         class draw_frame receive_impl() override;
111         constraints& pixel_constraints() override;
112         void on_interaction(const interaction_event::ptr& event) override;
113         bool collides(double x, double y) const override;
114         std::wstring print() const override;
115         std::wstring name() const override;
116         std::future<std::wstring>       call(const std::vector<std::wstring>& params) override;
117         boost::property_tree::wptree info() const override;
118         monitor::subject& monitor_output();
119
120         layer& create_layer(
121                         const spl::shared_ptr<frame_producer>& producer, int x, int y, const std::wstring& name);
122         layer& create_layer(
123                         const spl::shared_ptr<frame_producer>& producer, const std::wstring& name);
124         binding<int64_t> frame();
125         binding<double> speed();
126
127         template<typename T> binding<T>& create_variable(
128                         const std::wstring& name, bool is_public, const std::wstring& expr = L"")
129         {
130                 std::shared_ptr<core::variable> var =
131                                 std::make_shared<core::variable_impl<T>>(expr, is_public);
132
133                 store_variable(name, var);
134
135                 return var->as<T>();
136         }
137
138         template<typename T>
139         void add_keyframe(
140                         binding<T>& to_affect,
141                         T destination_value,
142                         int64_t at_frame,
143                         const std::wstring& easing)
144         {
145                 add_keyframe(to_affect, binding<T>(destination_value), at_frame, easing);
146         }
147
148         template<typename T>
149         void add_keyframe(
150                         binding<T>& to_affect,
151                         const binding<T>& destination_value,
152                         int64_t at_frame,
153                         const std::wstring& easing)
154         {
155                 if (easing.empty())
156                 {
157                         add_keyframe(to_affect, destination_value, at_frame);
158                         return;
159                 }
160
161                 tweener tween(easing);
162                 keyframe k(at_frame);
163
164                 std::shared_ptr<T> start_value(new T);
165
166                 k.on_start_animate = [=]() mutable
167                 {
168                         *start_value = to_affect.get();
169                         to_affect.unbind();
170                 };
171
172                 k.on_destination_frame = [=]() mutable
173                 {
174                         to_affect.bind(destination_value);
175                 };
176
177                 k.on_animate_to =
178                                 [=](int64_t start_frame, int64_t current_frame) mutable
179                                 {
180                                         auto relative_frame = current_frame - start_frame;
181                                         auto duration = at_frame - start_frame;
182                                         auto tweened = static_cast<T>(tween(
183                                                         static_cast<double>(relative_frame),
184                                                         *start_value,
185                                                         destination_value.get() - *start_value,
186                                                         static_cast<double>(duration)));
187
188                                         to_affect.set(tweened);
189                                         
190                                         //CASPAR_LOG(info) << relative_frame << L" " << *start_value << L" " << duration << L" " << tweened;
191                                 };
192
193                 store_keyframe(to_affect.identity(), k);
194         }
195
196         template<typename T>
197         void add_keyframe(binding<T>& to_affect, T set_value, int64_t at_frame)
198         {
199                 add_keyframe(to_affect, binding<T>(set_value), at_frame);
200         }
201
202         template<typename T>
203         void add_keyframe(binding<T>& to_affect, const binding<T>& set_value, int64_t at_frame)
204         {
205                 keyframe k(at_frame);
206
207                 k.on_destination_frame = [=]() mutable
208                 {
209                         to_affect.bind(set_value);
210                 };
211
212                 store_keyframe(to_affect.identity(), k);
213         }
214
215         core::variable& get_variable(const std::wstring& name) override;
216         const std::vector<std::wstring>& get_variables() const override;
217 private:
218         void store_keyframe(void* timeline_identity, const keyframe& k);
219         void store_variable(
220                         const std::wstring& name, const std::shared_ptr<core::variable>& var);
221
222         struct impl;
223         std::unique_ptr<impl> impl_;
224 };
225
226 spl::shared_ptr<frame_producer> create_dummy_scene_producer(const spl::shared_ptr<frame_factory>& frame_factory, const video_format_desc& format_desc, const std::vector<std::wstring>& params);
227
228 }}}