]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Fixed data race in video_channel_context.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 3 Jun 2011 09:51:05 +0000 (09:51 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 3 Jun 2011 09:51:05 +0000 (09:51 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@840 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

13 files changed:
core/consumer/frame_consumer_device.cpp
core/consumer/frame_consumer_device.h
core/mixer/frame_mixer_device.cpp
core/mixer/frame_mixer_device.h
core/mixer/image/image_mixer.cpp
core/mixer/image/image_mixer.h
core/producer/frame/frame_factory.h
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/video_channel.cpp
core/video_channel.h
core/video_channel_context.h
modules/flash/producer/flash_producer.cpp

index 8357d1c199ee7e828a89b451828f9d55c8642eb8..3cb0ecaa442e46844d74bb1cf942ee4b1f8b5f4a 100644 (file)
@@ -81,8 +81,8 @@ public:
 \r
        void add(int index, safe_ptr<frame_consumer>&& consumer)\r
        {               \r
-               consumer->initialize(channel_.format_desc);\r
-               channel_.execution.invoke([&]\r
+               consumer->initialize(channel_.get_format_desc());\r
+               channel_.execution().invoke([&]\r
                {\r
                        this->remove(index);\r
                        consumers_.insert(std::make_pair(index, consumer));\r
@@ -102,7 +102,7 @@ public:
 \r
        void remove(int index)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {\r
                        auto it = consumers_.find(index);\r
                        if(it != consumers_.end())\r
@@ -116,7 +116,7 @@ public:
        void operator()(const safe_ptr<read_frame>& frame)\r
        {               \r
                if(!has_synchronization_clock())\r
-                       timer_.tick(1.0/channel_.format_desc.fps);\r
+                       timer_.tick(1.0/channel_.get_format_desc().fps);\r
 \r
                frame_timer_.restart();\r
                                                \r
@@ -126,8 +126,8 @@ public:
        \r
                for_each_consumer([&](safe_ptr<frame_consumer>& consumer)\r
                {\r
-                       if(consumer->get_video_format_desc() != channel_.format_desc)\r
-                               consumer->initialize(channel_.format_desc);\r
+                       if(consumer->get_video_format_desc() != channel_.get_format_desc())\r
+                               consumer->initialize(channel_.get_format_desc());\r
 \r
                        auto pair = buffer_[consumer->buffer_depth()-buffer_depth().first];\r
                        auto frame = consumer->key_only() ? pair.second : pair.first;\r
@@ -136,9 +136,9 @@ public:
                                consumer->send(frame);\r
                });\r
 \r
-               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
                        \r
-               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
                tick_timer_.restart();\r
        }\r
 \r
@@ -162,7 +162,7 @@ private:
                if(has_key_only)\r
                {\r
                        // Currently do key_only transform on cpu. Unsure if the extra 400MB/s (1080p50) overhead is worth it to do it on gpu.\r
-                       auto key_data = channel_.ogl.create_host_buffer(frame->image_data().size(), host_buffer::write_only);                           \r
+                       auto key_data = channel_.ogl().create_host_buffer(frame->image_data().size(), host_buffer::write_only);                         \r
                        fast_memsfhl(key_data->data(), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
                        std::vector<int16_t> audio_data(frame->audio_data().begin(), frame->audio_data().end());\r
                        return make_safe<read_frame>(std::move(key_data), std::move(audio_data));\r
index 23771bfefb5896153fc371f0e49c1f750c4cf5e7..ea3a570e7e57a14a0a7460675bd347a734caf243 100644 (file)
@@ -31,7 +31,7 @@ class executor;
        \r
 namespace core {\r
        \r
-struct video_channel_context;\r
+class video_channel_context;;\r
 \r
 class frame_consumer_device : boost::noncopyable\r
 {\r
index 300356d535728395c3ea727e3e35264f0475a19d..e9f80c804b38c351ea797d449e52028e4a5edefa 100644 (file)
@@ -124,9 +124,9 @@ public:
                auto image = mix_image(frames);\r
                auto audio = mix_audio(frames);\r
                        \r
-               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
                \r
-               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
                tick_timer_.restart();\r
 \r
                return make_safe<read_frame>(std::move(image), std::move(audio));\r
@@ -140,7 +140,7 @@ public:
        template<typename T>    \r
        void set_transform(const T& transform, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {\r
                        auto& root = boost::fusion::at_key<T>(root_transforms_);\r
 \r
@@ -153,7 +153,7 @@ public:
        template<typename T>\r
        void set_transform(int index, const T& transform, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {\r
                        auto& transforms = boost::fusion::at_key<T>(transforms_);\r
 \r
@@ -166,7 +166,7 @@ public:
        template<typename T>\r
        void apply_transform(const std::function<T(const T&)>& transform, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               return channel_.execution.invoke([&]\r
+               return channel_.execution().invoke([&]\r
                {\r
                        auto& root = boost::fusion::at_key<T>(root_transforms_);\r
 \r
@@ -179,7 +179,7 @@ public:
        template<typename T>\r
        void apply_transform(int index, const std::function<T(T)>& transform, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {\r
                        auto& transforms = boost::fusion::at_key<T>(transforms_);\r
 \r
@@ -192,7 +192,7 @@ public:
        template<typename T>\r
        void reset_transform(unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {\r
                        auto& transforms = boost::fusion::at_key<T>(transforms_);\r
 \r
@@ -205,7 +205,7 @@ public:
        template<typename T>\r
        void reset_transform(int index, unsigned int mix_duration, const std::wstring& tween)\r
        {\r
-               channel_.execution.invoke([&]\r
+               channel_.execution().invoke([&]\r
                {               \r
                        set_transform(T(), mix_duration, tween);\r
                });\r
@@ -227,7 +227,7 @@ private:
                {\r
                        image_mixer_.begin_layer();\r
                        \r
-                       if(channel_.format_desc.mode != core::video_mode::progressive)\r
+                       if(channel_.get_format_desc().mode != core::video_mode::progressive)\r
                        {\r
                                auto frame1 = make_safe<core::basic_frame>(frame.second);\r
                                auto frame2 = make_safe<core::basic_frame>(frame.second);\r
@@ -236,7 +236,7 @@ private:
                                frame2->get_image_transform() = root_image_transform.fetch_and_tick(1)*image_transforms[frame.first].fetch_and_tick(1);\r
 \r
                                if(frame1->get_image_transform() != frame2->get_image_transform())\r
-                                       core::basic_frame::interlace(frame1, frame2, channel_.format_desc.mode)->accept(image_mixer_);\r
+                                       core::basic_frame::interlace(frame1, frame2, channel_.get_format_desc().mode)->accept(image_mixer_);\r
                                else\r
                                        frame2->accept(image_mixer_);\r
                        }\r
@@ -260,7 +260,7 @@ private:
 \r
                BOOST_FOREACH(auto& frame, frames)\r
                {\r
-                       const unsigned int num = channel_.format_desc.mode == core::video_mode::progressive ? 1 : 2;\r
+                       const unsigned int num = channel_.get_format_desc().mode == core::video_mode::progressive ? 1 : 2;\r
 \r
                        auto frame1 = make_safe<core::basic_frame>(frame.second);\r
                        frame1->get_audio_transform() = root_audio_transform.fetch_and_tick(num)*audio_transforms[frame.first].fetch_and_tick(num);\r
@@ -273,7 +273,7 @@ private:
        \r
 frame_mixer_device::frame_mixer_device(video_channel_context& video_channel) : impl_(new implementation(video_channel)){}\r
 safe_ptr<core::read_frame> frame_mixer_device::operator()(const std::map<int, safe_ptr<core::basic_frame>>& frames){ return (*impl_)(frames);}\r
-const core::video_format_desc& frame_mixer_device::get_video_format_desc() const { return impl_->channel_.format_desc; }\r
+core::video_format_desc frame_mixer_device::get_video_format_desc() const { return impl_->channel_.get_format_desc(); }\r
 safe_ptr<core::write_frame> frame_mixer_device::create_frame(void* tag, const core::pixel_format_desc& desc){ return impl_->create_frame(tag, desc); }         \r
 safe_ptr<core::write_frame> frame_mixer_device::create_frame(void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt)\r
 {\r
index acac45e3d1c9cd12308b56cf456a84080a31a9c7..2410bdf403ee2002803f31dd1d2385e41f092d73 100644 (file)
@@ -37,7 +37,7 @@ class write_frame;
 class basic_frame;\r
 class audio_transform;\r
 class image_transform;\r
-struct video_channel_context;\r
+class video_channel_context;;\r
 \r
 class frame_mixer_device : public core::frame_factory\r
 {\r
@@ -49,7 +49,7 @@ public:
        safe_ptr<core::write_frame> create_frame(void* tag, const core::pixel_format_desc& desc);               \r
        safe_ptr<core::write_frame> create_frame(void* tag, size_t width, size_t height, core::pixel_format::type pix_fmt = core::pixel_format::bgra);          \r
        \r
-       const core::video_format_desc& get_video_format_desc() const; // nothrow\r
+       core::video_format_desc get_video_format_desc() const; // nothrow\r
 \r
        void set_image_transform(const core::image_transform& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
        void set_image_transform(int index, const core::image_transform& transform, unsigned int mix_duration = 0, const std::wstring& tween = L"linear");\r
index ada8ebf0ec00dfe200fb81969ad8d8d13c1f9db0..39f69e594359d05f441b181722798ac936cd4175 100644 (file)
@@ -76,11 +76,11 @@ struct image_mixer::implementation : boost::noncopyable
 public:\r
        implementation(video_channel_context& video_channel) \r
                : channel_(video_channel)\r
-               , read_buffer_(video_channel.ogl.create_host_buffer(video_channel.format_desc.size, host_buffer::read_only))\r
-               , draw_buffer_(video_channel.ogl.create_device_buffer(video_channel.format_desc.width, channel_.format_desc.height, 4))\r
-               , write_buffer_ (video_channel.ogl.create_device_buffer(video_channel.format_desc.width, channel_.format_desc.height, 4))\r
-               , local_key_buffer_(video_channel.ogl.create_device_buffer(video_channel.format_desc.width, channel_.format_desc.height, 1))\r
-               , layer_key_buffer_(video_channel.ogl.create_device_buffer(video_channel.format_desc.width, channel_.format_desc.height, 1))\r
+               , read_buffer_(video_channel.ogl().create_host_buffer(video_channel.get_format_desc().size, host_buffer::read_only))\r
+               , draw_buffer_(video_channel.ogl().create_device_buffer(video_channel.get_format_desc().width, channel_.get_format_desc().height, 4))\r
+               , write_buffer_ (video_channel.ogl().create_device_buffer(video_channel.get_format_desc().width, channel_.get_format_desc().height, 4))\r
+               , local_key_buffer_(video_channel.ogl().create_device_buffer(video_channel.get_format_desc().width, channel_.get_format_desc().height, 1))\r
+               , layer_key_buffer_(video_channel.ogl().create_device_buffer(video_channel.get_format_desc().width, channel_.get_format_desc().height, 1))\r
                , local_key_(false)\r
                , layer_key_(false)\r
        {\r
@@ -114,18 +114,18 @@ public:
 \r
        void reinitialize_buffers()\r
        {\r
-               read_buffer_      = channel_.ogl.create_host_buffer(channel_.format_desc.size, host_buffer::read_only);\r
-               draw_buffer_      = channel_.ogl.create_device_buffer(channel_.format_desc.width, channel_.format_desc.height, 4);\r
-               write_buffer_     = channel_.ogl.create_device_buffer(channel_.format_desc.width, channel_.format_desc.height, 4);\r
-               local_key_buffer_ = channel_.ogl.create_device_buffer(channel_.format_desc.width, channel_.format_desc.height, 1);\r
-               layer_key_buffer_ = channel_.ogl.create_device_buffer(channel_.format_desc.width, channel_.format_desc.height, 1);\r
-               channel_.ogl.gc();\r
+               read_buffer_      = channel_.ogl().create_host_buffer(channel_.get_format_desc().size, host_buffer::read_only);\r
+               draw_buffer_      = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
+               write_buffer_     = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 4);\r
+               local_key_buffer_ = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
+               layer_key_buffer_ = channel_.ogl().create_device_buffer(channel_.get_format_desc().width, channel_.get_format_desc().height, 1);\r
+               channel_.ogl().gc();\r
        }\r
 \r
        safe_ptr<host_buffer> render()\r
        {               \r
                auto read_buffer = read_buffer_;\r
-               auto result = channel_.ogl.begin_invoke([=]()  -> safe_ptr<host_buffer>\r
+               auto result = channel_.ogl().begin_invoke([=]()  -> safe_ptr<host_buffer>\r
                {\r
                        read_buffer->map();\r
                        return read_buffer;\r
@@ -133,9 +133,9 @@ public:
 \r
                auto render_queue = std::move(render_queue_);\r
 \r
-               channel_.ogl.begin_invoke([=]() mutable\r
+               channel_.ogl().begin_invoke([=]() mutable\r
                {\r
-                       if(draw_buffer_->width() != channel_.format_desc.width || draw_buffer_->height() != channel_.format_desc.height)\r
+                       if(draw_buffer_->width() != channel_.get_format_desc().width || draw_buffer_->height() != channel_.get_format_desc().height)\r
                                reinitialize_buffers();\r
 \r
                        local_key_ = false;\r
@@ -159,7 +159,7 @@ public:
                                {\r
                                        draw(layer.front());\r
                                        layer.pop();\r
-                                       channel_.ogl.yield(); // Allow quick buffer allocation to execute.\r
+                                       channel_.ogl().yield(); // Allow quick buffer allocation to execute.\r
                                }\r
 \r
                                layer_key_ = local_key_; // If there was only key in last layer then use it as key for the entire next layer.\r
@@ -171,7 +171,7 @@ public:
                        std::swap(draw_buffer_, write_buffer_);\r
 \r
                        // Start transfer from device to host.  \r
-                       read_buffer_ = channel_.ogl.create_host_buffer(channel_.format_desc.size, host_buffer::read_only);                                      \r
+                       read_buffer_ = channel_.ogl().create_host_buffer(channel_.get_format_desc().size, host_buffer::read_only);                                      \r
                        write_buffer_->write(*read_buffer_);\r
                });\r
 \r
@@ -217,12 +217,12 @@ public:
 \r
                // Draw\r
 \r
-               kernel_.draw(channel_.format_desc.width, channel_.format_desc.height, item.desc, item.transform, local_key, layer_key); \r
+               kernel_.draw(channel_.get_format_desc().width, channel_.get_format_desc().height, item.desc, item.transform, local_key, layer_key);     \r
        }\r
                        \r
        safe_ptr<write_frame> create_frame(void* tag, const core::pixel_format_desc& desc)\r
        {\r
-               return make_safe<write_frame>(channel_.ogl, reinterpret_cast<int>(tag), desc);\r
+               return make_safe<write_frame>(channel_.ogl(), reinterpret_cast<int>(tag), desc);\r
        }\r
 };\r
 \r
index afe17bf5357d2d549918f57d97bca6f02cafc64a..a6c83ef2fe9bded5076cff0aef791f7db6115072 100644 (file)
@@ -32,7 +32,7 @@ namespace caspar { namespace core {
 class write_frame;\r
 class host_buffer;\r
 class ogl_device;\r
-struct video_channel_context;\r
+class video_channel_context;;\r
 \r
 class image_mixer : public core::frame_visitor, boost::noncopyable\r
 {\r
index 26b896b0aad730f3cf1d3856300e401680c1b69a..30e7bcfc9c20d2143046e833ed9141edec80f6f2 100644 (file)
@@ -36,7 +36,7 @@ struct frame_factory : boost::noncopyable
        virtual safe_ptr<write_frame> create_frame(void* video_stream_tag, const pixel_format_desc& desc) = 0;\r
        virtual safe_ptr<write_frame> create_frame(void* video_stream_tag, size_t width, size_t height, pixel_format::type pix_fmt = pixel_format::bgra) = 0;           \r
        \r
-       virtual const video_format_desc& get_video_format_desc() const = 0; // nothrow\r
+       virtual video_format_desc get_video_format_desc() const = 0; // nothrow\r
 };\r
 \r
 }}
\ No newline at end of file
index 30edde024fdfe4d17431967a529fa4c9b7e13c82..21aa350da35944e06befba29bda664ca3523bee5 100644 (file)
@@ -110,9 +110,9 @@ public:
                        frames[layer.first] = layer.second.receive();\r
                });\r
                \r
-               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("frame-time", frame_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
 \r
-               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.format_desc.fps*0.5);\r
+               diag_->update_value("tick-time", tick_timer_.elapsed()*channel_.get_format_desc().fps*0.5);\r
                tick_timer_.restart();\r
 \r
                return frames;\r
@@ -120,37 +120,37 @@ public:
 \r
        void load(int index, const safe_ptr<frame_producer>& producer, bool preview)\r
        {\r
-               channel_.execution.invoke([&]{layers_[index].load(make_safe<destroy_producer_proxy>(channel_.destruction, producer), preview);});\r
+               channel_.execution().invoke([&]{layers_[index].load(make_safe<destroy_producer_proxy>(channel_.destruction(), producer), preview);});\r
        }\r
 \r
        void pause(int index)\r
        {               \r
-               channel_.execution.invoke([&]{layers_[index].pause();});\r
+               channel_.execution().invoke([&]{layers_[index].pause();});\r
        }\r
 \r
        void play(int index)\r
        {               \r
-               channel_.execution.invoke([&]{layers_[index].play();});\r
+               channel_.execution().invoke([&]{layers_[index].play();});\r
        }\r
 \r
        void stop(int index)\r
        {               \r
-               channel_.execution.invoke([&]{layers_[index].stop();});\r
+               channel_.execution().invoke([&]{layers_[index].stop();});\r
        }\r
 \r
        void clear(int index)\r
        {\r
-               channel_.execution.invoke([&]{layers_.erase(index);});\r
+               channel_.execution().invoke([&]{layers_.erase(index);});\r
        }\r
                \r
        void clear()\r
        {\r
-               channel_.execution.invoke([&]{layers_.clear();});\r
+               channel_.execution().invoke([&]{layers_.clear();});\r
        }       \r
        \r
        void swap_layer(int index, size_t other_index)\r
        {\r
-               channel_.execution.invoke([&]{layers_[index].swap(layers_[other_index]);});\r
+               channel_.execution().invoke([&]{layers_[index].swap(layers_[other_index]);});\r
        }\r
 \r
        void swap_layer(int index, size_t other_index, frame_producer_device& other)\r
@@ -159,12 +159,12 @@ public:
                        swap_layer(index, other_index);\r
                else\r
                {\r
-                       if(channel_.format_desc != other.impl_->channel_.format_desc)\r
+                       if(channel_.get_format_desc() != other.impl_->channel_.get_format_desc())\r
                                BOOST_THROW_EXCEPTION(not_supported() << msg_info("Cannot swap between channels with different formats."));\r
 \r
                        auto func = [&]{layers_[index].swap(other.impl_->layers_[other_index]);};\r
                \r
-                       channel_.execution.invoke([&]{other.impl_->channel_.execution.invoke(func);});\r
+                       channel_.execution().invoke([&]{other.impl_->channel_.execution().invoke(func);});\r
                }\r
        }\r
 \r
@@ -173,7 +173,7 @@ public:
                if(other.impl_.get() == this)\r
                        return;\r
 \r
-               if(channel_.format_desc != other.impl_->channel_.format_desc)\r
+               if(channel_.get_format_desc() != other.impl_->channel_.get_format_desc())\r
                        BOOST_THROW_EXCEPTION(not_supported() << msg_info("Cannot swap between channels with different formats."));\r
 \r
                auto func = [&]\r
@@ -190,17 +190,17 @@ public:
                                layers_[index].swap(other.impl_->layers_[index]);\r
                };\r
                \r
-               channel_.execution.invoke([&]{other.impl_->channel_.execution.invoke(func);});\r
+               channel_.execution().invoke([&]{other.impl_->channel_.execution().invoke(func);});\r
        }\r
        \r
        boost::unique_future<safe_ptr<frame_producer>> foreground(int index)\r
        {\r
-               return channel_.execution.begin_invoke([=]{return layers_[index].foreground();});\r
+               return channel_.execution().begin_invoke([=]{return layers_[index].foreground();});\r
        }\r
        \r
        boost::unique_future<safe_ptr<frame_producer>> background(int index)\r
        {\r
-               return channel_.execution.begin_invoke([=]{return layers_[index].background();});\r
+               return channel_.execution().begin_invoke([=]{return layers_[index].background();});\r
        }\r
 };\r
 \r
index 46a5c8982389f5c848003b30c3aede8c43829d5a..89325837e3d2d11f8c3e7a424908952b51d9b0ce 100644 (file)
@@ -30,7 +30,7 @@
 namespace caspar { namespace core {\r
 \r
 struct video_format_desc;\r
-struct video_channel_context;\r
+class video_channel_context;;\r
 \r
 class frame_producer_device : boost::noncopyable\r
 {\r
index d3e43ab224c351571b57b895af10935b75d0bfdb..c31a7c05da5c18b6bba3e81193f28266f02e80c9 100644 (file)
@@ -53,16 +53,16 @@ public:
                , producer_(new frame_producer_device(context_))        \r
        {\r
                CASPAR_LOG(info) << print() << " Successfully Initialized.";\r
-               context_.execution.begin_invoke([this]{tick();});\r
+               context_.execution().begin_invoke([this]{tick();});\r
        }\r
 \r
        ~implementation()\r
        {\r
                // Stop context before destroying devices.\r
-               context_.execution.stop();\r
-               context_.execution.join();\r
-               context_.destruction.stop();\r
-               context_.destruction.join();\r
+               context_.execution().stop();\r
+               context_.execution().join();\r
+               context_.destruction().stop();\r
+               context_.destruction().join();\r
        }\r
 \r
        void tick()\r
@@ -71,7 +71,7 @@ public:
                auto finished_frame = (*mixer_)(simple_frames);\r
                (*consumer_)(finished_frame);\r
 \r
-               context_.execution.begin_invoke([this]{tick();});\r
+               context_.execution().begin_invoke([this]{tick();});\r
        }\r
                \r
        std::wstring print() const\r
@@ -81,9 +81,9 @@ public:
 \r
        void set_video_format_desc(const video_format_desc& format_desc)\r
        {\r
-               context_.execution.begin_invoke([=]\r
+               context_.execution().begin_invoke([=]\r
                {\r
-                       context_.format_desc = format_desc;\r
+                       context_.set_format_desc(format_desc);\r
                });\r
        }\r
 };\r
@@ -93,7 +93,7 @@ video_channel::video_channel(video_channel&& other) : impl_(std::move(other.impl
 safe_ptr<frame_producer_device> video_channel::producer() { return impl_->producer_;} \r
 safe_ptr<frame_mixer_device> video_channel::mixer() { return impl_->mixer_;} \r
 safe_ptr<frame_consumer_device> video_channel::consumer() { return impl_->consumer_;} \r
-const video_format_desc& video_channel::get_video_format_desc() const{return impl_->context_.format_desc;}\r
+video_format_desc video_channel::get_video_format_desc() const{return impl_->context_.get_format_desc();}\r
 void video_channel::set_video_format_desc(const video_format_desc& format_desc){impl_->set_video_format_desc(format_desc);}\r
 std::wstring video_channel::print() const { return impl_->print();}\r
 \r
index 1634ca43f9836a96ff3da002bc5835a609217f7d..a87ea6309bce15250e3057a4ff1035d9a0e83c54 100644 (file)
@@ -42,7 +42,7 @@ public:
        safe_ptr<frame_mixer_device>    mixer();\r
        safe_ptr<frame_consumer_device> consumer();\r
 \r
-       const video_format_desc& get_video_format_desc() const;\r
+       video_format_desc get_video_format_desc() const;\r
        void set_video_format_desc(const video_format_desc& format_desc);\r
 \r
        std::wstring print() const;\r
index 9b8bf24dc22f9f47df6df88df3aa11cb969c6a6a..7e0393fa0023b453b075cb40f2a5ebe139d6a4f4 100644 (file)
@@ -5,6 +5,8 @@
 #include <core/mixer/gpu/ogl_device.h>\r
 #include <core/video_format.h>\r
 \r
+#include <tbb/spin_rw_mutex.h>\r
+\r
 #include <boost/noncopyable.hpp>\r
 #include <boost/lexical_cast.hpp>\r
 \r
 \r
 namespace caspar { namespace core {\r
 \r
-struct video_channel_context\r
+class video_channel_context\r
 {\r
+       mutable tbb::spin_rw_mutex      mutex_;\r
+       const int                                       index_;\r
+       video_format_desc                       format_desc_;\r
+       executor                                        execution_;\r
+       executor                                        destruction_;\r
+       ogl_device&                                     ogl_;\r
+\r
+public:\r
        video_channel_context(int index,  ogl_device& ogl, const video_format_desc& format_desc) \r
-               : index(index)\r
-               , format_desc(format_desc)\r
-               , execution(print() + L"/execution")\r
-               , destruction(print() + L"/destruction")\r
-               , ogl(ogl)\r
+               : index_(index)\r
+               , format_desc_(format_desc)\r
+               , execution_(print() + L"/execution")\r
+               , destruction_(print() + L"/destruction")\r
+               , ogl_(ogl)\r
+       {\r
+               execution_.set_priority_class(above_normal_priority_class);\r
+               destruction_.set_priority_class(below_normal_priority_class);\r
+       }\r
+\r
+       const int index() const {return index_;}\r
+\r
+       video_format_desc get_format_desc()\r
+       {\r
+               tbb::spin_rw_mutex::scoped_lock lock(mutex_, false);\r
+               return format_desc_;\r
+       }\r
+\r
+       void set_format_desc(const video_format_desc& format_desc)\r
        {\r
-               execution.set_priority_class(above_normal_priority_class);\r
-               destruction.set_priority_class(below_normal_priority_class);\r
+               tbb::spin_rw_mutex::scoped_lock lock(mutex_, true);\r
+               format_desc_ = format_desc;\r
        }\r
 \r
-       const int                       index;\r
-       video_format_desc       format_desc;\r
-       executor                        execution;\r
-       executor                        destruction;\r
-       ogl_device&                     ogl;\r
+       executor& execution() {return execution_;}\r
+       executor& destruction() {return destruction_;}\r
+       ogl_device& ogl() { return ogl_;}\r
 \r
        std::wstring print() const\r
        {\r
-               return L"video_channel[" + boost::lexical_cast<std::wstring>(index+1) + L"-" +  format_desc.name + L"]";\r
+               return L"video_channel[" + boost::lexical_cast<std::wstring>(index_+1) + L"-" +  format_desc_.name + L"]";\r
        }\r
 };\r
        \r
index 036b818f5b5c17ee3748204b791fcaf256c2dc11..e6b49c21fb7bdf8e6be4224e6882d6d7542fa830 100644 (file)
@@ -168,6 +168,7 @@ public:
                if(format_desc_ != frame_factory_->get_video_format_desc())\r
                {\r
                        format_desc_ = frame_factory_->get_video_format_desc();\r
+                       bmp_ = bitmap(format_desc_.width, format_desc_.height);\r
                        ax_->SetFormat(format_desc_);\r
                }\r
 \r