]> 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, 23 Oct 2011 18:23:20 +0000 (18:23 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 23 Oct 2011 18:23:20 +0000 (18:23 +0000)
modules/ffmpeg/ffmpeg.vcxproj
modules/ffmpeg/ffmpeg.vcxproj.filters
modules/ffmpeg/producer/audio/audio_decoder.cpp
modules/ffmpeg/producer/display_mode.h [new file with mode: 0644]
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/frame_muxer.cpp
modules/ffmpeg/producer/video/video_decoder.cpp

index 31cf449500b8992e63cd09a864dc5b3f6142bba9..bbd1d4e6ebf56df3059545fd6703474edae6424f 100644 (file)
     <ClInclude Include="ffmpeg_error.h" />\r
     <ClInclude Include="producer\audio\audio_decoder.h" />\r
     <ClInclude Include="producer\audio\audio_resampler.h" />\r
+    <ClInclude Include="producer\display_mode.h" />\r
     <ClInclude Include="producer\ffmpeg_producer.h" />\r
     <ClInclude Include="producer\filter\filter.h" />\r
     <ClInclude Include="producer\filter\parallel_yadif.h" />\r
index 57a965fbbca8213f513268764249afd885779f4d..b3963a5e780735ca78c7688906ef549d3c021f8f 100644 (file)
@@ -94,5 +94,8 @@
     <ClInclude Include="producer\input.h">\r
       <Filter>source\producer</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="producer\display_mode.h">\r
+      <Filter>source\producer</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 8932b6531038a104ff7ef05fbf4ea8b0988872d1..784de026d6bc77566a2804d0de4d62caad9819d9 100644 (file)
@@ -87,7 +87,6 @@ public:
        {\r
                send(is_running_, false);\r
                semaphore_->release();\r
-               semaphore_->release();\r
                agent::wait(this);\r
        }\r
 \r
diff --git a/modules/ffmpeg/producer/display_mode.h b/modules/ffmpeg/producer/display_mode.h
new file mode 100644 (file)
index 0000000..e69fe91
--- /dev/null
@@ -0,0 +1,89 @@
+#pragma once\r
+\r
+#include <core/video_format.h>\r
+\r
+namespace caspar { namespace ffmpeg {\r
+       \r
+struct display_mode\r
+{\r
+       enum type\r
+       {\r
+               simple,\r
+               duplicate,\r
+               half,\r
+               interlace,\r
+               deinterlace_bob,\r
+               deinterlace_bob_reinterlace,\r
+               deinterlace,\r
+               count,\r
+               invalid\r
+       };\r
+\r
+       static std::wstring print(display_mode::type value)\r
+       {\r
+               switch(value)\r
+               {\r
+                       case simple:                                            return L"simple";\r
+                       case duplicate:                                         return L"duplicate";\r
+                       case half:                                                      return L"half";\r
+                       case interlace:                                         return L"interlace";\r
+                       case deinterlace_bob:                           return L"deinterlace_bob";\r
+                       case deinterlace_bob_reinterlace:       return L"deinterlace_bob_reinterlace";\r
+                       case deinterlace:                                       return L"deinterlace";\r
+                       default:                                                        return L"invalid";\r
+               }\r
+       }\r
+};\r
+\r
+display_mode::type get_display_mode(const core::field_mode::type in_mode, double in_fps, const core::field_mode::type out_mode, double out_fps)\r
+{              \r
+       static const auto epsilon = 2.0;\r
+\r
+       if(in_fps < 20.0 || in_fps > 80.0)\r
+       {\r
+               //if(out_mode != core::field_mode::progressive && in_mode == core::field_mode::progressive)\r
+               //      return display_mode::interlace;\r
+               \r
+               if(out_mode == core::field_mode::progressive && in_mode != core::field_mode::progressive)\r
+               {\r
+                       if(in_fps < 35.0)\r
+                               return display_mode::deinterlace;\r
+                       else\r
+                               return display_mode::deinterlace_bob;\r
+               }\r
+       }\r
+\r
+       if(std::abs(in_fps - out_fps) < epsilon)\r
+       {\r
+               if(in_mode != core::field_mode::progressive && out_mode == core::field_mode::progressive)\r
+                       return display_mode::deinterlace;\r
+               //else if(in_mode == core::field_mode::progressive && out_mode != core::field_mode::progressive)\r
+               //      simple(); // interlace_duplicate();\r
+               else\r
+                       return display_mode::simple;\r
+       }\r
+       else if(std::abs(in_fps/2.0 - out_fps) < epsilon)\r
+       {\r
+               if(in_mode != core::field_mode::progressive)\r
+                       return display_mode::invalid;\r
+\r
+               if(out_mode != core::field_mode::progressive)\r
+                       return display_mode::interlace;\r
+               else\r
+                       return display_mode::half;\r
+       }\r
+       else if(std::abs(in_fps - out_fps/2.0) < epsilon)\r
+       {\r
+               if(out_mode != core::field_mode::progressive)\r
+                       return display_mode::invalid;\r
+\r
+               if(in_mode != core::field_mode::progressive)\r
+                       return display_mode::deinterlace_bob;\r
+               else\r
+                       return display_mode::duplicate;\r
+       }\r
+\r
+       return display_mode::invalid;\r
+}\r
+\r
+}}
\ No newline at end of file
index c7e77cac183028ace8284b080c63551793325748..d6703bf8129dffaa9f6e53de3073ff88eefd458d 100644 (file)
@@ -62,10 +62,10 @@ struct ffmpeg_producer : public core::frame_producer
        const bool                                                                              loop_;\r
        const size_t                                                                    length_;\r
        \r
-       call<safe_ptr<AVPacket>>                                                throw_away_;\r
        unbounded_buffer<safe_ptr<AVPacket>>                    packets_;\r
        unbounded_buffer<safe_ptr<AVFrame>>                             video_;\r
        unbounded_buffer<safe_ptr<core::audio_buffer>>  audio_;\r
+       call<safe_ptr<AVPacket>>                                                throw_away_;\r
        bounded_buffer<safe_ptr<core::basic_frame>>             frames_;\r
                \r
        const safe_ptr<diagnostics::graph>                              graph_;\r
index 5380767d2af7de440d1492c8fb3509bc492fc04d..f7b80e902204cc3182415804b3a33b22f1d2692a 100644 (file)
@@ -5,6 +5,7 @@
 #include "filter/filter.h"\r
 \r
 #include "util.h"\r
+#include "display_mode.h"\r
 \r
 #include <core/producer/frame_producer.h>\r
 #include <core/producer/frame/basic_frame.h>\r
@@ -30,105 +31,19 @@ extern "C"
 #pragma warning (pop)\r
 #endif\r
 \r
-#include <boost/foreach.hpp>\r
-\r
-#include <agents_extras.h>\r
-\r
-using namespace caspar::core;\r
+#include <agents.h>\r
 \r
 using namespace Concurrency;\r
 \r
 namespace caspar { namespace ffmpeg {\r
-\r
-struct display_mode\r
-{\r
-       enum type\r
-       {\r
-               simple,\r
-               duplicate,\r
-               half,\r
-               interlace,\r
-               deinterlace_bob,\r
-               deinterlace_bob_reinterlace,\r
-               deinterlace,\r
-               count,\r
-               invalid\r
-       };\r
-\r
-       static std::wstring print(display_mode::type value)\r
-       {\r
-               switch(value)\r
-               {\r
-                       case simple:                                            return L"simple";\r
-                       case duplicate:                                         return L"duplicate";\r
-                       case half:                                                      return L"half";\r
-                       case interlace:                                         return L"interlace";\r
-                       case deinterlace_bob:                           return L"deinterlace_bob";\r
-                       case deinterlace_bob_reinterlace:       return L"deinterlace_bob_reinterlace";\r
-                       case deinterlace:                                       return L"deinterlace";\r
-                       default:                                                        return L"invalid";\r
-               }\r
-       }\r
-};\r
-\r
-display_mode::type get_display_mode(const core::field_mode::type in_mode, double in_fps, const core::field_mode::type out_mode, double out_fps)\r
-{              \r
-       static const auto epsilon = 2.0;\r
-\r
-       if(in_fps < 20.0 || in_fps > 80.0)\r
-       {\r
-               //if(out_mode != core::field_mode::progressive && in_mode == core::field_mode::progressive)\r
-               //      return display_mode::interlace;\r
-               \r
-               if(out_mode == core::field_mode::progressive && in_mode != core::field_mode::progressive)\r
-               {\r
-                       if(in_fps < 35.0)\r
-                               return display_mode::deinterlace;\r
-                       else\r
-                               return display_mode::deinterlace_bob;\r
-               }\r
-       }\r
-\r
-       if(std::abs(in_fps - out_fps) < epsilon)\r
-       {\r
-               if(in_mode != core::field_mode::progressive && out_mode == core::field_mode::progressive)\r
-                       return display_mode::deinterlace;\r
-               //else if(in_mode == core::field_mode::progressive && out_mode != core::field_mode::progressive)\r
-               //      simple(); // interlace_duplicate();\r
-               else\r
-                       return display_mode::simple;\r
-       }\r
-       else if(std::abs(in_fps/2.0 - out_fps) < epsilon)\r
-       {\r
-               if(in_mode != core::field_mode::progressive)\r
-                       return display_mode::invalid;\r
-\r
-               if(out_mode != core::field_mode::progressive)\r
-                       return display_mode::interlace;\r
-               else\r
-                       return display_mode::half;\r
-       }\r
-       else if(std::abs(in_fps - out_fps/2.0) < epsilon)\r
-       {\r
-               if(out_mode != core::field_mode::progressive)\r
-                       return display_mode::invalid;\r
-\r
-               if(in_mode != core::field_mode::progressive)\r
-                       return display_mode::deinterlace_bob;\r
-               else\r
-                       return display_mode::duplicate;\r
-       }\r
-\r
-       return display_mode::invalid;\r
-}\r
-\r
+       \r
 struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopyable\r
 {              \r
        ITarget<safe_ptr<core::basic_frame>>&                   target_;\r
        mutable single_assignment<display_mode::type>   display_mode_;\r
        const double                                                                    in_fps_;\r
-       const video_format_desc                                                 format_desc_;\r
-       bool                                                                                    auto_transcode_;\r
+       const core::video_format_desc                                   format_desc_;\r
+       const bool                                                                              auto_transcode_;\r
        \r
        mutable single_assignment<safe_ptr<filter>>             filter_;\r
        const safe_ptr<core::frame_factory>                             frame_factory_;\r
@@ -141,7 +56,7 @@ struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopya
        \r
        core::audio_buffer                                                              audio_data_;\r
 \r
-       Concurrency::overwrite_buffer<bool>                             is_running_;\r
+       overwrite_buffer<bool>                                                  is_running_;\r
 \r
        std::wstring                                                                    filter_str_;\r
        \r
@@ -178,8 +93,11 @@ struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopya
                auto video = receive(video_);\r
 \r
                if(!is_running_.value() || video == eof_video())\r
+               {       \r
+                       send(is_running_ , false);\r
                        return nullptr;\r
-                               \r
+               }\r
+\r
                CASPAR_ASSERT(video != loop_video());\r
 \r
                try\r
@@ -202,8 +120,11 @@ struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopya
                auto audio = receive(audio_);\r
 \r
                if(!is_running_.value() || audio == eof_audio())\r
+               {\r
+                       send(is_running_ , false);\r
                        return nullptr;\r
-               \r
+               }\r
+\r
                CASPAR_ASSERT(audio != loop_audio());\r
 \r
                try\r
@@ -232,69 +153,54 @@ struct frame_muxer2::implementation : public Concurrency::agent, boost::noncopya
                                auto video = receive_video();\r
 \r
                                if(!audio)\r
-                               {\r
-                                       send(is_running_ , false);\r
                                        break;\r
-                               }\r
 \r
                                if(!video)\r
-                               {\r
-                                       send(is_running_ , false);\r
                                        break;\r
-                               }\r
 \r
                                video->audio_data() = std::move(*audio);\r
 \r
-                               auto frame = safe_ptr<core::basic_frame>(video);\r
-\r
                                switch(display_mode_.value())\r
                                {\r
                                case display_mode::simple:                      \r
                                case display_mode::deinterlace:\r
                                case display_mode::deinterlace_bob:\r
                                        {\r
-                                               send(target_, frame);\r
+                                               send(target_, safe_ptr<core::basic_frame>(std::move(video)));\r
 \r
                                                break;\r
                                        }\r
                                case display_mode::duplicate:                                   \r
                                        {                                                                               \r
-                                               send(target_, frame);\r
+                                               send(target_, safe_ptr<core::basic_frame>(video));\r
 \r
                                                auto audio2 = receive_audio();\r
                                                if(audio2)\r
                                                {\r
                                                        auto video2 = make_safe<core::write_frame>(*video);\r
                                                        video2->audio_data() = std::move(*audio2);\r
-                                                       auto frame2 = safe_ptr<core::basic_frame>(video2);\r
-                                                       send(target_, frame2);\r
+                                                       send(target_, safe_ptr<core::basic_frame>(video2));\r
                                                }\r
-                                               else\r
-                                                       send(is_running_, false);\r
 \r
                                                break;\r
                                        }\r
                                case display_mode::half:                                                \r
                                        {                                                               \r
-                                               send(target_, frame);\r
-\r
-                                               if(!receive_video()) // throw away      \r
-                                                       send(is_running_ , false);\r
-\r
+                                               send(target_, safe_ptr<core::basic_frame>(std::move(video)));\r
+                                               receive_video();\r
                                                break;\r
                                        }\r
                                case display_mode::deinterlace_bob_reinterlace:\r
                                case display_mode::interlace:                                   \r
                                        {                                       \r
+                                               auto frame = safe_ptr<core::basic_frame>(std::move(video));\r
                                                auto video2 = receive_video();\r
                                                auto frame2 = core::basic_frame::empty();\r
 \r
                                                if(video2)                                              \r
-                                                       frame2 = safe_ptr<core::basic_frame>(video2);                                           \r
-                                               else\r
-                                                       send(is_running_, false);                                               \r
+                                                       frame2 = safe_ptr<core::basic_frame>(video2);                                                           \r
                                                \r
-                                               frame = core::basic_frame::interlace(frame, frame2, format_desc_.field_mode);   \r
+                                               frame = core::basic_frame::interlace(std::move(frame), std::move(frame2), format_desc_.field_mode);     \r
                                                send(target_, frame);\r
 \r
                                                break;\r
index 6ec916945a25b5af3430cfd59a983c2ee6b6d2b1..ee78b3f18abd48e72d0671213e169496acb847af 100644 (file)
@@ -76,7 +76,7 @@ public:
                , is_progressive_(true)\r
                , source_([this](const safe_ptr<AVPacket>& packet){return packet->stream_index == index_;})\r
                , target_(target)\r
-               , semaphore_(make_safe<Concurrency::semaphore>(1))\r
+               , semaphore_(make_safe<Concurrency::semaphore>(1)) // IMPORTANT: Must be 1 since avcodec_decode_video2 reuses frame memory.\r
        {               \r
                CASPAR_LOG(debug) << "[video_decoder] " << context.streams[index_]->codec->codec->long_name;\r
                \r
@@ -134,7 +134,7 @@ public:
                                is_progressive_ = decoded_frame->interlaced_frame == 0;\r
                                \r
                                send(target_, make_safe_ptr(decoded_frame));\r
-                               Concurrency::wait(10);\r
+                               Concurrency::wait(2);\r
                        }\r
                }\r
                catch(...)\r