]> git.sesse.net Git - casparcg/blobdiff - core/mixer/write_frame.cpp
2.0. audio:
[casparcg] / core / mixer / write_frame.cpp
index c56edb4d02c9a55b7e612ee6b8065b9125fa3fed..f7b25f50a08c56660f7fa8c17886fe9c942ce677 100644 (file)
 #include "write_frame.h"\r
 \r
 #include "gpu/ogl_device.h"\r
+#include "gpu/host_buffer.h"\r
+#include "gpu/device_buffer.h"\r
 \r
+#include <core/producer/frame/frame_visitor.h>\r
 #include <core/producer/frame/pixel_format.h>\r
 \r
-#include <common/gl/gl_check.h>\r
-\r
-#include <boost/range/algorithm.hpp>\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
-       std::vector<safe_ptr<host_buffer>> buffers_;\r
-       std::vector<safe_ptr<device_buffer>> textures_;\r
-       std::vector<short> audio_data_;\r
-       const core::pixel_format_desc desc_;\r
-       int tag_;\r
-\r
-public:\r
-       implementation(int tag, const core::pixel_format_desc& desc, const std::vector<safe_ptr<host_buffer>>& buffers, const std::vector<safe_ptr<device_buffer>>& textures) \r
-               : desc_(desc)\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
@@ -54,20 +73,20 @@ public:
                visitor.end();\r
        }\r
 \r
-       boost::iterator_range<unsigned char*> image_data(size_t index)\r
+       boost::iterator_range<uint8_t*> image_data(size_t index)\r
        {\r
                if(index >= buffers_.size() || !buffers_[index]->data())\r
-                       return boost::iterator_range<const unsigned char*>();\r
-               auto ptr = static_cast<unsigned char*>(buffers_[index]->data());\r
-               return boost::iterator_range<unsigned char*>(ptr, ptr+buffers_[index]->size());\r
+                       return boost::iterator_range<const uint8_t*>();\r
+               auto ptr = static_cast<uint8_t*>(buffers_[index]->data());\r
+               return boost::iterator_range<uint8_t*>(ptr, ptr+buffers_[index]->size());\r
        }\r
 \r
-       const boost::iterator_range<const unsigned char*> image_data(size_t index) const\r
+       const boost::iterator_range<const uint8_t*> image_data(size_t index) const\r
        {\r
                if(index >= buffers_.size() || !buffers_[index]->data())\r
-                       return boost::iterator_range<const unsigned char*>();\r
-               auto ptr = static_cast<const unsigned char*>(buffers_[index]->data());\r
-               return boost::iterator_range<const unsigned char*>(ptr, ptr+buffers_[index]->size());\r
+                       return boost::iterator_range<const uint8_t*>();\r
+               auto ptr = static_cast<const uint8_t*>(buffers_[index]->data());\r
+               return boost::iterator_range<const uint8_t*>(ptr, ptr+buffers_[index]->size());\r
        }\r
 \r
        void commit()\r
@@ -81,33 +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]);\r
+               auto buffer = std::move(buffers_[plane_index]); // Release buffer once done.\r
 \r
-               ogl_device::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(int tag, const core::pixel_format_desc& desc, const std::vector<safe_ptr<host_buffer>>& buffers, const std::vector<safe_ptr<device_buffer>>& textures) : impl_(new implementation(tag, desc, buffers, textures)){}\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<unsigned char*> write_frame::image_data(size_t index){return impl_->image_data(index);}\r
-std::vector<short>& write_frame::audio_data() { return impl_->audio_data_; }\r
-const boost::iterator_range<const unsigned char*> write_frame::image_data(size_t index) const\r
+boost::iterator_range<uint8_t*> write_frame::image_data(size_t index){return impl_->image_data(index);}\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 unsigned char*>(impl_->image_data(index).begin(), impl_->image_data(index).end());\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 short*> 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 short*>(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
-int 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