]> git.sesse.net Git - casparcg/blob - accelerator/ogl/write_frame.cpp
2.1.0: ogl: Added secondary host allocation OpenGL thread to reduce blocking time...
[casparcg] / accelerator / ogl / write_frame.cpp
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\r
5 *\r
6 * CasparCG is free software: you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation, either version 3 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * CasparCG is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 * Author: Robert Nagy, ronag89@gmail.com\r
20 */\r
21 \r
22 #include "../stdafx.h"\r
23 \r
24 #include "write_frame.h"\r
25 \r
26 #include "context.h"\r
27 #include "host_buffer.h"\r
28 #include "device_buffer.h"\r
29 \r
30 #include <common/except.h>\r
31 #include <core/frame/frame_visitor.h>\r
32 #include <core/frame/pixel_format.h>\r
33 \r
34 #include <boost/lexical_cast.hpp>\r
35 \r
36 namespace caspar { namespace accelerator { namespace ogl {\r
37                                                                                                                                                                                                                                                                                                                         \r
38 struct write_frame::impl : boost::noncopyable\r
39 {                       \r
40         std::shared_ptr<context>                                                ogl_;\r
41         std::vector<spl::shared_ptr<ogl::host_buffer>>  buffers_;\r
42         core::audio_buffer                                                              audio_data_;\r
43         const core::pixel_format_desc                                   desc_;\r
44         const void*                                                                             tag_;\r
45 \r
46         impl(const void* tag)\r
47                 : desc_(core::pixel_format::invalid)\r
48                 , tag_(tag)             \r
49         {\r
50         }\r
51 \r
52         impl(const spl::shared_ptr<ogl::context>& ogl, const void* tag, const core::pixel_format_desc& desc) \r
53                 : ogl_(ogl)\r
54                 , desc_(desc)\r
55                 , tag_(tag)\r
56         {\r
57                 std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
58                 {\r
59                         return ogl_->create_host_buffer(plane.size, ogl::host_buffer::usage::write_only);\r
60                 });\r
61         }\r
62                         \r
63         void accept(write_frame& self, core::frame_visitor& visitor)\r
64         {\r
65                 visitor.push(self.get_frame_transform());\r
66                 visitor.visit(self);\r
67                 visitor.pop();\r
68         }\r
69 \r
70         boost::iterator_range<uint8_t*> image_data(int index)\r
71         {\r
72                 if(index >= buffers_.size() || !buffers_[index]->data())\r
73                         BOOST_THROW_EXCEPTION(out_of_range());\r
74                 auto ptr = static_cast<uint8_t*>(buffers_[index]->data());\r
75                 return boost::iterator_range<uint8_t*>(ptr, ptr+buffers_[index]->size());\r
76         }\r
77 };\r
78         \r
79 write_frame::write_frame(const void* tag) : impl_(new impl(tag)){}\r
80 write_frame::write_frame(const spl::shared_ptr<ogl::context>& ogl, const void* tag, const core::pixel_format_desc& desc) \r
81         : impl_(new impl(ogl, tag, desc)){}\r
82 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
83 write_frame& write_frame::operator=(write_frame&& other)\r
84 {\r
85         impl_ = std::move(other.impl_);\r
86         return *this;\r
87 }\r
88 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
89 void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
90 const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
91 const boost::iterator_range<const uint8_t*> write_frame::image_data(int index) const{return impl_->image_data(index);}\r
92 const core::audio_buffer& write_frame::audio_data() const{return impl_->audio_data_;}\r
93 const boost::iterator_range<uint8_t*> write_frame::image_data(int index){return impl_->image_data(index);}\r
94 core::audio_buffer& write_frame::audio_data(){return impl_->audio_data_;}\r
95 double write_frame::get_frame_rate() const{return 0.0;} // TODO: what's this?\r
96 int write_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
97 int write_frame::height() const{return impl_->desc_.planes.at(0).height;}                                               \r
98 const void* write_frame::tag() const{return impl_->tag_;}       \r
99 std::vector<spl::shared_ptr<ogl::host_buffer>> write_frame::get_buffers(){return impl_->buffers_;}\r
100 \r
101 }}}