<Filter Include="Source\io">\r
<UniqueIdentifier>{f4b0d63f-3cb3-4ab4-a6b9-3f249204dd3f}</UniqueIdentifier>\r
</Filter>\r
+ <Filter Include="Afx">\r
+ <UniqueIdentifier>{9250809a-3410-418d-95ca-ff2dcb6f0578}</UniqueIdentifier>\r
+ </Filter>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClCompile Include="stdafx.cpp">\r
- <Filter>Source</Filter>\r
- </ClCompile>\r
<ClCompile Include="log\log.cpp">\r
<Filter>Source\log</Filter>\r
</ClCompile>\r
<Filter>Source\exception</Filter>\r
</ClCompile>\r
<ClCompile Include="concurrency\Thread.cpp">\r
- <Filter>Source\concurrency</Filter>\r
+ <Filter>Source\io</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="stdafx.cpp">\r
+ <Filter>Afx</Filter>\r
</ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="stdafx.h">\r
- <Filter>Source</Filter>\r
- </ClInclude>\r
<ClInclude Include="log\log.h">\r
<Filter>Source\log</Filter>\r
</ClInclude>\r
<ClInclude Include="exception\win32_exception.h">\r
<Filter>Source\exception</Filter>\r
</ClInclude>\r
- <ClInclude Include="concurrency\executor.h">\r
- <Filter>Source\concurrency</Filter>\r
- </ClInclude>\r
<ClInclude Include="config.h">\r
<Filter>Source</Filter>\r
</ClInclude>\r
- <ClInclude Include="utility\string_convert.h">\r
- <Filter>Source\utility</Filter>\r
- </ClInclude>\r
<ClInclude Include="gl\utility.h">\r
<Filter>Source\gl</Filter>\r
</ClInclude>\r
<ClInclude Include="compiler\vs\disable_silly_warnings.h">\r
<Filter>Source\compiler\vs</Filter>\r
</ClInclude>\r
- <ClInclude Include="utility\singleton_pool.h">\r
+ <ClInclude Include="concurrency\Thread.h">\r
+ <Filter>Source\io</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="stdafx.h">\r
+ <Filter>Afx</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="concurrency\executor.h">\r
+ <Filter>Source\concurrency</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="utility\string_convert.h">\r
<Filter>Source\utility</Filter>\r
</ClInclude>\r
<ClInclude Include="utility\safe_ptr.h">\r
<Filter>Source\utility</Filter>\r
</ClInclude>\r
- <ClInclude Include="concurrency\Thread.h">\r
- <Filter>Source\concurrency</Filter>\r
+ <ClInclude Include="utility\singleton_pool.h">\r
+ <Filter>Source\utility</Filter>\r
</ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
return draw_frame(frames);\r
}\r
\r
- void load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay)\r
+ void load(int index, const safe_ptr<frame_producer>& producer, bool autoplay)\r
{\r
producer->initialize(processor_device_);\r
executor_.begin_invoke([=]\r
{\r
- auto it = layers_.insert(std::make_pair(render_layer, layer(render_layer))).first;\r
+ auto it = layers_.insert(std::make_pair(index, layer(index))).first;\r
it->second.load(producer, autoplay);\r
});\r
}\r
\r
- void preview(int render_layer, const safe_ptr<frame_producer>& producer)\r
+ void preview(int index, const safe_ptr<frame_producer>& producer)\r
{\r
producer->initialize(processor_device_);\r
executor_.begin_invoke([=]\r
{\r
- auto it = layers_.insert(std::make_pair(render_layer, layer(render_layer))).first;\r
+ auto it = layers_.insert(std::make_pair(index, layer(index))).first;\r
it->second.preview(producer);\r
});\r
}\r
\r
- void pause(int render_layer)\r
+ void pause(int index)\r
{ \r
executor_.begin_invoke([=]\r
{ \r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
if(it != layers_.end())\r
it->second.pause(); \r
});\r
}\r
\r
- void play(int render_layer)\r
+ void play(int index)\r
{ \r
executor_.begin_invoke([=]\r
{\r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
if(it != layers_.end())\r
it->second.play(); \r
});\r
}\r
\r
- void stop(int render_layer)\r
+ void stop(int index)\r
{ \r
executor_.begin_invoke([=]\r
{\r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
if(it != layers_.end()) \r
{\r
it->second.stop(); \r
});\r
}\r
\r
- void clear(int render_layer)\r
+ void clear(int index)\r
{\r
executor_.begin_invoke([=]\r
{ \r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
if(it != layers_.end())\r
{\r
it->second.clear(); \r
});\r
} \r
\r
- boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const\r
+ boost::unique_future<safe_ptr<frame_producer>> foreground(int index) const\r
{\r
return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
{ \r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
return it != layers_.end() ? it->second.foreground() : frame_producer::empty();\r
});\r
}\r
\r
- boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const\r
+ boost::unique_future<safe_ptr<frame_producer>> background(int index) const\r
{\r
return executor_.begin_invoke([=]() -> safe_ptr<frame_producer>\r
{\r
- auto it = layers_.find(render_layer);\r
+ auto it = layers_.find(index);\r
return it != layers_.end() ? it->second.background() : frame_producer::empty();\r
});\r
}\r
channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
channel::channel(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers)\r
: impl_(new implementation(format_desc, consumers)){}\r
-void channel::load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay){impl_->load(render_layer, producer, autoplay);}\r
-void channel::preview(int render_layer, const safe_ptr<frame_producer>& producer){impl_->preview(render_layer, producer);}\r
-void channel::pause(int render_layer){impl_->pause(render_layer);}\r
-void channel::play(int render_layer){impl_->play(render_layer);}\r
-void channel::stop(int render_layer){impl_->stop(render_layer);}\r
-void channel::clear(int render_layer){impl_->clear(render_layer);}\r
+void channel::load(int index, const safe_ptr<frame_producer>& producer, bool autoplay){impl_->load(index, producer, autoplay);}\r
+void channel::preview(int index, const safe_ptr<frame_producer>& producer){impl_->preview(index, producer);}\r
+void channel::pause(int index){impl_->pause(index);}\r
+void channel::play(int index){impl_->play(index);}\r
+void channel::stop(int index){impl_->stop(index);}\r
+void channel::clear(int index){impl_->clear(index);}\r
void channel::clear(){impl_->clear();}\r
-boost::unique_future<safe_ptr<frame_producer>> channel::foreground(int render_layer) const{ return impl_->foreground(render_layer);}\r
-boost::unique_future<safe_ptr<frame_producer>> channel::background(int render_layer) const{return impl_->background(render_layer);}\r
+boost::unique_future<safe_ptr<frame_producer>> channel::foreground(int index) const{ return impl_->foreground(index);}\r
+boost::unique_future<safe_ptr<frame_producer>> channel::background(int index) const{return impl_->background(index);}\r
const video_format_desc& channel::get_video_format_desc() const{ return impl_->format_desc_;}\r
\r
}}
\ No newline at end of file
#include "consumer/frame_consumer.h"\r
#include "producer/frame_producer.h"\r
\r
-#include <boost/noncopyable.hpp>\r
+#include <common/utility/safe_ptr.h>\r
\r
-#include <memory>\r
+#include <boost/noncopyable.hpp>\r
+#include <boost/thread/future.hpp>\r
\r
namespace caspar { namespace core {\r
\r
channel(channel&& other);\r
channel(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
\r
- void load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay = false);\r
- void preview(int render_layer, const safe_ptr<frame_producer>& producer);\r
- void pause(int render_layer);\r
- void play(int render_layer);\r
- void stop(int render_layer);\r
- void clear(int render_layer);\r
+ void load(int index, const safe_ptr<frame_producer>& producer, bool autoplay = false);\r
+ void preview(int index, const safe_ptr<frame_producer>& producer);\r
+ void pause(int index);\r
+ void play(int index);\r
+ void stop(int index);\r
+ void clear(int index);\r
void clear(); \r
- boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const;\r
- boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const;\r
+ boost::unique_future<safe_ptr<frame_producer>> foreground(int index) const;\r
+ boost::unique_future<safe_ptr<frame_producer>> background(int index) const;\r
const video_format_desc& get_video_format_desc() const;\r
private:\r
struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
+ safe_ptr<implementation> impl_;\r
};\r
\r
}}
\ No newline at end of file
\r
struct frame_consumer_device::implementation\r
{\r
- typedef safe_ptr<const read_frame> frame_type;\r
public:\r
implementation(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers) : consumers_(consumers), fmt_(format_desc)\r
{ \r
executor_.start();\r
}\r
\r
- void tick(const frame_type& frame)\r
+ void tick(const safe_ptr<const read_frame>& frame)\r
{\r
buffer_.push_back(frame);\r
\r
buffer_.pop_front();\r
}\r
\r
- void consume(frame_type&& frame)\r
+ void consume(safe_ptr<const read_frame>&& frame)\r
{ \r
if(executor_.size() < 3)\r
executor_.begin_invoke([=]{tick(frame);});\r
public:\r
frame_consumer_device(frame_consumer_device&& other);\r
frame_consumer_device(const video_format_desc& format_desc, const std::vector<safe_ptr<frame_consumer>>& consumers);\r
- void consume(safe_ptr<const read_frame>&& future_frame);\r
+ void consume(safe_ptr<const read_frame>&& future_frame); // nothrow\r
private:\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
<ClInclude Include="consumer\frame_consumer.h" />\r
<ClInclude Include="consumer\oal\oal_consumer.h" />\r
<ClInclude Include="consumer\ogl\ogl_consumer.h" />\r
- <ClInclude Include="format\pixel_format.h" />\r
<ClInclude Include="format\video_format.h" />\r
<ClInclude Include="processor\audio_processor.h" />\r
<ClInclude Include="processor\device_buffer.h" />\r
<ClInclude Include="processor\image_processor.h" />\r
<ClInclude Include="processor\fwd.h" />\r
<ClInclude Include="processor\ogl_device.h" />\r
+ <ClInclude Include="processor\pixel_format.h" />\r
<ClInclude Include="processor\read_frame.h" />\r
<ClInclude Include="processor\draw_frame.h" />\r
<ClInclude Include="processor\write_frame.h" />\r
<Filter Include="Source\channel\producer\image">\r
<UniqueIdentifier>{3d4314f3-8a39-44e3-a0c9-9b833bb8f809}</UniqueIdentifier>\r
</Filter>\r
- <Filter Include="Source\channel\format">\r
- <UniqueIdentifier>{f19ced4f-4ad2-4c0a-b51f-50e89909d669}</UniqueIdentifier>\r
- </Filter>\r
<Filter Include="Source\channel\processor\frame">\r
<UniqueIdentifier>{1b9effc5-16ee-4be7-9189-d2b6bec0165a}</UniqueIdentifier>\r
</Filter>\r
<Filter Include="Source\channel\processor\ogl">\r
<UniqueIdentifier>{219e5733-b365-4231-8c79-fd689c46c488}</UniqueIdentifier>\r
</Filter>\r
+ <Filter Include="Afx">\r
+ <UniqueIdentifier>{a15604fc-d914-48e1-8fd5-ae1edeba9c6c}</UniqueIdentifier>\r
+ </Filter>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClInclude Include="StdAfx.h">\r
- <Filter>Source</Filter>\r
- </ClInclude>\r
<ClInclude Include="protocol\amcp\AMCPCommandQueue.h">\r
<Filter>Source\protocol\amcp</Filter>\r
</ClInclude>\r
<ClInclude Include="processor\frame_processor_device.h">\r
<Filter>Source\channel\processor</Filter>\r
</ClInclude>\r
- <ClInclude Include="format\pixel_format.h">\r
- <Filter>Source\channel\format</Filter>\r
- </ClInclude>\r
- <ClInclude Include="format\video_format.h">\r
- <Filter>Source\channel\format</Filter>\r
- </ClInclude>\r
<ClInclude Include="channel.h">\r
<Filter>Source\channel</Filter>\r
</ClInclude>\r
<ClInclude Include="processor\device_buffer.h">\r
<Filter>Source\channel\processor\ogl</Filter>\r
</ClInclude>\r
+ <ClInclude Include="StdAfx.h">\r
+ <Filter>Afx</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="format\video_format.h">\r
+ <Filter>Source\channel</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="processor\pixel_format.h">\r
+ <Filter>Source\channel\processor</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
- <ClCompile Include="StdAfx.cpp">\r
- <Filter>Source</Filter>\r
- </ClCompile>\r
<ClCompile Include="protocol\amcp\AMCPCommandQueue.cpp">\r
<Filter>Source\protocol\amcp</Filter>\r
</ClCompile>\r
<ClCompile Include="processor\frame_processor_device.cpp">\r
<Filter>Source\channel\processor</Filter>\r
</ClCompile>\r
- <ClCompile Include="format\video_format.cpp">\r
- <Filter>Source\channel\format</Filter>\r
- </ClCompile>\r
<ClCompile Include="channel.cpp">\r
<Filter>Source\channel</Filter>\r
</ClCompile>\r
<ClCompile Include="processor\device_buffer.cpp">\r
<Filter>Source\channel\processor\ogl</Filter>\r
</ClCompile>\r
+ <ClCompile Include="StdAfx.cpp">\r
+ <Filter>Afx</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="format\video_format.cpp">\r
+ <Filter>Source\channel</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<Midl Include="consumer\decklink\DeckLinkAPI_v7_3.idl">\r
+++ /dev/null
-#pragma once\r
-\r
-#include <memory>\r
-#include <vector>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct pixel_format\r
-{\r
- enum type\r
- {\r
- bgra,\r
- rgba,\r
- argb,\r
- abgr,\r
- ycbcr,\r
- ycbcra,\r
- count,\r
- invalid\r
- };\r
-};\r
-\r
-struct pixel_format_desc\r
-{\r
- struct plane\r
- {\r
- plane() : linesize(0), width(0), height(0), size(0), channels(0){}\r
- plane(size_t width, size_t height, size_t channels)\r
- : linesize(width*channels), width(width), height(height), size(width*height*channels), channels(channels)\r
- {}\r
- size_t linesize;\r
- size_t width;\r
- size_t height;\r
- size_t size;\r
- size_t channels;\r
- };\r
-\r
- pixel_format_desc() : pix_fmt(pixel_format::invalid){}\r
- \r
- pixel_format::type pix_fmt;\r
- std::vector<plane> planes;\r
-};\r
- \r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include "gpu_frame.h"\r
-#include "frame_format.h"\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-namespace caspar { namespace core { \r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \struct frame_factory\r
-///\r
-/// \brief Factory interface used to create frames.\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-struct frame_factory\r
-{\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual ~frame_factory()\r
- ///\r
- /// \brief Destructor. \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual ~frame_factory(){}\r
-\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual void release_frames(void* tag) = 0;\r
- ///\r
- /// \brief Releases the frame pool associated with the provided tag. \r
- ///\r
- /// \param tag Tag associated with the source frame pool. \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual void release_frames(void* tag) = 0;\r
-\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual gpu_frame_ptr create_frame(size_t width, size_t height, void* tag) = 0;\r
- ///\r
- /// \brief Creates a frame from a pool associated with the provided tag. \r
- /// Frames are pooled on destruction and need to be released with *release_frames*. \r
- ///\r
- /// \param width The width. \r
- /// \param height The height. \r
- /// \param tag Tag associated with the source frame pool. \r
- ///\r
- /// \return . \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual gpu_frame_ptr create_frame(size_t width, size_t height, void* tag) = 0;\r
-\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn virtual gpu_frame_ptr create_frame(const gpu_frame_desc& desc, void* tag) = 0;\r
- ///\r
- /// \brief Creates a frame from a pool associated with the provided tag. \r
- /// Frames are pooled on destruction and need to be released with *release_frames*. \r
- ///\r
- /// \param desc Information describing the frame. \r
- /// \param tag Tag associated with the source frame pool. \r
- ///\r
- /// \return . \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- virtual gpu_frame_ptr create_frame(const gpu_frame_desc& desc, void* tag) = 0;\r
-\r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- /// \fn gpu_frame_ptr create_frame(const frame_format_desc format_desc, void* tag)\r
- ///\r
- /// \brief Creates a frame from a pool associated with the provided tag. \r
- /// Frames are pooled on destruction and need to be released with *release_frames*. \r
- ///\r
- /// \param format_desc Information describing the frame format. \r
- /// \param tag Tag associated with the source frame pool. \r
- ///\r
- /// \return . \r
- ////////////////////////////////////////////////////////////////////////////////////////////////////\r
- gpu_frame_ptr create_frame(const frame_format_desc format_desc, void* tag)\r
- {\r
- return create_frame(format_desc.width, format_desc.height, tag);\r
- }\r
-};\r
-\r
-typedef std::shared_ptr<frame_factory> frame_factory_ptr;\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG.\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
- \r
-#include "..\StdAfx.h"\r
-\r
-#include "frame_format.h"\r
-\r
-#include <boost/algorithm/string.hpp>\r
-\r
-#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s, fmt) { (w), (h), (m), (f), (w)*(h)*4, s, (fmt) }\r
-\r
-namespace caspar { namespace core {\r
-\r
-const frame_format_desc frame_format_desc::format_descs[frame_format::count] = \r
-{ \r
- DEFINE_VIDEOFORMATDESC(720, 576, video_mode::upper, 50, TEXT("PAL"), frame_format::pal), \r
- DEFINE_VIDEOFORMATDESC(720, 486, video_mode::lower, 60/1.001, TEXT("NTSC"), frame_format::ntsc), \r
- DEFINE_VIDEOFORMATDESC(720, 576, video_mode::progressive, 25, TEXT("576p2500"), frame_format::x576p2500),\r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 25, TEXT("720p2500"), frame_format::x720p2500), \r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 50, TEXT("720p5000"), frame_format::x720p5000), \r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60/1.001, TEXT("720p5994"), frame_format::x720p5994),\r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_mode::progressive, 60, TEXT("720p6000"), frame_format::x720p6000),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24/1.001, TEXT("1080p2397"), frame_format::x1080p2397),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 24, TEXT("1080p2400"), frame_format::x1080p2400),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 50, TEXT("1080i5000"), frame_format::x1080i5000),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60/1.001, TEXT("1080i5994"), frame_format::x1080i5994),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::upper, 60, TEXT("1080i6000"), frame_format::x1080i6000),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 25, TEXT("1080p2500"), frame_format::x1080p2500),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_mode::progressive, 30/1.001, TEXT("1080p2997"), frame_format::x1080p2997),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080,video_mode:: progressive, 30, TEXT("1080p3000"), frame_format::x1080p3000)\r
-};\r
-\r
-frame_format get_video_format(const std::wstring& name)\r
-{\r
- for(int n = 0; n < frame_format::count; ++n)\r
- {\r
- if(boost::iequals(frame_format_desc::format_descs[n].name, name))\r
- return static_cast<frame_format>(n);\r
- }\r
-\r
- return frame_format::invalid;\r
-}\r
-\r
-}}\r
-\r
+++ /dev/null
-#pragma once\r
-\r
-#include <string>\r
-\r
-#include "../../common/compiler/vs/disable_silly_warnings.h"\r
-\r
-namespace caspar { namespace core {\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \enum video_mode\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-enum video_mode\r
-{\r
- progressive,\r
- lower,\r
- upper\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \enum frame_format\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-enum frame_format\r
-{\r
- pal = 0,\r
- ntsc,\r
- x576p2500,\r
- x720p2500,\r
- x720p5000,\r
- x720p5994,\r
- x720p6000,\r
- x1080p2397,\r
- x1080p2400,\r
- x1080i5000,\r
- x1080i5994,\r
- x1080i6000,\r
- x1080p2500,\r
- x1080p2997,\r
- x1080p3000,\r
- count,\r
- invalid\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \struct frame_format_desc\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-struct frame_format_desc\r
-{\r
- size_t width;\r
- size_t height;\r
- video_mode mode;\r
- double fps;\r
- size_t size;\r
- std::wstring name;\r
- frame_format format;\r
-\r
- static const frame_format_desc format_descs[frame_format::count];\r
-};\r
-\r
-inline bool operator==(const frame_format_desc& rhs, const frame_format_desc& lhs)\r
-{\r
- return rhs.format == lhs.format;\r
-}\r
-\r
-inline bool operator!=(const frame_format_desc& rhs, const frame_format_desc& lhs)\r
-{\r
- return !(rhs == lhs);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \fn frame_format get_video_format(const std::wstring& strVideoMode);\r
-///\r
-/// \brief Gets the *frame_format* associated with the specified name.\r
-///\r
-/// \param name Name of the *frame_format*.. \r
-///\r
-/// \return The video format. \r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-frame_format get_video_format(const std::wstring& name);\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \fn frame_format get_video_format_desc(const std::wstring& strVideoMode);\r
-///\r
-/// \brief Gets the *frame_format_desc* associated with the specified name.\r
-///\r
-/// \param name Name of the *frame_format_desc*.. \r
-///\r
-/// \return The video format. \r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-inline frame_format_desc get_video_format_desc(const std::wstring& name, frame_format default_format = frame_format::x576p2500)\r
-{ \r
- auto casparVideoFormat = default_format;\r
- if(!name.empty())\r
- casparVideoFormat = get_video_format(name);\r
- return frame_format_desc::format_descs[casparVideoFormat];\r
-}\r
-\r
-inline double render_frame_format_period(const frame_format_desc& format_desc)\r
-{\r
- return 1.0/(format_desc.mode == video_mode::progressive ? format_desc.fps : format_desc.fps/2.0);\r
-}\r
-\r
-inline std::wostream& operator<<(std::wostream& out, const frame_format_desc& format_desc)\r
-{\r
- out << format_desc.name.c_str();\r
- return out;\r
-}\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include <memory>\r
-\r
-namespace caspar { namespace core {\r
- \r
-class gpu_frame;\r
-typedef std::shared_ptr<gpu_frame> gpu_frame_ptr;\r
-\r
-struct frame_factory;\r
-typedef std::shared_ptr<frame_factory> frame_factory_ptr;\r
-\r
-struct frame_format_desc;\r
- \r
-struct sound_channel_info;\r
-typedef std::shared_ptr<sound_channel_info> sound_channel_info_ptr;\r
-typedef std::unique_ptr<sound_channel_info> sound_channel_info_uptr;\r
-\r
-class audio_chunk;\r
-typedef std::shared_ptr<audio_chunk> audio_chunk_ptr;\r
-typedef std::unique_ptr<audio_chunk> audio_chunk_uptr;\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#include "../StdAfx.h"\r
-\r
-#include "gpu_composite_frame.h"\r
-#include "../../common/gl/utility.h"\r
-#include "../../common/utility/memory.h"\r
-\r
-#include <boost/range/algorithm.hpp>\r
-\r
-#include <algorithm>\r
-#include <numeric>\r
-\r
-#include <tbb/parallel_for.h>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct gpu_composite_frame::implementation : boost::noncopyable\r
-{\r
- implementation(gpu_composite_frame* self) : self_(self){}\r
-\r
- void begin_write()\r
- {\r
- boost::range::for_each(frames_, std::mem_fn(&gpu_frame::begin_write)); \r
- }\r
-\r
- void end_write()\r
- {\r
- boost::range::for_each(frames_, std::mem_fn(&gpu_frame::end_write)); \r
- }\r
- \r
- void begin_read()\r
- { \r
- boost::range::for_each(frames_, std::mem_fn(&gpu_frame::begin_read)); \r
- }\r
-\r
- void end_read()\r
- {\r
- boost::range::for_each(frames_, std::mem_fn(&gpu_frame::end_read)); \r
- }\r
-\r
- void draw(const gpu_frame_shader_ptr& shader)\r
- {\r
- glPushMatrix();\r
- glTranslated(self_->x()*2.0, self_->y()*2.0, 0.0);\r
- boost::range::for_each(frames_, std::bind(&gpu_frame::draw, std::placeholders::_1, shader));\r
- glPopMatrix();\r
- }\r
- \r
- void add(const gpu_frame_ptr& frame)\r
- {\r
- if(frame == nullptr || frame == gpu_frame::null())\r
- return;\r
-\r
- frames_.push_back(frame);\r
-\r
- if(self_->audio_data().empty())\r
- self_->audio_data() = std::move(frame->audio_data());\r
- else\r
- {\r
- tbb::parallel_for\r
- (\r
- tbb::blocked_range<size_t>(0, frame->audio_data().size()),\r
- [&](const tbb::blocked_range<size_t>& r)\r
- {\r
- for(size_t n = r.begin(); n < r.end(); ++n)\r
- {\r
- self_->audio_data()[n] = static_cast<short>(\r
- static_cast<int>(self_->audio_data()[n]) + \r
- static_cast<int>(frame->audio_data()[n]) & 0xFFFF); \r
- }\r
- }\r
- );\r
- }\r
- }\r
-\r
- unsigned char* data(size_t)\r
- {\r
- BOOST_THROW_EXCEPTION(invalid_operation());\r
- }\r
-\r
- gpu_composite_frame* self_;\r
- std::vector<gpu_frame_ptr> frames_;\r
- size_t size_;\r
-};\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (disable : 4355) // 'this' : used in base member initializer list\r
-#endif\r
-\r
-gpu_composite_frame::gpu_composite_frame() \r
- : gpu_frame(0, 0), impl_(new implementation(this)){}\r
-void gpu_composite_frame::begin_write(){impl_->begin_write();}\r
-void gpu_composite_frame::end_write(){impl_->end_write();} \r
-void gpu_composite_frame::begin_read(){impl_->begin_read();}\r
-void gpu_composite_frame::end_read(){impl_->end_read();}\r
-void gpu_composite_frame::draw(const gpu_frame_shader_ptr& shader){impl_->draw(shader);}\r
-unsigned char* gpu_composite_frame::data(size_t index){return impl_->data(index);}\r
-void gpu_composite_frame::add(const gpu_frame_ptr& frame){impl_->add(frame);}\r
-\r
-gpu_frame_ptr gpu_composite_frame::interlace(const gpu_frame_ptr& frame1,\r
- const gpu_frame_ptr& frame2, \r
- video_mode mode)\r
-{ \r
- auto result = std::make_shared<gpu_composite_frame>();\r
- result->add(frame1);\r
- result->add(frame2);\r
- if(mode == video_mode::upper)\r
- {\r
- frame1->mode(video_mode::upper);\r
- frame2->mode(video_mode::lower);\r
- }\r
- else\r
- {\r
- frame1->mode(video_mode::lower);\r
- frame2->mode(video_mode::upper);\r
- }\r
- return result;\r
-}\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include <memory>\r
-\r
-#include <Glee.h>\r
-\r
-#include "gpu_frame.h"\r
-\r
-namespace caspar { namespace core {\r
- \r
-class gpu_composite_frame : public gpu_frame\r
-{\r
-public:\r
- gpu_composite_frame();\r
- \r
- void add(const gpu_frame_ptr& frame);\r
-\r
- static gpu_frame_ptr interlace(const gpu_frame_ptr& frame1,\r
- const gpu_frame_ptr& frame2, video_mode mode);\r
- \r
-private:\r
- virtual unsigned char* data(size_t index);\r
- virtual void begin_write();\r
- virtual void end_write();\r
- virtual void begin_read();\r
- virtual void end_read();\r
- virtual void draw(const gpu_frame_shader_ptr& shader);\r
-\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<gpu_composite_frame> gpu_composite_frame_ptr;\r
- \r
-}}
\ No newline at end of file
+++ /dev/null
-#include "../StdAfx.h"\r
-\r
-#include "gpu_frame.h"\r
-#include "gpu_frame_desc.h"\r
-#include "../../common/utility/memory.h"\r
-#include "../../common/gl/utility.h"\r
-#include "../../common/gl/pixel_buffer_object.h"\r
-\r
-#include <boost/range/algorithm.hpp>\r
-\r
-namespace caspar { namespace core {\r
- \r
-GLubyte progressive_pattern[] = {\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
- \r
-GLubyte upper_pattern[] = {\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
- \r
-GLubyte lower_pattern[] = {\r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
- \r
-struct gpu_frame::implementation : boost::noncopyable\r
-{\r
- implementation(size_t width, size_t height)\r
- : alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive), texcoords_(0.0, 1.0, 1.0, 0.0)\r
- { \r
- desc_.planes[0] = plane(width, height, 4);\r
- desc_.plane_count = 1;\r
- desc_.pix_fmt = pixel_format::bgra;\r
- if(width >= 2 && height >= 2)\r
- {\r
- pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(width, height, GL_BGRA));\r
- pixel_data_.resize(pbo_.size(), 0);\r
- end_write();\r
- }\r
- }\r
-\r
- implementation(const gpu_frame_desc& desc)\r
- : alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive), texcoords_(0.0, 1.0, 1.0, 0.0)\r
- { \r
- desc_ = desc;\r
-\r
- for(size_t n = 0; n < desc_.plane_count; ++n)\r
- {\r
- GLuint format = [&]() -> GLuint\r
- {\r
- switch(desc_.planes[n].channels)\r
- {\r
- case 1: return GL_LUMINANCE;\r
- case 2: return GL_LUMINANCE_ALPHA;\r
- case 3: return GL_BGR;\r
- case 4: return GL_BGRA;\r
- default: BOOST_THROW_EXCEPTION(out_of_range() << msg_info("1-4 channels are supported") << arg_name_info("desc.planes.channels")); \r
- }\r
- }();\r
-\r
- pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(desc_.planes[n].width, desc_.planes[n].height, format));\r
- }\r
- pixel_data_.resize(pbo_.size(), 0);\r
- end_write();\r
- }\r
- \r
- void begin_write()\r
- {\r
- pixel_data_ = std::vector<void*>(4, 0);\r
- boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_write));\r
- }\r
-\r
- void end_write()\r
- {\r
- boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_write));\r
- }\r
- \r
- void begin_read()\r
- { \r
- pixel_data_ = std::vector<void*>(4, 0);\r
- boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_read));\r
- }\r
-\r
- void end_read()\r
- {\r
- boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_read));\r
- }\r
-\r
- void draw(const gpu_frame_shader_ptr& shader)\r
- {\r
- shader->use(desc_);\r
- glPushMatrix();\r
- glTranslated(x_*2.0, y_*2.0, 0.0);\r
- glColor4d(1.0, 1.0, 1.0, alpha_);\r
-\r
- if(mode_ == video_mode::progressive)\r
- glPolygonStipple(progressive_pattern);\r
- else if(mode_ == video_mode::upper)\r
- glPolygonStipple(upper_pattern);\r
- else if(mode_ == video_mode::lower)\r
- glPolygonStipple(lower_pattern);\r
-\r
- for(size_t n = 0; n < pbo_.size(); ++n)\r
- {\r
- glActiveTexture(GL_TEXTURE0+n);\r
- pbo_[n]->bind_texture();\r
- }\r
- glBegin(GL_QUADS);\r
- glTexCoord2d(texcoords_.left, texcoords_.bottom); glVertex2d(-1.0, -1.0);\r
- glTexCoord2d(texcoords_.right, texcoords_.bottom); glVertex2d( 1.0, -1.0);\r
- glTexCoord2d(texcoords_.right, texcoords_.top); glVertex2d( 1.0, 1.0);\r
- glTexCoord2d(texcoords_.left, texcoords_.top); glVertex2d(-1.0, 1.0);\r
- glEnd();\r
- glPopMatrix();\r
- }\r
-\r
- unsigned char* data(size_t index)\r
- {\r
- if(pbo_.size() < index)\r
- BOOST_THROW_EXCEPTION(out_of_range());\r
- return static_cast<unsigned char*>(pixel_data_[index]);\r
- }\r
-\r
- void reset()\r
- {\r
- audio_data_.clear();\r
- alpha_ = 1.0f;\r
- x_ = 0.0f;\r
- y_ = 0.0f;\r
- texcoords_ = rectangle(0.0, 1.0, 1.0, 0.0);\r
- mode_ = video_mode::progressive;\r
- }\r
-\r
- std::vector<common::gl::pixel_buffer_object_ptr> pbo_;\r
- std::vector<void*> pixel_data_; \r
- std::vector<short> audio_data_;\r
-\r
- double alpha_;\r
- double x_;\r
- double y_;\r
- video_mode mode_;\r
- rectangle texcoords_;\r
-\r
- gpu_frame_desc desc_;\r
-};\r
-\r
-gpu_frame::gpu_frame(size_t width, size_t height) \r
- : impl_(new implementation(width, height)){}\r
-gpu_frame::gpu_frame(const gpu_frame_desc& desc)\r
- : impl_(new implementation(desc)){}\r
-void gpu_frame::draw(const gpu_frame_shader_ptr& shader){impl_->draw(shader);}\r
-void gpu_frame::begin_write(){impl_->begin_write();}\r
-void gpu_frame::end_write(){impl_->end_write();} \r
-void gpu_frame::begin_read(){impl_->begin_read();}\r
-void gpu_frame::end_read(){impl_->end_read();}\r
-void gpu_frame::pix_fmt(pixel_format format) {impl_->desc_.pix_fmt = format;}\r
-unsigned char* gpu_frame::data(size_t index){return impl_->data(index);}\r
-size_t gpu_frame::size(size_t index) const { return impl_->desc_.planes[index].size; }\r
-std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }\r
-void gpu_frame::reset(){impl_->reset();}\r
-void gpu_frame::alpha(double value){ impl_->alpha_ = value;}\r
-void gpu_frame::translate(double x, double y) { impl_->x_ += x; impl_->y_ += y; }\r
-void gpu_frame::texcoords(const rectangle& texcoords){impl_->texcoords_ = texcoords;}\r
-void gpu_frame::mode(video_mode mode){ impl_->mode_ = mode;}\r
-double gpu_frame::x() const { return impl_->x_;}\r
-double gpu_frame::y() const { return impl_->y_;}\r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include "frame_format.h"\r
-\r
-#include "gpu_frame_shader.h"\r
-#include "gpu_frame_desc.h"\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-#include <boost/noncopyable.hpp>\r
-\r
-#include <Glee.h>\r
-\r
-#include <boost/tuple/tuple.hpp>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct rectangle\r
-{\r
- rectangle(double left, double top, double right, double bottom)\r
- : left(left), top(top), right(right), bottom(bottom)\r
- {}\r
- double left;\r
- double top;\r
- double right;\r
- double bottom;\r
-};\r
-\r
-class gpu_frame : boost::noncopyable\r
-{\r
-public:\r
- virtual ~gpu_frame(){}\r
- \r
- virtual unsigned char* data(size_t index = 0);\r
- virtual size_t size(size_t index = 0) const;\r
- \r
- virtual std::vector<short>& audio_data();\r
-\r
- virtual void alpha(double value);\r
- virtual void translate(double x, double y);\r
- virtual void texcoords(const rectangle& texcoords);\r
- virtual void mode(video_mode mode); \r
- virtual void pix_fmt(pixel_format format);\r
- \r
- virtual double x() const;\r
- virtual double y() const;\r
-\r
- static std::shared_ptr<gpu_frame> null()\r
- {\r
- static auto my_null_frame = std::shared_ptr<gpu_frame>(new gpu_frame(0,0));\r
- return my_null_frame;\r
- }\r
- \r
- virtual void begin_write();\r
- virtual void end_write();\r
- virtual void begin_read();\r
- virtual void end_read();\r
- virtual void draw(const gpu_frame_shader_ptr& shader);\r
-\r
-protected:\r
- gpu_frame(size_t width, size_t height);\r
- gpu_frame(const gpu_frame_desc& desc);\r
-\r
- friend class gpu_frame_device;\r
-\r
- virtual void reset();\r
-\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<gpu_frame> gpu_frame_ptr;\r
- \r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-enum pixel_format\r
-{\r
- invalid_pixel_format = 0,\r
- bgra,\r
- rgba,\r
- argb,\r
- abgr,\r
- ycbcr,\r
- ycbcra,\r
- pixel_format_count,\r
-};\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct plane\r
-{\r
- plane(){}\r
- plane(size_t width, size_t height, size_t channels)\r
- : width(width), height(height), size(width*height*channels), channels(channels)\r
- {}\r
- size_t width;\r
- size_t height;\r
- size_t size;\r
- size_t channels;\r
-};\r
-\r
-struct gpu_frame_desc\r
-{\r
- gpu_frame_desc(){memset(this, sizeof(gpu_frame_desc), 0);}\r
- pixel_format pix_fmt;\r
- std::array<plane, 4> planes;\r
- size_t plane_count;\r
-};\r
- \r
-}}
\ No newline at end of file
+++ /dev/null
-#include "../StdAfx.h"\r
-\r
-#include "gpu_frame_device.h"\r
-\r
-#include "gpu_frame_renderer.h"\r
-#include "gpu_frame.h"\r
-#include "gpu_composite_frame.h"\r
-\r
-#include "frame_format.h"\r
-\r
-#include "../../common/exception/exceptions.h"\r
-#include "../../common/concurrency/executor.h"\r
-#include "../../common/gl/utility.h"\r
-\r
-#include <Glee.h>\r
-#include <SFML/Window.hpp>\r
-\r
-#include <tbb/concurrent_queue.h>\r
-#include <tbb/concurrent_unordered_map.h>\r
-\r
-#include <boost/thread.hpp>\r
-#include <boost/range/algorithm.hpp>\r
-\r
-#include <functional>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct gpu_frame_device::implementation : boost::noncopyable\r
-{ \r
- implementation(gpu_frame_device* self, const frame_format_desc& format_desc) \r
- { \r
- input_.set_capacity(2);\r
- executor_.start();\r
- executor_.invoke([=]\r
- {\r
- ogl_context_.reset(new sf::Context());\r
- ogl_context_->SetActive(true);\r
- GL(glEnable(GL_POLYGON_STIPPLE));\r
- GL(glEnable(GL_TEXTURE_2D));\r
- GL(glEnable(GL_BLEND));\r
- GL(glDisable(GL_DEPTH_TEST));\r
- GL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); \r
- GL(glClearColor(0.0, 0.0, 0.0, 0.0));\r
- GL(glViewport(0, 0, format_desc.width, format_desc.height));\r
- glLoadIdentity(); \r
-\r
- renderer_ = std::make_shared<gpu_frame_renderer>(*self, format_desc);\r
- });\r
- }\r
-\r
- ~implementation()\r
- {\r
- executor_.stop();\r
- }\r
- \r
- void push(const std::vector<gpu_frame_ptr>& frames)\r
- {\r
- auto composite_frame = std::make_shared<gpu_composite_frame>();\r
- boost::range::for_each(frames, std::bind(&gpu_composite_frame::add, composite_frame, std::placeholders::_1));\r
-\r
- input_.push(composite_frame);\r
- executor_.begin_invoke([=]\r
- {\r
- try\r
- {\r
- gpu_frame_ptr frame;\r
- input_.pop(frame);\r
- output_.push(renderer_->render(frame));\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- }\r
- }); \r
- }\r
- \r
- gpu_frame_ptr pop()\r
- {\r
- gpu_frame_ptr frame;\r
- output_.pop(frame);\r
- return frame;\r
- }\r
- \r
- gpu_frame_ptr do_create_frame(size_t key, const std::function<gpu_frame*()>& constructor)\r
- {\r
- auto& pool = writing_pools_[key];\r
- \r
- gpu_frame_ptr frame;\r
- if(!pool.try_pop(frame))\r
- {\r
- frame = executor_.invoke([&]\r
- {\r
- return std::shared_ptr<gpu_frame>(constructor());\r
- });\r
- }\r
- \r
- auto destructor = [=]\r
- {\r
- frame->reset();\r
- writing_pools_[key].push(frame);\r
- };\r
-\r
- return gpu_frame_ptr(frame.get(), [=](gpu_frame*) \r
- {\r
- executor_.begin_invoke(destructor);\r
- });\r
- }\r
-\r
- gpu_frame_ptr create_frame(size_t width, size_t height, void* tag)\r
- {\r
- return do_create_frame(reinterpret_cast<size_t>(tag), [&]\r
- {\r
- return new gpu_frame(width, height);\r
- });\r
- }\r
- \r
- gpu_frame_ptr create_frame(const gpu_frame_desc& desc, void* tag)\r
- {\r
- return do_create_frame(reinterpret_cast<size_t>(tag), [&]\r
- {\r
- return new gpu_frame(desc);\r
- });\r
- }\r
-\r
- void release_frames(void* tag)\r
- {\r
- writing_pools_[reinterpret_cast<size_t>(tag)].clear();\r
- }\r
- \r
- typedef tbb::concurrent_bounded_queue<gpu_frame_ptr> gpu_frame_queue;\r
- tbb::concurrent_unordered_map<size_t, gpu_frame_queue> writing_pools_;\r
- gpu_frame_queue reading_pool_; \r
-\r
- gpu_frame_queue input_;\r
- gpu_frame_queue output_; \r
- \r
- std::unique_ptr<sf::Context> ogl_context_;\r
- \r
- common::executor executor_;\r
-\r
- gpu_frame_renderer_ptr renderer_;\r
-};\r
- \r
-#if defined(_MSC_VER)\r
-#pragma warning (disable : 4355) // 'this' : used in base member initializer list\r
-#endif\r
-\r
-gpu_frame_device::gpu_frame_device(const frame_format_desc& format_desc) : impl_(new implementation(this, format_desc)){}\r
-void gpu_frame_device::push(const std::vector<gpu_frame_ptr>& frames){ impl_->push(frames);}\r
-gpu_frame_ptr gpu_frame_device::pop(){return impl_->pop();}\r
-gpu_frame_ptr gpu_frame_device::create_frame(size_t width, size_t height, void* tag){return impl_->create_frame(width, height, tag);}\r
-gpu_frame_ptr gpu_frame_device::create_frame(const gpu_frame_desc& desc, void* tag){return impl_->create_frame(desc, tag);}\r
-void gpu_frame_device::release_frames(void* tag){impl_->release_frames(tag);}\r
-}}
\ No newline at end of file
+++ /dev/null
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG.\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#pragma once\r
-\r
-#include <memory>\r
-#include <vector>\r
-\r
-#include "frame_fwd.h"\r
-#include "frame_factory.h"\r
-\r
-namespace caspar { namespace core {\r
-\r
-class gpu_frame_device : public frame_factory, boost::noncopyable\r
-{\r
-public:\r
- gpu_frame_device(const frame_format_desc& format_desc);\r
- \r
- void push(const std::vector<gpu_frame_ptr>& frames);\r
- gpu_frame_ptr pop();\r
- \r
- void release_frames(void* tag);\r
- gpu_frame_ptr create_frame(size_t width, size_t height, void* tag);\r
- gpu_frame_ptr create_frame(const gpu_frame_desc& desc, void* tag);\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<gpu_frame_device> gpu_frame_device_ptr;\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#include "../StdAfx.h"\r
-\r
-#include "gpu_frame_renderer.h"\r
-\r
-#include "gpu_frame.h"\r
-\r
-#include "frame_format.h"\r
-#include "frame_factory.h"\r
-\r
-#include "../../common/exception/exceptions.h"\r
-#include "../../common/gl/utility.h"\r
-#include "../../common/gl/frame_buffer_object.h"\r
-\r
-#include <Glee.h>\r
-\r
-#include <tbb/concurrent_queue.h>\r
-\r
-#include <boost/range/algorithm_ext/erase.hpp>\r
-#include <boost/range/algorithm.hpp>\r
-\r
-#include <functional>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct gpu_frame_renderer::implementation : boost::noncopyable\r
-{ \r
- implementation(frame_factory& factory, const frame_format_desc& format_desc) \r
- : factory_(factory), format_desc_(format_desc), index_(0), shader_(std::make_shared<gpu_frame_shader>(format_desc)), \r
- writing_(2, gpu_frame::null()), output_frame_(gpu_frame::null())\r
- { \r
- fbo_.create(format_desc_.width, format_desc_.height);\r
- fbo_.bind_pixel_source();\r
- }\r
- \r
- gpu_frame_ptr render(const gpu_frame_ptr& frame)\r
- {\r
- gpu_frame_ptr result;\r
- try\r
- {\r
- index_ = (index_ + 1) % 2;\r
- int next_index = (index_ + 1) % 2;\r
-\r
- // 1. Start asynchronous DMA transfer to video memory.\r
- writing_[index_] = std::move(frame); \r
- // Lock frame and give pointer ownership to OpenGL.\r
- writing_[index_]->begin_write();\r
- \r
- // 3. Output to external buffer.\r
- output_frame_->end_read();\r
- result = output_frame_;\r
- \r
- // Clear framebuffer.\r
- GL(glClear(GL_COLOR_BUFFER_BIT)); \r
-\r
- // 2. Draw to framebuffer and start asynchronous DMA transfer \r
- // to page-locked memory.\r
- writing_[next_index]->draw(shader_);\r
- \r
- // Create an output frame\r
- auto temp_frame = factory_.create_frame(format_desc_, this);\r
- \r
- // Read from framebuffer into page-locked memory.\r
- temp_frame->begin_read();\r
- temp_frame->audio_data() = std::move(writing_[next_index]->audio_data());\r
-\r
- output_frame_ = temp_frame;\r
-\r
- // Return frames to pool.\r
- writing_[next_index]->end_write();\r
- writing_[next_index] = nullptr;\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- }\r
- return result == gpu_frame::null() ? nullptr : result;;\r
- }\r
-\r
- size_t index_;\r
-\r
- gpu_frame_ptr output_frame_; \r
- frame_format_desc format_desc_;\r
- frame_factory& factory_;\r
-\r
- std::vector<gpu_frame_ptr> writing_;\r
- \r
- common::gl::frame_buffer_object fbo_;\r
- gpu_frame_shader_ptr shader_;\r
-};\r
- \r
-gpu_frame_renderer::gpu_frame_renderer(frame_factory& factory, const frame_format_desc& format_desc) : impl_(new implementation(factory, format_desc)){}\r
-gpu_frame_ptr gpu_frame_renderer::render(const gpu_frame_ptr& frames){ return impl_->render(frames);}\r
-}}
\ No newline at end of file
+++ /dev/null
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG.\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#pragma once\r
-\r
-#include <memory>\r
-#include <vector>\r
-\r
-#include "frame_fwd.h"\r
-\r
-namespace caspar { namespace core {\r
-\r
-class gpu_frame_renderer : boost::noncopyable\r
-{\r
-public:\r
- gpu_frame_renderer(frame_factory& factory, const frame_format_desc& format_desc_);\r
- \r
- gpu_frame_ptr render(const gpu_frame_ptr& frames);\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<gpu_frame_renderer> gpu_frame_renderer_ptr;\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#include "../StdAfx.h"\r
-\r
-#include "gpu_frame_shader.h"\r
-\r
-#include "../../common/exception/exceptions.h"\r
-#include "../../common/gl/utility.h"\r
-\r
-#include <Glee.h>\r
-\r
-#include <boost/noncopyable.hpp>\r
-\r
-#include <unordered_map>\r
-\r
-namespace caspar { namespace core {\r
- \r
-class shader_program : boost::noncopyable\r
-{\r
-public:\r
- shader_program() : program_(0){}\r
- shader_program(shader_program&& other) : program_(other.program_){}\r
- shader_program& operator=(shader_program&& other) \r
- {\r
- program_ = other.program_; \r
- other.program_ = 0; \r
- return *this;\r
- }\r
-\r
- shader_program(const std::string& fragment_source_str) : program_(0)\r
- {\r
- GLint success;\r
-\r
- try\r
- { \r
- const char* fragment_source = fragment_source_str.c_str();\r
- static const char* vertex_source = \r
- "void main()"\r
- "{"\r
- "gl_TexCoord[0] = gl_MultiTexCoord0;"\r
- "gl_FrontColor = gl_Color;"\r
- "gl_Position = ftransform();"\r
- "}";\r
- \r
- auto vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);\r
- auto fragmemt_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);\r
-\r
- GL(glShaderSourceARB(vertex_shader, 1, &vertex_source, NULL));\r
- GL(glCompileShaderARB(vertex_shader));\r
-\r
- GL(glGetObjectParameterivARB(vertex_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
- if (success == GL_FALSE)\r
- {\r
- char info[2048];\r
- GL(glGetInfoLogARB(vertex_shader, sizeof(info), 0, info));\r
- GL(glDeleteObjectARB(vertex_shader));\r
- GL(glDeleteObjectARB(fragmemt_shader));\r
- GL(glDeleteObjectARB(program_));\r
- std::stringstream str;\r
- str << "Failed to compile vertex shader:" << std::endl << info << std::endl;\r
- BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
- }\r
-\r
- GL(glShaderSourceARB(fragmemt_shader, 1, &fragment_source, NULL));\r
- GL(glCompileShaderARB(fragmemt_shader));\r
-\r
- GL(glGetObjectParameterivARB(fragmemt_shader, GL_OBJECT_COMPILE_STATUS_ARB, &success));\r
- if (success == GL_FALSE)\r
- {\r
- char info[2048];\r
- GL(glGetInfoLogARB(fragmemt_shader, sizeof(info), 0, info));\r
- GL(glDeleteObjectARB(vertex_shader));\r
- GL(glDeleteObjectARB(fragmemt_shader));\r
- GL(glDeleteObjectARB(program_));\r
- std::stringstream str;\r
- str << "Failed to compile fragment shader:" << std::endl << info << std::endl;\r
- BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
- }\r
- \r
- program_ = glCreateProgramObjectARB();\r
-\r
- GL(glAttachObjectARB(program_, vertex_shader));\r
- GL(glAttachObjectARB(program_, fragmemt_shader));\r
-\r
- GL(glDeleteObjectARB(vertex_shader));\r
- GL(glDeleteObjectARB(fragmemt_shader));\r
-\r
- GL(glLinkProgramARB(program_));\r
-\r
- GL(glGetObjectParameterivARB(program_, GL_OBJECT_LINK_STATUS_ARB, &success));\r
- if (success == GL_FALSE)\r
- {\r
- char info[2048];\r
- GL(glGetInfoLogARB(program_, sizeof(info), 0, info));\r
- GL(glDeleteObjectARB(program_));\r
- std::stringstream str;\r
- str << "Failed to link shader program:" << std::endl << info << std::endl;\r
- BOOST_THROW_EXCEPTION(caspar_exception() << msg_info(str.str()));\r
- }\r
- GL(glUseProgramObjectARB(program_));\r
- glUniform1i(glGetUniformLocation(program_, "plane[0]"), 0);\r
- glUniform1i(glGetUniformLocation(program_, "plane[1]"), 1);\r
- glUniform1i(glGetUniformLocation(program_, "plane[2]"), 2);\r
- glUniform1i(glGetUniformLocation(program_, "plane[3]"), 3);\r
- }\r
- catch(...)\r
- {\r
- CASPAR_LOG_CURRENT_EXCEPTION();\r
- throw;\r
- }\r
- }\r
-\r
- ~shader_program()\r
- {\r
- glDeleteProgram(program_);\r
- }\r
-\r
- void use()\r
- { \r
- GL(glUseProgramObjectARB(program_)); \r
- }\r
-\r
- GLuint get_location(const std::string& name)\r
- {\r
- return glGetUniformLocation(program_, name.c_str());\r
- }\r
- \r
-private:\r
- GLuint program_;\r
-};\r
-typedef std::shared_ptr<shader_program> shader_program_ptr;\r
-\r
-struct gpu_frame_shader::implementation\r
-{\r
- implementation(const frame_format_desc& format_desc) \r
- : current_(pixel_format::invalid_pixel_format), format_desc_(format_desc)\r
- {\r
- std::string common = \r
- "uniform sampler2D plane[4]; "\r
- "uniform vec4 plane_size[4]; "\r
- \r
- // NOTE: YCbCr, ITU-R, http://www.intersil.com/data/an/an9717.pdf \r
- // TODO: Support for more yuv formats might be needed. \r
- "vec4 ycbcra_to_bgra(float y, float cb, float cr, float a) "\r
- "{ "\r
- " vec4 color; "\r
- " "\r
- " cb -= 0.5; "\r
- " cr -= 0.5; "\r
- " y = 1.164*(y-0.0625); "\r
- " "\r
- " color.r = y + 1.596 * cr; "\r
- " color.g = y - 0.813 * cr - 0.337633 * cb; "\r
- " color.b = y + 2.017 * cb; "\r
- " color.a = a; "\r
- " "\r
- " return color; "\r
- "} ";\r
- \r
- shaders_[pixel_format::abgr] = common +\r
-\r
- "void main() "\r
- "{ "\r
- "vec4 abgr = texture2D(plane[0], gl_TexCoord[0].st); "\r
- "gl_FragColor = abgr.argb * gl_Color; "\r
- "} ";\r
- \r
- shaders_[pixel_format::argb] = common +\r
-\r
- "void main() " \r
- "{ "\r
- "vec4 argb = texture2D(plane[0], gl_TexCoord[0].st); "\r
- "gl_FragColor = argb.grab * gl_Color; " \r
- "} ";\r
- \r
- shaders_[pixel_format::bgra] = common +\r
-\r
- "void main() "\r
- "{ "\r
- "vec4 bgra = texture2D(plane[0], gl_TexCoord[0].st); "\r
- "gl_FragColor = bgra.rgba * gl_Color; "\r
- "} ";\r
- \r
- shaders_[pixel_format::rgba] = common +\r
-\r
- "void main() "\r
- "{ "\r
- "vec4 rgba = texture2D(plane[0], gl_TexCoord[0].st); "\r
- "gl_FragColor = rgba.bgra * gl_Color; "\r
- "} ";\r
- \r
- shaders_[pixel_format::ycbcr] = common +\r
-\r
- "void main() "\r
- "{ "\r
- "float y = texture2D(plane[0], gl_TexCoord[0].st).r; "\r
- "float cb = texture2D(plane[1], gl_TexCoord[0].st).r; "\r
- "float cr = texture2D(plane[2], gl_TexCoord[0].st).r; "\r
- "float a = 1.0; " \r
- "gl_FragColor = ycbcra_to_bgra(y, cb, cr, a) * gl_Color; "\r
- "} ";\r
- \r
- shaders_[pixel_format::ycbcra] = common +\r
-\r
- "void main() "\r
- "{ "\r
- "float y = texture2D(plane[0], gl_TexCoord[0].st).r; "\r
- "float cb = texture2D(plane[1], gl_TexCoord[0].st).r; "\r
- "float cr = texture2D(plane[2], gl_TexCoord[0].st).r; "\r
- "float a = texture2D(plane[3], gl_TexCoord[0].st).r; "\r
- "gl_FragColor = ycbcra_to_bgra(y, cb, cr, a) * gl_Color; "\r
- "} ";\r
- }\r
-\r
- void use(gpu_frame_desc& desc)\r
- {\r
- set_pixel_format(desc.pix_fmt);\r
-// set_size(desc);\r
- }\r
-\r
- void set_pixel_format(pixel_format format)\r
- {\r
- if(current_ == format)\r
- return;\r
- current_ = format;\r
- shaders_[format].use();\r
- }\r
-\r
- //void set_size(gpu_frame_desc& desc)\r
- //{\r
- // for(int n = 0; n < 4; ++n)\r
- // {\r
- // std::string name = std::string("plane_size[") + boost::lexical_cast<std::string>(n) + "]";\r
- // GL(glUniform4f(shaders_[current_].get_location(name), \r
- // static_cast<float>(desc.planes[n].width), \r
- // static_cast<float>(desc.planes[n].height),\r
- // 1.0f/static_cast<float>(desc.planes[n].width),\r
- // 1.0f/static_cast<float>(desc.planes[n].height)));\r
- // }\r
- //} \r
-\r
- frame_format_desc format_desc_;\r
- pixel_format current_;\r
- std::unordered_map<pixel_format, shader_program> shaders_;\r
-};\r
-\r
-gpu_frame_shader::gpu_frame_shader(const frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
-void gpu_frame_shader::use(gpu_frame_desc& desc){impl_->use(desc);}\r
-\r
-}}
\ No newline at end of file
+++ /dev/null
-#pragma once\r
-\r
-#include "frame_format.h"\r
-#include "gpu_frame_desc.h"\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-namespace caspar { namespace core {\r
- \r
-class gpu_frame_shader\r
-{\r
-public:\r
- gpu_frame_shader(const frame_format_desc& format_desc);\r
- void use(gpu_frame_desc& image);\r
-\r
-private:\r
- struct implementation;\r
- std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<gpu_frame_shader> gpu_frame_shader_ptr;\r
-\r
-}}
\ No newline at end of file
\r
#include "image_processor.h"\r
#include "audio_processor.h"\r
+#include "pixel_format.h"\r
\r
-#include "../format/pixel_format.h"\r
-#include "../../common/utility/singleton_pool.h"\r
+#include <common/utility/singleton_pool.h>\r
\r
#include <boost/range/algorithm.hpp>\r
\r
#include "draw_frame.h"\r
\r
#include "../format/video_format.h"\r
-#include "../format/pixel_format.h"\r
\r
#include <boost/noncopyable.hpp>\r
#include <boost/range/iterator_range.hpp>\r
#include <boost/range/algorithm.hpp>\r
\r
namespace caspar { namespace core {\r
-\r
-\r
+ \r
struct frame_processor_device::implementation : boost::noncopyable\r
{ \r
implementation(const video_format_desc& format_desc) : fmt_(format_desc), image_processor_(format_desc){}\r
\r
#include "fwd.h"\r
\r
+#include "pixel_format.h"\r
#include "write_frame.h"\r
\r
#include "../format/video_format.h"\r
#include <memory>\r
\r
namespace caspar { namespace core {\r
- \r
+\r
class frame_processor_device : boost::noncopyable\r
{\r
public:\r
#pragma once\r
\r
-#include "../format/pixel_format.h"\r
#include "../format/video_format.h"\r
\r
+#include "frame_processor_device.h"\r
+\r
#include <memory>\r
\r
namespace caspar { namespace core {\r
return buffers;\r
}\r
\r
- const video_format_desc format_desc_;\r
-\r
ogl_device context_;\r
\r
+ const video_format_desc format_desc_;\r
+ \r
std::stack<image_transform> transform_stack_;\r
\r
GLuint fbo_;\r
#include "host_buffer.h"\r
\r
#include "../format/video_format.h"\r
-#include "../format/pixel_format.h"\r
\r
#include <boost/tuple/tuple.hpp>\r
#include <boost/thread/future.hpp>\r
#include <array>\r
\r
namespace caspar { namespace core {\r
+\r
+struct pixel_format_desc;\r
\r
struct image_transform\r
{\r
#include "draw_frame.h"\r
#include "image_processor.h"\r
#include "audio_processor.h"\r
+#include "pixel_format.h"\r
\r
-#include "../format/pixel_format.h"\r
#include "../../common/gl/utility.h"\r
#include "../../common/utility/singleton_pool.h"\r
\r
#include "draw_frame.h"\r
\r
#include "../format/video_format.h"\r
-#include "../format/pixel_format.h"\r
\r
#include <boost/noncopyable.hpp>\r
#include <boost/range/iterator_range.hpp>\r
#include <vector>\r
\r
namespace caspar { namespace core {\r
- \r
+ \r
+struct pixel_format_desc;\r
+\r
class write_frame : public draw_frame, boost::noncopyable\r
{\r
public: \r
BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(narrow(color)) << msg_info("Invalid color code"));\r
}\r
\r
- safe_ptr<draw_frame> receive() { return frame_; }\r
+ virtual safe_ptr<draw_frame> receive() { return frame_; }\r
\r
- void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
+ virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
{\r
auto frame = frame_processor->create_frame(1, 1, pixel_format::bgra);\r
auto& value = *reinterpret_cast<unsigned long*>(frame->image_data().begin());\r
frame_ = std::move(frame);\r
}\r
\r
- std::wstring print() const { return + L"color[" + color_str_ + L"]"; }\r
+ virtual std::wstring print() const { return + L"color[" + color_str_ + L"]"; }\r
\r
safe_ptr<draw_frame> frame_;\r
std::wstring color_str_;\r
}\r
}\r
\r
- void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
+ virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
{\r
format_desc_ = frame_processor->get_video_format_desc();\r
video_decoder_.initialize(frame_processor);\r
}\r
\r
- safe_ptr<draw_frame> receive()\r
+ virtual safe_ptr<draw_frame> receive()\r
{\r
while(ouput_channel_.empty() && !input_.is_eof())\r
{ \r
return result;\r
}\r
\r
- std::wstring print() const\r
+ virtual std::wstring print() const\r
{\r
return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
}\r
ct_producer(ct_producer&& other) : initialized_(std::move(other.initialized_)), filename_(std::move(other.filename_)){}\r
ct_producer(const std::wstring& filename) : filename_(filename), initialized_(false){}\r
\r
- safe_ptr<draw_frame> receive()\r
+ virtual safe_ptr<draw_frame> receive()\r
{\r
if(!initialized_)\r
{\r
return cg_producer::receive();\r
}\r
\r
- std::wstring print() const\r
+ virtual std::wstring print() const\r
{\r
return L"ct[" + filename_ + L"]";\r
}\r
image_producer(image_producer&& other) : frame_processor_(std::move(other.frame_processor_)), filename_(std::move(other.filename_)), frame_(draw_frame::empty()){}\r
image_producer(const std::wstring& filename) : filename_(filename), frame_(draw_frame::empty()) {}\r
\r
- safe_ptr<draw_frame> receive(){return frame_;}\r
+ virtual safe_ptr<draw_frame> receive(){return frame_;}\r
\r
- void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
+ virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
{\r
frame_processor_ = frame_processor;\r
auto bitmap = load_image(filename_);\r
frame_ = std::move(frame);\r
}\r
\r
- std::wstring print() const\r
+ virtual std::wstring print() const\r
{\r
return L"image_producer. filename: " + filename_;\r
}\r
\r
namespace caspar { namespace core {\r
\r
-struct layer::implementation\r
+struct layer::implementation : boost::noncopyable\r
{ \r
implementation(size_t index) : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()), index_(index) {}\r
\r
\r
try\r
{\r
- last_frame_ = foreground_->receive();\r
-\r
+ last_frame_ = foreground_->receive(); \r
if(last_frame_ == draw_frame::eof())\r
{\r
auto following = foreground_->get_following_producer();\r
safe_ptr<draw_frame> last_frame_;\r
safe_ptr<frame_producer> foreground_;\r
safe_ptr<frame_producer> background_;\r
- size_t index_;\r
+ const size_t index_;\r
};\r
\r
layer::layer(size_t index) : impl_(new implementation(index)){}\r
#pragma once\r
\r
+#include <common/utility/safe_ptr.h>\r
+\r
#include <boost/noncopyable.hpp>\r
\r
namespace caspar { namespace core {\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
};\r
-typedef std::shared_ptr<layer> layer_ptr;\r
-typedef std::unique_ptr<layer> layer_uptr;\r
\r
}}
\ No newline at end of file
\r
transition_producer(const safe_ptr<frame_producer>& destination, const transition_info& info);\r
\r
- safe_ptr<draw_frame> receive();\r
+ virtual safe_ptr<draw_frame> receive();\r
\r
- safe_ptr<frame_producer> get_following_producer() const;\r
- void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
+ virtual safe_ptr<frame_producer> get_following_producer() const;\r
+ virtual void set_leading_producer(const safe_ptr<frame_producer>& producer);\r
virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor);\r
virtual std::wstring print() const;\r
private:\r
+++ /dev/null
-#pragma once\r
-\r
-#include <memory>\r
-#include <array>\r
-\r
-namespace caspar { namespace core {\r
- \r
-struct pixel_format\r
-{\r
- enum type\r
- {\r
- bgra,\r
- rgba,\r
- argb,\r
- abgr,\r
- ycbcr,\r
- ycbcra,\r
- count,\r
- invalid\r
- };\r
-};\r
-\r
-struct pixel_format_desc\r
-{\r
- struct plane\r
- {\r
- plane() : linesize(0), width(0), height(0), size(0), channels(0){}\r
- plane(size_t width, size_t height, size_t channels)\r
- : linesize(width*channels), width(width), height(height), size(width*height*channels), channels(channels)\r
- {}\r
- size_t linesize;\r
- size_t width;\r
- size_t height;\r
- size_t size;\r
- size_t channels;\r
- };\r
-\r
- pixel_format_desc() : pix_fmt(pixel_format::invalid)\r
- {\r
- planes[0] = plane();\r
- planes[1] = plane();\r
- planes[2] = plane();\r
- planes[3] = plane();\r
- }\r
-\r
- pixel_format::type pix_fmt;\r
-\r
- std::array<plane, 4> planes;\r
-};\r
- \r
-}}
\ No newline at end of file
+++ /dev/null
-/*\r
-* copyright (c) 2010 Sveriges Television AB <info@casparcg.com>\r
-*\r
-* This file is part of CasparCG.\r
-*\r
-* CasparCG is free software: you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation, either version 3 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* CasparCG is distributed in the hope that it will be useful,\r
-* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-* GNU General Public License for more details.\r
-\r
-* You should have received a copy of the GNU General Public License\r
-* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
- \r
-#include "..\StdAfx.h"\r
-\r
-#include "video_format.h"\r
-\r
-#include <boost/algorithm/string.hpp>\r
-\r
-#define DEFINE_VIDEOFORMATDESC(w, h, m, f, s, fmt) { (fmt), (w), (h), (m), (f), (w)*(h)*4, (s) }\r
-\r
-namespace caspar { namespace core {\r
-\r
-const video_format_desc video_format_desc::format_descs[video_format::count] = \r
-{ \r
- DEFINE_VIDEOFORMATDESC(720, 576, video_update_format::upper, 50, TEXT("PAL"), video_format::pal ), \r
- DEFINE_VIDEOFORMATDESC(720, 486, video_update_format::lower, 60/1.001, TEXT("NTSC"), video_format::ntsc ), \r
- DEFINE_VIDEOFORMATDESC(720, 576, video_update_format::progressive, 25, TEXT("576p2500"), video_format::x576p2500 ),\r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_update_format::progressive, 25, TEXT("720p2500"), video_format::x720p2500 ), \r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_update_format::progressive, 50, TEXT("720p5000"), video_format::x720p5000 ), \r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_update_format::progressive, 60/1.001, TEXT("720p5994"), video_format::x720p5994 ),\r
- DEFINE_VIDEOFORMATDESC(1280, 720, video_update_format::progressive, 60, TEXT("720p6000"), video_format::x720p6000 ),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::progressive, 24/1.001, TEXT("1080p2397"), video_format::x1080p2397),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::progressive, 24, TEXT("1080p2400"), video_format::x1080p2400),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::upper, 50, TEXT("1080i5000"), video_format::x1080i5000),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::upper, 60/1.001, TEXT("1080i5994"), video_format::x1080i5994),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::upper, 60, TEXT("1080i6000"), video_format::x1080i6000),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::progressive, 25, TEXT("1080p2500"), video_format::x1080p2500),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format::progressive, 30/1.001, TEXT("1080p2997"), video_format::x1080p2997),\r
- DEFINE_VIDEOFORMATDESC(1920, 1080, video_update_format:: progressive, 30, TEXT("1080p3000"), video_format::x1080p3000)\r
-};\r
-\r
-video_format::type get_video_format(const std::wstring& name)\r
-{\r
- for(int n = 0; n < video_format::count; ++n)\r
- {\r
- if(boost::iequals(video_format_desc::format_descs[n].name, name))\r
- return static_cast<video_format::type>(n);\r
- }\r
-\r
- return video_format::invalid;\r
-}\r
-\r
-}}\r
-\r
+++ /dev/null
-#pragma once\r
-\r
-#include <string>\r
-\r
-#include "../../common/compiler/vs/disable_silly_warnings.h"\r
-\r
-namespace caspar { namespace core {\r
- \r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \enum video_format\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-struct video_format \r
-{ \r
- enum type\r
- {\r
- pal = 0,\r
- ntsc,\r
- x576p2500,\r
- x720p2500,\r
- x720p5000,\r
- x720p5994,\r
- x720p6000,\r
- x1080p2397,\r
- x1080p2400,\r
- x1080i5000,\r
- x1080i5994,\r
- x1080i6000,\r
- x1080p2500,\r
- x1080p2997,\r
- x1080p3000,\r
- count,\r
- invalid\r
- };\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \enum video_update_format\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-struct video_update_format \r
-{ \r
- enum type\r
- {\r
- progressive,\r
- lower,\r
- upper,\r
- count,\r
- invalid\r
- };\r
-};\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \struct video_format_desc\r
-///\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-struct video_format_desc\r
-{\r
- video_format::type format;\r
-\r
- size_t width;\r
- size_t height;\r
- video_update_format::type update;\r
- double fps;\r
- size_t size;\r
- std::wstring name;\r
-\r
- static const video_format_desc format_descs[video_format::count];\r
-};\r
-\r
-inline bool operator==(const video_format_desc& rhs, const video_format_desc& lhs)\r
-{\r
- return rhs.format == lhs.format;\r
-}\r
-\r
-inline bool operator!=(const video_format_desc& rhs, const video_format_desc& lhs)\r
-{\r
- return !(rhs == lhs);\r
-}\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \fn video_format get_video_format(const std::wstring& strVideoMode);\r
-///\r
-/// \brief Gets the *video_format* associated with the specified name.\r
-///\r
-/// \param name Name of the *video_format*.. \r
-///\r
-/// \return The video format. \r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-video_format::type get_video_format(const std::wstring& name);\r
-\r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-/// \fn video_format get_video_format_desc(const std::wstring& strVideoMode);\r
-///\r
-/// \brief Gets the *video_format_desc* associated with the specified name.\r
-///\r
-/// \param name Name of the *video_format_desc*.. \r
-///\r
-/// \return The video format. \r
-////////////////////////////////////////////////////////////////////////////////////////////////////\r
-inline video_format_desc get_video_format_desc(const std::wstring& name, video_format::type default_format = video_format::x576p2500)\r
-{ \r
- auto casparVideoFormat = default_format;\r
- if(!name.empty())\r
- casparVideoFormat = get_video_format(name);\r
- return video_format_desc::format_descs[casparVideoFormat];\r
-}\r
-\r
-inline double render_video_format_period(const video_format_desc& format_desc)\r
-{\r
- return 1.0/(format_desc.update == video_update_format::progressive ? format_desc.fps : format_desc.fps/2.0);\r
-}\r
-\r
-inline std::wostream& operator<<(std::wostream& out, const video_format_desc& format_desc)\r
-{\r
- out << format_desc.name.c_str();\r
- return out;\r
-}\r
-\r
-}}
\ No newline at end of file
</paths>\r
<channels>\r
<channel>\r
- <videomode>PAL</videomode>\r
+ <videomode>1080i5000</videomode>\r
<consumers>\r
<ogl>\r
- <device>0</device>\r
+ <device>1</device>\r
<stretch>uniform</stretch>\r
<windowed>true</windowed>\r
</ogl>\r