1 #include "../StdAfx.h"
\r
3 #include "gpu_frame.h"
\r
4 #include "../../common/utility/memory.h"
\r
5 #include "../../common/gl/gl_check.h"
\r
6 #include "../../common/gl/pixel_buffer_object.h"
\r
8 namespace caspar { namespace core {
\r
10 GLubyte progressive_pattern[] = {
\r
11 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
12 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
13 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
14 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
15 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
16 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
17 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
18 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
19 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
20 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
21 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
22 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
23 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
24 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
25 0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff,
\r
26 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
28 GLubyte upper_pattern[] = {
\r
29 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
30 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
31 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
32 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
33 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
34 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
35 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
36 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
37 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
38 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
39 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
40 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
41 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
42 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
43 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
44 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
\r
46 GLubyte lower_pattern[] = {
\r
47 0x00, 0x00, 0x00, 0x00,
\r
48 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
49 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
50 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
51 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
52 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
53 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
54 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
55 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
56 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
57 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
58 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
59 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
60 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
61 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
62 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\r
63 0xff, 0xff, 0xff, 0xff};
\r
65 struct gpu_frame::implementation : boost::noncopyable
\r
67 implementation(size_t width, size_t height)
\r
68 : reading_(false), alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive),
\r
69 texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false), pix_format_(pixel_format::bgra)
\r
72 pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(width, height, GL_BGRA));
\r
73 if(width > 0 && height > 0)
\r
77 implementation(const planar_frame_dimension& data_size)
\r
78 : reading_(false), alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive),
\r
79 texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false), pix_format_(pixel_format::bgra)
\r
81 data_.resize(data_size.size(), 0);
\r
82 for(size_t n = 0; n < data_size.size() && data_size[n].first > 0 && data_size[n].second > 0; ++n)
\r
83 pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(data_size[n].first, data_size[n].second, GL_LUMINANCE));
\r
89 data_ = std::vector<unsigned char*>(4, 0);
\r
90 for(size_t n = 0; n < pbo_.size(); ++n)
\r
91 pbo_[n]->begin_write();
\r
96 for(size_t n = 0; n < pbo_.size(); ++n)
\r
97 data_[n] = static_cast<unsigned char*>(pbo_[n]->end_write());
\r
102 data_ = std::vector<unsigned char*>(4, 0);
\r
103 for(size_t n = 0; n < pbo_.size(); ++n)
\r
104 pbo_[n]->begin_read();
\r
109 for(size_t n = 0; n < pbo_.size(); ++n)
\r
110 data_[n] = static_cast<unsigned char*>(pbo_[n]->end_read());
\r
113 void draw(const gpu_frame_transform_ptr& transform)
\r
115 transform->set_pixel_format(pix_format_);
\r
117 glTranslated(x_*2.0, y_*2.0, 0.0);
\r
118 glColor4d(1.0, 1.0, 1.0, alpha_);
\r
120 if(mode_ == video_mode::progressive)
\r
121 glPolygonStipple(progressive_pattern);
\r
122 else if(mode_ == video_mode::upper)
\r
123 glPolygonStipple(upper_pattern);
\r
124 else if(mode_ == video_mode::lower)
\r
125 glPolygonStipple(lower_pattern);
\r
127 for(size_t n = 0; n < pbo_.size(); ++n)
\r
129 glActiveTexture(GL_TEXTURE0+n);
\r
130 pbo_[n]->bind_texture();
\r
133 glTexCoord2d(texcoords_.left, texcoords_.bottom); glVertex2d(-1.0, -1.0);
\r
134 glTexCoord2d(texcoords_.right, texcoords_.bottom); glVertex2d( 1.0, -1.0);
\r
135 glTexCoord2d(texcoords_.right, texcoords_.top); glVertex2d( 1.0, 1.0);
\r
136 glTexCoord2d(texcoords_.left, texcoords_.top); glVertex2d(-1.0, 1.0);
\r
141 unsigned char* data(size_t index)
\r
143 if(pbo_.size() < index || data_[index] == nullptr)
\r
144 BOOST_THROW_EXCEPTION(invalid_operation());
\r
145 return data_[index];
\r
150 audio_data_.clear();
\r
154 texcoords_ = rectangle(0.0, 1.0, 1.0, 0.0);
\r
155 mode_ = video_mode::progressive;
\r
158 std::vector<common::gl::pixel_buffer_object_ptr> pbo_;
\r
159 std::vector<unsigned char*> data_;
\r
167 std::vector<short> audio_data_;
\r
173 rectangle texcoords_;
\r
174 pixel_format pix_format_;
\r
177 gpu_frame::gpu_frame(size_t width, size_t height)
\r
178 : impl_(new implementation(width, height)){}
\r
179 gpu_frame::gpu_frame(const planar_frame_dimension& data_size)
\r
180 : impl_(new implementation(data_size)){}
\r
181 void gpu_frame::begin_write(){impl_->begin_write();}
\r
182 void gpu_frame::end_write(){impl_->end_write();}
\r
183 void gpu_frame::begin_read(){impl_->begin_read();}
\r
184 void gpu_frame::end_read(){impl_->end_read();}
\r
185 void gpu_frame::draw(const gpu_frame_transform_ptr& transform){impl_->draw(transform);}
\r
186 void gpu_frame::set_pixel_format(pixel_format format) {impl_->pix_format_ = format;}
\r
187 unsigned char* gpu_frame::data(size_t index){return impl_->data(index);}
\r
188 size_t gpu_frame::size(size_t index) const { return impl_->pbo_.at(index)->size(); }
\r
189 size_t gpu_frame::width(size_t index) const { return impl_->pbo_.at(index)->width();}
\r
190 size_t gpu_frame::height(size_t index) const { return impl_->pbo_.at(index)->height();}
\r
191 std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }
\r
192 void gpu_frame::reset(){impl_->reset();}
\r
193 double gpu_frame::alpha() const{ return impl_->alpha_;}
\r
194 void gpu_frame::alpha(double value){ impl_->alpha_ = value;}
\r
195 double gpu_frame::x() const { return impl_->x_;}
\r
196 double gpu_frame::y() const { return impl_->y_;}
\r
197 void gpu_frame::translate(double x, double y) { impl_->x_ += x; impl_->y_ += y; }
\r
198 void gpu_frame::texcoords(const rectangle& texcoords){impl_->texcoords_ = texcoords;}
\r
199 void gpu_frame::mode(video_mode mode){ impl_->mode_ = mode;}
\r
200 video_mode gpu_frame::mode() const{ return impl_->mode_;}
\r