\r
#include <common/spl/memory.h>\r
\r
-#include <boost/noncopyable.hpp>\r
#include <boost/property_tree/ptree_fwd.hpp>\r
\r
#include <functional>\r
\r
namespace caspar { namespace core {\r
\r
-class frame_consumer : boost::noncopyable\r
+/// Interface\r
+class frame_consumer\r
{\r
+ frame_consumer(const frame_consumer&);\r
+ frame_consumer& operator=(const frame_consumer&);\r
public:\r
+\r
+ /// Static Members\r
+ \r
+ static const spl::shared_ptr<frame_consumer>& empty();\r
+\r
+ /// Constructors\r
+\r
frame_consumer(){}\r
virtual ~frame_consumer() {}\r
\r
+ /// Methods\r
+\r
+ virtual bool send(const spl::shared_ptr<const class data_frame>& frame) = 0;\r
+ virtual void initialize(const struct video_format_desc& format_desc, int channel_index) = 0;\r
+\r
+ /// Properties\r
+\r
virtual std::wstring print() const = 0;\r
virtual std::wstring name() const = 0;\r
virtual boost::property_tree::wptree info() const = 0;\r
virtual bool has_synchronization_clock() const {return true;}\r
virtual int buffer_depth() const = 0;\r
virtual int index() const = 0;\r
-\r
- virtual bool send(const spl::shared_ptr<const class data_frame>& frame) = 0;\r
- virtual void initialize(const struct video_format_desc& format_desc, int channel_index) = 0;\r
-\r
- static const spl::shared_ptr<frame_consumer>& empty();\r
};\r
\r
typedef std::function<spl::shared_ptr<frame_consumer>(const std::vector<std::wstring>&)> consumer_factory_t;\r
#include <common/spl/memory.h>\r
#include <common/reactive.h>\r
\r
-#include <boost/noncopyable.hpp>\r
#include <boost/property_tree/ptree_fwd.hpp>\r
\r
FORWARD1(boost, template<typename> class unique_future)\r
\r
namespace caspar { namespace core {\r
\r
-class output sealed : boost::noncopyable\r
+class output sealed\r
{\r
+ output(const output&);\r
+ output& operator=(const output&);\r
public:\r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
explicit output(spl::shared_ptr<diagnostics::graph> graph, const struct video_format_desc& format_desc, int channel_index);\r
\r
- // output\r
+ /// Methods\r
\r
void operator()(spl::shared_ptr<const class data_frame> frame, const struct video_format_desc& format_desc);\r
\r
void remove(const spl::shared_ptr<class frame_consumer>& consumer);\r
void remove(int index);\r
\r
+ /// Properties\r
+\r
boost::unique_future<boost::property_tree::wptree> info() const;\r
\r
private:\r
\r
#include <common/spl/memory.h>\r
\r
-#include <boost/noncopyable.hpp>\r
#include <boost/range.hpp>\r
\r
#include <tbb/cache_aligned_allocator.h>\r
\r
typedef std::vector<int32_t, tbb::cache_aligned_allocator<int32_t>> audio_buffer;\r
\r
+ /// Interface\r
class data_frame\r
{\r
+ data_frame(const data_frame&);\r
+ data_frame& operator=(const data_frame&);\r
public:\r
+ /// Static Members\r
+ \r
+ static spl::shared_ptr<data_frame> empty();\r
+\r
+ /// Constructors\r
+\r
data_frame(){}\r
virtual ~data_frame(){}\r
\r
- virtual const struct pixel_format_desc& pixel_format_desc() const = 0;\r
+ /// Methods\r
+\r
+ /// Properties\r
+\r
+ virtual const struct pixel_format_desc& pixel_format_desc() const = 0;\r
\r
virtual const boost::iterator_range<const uint8_t*> image_data(int index = 0) const = 0;\r
- virtual const audio_buffer& audio_data() const = 0;\r
- \r
- virtual const boost::iterator_range<uint8_t*> image_data(int index) = 0;\r
- virtual audio_buffer& audio_data() = 0;\r
+ virtual const boost::iterator_range<uint8_t*> image_data(int index) = 0;\r
\r
- virtual double frame_rate() const = 0;\r
- virtual field_mode field_mode() const = 0;\r
+ virtual const audio_buffer& audio_data() const = 0; \r
+ virtual audio_buffer& audio_data() = 0;\r
\r
- virtual int width() const = 0;\r
- virtual int height() const = 0;\r
+ virtual double frame_rate() const = 0;\r
+ virtual field_mode field_mode() const = 0;\r
\r
- virtual const void* tag() const = 0;\r
+ virtual int width() const = 0;\r
+ virtual int height() const = 0;\r
\r
- static spl::shared_ptr<data_frame> empty();\r
-private:\r
- data_frame(const data_frame&);\r
- data_frame& operator=(const data_frame&);\r
+ virtual const void* tag() const = 0;\r
};\r
\r
}}
\ No newline at end of file
\r
#include <boost/foreach.hpp>\r
\r
+#include <boost/variant.hpp>\r
+\r
namespace caspar { namespace core {\r
- \r
+ \r
struct draw_frame::impl\r
{ \r
- std::vector<spl::shared_ptr<const draw_frame>> frames_;\r
- std::shared_ptr<spl::unique_ptr<const data_frame>> data_frame_;\r
+ int tag_;\r
+ std::vector<const draw_frame> frames_;\r
+ std::shared_ptr<spl::unique_ptr<const data_frame>> data_frame_;\r
\r
core::frame_transform frame_transform_; \r
-public:\r
- impl()\r
+public: \r
+ enum tags\r
{\r
- }\r
- \r
- impl(spl::unique_ptr<const data_frame> frame) \r
- : data_frame_(new spl::unique_ptr<const data_frame>(std::move(frame)))\r
+ frame_tag = 0,\r
+ empty_tag,\r
+ eof_tag,\r
+ late_tag\r
+ };\r
+\r
+ impl(int tag = impl::empty_tag)\r
+ : tag_(tag)\r
{\r
}\r
\r
- impl(spl::shared_ptr<const draw_frame> frame) \r
+ impl(spl::unique_ptr<const data_frame>&& frame) \r
+ : tag_(frame_tag)\r
+ , data_frame_(new spl::unique_ptr<const data_frame>(std::move(frame)))\r
{\r
- frames_.push_back(std::move(frame));\r
}\r
\r
- impl(std::vector<spl::shared_ptr<const draw_frame>> frames) : frames_(std::move(frames))\r
+ impl(draw_frame frame) \r
+ : tag_(frame_tag)\r
{\r
+ frames_.push_back(std::move(frame));\r
}\r
\r
- impl(std::vector<spl::shared_ptr<draw_frame>> frames)\r
+ impl(std::vector<draw_frame> frames)\r
+ : tag_(frame_tag)\r
{\r
frames_.insert(frames_.end(), frames.begin(), frames.end());\r
}\r
-\r
\r
void accept(frame_visitor& visitor) const\r
{\r
else\r
{\r
BOOST_FOREACH(auto frame, frames_)\r
- frame->accept(visitor);\r
+ frame.accept(visitor);\r
}\r
visitor.pop();\r
} \r
+\r
+ bool operator==(const impl& other)\r
+ {\r
+ return tag_ == other.tag_ && \r
+ frames_ == other.frames_ && \r
+ data_frame_ == other.data_frame_;\r
+ }\r
};\r
\r
draw_frame::draw_frame() : impl_(new impl()){}\r
+draw_frame::draw_frame(int tag) : impl_(new impl(std::move(tag))){}\r
draw_frame::draw_frame(const draw_frame& other) : impl_(new impl(*other.impl_)){}\r
draw_frame::draw_frame(draw_frame&& other) : impl_(std::move(other.impl_)){}\r
-draw_frame::draw_frame(spl::unique_ptr<const data_frame> frame) : impl_(new impl(std::move(frame))){}\r
-draw_frame::draw_frame(spl::shared_ptr<const draw_frame> frame) : impl_(new impl(std::move(frame))){}\r
-draw_frame::draw_frame(std::vector<spl::shared_ptr<draw_frame>> frames) : impl_(new impl(frames)){}\r
-draw_frame::draw_frame(std::vector<spl::shared_ptr<const draw_frame>> frames) : impl_(new impl(frames)){}\r
+draw_frame::draw_frame(spl::unique_ptr<const data_frame>&& frame) : impl_(new impl(std::move(frame))){}\r
+draw_frame::draw_frame(std::vector<draw_frame> frames) : impl_(new impl(frames)){}\r
+draw_frame::~draw_frame(){}\r
draw_frame& draw_frame::operator=(draw_frame other)\r
{\r
other.swap(*this);\r
}\r
void draw_frame::swap(draw_frame& other){impl_.swap(other.impl_);}\r
\r
-const core::frame_transform& draw_frame::frame_transform() const { return impl_->frame_transform_;}\r
-core::frame_transform& draw_frame::frame_transform() { return impl_->frame_transform_;}\r
+const core::frame_transform& draw_frame::transform() const { return impl_->frame_transform_;}\r
+core::frame_transform& draw_frame::transform() { return impl_->frame_transform_;}\r
void draw_frame::accept(frame_visitor& visitor) const{impl_->accept(visitor);}\r
-spl::shared_ptr<draw_frame> draw_frame::interlace(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2, core::field_mode mode)\r
+bool draw_frame::operator==(const draw_frame& other)const{return *impl_ == *other.impl_;}\r
+bool draw_frame::operator!=(const draw_frame& other)const{return !(*this == other);}\r
+\r
+draw_frame draw_frame::interlace(draw_frame frame1, draw_frame frame2, core::field_mode mode)\r
{ \r
if(frame1 == draw_frame::eof() || frame2 == draw_frame::eof())\r
return draw_frame::eof();\r
if(frame1 == draw_frame::empty() && frame2 == draw_frame::empty())\r
return draw_frame::empty();\r
\r
- auto my_frame1 = spl::make_shared<draw_frame>(frame1);\r
- auto my_frame2 = spl::make_shared<draw_frame>(frame2);\r
-\r
if(frame1 == frame2 || mode == field_mode::progressive)\r
- return my_frame2;\r
+ return frame2;\r
\r
if(mode == field_mode::upper)\r
{\r
- my_frame1->frame_transform().image_transform.field_mode = field_mode::upper; \r
- my_frame2->frame_transform().image_transform.field_mode = field_mode::lower; \r
+ frame1.transform().image_transform.field_mode = field_mode::upper; \r
+ frame2.transform().image_transform.field_mode = field_mode::lower; \r
} \r
else \r
{ \r
- my_frame1->frame_transform().image_transform.field_mode = field_mode::lower; \r
- my_frame2->frame_transform().image_transform.field_mode = field_mode::upper; \r
+ frame1.transform().image_transform.field_mode = field_mode::lower; \r
+ frame2.transform().image_transform.field_mode = field_mode::upper; \r
}\r
\r
- std::vector<spl::shared_ptr<const draw_frame>> frames;\r
- frames.push_back(my_frame1);\r
- frames.push_back(my_frame2);\r
- return spl::make_shared<draw_frame>(std::move(frames));\r
+ std::vector<draw_frame> frames;\r
+ frames.push_back(std::move(frame1));\r
+ frames.push_back(std::move(frame2));\r
+ return draw_frame(std::move(frames));\r
}\r
\r
-spl::shared_ptr<draw_frame> draw_frame::over(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2)\r
+draw_frame draw_frame::over(draw_frame frame1, draw_frame frame2)\r
{ \r
if(frame1 == draw_frame::eof() || frame2 == draw_frame::eof())\r
return draw_frame::eof();\r
if(frame1 == draw_frame::empty() && frame2 == draw_frame::empty())\r
return draw_frame::empty();\r
\r
- std::vector<spl::shared_ptr<const draw_frame>> frames;\r
- frames.push_back(frame1);\r
- frames.push_back(frame2);\r
- return spl::make_shared<draw_frame>(std::move(frames));\r
+ std::vector<draw_frame> frames;\r
+ frames.push_back(std::move(frame1));\r
+ frames.push_back(std::move(frame2));\r
+ return draw_frame(std::move(frames));\r
}\r
\r
-spl::shared_ptr<draw_frame> draw_frame::mask(const spl::shared_ptr<const draw_frame>& fill, const spl::shared_ptr<const draw_frame>& key)\r
+draw_frame draw_frame::mask(draw_frame fill, draw_frame key)\r
{ \r
if(fill == draw_frame::eof() || key == draw_frame::eof())\r
return draw_frame::eof();\r
if(fill == draw_frame::empty() || key == draw_frame::empty())\r
return draw_frame::empty();\r
\r
- std::vector<spl::shared_ptr<const draw_frame>> frames;\r
- auto key2 = spl::make_shared<draw_frame>(key);\r
- key2->frame_transform().image_transform.is_key = true;\r
- frames.push_back(key2);\r
- frames.push_back(fill);\r
- return spl::make_shared<draw_frame>(std::move(frames));\r
+ std::vector<draw_frame> frames;\r
+ key.transform().image_transform.is_key = true;\r
+ frames.push_back(std::move(key));\r
+ frames.push_back(std::move(fill));\r
+ return draw_frame(std::move(frames));\r
}\r
\r
-spl::shared_ptr<draw_frame> draw_frame::still(const spl::shared_ptr<const draw_frame>& frame)\r
+draw_frame draw_frame::still(draw_frame frame)\r
{\r
- auto frame2 = spl::make_shared<draw_frame>(frame);\r
- frame2->frame_transform().image_transform.is_still = true; \r
- frame2->frame_transform().audio_transform.volume = 0.0; \r
- return frame2;\r
+ frame.transform().image_transform.is_still = true; \r
+ frame.transform().audio_transform.volume = 0.0; \r
+ return frame;\r
}\r
\r
-const spl::shared_ptr<draw_frame>& draw_frame::eof()\r
+const draw_frame& draw_frame::eof()\r
{\r
- static spl::shared_ptr<draw_frame> frame = spl::make_shared<draw_frame>();\r
+ static draw_frame frame(impl::eof_tag);\r
return frame;\r
}\r
\r
-const spl::shared_ptr<draw_frame>& draw_frame::empty()\r
+const draw_frame& draw_frame::empty()\r
{\r
- static spl::shared_ptr<draw_frame> frame = spl::make_shared<draw_frame>();\r
+ static draw_frame frame(impl::empty_tag);\r
return frame;\r
}\r
\r
-const spl::shared_ptr<draw_frame>& draw_frame::late()\r
+const draw_frame& draw_frame::late()\r
{\r
- static spl::shared_ptr<draw_frame> frame = spl::make_shared<draw_frame>();\r
+ static draw_frame frame(impl::late_tag);\r
return frame;\r
}\r
\r
\r
struct frame_transform;\r
\r
-class draw_frame\r
+class draw_frame sealed\r
{\r
-public:\r
- draw_frame(); \r
- draw_frame(const draw_frame& other);\r
- draw_frame(draw_frame&& other);\r
- draw_frame& operator=(draw_frame other);\r
- virtual ~draw_frame(){}\r
- \r
- draw_frame(spl::unique_ptr<const data_frame> frame);\r
- draw_frame(spl::shared_ptr<const draw_frame> frame);\r
- draw_frame(std::vector<spl::shared_ptr<draw_frame>> frames);\r
- draw_frame(std::vector<spl::shared_ptr<const draw_frame>> frames);\r
+ draw_frame(int tag);\r
+public: \r
+ /// Static Members\r
+\r
+ static draw_frame interlace(draw_frame frame1, draw_frame frame2, core::field_mode mode);\r
+ static draw_frame over(draw_frame frame1, draw_frame frame2);\r
+ static draw_frame mask(draw_frame fill, draw_frame key);\r
+ static draw_frame still(draw_frame frame);\r
\r
- void swap(draw_frame& other);\r
+ static const draw_frame& eof();\r
+ static const draw_frame& empty();\r
+ static const draw_frame& late();\r
+\r
+ /// Constructors\r
+\r
+ draw_frame();\r
+ draw_frame(const draw_frame& other);\r
+ draw_frame(draw_frame&& other); \r
+ explicit draw_frame(spl::unique_ptr<const data_frame>&& frame);\r
+ explicit draw_frame(std::vector<draw_frame> frames);\r
+\r
+ ~draw_frame();\r
\r
- const core::frame_transform& frame_transform() const;\r
- core::frame_transform& frame_transform();\r
- \r
- static spl::shared_ptr<draw_frame> interlace(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2, core::field_mode mode);\r
- static spl::shared_ptr<draw_frame> over(const spl::shared_ptr<const draw_frame>& frame1, const spl::shared_ptr<const draw_frame>& frame2);\r
- static spl::shared_ptr<draw_frame> mask(const spl::shared_ptr<const draw_frame>& fill, const spl::shared_ptr<const draw_frame>& key);\r
- static spl::shared_ptr<draw_frame> still(const spl::shared_ptr<const draw_frame>& frame);\r
- \r
- static const spl::shared_ptr<draw_frame>& eof();\r
- static const spl::shared_ptr<draw_frame>& empty();\r
- static const spl::shared_ptr<draw_frame>& late();\r
+ /// Methods\r
+\r
+ draw_frame& operator=(draw_frame other);\r
+\r
+ void swap(draw_frame& other); \r
\r
- virtual void accept(frame_visitor& visitor) const;\r
+ void accept(frame_visitor& visitor) const;\r
+\r
+ bool operator==(const draw_frame& other) const;\r
+ bool operator!=(const draw_frame& other) const;\r
+\r
+ /// Properties\r
+\r
+ const core::frame_transform& transform() const;\r
+ core::frame_transform& transform(); \r
private:\r
struct impl;\r
- spl::shared_ptr<impl> impl_;\r
+ spl::unique_ptr<impl> impl_;\r
};\r
\r
\r
\r
#include <core/video_format.h>\r
\r
-#include <boost/noncopyable.hpp>\r
-\r
namespace caspar { namespace core {\r
\r
class frame_factory : boost::noncopyable\r
{\r
+ frame_factory(const frame_factory&);\r
+ frame_factory& operator=(const frame_factory&);\r
public:\r
+ /// Static Members\r
+\r
+ //Constructors\r
+\r
+ frame_factory(){}\r
virtual ~frame_factory(){}\r
\r
- virtual spl::unique_ptr<class data_frame> create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0; \r
- spl::unique_ptr<class data_frame> create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc)\r
+ /// Methods\r
+\r
+ virtual spl::unique_ptr<class data_frame> create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0; \r
+ spl::unique_ptr<class data_frame> create_frame(const void* video_stream_tag, const struct pixel_format_desc& desc)\r
{\r
auto format_desc = video_format_desc();\r
return create_frame(video_stream_tag, desc, format_desc.fps, format_desc.field_mode);\r
}\r
- virtual struct video_format_desc video_format_desc() const = 0; // nothrow\r
+\r
+ /// Properties\r
+\r
+ virtual struct video_format_desc video_format_desc() const = 0; \r
};\r
\r
}}
\ No newline at end of file
\r
#pragma once\r
\r
-#include <boost/noncopyable.hpp>\r
-\r
namespace caspar { namespace core {\r
\r
-class frame_visitor : boost::noncopyable\r
+class frame_visitor\r
{\r
+ frame_visitor(const frame_visitor&);\r
+ frame_visitor& operator=(const frame_visitor&);\r
public:\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
+ frame_visitor(){}\r
virtual ~frame_visitor(){}\r
+\r
+ /// Methods\r
+\r
virtual void push(const struct frame_transform& transform) = 0;\r
virtual void visit(const class data_frame& frame) = 0;\r
virtual void pop() = 0;\r
+\r
+ /// Properties\r
};\r
\r
}}
\ No newline at end of file
\r
class audio_mixer sealed : public frame_visitor\r
{\r
+ audio_mixer(const audio_mixer&);\r
+ audio_mixer& operator=(const audio_mixer&);\r
public:\r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
audio_mixer();\r
\r
+ /// Methods\r
+ \r
+ audio_buffer operator()(const struct video_format_desc& format_desc);\r
+\r
+ // frame_visitor\r
+\r
virtual void push(const struct frame_transform& transform);\r
virtual void visit(const class data_frame& frame);\r
virtual void pop();\r
-\r
- audio_buffer operator()(const struct video_format_desc& format_desc);\r
\r
+ /// Properties\r
+\r
private:\r
struct impl;\r
spl::shared_ptr<impl> impl_;\r
\r
namespace caspar { namespace core {\r
\r
+/// Interface\r
class image_mixer : public frame_visitor\r
{\r
+ image_mixer(const image_mixer&);\r
+ image_mixer& operator=(const image_mixer&);\r
public:\r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
+ image_mixer(){}\r
virtual ~image_mixer(){}\r
\r
+ /// Methods\r
+\r
virtual void push(const struct frame_transform& frame) = 0;\r
virtual void visit(const class data_frame& frame) = 0;\r
virtual void pop() = 0;\r
virtual void end_layer() = 0;\r
\r
virtual boost::shared_future<boost::iterator_range<const uint8_t*>> operator()(const struct video_format_desc& format_desc) = 0;\r
+\r
virtual spl::unique_ptr<core::data_frame> create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) = 0;\r
+\r
+ /// Properties\r
};\r
\r
}}
\ No newline at end of file
graph_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 0.9f, 0.8));\r
} \r
\r
- spl::shared_ptr<const data_frame> operator()(std::map<int, spl::shared_ptr<draw_frame>> frames, const video_format_desc& format_desc)\r
+ spl::shared_ptr<const data_frame> operator()(std::map<int, draw_frame> frames, const video_format_desc& format_desc)\r
{ \r
return executor_.invoke([=]() mutable -> spl::shared_ptr<const class data_frame>\r
{ \r
auto blend_it = blend_modes_.find(frame.first);\r
image_mixer_->begin_layer(blend_it != blend_modes_.end() ? blend_it->second : blend_mode::normal);\r
\r
- frame.second->accept(audio_mixer_); \r
- frame.second->accept(*image_mixer_);\r
+ frame.second.accept(audio_mixer_); \r
+ frame.second.accept(*image_mixer_);\r
\r
image_mixer_->end_layer();\r
}\r
: impl_(new impl(std::move(graph), std::move(image_mixer))){}\r
void mixer::set_blend_mode(int index, blend_mode value){impl_->set_blend_mode(index, value);}\r
boost::unique_future<boost::property_tree::wptree> mixer::info() const{return impl_->info();}\r
-spl::shared_ptr<const data_frame> mixer::operator()(std::map<int, spl::shared_ptr<draw_frame>> frames, const struct video_format_desc& format_desc){return (*impl_)(std::move(frames), format_desc);}\r
+spl::shared_ptr<const data_frame> mixer::operator()(std::map<int, draw_frame> frames, const struct video_format_desc& format_desc){return (*impl_)(std::move(frames), format_desc);}\r
spl::unique_ptr<data_frame> mixer::create_frame(const void* tag, const core::pixel_format_desc& desc, double frame_rate, core::field_mode field_mode) {return impl_->image_mixer_->create_frame(tag, desc, frame_rate, field_mode);}\r
}}
\ No newline at end of file
\r
#include <core/video_format.h>\r
\r
-#include <boost/noncopyable.hpp>\r
#include <boost/property_tree/ptree_fwd.hpp>\r
\r
#include <map>\r
\r
namespace caspar { namespace core {\r
\r
-class mixer sealed : boost::noncopyable\r
+class mixer sealed\r
{\r
-public: \r
- explicit mixer(spl::shared_ptr<diagnostics::graph> graph, spl::unique_ptr<class image_mixer> image_mixer);\r
+ mixer(const mixer&);\r
+ mixer& operator=(const mixer&);\r
+public:\r
+ \r
+ /// Static Members\r
\r
- spl::shared_ptr<const class data_frame> operator()(std::map<int, spl::shared_ptr<class draw_frame>> frames, const struct video_format_desc& format_desc);\r
+ /// Constructors\r
\r
- void set_blend_mode(int index, blend_mode value);\r
+ explicit mixer(spl::shared_ptr<diagnostics::graph> graph, spl::unique_ptr<class image_mixer> image_mixer);\r
+\r
+ /// Methods\r
+ \r
+ spl::shared_ptr<const class data_frame> operator()(std::map<int, class draw_frame> frames, const struct video_format_desc& format_desc);\r
+ \r
+ void set_blend_mode(int index, blend_mode value);\r
+\r
+ spl::unique_ptr<class data_frame> create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
+\r
+ /// Properties\r
\r
boost::unique_future<boost::property_tree::wptree> info() const;\r
\r
- spl::unique_ptr<class data_frame> create_frame(const void* tag, const struct pixel_format_desc& desc, double frame_rate, core::field_mode field_mode);\r
private:\r
struct impl;\r
spl::shared_ptr<impl> impl_;\r
class path sealed\r
{\r
public: \r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
path(); \r
path(const char* path);\r
path(std::string path);\r
path(const path& other); \r
path(path&& other);\r
\r
+ /// Methods\r
+\r
path& operator=(path other);\r
path& operator%=(path other);\r
\r
\r
void swap(path& other);\r
\r
+ /// Properties\r
+\r
const std::string& str() const; \r
bool empty() const;\r
private:\r
class event sealed\r
{ \r
public: \r
- typedef std::vector<param, tbb::cache_aligned_allocator<param>> params_t;\r
\r
+ /// Static Members\r
+\r
+ typedef std::vector<param, tbb::cache_aligned_allocator<param>> params_t;\r
+\r
+ /// Constructors\r
+\r
event(path path); \r
- event(path path, params_t params); \r
- \r
+ event(path path, params_t params); \r
event(const event& other);\r
event(event&& other);\r
+\r
+ /// Methods\r
+\r
event& operator=(event other);\r
\r
void swap(event& other);\r
}\r
\r
event propagate(path path) const;\r
+\r
+ /// Properties\r
+\r
const path& path() const;\r
const params_t& params() const;\r
private:\r
};\r
\r
public: \r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
basic_subject(monitor::path path = monitor::path())\r
: impl_(std::make_shared<impl>(std::move(path)))\r
\r
{\r
}\r
\r
+ /// Methods\r
+\r
basic_subject& operator=(basic_subject&& other)\r
{\r
impl_ = std::move(other.impl_);\r
}\r
+\r
+ operator std::weak_ptr<observer>()\r
+ {\r
+ return impl_;\r
+ }\r
+\r
+ // observable\r
\r
virtual void subscribe(const observer_ptr& o) override\r
{ \r
{\r
impl_->unsubscribe(o);\r
}\r
+\r
+ // observer\r
\r
virtual void on_next(const monitor::event& e) override\r
{ \r
impl_->on_next(e);\r
}\r
\r
- operator std::weak_ptr<observer>()\r
- {\r
- return impl_;\r
- }\r
+ /// Properties\r
+\r
private:\r
std::shared_ptr<impl> impl_;\r
};\r
\r
class color_producer : public frame_producer\r
{\r
- spl::shared_ptr<draw_frame> frame_;\r
+ draw_frame frame_;\r
const std::wstring color_str_;\r
\r
public:\r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<draw_frame> receive(int) override\r
+ virtual draw_frame receive(int) override\r
{\r
return frame_;\r
} \r
return L"color";\r
}\r
\r
- virtual spl::shared_ptr<draw_frame> last_frame() const override\r
+ virtual draw_frame last_frame() const override\r
{\r
return frame_;\r
}\r
\r
return core::wrap_producer(spl::make_shared<color_producer>(frame_factory, color2));\r
}\r
-spl::shared_ptr<draw_frame> create_color_frame(void* tag, const spl::shared_ptr<frame_factory>& frame_factory, const std::wstring& color)\r
+\r
+draw_frame create_color_frame(void* tag, const spl::shared_ptr<frame_factory>& frame_factory, const std::wstring& color)\r
{\r
auto color2 = get_hex_color(color);\r
if(color2.length() != 9 || color2[0] != '#')\r
if(!(str >> std::hex >> value) || !str.eof())\r
BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(color2) << msg_info("Invalid color."));\r
\r
- return spl::make_shared<draw_frame>(std::move(frame));\r
+ return core::draw_frame(std::move(frame));\r
}\r
\r
}}
\ No newline at end of file
namespace caspar { namespace core {\r
\r
spl::shared_ptr<class frame_producer> create_color_producer(const spl::shared_ptr<class frame_factory>& frame_factory, const std::vector<std::wstring>& params);\r
-spl::shared_ptr<class draw_frame> create_color_frame(void* tag, const spl::shared_ptr<class frame_factory>& frame_factory, const std::wstring& color);\r
+class draw_frame create_color_frame(void* tag, const spl::shared_ptr<class frame_factory>& frame_factory, const std::wstring& color);\r
\r
}}\r
BOOST_THROW_EXCEPTION(not_supported());\r
}\r
\r
-const spl::shared_ptr<frame_producer>& frame_producer::empty() // nothrow\r
+const spl::shared_ptr<frame_producer>& frame_producer::empty() \r
{\r
class empty_frame_producer : public frame_producer\r
{\r
public:\r
- virtual spl::shared_ptr<draw_frame> receive(int){return draw_frame::empty();}\r
- virtual spl::shared_ptr<draw_frame> last_frame() const{return draw_frame::empty();}\r
+ empty_frame_producer(){}\r
+ virtual draw_frame receive(int){return draw_frame::empty();}\r
+ virtual draw_frame last_frame() const{return draw_frame::empty();}\r
virtual void set_frame_factory(const spl::shared_ptr<frame_factory>&){}\r
virtual uint32_t nb_frames() const {return 0;}\r
virtual std::wstring print() const { return L"empty";}\r
}); \r
}\r
\r
- virtual spl::shared_ptr<draw_frame> receive(int flags) override {return producer_->receive(flags);}\r
- virtual spl::shared_ptr<draw_frame> last_frame() const override {return producer_->last_frame();}\r
+ virtual draw_frame receive(int flags) override {return producer_->receive(flags);}\r
+ virtual draw_frame last_frame() const override {return producer_->last_frame();}\r
virtual std::wstring print() const override {return producer_->print();}\r
virtual std::wstring name() const override {return producer_->name();}\r
virtual boost::property_tree::wptree info() const override {return producer_->info();}\r
#include <type_traits>\r
#include <vector>\r
\r
-#include <boost/noncopyable.hpp>\r
#include <boost/property_tree/ptree_fwd.hpp>\r
\r
FORWARD1(caspar, class executor);\r
\r
namespace caspar { namespace core {\r
\r
+/// Interface\r
class frame_producer : public monitor::observable\r
- , boost::noncopyable\r
{\r
+ frame_producer(const frame_producer&);\r
+ frame_producer& operator=(const frame_producer&);\r
public:\r
+\r
+ /// Static Members\r
+ \r
struct flags_def\r
{\r
enum type\r
};\r
typedef enum_class<flags_def> flags;\r
\r
+ static const spl::shared_ptr<frame_producer>& empty();\r
+\r
+ /// Constructors\r
+\r
+ frame_producer(){}\r
virtual ~frame_producer(){} \r
\r
- virtual std::wstring print() const = 0; // nothrow\r
- virtual std::wstring name() const = 0;\r
- virtual boost::property_tree::wptree info() const = 0;\r
- virtual uint32_t nb_frames() const {return std::numeric_limits<uint32_t>::max();}\r
- virtual spl::shared_ptr<class draw_frame> last_frame() const = 0;\r
+ /// Methods \r
\r
- virtual spl::shared_ptr<class draw_frame> receive(int flags) = 0;\r
+ virtual class draw_frame receive(int flags) = 0;\r
virtual boost::unique_future<std::wstring> call(const std::wstring&);\r
- virtual void leading_producer(const spl::shared_ptr<frame_producer>&) {} // nothrow\r
\r
- static const spl::shared_ptr<frame_producer>& empty(); // nothrow\r
-\r
// monitor::observable\r
\r
virtual void subscribe(const monitor::observable::observer_ptr& o) {}\r
virtual void unsubscribe(const monitor::observable::observer_ptr& o) {}\r
+\r
+ /// Properties\r
+\r
+ virtual std::wstring print() const = 0;\r
+ virtual std::wstring name() const = 0;\r
+ virtual boost::property_tree::wptree info() const = 0;\r
+ virtual uint32_t nb_frames() const {return std::numeric_limits<uint32_t>::max();}\r
+ virtual class draw_frame last_frame() const = 0;\r
+ virtual void leading_producer(const spl::shared_ptr<frame_producer>&) {} \r
};\r
\r
typedef std::function<spl::shared_ptr<core::frame_producer>(const spl::shared_ptr<class frame_factory>&, const std::vector<std::wstring>&)> producer_factory_t;\r
pause();\r
}\r
\r
- spl::shared_ptr<draw_frame> receive(frame_producer::flags flags, const video_format_desc& format_desc)\r
+ draw_frame receive(frame_producer::flags flags, const video_format_desc& format_desc)\r
{ \r
try\r
{\r
void layer::play(){impl_->play();}\r
void layer::pause(){impl_->pause();}\r
void layer::stop(){impl_->stop();}\r
-spl::shared_ptr<draw_frame> layer::receive(frame_producer::flags flags, const video_format_desc& format_desc) {return impl_->receive(flags, format_desc);}\r
+draw_frame layer::receive(frame_producer::flags flags, const video_format_desc& format_desc) {return impl_->receive(flags, format_desc);}\r
spl::shared_ptr<frame_producer> layer::foreground() const { return impl_->foreground_;}\r
spl::shared_ptr<frame_producer> layer::background() const { return impl_->background_;}\r
boost::property_tree::wptree layer::info() const{return impl_->info();}\r
\r
class layer sealed : public monitor::observable\r
{\r
+ layer(const layer&);\r
+ layer& operator=(const layer&);\r
public:\r
- layer(int index = -1); // nothrow\r
- layer(layer&& other); // nothrow\r
- layer& operator=(layer&& other); // nothrow\r
+ /// Static Members\r
\r
- void swap(layer& other); // nothrow \r
- \r
- void load(spl::shared_ptr<class frame_producer> producer, const boost::optional<int32_t>& auto_play_delta = nullptr); // nothrow\r
- void play(); // nothrow\r
- void pause(); // nothrow\r
- void stop(); // nothrow\r
- \r
- spl::shared_ptr<class frame_producer> foreground() const; // nothrow\r
- spl::shared_ptr<class frame_producer> background() const; // nothrow\r
+ /// Constructors\r
+\r
+ explicit layer(int index = -1); \r
+ layer(layer&& other); \r
\r
- spl::shared_ptr<class draw_frame> receive(frame_producer::flags flags, const struct video_format_desc& format_desc); // nothrow\r
+ /// Methods\r
\r
- boost::property_tree::wptree info() const;\r
+ layer& operator=(layer&& other); \r
\r
+ void swap(layer& other); \r
+ \r
+ void load(spl::shared_ptr<class frame_producer> producer, const boost::optional<int32_t>& auto_play_delta = nullptr); \r
+ void play(); \r
+ void pause(); \r
+ void stop(); \r
+ \r
+ class draw_frame receive(frame_producer::flags flags, const struct video_format_desc& format_desc); \r
+ \r
// monitor::observable\r
\r
virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
+\r
+ /// Properties\r
+ \r
+ spl::shared_ptr<class frame_producer> foreground() const; \r
+ spl::shared_ptr<class frame_producer> background() const; \r
+\r
+ boost::property_tree::wptree info() const;\r
+\r
private:\r
struct impl;\r
spl::shared_ptr<impl> impl_;\r
{ \r
spl::shared_ptr<frame_producer> fill_producer_;\r
spl::shared_ptr<frame_producer> key_producer_;\r
- spl::shared_ptr<draw_frame> fill_;\r
- spl::shared_ptr<draw_frame> key_;\r
- spl::shared_ptr<draw_frame> last_frame_;\r
+ draw_frame fill_;\r
+ draw_frame key_;\r
+ draw_frame last_frame_;\r
\r
public:\r
explicit separated_producer(const spl::shared_ptr<frame_producer>& fill, const spl::shared_ptr<frame_producer>& key) \r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<draw_frame> receive(int flags) override\r
+ virtual draw_frame receive(int flags) override\r
{\r
tbb::parallel_invoke(\r
[&]\r
return frame;\r
}\r
\r
- virtual spl::shared_ptr<draw_frame> last_frame() const override\r
+ virtual draw_frame last_frame() const override\r
{\r
return draw_frame::still(last_frame_);\r
}\r
graph_->set_color("produce-time", diagnostics::color(0.0f, 1.0f, 0.0f));\r
}\r
\r
- std::map<int, spl::shared_ptr<draw_frame>> operator()(const struct video_format_desc& format_desc)\r
+ std::map<int, draw_frame> operator()(const struct video_format_desc& format_desc)\r
{ \r
- return executor_.invoke([=]() -> std::map<int, spl::shared_ptr<draw_frame>>\r
+ return executor_.invoke([=]() -> std::map<int, draw_frame>\r
{\r
boost::timer frame_timer;\r
\r
- std::map<int, spl::shared_ptr<class draw_frame>> frames;\r
+ std::map<int, class draw_frame> frames;\r
\r
try\r
{ \r
});\r
}\r
\r
- void draw(int index, const video_format_desc& format_desc, std::map<int, spl::shared_ptr<draw_frame>>& frames)\r
+ void draw(int index, const video_format_desc& format_desc, std::map<int, draw_frame>& frames)\r
{\r
auto& layer = layers_[index];\r
auto& tween = tweens_[index];\r
\r
auto frame = layer.receive(flags, format_desc); \r
\r
- auto frame1 = spl::make_shared<core::draw_frame>(frame);\r
- frame1->frame_transform() = transform;\r
+ auto frame1 = core::draw_frame(frame);\r
+ frame1.transform() = transform;\r
\r
if(format_desc.field_mode != core::field_mode::progressive)\r
{ \r
- auto frame2 = spl::make_shared<core::draw_frame>(frame);\r
- frame2->frame_transform() = tween.fetch_and_tick(1);\r
+ auto frame2 = core::draw_frame(frame);\r
+ frame2.transform() = tween.fetch_and_tick(1);\r
frame1 = core::draw_frame::interlace(frame1, frame2, format_desc.field_mode);\r
}\r
\r
boost::unique_future<spl::shared_ptr<frame_producer>> stage::background(int index) {return impl_->background(index);}\r
boost::unique_future<boost::property_tree::wptree> stage::info() const{return impl_->info();}\r
boost::unique_future<boost::property_tree::wptree> stage::info(int index) const{return impl_->info(index);}\r
-std::map<int, spl::shared_ptr<class draw_frame>> stage::operator()(const video_format_desc& format_desc){return (*impl_)(format_desc);}\r
+std::map<int, class draw_frame> stage::operator()(const video_format_desc& format_desc){return (*impl_)(format_desc);}\r
void stage::subscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_.subscribe(o);}\r
void stage::unsubscribe(const monitor::observable::observer_ptr& o) {impl_->event_subject_.unsubscribe(o);}\r
}}
\ No newline at end of file
stage(const stage&);\r
stage& operator=(const stage&);\r
public: \r
+\r
+ /// Static Members\r
+ \r
typedef std::function<struct frame_transform(struct frame_transform)> transform_func_t;\r
typedef std::tuple<int, transform_func_t, unsigned int, tweener> transform_tuple_t;\r
\r
- stage(spl::shared_ptr<diagnostics::graph> graph);\r
- \r
- std::map<int, spl::shared_ptr<class draw_frame>> operator()(const struct video_format_desc& format_desc);\r
+ /// Constructors\r
+\r
+ explicit stage(spl::shared_ptr<diagnostics::graph> graph);\r
+ \r
+ /// Methods\r
+\r
+ std::map<int, class draw_frame> operator()(const struct video_format_desc& format_desc);\r
\r
void apply_transforms(const std::vector<transform_tuple_t>& transforms);\r
void apply_transform(int index, const transform_func_t& transform, unsigned int mix_duration = 0, const tweener& tween = L"linear");\r
void swap_layer(int index, int other_index);\r
void swap_layer(int index, int other_index, stage& other);\r
\r
- boost::unique_future<spl::shared_ptr<class frame_producer>> foreground(int index);\r
- boost::unique_future<spl::shared_ptr<class frame_producer>> background(int index);\r
-\r
- boost::unique_future<boost::property_tree::wptree> info() const;\r
- boost::unique_future<boost::property_tree::wptree> info(int index) const;\r
- \r
// monitor::observable\r
\r
virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
+\r
+ /// Properties\r
+\r
+ boost::unique_future<spl::shared_ptr<class frame_producer>> foreground(int index);\r
+ boost::unique_future<spl::shared_ptr<class frame_producer>> background(int index);\r
+\r
+ boost::unique_future<boost::property_tree::wptree> info() const;\r
+ boost::unique_future<boost::property_tree::wptree> info(int index) const;\r
+\r
private:\r
struct impl;\r
spl::shared_ptr<impl> impl_;\r
\r
const transition_info info_;\r
\r
- spl::shared_ptr<draw_frame> last_frame_;\r
+ draw_frame last_frame_;\r
\r
spl::shared_ptr<frame_producer> dest_producer_;\r
spl::shared_ptr<frame_producer> source_producer_;\r
\r
public:\r
+\r
explicit transition_producer(const field_mode& mode, const spl::shared_ptr<frame_producer>& dest, const transition_info& info) \r
: mode_(mode)\r
, current_frame_(0)\r
source_producer_ = producer;\r
}\r
\r
- virtual spl::shared_ptr<draw_frame> receive(int flags) override\r
+ virtual draw_frame receive(int flags) override\r
{\r
if(current_frame_ >= info_.duration)\r
return dest_producer_->receive(flags);\r
return compose(dest, source);\r
}\r
\r
- virtual spl::shared_ptr<draw_frame> last_frame() const override\r
+ virtual draw_frame last_frame() const override\r
{\r
return dest_producer_->last_frame();\r
}\r
\r
// transition_producer\r
\r
- spl::shared_ptr<draw_frame> compose(const spl::shared_ptr<draw_frame>& dest_frame, const spl::shared_ptr<draw_frame>& src_frame) \r
+ draw_frame compose(draw_frame dest_frame, draw_frame src_frame) \r
{ \r
if(info_.type == transition_type::cut) \r
return src_frame;\r
\r
// For interlaced transitions. Seperate fields into seperate frames which are transitioned accordingly.\r
\r
- src_frame->frame_transform().audio_transform.volume = 1.0-delta2;\r
- auto s_frame1 = spl::make_shared<draw_frame>(src_frame);\r
- auto s_frame2 = spl::make_shared<draw_frame>(src_frame);\r
+ src_frame.transform().audio_transform.volume = 1.0-delta2;\r
+ auto s_frame1 = src_frame;\r
+ auto s_frame2 = src_frame;\r
\r
- dest_frame->frame_transform().audio_transform.volume = delta2;\r
- auto d_frame1 = spl::make_shared<draw_frame>(dest_frame);\r
- auto d_frame2 = spl::make_shared<draw_frame>(dest_frame);\r
+ dest_frame.transform().audio_transform.volume = delta2;\r
+ auto d_frame1 = dest_frame;\r
+ auto d_frame2 = dest_frame;\r
\r
if(info_.type == transition_type::mix)\r
{\r
- d_frame1->frame_transform().image_transform.opacity = delta1; \r
- d_frame1->frame_transform().image_transform.is_mix = true;\r
- d_frame2->frame_transform().image_transform.opacity = delta2;\r
- d_frame2->frame_transform().image_transform.is_mix = true;\r
-\r
- s_frame1->frame_transform().image_transform.opacity = 1.0-delta1; \r
- s_frame1->frame_transform().image_transform.is_mix = true;\r
- s_frame2->frame_transform().image_transform.opacity = 1.0-delta2; \r
- s_frame2->frame_transform().image_transform.is_mix = true;\r
+ d_frame1.transform().image_transform.opacity = delta1; \r
+ d_frame1.transform().image_transform.is_mix = true;\r
+ d_frame2.transform().image_transform.opacity = delta2;\r
+ d_frame2.transform().image_transform.is_mix = true;\r
+\r
+ s_frame1.transform().image_transform.opacity = 1.0-delta1; \r
+ s_frame1.transform().image_transform.is_mix = true;\r
+ s_frame2.transform().image_transform.opacity = 1.0-delta2; \r
+ s_frame2.transform().image_transform.is_mix = true;\r
}\r
if(info_.type == transition_type::slide)\r
{\r
- d_frame1->frame_transform().image_transform.fill_translation[0] = (-1.0+delta1)*dir; \r
- d_frame2->frame_transform().image_transform.fill_translation[0] = (-1.0+delta2)*dir; \r
+ d_frame1.transform().image_transform.fill_translation[0] = (-1.0+delta1)*dir; \r
+ d_frame2.transform().image_transform.fill_translation[0] = (-1.0+delta2)*dir; \r
}\r
else if(info_.type == transition_type::push)\r
{\r
- d_frame1->frame_transform().image_transform.fill_translation[0] = (-1.0+delta1)*dir;\r
- d_frame2->frame_transform().image_transform.fill_translation[0] = (-1.0+delta2)*dir;\r
+ d_frame1.transform().image_transform.fill_translation[0] = (-1.0+delta1)*dir;\r
+ d_frame2.transform().image_transform.fill_translation[0] = (-1.0+delta2)*dir;\r
\r
- s_frame1->frame_transform().image_transform.fill_translation[0] = (0.0+delta1)*dir; \r
- s_frame2->frame_transform().image_transform.fill_translation[0] = (0.0+delta2)*dir; \r
+ s_frame1.transform().image_transform.fill_translation[0] = (0.0+delta1)*dir; \r
+ s_frame2.transform().image_transform.fill_translation[0] = (0.0+delta2)*dir; \r
}\r
else if(info_.type == transition_type::wipe) \r
{\r
- d_frame1->frame_transform().image_transform.clip_scale[0] = delta1; \r
- d_frame2->frame_transform().image_transform.clip_scale[0] = delta2; \r
+ d_frame1.transform().image_transform.clip_scale[0] = delta1; \r
+ d_frame2.transform().image_transform.clip_scale[0] = delta2; \r
}\r
\r
- const auto s_frame = s_frame1->frame_transform() == s_frame2->frame_transform() ? s_frame2 : draw_frame::interlace(s_frame1, s_frame2, mode_);\r
- const auto d_frame = d_frame1->frame_transform() == d_frame2->frame_transform() ? d_frame2 : draw_frame::interlace(d_frame1, d_frame2, mode_);\r
+ const auto s_frame = s_frame1.transform() == s_frame2.transform() ? s_frame2 : draw_frame::interlace(s_frame1, s_frame2, mode_);\r
+ const auto d_frame = d_frame1.transform() == d_frame2.transform() ? d_frame2 : draw_frame::interlace(d_frame1, d_frame2, mode_);\r
\r
return draw_frame::over(s_frame, d_frame);\r
}\r
#include "mixer/mixer.h"\r
#include "consumer/output.h"\r
#include "frame/data_frame.h"\r
+#include "frame/draw_frame.h"\r
#include "frame/frame_factory.h"\r
\r
#include <common/diagnostics/graph.h>\r
video_channel(const video_channel&);\r
video_channel& operator=(const video_channel&);\r
public:\r
+\r
+ /// Static Members\r
+\r
+ /// Constructors\r
+\r
explicit video_channel(int index, const video_format_desc& format_desc, spl::unique_ptr<image_mixer> image_mixer);\r
\r
- const core::stage& stage() const;\r
- core::stage& stage();\r
- const core::mixer& mixer() const;\r
- core::mixer& mixer();\r
- const core::output& output() const;\r
- core::output& output();\r
- \r
- core::video_format_desc video_format_desc() const;\r
- void video_format_desc(const core::video_format_desc& format_desc);\r
- \r
- spl::shared_ptr<core::frame_factory> frame_factory();\r
-\r
- boost::property_tree::wptree info() const;\r
+ /// Methods\r
\r
// observable<spl::shared_ptr<const class data_frame>>\r
\r
\r
virtual void subscribe(const monitor::observable::observer_ptr& o) override;\r
virtual void unsubscribe(const monitor::observable::observer_ptr& o) override;\r
+\r
+ /// Properties\r
+\r
+ const core::stage& stage() const;\r
+ core::stage& stage();\r
+ const core::mixer& mixer() const;\r
+ core::mixer& mixer();\r
+ const core::output& output() const;\r
+ core::output& output();\r
+ \r
+ core::video_format_desc video_format_desc() const;\r
+ void video_format_desc(const core::video_format_desc& format_desc);\r
+ \r
+ spl::shared_ptr<core::frame_factory> frame_factory();\r
+\r
+ boost::property_tree::wptree info() const;\r
private:\r
struct impl;\r
spl::shared_ptr<impl> impl_;\r
\r
class decklink_producer : boost::noncopyable, public IDeckLinkInputCallback\r
{ \r
- spl::shared_ptr<diagnostics::graph> graph_;\r
- boost::timer tick_timer_;\r
- boost::timer frame_timer_;\r
+ spl::shared_ptr<diagnostics::graph> graph_;\r
+ boost::timer tick_timer_;\r
+ boost::timer frame_timer_;\r
\r
- CComPtr<IDeckLink> decklink_;\r
- CComQIPtr<IDeckLinkInput> input_;\r
- CComQIPtr<IDeckLinkAttributes > attributes_;\r
+ CComPtr<IDeckLink> decklink_;\r
+ CComQIPtr<IDeckLinkInput> input_;\r
+ CComQIPtr<IDeckLinkAttributes > attributes_;\r
\r
- const std::wstring model_name_;\r
- const size_t device_index_;\r
- const std::wstring filter_;\r
+ const std::wstring model_name_;\r
+ const size_t device_index_;\r
+ const std::wstring filter_;\r
\r
- core::video_format_desc format_desc_;\r
- std::vector<int> audio_cadence_;\r
- boost::circular_buffer<size_t> sync_buffer_;\r
- ffmpeg::frame_muxer muxer_;\r
+ core::video_format_desc format_desc_;\r
+ std::vector<int> audio_cadence_;\r
+ boost::circular_buffer<size_t> sync_buffer_;\r
+ ffmpeg::frame_muxer muxer_;\r
\r
- tbb::atomic<int> flags_;\r
- spl::shared_ptr<core::frame_factory> frame_factory_;\r
+ tbb::atomic<int> flags_;\r
+ spl::shared_ptr<core::frame_factory> frame_factory_;\r
\r
- tbb::concurrent_bounded_queue<\r
- spl::shared_ptr<core::draw_frame>> frame_buffer_;\r
+ tbb::concurrent_bounded_queue<core::draw_frame> frame_buffer_;\r
\r
- std::exception_ptr exception_; \r
+ std::exception_ptr exception_; \r
\r
public:\r
decklink_producer(const core::video_format_desc& format_desc, size_t device_index, const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
return S_OK;\r
}\r
\r
- spl::shared_ptr<core::draw_frame> get_frame(int flags)\r
+ core::draw_frame get_frame(int flags)\r
{\r
if(exception_ != nullptr)\r
std::rethrow_exception(exception_);\r
\r
flags_ = flags;\r
\r
- spl::shared_ptr<core::draw_frame> frame = core::draw_frame::late();\r
+ core::draw_frame frame = core::draw_frame::late();\r
if(!frame_buffer_.try_pop(frame))\r
graph_->set_tag("late-frame");\r
graph_->set_value("output-buffer", static_cast<float>(frame_buffer_.size())/static_cast<float>(frame_buffer_.capacity())); \r
{ \r
std::unique_ptr<decklink_producer> producer_;\r
const uint32_t length_;\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ core::draw_frame last_frame_;\r
executor executor_;\r
public:\r
explicit decklink_producer_proxy(const spl::shared_ptr<core::frame_factory>& frame_factory, const core::video_format_desc& format_desc, size_t device_index, const std::wstring& filter_str, uint32_t length)\r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int flags) override\r
+ virtual core::draw_frame receive(int flags) override\r
{\r
auto frame = producer_->get_frame(flags);\r
\r
return frame;\r
}\r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return core::draw_frame::still(last_frame_);\r
}\r
<ClInclude Include="producer\ffmpeg_producer.h">\r
<Filter>source\producer</Filter>\r
</ClInclude>\r
- <ClInclude Include="producer\video\video_decoder.h">\r
- <Filter>source\producer\video</Filter>\r
- </ClInclude>\r
<ClInclude Include="producer\audio\audio_decoder.h">\r
<Filter>source\producer\audio</Filter>\r
</ClInclude>\r
<ClInclude Include="producer\tbb_avcodec.h">\r
<Filter>source\producer</Filter>\r
</ClInclude>\r
+ <ClInclude Include="producer\video\video_decoder.h">\r
+ <Filter>source\producer\video</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
\r
int64_t frame_number_;\r
\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ core::draw_frame last_frame_;\r
\r
public:\r
explicit ffmpeg_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, const std::wstring& filter, bool loop, uint32_t start, uint32_t length) \r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int flags) override\r
+ virtual core::draw_frame receive(int flags) override\r
{ \r
boost::timer frame_timer;\r
\r
return frame;\r
}\r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return core::draw_frame::still(last_frame_);\r
}\r
BOOST_THROW_EXCEPTION(invalid_argument());\r
}\r
\r
- bool try_decode_frame(spl::shared_ptr<core::draw_frame>& result, int flags)\r
+ bool try_decode_frame(core::draw_frame& result, int flags)\r
{\r
for(int n = 0; n < 32; ++n)\r
{\r
{ \r
std::queue<std::queue<spl::unique_ptr<data_frame>>> video_streams_;\r
std::queue<core::audio_buffer> audio_streams_;\r
- std::queue<spl::shared_ptr<draw_frame>> frame_buffer_;\r
+ std::queue<draw_frame> frame_buffer_;\r
display_mode display_mode_;\r
const double in_fps_;\r
const video_format_desc format_desc_;\r
}\r
}\r
\r
- bool try_pop(spl::shared_ptr<core::draw_frame>& result)\r
+ bool try_pop(core::draw_frame& result)\r
{\r
if(!frame_buffer_.empty())\r
{\r
case display_mode::deinterlace_bob: \r
case display_mode::deinterlace: \r
{\r
- frame_buffer_.push(spl::make_shared<draw_frame>(std::move(frame1)));\r
+ frame_buffer_.push(core::draw_frame(std::move(frame1)));\r
break;\r
}\r
case display_mode::interlace: \r
auto frame2 = pop_video();\r
\r
frame_buffer_.push(core::draw_frame::interlace(\r
- spl::make_shared<core::draw_frame>(std::move(frame1)),\r
- spl::make_shared<core::draw_frame>(std::move(frame2)),\r
+ core::draw_frame(std::move(frame1)),\r
+ core::draw_frame(std::move(frame2)),\r
format_desc_.field_mode)); \r
break;\r
}\r
{\r
boost::range::push_back(frame1->audio_data(), pop_audio());\r
\r
- auto draw_frame = spl::make_shared<core::draw_frame>(std::move(frame1));\r
+ auto draw_frame = core::draw_frame(std::move(frame1));\r
frame_buffer_.push(draw_frame);\r
frame_buffer_.push(draw_frame);\r
break;\r
{ \r
pop_video(); // Throw away\r
\r
- frame_buffer_.push(spl::make_shared<draw_frame>(std::move(frame1)));\r
+ frame_buffer_.push(core::draw_frame(std::move(frame1)));\r
break;\r
}\r
default:\r
: impl_(new impl(in_fps, frame_factory, filter)){}\r
void frame_muxer::push(const std::shared_ptr<AVFrame>& video_frame, int flags){impl_->push(video_frame, flags);}\r
void frame_muxer::push(const std::shared_ptr<core::audio_buffer>& audio_samples){return impl_->push(audio_samples);}\r
-bool frame_muxer::try_pop(spl::shared_ptr<core::draw_frame>& result){return impl_->try_pop(result);}\r
+bool frame_muxer::try_pop(core::draw_frame& result){return impl_->try_pop(result);}\r
uint32_t frame_muxer::calc_nb_frames(uint32_t nb_frames) const {return impl_->calc_nb_frames(nb_frames);}\r
bool frame_muxer::video_ready() const{return impl_->video_ready();}\r
bool frame_muxer::audio_ready() const{return impl_->audio_ready();}\r
bool video_ready() const;\r
bool audio_ready() const;\r
\r
- bool try_pop(spl::shared_ptr<core::draw_frame>& result);\r
+ bool try_pop(core::draw_frame& result);\r
\r
uint32_t calc_nb_frames(uint32_t nb_frames) const;\r
private:\r
const std::shared_ptr<core::frame_factory> frame_factory_;\r
\r
CComObject<caspar::flash::FlashAxContainer>* ax_;\r
- spl::shared_ptr<core::draw_frame> head_;\r
+ core::draw_frame head_;\r
bitmap bmp_;\r
\r
spl::shared_ptr<diagnostics::graph> graph_;\r
}\r
}\r
\r
- spl::shared_ptr<core::draw_frame> render()\r
+ core::draw_frame render()\r
{ \r
const float frame_time = 1.0f/fps();\r
\r
auto frame = frame_factory_->create_frame(this, desc, fps(), core::field_mode::progressive);\r
\r
A_memcpy(frame->image_data(0).begin(), bmp_.data(), width_*height_*4);\r
- head_ = spl::make_shared<core::draw_frame>(std::move(frame)); \r
+ head_ = core::draw_frame(std::move(frame)); \r
} \r
\r
graph_->set_value("frame-time", static_cast<float>(frame_timer_.elapsed()/frame_time)*0.5f);\r
\r
struct flash_producer : public core::frame_producer\r
{ \r
- const std::wstring filename_; \r
- const spl::shared_ptr<core::frame_factory> frame_factory_;\r
- const int width_;\r
- const int height_;\r
- const int buffer_size_;\r
+ const std::wstring filename_; \r
+ const spl::shared_ptr<core::frame_factory> frame_factory_;\r
+ const int width_;\r
+ const int height_;\r
+ const int buffer_size_;\r
\r
- tbb::atomic<int> fps_;\r
- tbb::atomic<bool> sync_;\r
+ tbb::atomic<int> fps_;\r
+ tbb::atomic<bool> sync_;\r
\r
- spl::shared_ptr<diagnostics::graph> graph_;\r
+ spl::shared_ptr<diagnostics::graph> graph_;\r
\r
- std::queue<spl::shared_ptr<core::draw_frame>> frame_buffer_;\r
- tbb::concurrent_bounded_queue<spl::shared_ptr<core::draw_frame>> output_buffer_;\r
+ std::queue<core::draw_frame> frame_buffer_;\r
+ tbb::concurrent_bounded_queue<core::draw_frame> output_buffer_;\r
\r
- std::unique_ptr<flash_renderer> renderer_;\r
+ std::unique_ptr<flash_renderer> renderer_;\r
\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ core::draw_frame last_frame_;\r
\r
- executor executor_; \r
+ executor executor_; \r
public:\r
flash_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int width, int height) \r
: filename_(filename) \r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int) override\r
+ virtual core::draw_frame receive(int) override\r
{ \r
auto frame = core::draw_frame::late();\r
\r
return frame;\r
}\r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return core::draw_frame::still(last_frame_);\r
}\r
\r
struct image_producer : public core::frame_producer\r
{ \r
- const std::wstring filename_;\r
- spl::shared_ptr<core::draw_frame> frame_;\r
+ const std::wstring filename_;\r
+ core::draw_frame frame_;\r
\r
explicit image_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename) \r
: filename_(filename)\r
auto frame = frame_factory->create_frame(this, desc);\r
\r
std::copy_n(FreeImage_GetBits(bitmap.get()), frame->image_data(0).size(), frame->image_data(0).begin());\r
- frame_ = spl::make_shared<core::draw_frame>(std::move(frame));\r
+ frame_ = core::draw_frame(std::move(frame));\r
}\r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int) override\r
+ virtual core::draw_frame receive(int) override\r
{\r
return frame_;\r
}\r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return frame_;\r
}\r
struct image_scroll_producer : public core::frame_producer\r
{ \r
const std::wstring filename_;\r
- std::vector<spl::shared_ptr<core::draw_frame>> frames_;\r
+ std::vector<core::draw_frame> frames_;\r
core::video_format_desc format_desc_;\r
int width_;\r
int height_;\r
\r
std::array<double, 2> start_offset_;\r
\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ core::draw_frame last_frame_;\r
\r
explicit image_scroll_producer(const spl::shared_ptr<core::frame_factory>& frame_factory, const std::wstring& filename, int speed) \r
: filename_(filename)\r
count = 0;\r
}\r
\r
- frames_.push_back(spl::make_shared<core::draw_frame>(std::move(frame)));\r
+ frames_.push_back(core::draw_frame(std::move(frame)));\r
}\r
\r
if(speed_ < 0.0)\r
count = 0;\r
}\r
\r
- frames_.push_back(spl::make_shared<core::draw_frame>(std::move(frame)));\r
+ frames_.push_back(core::draw_frame(std::move(frame)));\r
}\r
\r
std::reverse(frames_.begin(), frames_.end());\r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int) override\r
+ virtual core::draw_frame receive(int) override\r
{ \r
delta_ += speed_;\r
\r
\r
for(int n = 0; n < frames_.size(); ++n)\r
{\r
- frames_[n]->frame_transform().image_transform.fill_translation[0] = start_offset_[0];\r
- frames_[n]->frame_transform().image_transform.fill_translation[1] = start_offset_[1] - (n+1) + delta_ * 0.5/static_cast<double>(format_desc_.height);\r
+ frames_[n].transform().image_transform.fill_translation[0] = start_offset_[0];\r
+ frames_[n].transform().image_transform.fill_translation[1] = start_offset_[1] - (n+1) + delta_ * 0.5/static_cast<double>(format_desc_.height);\r
}\r
}\r
else\r
\r
for(int n = 0; n < frames_.size(); ++n)\r
{\r
- frames_[n]->frame_transform().image_transform.fill_translation[0] = start_offset_[0] - (n+1) + delta_ * 0.5/static_cast<double>(format_desc_.width); \r
- frames_[n]->frame_transform().image_transform.fill_translation[1] = start_offset_[1];\r
+ frames_[n].transform().image_transform.fill_translation[0] = start_offset_[0] - (n+1) + delta_ * 0.5/static_cast<double>(format_desc_.width); \r
+ frames_[n].transform().image_transform.fill_translation[1] = start_offset_[1];\r
}\r
}\r
\r
- return last_frame_ = spl::make_shared<core::draw_frame>(frames_);\r
+ return last_frame_ = core::draw_frame(frames_);\r
}\r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return core::draw_frame::still(last_frame_);\r
}\r
const spl::shared_ptr<core::frame_factory> frame_factory_;\r
\r
tbb::concurrent_bounded_queue<std::shared_ptr<const core::data_frame>> input_buffer_;\r
- std::queue<spl::shared_ptr<core::draw_frame>> frame_buffer_;\r
+ std::queue<core::draw_frame> frame_buffer_;\r
uint64_t frame_number_;\r
\r
- spl::shared_ptr<core::draw_frame> last_frame_;\r
+ core::draw_frame last_frame_;\r
\r
public:\r
explicit reroute_producer(const spl::shared_ptr<core::frame_factory>& frame_factory) \r
\r
// frame_producer\r
\r
- virtual spl::shared_ptr<core::draw_frame> receive(int) override\r
+ virtual core::draw_frame receive(int) override\r
{\r
if(!frame_buffer_.empty())\r
{\r
- auto frame = frame_buffer_.front();\r
+ auto frame = std::move(frame_buffer_.front());\r
frame_buffer_.pop();\r
return last_frame_ = frame;\r
}\r
A_memcpy(frame->image_data(0).begin(), read_frame->image_data().begin(), read_frame->image_data().size());\r
boost::push_back(frame->audio_data(), read_frame->audio_data());\r
\r
- auto draw_frame = spl::make_shared<core::draw_frame>(std::move(frame));\r
+ auto draw_frame = core::draw_frame(std::move(frame));\r
\r
frame_buffer_.push(draw_frame);\r
\r
return receive(0);\r
} \r
\r
- virtual spl::shared_ptr<core::draw_frame> last_frame() const override\r
+ virtual core::draw_frame last_frame() const override\r
{\r
return core::draw_frame::still(last_frame_);\r
}\r