#include <core/producer/frame/frame_visitor.h>\r
#include <core/producer/frame/pixel_format.h>\r
\r
+#include <boost/lexical_cast.hpp>\r
+\r
namespace caspar { namespace core {\r
\r
-struct write_frame::implementation : boost::noncopyable\r
+struct write_frame::implementation\r
{ \r
- ogl_device& ogl_;\r
- std::vector<safe_ptr<host_buffer>> buffers_;\r
- std::vector<safe_ptr<device_buffer>> textures_;\r
- std::vector<int16_t> audio_data_;\r
- const core::pixel_format_desc desc_;\r
- int32_t tag_;\r
-\r
-public:\r
- implementation(ogl_device& ogl, int32_t tag, const core::pixel_format_desc& desc) \r
- : ogl_(ogl)\r
+ ogl_device* ogl_;\r
+ std::vector<std::shared_ptr<host_buffer>> buffers_;\r
+ std::vector<safe_ptr<device_buffer>> textures_;\r
+ std::vector<int16_t> audio_data_;\r
+ const core::pixel_format_desc desc_;\r
+ const void* tag_;\r
+ core::field_mode::type mode_;\r
+\r
+ implementation(const void* tag)\r
+ : tag_(tag)\r
+ {\r
+ }\r
+\r
+ implementation(ogl_device& ogl, const void* tag, const core::pixel_format_desc& desc) \r
+ : ogl_(&ogl)\r
, desc_(desc)\r
, tag_(tag)\r
+ , mode_(core::field_mode::progressive)\r
{\r
- ogl_.invoke([&]\r
+ ogl_->invoke([&]\r
{\r
std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
{\r
- return ogl_.create_host_buffer(plane.size, host_buffer::write_only);\r
+ return ogl_->create_host_buffer(plane.size, host_buffer::write_only);\r
});\r
std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(textures_), [&](const core::pixel_format_desc::plane& plane)\r
{\r
- return ogl_.create_device_buffer(plane.width, plane.height, plane.channels);\r
+ return ogl_->create_device_buffer(plane.width, plane.height, plane.channels); \r
});\r
}, high_priority);\r
}\r
-\r
- ~implementation()\r
- {\r
- ogl_.invoke([=]\r
- {\r
- buffers_.clear();\r
- textures_.clear();\r
- }, high_priority);\r
- }\r
- \r
+ \r
void accept(write_frame& self, core::frame_visitor& visitor)\r
{\r
visitor.begin(self);\r
if(plane_index >= buffers_.size())\r
return;\r
\r
- auto texture = textures_[plane_index];\r
auto buffer = std::move(buffers_[plane_index]); // Release buffer once done.\r
\r
- ogl_.begin_invoke([=]\r
- {\r
- texture->read(*buffer);\r
- });\r
+ if(!buffer)\r
+ return;\r
+\r
+ auto texture = textures_.at(plane_index);\r
+ \r
+ ogl_->begin_invoke([=]\r
+ { \r
+ buffer->unmap();\r
+ buffer->bind();\r
+ texture->begin_read();\r
+ buffer->unbind();\r
+ }, high_priority);\r
+ }\r
+\r
+ std::wstring print() const\r
+ {\r
+ return L"write_frame[" + boost::lexical_cast<std::wstring>(tag_) + L"]";\r
}\r
};\r
\r
-write_frame::write_frame(ogl_device& ogl, int32_t tag, const core::pixel_format_desc& desc) \r
+write_frame::write_frame(const void* tag) : impl_(new implementation(tag)){}\r
+write_frame::write_frame(ogl_device& ogl, const void* tag, const core::pixel_format_desc& desc) \r
: impl_(new implementation(ogl, tag, desc)){}\r
-void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
+write_frame::write_frame(const write_frame& other) : impl_(new implementation(*other.impl_)){}\r
+write_frame::write_frame(write_frame&& other) : impl_(std::move(*other.impl_)){}\r
+write_frame& write_frame::operator=(const write_frame& other)\r
+{\r
+ basic_frame temp(other);\r
+ temp.swap(*this);\r
+ return *this;\r
+}\r
+write_frame& write_frame::operator=(write_frame&& other)\r
+{\r
+ write_frame temp(std::move(other));\r
+ temp.swap(*this);\r
+ return *this;\r
+}\r
+void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
\r
boost::iterator_range<uint8_t*> write_frame::image_data(size_t index){return impl_->image_data(index);}\r
std::vector<int16_t>& write_frame::audio_data() { return impl_->audio_data_; }\r
{\r
return boost::iterator_range<const int16_t*>(impl_->audio_data_.data(), impl_->audio_data_.data() + impl_->audio_data_.size());\r
}\r
-int32_t write_frame::tag() const {return impl_->tag_;}\r
+const void* write_frame::tag() const {return impl_->tag_;}\r
const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
const std::vector<safe_ptr<device_buffer>>& write_frame::get_textures() const{return impl_->textures_;}\r
-const std::vector<safe_ptr<host_buffer>>& write_frame::get_buffers() const{return impl_->buffers_;}\r
void write_frame::commit(size_t plane_index){impl_->commit(plane_index);}\r
void write_frame::commit(){impl_->commit();}\r
+void write_frame::set_type(const field_mode::type& mode){impl_->mode_ = mode;}\r
+core::field_mode::type write_frame::get_type() const{return impl_->mode_;}\r
+\r
+std::wstring write_frame::print() const{return impl_->print();}\r
+void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
+\r
}}
\ No newline at end of file