]> 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>
Sun, 19 Dec 2010 12:18:01 +0000 (12:18 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 19 Dec 2010 12:18:01 +0000 (12:18 +0000)
37 files changed:
common/concurrency/executor.h
common/gl/pixel_buffer_object.cpp
core/StdAfx.h
core/channel.cpp
core/channel.h
core/core.vcxproj
core/core.vcxproj.filters
core/format/pixel_format.h
core/processor/frame_processor_device.cpp
core/processor/frame_processor_device.h
core/processor/fwd.h
core/processor/image_processor.cpp
core/producer/color/color_producer.cpp
core/producer/ffmpeg/audio/audio_decoder.cpp
core/producer/ffmpeg/audio/audio_decoder.h
core/producer/ffmpeg/ffmpeg_producer.cpp
core/producer/ffmpeg/ffmpeg_producer.h
core/producer/ffmpeg/input.cpp
core/producer/ffmpeg/input.h
core/producer/ffmpeg/video/video_decoder.cpp
core/producer/ffmpeg/video/video_decoder.h
core/producer/ffmpeg/video/video_transformer.cpp [deleted file]
core/producer/ffmpeg/video/video_transformer.h [deleted file]
core/producer/flash/bitmap.h
core/producer/flash/cg_producer.cpp
core/producer/flash/ct_producer.h
core/producer/flash/flash_producer.cpp
core/producer/flash/flash_producer.h
core/producer/frame_producer.h
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
core/producer/transition/transition_producer.h
core/protocol/amcp/AMCPCommandsImpl.cpp
core/protocol/cii/CIIProtocolStrategy.h

index 3415ba003f2967e6d2d5b68c5c13e1c4fd617e48..fcfb14f1ef875518c9f837aac6b514a14c29b217 100644 (file)
@@ -2,6 +2,7 @@
 \r
 #include "../exception/exceptions.h"\r
 #include "../exception/win32_exception.h"\r
+#include "../log/log.h"\r
 \r
 #include <boost/thread.hpp>\r
 \r
@@ -9,6 +10,7 @@
 #include <tbb/concurrent_queue.h>\r
 \r
 #include <functional>\r
+#include <array>\r
 \r
 namespace caspar {\r
 \r
@@ -47,12 +49,12 @@ public:
                return is_running_;\r
        }\r
        \r
-       void stop() // noexcept\r
+       void stop(bool wait = true) // noexcept\r
        {\r
                is_running_ = false;    \r
                begin_invoke([]{}); // wake if sleeping\r
-               assert(boost::this_thread::get_id() != thread_.get_id());\r
-               thread_.join();\r
+               if(wait && boost::this_thread::get_id() != thread_.get_id())\r
+                       thread_.join();\r
        }\r
 \r
        void execute() // noexcept\r
@@ -104,6 +106,16 @@ public:
 \r
                return std::move(future);               \r
        }\r
+\r
+       size_t size() const\r
+       {\r
+               return execution_queue_.size();\r
+       }\r
+\r
+       bool empty() const\r
+       {\r
+               return execution_queue_.empty();\r
+       }\r
        \r
        template<typename Func>\r
        auto invoke(Func&& func, priority p = normal_priority) -> decltype(func())\r
index c956d23d7bd2ce60d5cf3ebc23d78e453366e5b9..48633f69424197b448aeb8833aa187d7d6259259 100644 (file)
@@ -36,7 +36,7 @@ struct pixel_buffer_object::implementation : boost::noncopyable
                default:\r
                        BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Unsupported format.") << arg_name_info("format"));\r
                }\r
-               if(width < 2 || height < 2)\r
+               if(width < 1 || height < 1)\r
                        BOOST_THROW_EXCEPTION(invalid_argument() << msg_info("Invalid dimensions.")  << arg_name_info("width/height"));\r
        }\r
 \r
index 78566bcfabdc86cd4289a84a90188354f34e730a..4a77f6155bfd98c3dc76a55380dff783a4da0d7e 100644 (file)
@@ -67,6 +67,8 @@
 \r
 #include "../common/utility/string_convert.h"\r
 #include "../common/utility/safe_ptr.h"\r
+//#include "../common/concurrency/executor.h" // Can't include this due to MSVC lambda bug\r
+#include "../common/concurrency/concurrent_queue.h"\r
 \r
 #include "../common/log/Log.h"\r
 #include "../common/exception/exceptions.h"\r
index 713e1c612ec3b6d7066fd5ada68e66518a86f8f5..c8072dc316390f3af8eb9561a1f6227bc26621c7 100644 (file)
@@ -21,9 +21,14 @@ public:
                producer_device_->clear();\r
        }\r
        \r
-       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none)\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay)\r
        {\r
-               producer_device_->load(render_layer, producer, option);\r
+               producer_device_->load(render_layer, producer, autoplay);\r
+       }\r
+\r
+       void preview(int render_layer, const safe_ptr<frame_producer>& producer)\r
+       {\r
+               producer_device_->preview(render_layer, producer);\r
        }\r
 \r
        void pause(int render_layer)\r
@@ -75,7 +80,8 @@ private:
 channel::channel(channel&& other) : impl_(std::move(other.impl_)){}\r
 channel::channel(const safe_ptr<frame_producer_device>& producer_device, const safe_ptr<frame_processor_device>& processor_device, const safe_ptr<frame_consumer_device>& consumer_device)\r
        : impl_(new implementation(producer_device, processor_device, consumer_device)){}\r
-void channel::load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
+void channel::load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay){impl_->load(render_layer, producer, autoplay);}\r
+void channel::preview(int render_layer, const safe_ptr<frame_producer>& producer){impl_->preview(render_layer, producer);}\r
 void channel::pause(int render_layer){impl_->pause(render_layer);}\r
 void channel::play(int render_layer){impl_->play(render_layer);}\r
 void channel::stop(int render_layer){impl_->stop(render_layer);}\r
index 9ee3334bf3ea3b525358b1113ff19bbe26b3be3f..bbd6b5653b149bc84208c5cde6cdfc36ca05793c 100644 (file)
@@ -26,7 +26,8 @@ public:
        channel(channel&& other);\r
        channel(const safe_ptr<frame_producer_device>& producer_device, const safe_ptr<frame_processor_device>& processor_device, const safe_ptr<frame_consumer_device>& consumer_device);\r
        \r
-       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay = false);\r
+       void preview(int render_layer, const safe_ptr<frame_producer>& producer);\r
        void pause(int render_layer);\r
        void play(int render_layer);\r
        void stop(int render_layer);\r
index 2567ac77a2ecd2ea44fb60c75c2a6a2c4e99c976..e0045093f1888b68489a3d1dfd10006698dcba25 100644 (file)
@@ -44,8 +44,8 @@
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\</IntDir>\r
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\</IntDir>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\dependencies\boost_1_44_0\;..\..\..\dependencies\boost_1_44_0\;..\..\dependencies\ffmpeg 0.6\include\;..\..\..\dependencies\ffmpeg 0.6\include\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\include\;..\..\..\dependencies\SFML-1.6\include\;..\..\dependencies\tbb30_20100406oss\include\;..\..\..\dependencies\tbb30_20100406oss\include\;$(IncludePath)</IncludePath>\r
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\dependencies\boost_1_44_0\;..\..\..\dependencies\boost_1_44_0\;..\..\dependencies\ffmpeg 0.6\include\;..\..\..\dependencies\ffmpeg 0.6\include\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\include\;..\..\..\dependencies\SFML-1.6\include\;..\..\dependencies\tbb30_20100406oss\include\;..\..\..\dependencies\tbb30_20100406oss\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\common;..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\dependencies\boost_1_44_0\;..\..\..\dependencies\boost_1_44_0\;..\..\dependencies\ffmpeg 0.6\include\;..\..\..\dependencies\ffmpeg 0.6\include\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\include\;..\..\..\dependencies\SFML-1.6\include\;..\..\dependencies\tbb30_20100406oss\include\;..\..\..\dependencies\tbb30_20100406oss\include\;$(IncludePath)</IncludePath>\r
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\common;..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Inc\;..\..\dependencies\boost_1_44_0\;..\..\..\dependencies\boost_1_44_0\;..\..\dependencies\ffmpeg 0.6\include\;..\..\..\dependencies\ffmpeg 0.6\include\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\include\;..\..\..\dependencies\SFML-1.6\include\;..\..\dependencies\tbb30_20100406oss\include\;..\..\..\dependencies\tbb30_20100406oss\include\;$(IncludePath)</IncludePath>\r
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\dependencies\BluefishSDK_V5_8_0_31\Lib\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Lib\;..\..\dependencies\boost_1_44_0\stage\lib\;..\..\..\dependencies\boost_1_44_0\stage\lib\;..\..\dependencies\ffmpeg 0.6\lib\;..\..\..\dependencies\ffmpeg 0.6\lib\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\lib\;..\..\..\dependencies\SFML-1.6\lib\;..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;..\..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;$(LibraryPath)</LibraryPath>\r
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\dependencies\BluefishSDK_V5_8_0_31\Lib\;..\..\..\dependencies\BluefishSDK_V5_8_0_31\Lib\;..\..\dependencies\boost_1_44_0\stage\lib\;..\..\..\dependencies\boost_1_44_0\stage\lib\;..\..\dependencies\ffmpeg 0.6\lib\;..\..\..\dependencies\ffmpeg 0.6\lib\;..\..\dependencies\FreeImage\Dist\;..\..\..\dependencies\FreeImage\Dist\;..\..\dependencies\GLee5_4\;..\..\..\dependencies\GLee5_4\;..\..\dependencies\SFML-1.6\lib\;..\..\..\dependencies\SFML-1.6\lib\;..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;..\..\..\dependencies\tbb30_20100406oss\lib\ia32\vc10\;$(LibraryPath)</LibraryPath>\r
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)debug\</OutDir>\r
     <ClInclude Include="producer\ffmpeg\ffmpeg_producer.h" />\r
     <ClInclude Include="producer\ffmpeg\input.h" />\r
     <ClInclude Include="producer\ffmpeg\video\video_decoder.h" />\r
-    <ClInclude Include="producer\ffmpeg\video\video_transformer.h" />\r
     <ClInclude Include="producer\flash\axflash.h" />\r
     <ClInclude Include="producer\flash\bitmap.h" />\r
     <ClInclude Include="producer\flash\cg_producer.h" />\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
     <ClCompile Include="producer\ffmpeg\video\video_decoder.cpp">\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\ffmpeg\video\video_transformer.cpp">\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../stdafx.h</PrecompiledHeaderFile>\r
     </ClCompile>\r
index ef4597be7fe0f9e373afe67fc32e59363707a868..36b05bdc6a9c6e2dc33c73ea32c225da0b4ae1b9 100644 (file)
     <ClInclude Include="producer\ffmpeg\ffmpeg_producer.h">\r
       <Filter>Source\channel\producer\ffmpeg</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="producer\ffmpeg\audio\audio_decoder.h">\r
-      <Filter>Source\channel\producer\ffmpeg\audio</Filter>\r
-    </ClInclude>\r
-    <ClInclude Include="producer\ffmpeg\video\video_decoder.h">\r
-      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="producer\image\image_loader.h">\r
       <Filter>Source\channel\producer\image</Filter>\r
     </ClInclude>\r
     <ClInclude Include="producer\frame_producer.h">\r
       <Filter>Source\channel\producer</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="producer\ffmpeg\video\video_transformer.h">\r
-      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="producer\flash\cg_producer.h">\r
       <Filter>Source\channel\producer\flash</Filter>\r
     </ClInclude>\r
     <ClInclude Include="processor\read_frame.h">\r
       <Filter>Source\channel\processor\frame</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="producer\ffmpeg\input.h">\r
-      <Filter>Source\channel\producer\ffmpeg\io</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="processor\draw_frame.h">\r
       <Filter>Source\channel\processor\frame</Filter>\r
     </ClInclude>\r
     <ClInclude Include="processor\audio_processor.h">\r
       <Filter>Source\channel\processor\audio</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="producer\ffmpeg\audio\audio_decoder.h">\r
+      <Filter>Source\channel\producer\ffmpeg\audio</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\ffmpeg\input.h">\r
+      <Filter>Source\channel\producer\ffmpeg\io</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="producer\ffmpeg\video\video_decoder.h">\r
+      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="StdAfx.cpp">\r
     <ClCompile Include="producer\ffmpeg\ffmpeg_producer.cpp">\r
       <Filter>Source\channel\producer\ffmpeg</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="producer\ffmpeg\audio\audio_decoder.cpp">\r
-      <Filter>Source\channel\producer\ffmpeg\audio</Filter>\r
-    </ClCompile>\r
-    <ClCompile Include="producer\ffmpeg\video\video_decoder.cpp">\r
-      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="producer\image\image_loader.cpp">\r
       <Filter>Source\channel\producer\image</Filter>\r
     </ClCompile>\r
     <ClCompile Include="protocol\media.cpp">\r
       <Filter>Source\protocol</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="producer\ffmpeg\video\video_transformer.cpp">\r
-      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="producer\flash\cg_producer.cpp">\r
       <Filter>Source\channel\producer\flash</Filter>\r
     </ClCompile>\r
     <ClCompile Include="processor\read_frame.cpp">\r
       <Filter>Source\channel\processor\frame</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="producer\ffmpeg\input.cpp">\r
-      <Filter>Source\channel\producer\ffmpeg\io</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="format\pixel_format.cpp">\r
       <Filter>Source\channel\format</Filter>\r
     </ClCompile>\r
     <ClCompile Include="processor\audio_processor.cpp">\r
       <Filter>Source\channel\processor\audio</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="producer\ffmpeg\audio\audio_decoder.cpp">\r
+      <Filter>Source\channel\producer\ffmpeg\audio</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\ffmpeg\input.cpp">\r
+      <Filter>Source\channel\producer\ffmpeg\io</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="producer\ffmpeg\video\video_decoder.cpp">\r
+      <Filter>Source\channel\producer\ffmpeg\video</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <Midl Include="consumer\decklink\DeckLinkAPI_v7_3.idl">\r
index a6037b56ed4d5985d184148cf32374cd3b5e315e..d99fffaceccd14f5511bfaf33438f0c67bfec0c8 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once\r
 \r
 #include <memory>\r
-#include <array>\r
+#include <vector>\r
 \r
 namespace caspar { namespace core {\r
        \r
index 6a132ad46ddb9bce4229fab2bc247b68b6e86384..397048b6ad0805049375f2ea31e13cfe28e78b8d 100644 (file)
 \r
 #include "../format/video_format.h"\r
 \r
-#include "../../common/exception/exceptions.h"\r
-#include "../../common/concurrency/executor.h"\r
-#include "../../common/gl/utility.h"\r
-\r
+#include <common/exception/exceptions.h>\r
+#include <common/concurrency/executor.h>\r
+#include <common/gl/utility.h>\r
 \r
 #include <tbb/concurrent_queue.h>\r
 #include <tbb/concurrent_unordered_map.h>\r
 \r
 #include <boost/range/algorithm.hpp>\r
-#include <boost/thread.hpp>\r
-\r
-#include <functional>\r
 \r
 namespace caspar { namespace core {\r
        \r
@@ -98,20 +94,20 @@ void frame_processor_device::send(safe_ptr<draw_frame>&& frame){impl_->send(std:
 safe_ptr<const read_frame> frame_processor_device::receive(){return impl_->receive();}\r
 const video_format_desc& frame_processor_device::get_video_format_desc() const { return impl_->fmt_; }\r
 safe_ptr<write_frame> frame_processor_device::create_frame(const pixel_format_desc& desc){ return impl_->create_frame(desc); }         \r
-safe_ptr<write_frame> frame_processor_device::create_frame(size_t width, size_t height)\r
+safe_ptr<write_frame> frame_processor_device::create_frame(size_t width, size_t height, pixel_format::type pix_fmt)\r
 {\r
        // Create bgra frame\r
        pixel_format_desc desc;\r
-       desc.pix_fmt = pixel_format::bgra;\r
+       desc.pix_fmt = pix_fmt;\r
        desc.planes.push_back(pixel_format_desc::plane(width, height, 4));\r
        return create_frame(desc);\r
 }\r
                        \r
-safe_ptr<write_frame> frame_processor_device::create_frame()\r
+safe_ptr<write_frame> frame_processor_device::create_frame(pixel_format::type pix_fmt)\r
 {\r
        // Create bgra frame with output resolution\r
        pixel_format_desc desc;\r
-       desc.pix_fmt = pixel_format::bgra;\r
+       desc.pix_fmt = pix_fmt;\r
        desc.planes.push_back(pixel_format_desc::plane(get_video_format_desc().width, get_video_format_desc().height, 4));\r
        return create_frame(desc);\r
 }\r
index af71f871adeaa42e51bd51310937b038c96b9873..2e5f1c6d93275cee8ac3057438a4207eda420b7d 100644 (file)
 */\r
 #pragma once\r
 \r
-#include <memory>\r
-#include <vector>\r
-\r
 #include "fwd.h"\r
+\r
 #include "write_frame.h"\r
 \r
 #include "../format/video_format.h"\r
 \r
-namespace caspar { namespace core {\r
+#include <common/utility/safe_ptr.h>\r
+\r
+#include <memory>\r
 \r
+namespace caspar { namespace core {\r
+       \r
 class frame_processor_device : boost::noncopyable\r
 {\r
 public:\r
-       frame_processor_device(frame_processor_device&& other);\r
+       frame_processor_device(frame_processor_device&& other); // nothrow\r
        frame_processor_device(const video_format_desc& format_desc);\r
                \r
-       void send(safe_ptr<draw_frame>&& frame);\r
+       void send(safe_ptr<draw_frame>&& frame); // nothrow\r
        safe_ptr<const read_frame> receive();\r
-       \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);                        \r
-       safe_ptr<write_frame> create_frame();\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;\r
+       const video_format_desc& get_video_format_desc() const; // nothrow\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index 1e03e2525c902b37f5a25aa26f0e019bdcde9a99..775d367e1e025cc270be49ff36851b04645a85ee 100644 (file)
@@ -7,9 +7,6 @@ namespace caspar { namespace core {
 class read_frame;\r
 class write_frame;\r
 class draw_frame;\r
-\r
-class draw_frame;\r
-\r
 class transform_frame;\r
 class composite_frame;\r
 \r
@@ -17,4 +14,5 @@ class image_processor;
 class frame_processor;\r
 class audio_processor;\r
 class frame_processor_device;\r
+\r
 }}
\ No newline at end of file
index 477909d89c3e68edaf297c70afc9759d4adc4398..3587b7e70166e7213d2bf2458664bc52e5fbf492 100644 (file)
@@ -191,6 +191,7 @@ struct image_processor::implementation : boost::noncopyable
        {\r
                transform_stack_.pop();\r
                set_mode(transform_stack_.top().mode);\r
+               glColor4d(1.0, 1.0, 1.0, transform_stack_.top().alpha);\r
                glPopMatrix();\r
        }\r
 \r
index 35bb77677bf92bcb3e561c50d3b63715880e1ece..c58a80a7fa3c999aa5d7e724b24b8b3243a79dc0 100644 (file)
 #include "color_producer.h"\r
 \r
 #include "../../processor/draw_frame.h"\r
-#include "../../format/video_format.h"\r
 \r
-#include <intrin.h>\r
-#pragma intrinsic(__movsd, __stosd)\r
+#include <sstream>\r
 \r
 namespace caspar { namespace core {\r
        \r
-unsigned int get_pixel_color_value(const std::wstring& parameter)\r
-{\r
-       union Color \r
-       {\r
-               struct Components \r
-               {\r
-                       unsigned char a;\r
-                       unsigned char r;\r
-                       unsigned char g;\r
-                       unsigned char b;\r
-               } comp;\r
-\r
-               unsigned int value;\r
-       };\r
-\r
-       std::wstring color_code;\r
-       if(parameter.length() != 9 || parameter[0] != '#')\r
-               BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("parameter") << arg_value_info(narrow(parameter)) << msg_info("Invalid color code"));\r
-       \r
-       color_code = parameter.substr(1);\r
-\r
-       Color color;\r
-       color.value = _tcstoul(color_code.c_str(), 0, 16);\r
-       unsigned char temp = color.comp.a;\r
-       color.comp.a = color.comp.b;\r
-       color.comp.b = temp;\r
-       temp = color.comp.r;\r
-       color.comp.r = color.comp.g;\r
-       color.comp.g = temp;\r
-\r
-       return color.value;\r
-}\r
-\r
 class color_producer : public frame_producer\r
 {\r
 public:\r
-       color_producer(color_producer&& other) : frame_(std::move(other.frame_)), color_value_(std::move(other.color_value_)), color_str_(std::move(other.color_str_)){}\r
-       explicit color_producer(const std::wstring& color) : color_str_(color), color_value_(get_pixel_color_value(color)), frame_(draw_frame::empty()){}\r
-       \r
-       safe_ptr<draw_frame> receive()\r
-       { \r
-               return frame_;\r
+       color_producer(color_producer&& other) : frame_(std::move(other.frame_)), color_str_(std::move(other.color_str_)){}\r
+\r
+       explicit color_producer(const std::wstring& color) : color_str_(color), frame_(draw_frame::empty())\r
+       {\r
+               if(color.length() != 9 || color[0] != '#')\r
+                       BOOST_THROW_EXCEPTION(invalid_argument() << arg_name_info("color") << arg_value_info(narrow(color)) << msg_info("Invalid color code"));\r
        }\r
+       \r
+       safe_ptr<draw_frame> receive() { return frame_; }\r
 \r
        void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
        {\r
-               auto frame = std::move(frame_processor->create_frame());\r
-               __stosd(reinterpret_cast<unsigned long*>(frame->pixel_data().begin()), color_value_, frame->pixel_data().size() / sizeof(unsigned long));\r
+               auto frame = frame_processor->create_frame(1, 1, pixel_format::bgra);\r
+               auto& value = *reinterpret_cast<unsigned long*>(frame->pixel_data().begin());\r
+               std::wstringstream str(color_str_.substr(1));\r
+               str >> std::hex >> value;       \r
                frame_ = std::move(frame);\r
        }\r
        \r
-       std::wstring print() const\r
-       {\r
-               return + L"color[" + color_str_ + L"]";\r
-       }\r
+       std::wstring print() const { return + L"color[" + color_str_ + L"]"; }\r
 \r
        safe_ptr<draw_frame> frame_;\r
-       unsigned int color_value_;\r
        std::wstring color_str_;\r
 };\r
 \r
index 4f5e07b5dfb34a2950f00f474568c7c461fe8ef7..782585e5947bda569ba0d1514ecad180c5499a21 100644 (file)
@@ -3,6 +3,7 @@
 #include "audio_decoder.h"\r
 \r
 #include <queue>\r
+#include <deque>\r
 \r
 #include <tbb/cache_aligned_allocator.h>\r
                \r
@@ -28,9 +29,8 @@ struct audio_decoder::implementation : boost::noncopyable
        static const int FRAME_AUDIO_SAMPLES = 1920*2;\r
        static const int SAMPLE_RATE = 48000;\r
 \r
-       implementation(AVCodecContext* codec_context) \r
-               : current_chunk_(), codec_context_(codec_context), audio_resample_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2),\r
-               audio_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2)/*, resample_context_(nullptr)*/\r
+       implementation(AVCodecContext* codec_context) : current_chunk_(), codec_context_(codec_context), audio_resample_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2),\r
+               audio_buffer_(4*SAMPLE_RATE*2+FF_INPUT_BUFFER_PADDING_SIZE/2)//, resample_context_(nullptr)\r
        {\r
                //if(codec_context_->sample_rate != SAMPLE_RATE)\r
                //{\r
@@ -107,9 +107,9 @@ struct audio_decoder::implementation : boost::noncopyable
        buffer audio_buffer_;   \r
        buffer audio_resample_buffer_;\r
 \r
-       std::deque<short, tbb::cache_aligned_allocator<short>> current_chunk_;\r
+       std::vector<short, tbb::cache_aligned_allocator<short>> current_chunk_;\r
 \r
-       std::vector<short, tbb::cache_aligned_allocator<short>> current_resample_chunk_;\r
+       //std::vector<short, tbb::cache_aligned_allocator<short>> current_resample_chunk_;\r
 \r
        AVCodecContext* codec_context_;\r
 };\r
index d37c7851c765a331a53996f2f2543c5c3146d1aa..630ea235ad5672976b892aa42fa65e54c60ee912 100644 (file)
@@ -22,6 +22,5 @@ private:
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<audio_decoder> audio_decoder_ptr;\r
 \r
 }}}
\ No newline at end of file
index 22675b1fee1664010206b379b7492105443be3fe..718f629f9de61703e957cde704194e964fb879f5 100644 (file)
@@ -25,7 +25,7 @@ extern "C"
 \r
 #include "audio/audio_decoder.h"\r
 #include "video/video_decoder.h"\r
-#include "video/video_transformer.h"\r
+#include "video/video_decoder.h"\r
 \r
 #include "../../format/video_format.h"\r
 #include "../../processor/transform_frame.h"\r
@@ -52,7 +52,7 @@ struct ffmpeg_producer_impl
 {\r
 public:\r
        ffmpeg_producer_impl(const std::wstring& filename, const  std::vector<std::wstring>& params) : filename_(filename), last_frame_(transform_frame(draw_frame::empty())), underrun_count_(0),\r
-               input_(filename), video_decoder_(input_.get_video_codec_context().get()), video_transformer_(input_.get_video_codec_context().get()), audio_decoder_(input_.get_audio_codec_context().get())\r
+               input_(filename), video_decoder_(input_.get_video_codec_context().get()), audio_decoder_(input_.get_audio_codec_context().get())\r
        {                               \r
                input_.set_loop(std::find(params.begin(), params.end(), L"LOOP") != params.end());\r
 \r
@@ -67,7 +67,7 @@ public:
        void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
        {\r
                format_desc_ = frame_processor->get_video_format_desc();\r
-               video_transformer_.initialize(frame_processor);\r
+               video_decoder_.initialize(frame_processor);\r
        }\r
                \r
        safe_ptr<draw_frame> receive()\r
@@ -87,8 +87,7 @@ public:
                        { // Video Decoding and Scaling\r
                                if(!video_packet.empty())\r
                                {\r
-                                       auto decoded_frame = video_decoder_.execute(video_packet);\r
-                                       auto frame = video_transformer_.execute(decoded_frame);\r
+                                       auto frame = video_decoder_.execute(video_packet);\r
                                        video_frame_channel_.push_back(std::move(frame));       \r
                                }\r
                        }, \r
@@ -160,7 +159,6 @@ public:
        input                                                                   input_;                 \r
        audio_decoder                                                   audio_decoder_;\r
        video_decoder                                                   video_decoder_;\r
-       video_transformer                                               video_transformer_;\r
 \r
        std::deque<safe_ptr<write_frame>>               video_frame_channel_;   \r
        std::deque<std::vector<short>>                  audio_chunk_channel_;\r
index fb4e444af0c62ed795feb092a92e8b400ee3122b..8be774089f0e842f73b92e01822ed119b2116da6 100644 (file)
@@ -2,6 +2,8 @@
 \r
 #include "../frame_producer.h"\r
 \r
+#include <common/utility/safe_ptr.h>\r
+\r
 #include <string>\r
 #include <vector>\r
 \r
index 003a594e8f42db5caf833401fd0ab4772053893b..1cd45dca1047a2ebf9a6a39ddd7413fbb354764b 100644 (file)
@@ -3,7 +3,6 @@
 #include "input.h"\r
 \r
 #include "../../format/video_format.h"\r
-#include "../../../common/utility/scope_exit.h"\r
 #include "../../../common/concurrency/concurrent_queue.h"\r
 \r
 #include <tbb/concurrent_queue.h>\r
@@ -19,7 +18,7 @@
 #pragma warning (disable : 4244)\r
 #endif\r
 \r
-#include <boost/thread.hpp>\r
+#include "../../../common/concurrency/executor.h"\r
 \r
 extern "C" \r
 {\r
@@ -30,7 +29,7 @@ extern "C"
 \r
 namespace caspar { namespace core { namespace ffmpeg{\r
                \r
-struct input::implementation : public std::enable_shared_from_this<implementation>, boost::noncopyable\r
+struct input::implementation : boost::noncopyable\r
 {\r
        static const size_t BUFFER_SIZE = 2 << 25;\r
 \r
@@ -59,26 +58,25 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
 \r
                video_codec_context_ = open_stream(CODEC_TYPE_VIDEO, video_s_index_);\r
                if(!video_codec_context_)\r
-                       CASPAR_LOG(warning) << "No video stream found.";\r
+                       CASPAR_LOG(warning) << "Could not open any video stream.";\r
                \r
                audio_codex_context_ = open_stream(CODEC_TYPE_AUDIO, audio_s_index_);\r
                if(!audio_codex_context_)\r
-                       CASPAR_LOG(warning) << "No audio stream found.";\r
+                       CASPAR_LOG(warning) << "Could not open any audio stream.";\r
 \r
                if(!video_codec_context_ && !audio_codex_context_)\r
                        BOOST_THROW_EXCEPTION(file_read_error() << msg_info("No video or audio codec context found."));         \r
-                               \r
-               is_running_ = true;\r
-               io_thread_ = boost::thread([=]{read_file();});\r
+                       \r
+               executor_.start();\r
+               executor_.begin_invoke([this]{read_file();});\r
+               CASPAR_LOG(info) << print() << " Started";\r
        }\r
 \r
-       void stop()\r
-       {               \r
-               is_running_ = false;\r
-               buffer_size_ = 0;\r
-               cond_.notify_one();\r
+       ~implementation()\r
+       {\r
+               CASPAR_LOG(info) << print() << " Ended";\r
        }\r
-                               \r
+                                                       \r
        std::shared_ptr<AVCodecContext> open_stream(int codec_type, int& s_index)\r
        {               \r
                AVStream** streams_end = format_context_->streams+format_context_->nb_streams;\r
@@ -100,67 +98,33 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
                return std::shared_ptr<AVCodecContext>((*stream)->codec, avcodec_close);\r
        }\r
                \r
-       void read_file()\r
-       {       \r
-               static tbb::atomic<size_t> instances(boost::initialized_value); // Dangling threads debug info.\r
-\r
-               CASPAR_LOG(info) << L"ffmpeg[" << boost::filesystem::wpath(filename_).filename().c_str() << L"] Started file buffer thread. Instances: " << ++instances;\r
-               win32_exception::install_handler();\r
-               \r
-               try\r
+       void read_file() // For every packet taken: read in a number of packets.\r
+       {               \r
+               for(size_t n = 0; (n < 3 || video_packet_buffer_.size() < 3 || audio_packet_buffer_.size() < 3) && buffer_size_ < BUFFER_SIZE && executor_.is_running(); ++n)\r
                {\r
-                       auto keep_alive = shared_from_this(); // keep alive this while thread is running.\r
-                       while(keep_alive->is_running_)\r
+                       AVPacket tmp_packet;\r
+                       safe_ptr<AVPacket> read_packet(&tmp_packet, av_free_packet);    \r
+                       tbb::queuing_mutex::scoped_lock lock(seek_mutex_);      \r
+\r
+                       if (av_read_frame(format_context_.get(), read_packet.get()) >= 0) // NOTE: read_packet is only valid until next call of av_safe_ptr<read_frame> or av_close_input_file\r
                        {\r
+                               auto packet = aligned_buffer(read_packet->data, read_packet->data + read_packet->size);\r
+                               if(read_packet->stream_index == video_s_index_)                                                 \r
                                {\r
-                                       AVPacket tmp_packet;\r
-                                       safe_ptr<AVPacket> read_packet(&tmp_packet, av_free_packet);    \r
-                                       tbb::queuing_mutex::scoped_lock lock(seek_mutex_);      \r
-\r
-                                       if (av_read_frame(format_context_.get(), read_packet.get()) >= 0) // NOTE: read_packet is only valid until next call of av_safe_ptr<read_frame> or av_close_input_file\r
-                                       {\r
-                                               auto packet = aligned_buffer(read_packet->data, read_packet->data + read_packet->size);\r
-                                               if(read_packet->stream_index == video_s_index_)                                                 \r
-                                               {\r
-                                                       buffer_size_ += packet.size();\r
-                                                       video_packet_buffer_.try_push(std::move(packet));                                               \r
-                                               }\r
-                                               else if(read_packet->stream_index == audio_s_index_)    \r
-                                               {\r
-                                                       buffer_size_ += packet.size();\r
-                                                       audio_packet_buffer_.try_push(std::move(packet));\r
-                                               }\r
-                                       }\r
-                                       else if(!loop_ || av_seek_frame(format_context_.get(), -1, 0, AVSEEK_FLAG_BACKWARD) < 0) // TODO: av_seek_frame does not work for all formats\r
-                                               is_running_ = false;\r
+                                       buffer_size_ += packet.size();\r
+                                       video_packet_buffer_.try_push(std::move(packet));                                               \r
                                }\r
-\r
-                               if(!need_packet() && is_running_)\r
-                                       boost::this_thread::sleep(boost::posix_time::milliseconds(10)); // Read packets in max 100 pps\r
-\r
-                               if(buffer_size_ >= BUFFER_SIZE)\r
+                               else if(read_packet->stream_index == audio_s_index_)    \r
                                {\r
-                                       boost::unique_lock<boost::mutex> lock(mut_);\r
-                                       while(buffer_size_ >= BUFFER_SIZE && !need_packet() && is_running_)\r
-                                               cond_.wait(lock);\r
+                                       buffer_size_ += packet.size();\r
+                                       audio_packet_buffer_.try_push(std::move(packet));\r
                                }\r
                        }\r
+                       else if(!loop_ || av_seek_frame(format_context_.get(), -1, 0, AVSEEK_FLAG_BACKWARD) < 0) // TODO: av_seek_frame does not work for all formats\r
+                               executor_.stop(false);\r
                }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-               }\r
-               \r
-               is_running_ = false;\r
-               \r
-               CASPAR_LOG(info) << L"ffmpeg[" << boost::filesystem::wpath(filename_).filename().c_str() << L"] Ended file buffer thread. Instances: " << --instances;\r
-       }\r
-\r
-       bool need_packet()\r
-       {\r
-               return video_packet_buffer_.size() < 3 || audio_packet_buffer_.size() < 3;\r
        }\r
-       \r
+               \r
        aligned_buffer get_video_packet()\r
        {\r
                return get_packet(video_packet_buffer_);\r
@@ -177,14 +141,15 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
                if(buffer.try_pop(packet))\r
                {\r
                        buffer_size_ -= packet.size();\r
-                       cond_.notify_one();\r
+                       if(executor_.size() < 4) // Avoid problems when in underrun.\r
+                               executor_.begin_invoke([this]{read_file();});\r
                }\r
                return std::move(packet);\r
        }\r
 \r
        bool is_eof() const\r
        {\r
-               return !is_running_ && video_packet_buffer_.empty() && audio_packet_buffer_.empty();\r
+               return !executor_.is_running() && video_packet_buffer_.empty() && audio_packet_buffer_.empty();\r
        }\r
                \r
        // TODO: Not properly done.\r
@@ -203,6 +168,11 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
                        avcodec_flush_buffers(audio_codex_context_.get());\r
                return true;\r
        }\r
+\r
+       std::wstring print() const\r
+       {\r
+               return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"] Buffering ";\r
+       }\r
                                \r
        std::shared_ptr<AVFormatContext>        format_context_;        // Destroy this last\r
 \r
@@ -221,16 +191,12 @@ struct input::implementation : public std::enable_shared_from_this<implementatio
        concurrent_bounded_queue_r<aligned_buffer> video_packet_buffer_;\r
        concurrent_bounded_queue_r<aligned_buffer> audio_packet_buffer_;\r
        \r
-       boost::mutex                            mut_;\r
-       boost::condition_variable       cond_;\r
        tbb::atomic<size_t>                     buffer_size_;\r
 \r
-       boost::thread   io_thread_;\r
-       tbb::atomic<bool> is_running_;\r
+       executor executor_;\r
 };\r
 \r
 input::input(const std::wstring& filename) : impl_(new implementation(filename)){}\r
-input::~input(){impl_->stop();}\r
 void input::set_loop(bool value){impl_->loop_ = value;}\r
 const std::shared_ptr<AVCodecContext>& input::get_video_codec_context() const{return impl_->video_codec_context_;}\r
 const std::shared_ptr<AVCodecContext>& input::get_audio_codec_context() const{return impl_->audio_codex_context_;}\r
index 06b17be670c2b2aefbd790295d8e52c2df276309..24a5b0cd5e113238621d83a374a2ba64e463ae65 100644 (file)
@@ -1,9 +1,10 @@
 #pragma once\r
 \r
-#include <system_error>\r
-\r
 #include <tbb/cache_aligned_allocator.h>\r
 \r
+#include <memory>\r
+#include <string>\r
+\r
 struct AVCodecContext;\r
 \r
 namespace caspar { namespace core { namespace ffmpeg{  \r
@@ -14,7 +15,6 @@ class input : boost::noncopyable
 {\r
 public:\r
        input(const std::wstring& filename);\r
-       ~input();\r
        const std::shared_ptr<AVCodecContext>& get_video_codec_context() const;\r
        const std::shared_ptr<AVCodecContext>& get_audio_codec_context() const;\r
 \r
@@ -29,8 +29,6 @@ private:
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<input> input_ptr;\r
-typedef std::unique_ptr<input> input_uptr;\r
 \r
        }\r
 }}\r
index b5edfb0e93b514c89b608af051e244d2e9dbc630..395915e0dd5e9babdf5446e402bc375a21931f3c 100644 (file)
@@ -2,8 +2,16 @@
 \r
 #include "video_decoder.h"\r
 \r
-#include "../../../../common/exception/exceptions.h"\r
-               \r
+#include "../../../format/video_format.h"\r
+#include "../../../processor/draw_frame.h"\r
+#include "../../../processor/frame_processor_device.h"\r
+\r
+#include <common/utility/safe_ptr.h>\r
+\r
+#include <tbb/parallel_for.h>\r
+\r
+#include <algorithm>\r
+\r
 #if defined(_MSC_VER)\r
 #pragma warning (push)\r
 #pragma warning (disable : 4244)\r
@@ -12,20 +20,93 @@ extern "C"
 {\r
        #define __STDC_CONSTANT_MACROS\r
        #define __STDC_LIMIT_MACROS\r
+       #include <libswscale/swscale.h>\r
        #include <libavformat/avformat.h>\r
 }\r
 #if defined(_MSC_VER)\r
 #pragma warning (pop)\r
 #endif\r
 \r
-namespace caspar { namespace core { namespace ffmpeg{\r
+namespace caspar { namespace core { namespace ffmpeg {\r
+       \r
+pixel_format::type get_pixel_format(PixelFormat pix_fmt)\r
+{\r
+       switch(pix_fmt)\r
+       {\r
+               case PIX_FMT_BGRA:              return pixel_format::bgra;\r
+               case PIX_FMT_ARGB:              return pixel_format::argb;\r
+               case PIX_FMT_RGBA:              return pixel_format::rgba;\r
+               case PIX_FMT_ABGR:              return pixel_format::abgr;\r
+               case PIX_FMT_YUV444P:   return pixel_format::ycbcr;\r
+               case PIX_FMT_YUV422P:   return pixel_format::ycbcr;\r
+               case PIX_FMT_YUV420P:   return pixel_format::ycbcr;\r
+               case PIX_FMT_YUV411P:   return pixel_format::ycbcr;\r
+               case PIX_FMT_YUV410P:   return pixel_format::ycbcr;\r
+               case PIX_FMT_YUVA420P:  return pixel_format::ycbcra;\r
+               default:                                return pixel_format::invalid;\r
+       }\r
+}\r
+\r
+pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, size_t width, size_t height)\r
+{\r
+       // Get linesizes\r
+       AVPicture dummy_pict;   \r
+       avpicture_fill(&dummy_pict, nullptr, pix_fmt, width, height);\r
+\r
+       pixel_format_desc desc;\r
+       desc.pix_fmt = get_pixel_format(pix_fmt);\r
+               \r
+       switch(desc.pix_fmt)\r
+       {\r
+       case pixel_format::bgra:\r
+       case pixel_format::argb:\r
+       case pixel_format::rgba:\r
+       case pixel_format::abgr:\r
+               {\r
+                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[0]/4, height, 4));                                           \r
+                       return desc;\r
+               }\r
+       case pixel_format::ycbcr:\r
+       case pixel_format::ycbcra:\r
+               {               \r
+                       // Find chroma height\r
+                       size_t size2 = dummy_pict.data[2] - dummy_pict.data[1];\r
+                       size_t h2 = size2/dummy_pict.linesize[1];                       \r
+\r
+                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[0], height, 1));\r
+                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[1], h2, 1));\r
+                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[2], h2, 1));\r
+\r
+                       if(desc.pix_fmt == pixel_format::ycbcra)                                                \r
+                               desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[3], height, 1));     \r
+                       return desc;\r
+               }               \r
+       default:                \r
+               desc.pix_fmt = pixel_format::invalid;\r
+               return desc;\r
+       }\r
+}\r
 \r
 struct video_decoder::implementation : boost::noncopyable\r
 {\r
-       implementation(AVCodecContext* codec_context) : codec_context_(codec_context){}\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
-       safe_ptr<AVFrame> execute(const aligned_buffer& video_packet)\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(  operation_failed() <<\r
+                                                                               msg_info("Could not create software scaling context.") << \r
+                                                                               boost::errinfo_api_function("sws_getContext"));\r
+               }\r
+       }\r
+       \r
+       safe_ptr<write_frame> execute(const aligned_buffer& video_packet)\r
+       {                               \r
                safe_ptr<AVFrame> decoded_frame(avcodec_alloc_frame(), av_free);\r
 \r
                int frame_finished = 0;\r
@@ -34,12 +115,56 @@ struct video_decoder::implementation : boost::noncopyable
                if(result < 0)\r
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("avcodec_decode_video failed"));\r
 \r
-               return decoded_frame;           \r
+               if(sws_context_ == nullptr)\r
+               {\r
+                       auto write = frame_processor_->create_frame(desc_);\r
+\r
+                       tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
+                       {\r
+                               auto plane            = desc_.planes[n];\r
+                               auto result           = write->pixel_data(n).begin();\r
+                               auto decoded          = decoded_frame->data[n];\r
+                               auto decoded_linesize = decoded_frame->linesize[n];\r
+                               \r
+                               tbb::parallel_for(0, static_cast<int>(desc_.planes[n].height), 1, [&](int y)\r
+                               {\r
+                                       std::copy_n(decoded + y*decoded_linesize, plane.linesize, result + y*plane.linesize);\r
+                               });\r
+                       });\r
+\r
+                       return std::move(write);\r
+               }\r
+               else\r
+               {\r
+                       auto write = 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), write->pixel_data().begin(), 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
+                       \r
+                       return std::move(write);\r
+               }       \r
+       }\r
+\r
+       void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
+       {\r
+               frame_processor_ = frame_processor;\r
        }\r
        \r
+       std::shared_ptr<frame_processor_device> frame_processor_;\r
+       std::shared_ptr<SwsContext> sws_context_;\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_decoder::video_decoder(AVCodecContext* codec_context) : impl_(new implementation(codec_context)){}\r
-safe_ptr<AVFrame> video_decoder::execute(const aligned_buffer& video_packet){return impl_->execute(video_packet);}\r
+safe_ptr<write_frame> video_decoder::execute(const aligned_buffer& video_packet){return impl_->execute(video_packet);}\r
+void video_decoder::initialize(const safe_ptr<frame_processor_device>& frame_processor){impl_->initialize(frame_processor); }\r
 }}}
\ No newline at end of file
index 5da22c59413c97334d6e0a44663f8657fb78aac6..b2c9505eed0064d5bd532eb4fa2a147a085ef1c2 100644 (file)
@@ -1,16 +1,12 @@
 #pragma once\r
 \r
-#include <tbb/cache_aligned_allocator.h>\r
-\r
-#include <boost/noncopyable.hpp>\r
+#include "../../../processor/frame_processor_device.h"\r
 \r
 #include <memory>\r
-#include <vector>\r
 \r
 struct AVCodecContext;\r
-struct AVFrame;\r
 \r
-namespace caspar { namespace core { namespace ffmpeg{\r
+namespace caspar { namespace core { namespace ffmpeg {\r
        \r
 typedef std::vector<unsigned char, tbb::cache_aligned_allocator<unsigned char>> aligned_buffer;\r
 \r
@@ -18,13 +14,11 @@ class video_decoder : boost::noncopyable
 {\r
 public:\r
        video_decoder(AVCodecContext* codec_context);\r
-       safe_ptr<AVFrame> execute(const aligned_buffer& video_packet);\r
+       safe_ptr<write_frame> execute(const aligned_buffer& video_packet);      \r
+       void initialize(const safe_ptr<frame_processor_device>& frame_processor);\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<video_decoder> video_decoder_ptr;\r
-typedef std::unique_ptr<video_decoder> video_decoder_uptr;\r
 \r
-       }\r
-}}
\ No newline at end of file
+}}}
\ No newline at end of file
diff --git a/core/producer/ffmpeg/video/video_transformer.cpp b/core/producer/ffmpeg/video/video_transformer.cpp
deleted file mode 100644 (file)
index 39f490c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "../../../stdafx.h"\r
-\r
-#include "video_transformer.h"\r
-\r
-#include "../../../format/video_format.h"\r
-#include "../../../processor/draw_frame.h"\r
-#include "../../../processor/frame_processor_device.h"\r
-\r
-#include <tbb/parallel_for.h>\r
-\r
-#include <algorithm>\r
-\r
-#if defined(_MSC_VER)\r
-#pragma warning (push)\r
-#pragma warning (disable : 4244)\r
-#endif\r
-extern "C" \r
-{\r
-       #define __STDC_CONSTANT_MACROS\r
-       #define __STDC_LIMIT_MACROS\r
-       #include <libswscale/swscale.h>\r
-       #include <libavformat/avformat.h>\r
-}\r
-#if defined(_MSC_VER)\r
-#pragma warning (pop)\r
-#endif\r
-\r
-namespace caspar { namespace core { namespace ffmpeg {\r
-       \r
-pixel_format::type get_pixel_format(PixelFormat pix_fmt)\r
-{\r
-       switch(pix_fmt)\r
-       {\r
-               case PIX_FMT_BGRA:              return pixel_format::bgra;\r
-               case PIX_FMT_ARGB:              return pixel_format::argb;\r
-               case PIX_FMT_RGBA:              return pixel_format::rgba;\r
-               case PIX_FMT_ABGR:              return pixel_format::abgr;\r
-               case PIX_FMT_YUV444P:   return pixel_format::ycbcr;\r
-               case PIX_FMT_YUV422P:   return pixel_format::ycbcr;\r
-               case PIX_FMT_YUV420P:   return pixel_format::ycbcr;\r
-               case PIX_FMT_YUV411P:   return pixel_format::ycbcr;\r
-               case PIX_FMT_YUV410P:   return pixel_format::ycbcr;\r
-               case PIX_FMT_YUVA420P:  return pixel_format::ycbcra;\r
-               default:                                return pixel_format::invalid;\r
-       }\r
-}\r
-\r
-pixel_format_desc get_pixel_format_desc(PixelFormat pix_fmt, size_t width, size_t height)\r
-{\r
-       // Get linesizes\r
-       AVPicture dummy_pict;   \r
-       avpicture_fill(&dummy_pict, nullptr, pix_fmt, width, height);\r
-\r
-       pixel_format_desc desc;\r
-       desc.pix_fmt = get_pixel_format(pix_fmt);\r
-               \r
-       switch(desc.pix_fmt)\r
-       {\r
-       case pixel_format::bgra:\r
-       case pixel_format::argb:\r
-       case pixel_format::rgba:\r
-       case pixel_format::abgr:\r
-               {\r
-                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[0]/4, height, 4));                                           \r
-                       return desc;\r
-               }\r
-       case pixel_format::ycbcr:\r
-       case pixel_format::ycbcra:\r
-               {               \r
-                       // Find chroma height\r
-                       size_t size2 = dummy_pict.data[2] - dummy_pict.data[1];\r
-                       size_t h2 = size2/dummy_pict.linesize[1];                       \r
-\r
-                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[0], height, 1));\r
-                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[1], h2, 1));\r
-                       desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[2], h2, 1));\r
-\r
-                       if(desc.pix_fmt == pixel_format::ycbcra)                                                \r
-                               desc.planes.push_back(pixel_format_desc::plane(dummy_pict.linesize[3], height, 1));     \r
-                       return desc;\r
-               }               \r
-       default:                \r
-               desc.pix_fmt = pixel_format::invalid;\r
-               return desc;\r
-       }\r
-}\r
-\r
-struct video_transformer::implementation : boost::noncopyable\r
-{\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(  operation_failed() <<\r
-                                                                               msg_info("Could not create software scaling context.") << \r
-                                                                               boost::errinfo_api_function("sws_getContext"));\r
-               }\r
-       }\r
-       \r
-       safe_ptr<write_frame> execute(const safe_ptr<AVFrame>& decoded_frame)\r
-       {                                                               \r
-               if(sws_context_ == nullptr)\r
-               {\r
-                       auto write = frame_processor_->create_frame(desc_);\r
-\r
-                       tbb::parallel_for(0, static_cast<int>(desc_.planes.size()), 1, [&](int n)\r
-                       {\r
-                               auto plane            = desc_.planes[n];\r
-                               auto result           = write->pixel_data(n).begin();\r
-                               auto decoded          = decoded_frame->data[n];\r
-                               auto decoded_linesize = decoded_frame->linesize[n];\r
-                               \r
-                               tbb::parallel_for(0, static_cast<int>(desc_.planes[n].height), 1, [&](int y)\r
-                               {\r
-                                       std::copy_n(decoded + y*decoded_linesize, plane.linesize, result + y*plane.linesize);\r
-                               });\r
-                       });\r
-\r
-                       return std::move(write);\r
-               }\r
-               else\r
-               {\r
-                       auto write = 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), write->pixel_data().begin(), 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
-                       \r
-                       return std::move(write);\r
-               }       \r
-       }\r
-\r
-       void initialize(const safe_ptr<frame_processor_device>& frame_processor)\r
-       {\r
-               frame_processor_ = frame_processor;\r
-       }\r
-       \r
-       std::shared_ptr<frame_processor_device> frame_processor_;\r
-       std::shared_ptr<SwsContext> sws_context_;\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
-safe_ptr<write_frame> video_transformer::execute(const safe_ptr<AVFrame>& decoded_frame){return impl_->execute(decoded_frame);}\r
-void video_transformer::initialize(const safe_ptr<frame_processor_device>& frame_processor){impl_->initialize(frame_processor); }\r
-}}}
\ No newline at end of file
diff --git a/core/producer/ffmpeg/video/video_transformer.h b/core/producer/ffmpeg/video/video_transformer.h
deleted file mode 100644 (file)
index d7a020c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once\r
-\r
-#include "../../../processor/frame_processor_device.h"\r
-\r
-#include <memory>\r
-\r
-struct AVCodecContext;\r
-struct AVFrame;\r
-\r
-namespace caspar { namespace core { namespace ffmpeg{\r
-\r
-class video_transformer : boost::noncopyable\r
-{\r
-public:\r
-       video_transformer(AVCodecContext* codec_context);\r
-       safe_ptr<write_frame> execute(const safe_ptr<AVFrame>& video_packet);   \r
-       void initialize(const safe_ptr<frame_processor_device>& frame_processor);\r
-private:\r
-       struct implementation;\r
-       std::shared_ptr<implementation> impl_;\r
-};\r
-typedef std::shared_ptr<video_transformer> video_transformer_ptr;\r
-typedef std::unique_ptr<video_transformer> video_transformer_uptr;\r
-\r
-}}}
\ No newline at end of file
index 11f01d19546f3ec941e77149e18d73c62b7b0a43..4729cbdb9da931b601c53c3e36012c938377d9fc 100644 (file)
@@ -37,8 +37,6 @@ private:
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 };\r
-typedef std::shared_ptr<bitmap> bitmap_ptr;\r
-typedef std::unique_ptr<bitmap> bitmap_uptr;\r
 \r
 }}\r
 \r
index f85750c2a0fed9b1dc34f166c23b2e8864370433..76562353fdfbbf8a1ef1935b92f8e210f064be70 100644 (file)
@@ -5,6 +5,7 @@
 #endif\r
 \r
 #include "cg_producer.h"\r
+\r
 #include "flash_producer.h"\r
 \r
 #include "../../processor/draw_frame.h"\r
@@ -164,7 +165,7 @@ safe_ptr<cg_producer> get_default_cg_producer(const safe_ptr<channel>& channel,
        catch(std::bad_cast&)\r
        {\r
                auto producer = make_safe<cg_producer>();               \r
-               channel->load(render_layer, producer, load_option::auto_play); \r
+               channel->load(render_layer, producer, true); \r
                return producer;\r
        }\r
 }\r
index cc0a09896e8782d3349b6ae63b7d8e1c59481e0f..61890b83c7e768dffc69d574aa21919cdbeef6b1 100644 (file)
 \r
 #include "../frame_producer.h"\r
 \r
+#include <common/utility/safe_ptr.h>\r
+\r
+#include <string>\r
+\r
 namespace caspar { namespace core { namespace flash{\r
                \r
 safe_ptr<frame_producer> create_ct_producer(const std::vector<std::wstring>& params);\r
index b6fd862f464478c6898bbd164aae18346436b89a..9b49775e6922f8621f40eab2220f8ad6824ba75d 100644 (file)
 \r
 #include "../../format/video_format.h"\r
 #include "../../server.h"\r
-#include "../../../common/concurrency/executor.h"\r
-#include "../../../common/concurrency/concurrent_queue.h"\r
 \r
-#include "../../processor/draw_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 \r
+#include <common/concurrency/executor.h>\r
+#include <common/concurrency/concurrent_queue.h>\r
+\r
 #include <boost/filesystem.hpp>\r
 #include <boost/thread.hpp>\r
 \r
@@ -111,7 +111,7 @@ public:
                \r
        void render()\r
        {                \r
-               while(frame_buffer_.size() < 3)\r
+               while(frame_buffer_.size() < 3) // Keep pipeline filled.\r
                {\r
                        bool is_progressive = format_desc_.mode == video_mode::progressive || (ax_->GetFPS() - format_desc_.fps/2 == 0);\r
 \r
@@ -125,7 +125,8 @@ public:
 \r
        safe_ptr<draw_frame> render_frame()\r
        {\r
-               ax_->Tick();\r
+               if(!ax_->IsEmpty())\r
+                       ax_->Tick();\r
                \r
                if(ax_->IsReadyToRender() && ax_->InvalidRectangle())\r
                {\r
@@ -191,18 +192,21 @@ struct flash_producer::implementation
        safe_ptr<draw_frame> receive()\r
        {\r
                auto frame = renderer_ ? renderer_->receive() : draw_frame::empty();\r
-               executor_.begin_invoke([this]\r
+               if(executor_.size() < 4) // Avoid problems when in underrun.\r
                {\r
-                       try\r
-                       {\r
-                               renderer_->render();\r
-                       }\r
-                       catch(...)\r
+                       executor_.begin_invoke([this]\r
                        {\r
-                               CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               renderer_.reset();\r
-                       }\r
-               });\r
+                               try\r
+                               {\r
+                                       renderer_->render();\r
+                               }\r
+                               catch(...)\r
+                               {\r
+                                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                                       renderer_.reset();\r
+                               }\r
+                       });\r
+               }\r
                return frame;\r
        }\r
 \r
index 53ebe9fa46aa846cf0cfb37c5790dc21f975dadf..600f70d08bddc6d574a41f556af1abce091b065f 100644 (file)
 \r
 #include "../frame_producer.h"\r
 \r
-namespace caspar { namespace core {\r
+#include <memory>\r
 \r
-class Monitor;\r
-\r
-namespace flash {\r
-\r
-class FlashAxContainer;\r
+namespace caspar { namespace core { namespace flash {\r
 \r
 ///=================================================================================================\r
 /// <summary>  Flash Producer. </summary>\r
@@ -48,8 +44,6 @@ public:
        static std::wstring find_template(const std::wstring& templateName);\r
 \r
 private:       \r
-       friend class flash::FlashAxContainer;\r
-\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
 \r
index 0e16262c7ce0d7e41ee54835000371d6599f8998..9e36deedddbd8768b09d18d64e3c699b5ad04f81 100644 (file)
 \r
 #include "../processor/draw_frame.h"\r
 #include "../processor/frame_processor_device.h"\r
-#include "../../common/utility/safe_ptr.h"\r
+\r
+#include <common/utility/safe_ptr.h>\r
 \r
 #include <boost/noncopyable.hpp>\r
 \r
-#include <memory>\r
+#include <string>\r
+#include <ostream>\r
 \r
 namespace caspar { namespace core {\r
-       \r
+\r
 class frame_producer : boost::noncopyable\r
 {\r
 public:\r
@@ -52,7 +54,7 @@ public:
        ///\r
        /// \return     The following producer, or nullptr if there is no following producer. \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();}\r
+       virtual safe_ptr<frame_producer> get_following_producer() const {return frame_producer::empty();}  // nothrow\r
        \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual void :::set_leading_producer(const std::shared_ptr<frame_producer>& producer)\r
@@ -61,7 +63,7 @@ public:
        ///\r
        /// \param      producer        The leading producer.\r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
-       virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {}\r
+       virtual void set_leading_producer(const safe_ptr<frame_producer>& /*producer*/) {}  // nothrow\r
        \r
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        /// \fn virtual void :::initialize(const safe_ptr<frame_processor_device>& frame_processor) = 0;\r
@@ -72,7 +74,7 @@ public:
        ////////////////////////////////////////////////////////////////////////////////////////////////////\r
        virtual void initialize(const safe_ptr<frame_processor_device>& frame_processor) = 0;\r
 \r
-       static safe_ptr<frame_producer> empty()\r
+       static safe_ptr<frame_producer> empty()  // nothrow\r
        {\r
                struct empty_frame_producer : public frame_producer\r
                {\r
index 85f95e05d6cd6df08d9d861aec7d15affc109f39..dd266ee56242094a5290a1d5816c8074ca1d616e 100644 (file)
@@ -4,21 +4,16 @@
 \r
 #include "layer.h"\r
 \r
-#include "../format/video_format.h"\r
 #include "../processor/composite_frame.h"\r
 #include "../processor/draw_frame.h"\r
+#include "../processor/frame_processor_device.h"\r
 \r
-#include "../../common/utility/scope_exit.h"\r
-#include "../../common/concurrency/executor.h"\r
+#include <common/concurrency/executor.h>\r
 \r
 #include <boost/thread.hpp>\r
 #include <boost/range/algorithm_ext/erase.hpp>\r
-#include <boost/range/algorithm.hpp>\r
-#include <boost/foreach.hpp>\r
 \r
-#include <tbb/concurrent_vector.h>\r
 #include <tbb/parallel_for.h>\r
-#include <tbb/mutex.h>\r
        \r
 namespace caspar { namespace core {\r
        \r
@@ -52,16 +47,26 @@ struct frame_producer_device::implementation : boost::noncopyable
                executor_.begin_invoke([=]{tick();});\r
        }\r
 \r
-       void load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option)\r
+       void load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay)\r
        {\r
                producer->initialize(frame_processor_);\r
                executor_.begin_invoke([=]\r
                {\r
                        auto it = layers_.insert(std::make_pair(render_layer, layer(render_layer))).first;\r
-                       it->second.load(producer, option);\r
+                       it->second.load(producer, autoplay);\r
                });\r
        }\r
                        \r
+       void preview(int render_layer, const safe_ptr<frame_producer>& producer)\r
+       {\r
+               producer->initialize(frame_processor_);\r
+               executor_.begin_invoke([=]\r
+               {\r
+                       auto it = layers_.insert(std::make_pair(render_layer, layer(render_layer))).first;\r
+                       it->second.preview(producer);\r
+               });\r
+       }\r
+\r
        void pause(int render_layer)\r
        {               \r
                executor_.begin_invoke([=]\r
@@ -88,9 +93,11 @@ struct frame_producer_device::implementation : boost::noncopyable
                {\r
                        auto it = layers_.find(render_layer);\r
                        if(it != layers_.end())                 \r
+                       {\r
                                it->second.stop();      \r
-                       if(it->second.empty())\r
-                               layers_.erase(it);\r
+                               if(it->second.empty())\r
+                                       layers_.erase(it);\r
+                       }\r
                });\r
        }\r
 \r
@@ -142,7 +149,8 @@ struct frame_producer_device::implementation : boost::noncopyable
 \r
 frame_producer_device::frame_producer_device(frame_producer_device&& other) : impl_(std::move(other.impl_)){}\r
 frame_producer_device::frame_producer_device(const safe_ptr<frame_processor_device>& frame_processor) : impl_(new implementation(frame_processor)){}\r
-void frame_producer_device::load(int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option){impl_->load(render_layer, producer, option);}\r
+void frame_producer_device::load(int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay){impl_->load(render_layer, producer, autoplay);}\r
+void frame_producer_device::preview(int render_layer, const safe_ptr<frame_producer>& producer){impl_->preview(render_layer, producer);}\r
 void frame_producer_device::pause(int render_layer){impl_->pause(render_layer);}\r
 void frame_producer_device::play(int render_layer){impl_->play(render_layer);}\r
 void frame_producer_device::stop(int render_layer){impl_->stop(render_layer);}\r
index 5b50aa7a7d2bb3d159aa79d9a7b5c400a313a4ca..abf0db82d184423a80d083dc7188280d8d94f790 100644 (file)
@@ -1,32 +1,37 @@
 #pragma once\r
 \r
-#include "../processor/frame_processor_device.h"\r
-#include "../consumer/frame_consumer.h"\r
+#include "frame_producer.h"\r
+\r
 #include "../format/video_format.h"\r
 \r
-#include "layer.h"\r
+#include <common/utility/safe_ptr.h>\r
 \r
-#include <boost/thread.hpp>\r
+#include <boost/thread/future.hpp>\r
 \r
-#include <functional>\r
+#include <memory>\r
 \r
 namespace caspar { namespace core {\r
+\r
+class frame_producer;\r
+class frame_processor_device;\r
+class layer;\r
                \r
 class frame_producer_device : boost::noncopyable\r
 {      \r
 public:\r
-       frame_producer_device(frame_producer_device&& other);\r
-       frame_producer_device(const safe_ptr<frame_processor_device>& frame_processor);\r
+       frame_producer_device(frame_producer_device&& other);  // nothrow\r
+       frame_producer_device(const safe_ptr<frame_processor_device>& frame_processor);  // nothrow\r
        \r
-       void load       (int render_layer, const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);     \r
-       void pause      (int render_layer);\r
-       void play       (int render_layer);\r
-       void stop       (int render_layer);\r
-       void clear      (int render_layer);\r
-       void clear      ();\r
+       void load       (int render_layer, const safe_ptr<frame_producer>& producer, bool autoplay = false); // throws if producer->initialize throws\r
+       void preview(int render_layer, const safe_ptr<frame_producer>& producer); // throws if producer->initialize throws\r
+       void pause      (int render_layer);  // nothrow\r
+       void play       (int render_layer);  // nothrow\r
+       void stop       (int render_layer);  // nothrow\r
+       void clear      (int render_layer);  // nothrow\r
+       void clear      ();  // nothrow\r
        \r
-       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const;\r
-       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const;\r
+       boost::unique_future<safe_ptr<frame_producer>> foreground(int render_layer) const; // nothrow\r
+       boost::unique_future<safe_ptr<frame_producer>> background(int render_layer) const; // nothrow\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index b145b9b88096ad1bb363bc4ea2d878f03241c59a..547c6a1bfe94fc295d07d43429569281f1fa2035 100644 (file)
@@ -13,16 +13,28 @@ struct layer::implementation
 {              \r
        implementation(size_t index) : foreground_(frame_producer::empty()), background_(frame_producer::empty()), last_frame_(draw_frame::empty()), index_(index) {}\r
        \r
-       void load(const safe_ptr<frame_producer>& frame_producer, load_option::type option)\r
+       void load(const safe_ptr<frame_producer>& frame_producer, bool autoplay)\r
        {                       \r
                background_ = frame_producer;\r
-               if(option == load_option::preview)              \r
+               if(autoplay)\r
+                       play();                 \r
+       }\r
+\r
+       void preview(const safe_ptr<frame_producer>& frame_producer)\r
+       {\r
+               background_ = frame_producer;\r
+               foreground_ = frame_producer::empty();  \r
+               try\r
                {\r
-                       foreground_ = frame_producer::empty();  \r
                        last_frame_ = frame_producer->receive();\r
                }\r
-               else if(option == load_option::auto_play)\r
-                       play();                 \r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(warning) << L"layer[" << index_ << L"] Error. Removed " << foreground_->print() << L" from layer.";\r
+                       background_ = frame_producer::empty();\r
+                       last_frame_ = draw_frame::empty();\r
+               }\r
        }\r
        \r
        void play()\r
@@ -74,19 +86,15 @@ struct layer::implementation
                }\r
                catch(...)\r
                {\r
-                       try\r
-                       {\r
-                               CASPAR_LOG_CURRENT_EXCEPTION();\r
-                               CASPAR_LOG(warning) << L"layer[" << index_ << L"] Error. Removed " << foreground_->print() << L" from layer.";\r
-                               foreground_ = frame_producer::empty();\r
-                               last_frame_ = draw_frame::empty();\r
-                       }\r
-                       catch(...){}\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       CASPAR_LOG(warning) << L"layer[" << index_ << L"] Error. Removed " << foreground_->print() << L" from layer.";\r
+                       foreground_ = frame_producer::empty();\r
+                       last_frame_ = draw_frame::empty();\r
                }\r
 \r
                return last_frame_;\r
-       }       \r
-               \r
+       }\r
+                               \r
        tbb::atomic<bool>                       is_paused_;\r
        safe_ptr<draw_frame>            last_frame_;\r
        safe_ptr<frame_producer>        foreground_;\r
@@ -102,7 +110,8 @@ layer& layer::operator=(layer&& other)
        other.impl_ = nullptr;\r
        return *this;\r
 }\r
-void layer::load(const safe_ptr<frame_producer>& frame_producer, load_option::type option){return impl_->load(frame_producer, option);}        \r
+void layer::load(const safe_ptr<frame_producer>& frame_producer, bool autoplay){return impl_->load(frame_producer, autoplay);} \r
+void layer::preview(const safe_ptr<frame_producer>& frame_producer){return impl_->preview(frame_producer);}    \r
 void layer::play(){impl_->play();}\r
 void layer::pause(){impl_->pause();}\r
 void layer::stop(){impl_->stop();}\r
index 6a021a97440a61612da64cd4d6b1ef5663415e5d..888ce4dd345bab9f1d39cf8eaf1702175c4e71e1 100644 (file)
@@ -1,40 +1,32 @@
 #pragma once\r
 \r
-#include "../producer/frame_producer.h"\r
-\r
 #include <boost/noncopyable.hpp>\r
 \r
 namespace caspar { namespace core {\r
 \r
-struct load_option\r
-{\r
-       enum type\r
-       {\r
-               none,\r
-               preview,\r
-               auto_play\r
-       };\r
-};\r
+class frame_producer;\r
+class draw_frame;\r
 \r
 class layer : boost::noncopyable\r
 {\r
 public:\r
-       layer(size_t index = -1);\r
-       layer(layer&& other);\r
-       layer& operator=(layer&& other);\r
-\r
-       void load(const safe_ptr<frame_producer>& producer, load_option::type option = load_option::none);      \r
-       void play();\r
-       void pause();\r
-       void stop();\r
-       void clear();\r
-\r
-       bool empty() const;\r
+       layer(size_t index = -1); // nothrow\r
+       layer(layer&& other); // nothrow\r
+       layer& operator=(layer&& other); // nothrow\r
+       \r
+       void load(const safe_ptr<frame_producer>& producer, bool autoplay = false); // nothrow\r
+       void preview(const safe_ptr<frame_producer>& producer); // nothrow\r
+       void play(); // nothrow\r
+       void pause(); // nothrow\r
+       void stop(); // nothrow\r
+       void clear(); // nothrow\r
+\r
+       bool empty() const; // nothrow\r
                \r
-       safe_ptr<frame_producer> foreground() const;\r
-       safe_ptr<frame_producer> background() const;\r
+       safe_ptr<frame_producer> foreground() const; // nothrow\r
+       safe_ptr<frame_producer> background() const; // nothrow\r
 \r
-       safe_ptr<draw_frame> receive();\r
+       safe_ptr<draw_frame> receive(); // nothrow\r
 private:\r
        struct implementation;\r
        std::shared_ptr<implementation> impl_;\r
index 70385179cd8736c0a826fe03e21f276aad429cea..bdf15fd0619e731a5c0c32fb25a4ea34e24b30ce 100644 (file)
 #include "transition_producer.h"\r
 \r
 #include "../../format/video_format.h"\r
-#include "../../processor/draw_frame.h"\r
 #include "../../processor/composite_frame.h"\r
 #include "../../processor/transform_frame.h"\r
 #include "../../processor/frame_processor_device.h"\r
 \r
-#include "../../producer/frame_producer_device.h"\r
-\r
 #include <boost/range/algorithm/copy.hpp>\r
 \r
 namespace caspar { namespace core {    \r
index 38d23e9203a2fb162768510fa6e9b1cf291f805c..ca206bbed1ba6e96021d505284b67a382eb74b8a 100644 (file)
@@ -22,7 +22,7 @@
 #include "../frame_producer.h"\r
 \r
 #include <string>\r
-#include <vector>\r
+#include <memory>\r
 \r
 namespace caspar { namespace core {\r
 \r
index 219e02b0c974e7bd888f09a3e29f27d4ecb5c6f2..b0044268a6786fb064f412019d8561e06b2fe0b7 100644 (file)
@@ -168,9 +168,8 @@ bool LoadCommand::DoExecute()
        //Perform loading of the clip\r
        try\r
        {\r
-               auto pFP = load_media(_parameters);     \r
-               bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();               \r
-               GetChannel()->load(GetLayerIndex(), pFP, autoPlay ? load_option::auto_play : load_option::preview);\r
+               auto pFP = load_media(_parameters);             \r
+               GetChannel()->preview(GetLayerIndex(), pFP);\r
        \r
                CASPAR_LOG(info) << "Loaded " <<  _parameters[0] << TEXT(" successfully");\r
 \r
@@ -249,7 +248,7 @@ bool LoadbgCommand::DoExecute()
 \r
                pFP = safe_ptr<frame_producer>(transition_producer(pFP, transitionInfo));\r
                bool autoPlay = std::find(_parameters.begin(), _parameters.end(), TEXT("AUTOPLAY")) != _parameters.end();\r
-               GetChannel()->load(GetLayerIndex(), pFP, autoPlay ? load_option::auto_play : load_option::none); // TODO: LOOP\r
+               GetChannel()->load(GetLayerIndex(), pFP, autoPlay); // TODO: LOOP\r
        \r
                CASPAR_LOG(info) << "Loaded " << _parameters[0] << TEXT(" successfully to background");\r
                SetReplyString(TEXT("202 LOADBG OK\r\n"));\r
index 81d714792b6ad92b7f6159adb8f799ccc6f96395..b59e9b29f3f8f6ef60dc5d85305cb4179fdd0c44 100644 (file)
 \r
 #include "../../channel.h"\r
 \r
-#include "../../../common/io/ProtocolStrategy.h"\r
+#include <common/io/ProtocolStrategy.h>\r
 #include "CIICommand.h"\r
 \r
 #include "../../consumer/frame_consumer.h"\r
 #include "../../producer/frame_producer_device.h"\r
 \r
-#include "../../../common/concurrency/executor.h"\r
+#include <common/concurrency/executor.h>\r
 \r
 namespace caspar { namespace core { namespace cii {\r
 \r