]> git.sesse.net Git - casparcg/blob - accelerator/cpu/util/write_frame.cpp
2.1.0: cpu/image_mixer: Added ffmpeg/swscale premultiplied color overflow fixes.
[casparcg] / accelerator / cpu / util / 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 <common/except.h>\r
27 #include <core/frame/frame_visitor.h>\r
28 #include <core/frame/pixel_format.h>\r
29 \r
30 #include <boost/lexical_cast.hpp>\r
31 \r
32 namespace caspar { namespace accelerator { namespace cpu {\r
33                         \r
34 struct write_frame::impl : boost::noncopyable\r
35 {                       \r
36         std::vector<spl::shared_ptr<host_buffer>>       buffers_;\r
37         core::audio_buffer                                                      audio_data_;\r
38         const core::pixel_format_desc                           desc_;\r
39         const void*                                                                     tag_;\r
40 \r
41         impl(const void* tag)\r
42                 : desc_(core::pixel_format::invalid)\r
43                 , tag_(tag)             \r
44         {\r
45         }\r
46 \r
47         impl(const void* tag, const core::pixel_format_desc& desc) \r
48                 : desc_(desc)\r
49                 , tag_(tag)\r
50         {\r
51                 std::transform(desc.planes.begin(), desc.planes.end(), std::back_inserter(buffers_), [&](const core::pixel_format_desc::plane& plane)\r
52                 {\r
53                         return spl::make_shared<host_buffer>(plane.size);\r
54                 });\r
55         }\r
56                         \r
57         void accept(write_frame& self, core::frame_visitor& visitor)\r
58         {\r
59                 visitor.push(self.get_frame_transform());\r
60                 visitor.visit(self);\r
61                 visitor.pop();\r
62         }\r
63 \r
64         boost::iterator_range<uint8_t*> image_data(int index)\r
65         {\r
66                 if(index >= buffers_.size() || !buffers_[index]->data())\r
67                         BOOST_THROW_EXCEPTION(out_of_range());\r
68                 auto ptr = buffers_[index]->data();\r
69                 return boost::iterator_range<uint8_t*>(ptr, ptr+buffers_[index]->size());\r
70         }\r
71 };\r
72         \r
73 write_frame::write_frame(const void* tag) : impl_(new impl(tag)){}\r
74 write_frame::write_frame(const void* tag, const core::pixel_format_desc& desc) \r
75         : impl_(new impl(tag, desc)){}\r
76 write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
77 write_frame& write_frame::operator=(write_frame&& other)\r
78 {\r
79         impl_ = std::move(other.impl_);\r
80         return *this;\r
81 }\r
82 void write_frame::swap(write_frame& other){impl_.swap(other.impl_);}\r
83 void write_frame::accept(core::frame_visitor& visitor){impl_->accept(*this, visitor);}\r
84 const core::pixel_format_desc& write_frame::get_pixel_format_desc() const{return impl_->desc_;}\r
85 const boost::iterator_range<const uint8_t*> write_frame::image_data(int index) const{return impl_->image_data(index);}\r
86 const core::audio_buffer& write_frame::audio_data() const{return impl_->audio_data_;}\r
87 const boost::iterator_range<uint8_t*> write_frame::image_data(int index){return impl_->image_data(index);}\r
88 core::audio_buffer& write_frame::audio_data(){return impl_->audio_data_;}\r
89 double write_frame::get_frame_rate() const{return 0.0;} // TODO: what's this?\r
90 int write_frame::width() const{return impl_->desc_.planes.at(0).width;}\r
91 int write_frame::height() const{return impl_->desc_.planes.at(0).height;}                                               \r
92 const void* write_frame::tag() const{return impl_->tag_;}       \r
93 std::vector<spl::shared_ptr<host_buffer>> write_frame::get_buffers(){return impl_->buffers_;}\r
94 \r
95 }}}