]> git.sesse.net Git - casparcg/blob - core/mixer/frame/draw_frame.cpp
2.0.0.2: clip-rect and fix-rect works now properly with transitions.
[casparcg] / core / mixer / frame / draw_frame.cpp
1 #include "../../StdAfx.h"\r
2 \r
3 #include "draw_frame.h"\r
4 \r
5 #include "../image/image_transform.h"\r
6 #include "../image/image_mixer.h"\r
7 #include "../audio/audio_mixer.h"\r
8 #include "../audio/audio_transform.h"\r
9 #include "pixel_format.h"\r
10 #include "../../video_format.h"\r
11 \r
12 #include <boost/range/algorithm.hpp>\r
13 \r
14 namespace caspar { namespace core {\r
15                                                                                                                                                                                                                                                                                                                 \r
16 struct draw_frame::implementation\r
17 {               \r
18         std::vector<safe_ptr<draw_frame>> frames_;\r
19 \r
20         image_transform image_transform_;       \r
21         audio_transform audio_transform_;\r
22 \r
23         int index_;\r
24 public:\r
25         implementation(const std::vector<safe_ptr<draw_frame>>& frames) \r
26                 : frames_(frames)\r
27                 , index_(std::numeric_limits<int>::min()) {}\r
28         implementation(std::vector<safe_ptr<draw_frame>>&& frames) \r
29                 : frames_(std::move(frames))\r
30                 , index_(std::numeric_limits<int>::min()) {}\r
31         \r
32         void process_image(image_mixer& mixer)\r
33         {\r
34                 mixer.begin(image_transform_);\r
35                 BOOST_FOREACH(auto frame, frames_)\r
36                         frame->process_image(mixer);\r
37                 mixer.end();\r
38         }\r
39 \r
40         void process_audio(audio_mixer& mixer)\r
41         {\r
42                 mixer.begin(audio_transform_);\r
43                 BOOST_FOREACH(auto frame, frames_)\r
44                         frame->process_audio(mixer);\r
45                 mixer.end();\r
46         }       \r
47 };\r
48         \r
49 draw_frame::draw_frame() : impl_(new implementation(std::vector<safe_ptr<draw_frame>>())){}\r
50 draw_frame::draw_frame(const std::vector<safe_ptr<draw_frame>>& frames) : impl_(new implementation(frames)){}\r
51 draw_frame::draw_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(new implementation(std::move(frames))){}\r
52 draw_frame::draw_frame(const draw_frame& other) : impl_(new implementation(*other.impl_)){}\r
53 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame)\r
54 {\r
55         std::vector<safe_ptr<draw_frame>> frames;\r
56         frames.push_back(frame);\r
57         impl_.reset(new implementation(std::move(frames)));\r
58 }\r
59 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame)\r
60 {\r
61         std::vector<safe_ptr<draw_frame>> frames;\r
62         frames.push_back(std::move(frame));\r
63         impl_.reset(new implementation(std::move(frames)));\r
64 }\r
65 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2)\r
66 {\r
67         std::vector<safe_ptr<draw_frame>> frames;\r
68         frames.push_back(frame1);\r
69         frames.push_back(frame2);\r
70         impl_.reset(new implementation(std::move(frames)));\r
71 }\r
72 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2)\r
73 {\r
74         std::vector<safe_ptr<draw_frame>> frames;\r
75         frames.push_back(std::move(frame1));\r
76         frames.push_back(std::move(frame2));\r
77         impl_.reset(new implementation(std::move(frames)));\r
78 }\r
79 \r
80 void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
81 draw_frame& draw_frame::operator=(const draw_frame& other)\r
82 {\r
83         draw_frame temp(other);\r
84         temp.swap(*this);\r
85         return *this;\r
86 }\r
87 draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
88 draw_frame& draw_frame::operator=(draw_frame&& other)\r
89 {\r
90         draw_frame temp(std::move(other));\r
91         temp.swap(*this);\r
92         return *this;\r
93 }\r
94 void draw_frame::process_image(image_mixer& mixer){impl_->process_image(mixer);}\r
95 void draw_frame::process_audio(audio_mixer& mixer){impl_->process_audio(mixer);}\r
96 \r
97 const image_transform& draw_frame::get_image_transform() const { return impl_->image_transform_;}\r
98 image_transform& draw_frame::get_image_transform() { return impl_->image_transform_;}\r
99 const audio_transform& draw_frame::get_audio_transform() const { return impl_->audio_transform_;}\r
100 audio_transform& draw_frame::get_audio_transform() { return impl_->audio_transform_;}\r
101 \r
102 safe_ptr<draw_frame> draw_frame::interlace(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2, video_mode::type mode)\r
103 {                       \r
104         if(frame1 == frame2 || mode == video_mode::progressive)\r
105                 return frame1;\r
106 \r
107         auto my_frame1 = make_safe<draw_frame>(frame1);\r
108         auto my_frame2 = make_safe<draw_frame>(frame2);\r
109         if(mode == video_mode::upper)\r
110         {\r
111                 my_frame1->get_image_transform().set_mode(video_mode::upper);   \r
112                 my_frame2->get_image_transform().set_mode(video_mode::lower);   \r
113         }                                                                                        \r
114         else                                                                             \r
115         {                                                                                        \r
116                 my_frame1->get_image_transform().set_mode(video_mode::lower);   \r
117                 my_frame2->get_image_transform().set_mode(video_mode::upper);   \r
118         }\r
119 \r
120         std::vector<safe_ptr<draw_frame>> frames;\r
121         frames.push_back(my_frame1);\r
122         frames.push_back(my_frame2);\r
123         return make_safe<draw_frame>(frames);\r
124 }\r
125 \r
126 void draw_frame::set_layer_index(int index) { impl_->index_ = index; }\r
127 int draw_frame::get_layer_index() const { return impl_->index_; }\r
128 \r
129 }}