]> git.sesse.net Git - casparcg/blob - core/frame/frame_transform.h
* Refactored blend_mode to be part of frame_transform instead of a global parameter...
[casparcg] / core / frame / frame_transform.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: Robert Nagy, ronag89@gmail.com
20 */
21
22 #pragma once
23
24 #include <common/tweener.h>
25 #include <core/video_format.h>
26 #include <core/mixer/image/blend_modes.h>
27
28 #include <boost/array.hpp>
29
30 namespace caspar { namespace core {
31                         
32 struct levels final
33 {
34         double min_input        = 0.0;
35         double max_input        = 1.0;
36         double gamma            = 1.0;
37         double min_output       = 0.0;
38         double max_output       = 1.0;
39 };
40
41 struct corners final
42 {
43         boost::array<double, 2> ul = boost::array<double, 2> { { 0.0, 0.0 } };
44         boost::array<double, 2> ur = boost::array<double, 2> { { 1.0, 0.0 } };
45         boost::array<double, 2> lr = boost::array<double, 2> { { 1.0, 1.0 } };
46         boost::array<double, 2> ll = boost::array<double, 2> { { 0.0, 1.0 } };
47 };
48
49 struct rectangle final
50 {
51         boost::array<double, 2> ul = boost::array<double, 2> { { 0.0, 0.0 } };
52         boost::array<double, 2> lr = boost::array<double, 2> { { 1.0, 1.0 } };
53 };
54
55 struct image_transform final
56 {
57         double                                  opacity                         = 1.0;
58         double                                  contrast                        = 1.0;
59         double                                  brightness                      = 1.0;
60         double                                  saturation                      = 1.0;
61
62         // A bug in VS 2013 prevents us from writing:
63         // boost::array<double, 2> fill_translation = { { 0.0, 0.0 } };
64         // See http://blogs.msdn.com/b/vcblog/archive/2014/08/19/the-future-of-non-static-data-member-initialization.aspx
65         boost::array<double, 2> anchor                          = boost::array<double, 2> { { 0.0, 0.0 } };
66         boost::array<double, 2> fill_translation        = boost::array<double, 2> { { 0.0, 0.0 } };
67         boost::array<double, 2> fill_scale                      = boost::array<double, 2> { { 1.0, 1.0 } };
68         boost::array<double, 2> clip_translation        = boost::array<double, 2> { { 0.0, 0.0 } };
69         boost::array<double, 2> clip_scale                      = boost::array<double, 2> { { 1.0, 1.0 } };
70         double                                  angle                           = 0.0;
71         rectangle                               crop;
72         corners                                 perspective;
73         core::levels                    levels;
74
75         core::field_mode                field_mode                      = core::field_mode::progressive;
76         bool                                    is_key                          = false;
77         bool                                    is_mix                          = false;
78         bool                                    is_still                        = false;
79         bool                                    use_mipmap                      = false;
80         core::blend_mode                blend_mode                      = core::blend_mode::normal;
81         int                                             layer_depth                     = 0;
82         
83         image_transform& operator*=(const image_transform &other);
84         image_transform operator*(const image_transform &other) const;
85
86         static image_transform tween(double time, const image_transform& source, const image_transform& dest, double duration, const tweener& tween);
87 };
88
89 bool operator==(const image_transform& lhs, const image_transform& rhs);
90 bool operator!=(const image_transform& lhs, const image_transform& rhs);
91
92 struct audio_transform final
93 {
94         double  volume          = 1.0;
95         bool    is_still        = false;
96         
97         audio_transform& operator*=(const audio_transform &other);
98         audio_transform operator*(const audio_transform &other) const;
99
100         static audio_transform tween(double time, const audio_transform& source, const audio_transform& dest, double duration, const tweener& tween);
101 };
102
103 bool operator==(const audio_transform& lhs, const audio_transform& rhs);
104 bool operator!=(const audio_transform& lhs, const audio_transform& rhs);
105
106 //__declspec(align(16)) 
107 struct frame_transform final
108 {
109 public:
110         frame_transform();
111         
112         core::image_transform image_transform;
113         core::audio_transform audio_transform;
114
115         //char padding[(sizeof(core::image_transform) + sizeof(core::audio_transform)) % 16];
116         
117         frame_transform& operator*=(const frame_transform &other);
118         frame_transform operator*(const frame_transform &other) const;
119
120         static frame_transform tween(double time, const frame_transform& source, const frame_transform& dest, double duration, const tweener& tween);
121 };
122
123 bool operator==(const frame_transform& lhs, const frame_transform& rhs);
124 bool operator!=(const frame_transform& lhs, const frame_transform& rhs);
125
126 class tweened_transform
127 {
128         frame_transform source_;
129         frame_transform dest_;
130         int duration_;
131         int time_;
132         tweener tweener_;
133 public: 
134         tweened_transform()
135                 : duration_(0)
136                 , time_(0)
137         {
138         }
139
140         tweened_transform(const frame_transform& source, const frame_transform& dest, int duration, const tweener& tween)
141                 : source_(source)
142                 , dest_(dest)
143                 , duration_(duration)
144                 , time_(0)
145                 , tweener_(tween)
146         {
147         }
148         
149         frame_transform fetch()
150         {
151                 return time_ == duration_ ? dest_ : frame_transform::tween(static_cast<double>(time_), source_, dest_, static_cast<double>(duration_), tweener_);
152         }
153
154         frame_transform fetch_and_tick(int num)
155         {                                               
156                 time_ = std::min(time_+num, duration_);
157                 return fetch();
158         }
159 };
160
161 namespace detail {
162
163 void set_current_aspect_ratio(double aspect_ratio);
164 double get_current_aspect_ratio();
165
166 }}}