]> 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>
Thu, 25 Nov 2010 18:47:21 +0000 (18:47 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 25 Nov 2010 18:47:21 +0000 (18:47 +0000)
20 files changed:
common/gl/frame_buffer_object.cpp
common/gl/frame_buffer_object.h
core/channel.cpp
core/channel.h
core/consumer/frame_consumer_device.cpp
core/format/pixel_format.h
core/processor/composite_frame.cpp
core/processor/composite_frame.h
core/processor/frame.cpp
core/processor/frame.h
core/processor/frame_processor_device.cpp
core/processor/frame_processor_device.h
core/processor/frame_renderer.cpp
core/producer/ffmpeg/video/video_transformer.cpp
core/producer/flash/flash_producer.cpp
core/producer/frame_producer_device.cpp
core/producer/image/image_scroll_producer.cpp
shell/caspar.config
shell/shell.vcxproj
shell/shell.vcxproj.filters

index 7b4b594d22e2e5dc38887f7667fc17fbc6b7b3b4..c5c7a582d77982c5437d9aeae8f5bb9c4c73e013 100644 (file)
@@ -23,6 +23,7 @@ public:
                GL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_));\r
                GL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, mode_, GL_TEXTURE_2D, \r
                                                                                texture_, 0));\r
+               GL(glReadBuffer(mode_));\r
        }\r
        \r
        ~implementation()\r
@@ -43,12 +44,6 @@ public:
        size_t height_;\r
 };\r
 \r
-frame_buffer_object::frame_buffer_object(){}\r
-frame_buffer_object::frame_buffer_object(size_t width, size_t height, GLenum mode)\r
-       : impl_(new implementation(width, height, mode)){}\r
-void frame_buffer_object::create(size_t width, size_t height, GLenum mode)\r
-{\r
-       impl_.reset(new implementation(width, height, mode));\r
-}\r
+frame_buffer_object::frame_buffer_object(size_t width, size_t height, GLenum mode) : impl_(new implementation(width, height, mode)){}\r
 void frame_buffer_object::bind_pixel_source() {impl_->bind_pixel_source();}\r
 }}}
\ No newline at end of file
index 8859927caa7c052fe011aff74c2d7363986ff14a..bebb1d2504cc41538a51cf00655b55601443fb8a 100644 (file)
@@ -9,9 +9,7 @@ namespace caspar { namespace common { namespace gl {
 class frame_buffer_object\r
 {\r
 public:\r
-       frame_buffer_object();\r
        frame_buffer_object(size_t width, size_t height, GLenum mode = GL_COLOR_ATTACHMENT0_EXT);\r
-       void create(size_t width, size_t height, GLenum mode = GL_COLOR_ATTACHMENT0_EXT);\r
        void bind_pixel_source();\r
 private:\r
        struct implementation;\r
index 098d8ca051399cade5c95d75a128bf01ca7db1ce..76b3a56b37dec114924666391d1244faf7d8e05a 100644 (file)
@@ -61,7 +61,7 @@ public:
                return producer_device_->background(render_layer);\r
        }\r
 \r
-       const video_format_desc get_video_format_desc() const\r
+       const video_format_desc& get_video_format_desc() const\r
        {\r
                return processor_device_->get_video_format_desc();\r
        }\r
@@ -82,6 +82,6 @@ void channel::clear(int render_layer){impl_->clear(render_layer);}
 void channel::clear(){impl_->clear();}\r
 frame_producer_ptr channel::foreground(int render_layer) const{        return impl_->foreground(render_layer);}\r
 frame_producer_ptr channel::background(int render_layer) const{return impl_->background(render_layer);}\r
-const video_format_desc channel::get_video_format_desc() const{        return impl_->get_video_format_desc();}\r
+const video_format_desc& channel::get_video_format_desc() const{       return impl_->get_video_format_desc();}\r
 \r
 }}
\ No newline at end of file
index 95b085e6ec1a71aaac478bd7ad172117ef7cb0a6..7ddfd11896b35065a1133bf6ba1942707bb80933 100644 (file)
@@ -33,7 +33,7 @@ public:
        void clear();   \r
        frame_producer_ptr foreground(int render_layer) const;\r
        frame_producer_ptr background(int render_layer) const;\r
-       const video_format_desc get_video_format_desc() const;\r
+       const video_format_desc& get_video_format_desc() const;\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index e40a47f796d97c09d42ac4c9a7bd4f91e1e11065..901d4656fc6d39898bcdded37b8fee045d6e1809 100644 (file)
@@ -85,7 +85,7 @@ public:
                                clock.synchronize();\r
                        \r
                        frame_ptr frame;\r
-                       while(frame == nullptr && is_running_)                  \r
+                       while((frame == nullptr || frame == frame::empty()) && is_running_)                     \r
                                frame_processor_->receive(frame);\r
                        \r
                        display_frame(frame);                   \r
@@ -131,7 +131,7 @@ public:
        bool needs_clock_;\r
        std::vector<frame_consumer_ptr> consumers_;\r
 \r
-       video_format_desc fmt_;\r
+       const video_format_desc& fmt_;\r
 \r
        frame_processor_device_ptr frame_processor_;\r
 };\r
index 1e4f6cb6906fb1361b2c81573be32f06c4698ef3..cf117d57584de12995860b397abb9a91bad6b971 100644 (file)
@@ -39,50 +39,69 @@ struct pixel_format_desc
        {\r
                std::fill(planes.begin(), planes.end(), plane());\r
        }\r
-\r
+       \r
        pixel_format::type pix_fmt;\r
        std::array<plane, 4> planes;\r
+};\r
 \r
-       static int hash(const pixel_format_desc& desc)\r
+static size_t hash(const pixel_format_desc& desc)\r
+{\r
+       size_t hash = 0;\r
+       switch(desc.pix_fmt)\r
        {\r
-               int hash = 0;\r
-               switch(desc.pix_fmt)\r
-               {\r
-               case pixel_format::ycbcr:\r
-               case pixel_format::ycbcra:\r
-                       //  0-10 (11) width\r
-                       // 11-21 (11) height\r
-                       // 22-24 (3)  x-ratio\r
-                       // 25-27 (3)  y-ratio\r
-                   // 28-29 (2)  unused\r
-                   // 30        (1)  alpha\r
-                   // 31    (1)  yuv = true => 1\r
-                       hash |= ( desc.planes[0].width                                                  & 0x7FF ) << 0;\r
-                       hash |= ( desc.planes[0].height                                                 & 0x7FF ) << 11;\r
-                       hash |= ((desc.planes[0].height/desc.planes[1].height)  & 0x7   ) << 22;\r
-                       hash |= ((desc.planes[0].width/desc.planes[1].width)    & 0x7   ) << 25;\r
-                       hash |= desc.pix_fmt == pixel_format::ycbcra ? (1 << 30) : 0;\r
-                       hash |= 1 << 31;\r
-                       return hash;\r
-               case pixel_format::bgra:\r
-               case pixel_format::rgba:\r
-               case pixel_format::argb:\r
-               case pixel_format::abgr:\r
+       case pixel_format::ycbcr:\r
+       case pixel_format::ycbcra:\r
+               //  0-10 (11) width\r
+               // 11-21 (11) height\r
+               // 22-24 (3)  x-ratio\r
+               // 25-27 (3)  y-ratio\r
+               // 28-29 (2)  unused\r
+               // 30    (1)  alpha\r
+               // 31    (1)  yuv = true => 1\r
+               hash |= ( desc.planes[0].width                                                  & 0x7FF ) << 0;\r
+               hash |= ( desc.planes[0].height                                                 & 0x7FF ) << 11;\r
+               hash |= ((desc.planes[0].height/desc.planes[1].height)  & 0x7   ) << 22;\r
+               hash |= ((desc.planes[0].width/desc.planes[1].width)    & 0x7   ) << 25;\r
+               hash |= desc.pix_fmt == pixel_format::ycbcra ? (1 << 30) : 0;\r
+               hash |= 1 << 31;\r
+               return hash;\r
+       case pixel_format::bgra:\r
+       case pixel_format::rgba:\r
+       case pixel_format::argb:\r
+       case pixel_format::abgr:\r
                \r
-                       //0-10  (11) height\r
-                       //11-21 (11) width\r
-                   //22-29 (8)  unused\r
-                       //30    (1)  alpha\r
-                       //31    (1)  yuv = false => 0\r
-                       hash |= (desc.planes[0].height & 0xFFFF) << 0;\r
-                       hash |= (desc.planes[0].width  & 0xFFFF) << 15;\r
-                       hash |= 1 << 30;\r
-                       return hash;\r
+               //0-10  (11) height\r
+               //11-21 (11) width\r
+               //22-29 (8)  unused\r
+               //30    (1)  alpha\r
+               //31    (1)  yuv = false => 0\r
+               hash |= (desc.planes[0].height & 0xFFFF) << 0;\r
+               hash |= (desc.planes[0].width  & 0xFFFF) << 15;\r
+               hash |= 1 << 30;\r
+               return hash;\r
 \r
-               default:\r
-                       return hash;\r
-               };\r
+       default:\r
+               return hash;\r
+       };\r
+}\r
+       \r
+class pixel_format_desc_hash\r
+{\r
+public:\r
+       size_t operator()(const pixel_format_desc& desc) const\r
+       {\r
+               return hash(desc);\r
        }\r
 };\r
+\r
+inline bool operator==(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
+{\r
+       return hash(lhs) == hash(rhs);\r
+}\r
+\r
+inline bool operator!=(const pixel_format_desc& lhs, const pixel_format_desc& rhs)\r
+{\r
+       return !(lhs == rhs);\r
+}\r
        \r
 }}
\ No newline at end of file
index 80116f633e58a297088215bfcb58bcffd0c8d28a..f5022f308556fa995d6e3d571f4740feb9e2739e 100644 (file)
@@ -17,17 +17,17 @@ struct composite_frame::implementation : boost::noncopyable
 {      \r
        implementation(composite_frame* self, const std::vector<frame_ptr>& frames) : self_(self), frames_(frames)\r
        {\r
-               mix_audio();\r
+               prepare();\r
        }\r
 \r
        implementation(composite_frame* self, const frame_ptr& frame1, const frame_ptr& frame2) : self_(self)\r
        {\r
                frames_.push_back(frame1);\r
                frames_.push_back(frame2);\r
-               mix_audio();\r
+               prepare();\r
        }\r
 \r
-       void mix_audio()\r
+       void prepare()\r
        {\r
                boost::range::remove_erase(frames_, nullptr);\r
                boost::range::remove_erase(frames_, frame::empty());\r
@@ -70,7 +70,7 @@ struct composite_frame::implementation : boost::noncopyable
                boost::range::for_each(frames_, std::mem_fn(&frame::end_read)); \r
        }\r
 \r
-       void draw(const frame_shader_ptr& shader)\r
+       void draw(frame_shader& shader)\r
        {\r
                glPushMatrix();\r
                glTranslated(self_->x()*2.0, self_->y()*2.0, 0.0);\r
@@ -92,7 +92,7 @@ void composite_frame::begin_write(){impl_->begin_write();}
 void composite_frame::end_write(){impl_->end_write();} \r
 void composite_frame::begin_read(){impl_->begin_read();}\r
 void composite_frame::end_read(){impl_->end_read();}\r
-void composite_frame::draw(const frame_shader_ptr& shader){impl_->draw(shader);}\r
+void composite_frame::draw(frame_shader& shader){impl_->draw(shader);}\r
 \r
 frame_ptr composite_frame::interlace(const frame_ptr& frame1, const frame_ptr& frame2, video_update_format::type mode)\r
 {                      \r
index 910697a4d3d5fcd4444c3b78a96e23bb74c607b6..d5cbe7dd43b35310cfa6d5827e5544f615382290 100644 (file)
@@ -21,7 +21,7 @@ private:
        virtual void end_write();\r
        virtual void begin_read();\r
        virtual void end_read();\r
-       virtual void draw(const frame_shader_ptr& shader);\r
+       virtual void draw(frame_shader& shader);\r
 \r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index e4a7b153e1f375f7e61d0b83c296ac4ab4ab060e..42d674d1f784860c54a48286a7847e914711233f 100644 (file)
@@ -52,9 +52,9 @@ GLubyte lower_pattern[] = {
                                                                                                                                                                                                                                                                                                                \r
 struct frame::implementation : boost::noncopyable\r
 {\r
-       implementation(const pixel_format_desc& desc)\r
-               : alpha_(1.0f), x_(0.0f), y_(0.0f), update_fmt_(video_update_format::progressive), texcoords_(0.0, 1.0, 1.0, 0.0), pixel_data_(4, nullptr)\r
+       implementation(const pixel_format_desc& desc) : alpha_(1.0f), x_(0.0f), y_(0.0f), update_fmt_(video_update_format::progressive), texcoords_(0.0, 1.0, 1.0, 0.0)\r
        {                       \r
+               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
                desc_ = desc;\r
 \r
                for(size_t n = 0; n < desc_.planes.size(); ++n)\r
@@ -81,7 +81,7 @@ struct frame::implementation : boost::noncopyable
        \r
        void begin_write()\r
        {\r
-               pixel_data_ = std::vector<void*>(4, 0);\r
+               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
                boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_write));\r
        }\r
 \r
@@ -92,7 +92,7 @@ struct frame::implementation : boost::noncopyable
        \r
        void begin_read()\r
        {       \r
-               pixel_data_ = std::vector<void*>(4, 0);\r
+               std::fill(pixel_data_.begin(), pixel_data_.end(), nullptr);\r
                boost::range::for_each(pbo_, std::mem_fn(&common::gl::pixel_buffer_object::begin_read));\r
        }\r
 \r
@@ -101,9 +101,9 @@ struct frame::implementation : boost::noncopyable
                boost::range::transform(pbo_, pixel_data_.begin(), std::mem_fn(&common::gl::pixel_buffer_object::end_read));\r
        }\r
 \r
-       void draw(const frame_shader_ptr& shader)\r
+       void draw(frame_shader& shader)\r
        {\r
-               shader->use(desc_);\r
+               shader.use(desc_);\r
                glPushMatrix();\r
                glTranslated(x_*2.0, y_*2.0, 0.0);\r
                glColor4d(1.0, 1.0, 1.0, alpha_);\r
@@ -146,7 +146,7 @@ struct frame::implementation : boost::noncopyable
        }\r
 \r
        std::vector<common::gl::pixel_buffer_object_ptr> pbo_;\r
-       std::vector<void*> pixel_data_; \r
+       std::array<void*, 4> pixel_data_;       \r
        std::vector<short> audio_data_;\r
 \r
        double alpha_;\r
@@ -159,7 +159,7 @@ struct frame::implementation : boost::noncopyable
 };\r
 frame::frame(const pixel_format_desc& desc)\r
        : impl_(new implementation(desc)){}\r
-void frame::draw(const frame_shader_ptr& shader){impl_->draw(shader);}\r
+void frame::draw(frame_shader& shader){impl_->draw(shader);}\r
 void frame::begin_write(){impl_->begin_write();}\r
 void frame::end_write(){impl_->end_write();}   \r
 void frame::begin_read(){impl_->begin_read();}\r
index c2b76ed5c4353668d90a9bf263c2208eb4f8ee2b..a7241609f684861ffe371d4eb463b1d860976af8 100644 (file)
@@ -53,7 +53,7 @@ protected:
        virtual void end_write();\r
        virtual void begin_read();\r
        virtual void end_read();\r
-       virtual void draw(const frame_shader_ptr& shader);\r
+       virtual void draw(frame_shader& shader);\r
 \r
 private:\r
 \r
index bf7bbf392cfd1f9f7c3d6617aaeec2c1d346b512..b6b00882b7f0a6d81a45b9520a7025567d64bb65 100644 (file)
@@ -30,7 +30,7 @@ struct frame_processor_device::implementation : boost::noncopyable
 {      \r
        implementation(frame_processor_device* self, const video_format_desc& format_desc) : fmt_(format_desc), underrun_count_(0)\r
        {               \r
-               output_.set_capacity(4);\r
+               output_.set_capacity(3);\r
                executor_.start();\r
                executor_.invoke([=]\r
                {\r
@@ -53,20 +53,21 @@ struct frame_processor_device::implementation : boost::noncopyable
 \r
        frame_ptr create_frame(const pixel_format_desc& desc)\r
        {\r
-               int key = pixel_format_desc::hash(desc);\r
-               auto& pool = frame_pools_[key];\r
+               tbb::concurrent_bounded_queue<frame_ptr>* pool = &frame_pools_[desc];\r
                \r
                frame_ptr my_frame;\r
-               if(!pool.try_pop(my_frame))             \r
+               if(!pool->try_pop(my_frame))            \r
                        my_frame = executor_.invoke([&]{return std::shared_ptr<frame>(new frame(desc));});              \r
                \r
+               auto destructor = [=]\r
+               {\r
+                       my_frame->reset();\r
+                       pool->push(my_frame);\r
+               };\r
+\r
                return frame_ptr(my_frame.get(), [=](frame*)\r
                {\r
-                       executor_.begin_invoke([=]\r
-                       {\r
-                               my_frame->reset();\r
-                               frame_pools_[key].push(my_frame);\r
-                       });\r
+                       executor_.begin_invoke(destructor);\r
                });\r
        }\r
                \r
@@ -106,7 +107,7 @@ struct frame_processor_device::implementation : boost::noncopyable
        std::unique_ptr<frame_renderer> renderer_;\r
                                \r
        tbb::concurrent_bounded_queue<boost::shared_future<frame_ptr>> output_; \r
-       tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<frame_ptr>> frame_pools_;\r
+       tbb::concurrent_unordered_map<pixel_format_desc, tbb::concurrent_bounded_queue<frame_ptr>, pixel_format_desc_hash> frame_pools_;\r
        \r
        video_format_desc fmt_;\r
        long underrun_count_;\r
@@ -120,7 +121,7 @@ frame_processor_device::frame_processor_device(const video_format_desc& format_d
 frame_ptr frame_processor_device::create_frame(const  pixel_format_desc& desc){return impl_->create_frame(desc);}\r
 void frame_processor_device::send(const frame_ptr& frame){impl_->send(frame);}\r
 void frame_processor_device::receive(frame_ptr& frame){impl_->receive(frame);}\r
-const video_format_desc frame_processor_device::get_video_format_desc() const { return impl_->fmt_;}\r
+const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_;}\r
 \r
 frame_ptr frame_processor_device::create_frame(size_t width, size_t height)\r
 {\r
index dc8844000861f9ca1d6a24628227674aa33f045e..62d904b9674fc4b7de51366de3f82fa9b338bb59 100644 (file)
@@ -41,7 +41,7 @@ public:
        frame_ptr create_frame(size_t width, size_t heightg);                   \r
        frame_ptr create_frame();\r
        \r
-       const video_format_desc get_video_format_desc() const;\r
+       const video_format_desc& get_video_format_desc() const;\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index e5a26b9db05e7117a15d01fe89490e7098052758..6413c462ac22bf99cdfdc39df4dc0744084638ac 100644 (file)
@@ -25,12 +25,9 @@ namespace caspar { namespace core {
 struct frame_renderer::implementation : boost::noncopyable\r
 {      \r
        implementation(frame_processor_device& frame_processor, const video_format_desc& format_desc) \r
-               : frame_processor_(frame_processor), format_desc_(format_desc), index_(0), shader_(std::make_shared<frame_shader>(format_desc)), \r
-                       writing_(2, frame::empty()), output_frame_(frame::empty())\r
+               : frame_processor_(frame_processor), index_(0), shader_(format_desc), output_frame_(frame::empty()), fbo_(format_desc.width, format_desc.height)\r
        {       \r
-               fbo_.create(format_desc_.width, format_desc_.height);\r
-               fbo_.bind_pixel_source();\r
-\r
+               std::fill(writing_.begin(), writing_.end(), frame::empty());\r
                GL(glEnable(GL_POLYGON_STIPPLE));\r
                GL(glEnable(GL_TEXTURE_2D));\r
                GL(glEnable(GL_BLEND));\r
@@ -44,58 +41,53 @@ struct frame_renderer::implementation : boost::noncopyable
                if(frame == nullptr)\r
                        return nullptr;\r
 \r
-               frame_ptr result;\r
                try\r
                {\r
                        index_ = (index_ + 1) % 2;\r
                        int next_index = (index_ + 1) % 2;\r
-\r
-                       // 1. Start asynchronous DMA transfer to video memory.\r
-                       writing_[index_] = std::move(frame);            \r
-                       // Lock frame and give pointer ownership to OpenGL.\r
-                       writing_[index_]->begin_write();\r
+                       \r
+                       // 1. Write from page-locked system memory to video memory.\r
+                       frame->begin_write();\r
+                       writing_[index_] = frame;               \r
                                \r
-                       // 3. Output to external buffer.\r
+                       // 3. Map video memory to page-locked system memory.\r
                        output_frame_->end_read();\r
-                       result = output_frame_;\r
                        \r
                        // Clear framebuffer.\r
                        GL(glClear(GL_COLOR_BUFFER_BIT));       \r
 \r
-                       // 2. Draw to framebuffer and start asynchronous DMA transfer \r
-                       // to page-locked memory.\r
+                       // 2. Draw to framebuffer\r
                        writing_[next_index]->draw(shader_);\r
                                \r
                        // Create an output frame\r
-                       auto temp_frame = frame_processor_.create_frame();\r
+                       output_frame_ = frame_processor_.create_frame();\r
                        \r
                        // Read from framebuffer into page-locked memory.\r
-                       temp_frame->begin_read();\r
-                       temp_frame->audio_data() = std::move(writing_[next_index]->audio_data());\r
-\r
-                       output_frame_ = temp_frame;\r
-\r
+                       output_frame_->begin_read();\r
+                       output_frame_->audio_data() = std::move(writing_[next_index]->audio_data());\r
+                       \r
                        // Return frames to pool.\r
-                       //writing_[next_index]->end_write();\r
+                       //writing_[next_index]->end_write(); // Is done in frame->reset();\r
                        writing_[next_index] = nullptr;\r
                }\r
                catch(...)\r
                {\r
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
-               return result == frame::empty() ? nullptr : result;;\r
+\r
+               return output_frame_;\r
        }\r
 \r
        size_t index_;\r
 \r
        frame_ptr output_frame_;                        \r
-       video_format_desc format_desc_;\r
+\r
        frame_processor_device& frame_processor_;\r
 \r
-       std::vector<frame_ptr> writing_;\r
+       std::array<frame_ptr, 2> writing_;\r
        \r
        common::gl::frame_buffer_object fbo_;\r
-       frame_shader_ptr shader_;\r
+       frame_shader shader_;\r
 };\r
        \r
 frame_renderer::frame_renderer(frame_processor_device& frame_processor, const video_format_desc& format_desc) : impl_(new implementation(frame_processor, format_desc)){}\r
index 9dd9c01387d29e9ba43e05e1ff30009e9d8b7f9f..ccf7ce6474e0f2237af0a483649015127dd28e9c 100644 (file)
@@ -91,66 +91,58 @@ pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, size_t width, size_
 \r
 struct video_transformer::implementation : boost::noncopyable\r
 {\r
-       implementation(AVCodecContext* codec_context) : codec_context_(codec_context), sw_warning_(false){}\r
+       implementation(AVCodecContext* codec_context) : codec_context_(codec_context), width_(codec_context_->width), height_(codec_context_->height), \r
+               pix_fmt_(codec_context_->pix_fmt), desc_(get_pixel_format_desc(pix_fmt_, width_, height_))\r
+       {\r
+               if(desc_.pix_fmt == pixel_format::invalid)\r
+               {\r
+                       CASPAR_LOG(warning) << "Hardware accelerated color transform not supported.";\r
+\r
+                       double param;\r
+                       sws_context_.reset(sws_getContext(width_, height_, pix_fmt_, width_, height_, PIX_FMT_BGRA, SWS_BILINEAR, nullptr, nullptr, &param), sws_freeContext);\r
+                       if(!sws_context_)\r
+                               BOOST_THROW_EXCEPTION(\r
+                                       operation_failed() <<\r
+                                       msg_info("Could not create software scaling context.") << \r
+                                       boost::errinfo_api_function("sws_getContext"));\r
+               }\r
+       }\r
        \r
        frame_ptr execute(const std::shared_ptr<AVFrame>& decoded_frame)\r
        {                               \r
                if(decoded_frame == nullptr)\r
                        return nullptr;\r
-\r
-               int width = codec_context_->width;\r
-               int height = codec_context_->height;\r
-               auto pix_fmt = codec_context_->pix_fmt;\r
-               \r
-               pixel_format_desc desc = get_pixel_format_desc(pix_fmt, width, height);\r
-\r
+                               \r
                frame_ptr result_frame;\r
-               if(desc.pix_fmt != pixel_format::invalid)\r
+               if(sws_context_ == nullptr)\r
                {\r
-                       result_frame = frame_processor_->create_frame(desc);\r
+                       result_frame = frame_processor_->create_frame(desc_);\r
 \r
-                       tbb::parallel_for(0, static_cast<int>(desc.planes.size()), 1, [&](int n)\r
+                       tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
                        {\r
-                               if(desc.planes[n].size == 0)\r
+                               if(desc_.planes[n].size == 0)\r
                                        return;\r
 \r
-                               tbb::parallel_for(0, static_cast<int>(desc.planes[n].height), 1, [&](int y)\r
+                               tbb::parallel_for(0, static_cast<int>(desc_.planes[n].height), 1, [&](int y)\r
                                {\r
                                        memcpy\r
                                        (\r
-                                               result_frame->data(n)+y*desc.planes[n].linesize, \r
+                                               result_frame->data(n)+y*desc_.planes[n].linesize, \r
                                                decoded_frame->data[n] + y*decoded_frame->linesize[n], \r
-                                               desc.planes[n].linesize\r
+                                               desc_.planes[n].linesize\r
                                        );\r
                                });\r
                        });\r
                }\r
                else\r
                {\r
-                       if(!sw_warning_)\r
-                       {\r
-                               CASPAR_LOG(warning) << "Hardware accelerated color transform not supported.";\r
-                               sw_warning_ = true;\r
-                       }\r
-                       result_frame = frame_processor_->create_frame(width, height);\r
+                       result_frame = frame_processor_->create_frame(width_, height_);\r
 \r
                        AVFrame av_frame;       \r
                        avcodec_get_frame_defaults(&av_frame);\r
-                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), result_frame->data(), PIX_FMT_BGRA, width, height);\r
-\r
-                       if(!sws_context_)\r
-                       {\r
-                               double param;\r
-                               sws_context_.reset(sws_getContext(width, height, pix_fmt, width, height, PIX_FMT_BGRA, SWS_BILINEAR, nullptr, nullptr, &param), sws_freeContext);\r
-                               if(!sws_context_)\r
-                                       BOOST_THROW_EXCEPTION(\r
-                                               operation_failed() <<\r
-                                               msg_info("Could not create software scaling context.") << \r
-                                               boost::errinfo_api_function("sws_getContext"));\r
-\r
-                       }               \r
+                       avpicture_fill(reinterpret_cast<AVPicture*>(&av_frame), result_frame->data(), PIX_FMT_BGRA, width_, height_);\r
                 \r
-                       sws_scale(sws_context_.get(), decoded_frame->data, decoded_frame->linesize, 0, height, av_frame.data, av_frame.linesize);               \r
+                       sws_scale(sws_context_.get(), decoded_frame->data, decoded_frame->linesize, 0, height_, av_frame.data, av_frame.linesize);              \r
                }\r
 \r
                // TODO: Make generic for all formats and modes.\r
@@ -167,9 +159,13 @@ struct video_transformer::implementation : boost::noncopyable
        \r
        frame_processor_device_ptr frame_processor_;\r
        std::shared_ptr<SwsContext> sws_context_;\r
-       bool sw_warning_;\r
 \r
        AVCodecContext* codec_context_;\r
+\r
+       int width_;\r
+       int height_;\r
+       PixelFormat pix_fmt_;\r
+       pixel_format_desc desc_;\r
 };\r
 \r
 video_transformer::video_transformer(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
index b0f9743b3961f2c746a8bb512e27f7a6a484cc77..8bc08a65d64c382bc753daf148d0135763fc02bb 100644 (file)
@@ -248,10 +248,8 @@ struct flash_producer::implementation
                flashax_container_->Tick();\r
                invalid_count_ = !flashax_container_->InvalidRectangle() ? std::min(2, invalid_count_+1) : 0;\r
                if(current_frame_ == nullptr || invalid_count_ < 2)\r
-               {               \r
-                       bitmap_ptr frame;               \r
-                       if(current_frame_ == nullptr)                           \r
-                               current_frame_ = std::make_shared<bitmap>(format_desc.width, format_desc.height);\r
+               {                               \r
+                       current_frame_ = bmp_frame_;\r
                        memset(current_frame_->data(), 0, current_frame_->size());\r
                        \r
                        flashax_container_->DrawControl(current_frame_->hdc());\r
@@ -274,15 +272,20 @@ struct flash_producer::implementation
        void initialize(const frame_processor_device_ptr& frame_processor)\r
        {\r
                frame_processor_ = frame_processor;\r
+               auto format_desc = frame_processor_->get_video_format_desc();\r
+               bmp_frame_ = std::make_shared<bitmap>(format_desc.width, format_desc.height);\r
                start(false);\r
        }\r
        \r
        CComObject<flash::FlashAxContainer>* flashax_container_;\r
                \r
        tbb::concurrent_bounded_queue<frame_ptr> frame_buffer_;\r
+\r
        frame_ptr last_frame_;\r
+\r
        bitmap_ptr current_frame_;\r
-               \r
+       bitmap_ptr bmp_frame_;\r
+\r
        std::wstring filename_;\r
        flash_producer* self_;\r
 \r
index 36fbd2364b95c1f9613ebcfacbbde22d2c1d82e0..c6f08d07fdee939dacbe531b3a809e754e795310 100644 (file)
@@ -44,7 +44,6 @@ struct frame_producer_device::implementation : boost::noncopyable
                        \r
        ~implementation()\r
        {\r
-               frame_processor_->clear();\r
                is_running_ = false;\r
                render_thread_.join();\r
        }\r
index 7757825b79ed645db321313d4e3ffd1645f0f2de..e923d2fb57cb847d94843d16568a99429fb073e6 100644 (file)
@@ -31,10 +31,8 @@ struct image_scroll_producer : public frame_producer
        static const int DEFAULT_SCROLL_SPEED = 50;\r
 \r
        image_scroll_producer(const std::wstring& filename, const std::vector<std::wstring>& params) \r
-               : speed_(image_scroll_producer::DEFAULT_SCROLL_SPEED), direction_(direction::Up), offset_(0)\r
+               : speed_(image_scroll_producer::DEFAULT_SCROLL_SPEED), direction_(direction::Up), offset_(0), filename_(filename)\r
        {\r
-               load_and_pad_image(filename);\r
-\r
                auto pos = filename.find_last_of(L'_');\r
                if(pos != std::wstring::npos && pos + 1 < filename.size())\r
                {\r
@@ -143,6 +141,8 @@ struct image_scroll_producer : public frame_producer
                        offset_ = image_width_ - format_desc_.width;\r
 \r
                speed_ = static_cast<int>(abs(static_cast<double>(speed_) / format_desc_.fps));\r
+               \r
+               load_and_pad_image(filename_);\r
        }\r
 \r
        const video_format_desc& get_video_format_desc() const { return format_desc_; } \r
@@ -157,6 +157,8 @@ struct image_scroll_producer : public frame_producer
        std::shared_ptr<unsigned char> image_;\r
        video_format_desc format_desc_;\r
 \r
+       std::wstring filename_;\r
+\r
        frame_processor_device_ptr frame_processor_;\r
 };\r
 \r
index 9c3d9cb9b5293f9adeae80b53995ad594e32c432..571ae182636bf7972ea584ada2238cabb6f2e9b2 100644 (file)
@@ -8,18 +8,18 @@
   </paths>\r
   <channels>\r
     <channel>\r
-      <videomode>PAL</videomode>\r
+      <videomode>1080p2500</videomode>\r
       <consumers>\r
-        <!--ogl>\r
+        <ogl>\r
           <device>1</device>\r
           <stretch>uniform</stretch>\r
           <windowed>true</windowed>\r
         </ogl>\r
-        <audio/-->\r
+        <!--audio/>\r
         <bluefish>\r
           <device>1</device> \r
           <embedded-audio>true</embedded-audio>\r
-        </bluefish>\r
+        </bluefish-->\r
       </consumers>\r
     </channel>\r
   </channels>\r
index 19181ac45d4c38edc87215908cecf74849c7cedf..4220941575a67fe77551364f4940c2e600411214 100644 (file)
@@ -31,6 +31,7 @@
     <None Include="My Amplifier Results\r006hs\r006hs.ampl" />\r
     <None Include="My Amplifier Results\r007cc\r007cc.ampl" />\r
     <None Include="My Amplifier Results\r008lw\r008lw.ampl" />\r
+    <None Include="My Amplifier Results\r009hs\r009hs.ampl" />\r
     <None Include="My Inspector Results\r000ti3\r000ti3.insp" />\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
index 1f6386dbb80005758ee0d2a8cdb7c53dd14ec084..f249f28502830e004d58447c15282b96f0d73638 100644 (file)
@@ -17,6 +17,9 @@
     <None Include="My Inspector Results\r000ti3\r000ti3.insp">\r
       <Filter>My Inspector Results</Filter>\r
     </None>\r
+    <None Include="My Amplifier Results\r009hs\r009hs.ampl">\r
+      <Filter>My Amplifier Results</Filter>\r
+    </None>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Filter Include="My Amplifier Results">\r