1 #include "../StdAfx.h"
\r
3 #include "gpu_composite_frame.h"
\r
4 #include "../../common/gl/gl_check.h"
\r
5 #include "../../common/utility/memory.h"
\r
7 #include <boost/range/algorithm.hpp>
\r
12 #include <tbb/parallel_for.h>
\r
14 namespace caspar { namespace core {
\r
16 struct gpu_composite_frame::implementation : boost::noncopyable
\r
18 implementation(gpu_composite_frame* self) : self_(self){}
\r
22 boost::range::for_each(frames_, std::mem_fn(&gpu_frame::begin_write));
\r
27 boost::range::for_each(frames_, std::mem_fn(&gpu_frame::end_write));
\r
32 boost::range::for_each(frames_, std::mem_fn(&gpu_frame::begin_read));
\r
37 boost::range::for_each(frames_, std::mem_fn(&gpu_frame::end_read));
\r
43 glTranslated(self_->x()*2.0, self_->y()*2.0, 0.0);
\r
44 boost::range::for_each(frames_, std::mem_fn(&gpu_frame::draw));
\r
48 void add(const gpu_frame_ptr& frame)
\r
50 frames_.push_back(frame);
\r
52 if(self_->audio_data().empty())
\r
53 self_->audio_data() = std::move(frame->audio_data());
\r
58 tbb::blocked_range<size_t>(0, frame->audio_data().size()),
\r
59 [&](const tbb::blocked_range<size_t>& r)
\r
61 for(size_t n = r.begin(); n < r.end(); ++n)
\r
63 self_->audio_data()[n] = static_cast<short>(
\r
64 static_cast<int>(self_->audio_data()[n]) +
\r
65 static_cast<int>(frame->audio_data()[n]) & 0xFFFF);
\r
72 unsigned char* data()
\r
74 BOOST_THROW_EXCEPTION(invalid_operation());
\r
77 gpu_composite_frame* self_;
\r
78 std::vector<gpu_frame_ptr> frames_;
\r
82 #pragma warning (disable : 4355)
\r
84 gpu_composite_frame::gpu_composite_frame()
\r
85 : gpu_frame(0, 0), impl_(new implementation(this)){}
\r
86 void gpu_composite_frame::begin_write(){impl_->begin_write();}
\r
87 void gpu_composite_frame::end_write(){impl_->end_write();}
\r
88 void gpu_composite_frame::begin_read(){impl_->begin_read();}
\r
89 void gpu_composite_frame::end_read(){impl_->end_read();}
\r
90 void gpu_composite_frame::draw(){impl_->draw();}
\r
91 unsigned char* gpu_composite_frame::data(){return impl_->data();}
\r
92 void gpu_composite_frame::add(const gpu_frame_ptr& frame){impl_->add(frame);}
\r
94 gpu_frame_ptr gpu_composite_frame::interlace(const gpu_frame_ptr& frame1,
\r
95 const gpu_frame_ptr& frame2,
\r
98 auto result = std::make_shared<gpu_composite_frame>();
\r
99 result->add(frame1);
\r
100 result->add(frame2);
\r
101 if(mode == video_mode::upper)
\r
103 frame1->mode(video_mode::upper);
\r
104 frame2->mode(video_mode::lower);
\r
108 frame1->mode(video_mode::lower);
\r
109 frame2->mode(video_mode::upper);
\r