]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 18 Jan 2011 20:26:10 +0000 (20:26 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 18 Jan 2011 20:26:10 +0000 (20:26 +0000)
20 files changed:
core/channel.cpp
core/channel.h
core/mixer/audio/audio_mixer.cpp
core/mixer/audio/audio_mixer.h
core/mixer/frame/draw_frame.cpp
core/mixer/frame/draw_frame.h
core/mixer/frame_mixer_device.cpp
core/mixer/frame_mixer_device.h
core/mixer/image/image_kernel.cpp
core/mixer/image/image_kernel.h
core/mixer/image/image_mixer.cpp
core/mixer/image/image_mixer.h
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/video/video_decoder.cpp
core/producer/frame_producer_device.cpp
core/producer/frame_producer_device.h
core/producer/layer.cpp
core/producer/layer.h
core/producer/transition/transition_producer.cpp
protocol/amcp/AMCPCommandsImpl.cpp

index ed10879e5e59dbb419cc46452e98c7a2e357e5cd..52d948045f87a8117d57fa01ef7ad0298d87a2c5 100644 (file)
@@ -52,6 +52,7 @@ public:
 channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
 channel::channel(const video_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r
 frame_producer_device& channel::producer() { return *impl_->producer_;} \r
+frame_mixer_device& channel::mixer() { return *impl_->mixer_;} \r
 frame_consumer_device& channel::consumer() { return *impl_->consumer_;} \r
 const video_format_desc& channel::get_video_format_desc() const{return impl_->format_desc_;}\r
 \r
index 75037029e7131d1c574872156124d136c08b6655..0605fde8ebbc47c22dc68b160279894f41781dcf 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once\r
 \r
 #include "consumer/frame_consumer_device.h"\r
+#include "mixer/frame_mixer_device.h"\r
 #include "producer/frame_producer_device.h"\r
 \r
 #include <common/memory/safe_ptr.h>\r
@@ -27,6 +28,7 @@ public:
        channel(channel&& other);\r
 \r
        frame_producer_device& producer();\r
+       frame_mixer_device& mixer();\r
        frame_consumer_device& consumer();\r
 \r
        const video_format_desc& get_video_format_desc() const;\r
index a8b68ad01eb4b113dc56d5d4d1ee0b98af98fda6..4be55434ccd02b56e6714b4fb5da8d68dc3524a8 100644 (file)
@@ -4,9 +4,25 @@
 \r
 namespace caspar { namespace core {\r
        \r
+audio_transform::audio_transform()\r
+       : gain_(1.0){}\r
+\r
+void audio_transform::set_gain(double value)\r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       gain_ = value;\r
+}\r
+\r
+double audio_transform::get_gain() const\r
+{\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       return gain_;\r
+}\r
+\r
 audio_transform& audio_transform::operator*=(const audio_transform &other) \r
 {\r
-       gain *= other.gain;\r
+       tbb::spin_mutex::scoped_lock lock(mutex_);\r
+       gain_ *= other.gain_;\r
        return *this;\r
 }\r
 \r
@@ -36,6 +52,7 @@ public:
                if(audio_data_.empty())\r
                        audio_data_.resize(audio_data.size(), 0);\r
 \r
+               double gain = transform_stack_.top().get_gain();\r
                tbb::parallel_for\r
                (\r
                        tbb::blocked_range<size_t>(0, audio_data.size()),\r
@@ -44,7 +61,7 @@ public:
                                for(size_t n = r.begin(); n < r.end(); ++n)\r
                                {\r
                                        int sample = static_cast<int>(audio_data[n]);\r
-                                       sample = (static_cast<int>(transform_stack_.top().gain*8192.0)*sample)/8192;\r
+                                       sample = (static_cast<int>(gain*8192.0)*sample)/8192;\r
                                        audio_data_[n] = static_cast<short>((static_cast<int>(audio_data_[n]) + sample) & 0xFFFF);\r
                                }\r
                        }\r
index 7801e7b0acd7d65549fb47ca226251e0c33bc05d..2e11ffda4a2bfae8a5263fc4a56a4948d0889d2f 100644 (file)
@@ -1,14 +1,22 @@
 #pragma once\r
 \r
+#include <tbb/spin_mutex.h>\r
+\r
 namespace caspar { namespace core {\r
 \r
-struct audio_transform\r
+class audio_transform\r
 {\r
-       audio_transform() : gain(1.0){}\r
-       double gain;\r
+public:\r
+       audio_transform();\r
+\r
+       void set_gain(double value);\r
+       double get_gain() const;\r
 \r
        audio_transform& operator*=(const audio_transform &other);\r
        const audio_transform operator*(const audio_transform &other) const;\r
+private:\r
+       double gain_;\r
+       mutable tbb::spin_mutex mutex_;\r
 };\r
 \r
 class audio_mixer\r
index 3ec376bb07b8542632d8b1fad5ff996d15ce546a..828912869c34435cd016ab4cf0cfe80692dfdb32 100644 (file)
@@ -18,11 +18,14 @@ struct draw_frame::implementation
        image_transform image_transform_;       \r
        audio_transform audio_transform_;\r
 \r
+       int index_;\r
 public:\r
        implementation(const std::vector<safe_ptr<draw_frame>>& frames) \r
-               : frames_(frames){}\r
+               : frames_(frames)\r
+               , index_(std::numeric_limits<int>::min()) {}\r
        implementation(std::vector<safe_ptr<draw_frame>>&& frames) \r
-               : frames_(std::move(frames)){}\r
+               : frames_(std::move(frames))\r
+               , index_(std::numeric_limits<int>::min()) {}\r
        \r
        void process_image(image_mixer& mixer)\r
        {\r
@@ -103,13 +106,13 @@ safe_ptr<draw_frame> draw_frame::interlace(const safe_ptr<draw_frame>& frame1, c
        auto my_frame2 = make_safe<draw_frame>(frame2);\r
        if(mode == video_mode::upper)\r
        {\r
-               my_frame1->get_image_transform().mode = video_mode::upper;      \r
-               my_frame2->get_image_transform().mode = video_mode::lower;      \r
-       }\r
-       else\r
-       {\r
-               my_frame1->get_image_transform().mode = video_mode::lower;      \r
-               my_frame2->get_image_transform().mode = video_mode::upper;      \r
+               my_frame1->get_image_transform().set_mode(video_mode::upper);   \r
+               my_frame2->get_image_transform().set_mode(video_mode::lower);   \r
+       }                                                                                        \r
+       else                                                                             \r
+       {                                                                                        \r
+               my_frame1->get_image_transform().set_mode(video_mode::lower);   \r
+               my_frame2->get_image_transform().set_mode(video_mode::upper);   \r
        }\r
 \r
        std::vector<safe_ptr<draw_frame>> frames;\r
@@ -118,4 +121,7 @@ safe_ptr<draw_frame> draw_frame::interlace(const safe_ptr<draw_frame>& frame1, c
        return make_safe<draw_frame>(frames);\r
 }\r
 \r
+void draw_frame::set_layer_index(int index) { impl_->index_ = index; }\r
+int draw_frame::get_layer_index() const { return impl_->index_; }\r
+\r
 }}
\ No newline at end of file
index 994fc67c9140fbd9714663f43e34236fdbfce2e9..c68718884d95edd31d18baa1a910ced149c886ce 100644 (file)
@@ -15,8 +15,8 @@
 \r
 namespace caspar { namespace core {\r
 \r
-struct image_transform;\r
-struct audio_transform;\r
+class image_transform;\r
+class audio_transform;\r
                \r
 class draw_frame\r
 {\r
@@ -62,6 +62,9 @@ public:
 \r
        virtual void process_image(image_mixer& mixer);\r
        virtual void process_audio(audio_mixer& mixer);\r
+\r
+       void set_layer_index(int index);\r
+       int get_layer_index() const;\r
        \r
 private:\r
        struct implementation;\r
index 5ba4ac90317d7037dda9739f803d018a12034bc9..8f06de02a47dbabdce7eacaf21b66dd55db254c0 100644 (file)
@@ -19,6 +19,8 @@
 \r
 #include <boost/range/algorithm.hpp>\r
 \r
+#include <unordered_map>\r
+\r
 namespace caspar { namespace core {\r
        \r
 struct frame_mixer_device::implementation : boost::noncopyable\r
@@ -32,6 +34,9 @@ struct frame_mixer_device::implementation : boost::noncopyable
 \r
        executor executor_;\r
 \r
+       std::unordered_map<int, image_transform> image_transforms_;\r
+       std::unordered_map<int, audio_transform> audio_transforms_;\r
+\r
 public:\r
        implementation(const video_format_desc& format_desc, const output_func& output) \r
                : format_desc_(format_desc)\r
@@ -47,16 +52,26 @@ public:
                CASPAR_LOG(info) << "Shutting down mixer-device.";\r
        }\r
 \r
-       void send(const safe_ptr<draw_frame>& frame)\r
+       void send(const std::vector<safe_ptr<draw_frame>>& frames)\r
        {                       \r
                executor_.begin_invoke([=]\r
                {\r
                        auto image = image_mixer_.begin_pass();\r
-                       frame->process_image(image_mixer_);\r
+                       BOOST_FOREACH(auto& frame, frames)\r
+                       {\r
+                               image_mixer_.begin(image_transforms_[frame->get_layer_index()]);\r
+                               frame->process_image(image_mixer_);\r
+                               image_mixer_.end();\r
+                       }\r
                        image_mixer_.end_pass();\r
 \r
                        auto audio = audio_mixer_.begin_pass();\r
-                       frame->process_audio(audio_mixer_);\r
+                       BOOST_FOREACH(auto& frame, frames)\r
+                       {\r
+                               audio_mixer_.begin(audio_transforms_[frame->get_layer_index()]);\r
+                               frame->process_audio(audio_mixer_);\r
+                               audio_mixer_.end();\r
+                       }\r
                        audio_mixer_.end_pass();\r
 \r
                        output_(make_safe<const read_frame>(std::move(image.get()), std::move(audio)));\r
@@ -67,11 +82,21 @@ public:
        {\r
                return make_safe<write_frame>(desc, image_mixer_.create_buffers(desc));\r
        }\r
+\r
+       image_transform& image(int index) \r
+       {\r
+               return image_transforms_[index];\r
+       }\r
+\r
+       audio_transform& audio(int index) \r
+       {\r
+               return audio_transforms_[index];\r
+       }\r
 };\r
        \r
 frame_mixer_device::frame_mixer_device(const video_format_desc& format_desc, const output_func& output) : impl_(new implementation(format_desc, output)){}\r
 frame_mixer_device::frame_mixer_device(frame_mixer_device&& other) : impl_(std::move(other.impl_)){}\r
-void frame_mixer_device::send(const safe_ptr<draw_frame>& frame){impl_->send(frame);}\r
+void frame_mixer_device::send(const std::vector<safe_ptr<draw_frame>>& frames){impl_->send(frames);}\r
 const video_format_desc& frame_mixer_device::get_video_format_desc() const { return impl_->format_desc_; }\r
 safe_ptr<write_frame> frame_mixer_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }             \r
 safe_ptr<write_frame> frame_mixer_device::create_frame(size_t width, size_t height, pixel_format::type pix_fmt)\r
@@ -92,4 +117,7 @@ safe_ptr<write_frame> frame_mixer_device::create_frame(pixel_format::type pix_fm
        return create_frame(desc);\r
 }\r
 \r
+image_transform& frame_mixer_device::image(int index) { return impl_->image(index);}\r
+audio_transform& frame_mixer_device::audio(int index) { return impl_->audio(index);}\r
+\r
 }}
\ No newline at end of file
index 4648792b8ee56fd3bdaa6e1609d7eb92ab685b58..8d825a0b7b2877a1b49cedecfc65c15f34c0972d 100644 (file)
@@ -30,6 +30,9 @@
 \r
 #include <functional>\r
 \r
+#include "image/image_mixer.h"\r
+#include "audio/audio_mixer.h"\r
+\r
 namespace caspar { namespace core {\r
        \r
 struct video_format;\r
@@ -42,13 +45,17 @@ public:
        frame_mixer_device(const video_format_desc& format_desc, const output_func& output);\r
        frame_mixer_device(frame_mixer_device&& other); // nothrow\r
                \r
-       void send(const safe_ptr<draw_frame>& frame); // nothrow\r
+       void send(const std::vector<safe_ptr<draw_frame>>& frames); // nothrow\r
                \r
        safe_ptr<write_frame> create_frame(const pixel_format_desc& desc);              \r
        safe_ptr<write_frame> create_frame(size_t width, size_t height, pixel_format::type pix_fmt = pixel_format::bgra);                       \r
        safe_ptr<write_frame> create_frame(pixel_format::type pix_fmt = pixel_format::bgra);\r
        \r
        const video_format_desc& get_video_format_desc() const; // nothrow\r
+\r
+       image_transform& image(int index);\r
+       audio_transform& audio(int index);\r
+\r
 private:\r
        struct implementation;\r
        safe_ptr<implementation> impl_;\r
index bf8d4939de7cb9fb2a9216ebc211fb1c6f5644c2..0a4e8c29082096bb805d00f70d99f622fe94b629 100644 (file)
@@ -237,11 +237,11 @@ void image_kernel::apply(pixel_format::type pix_fmt, const image_transform& tran
 {\r
        impl_->shaders()[pix_fmt].use();\r
 \r
-       GL(glUniform1f(impl_->shaders()[pix_fmt].get_location("color_gain"), static_cast<GLfloat>(transform.gain)));\r
+       GL(glUniform1f(impl_->shaders()[pix_fmt].get_location("color_gain"), static_cast<GLfloat>(transform.get_gain())));\r
 \r
-       if(transform.mode == video_mode::upper)\r
+       if(transform.get_mode() == video_mode::upper)\r
                glPolygonStipple(upper_pattern);\r
-       else if(transform.mode == video_mode::lower)\r
+       else if(transform.get_mode() == video_mode::lower)\r
                glPolygonStipple(lower_pattern);\r
        else\r
                glPolygonStipple(progressive_pattern);\r
index 523319d51819b59b785e9b642fe8a4e0ed28914d..fd8b5665f32db4894d08474b8d67ad146c322b92 100644 (file)
@@ -7,7 +7,7 @@
 \r
 namespace caspar { namespace core {\r
 \r
-struct image_transform;\r
+class image_transform;\r
 \r
 class image_kernel\r
 {\r
index c016729803da6414a21df431a18da1198b24adb1..d648f77f40b219966a007467f95fe6a0a79dde5b 100644 (file)
 \r
 namespace caspar { namespace core {\r
                \r
+image_transform::image_transform() \r
+       : opacity_(1.0)\r
+       , gain_(1.0)\r
+       , mode_(video_mode::invalid)\r
+{\r
+       std::fill(pos_.begin(), pos_.end(), 0.0);\r
+       std::fill(uv_.begin(), uv_.end(), 0.0);\r
+}\r
+\r
+void image_transform::set_opacity(double value)\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);   \r
+       opacity_ = value;\r
+}\r
+\r
+double image_transform::get_opacity() const\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       return opacity_;\r
+}\r
+\r
+void image_transform::set_gain(double value)\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       gain_ = value;\r
+}\r
+\r
+double image_transform::get_gain() const\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       return gain_;\r
+}\r
+\r
+void image_transform::set_position(double x, double y)\r
+{\r
+       std::array<double, 2> value = {x, y};\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       pos_ = value;\r
+}\r
+\r
+std::array<double, 2> image_transform::get_position() const\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       return pos_;\r
+}\r
+\r
+void image_transform::set_uv(double left, double top, double right, double bottom)\r
+{\r
+       std::array<double, 4> value = {left, top, right, bottom};\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       uv_ = value;\r
+}\r
+\r
+std::array<double, 4> image_transform::get_uv() const\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       return uv_;\r
+}\r
+\r
+void image_transform::set_mode(video_mode::type mode)\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       mode_ = mode;\r
+}\r
+\r
+video_mode::type image_transform::get_mode() const\r
+{\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       return mode_;\r
+}\r
+\r
+\r
 image_transform& image_transform::operator*=(const image_transform &other)\r
 {\r
-       alpha *= other.alpha;\r
-       mode = other.mode;\r
-       gain *= other.gain;\r
-       uv.get<0>() += other.uv.get<0>();\r
-       uv.get<1>() += other.uv.get<1>();\r
-       uv.get<2>() += other.uv.get<2>();\r
-       uv.get<3>() += other.uv.get<3>();\r
-       pos.get<0>() += other.pos.get<0>();\r
-       pos.get<1>() += other.pos.get<1>();\r
+       tbb::spin_mutex::scoped_lock(mutex_);\r
+       opacity_ *= other.opacity_;\r
+       mode_ = other.mode_;\r
+       gain_ *= other.gain_;\r
+       uv_[0] += other.uv_[0];\r
+       uv_[1] += other.uv_[1];\r
+       uv_[2] += other.uv_[2];\r
+       uv_[3] += other.uv_[3];\r
+       pos_[0] += other.pos_[0];\r
+       pos_[1] += other.pos_[1];\r
        return *this;\r
 }\r
 \r
@@ -58,8 +131,8 @@ public:
                context_.begin_invoke([=]\r
                {\r
                        transform_stack_.push(image_transform());\r
-                       transform_stack_.top().mode = video_mode::progressive;\r
-                       transform_stack_.top().uv = boost::make_tuple(0.0, 1.0, 1.0, 0.0);\r
+                       transform_stack_.top().set_mode(video_mode::progressive);\r
+                       transform_stack_.top().set_uv(0.0, 1.0, 1.0, 0.0);\r
 \r
                        GL(glEnable(GL_TEXTURE_2D));\r
                        GL(glDisable(GL_DEPTH_TEST));           \r
@@ -91,8 +164,8 @@ public:
                context_.begin_invoke([=]\r
                {\r
                        GL(glLoadIdentity());\r
-                       GL(glTranslated(transform.pos.get<0>()*2.0, transform.pos.get<1>()*2.0, 0.0));\r
-                       GL(glColor4d(1.0, 1.0, 1.0, transform.alpha));\r
+                       GL(glTranslated(transform.get_position()[0]*2.0, transform.get_position()[1]*2.0, 0.0));\r
+                       GL(glColor4d(1.0, 1.0, 1.0, transform.get_opacity()));\r
                        GL(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
                        kernel_.apply(desc.pix_fmt, transform);\r
 \r
@@ -112,10 +185,10 @@ public:
 \r
                        auto t = transform;\r
                        glBegin(GL_QUADS);\r
-                               glTexCoord2d(t.uv.get<0>(), t.uv.get<3>()); glVertex2d(-1.0, -1.0);\r
-                               glTexCoord2d(t.uv.get<2>(), t.uv.get<3>()); glVertex2d( 1.0, -1.0);\r
-                               glTexCoord2d(t.uv.get<2>(), t.uv.get<1>()); glVertex2d( 1.0,  1.0);\r
-                               glTexCoord2d(t.uv.get<0>(), t.uv.get<1>()); glVertex2d(-1.0,  1.0);\r
+                               glTexCoord2d(t.get_uv()[0], t.get_uv()[3]); glVertex2d(-1.0, -1.0);\r
+                               glTexCoord2d(t.get_uv()[2], t.get_uv()[3]); glVertex2d( 1.0, -1.0);\r
+                               glTexCoord2d(t.get_uv()[2], t.get_uv()[1]); glVertex2d( 1.0,  1.0);\r
+                               glTexCoord2d(t.get_uv()[0], t.get_uv()[1]); glVertex2d(-1.0,  1.0);\r
                        glEnd();\r
                });\r
        }\r
index bdd2f5c9a89793f67d8252dd66c39c5d3429cc83..d09c375316c47642380c9e2f860244d5a030bc5a 100644 (file)
@@ -15,17 +15,34 @@ namespace caspar { namespace core {
 \r
 struct pixel_format_desc;\r
        \r
-struct image_transform \r
+class image_transform \r
 {\r
-       image_transform() : alpha(1.0), pos(boost::make_tuple(0.0, 0.0)), gain(1.0), uv(boost::make_tuple(0.0, 0.0, 0.0, 0.0)), mode(video_mode::invalid){}\r
-       double alpha;\r
-       double gain;\r
-       boost::tuple<double, double> pos;\r
-       boost::tuple<double, double, double, double> uv;\r
-       video_mode::type mode; \r
+public:\r
+       image_transform();\r
+\r
+       void set_opacity(double value);\r
+       double get_opacity() const;\r
+\r
+       void set_gain(double value);\r
+       double get_gain() const;\r
+\r
+       void set_position(double x, double y);\r
+       std::array<double, 2> get_position() const;\r
+\r
+       void set_uv(double left, double top, double right, double bottom);\r
+       std::array<double, 4> get_uv() const;\r
+\r
+       void set_mode(video_mode::type mode);\r
+       video_mode::type get_mode() const;\r
 \r
        image_transform& operator*=(const image_transform &other);\r
        const image_transform operator*(const image_transform &other) const;\r
+private:\r
+       double opacity_;\r
+       double gain_;\r
+       std::array<double, 2> pos_;\r
+       std::array<double, 4> uv_;\r
+       video_mode::type mode_;\r
 };\r
 \r
 class image_mixer : boost::noncopyable\r
index 67be218a6778bcc1a0abd1f26458d376467a5f40..1b66316ffbed44bd522ed8e64dfb7a0084a04c4c 100644 (file)
@@ -108,7 +108,7 @@ public:
                {\r
                        result = std::move(ouput_channel_.front());\r
                        last_frame_ = draw_frame(result);\r
-                       last_frame_->get_audio_transform().gain = 0.0; // last_frame should not have audio\r
+                       last_frame_->get_audio_transform().set_gain(0.0); // last_frame should not have audio\r
                        ouput_channel_.pop();\r
                }\r
                else if(input_.is_eof())\r
index 76a5d15cef46202ae884a3919991e9e2b3e1e568..75a569486efd33953229a2649db5c5de1ef15556 100644 (file)
@@ -149,7 +149,7 @@ public:
                        });\r
 \r
                        if(codec_context_->codec_id == CODEC_ID_DVVIDEO) // Move up one field frame_factory_->get_video_format_desc().mode == video_mode::upper &&       \r
-                               write->get_image_transform().pos = boost::make_tuple(0.0f, 1.0/static_cast<double>(height_));\r
+                               write->get_image_transform().set_position(0.0f, 1.0/static_cast<double>(height_));\r
 \r
                        return write;\r
                }\r
index d2344ef1e9d788330d936f30f7af5a684399a721..43d1bec2d32e5edfb348cb54f47cb8a463a7076f 100644 (file)
@@ -49,7 +49,7 @@ public:
                executor_.begin_invoke([=]{tick();});\r
        }\r
        \r
-       safe_ptr<draw_frame> draw()\r
+       std::vector<safe_ptr<draw_frame>> draw()\r
        {       \r
                std::vector<safe_ptr<draw_frame>> frames(layers_.size(), draw_frame::empty());\r
                tbb::parallel_for(tbb::blocked_range<size_t>(0, frames.size()), \r
@@ -62,23 +62,7 @@ public:
                });             \r
                boost::range::remove_erase(frames, draw_frame::eof());\r
                boost::range::remove_erase(frames, draw_frame::empty());\r
-               return draw_frame(frames);\r
-       }\r
-\r
-       // Layers and Producers\r
-       void set_video_gain(int index, double value)\r
-       {\r
-               begin_invoke_layer(index, std::bind(&layer::set_video_gain, std::placeholders::_1, value));\r
-       }\r
-\r
-       void set_video_opacity(int index, double value)\r
-       {\r
-               begin_invoke_layer(index, std::bind(&layer::set_video_opacity, std::placeholders::_1, value));\r
-       }\r
-\r
-       void set_audio_gain(int index, double value)\r
-       {\r
-               begin_invoke_layer(index, std::bind(&layer::set_audio_gain, std::placeholders::_1, value));\r
+               return frames;\r
        }\r
 \r
        void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load)\r
@@ -170,9 +154,6 @@ public:
 frame_producer_device::frame_producer_device(frame_producer_device&& other) : impl_(std::move(other.impl_)){}\r
 frame_producer_device::frame_producer_device(const video_format_desc& format_desc, const safe_ptr<frame_factory>& factory, const output_func& output) \r
        : impl_(new implementation(format_desc, factory, output)){}\r
-void frame_producer_device::set_video_gain(int index, double value){impl_->set_video_gain(index, value);}\r
-void frame_producer_device::set_video_opacity(int index, double value){impl_->set_video_opacity(index, value);}\r
-void frame_producer_device::set_audio_gain(int index, double value){impl_->set_audio_gain(index, value);}\r
 void frame_producer_device::load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load){impl_->load(index, producer, play_on_load);}\r
 void frame_producer_device::preview(int index, const safe_ptr<frame_producer>& producer){impl_->preview(index, producer);}\r
 void frame_producer_device::pause(int index){impl_->pause(index);}\r
index f983517b3f5e28010d8af89a3847968874f52a9a..5e04284c504ad08ff9e2d57dd63e5e6025573c0a 100644 (file)
@@ -25,17 +25,11 @@ namespace caspar { namespace core {
 class frame_producer_device : boost::noncopyable\r
 {\r
 public:\r
-       typedef std::function<void(const safe_ptr<draw_frame>&)> output_func;\r
+       typedef std::function<void(const std::vector<safe_ptr<draw_frame>>&)> output_func;\r
 \r
        explicit frame_producer_device(const video_format_desc& format_desc, const safe_ptr<frame_factory>& factory, const output_func& output);\r
        frame_producer_device(frame_producer_device&& other);\r
                \r
-       // Layers and Producers\r
-       void set_video_gain(int index, double value);\r
-       void set_video_opacity(int index, double value);\r
-\r
-       void set_audio_gain(int index, double value);\r
-\r
        void load(int index, const safe_ptr<frame_producer>& producer, bool play_on_load = false);\r
        void preview(int index, const safe_ptr<frame_producer>& producer);\r
        void pause(int index);\r
index 21db1d15316afa1f8d47b02eac34e8690531a75d..ab32c18885a0fff7aadc5ba5b9ba24861f733d86 100644 (file)
@@ -21,21 +21,13 @@ struct layer::implementation : boost::noncopyable
        const int                                       index_;\r
        bool                                            is_paused_;\r
 \r
-       double                                          video_gain_;\r
-       double                                          video_opacity_;\r
-       \r
-       double                                          audio_gain_;\r
-\r
 public:\r
        implementation(int index) \r
                : foreground_(frame_producer::empty())\r
                , background_(frame_producer::empty())\r
                , last_frame_(draw_frame::empty())\r
                , index_(index) \r
-               , is_paused_(false)\r
-               , video_gain_(1.0)\r
-               , video_opacity_(1.0)\r
-               , audio_gain_(1.0){}\r
+               , is_paused_(false){}\r
        \r
        void load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load)\r
        {                       \r
@@ -101,6 +93,7 @@ public:
                try\r
                {\r
                        last_frame_ = foreground_->receive(); \r
+                       last_frame_->set_layer_index(index_);\r
                        if(last_frame_ == draw_frame::eof())\r
                        {\r
                                CASPAR_ASSERT(foreground_ != frame_producer::empty());\r
@@ -113,13 +106,6 @@ public:
 \r
                                last_frame_ = receive();\r
                        }\r
-                       else\r
-                       {\r
-                               last_frame_ = draw_frame(last_frame_);\r
-                               last_frame_->get_image_transform().gain *= video_gain_;\r
-                               last_frame_->get_image_transform().alpha *= video_opacity_;\r
-                               last_frame_->get_audio_transform().gain *= audio_gain_;\r
-                       }\r
                }\r
                catch(...)\r
                {\r
@@ -143,9 +129,6 @@ layer& layer::operator=(layer&& other)
 }\r
 void layer::load(const safe_ptr<frame_producer>& frame_producer, bool play_on_load){return impl_->load(frame_producer, play_on_load);} \r
 void layer::preview(const safe_ptr<frame_producer>& frame_producer){return impl_->preview(frame_producer);}    \r
-void layer::set_video_gain(double value) { impl_->video_gain_ = value;}\r
-void layer::set_video_opacity(double value) { impl_->video_opacity_ = value;}\r
-void layer::set_audio_gain(double value) { impl_->audio_gain_ = value;}\r
 void layer::play(){impl_->play();}\r
 void layer::pause(){impl_->pause();}\r
 void layer::stop(){impl_->stop();}\r
index 4f675bcff2c2c8e67513cdc2954fd12240d39154..897a21706aa578fd0ac7da2018d683246bcc8271 100644 (file)
@@ -15,12 +15,7 @@ public:
        layer(int index = -1); // nothrow\r
        layer(layer&& other); // nothrow\r
        layer& operator=(layer&& other); // nothrow\r
-\r
-       void set_video_gain(double value);\r
-       void set_video_opacity(double value);\r
-\r
-       void set_audio_gain(double value);\r
-       \r
+               \r
        void load(const safe_ptr<frame_producer>& producer, bool play_on_load = false); // nothrow\r
        void preview(const safe_ptr<frame_producer>& producer); // nothrow\r
        void play(); // nothrow\r
index e2f525a63a9436dae54126f70db8e0560785d0e9..d0e89e31e04b8eaa1c578062c3afd59c47977dcc 100644 (file)
@@ -126,24 +126,24 @@ struct transition_producer::implementation : boost::noncopyable
                auto my_src_frame = draw_frame(src_frame);\r
                auto my_dest_frame = draw_frame(dest_frame);\r
 \r
-               my_src_frame.get_audio_transform().gain = 1.0-alpha;\r
-               my_dest_frame.get_audio_transform().gain = alpha;\r
+               my_src_frame.get_audio_transform().set_gain(1.0-alpha);\r
+               my_dest_frame.get_audio_transform().set_gain(alpha);\r
 \r
                double dir = info_.direction == transition_direction::from_left ? 1.0 : -1.0;           \r
                \r
                if(info_.type == transition::mix)\r
-                       my_dest_frame.get_image_transform().alpha = alpha;              \r
+                       my_dest_frame.get_image_transform().set_opacity(alpha);         \r
                else if(info_.type == transition::slide)                        \r
-                       my_dest_frame.get_image_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);                     \r
+                       my_dest_frame.get_image_transform().set_position((-1.0+alpha)*dir, 0.0);                        \r
                else if(info_.type == transition::push)\r
                {\r
-                       my_dest_frame.get_image_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);\r
-                       my_src_frame.get_image_transform().pos = boost::make_tuple((0.0+alpha)*dir, 0.0);\r
+                       my_dest_frame.get_image_transform().set_position((-1.0+alpha)*dir, 0.0);\r
+                       my_src_frame.get_image_transform().set_position((0.0+alpha)*dir, 0.0);\r
                }\r
                else if(info_.type == transition::wipe)\r
                {\r
-                       my_dest_frame.get_image_transform().pos = boost::make_tuple((-1.0+alpha)*dir, 0.0);                     \r
-                       my_dest_frame.get_image_transform().uv = boost::make_tuple((-1.0+alpha)*dir, 0.0, 0.0-(1.0-alpha)*dir, 0.0);                            \r
+                       my_dest_frame.get_image_transform().set_position((-1.0+alpha)*dir, 0.0);                        \r
+                       my_dest_frame.get_image_transform().set_uv((-1.0+alpha)*dir, 0.0, 0.0-(1.0-alpha)*dir, 0.0);                            \r
                }\r
 \r
                return draw_frame(std::move(my_src_frame), std::move(my_dest_frame));\r
index 34a486922e04a7e1c8f6139616bd966333992493..54c7dacf6c9ce198f41576da1a0b2a5e506b0421 100644 (file)
@@ -176,17 +176,16 @@ bool MixerCommand::DoExecute()
                        if(_parameters[1] == L"OPACITY")\r
                        {\r
                                double value = boost::lexical_cast<double>(_parameters[2]);\r
-                               GetChannel()->producer().set_video_opacity(GetLayerIndex(), value);\r
+                               GetChannel()->mixer().image(GetLayerIndex()).set_opacity(value);\r
                        }\r
                        else if(_parameters[1] == L"GAIN")\r
                        {\r
                                double value = boost::lexical_cast<double>(_parameters[2]);\r
-                               GetChannel()->producer().set_video_gain(GetLayerIndex(), value);\r
+                               GetChannel()->mixer().image(GetLayerIndex()).set_gain(value);\r
                        }\r
                        else if(_parameters[1] == L"RESET")\r
                        {\r
-                               GetChannel()->producer().set_video_opacity(GetLayerIndex(), 1.0);\r
-                               GetChannel()->producer().set_video_gain(GetLayerIndex(), 1.0);\r
+                               GetChannel()->mixer().image(GetLayerIndex()) = image_transform();\r
                        }\r
                }\r
                else if(_parameters[0] == L"AUDIO")\r
@@ -194,18 +193,17 @@ bool MixerCommand::DoExecute()
                        if(_parameters[1] == L"GAIN")\r
                        {\r
                                double value = boost::lexical_cast<double>(_parameters[2]);\r
-                               GetChannel()->producer().set_audio_gain(GetLayerIndex(), value);\r
+                               GetChannel()->mixer().audio(GetLayerIndex()).set_gain(value);\r
                        }\r
                        else if(_parameters[1] == L"RESET")\r
                        {\r
-                               GetChannel()->producer().set_audio_gain(GetLayerIndex(), 1.0);\r
+                               GetChannel()->mixer().audio(GetLayerIndex()) = audio_transform();\r
                        }\r
                }\r
                else if(_parameters[0] == L"RESET")\r
                {\r
-                       GetChannel()->producer().set_video_opacity(GetLayerIndex(), 1.0);\r
-                       GetChannel()->producer().set_video_gain(GetLayerIndex(), 1.0);\r
-                       GetChannel()->producer().set_audio_gain(GetLayerIndex(), 1.0);\r
+                       GetChannel()->mixer().image(GetLayerIndex()) = image_transform();\r
+                       GetChannel()->mixer().audio(GetLayerIndex()) = audio_transform();\r
                }\r
        \r
                SetReplyString(TEXT("202 MIXER OK\r\n"));\r