]> git.sesse.net Git - casparcg/blobdiff - 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
index 0c030d9c7397de4240de0e427764fad6943eaf0f..bf90469864a34e89784f70cacb9f56810e0ebc63 100644 (file)
-#include "../stdafx.h"\r
+#include "../StdAfx.h"\r
 \r
 #include "draw_frame.h"\r
 \r
-#include "frame_shader.h"\r
+#include "image_processor.h"\r
+#include "audio_processor.h"\r
+#include "pixel_format.h"\r
+\r
+#include <boost/range/algorithm.hpp>\r
 \r
 namespace caspar { namespace core {\r
-       \r
-draw_frame::draw_frame() : type_(empty_tag){}\r
-draw_frame::draw_frame(const draw_frame& other) : impl_(other.impl_), type_(other.type_){}\r
-draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)), type_(other.type_)\r
-{\r
-       other.type_ = empty_tag;\r
-}\r
+                                                                                                                                                                                                                                                                                                               \r
+struct draw_frame::implementation\r
+{              \r
+       std::vector<safe_ptr<draw_frame>> frames_;\r
 \r
-const std::vector<short>& draw_frame::audio_data() const \r
-{\r
-       static std::vector<short> no_audio;\r
-       return impl_ ? impl_->audio_data() : no_audio;\r
-}      \r
+       image_transform image_transform_;       \r
+       audio_transform audio_transform_;\r
 \r
-void draw_frame::swap(draw_frame& other)\r
+public:\r
+       implementation(const std::vector<safe_ptr<draw_frame>>& frames) \r
+               : frames_(frames){}\r
+       implementation(std::vector<safe_ptr<draw_frame>>&& frames) \r
+               : frames_(std::move(frames)){}\r
+       \r
+       void process_image(image_processor& processor)\r
+       {\r
+               processor.begin(image_transform_);\r
+               BOOST_FOREACH(auto frame, frames_)\r
+                       frame->process_image(processor);\r
+               processor.end();\r
+       }\r
+\r
+       void process_audio(audio_processor& processor)\r
+       {\r
+               processor.begin(audio_transform_);\r
+               BOOST_FOREACH(auto frame, frames_)\r
+                       frame->process_audio(processor);\r
+               processor.end();\r
+       }       \r
+};\r
+       \r
+draw_frame::draw_frame() : impl_(new implementation(std::vector<safe_ptr<draw_frame>>())){}\r
+draw_frame::draw_frame(const std::vector<safe_ptr<draw_frame>>& frames) : impl_(new implementation(frames)){}\r
+draw_frame::draw_frame(std::vector<safe_ptr<draw_frame>>&& frames) : impl_(new implementation(std::move(frames))){}\r
+draw_frame::draw_frame(const draw_frame& other) : impl_(new implementation(*other.impl_)){}\r
+draw_frame::draw_frame(const safe_ptr<draw_frame>& frame)\r
 {\r
-       impl_.swap(other.impl_);\r
-       std::swap(type_, other.type_);\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
+       frames.push_back(frame);\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
-       \r
-void draw_frame::begin_write()\r
+draw_frame::draw_frame(safe_ptr<draw_frame>&& frame)\r
 {\r
-       if(impl_)\r
-               impl_->begin_write();\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
+       frames.push_back(std::move(frame));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
-\r
-void draw_frame::end_write()\r
+draw_frame::draw_frame(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2)\r
 {\r
-       if(impl_)\r
-               impl_->end_write();\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
+       frames.push_back(frame1);\r
+       frames.push_back(frame2);\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
-\r
-void draw_frame::draw(frame_shader& shader)\r
+draw_frame::draw_frame(safe_ptr<draw_frame>&& frame1, safe_ptr<draw_frame>&& frame2)\r
 {\r
-       if(impl_)\r
-               impl_->draw(shader);\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
+       frames.push_back(std::move(frame1));\r
+       frames.push_back(std::move(frame2));\r
+       impl_.reset(new implementation(std::move(frames)));\r
 }\r
 \r
-eof_frame draw_frame::eof(){return eof_frame();}\r
-empty_frame draw_frame::empty(){return empty_frame();}\r
-       \r
-bool draw_frame::operator==(const eof_frame&){return type_ == eof_tag;}\r
-bool draw_frame::operator==(const empty_frame&){return type_ == empty_tag;}\r
-bool draw_frame::operator==(const draw_frame& other){return impl_ == other.impl_ && type_ == other.type_;}\r
-       \r
+void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
 draw_frame& draw_frame::operator=(const draw_frame& other)\r
 {\r
        draw_frame temp(other);\r
        temp.swap(*this);\r
        return *this;\r
 }\r
+draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
 draw_frame& draw_frame::operator=(draw_frame&& other)\r
 {\r
-       impl_ = std::move(other.impl_);\r
-       type_ = other.type_;\r
-       other.type_ = empty_tag;\r
+       draw_frame temp(std::move(other));\r
+       temp.swap(*this);\r
        return *this;\r
 }\r
-draw_frame& draw_frame::operator=(eof_frame&&)\r
-{\r
-       impl_ = nullptr;\r
-       type_ = eof_tag;\r
-       return *this;\r
-}      \r
-draw_frame& draw_frame::operator=(empty_frame&&)\r
-{\r
-       impl_ = nullptr;\r
-       type_ = empty_tag;\r
-       return *this;\r
-}      \r
+void draw_frame::process_image(image_processor& processor){impl_->process_image(processor);}\r
+void draw_frame::process_audio(audio_processor& processor){impl_->process_audio(processor);}\r
+void draw_frame::audio_volume(double volume){impl_->audio_transform_.volume = volume;}\r
+void draw_frame::translate(double x, double y){impl_->image_transform_.pos = boost::make_tuple(x, y);}\r
+void draw_frame::texcoord(double left, double top, double right, double bottom){impl_->image_transform_.uv = boost::make_tuple(left, top, right, bottom);}\r
+void draw_frame::video_mode(video_mode::type mode){impl_->image_transform_.mode = mode;}\r
+void draw_frame::alpha(double value){impl_->image_transform_.alpha = value;}\r
+const image_transform& draw_frame::get_image_transform() const { return impl_->image_transform_;}\r
+const audio_transform& draw_frame::get_audio_transform() const { return impl_->audio_transform_;}\r
+\r
+safe_ptr<draw_frame> draw_frame::interlace(const safe_ptr<draw_frame>& frame1, const safe_ptr<draw_frame>& frame2, video_mode::type mode)\r
+{                      \r
+       if(frame1 == frame2 || mode == video_mode::progressive)\r
+               return frame1;\r
+\r
+       auto my_frame1 = make_safe<draw_frame>(frame1);\r
+       auto my_frame2 = make_safe<draw_frame>(frame2);\r
+       if(mode == video_mode::upper)\r
+       {\r
+               my_frame1->video_mode(video_mode::upper);       \r
+               my_frame2->video_mode(video_mode::lower);       \r
+       }\r
+       else\r
+       {\r
+               my_frame1->video_mode(video_mode::lower);       \r
+               my_frame2->video_mode(video_mode::upper);       \r
+       }\r
+\r
+       std::vector<safe_ptr<draw_frame>> frames;\r
+       frames.push_back(my_frame1);\r
+       frames.push_back(my_frame2);\r
+       return make_safe<draw_frame>(frames);\r
+}\r
 \r
 }}
\ No newline at end of file