]> 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, 4 Dec 2011 09:56:34 +0000 (09:56 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 4 Dec 2011 09:56:34 +0000 (09:56 +0000)
modules/decklink/producer/decklink_producer.cpp
modules/ffmpeg/producer/filter/filter.h
modules/ffmpeg/producer/muxer/display_mode.h
modules/ffmpeg/producer/muxer/frame_muxer.cpp
modules/ffmpeg/producer/muxer/frame_muxer.h

index 1aa27f80b99d524e5fa3529164a006f4499afe2d..e0812e3272402aca56b474a992bb4799c4de8bf7 100644 (file)
@@ -29,6 +29,7 @@
 #include "../../ffmpeg/producer/filter/filter.h"\r
 #include "../../ffmpeg/producer/util/util.h"\r
 #include "../../ffmpeg/producer/muxer/frame_muxer.h"\r
+#include "../../ffmpeg/producer/muxer/display_mode.h"\r
 \r
 #include <common/log/log.h>\r
 #include <common/diagnostics/graph.h>\r
@@ -106,7 +107,7 @@ public:
                , device_index_(device_index)\r
                , frame_factory_(frame_factory)\r
                , audio_cadence_(frame_factory->get_video_format_desc().audio_cadence)\r
-               , muxer_(format_desc.fps, frame_factory, filter)\r
+               , muxer_(format_desc.fps, frame_factory, filter, ffmpeg::display_mode::deinterlace)\r
        {\r
                frame_buffer_.set_capacity(2);\r
                \r
index 88548a087bd02f7d99bd51993b17a3e04bbd6a55..f1989201b729803c4dac927065b4c16572076046 100644 (file)
@@ -33,32 +33,6 @@ struct AVFrame;
 enum PixelFormat;\r
 \r
 namespace caspar { namespace ffmpeg {\r
-               \r
-static bool is_double_rate(const std::wstring& filters)\r
-{\r
-       if(boost::to_upper_copy(filters).find(L"YADIF=1") != std::string::npos)\r
-               return true;\r
-       \r
-       if(boost::to_upper_copy(filters).find(L"YADIF=3") != std::string::npos)\r
-               return true;\r
-\r
-       return false;\r
-}\r
-\r
-static bool is_deinterlacing(const std::wstring& filters)\r
-{\r
-       if(boost::to_upper_copy(filters).find(L"YADIF") != std::string::npos)\r
-               return true;    \r
-       return false;\r
-}      \r
-       \r
-static int filter_delay(const std::wstring& filters)\r
-{\r
-       if(is_double_rate(filters))\r
-               return 1;\r
-       \r
-       return 0;\r
-}\r
 \r
 static std::wstring append_filter(const std::wstring& filters, const std::wstring& filter)\r
 {\r
@@ -77,7 +51,44 @@ public:
        std::vector<safe_ptr<AVFrame>> poll_all();\r
 \r
        std::wstring filter_str() const;\r
+                       \r
+       static bool is_double_rate(const std::wstring& filters)\r
+       {\r
+               if(boost::to_upper_copy(filters).find(L"YADIF=1") != std::string::npos)\r
+                       return true;\r
+       \r
+               if(boost::to_upper_copy(filters).find(L"YADIF=3") != std::string::npos)\r
+                       return true;\r
+\r
+               return false;\r
+       }\r
+\r
+       static bool is_deinterlacing(const std::wstring& filters)\r
+       {\r
+               if(boost::to_upper_copy(filters).find(L"YADIF") != std::string::npos)\r
+                       return true;    \r
+               return false;\r
+       }       \r
+       \r
+       static int delay(const std::wstring& filters)\r
+       {\r
+               return is_double_rate(filters) ? 1 : 1;\r
+       }\r
+\r
+       int delay() const\r
+       {\r
+               return delay(filter_str());\r
+       }\r
+\r
+       bool is_double_rate() const\r
+       {\r
+               return is_double_rate(filter_str());\r
+       }\r
        \r
+       bool is_deinterlacing() const\r
+       {\r
+               return is_deinterlacing(filter_str());\r
+       }\r
 private:\r
        struct implementation;\r
        safe_ptr<implementation> impl_;\r
index d650f2f14e8f3ce9847159cab988e8230977155c..201074d81b325c0d645e20eea0aa93f8ebb96d6e 100644 (file)
@@ -56,7 +56,7 @@ struct display_mode
        }\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
+static 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
index 3faa47f833039b60ef52266f5c7f720eabe63290..66c8be37905169c3b395a2c7fbb2b0ea0823ecc2 100644 (file)
@@ -23,8 +23,6 @@
 \r
 #include "frame_muxer.h"\r
 \r
-#include "display_mode.h"\r
-\r
 #include "../filter/filter.h"\r
 #include "../util/util.h"\r
 \r
@@ -84,8 +82,9 @@ struct frame_muxer::implementation : boost::noncopyable
        filter                                                                                  filter_;\r
        const std::wstring                                                              filter_str_;\r
        bool                                                                                    force_deinterlacing_;\r
+       display_mode::type                                                              force_deinterlacing_mode_;\r
                \r
-       implementation(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter_str)\r
+       implementation(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter_str, display_mode::type force_deinterlacing_mode)\r
                : display_mode_(display_mode::invalid)\r
                , in_fps_(in_fps)\r
                , format_desc_(frame_factory->get_video_format_desc())\r
@@ -95,6 +94,7 @@ struct frame_muxer::implementation : boost::noncopyable
                , frame_factory_(frame_factory)\r
                , filter_str_(filter_str)\r
                , force_deinterlacing_(false)\r
+               , force_deinterlacing_mode_(force_deinterlacing_mode)\r
        {\r
                video_streams_.push(std::queue<safe_ptr<write_frame>>());\r
                audio_streams_.push(core::audio_buffer());\r
@@ -227,36 +227,34 @@ struct frame_muxer::implementation : boost::noncopyable
                case display_mode::simple:                                              \r
                case display_mode::deinterlace_bob:                             \r
                case display_mode::deinterlace: \r
-               {\r
-                       frame_buffer_.push(frame1);\r
-                       break;\r
-               }\r
+                       {\r
+                               frame_buffer_.push(frame1);\r
+                               break;\r
+                       }\r
                case display_mode::interlace:                                   \r
                case display_mode::deinterlace_bob_reinterlace: \r
-               {                               \r
-                       auto frame2 = pop_video();\r
+                       {                               \r
+                               auto frame2 = pop_video();\r
 \r
-                       frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, format_desc_.field_mode));      \r
-                       break;\r
-               }\r
+                               frame_buffer_.push(core::basic_frame::interlace(frame1, frame2, format_desc_.field_mode));      \r
+                               break;\r
+                       }\r
                case display_mode::duplicate:   \r
-               {\r
-                       auto frame2                             = make_safe<core::write_frame>(*frame1);\r
-                       frame2->audio_data()    = pop_audio();\r
+                       {\r
+                               auto frame2                             = make_safe<core::write_frame>(*frame1);\r
+                               frame2->audio_data()    = pop_audio();\r
 \r
-                       frame_buffer_.push(frame1);\r
-                       frame_buffer_.push(frame2);\r
-                       break;\r
-               }\r
+                               frame_buffer_.push(frame1);\r
+                               frame_buffer_.push(frame2);\r
+                               break;\r
+                       }\r
                case display_mode::half:        \r
-               {                               \r
-                       pop_video(); // Throw away\r
+                       {                               \r
+                               pop_video(); // Throw away\r
 \r
-                       frame_buffer_.push(frame1);\r
-                       break;\r
-               }\r
-               default:                                                                                \r
-                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("invalid display-mode"));\r
+                               frame_buffer_.push(frame1);\r
+                               break;\r
+                       }\r
                }\r
                \r
                return frame_buffer_.empty() ? nullptr : poll();\r
@@ -294,22 +292,28 @@ struct frame_muxer::implementation : boost::noncopyable
                        auto mode = get_mode(*frame);\r
                        auto fps  = in_fps_;\r
 \r
-                       if(is_deinterlacing(filter_str_))\r
+                       if(filter::is_deinterlacing(filter_str_))\r
                                mode = core::field_mode::progressive;\r
 \r
-                       if(is_double_rate(filter_str_))\r
+                       if(filter::is_double_rate(filter_str_))\r
                                fps *= 2;\r
                        \r
                        display_mode_ = get_display_mode(mode, fps, format_desc_.field_mode, format_desc_.fps);\r
                        \r
-                       if(force_deinterlacing_ || \r
-                               ((frame->height != 480 || format_desc_.height != 486) && \r
+                       if((frame->height != 480 || format_desc_.height != 486) && // don't deinterlace for NTSC DV\r
                                        display_mode_ == display_mode::simple && mode != core::field_mode::progressive && format_desc_.field_mode != core::field_mode::progressive && \r
-                                       frame->height != static_cast<int>(format_desc_.height)))\r
+                                       frame->height != static_cast<int>(format_desc_.height))\r
                        {\r
                                display_mode_ = display_mode::deinterlace_bob_reinterlace; // The frame will most likely be scaled, we need to deinterlace->reinterlace \r
                        }\r
 \r
+                       if(force_deinterlacing_ && mode != core::field_mode::progressive && display_mode_ != display_mode::deinterlace && display_mode_ != display_mode::deinterlace_bob)                       \r
+                       {       \r
+                               if(force_deinterlacing_mode_ == display_mode::deinterlace)\r
+                                       CASPAR_LOG(warning) << L"[frame_muxer] Forcing non bob deinterlacing.";\r
+                               display_mode_ = force_deinterlacing_mode_;\r
+                       }\r
+\r
                        if(display_mode_ == display_mode::deinterlace)\r
                                filter_str = append_filter(filter_str, L"YADIF=0:-1");\r
                        else if(display_mode_ == display_mode::deinterlace_bob || display_mode_ == display_mode::deinterlace_bob_reinterlace)\r
@@ -324,7 +328,7 @@ struct frame_muxer::implementation : boost::noncopyable
                        \r
                if(!boost::iequals(filter_.filter_str(), filter_str))\r
                {\r
-                       for(int n = 0; n < filter_delay(filter_.filter_str()); ++n)\r
+                       for(int n = 0; n < filter_.delay(); ++n)\r
                        {\r
                                filter_.push(frame);\r
                                auto av_frame = filter_.poll();\r
@@ -359,15 +363,15 @@ struct frame_muxer::implementation : boost::noncopyable
                        break;\r
                }\r
 \r
-               if(is_double_rate(widen(filter_.filter_str()))) // Take into account transformations in filter.\r
+               if(filter_.is_double_rate()) // Take into account transformations in filter.\r
                        nb_frames *= 2;\r
 \r
                return nb_frames;\r
        }\r
 };\r
 \r
-frame_muxer::frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter)\r
-       : impl_(new implementation(in_fps, frame_factory, filter)){}\r
+frame_muxer::frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter, display_mode::type force_deinterlacing_mode)\r
+       : impl_(new implementation(in_fps, frame_factory, filter, force_deinterlacing_mode)){}\r
 void frame_muxer::push(const std::shared_ptr<AVFrame>& video_frame, int hints){impl_->push(video_frame, hints);}\r
 void frame_muxer::push(const std::shared_ptr<core::audio_buffer>& audio_samples){return impl_->push(audio_samples);}\r
 std::shared_ptr<basic_frame> frame_muxer::poll(){return impl_->poll();}\r
index 10e6d9c12952ed663e20ace250abad0960a15cb3..02ccb9d7f068bd82762c3107329433814c468197 100644 (file)
@@ -21,6 +21,8 @@
 \r
 #pragma once\r
 \r
+#include "display_mode.h"\r
+\r
 #include <common/memory/safe_ptr.h>\r
 \r
 #include <core/mixer/audio/audio_mixer.h>\r
@@ -46,7 +48,7 @@ namespace ffmpeg {
 class frame_muxer : boost::noncopyable\r
 {\r
 public:\r
-       frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter = L"");\r
+       frame_muxer(double in_fps, const safe_ptr<core::frame_factory>& frame_factory, const std::wstring& filter = L"", display_mode::type force_deinterlace_mode = display_mode::deinterlace_bob_reinterlace);\r
        \r
        void push(const std::shared_ptr<AVFrame>& video_frame, int hints = 0);\r
        void push(const std::shared_ptr<core::audio_buffer>& audio_samples);\r