]> git.sesse.net Git - casparcg/blob - core/processor/write_frame.cpp
2.0.0.2
[casparcg] / core / processor / write_frame.cpp
1 #include "../StdAfx.h"\r
2 \r
3 #include "write_frame.h"\r
4 \r
5 #include "draw_frame.h"\r
6 #include "frame_shader.h"\r
7 \r
8 #include "../format/pixel_format.h"\r
9 #include "../../common/gl/utility.h"\r
10 #include "../../common/gl/pixel_buffer_object.h"\r
11 #include "../../common/utility/singleton_pool.h"\r
12 \r
13 #include <boost/range/algorithm.hpp>\r
14 \r
15 namespace caspar { namespace core {\r
16                                                                                                                                                                                                                                                                                                                         \r
17 struct write_frame::implementation : boost::noncopyable\r
18 {\r
19         implementation(const pixel_format_desc& desc) : desc_(desc)\r
20         {\r
21                 CASPAR_LOG(trace) << "Allocated write_frame.";\r
22 \r
23                 static GLenum mapping[] = {GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
24                 std::transform(desc_.planes.begin(), desc_.planes.end(), std::back_inserter(pbos_), [&](const pixel_format_desc::plane& plane)\r
25                 {\r
26                         return gl::pbo(plane.width, plane.height, mapping[plane.channels-1]);\r
27                 });\r
28                 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::map_write));\r
29         }\r
30         \r
31         void unmap()\r
32         {\r
33                 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::unmap_write));\r
34         }\r
35 \r
36         void map()\r
37         {\r
38                 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::map_write));\r
39         }\r
40 \r
41         void draw(frame_shader& shader)\r
42         {\r
43                 for(size_t n = 0; n < pbos_.size(); ++n)\r
44                 {\r
45                         glActiveTexture(GL_TEXTURE0+n);\r
46                         pbos_[n].bind_texture();\r
47                 }\r
48                 shader.render(desc_);\r
49         }\r
50 \r
51         boost::iterator_range<unsigned char*> pixel_data(size_t index)\r
52         {\r
53                 if(index >= pbos_.size() || !pbos_[index].data())\r
54                         return boost::iterator_range<const unsigned char*>();\r
55                 auto ptr = static_cast<unsigned char*>(pbos_[index].data());\r
56                 return boost::iterator_range<unsigned char*>(ptr, ptr+pbos_[index].size());\r
57         }\r
58         const boost::iterator_range<const unsigned char*> pixel_data(size_t index) const\r
59         {\r
60                 if(index >= pbos_.size() || !pbos_[index].data())\r
61                         return boost::iterator_range<const unsigned char*>();\r
62                 auto ptr = static_cast<const unsigned char*>(pbos_[index].data());\r
63                 return boost::iterator_range<const unsigned char*>(ptr, ptr+pbos_[index].size());\r
64         }\r
65                                 \r
66         std::vector<gl::pbo> pbos_;\r
67         std::vector<short> audio_data_;\r
68         const pixel_format_desc desc_;\r
69 };\r
70         \r
71 write_frame::write_frame(const pixel_format_desc& desc) : impl_(singleton_pool<implementation>::make_shared(desc)){}\r
72 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
73 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
74 write_frame& write_frame::operator=(write_frame&& other)\r
75 {\r
76         write_frame temp(std::move(other));\r
77         temp.swap(*this);\r
78         return *this;\r
79 }\r
80 void write_frame::map(){impl_->map();}  \r
81 void write_frame::unmap(){impl_->unmap();}      \r
82 void write_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
83 boost::iterator_range<unsigned char*> write_frame::pixel_data(size_t index){return impl_->pixel_data(index);}\r
84 const boost::iterator_range<const unsigned char*> write_frame::pixel_data(size_t index) const {return impl_->pixel_data(index);}\r
85 std::vector<short>& write_frame::audio_data() { return impl_->audio_data_; }\r
86 const std::vector<short>& write_frame::audio_data() const { return impl_->audio_data_; }\r
87 }}