-#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