]> git.sesse.net Git - casparcg/commitdiff
[general] Abstracted the concept of a key only frame so that readers of const_frame...
authorHelge Norberg <helge.norberg@svt.se>
Tue, 1 Nov 2016 20:10:56 +0000 (21:10 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Tue, 1 Nov 2016 20:10:56 +0000 (21:10 +0100)
core/frame/frame.cpp
core/frame/frame.h

index 19a83d286e1671a9d4e4d8b9775debe3122e6a1c..f2c5fa01a4b0108794895f0a02ec7de1ebae1ed4 100644 (file)
@@ -27,6 +27,7 @@
 #include <common/array.h>
 #include <common/future.h>
 #include <common/timer.h>
+#include <common/memshfl.h>
 
 #include <core/frame/frame_visitor.h>
 #include <core/frame/pixel_format.h>
@@ -40,9 +41,9 @@
 #include <boost/thread/future.hpp>
 
 namespace caspar { namespace core {
-               
+
 struct mutable_frame::impl : boost::noncopyable
-{                      
+{
        std::vector<array<std::uint8_t>>                        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<array<std::uint8_t>> 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<array<std::uint8_t>> image_buffers,
                mutable_audio_buffer audio_data,
@@ -91,8 +92,8 @@ const core::mutable_audio_buffer& mutable_frame::audio_data() const{return impl_
 array<std::uint8_t>& 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<std::shared_future<array<const std::uint8_t>>>      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<int64_t>                                                                            recorded_age_;
+       std::shared_future<array<const std::uint8_t>>                                           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<array<const std::uint8_t>> 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<std::uint8_t>(fill.size());
+
+                       aligned_memshfl(key.data(), fill.data(), fill.size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);
+
+                       return array<const std::uint8_t>(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<const std::uint8_t>(nullptr, 0, true, 0);
        }
 
+       spl::shared_ptr<impl> key_only() const
+       {
+               return spl::make_shared<impl>(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<int64_t>(since_created_timer_.elapsed() * 1000.0);
        }
 };
-       
+
 const_frame::const_frame(const void* tag) : impl_(new impl(tag)){}
 const_frame::const_frame(
                std::shared_future<array<const std::uint8_t>> image,
@@ -232,11 +251,18 @@ const core::audio_channel_layout& const_frame::audio_channel_layout()const { ret
 array<const std::uint8_t> 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;
+}
 
 }}
index 6ae3d0a044c6490af1d3f7a035b6bee9a6ee8a2f..fff5382c845a715e34cecb93380e2dd107852be5 100644 (file)
@@ -18,7 +18,7 @@
 FORWARD1(boost, template<typename> class shared_future);
 
 namespace caspar { namespace core {
-       
+
 typedef caspar::array<const int32_t> audio_buffer;
 typedef cache_aligned_vector<int32_t> 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<array<std::uint8_t>> image_buffers, 
+       explicit mutable_frame(std::vector<array<std::uint8_t>> 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<std::uint8_t>& 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> 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<array<const std::uint8_t>> image, 
-                                               audio_buffer audio_data, 
-                                               const void* tag, 
+       explicit const_frame(std::shared_future<array<const std::uint8_t>> 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<const std::uint8_t> 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> impl_;