]> git.sesse.net Git - casparcg/blob - core/processor/draw_frame.cpp
2.0.0.2: decklink_consumer: Ensured com init and uninit is on same thread.
[casparcg] / core / processor / draw_frame.cpp
1 #include "../StdAfx.h"\r
2 \r
3 #include "draw_frame.h"\r
4 \r
5 #include "image_processor.h"\r
6 #include "audio_processor.h"\r
7 #include "pixel_format.h"\r
8 \r
9 #include <boost/range/algorithm.hpp>\r
10 \r
11 namespace caspar { namespace core {\r
12                                                                                                                                                                                                                                                                                                                 \r
13 struct draw_frame::implementation\r
14 {               \r
15         std::vector<safe_ptr<draw_frame>> frames_;\r
16 \r
17         image_transform image_transform_;       \r
18         audio_transform audio_transform_;\r
19 \r
20 public:\r
21         implementation(const std::vector<safe_ptr<draw_frame>>& frames) \r
22                 : frames_(frames){}\r
23         implementation(std::vector<safe_ptr<draw_frame>>&& frames) \r
24                 : frames_(std::move(frames)){}\r
25         \r
26         void process_image(image_processor& processor)\r
27         {\r
28                 processor.begin(image_transform_);\r
29                 BOOST_FOREACH(auto frame, frames_)\r
30                         frame->process_image(processor);\r
31                 processor.end();\r
32         }\r
33 \r
34         void process_audio(audio_processor& processor)\r
35         {\r
36                 processor.begin(audio_transform_);\r
37                 BOOST_FOREACH(auto frame, frames_)\r
38                         frame->process_audio(processor);\r
39                 processor.end();\r
40         }       \r
41 };\r
42         \r
43 draw_frame::draw_frame() : impl_(new implementation(std::vector<safe_ptr<draw_frame>>())){}\r
44 draw_frame::draw_frame(const std::vector<safe_ptr<draw_frame>>& frames) : impl_(new implementation(frames)){}\r
45 draw_frame::draw_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(new implementation(std::move(frames))){}\r
46 draw_frame::draw_frame(const draw_frame& other) : impl_(new implementation(*other.impl_)){}\r
47 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame)\r
48 {\r
49         std::vector<safe_ptr<draw_frame>> frames;\r
50         frames.push_back(frame);\r
51         impl_.reset(new implementation(std::move(frames)));\r
52 }\r
53 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame)\r
54 {\r
55         std::vector<safe_ptr<draw_frame>> frames;\r
56         frames.push_back(std::move(frame));\r
57         impl_.reset(new implementation(std::move(frames)));\r
58 }\r
59 draw_frame::draw_frame(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2)\r
60 {\r
61         std::vector<safe_ptr<draw_frame>> frames;\r
62         frames.push_back(frame1);\r
63         frames.push_back(frame2);\r
64         impl_.reset(new implementation(std::move(frames)));\r
65 }\r
66 draw_frame::draw_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2)\r
67 {\r
68         std::vector<safe_ptr<draw_frame>> frames;\r
69         frames.push_back(std::move(frame1));\r
70         frames.push_back(std::move(frame2));\r
71         impl_.reset(new implementation(std::move(frames)));\r
72 }\r
73 \r
74 void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
75 draw_frame& draw_frame::operator=(const draw_frame& other)\r
76 {\r
77         draw_frame temp(other);\r
78         temp.swap(*this);\r
79         return *this;\r
80 }\r
81 draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
82 draw_frame& draw_frame::operator=(draw_frame&& other)\r
83 {\r
84         draw_frame temp(std::move(other));\r
85         temp.swap(*this);\r
86         return *this;\r
87 }\r
88 void draw_frame::process_image(image_processor& processor){impl_->process_image(processor);}\r
89 void draw_frame::process_audio(audio_processor& processor){impl_->process_audio(processor);}\r
90 void draw_frame::audio_volume(double volume){impl_->audio_transform_.volume = volume;}\r
91 void draw_frame::translate(double x, double y){impl_->image_transform_.pos = boost::make_tuple(x, y);}\r
92 void draw_frame::texcoord(double left, double top, double right, double bottom){impl_->image_transform_.uv = boost::make_tuple(left, top, right, bottom);}\r
93 void draw_frame::video_mode(video_mode::type mode){impl_->image_transform_.mode = mode;}\r
94 void draw_frame::alpha(double value){impl_->image_transform_.alpha = value;}\r
95 const image_transform& draw_frame::get_image_transform() const { return impl_->image_transform_;}\r
96 const audio_transform& draw_frame::get_audio_transform() const { return impl_->audio_transform_;}\r
97 \r
98 safe_ptr<draw_frame> draw_frame::interlace(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2, video_mode::type mode)\r
99 {                       \r
100         if(frame1 == frame2 || mode == video_mode::progressive)\r
101                 return frame1;\r
102 \r
103         auto my_frame1 = make_safe<draw_frame>(frame1);\r
104         auto my_frame2 = make_safe<draw_frame>(frame2);\r
105         if(mode == video_mode::upper)\r
106         {\r
107                 my_frame1->video_mode(video_mode::upper);       \r
108                 my_frame2->video_mode(video_mode::lower);       \r
109         }\r
110         else\r
111         {\r
112                 my_frame1->video_mode(video_mode::lower);       \r
113                 my_frame2->video_mode(video_mode::upper);       \r
114         }\r
115 \r
116         std::vector<safe_ptr<draw_frame>> frames;\r
117         frames.push_back(my_frame1);\r
118         frames.push_back(my_frame2);\r
119         return make_safe<draw_frame>(frames);\r
120 }\r
121 \r
122 }}