1 #include "../StdAfx.h"
\r
3 #include "write_frame.h"
\r
5 #include "draw_frame.h"
\r
6 #include "frame_shader.h"
\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
13 #include <boost/range/algorithm.hpp>
\r
15 namespace caspar { namespace core {
\r
17 struct write_frame::implementation : boost::noncopyable
\r
19 implementation(const pixel_format_desc& desc) : desc_(desc)
\r
21 CASPAR_LOG(trace) << "Allocated write_frame.";
\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
26 return gl::pbo(plane.width, plane.height, mapping[plane.channels-1]);
\r
28 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::map_write));
\r
33 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::unmap_write));
\r
38 boost::range::for_each(pbos_, std::mem_fn(&gl::pbo::map_write));
\r
41 void draw(frame_shader& shader)
\r
43 for(size_t n = 0; n < pbos_.size(); ++n)
\r
45 glActiveTexture(GL_TEXTURE0+n);
\r
46 pbos_[n].bind_texture();
\r
48 shader.render(desc_);
\r
51 boost::iterator_range<unsigned char*> pixel_data(size_t index)
\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
58 const boost::iterator_range<const unsigned char*> pixel_data(size_t index) const
\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
66 std::vector<gl::pbo> pbos_;
\r
67 std::vector<short> audio_data_;
\r
68 const pixel_format_desc desc_;
\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
76 write_frame temp(std::move(other));
\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