]> git.sesse.net Git - casparcg/commitdiff
Merged screen consumer improvements from trunk
authorhellgore <hellgore@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 3 Sep 2012 13:25:10 +0000 (13:25 +0000)
committerhellgore <hellgore@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 3 Sep 2012 13:25:10 +0000 (13:25 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@3228 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/screen/consumer/screen_consumer.cpp

index 9bdfb4179d93896d9f3f7970272b829f3206b2d2..46b9203a4aa9aae7e49d4508234abbc9519c31b3 100644 (file)
@@ -31,6 +31,7 @@
 #include <common/array.h>\r
 #include <common/memshfl.h>\r
 #include <common/utf.h>\r
+#include <common/prec_timer.h>\r
 \r
 #include <ffmpeg/producer/filter/filter.h>\r
 \r
@@ -136,6 +137,8 @@ struct screen_consumer : boost::noncopyable
        boost::timer                                            perf_timer_;\r
        boost::timer                                            tick_timer_;\r
 \r
+       caspar::prec_timer                                      wait_timer_;\r
+\r
        tbb::concurrent_bounded_queue<core::const_frame>        frame_buffer_;\r
 \r
        boost::thread                                           thread_;\r
@@ -153,7 +156,7 @@ public:
                , screen_height_(format_desc.height)\r
                , square_width_(format_desc.square_width)\r
                , square_height_(format_desc.square_height)\r
-               , filter_(format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? L"" : L"YADIF=0:-1", boost::assign::list_of(PIX_FMT_BGRA))\r
+               , filter_(format_desc.field_mode == core::field_mode::progressive || !config.auto_deinterlace ? L"" : L"YADIF=1:-1", boost::assign::list_of(PIX_FMT_BGRA))\r
        {               \r
                if(format_desc_.format == core::video_format::ntsc && config_.aspect == configuration::aspect_4_3)\r
                {\r
@@ -290,13 +293,15 @@ public:
                        \r
                                        auto frame = core::const_frame::empty();\r
                                        frame_buffer_.pop(frame);\r
+\r
+                                       render_and_draw_frame(frame);\r
                                        \r
-                                       perf_timer_.restart();\r
+                                       /*perf_timer_.restart();\r
                                        render(frame);\r
                                        graph_->set_value("frame-time", perf_timer_.elapsed()*format_desc_.fps*0.5);    \r
 \r
-                                       window_.Display();\r
-                                       \r
+                                       window_.Display();*/\r
+\r
                                        graph_->set_value("tick-time", tick_timer_.elapsed()*format_desc_.fps*0.5);     \r
                                        tick_timer_.restart();\r
                                }\r
@@ -314,7 +319,25 @@ public:
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
        }\r
-       \r
+\r
+       void try_sleep_almost_until_vblank()\r
+       {\r
+               static const double THRESHOLD = 0.003;\r
+               double threshold = config_.vsync ? THRESHOLD : 0.0;\r
+\r
+               auto frame_time = 1.0 / (format_desc_.fps * format_desc_.field_count);\r
+\r
+               wait_timer_.tick(frame_time - threshold);\r
+       }\r
+\r
+       void wait_for_vblank_and_display()\r
+       {\r
+               try_sleep_almost_until_vblank();\r
+               window_.Display();\r
+               // Make sure that the next tick measures the duration from this point in time.\r
+               wait_timer_.tick(0.0);\r
+       }\r
+\r
        spl::shared_ptr<AVFrame> get_av_frame()\r
        {               \r
                spl::shared_ptr<AVFrame> av_frame(avcodec_alloc_frame(), av_free);      \r
@@ -330,25 +353,49 @@ public:
                return av_frame;\r
        }\r
 \r
-       void render(core::const_frame frame)\r
-       {                       \r
-               if(static_cast<int>(frame.image_data().size()) != format_desc_.size)\r
+       void render_and_draw_frame(core::const_frame frame)\r
+       {\r
+               if(static_cast<size_t>(frame.image_data().size()) != format_desc_.size)\r
                        return;\r
 \r
                if(screen_width_ == 0 && screen_height_ == 0)\r
                        return;\r
                                        \r
+               perf_timer_.restart();\r
                auto av_frame = get_av_frame();\r
                av_frame->data[0] = const_cast<uint8_t*>(frame.image_data().begin());\r
 \r
                filter_.push(av_frame);\r
                auto frames = filter_.poll_all();\r
 \r
-               if(frames.empty())\r
+               if (frames.empty())\r
                        return;\r
 \r
-               av_frame = frames[0];\r
-               \r
+               if (frames.size() == 1)\r
+               {\r
+                       render(frames[0]);\r
+                       graph_->set_value("frame-time", perf_timer_.elapsed() * format_desc_.fps * 0.5);\r
+\r
+                       wait_for_vblank_and_display(); // progressive frame\r
+               }\r
+               else if (frames.size() == 2)\r
+               {\r
+                       render(frames[0]);\r
+                       double perf_elapsed = perf_timer_.elapsed();\r
+\r
+                       wait_for_vblank_and_display(); // field1\r
+\r
+                       perf_timer_.restart();\r
+                       render(frames[1]);\r
+                       perf_elapsed += perf_timer_.elapsed();\r
+                       graph_->set_value("frame-time", perf_elapsed * format_desc_.fps * 0.5);\r
+\r
+                       wait_for_vblank_and_display(); // field2\r
+               }\r
+       }\r
+\r
+       void render(spl::shared_ptr<AVFrame> av_frame)\r
+       {\r
                GL(glBindTexture(GL_TEXTURE_2D, texture_));\r
 \r
                GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[0]));\r
@@ -395,6 +442,7 @@ public:
                std::rotate(pbos_.begin(), pbos_.begin() + 1, pbos_.end());\r
        }\r
 \r
+\r
        bool send(core::const_frame frame)\r
        {\r
                if(!frame_buffer_.try_push(frame))\r
@@ -520,7 +568,7 @@ public:
 \r
        int index() const override\r
        {\r
-               return 600 + (config_.key_only ? 1 : 0);\r
+               return 600 + (config_.key_only ? 10 : 0) + config_.screen_index;\r
        }\r
 \r
        void subscribe(const monitor::observable::observer_ptr& o) override\r