]> git.sesse.net Git - casparcg/blob - core/producer/scene/scene_producer.h
* Implemented supports for timeline marks in scene_producer. A mark is set on a speci...
[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 enum class mark_action
105 {
106         start,
107         stop,
108         jump_to,
109         remove
110 };
111
112 mark_action get_mark_action(const std::wstring& name);
113
114 class scene_producer : public frame_producer_base
115 {
116 public:
117         scene_producer(int width, int height, const video_format_desc& format_desc);
118         ~scene_producer();
119
120         class draw_frame receive_impl() override;
121         constraints& pixel_constraints() override;
122         void on_interaction(const interaction_event::ptr& event) override;
123         bool collides(double x, double y) const override;
124         std::wstring print() const override;
125         std::wstring name() const override;
126         std::future<std::wstring> call(const std::vector<std::wstring>& params) override;
127         boost::property_tree::wptree info() const override;
128         monitor::subject& monitor_output();
129
130         layer& create_layer(
131                         const spl::shared_ptr<frame_producer>& producer, int x, int y, const std::wstring& name);
132         layer& create_layer(
133                         const spl::shared_ptr<frame_producer>& producer, const std::wstring& name);
134         binding<int64_t> frame();
135         binding<double> speed();
136
137         template<typename T> binding<T>& create_variable(
138                         const std::wstring& name, bool is_public, const std::wstring& expr = L"")
139         {
140                 std::shared_ptr<core::variable> var =
141                                 std::make_shared<core::variable_impl<T>>(expr, is_public);
142
143                 store_variable(name, var);
144
145                 return var->as<T>();
146         }
147
148         template<typename T>
149         void add_keyframe(
150                         binding<T>& to_affect,
151                         T destination_value,
152                         int64_t at_frame,
153                         const std::wstring& easing)
154         {
155                 add_keyframe(to_affect, binding<T>(destination_value), at_frame, easing);
156         }
157
158         template<typename T>
159         void add_keyframe(
160                         binding<T>& to_affect,
161                         const binding<T>& destination_value,
162                         int64_t at_frame,
163                         const std::wstring& easing)
164         {
165                 if (easing.empty())
166                 {
167                         add_keyframe(to_affect, destination_value, at_frame);
168                         return;
169                 }
170
171                 tweener tween(easing);
172                 keyframe k(at_frame);
173
174                 std::shared_ptr<T> start_value(new T);
175
176                 k.on_start_animate = [=]() mutable
177                 {
178                         *start_value = to_affect.get();
179                         to_affect.unbind();
180                 };
181
182                 k.on_destination_frame = [=]() mutable
183                 {
184                         to_affect.bind(destination_value);
185                 };
186
187                 k.on_animate_to =
188                                 [=](int64_t start_frame, int64_t current_frame) mutable
189                                 {
190                                         auto relative_frame = current_frame - start_frame;
191                                         auto duration = at_frame - start_frame;
192                                         auto tweened = static_cast<T>(tween(
193                                                         static_cast<double>(relative_frame),
194                                                         *start_value,
195                                                         destination_value.get() - *start_value,
196                                                         static_cast<double>(duration)));
197
198                                         to_affect.set(tweened);
199                                         
200                                         //CASPAR_LOG(info) << relative_frame << L" " << *start_value << L" " << duration << L" " << tweened;
201                                 };
202
203                 store_keyframe(to_affect.identity(), k);
204         }
205
206         template<typename T>
207         void add_keyframe(binding<T>& to_affect, T set_value, int64_t at_frame)
208         {
209                 add_keyframe(to_affect, binding<T>(set_value), at_frame);
210         }
211
212         template<typename T>
213         void add_keyframe(binding<T>& to_affect, const binding<T>& set_value, int64_t at_frame)
214         {
215                 keyframe k(at_frame);
216
217                 k.on_destination_frame = [=]() mutable
218                 {
219                         to_affect.bind(set_value);
220                 };
221
222                 store_keyframe(to_affect.identity(), k);
223         }
224
225         void add_mark(int64_t frame, mark_action action, const std::wstring& label);
226
227         core::variable& get_variable(const std::wstring& name) override;
228         const std::vector<std::wstring>& get_variables() const override;
229 private:
230         void store_keyframe(void* timeline_identity, const keyframe& k);
231         void store_variable(
232                         const std::wstring& name, const std::shared_ptr<core::variable>& var);
233
234         struct impl;
235         std::unique_ptr<impl> impl_;
236 };
237
238 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);
239
240 }}}