]> git.sesse.net Git - casparcg/commitdiff
2.0. core: Simplified layer and frame_producer logic.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 24 Aug 2011 14:18:44 +0000 (14:18 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Wed, 24 Aug 2011 14:18:44 +0000 (14:18 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1274 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/producer/frame_producer.cpp
core/producer/layer.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp

index da08185ac5ef7e66d22c0db298098c6f153a2410..f881d2adbb6d36353912b8cfb8b56b3c12e23335 100644 (file)
@@ -34,16 +34,36 @@ namespace caspar { namespace core {
        \r
 std::vector<const producer_factory_t> g_factories;\r
 \r
-const safe_ptr<frame_producer>& frame_producer::empty() // nothrow\r
+class last_frame_producer : public frame_producer\r
 {\r
-       struct empty_frame_producer : public frame_producer\r
+       const std::wstring                      print_;\r
+       const safe_ptr<basic_frame>     frame_;\r
+       const int64_t                           nb_frames_;\r
+public:\r
+       last_frame_producer(const safe_ptr<frame_producer>& producer) \r
+               : print_(producer->print())\r
+               , frame_(producer->last_frame() != basic_frame::eof() ? producer->last_frame() : basic_frame::empty())\r
+               , nb_frames_(producer->nb_frames())\r
        {\r
-               virtual safe_ptr<basic_frame> receive(int){return basic_frame::empty();}\r
-               virtual safe_ptr<basic_frame> last_frame() const{return basic_frame::empty();}\r
-               virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
-               virtual int64_t nb_frames() const {return 0;}\r
-               virtual std::wstring print() const { return L"empty";}\r
-       };\r
+       }\r
+       \r
+       virtual safe_ptr<basic_frame> receive(int){return frame_;}\r
+       virtual safe_ptr<core::basic_frame> last_frame() const{return frame_;}\r
+       virtual std::wstring print() const{return L"dummy[" + print_ + L"]";}\r
+       virtual int64_t nb_frames() const {return nb_frames_;}  \r
+};\r
+\r
+struct empty_frame_producer : public frame_producer\r
+{\r
+       virtual safe_ptr<basic_frame> receive(int){return basic_frame::empty();}\r
+       virtual safe_ptr<basic_frame> last_frame() const{return basic_frame::empty();}\r
+       virtual void set_frame_factory(const safe_ptr<frame_factory>&){}\r
+       virtual int64_t nb_frames() const {return 0;}\r
+       virtual std::wstring print() const { return L"empty";}\r
+};\r
+\r
+const safe_ptr<frame_producer>& frame_producer::empty() // nothrow\r
+{\r
        static safe_ptr<frame_producer> producer = make_safe<empty_frame_producer>();\r
        return producer;\r
 }      \r
@@ -55,11 +75,13 @@ safe_ptr<basic_frame> receive_and_follow(safe_ptr<frame_producer>& producer, int
        {\r
                CASPAR_LOG(info) << producer->print() << " End Of File.";\r
                auto following = producer->get_following_producer();\r
-               following->set_leading_producer(producer);\r
-               producer = std::move(following);                \r
-                               \r
-               if(producer == frame_producer::empty())\r
-                       return basic_frame::eof();\r
+               if(following != frame_producer::empty())\r
+               {\r
+                       following->set_leading_producer(producer);\r
+                       producer = std::move(following);\r
+               }\r
+               else\r
+                       producer = make_safe<last_frame_producer>(producer);\r
 \r
                return receive_and_follow(producer, hints);\r
        }\r
index c267c611e7d00bd922ba107a8336fb43b7ae764c..7ef42e9fe9875fa6cdf08b4bc1a799e3c84d1bee 100644 (file)
@@ -31,19 +31,19 @@ struct layer::implementation
 {                              \r
        safe_ptr<frame_producer>        foreground_;\r
        safe_ptr<frame_producer>        background_;\r
-       bool                                            is_paused_;\r
-       int                                                     auto_play_delta_;\r
        int64_t                                         frame_number_;\r
-       safe_ptr<core::basic_frame> last_frame_;\r
+       int                                                     auto_play_delta_;\r
+       bool                                            is_paused_;\r
 \r
 public:\r
        implementation() \r
                : foreground_(frame_producer::empty())\r
                , background_(frame_producer::empty())\r
-               , is_paused_(false)\r
-               , auto_play_delta_(-1)\r
                , frame_number_(0)\r
-               , last_frame_(core::basic_frame::empty()){}\r
+               , auto_play_delta_(std::numeric_limits<int>::min())\r
+               , is_paused_(false)\r
+       {\r
+       }\r
        \r
        void pause()\r
        {\r
@@ -73,19 +73,24 @@ public:
                if(background_ != frame_producer::empty())\r
                {\r
                        background_->set_leading_producer(foreground_);\r
-                       foreground_ = background_;\r
-                       frame_number_ = 0;\r
-                       auto_play_delta_ = -1;\r
-                       background_ = frame_producer::empty();\r
+                       \r
+                       foreground_                     = background_;\r
+                       background_                     = frame_producer::empty();\r
+                       frame_number_           = 0;\r
+                       auto_play_delta_        = std::numeric_limits<int>::min();      \r
                }\r
-               resume();\r
+\r
+               is_paused_                      = false;\r
        }\r
        \r
        void stop()\r
        {\r
-               foreground_ = frame_producer::empty();\r
-               frame_number_ = 0;\r
-               last_frame_ = core::basic_frame::empty();\r
+               foreground_                     = frame_producer::empty();\r
+               background_                     = background_;\r
+               frame_number_           = 0;\r
+               auto_play_delta_        = std::numeric_limits<int>::min();\r
+\r
+               is_paused_                      = true;\r
        }\r
                \r
        safe_ptr<basic_frame> receive()\r
@@ -93,35 +98,20 @@ public:
                try\r
                {\r
                        if(is_paused_)\r
-                               return disable_audio(last_frame_);\r
+                               return disable_audio(foreground_->last_frame());\r
                \r
-                       const auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_;\r
-\r
                        auto frame = receive_and_follow(foreground_, frame_producer::NO_HINT);\r
                        if(frame == core::basic_frame::late())\r
                                return foreground_->last_frame();\r
-               \r
-                       if(auto_play_delta_ >= 0)\r
-                       {\r
-                               CASPAR_ASSERT(background_ != core::frame_producer::empty());\r
-                               if(frames_left <= 0 || frame == core::basic_frame::eof())\r
-                               {\r
-                                       //CASPAR_ASSERT(frame != core::basic_frame::eof() && "Received early EOF. Media duration metadata incorrect.");\r
-\r
-                                       CASPAR_LOG(info) << L"Automatically playing next clip with " << auto_play_delta_ << " frames offset. Frames left: " << frames_left;\r
-                               \r
-                                       play();\r
-                                       frame = receive();\r
-                               }\r
-                       }\r
 \r
-                       if(frame == core::basic_frame::eof())\r
+                       auto frames_left = foreground_->nb_frames() - (++frame_number_) - auto_play_delta_;\r
+                       if(frames_left < 1)\r
                        {\r
-                               pause();\r
+                               play();\r
                                return receive();\r
                        }\r
                                \r
-                       return last_frame_ = frame;\r
+                       return frame;\r
                }\r
                catch(...)\r
                {\r
index 3b62cf40319dd8dcd5da9608260b8b039f39d56b..3db902f5fe64b8e93776972bebce1a95e3de7e65 100644 (file)
@@ -65,7 +65,6 @@ struct ffmpeg_producer : public core::frame_producer
        double                                                                                  fps_;\r
        frame_muxer                                                                             muxer_;\r
 \r
-       int                                                                                             late_frames_;\r
        const int                                                                               start_;\r
        const bool                                                                              loop_;\r
        const size_t                                                                    length_;\r
@@ -87,7 +86,6 @@ public:
                , audio_decoder_(input_.context(), frame_factory->get_video_format_desc())\r
                , fps_(video_decoder_.fps())\r
                , muxer_(fps_, frame_factory)\r
-               , late_frames_(0)\r
                , start_(start)\r
                , loop_(loop)\r
                , length_(length)\r
@@ -121,11 +119,8 @@ public:
                {\r
                        if(input_.eof())\r
                                return core::basic_frame::eof();\r
-                       else\r
-                       {\r
+                       else                    \r
                                graph_->add_tag("underflow");   \r
-                               ++late_frames_;         \r
-                       }\r
                }\r
                \r
                return frame;\r
@@ -194,7 +189,7 @@ public:
 \r
                // TODO: Might need to scale nb_frames av frame_muxer transformations.\r
 \r
-               return nb_frames + late_frames_ - start_;\r
+               return nb_frames - start_;\r
        }\r
                                \r
        virtual std::wstring print() const\r