]> git.sesse.net Git - casparcg/blobdiff - core/mixer/write_frame.cpp
2.0. audio:
[casparcg] / core / mixer / write_frame.cpp
index 4dbb43cde685928306784d0aec8ca8f141aede11..f7b25f50a08c56660f7fa8c17886fe9c942ce677 100644 (file)
 #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
-       safe_ptr<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(int32_t tag, const core::pixel_format_desc& desc, const std::vector<safe_ptr<host_buffer>>& buffers, const std::vector<safe_ptr<device_buffer>>& textures, const safe_ptr<ogl_device> ogl) \r
-               : ogl_(ogl)\r
-               , buffers_(buffers)\r
-               , textures_(textures)\r
+       ogl_device*                                                                     ogl_;\r
+       std::vector<std::shared_ptr<host_buffer>>       buffers_;\r
+       std::vector<safe_ptr<device_buffer>>            textures_;\r
+       audio_buffer                                                            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
-       {}\r
-       \r
+               , mode_(core::field_mode::progressive)\r
+       {\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
+                       });\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
+                       });\r
+               }, high_priority);\r
+       }\r
+                       \r
        void accept(write_frame& self, core::frame_visitor& visitor)\r
        {\r
                visitor.begin(self);\r
@@ -82,34 +100,66 @@ public:
                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
+               if(!buffer)\r
+                       return;\r
+\r
+               auto texture = textures_.at(plane_index);\r
+               \r
                ogl_->begin_invoke([=]\r
-               {\r
-                       texture->read(*buffer);\r
-               });\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(int32_t tag, const core::pixel_format_desc& desc, const std::vector<safe_ptr<host_buffer>>& buffers, const std::vector<safe_ptr<device_buffer>>& textures, const safe_ptr<ogl_device>& ogl) \r
-       : impl_(new implementation(tag, desc, buffers, textures, ogl)){}\r
-void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\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
+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
+audio_buffer& write_frame::audio_data() { return impl_->audio_data_; }\r
 const boost::iterator_range<const uint8_t*> write_frame::image_data(size_t index) const\r
 {\r
        return boost::iterator_range<const uint8_t*>(impl_->image_data(index).begin(), impl_->image_data(index).end());\r
 }\r
-const boost::iterator_range<const int16_t*> write_frame::audio_data() const\r
+const boost::iterator_range<const int32_t*> write_frame::audio_data() const\r
 {\r
-       return boost::iterator_range<const int16_t*>(impl_->audio_data_.data(), impl_->audio_data_.data() + impl_->audio_data_.size());\r
+       return boost::iterator_range<const int32_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