From f09adb004af5d444dd8e5f1a13e12ad4641a595d Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Tue, 1 Nov 2016 21:10:56 +0100 Subject: [PATCH] [general] Abstracted the concept of a key only frame so that readers of const_frame can be transparently tricked into accessing key only data. --- core/frame/frame.cpp | 58 ++++++++++++++++++++++++++++++++------------ core/frame/frame.h | 38 +++++++++++++++-------------- 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/core/frame/frame.cpp b/core/frame/frame.cpp index 19a83d286..f2c5fa01a 100644 --- a/core/frame/frame.cpp +++ b/core/frame/frame.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -40,9 +41,9 @@ #include namespace caspar { namespace core { - + struct mutable_frame::impl : boost::noncopyable -{ +{ std::vector> buffers_; core::mutable_audio_buffer audio_data_; const core::pixel_format_desc desc_; @@ -50,7 +51,7 @@ struct mutable_frame::impl : boost::noncopyable const void* tag_; core::frame_geometry geometry_ = frame_geometry::get_default(); caspar::timer since_created_timer_; - + impl( std::vector> buffers, mutable_audio_buffer audio_data, @@ -68,7 +69,7 @@ struct mutable_frame::impl : boost::noncopyable CASPAR_THROW_EXCEPTION(invalid_argument() << msg_info("mutable_frame: null argument")); } }; - + mutable_frame::mutable_frame( std::vector> image_buffers, mutable_audio_buffer audio_data, @@ -91,8 +92,8 @@ const core::mutable_audio_buffer& mutable_frame::audio_data() const{return impl_ array& mutable_frame::image_data(std::size_t index){return impl_->buffers_.at(index);} core::mutable_audio_buffer& mutable_frame::audio_data(){return impl_->audio_data_;} std::size_t mutable_frame::width() const{return impl_->desc_.planes.at(0).width;} -std::size_t mutable_frame::height() const{return impl_->desc_.planes.at(0).height;} -const void* mutable_frame::stream_tag()const{return impl_->tag_;} +std::size_t mutable_frame::height() const{return impl_->desc_.planes.at(0).height;} +const void* mutable_frame::stream_tag()const{return impl_->tag_;} const frame_geometry& mutable_frame::geometry() const { return impl_->geometry_; } void mutable_frame::set_geometry(const frame_geometry& g) { impl_->geometry_ = g; } caspar::timer mutable_frame::since_created() const { return impl_->since_created_timer_; } @@ -105,7 +106,7 @@ const const_frame& const_frame::empty() } struct const_frame::impl : boost::noncopyable -{ +{ mutable std::vector>> future_buffers_; mutable core::audio_buffer audio_data_; const core::pixel_format_desc desc_; @@ -115,35 +116,48 @@ struct const_frame::impl : boost::noncopyable caspar::timer since_created_timer_; bool should_record_age_; mutable tbb::atomic recorded_age_; + std::shared_future> key_only_on_demand_; impl(const void* tag) : audio_data_(0, 0, true, 0) , desc_(core::pixel_format::invalid) , channel_layout_(audio_channel_layout::invalid()) - , tag_(tag) + , tag_(tag) , geometry_(frame_geometry::get_default()) , should_record_age_(true) { recorded_age_ = 0; } - + impl( std::shared_future> image, audio_buffer audio_data, const void* tag, const core::pixel_format_desc& desc, - const core::audio_channel_layout& channel_layout) + const core::audio_channel_layout& channel_layout, + caspar::timer since_created_timer = caspar::timer()) : audio_data_(std::move(audio_data)) , desc_(desc) , channel_layout_(channel_layout) , tag_(tag) , geometry_(frame_geometry::get_default()) + , since_created_timer_(std::move(since_created_timer)) , should_record_age_(false) { if (desc.format != core::pixel_format::bgra) CASPAR_THROW_EXCEPTION(not_implemented()); - - future_buffers_.push_back(std::move(image)); + + future_buffers_.push_back(image); + + key_only_on_demand_ = std::async(std::launch::deferred, [image] + { + auto fill = image.get(); + auto key = cache_aligned_vector(fill.size()); + + aligned_memshfl(key.data(), fill.data(), fill.size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303); + + return array(key.data(), key.size(), false, std::move(key)); + }).share(); } impl(mutable_frame&& other) @@ -172,6 +186,11 @@ struct const_frame::impl : boost::noncopyable return tag_ != empty().stream_tag() ? future_buffers_.at(index).get() : array(nullptr, 0, true, 0); } + spl::shared_ptr key_only() const + { + return spl::make_shared(key_only_on_demand_, audio_data_, tag_, desc_, channel_layout_, since_created_timer_); + } + std::size_t width() const { return tag_ != empty().stream_tag() ? desc_.planes.at(0).width : 0; @@ -200,7 +219,7 @@ struct const_frame::impl : boost::noncopyable return static_cast(since_created_timer_.elapsed() * 1000.0); } }; - + const_frame::const_frame(const void* tag) : impl_(new impl(tag)){} const_frame::const_frame( std::shared_future> image, @@ -232,11 +251,18 @@ const core::audio_channel_layout& const_frame::audio_channel_layout()const { ret array const_frame::image_data(int index)const{return impl_->image_data(index);} const core::audio_buffer& const_frame::audio_data()const{return impl_->audio_data_;} std::size_t const_frame::width()const{return impl_->width();} -std::size_t const_frame::height()const{return impl_->height();} -std::size_t const_frame::size()const{return impl_->size();} -const void* const_frame::stream_tag()const{return impl_->tag_;} +std::size_t const_frame::height()const{return impl_->height();} +std::size_t const_frame::size()const{return impl_->size();} +const void* const_frame::stream_tag()const{return impl_->tag_;} const frame_geometry& const_frame::geometry() const { return impl_->geometry_; } void const_frame::set_geometry(const frame_geometry& g) { impl_->geometry_ = g; } int64_t const_frame::get_age_millis() const { return impl_->get_age_millis(); } +const_frame const_frame::key_only() const +{ + auto result = const_frame(); + result.impl_ = impl_->key_only(); + + return result; +} }} diff --git a/core/frame/frame.h b/core/frame/frame.h index 6ae3d0a04..fff5382c8 100644 --- a/core/frame/frame.h +++ b/core/frame/frame.h @@ -18,7 +18,7 @@ FORWARD1(boost, template class shared_future); namespace caspar { namespace core { - + typedef caspar::array audio_buffer; typedef cache_aligned_vector mutable_audio_buffer; class frame_geometry; @@ -27,15 +27,15 @@ class mutable_frame final { mutable_frame(const mutable_frame&); mutable_frame& operator=(const mutable_frame&); -public: +public: // Static Members // Constructors - explicit mutable_frame(std::vector> image_buffers, + explicit mutable_frame(std::vector> image_buffers, mutable_audio_buffer audio_data, - const void* tag, + const void* tag, const pixel_format_desc& desc, const audio_channel_layout& channel_layout); ~mutable_frame(); @@ -46,9 +46,9 @@ public: mutable_frame& operator=(mutable_frame&& other); void swap(mutable_frame& other); - + // Properties - + const core::pixel_format_desc& pixel_format_desc() const; const core::audio_channel_layout& audio_channel_layout() const; @@ -57,17 +57,17 @@ public: array& image_data(std::size_t index = 0); core::mutable_audio_buffer& audio_data(); - + std::size_t width() const; std::size_t height() const; - + const void* stream_tag() const; const core::frame_geometry& geometry() const; void set_geometry(const frame_geometry& g); caspar::timer since_created() const; - + private: struct impl; spl::unique_ptr impl_; @@ -75,7 +75,7 @@ private: class const_frame final { -public: +public: // Static Members @@ -84,9 +84,9 @@ public: // Constructors explicit const_frame(const void* tag = nullptr); - explicit const_frame(std::shared_future> image, - audio_buffer audio_data, - const void* tag, + explicit const_frame(std::shared_future> image, + audio_buffer audio_data, + const void* tag, const pixel_format_desc& desc, const audio_channel_layout& channel_layout); const_frame(mutable_frame&& other); @@ -98,19 +98,21 @@ public: const_frame& operator=(const_frame&& other); const_frame(const const_frame&); const_frame& operator=(const const_frame& other); - + + const_frame key_only() const; + // Properties - + const core::pixel_format_desc& pixel_format_desc() const; const core::audio_channel_layout& audio_channel_layout() const; array image_data(int index = 0) const; const core::audio_buffer& audio_data() const; - + std::size_t width() const; std::size_t height() const; std::size_t size() const; - + const void* stream_tag() const; const core::frame_geometry& geometry() const; @@ -121,7 +123,7 @@ public: bool operator!=(const const_frame& other); bool operator<(const const_frame& other); bool operator>(const const_frame& other); - + private: struct impl; spl::shared_ptr impl_; -- 2.39.2