]> git.sesse.net Git - casparcg/commitdiff
* Improved precision of prec_timer on Linux.
authorHelge Norberg <helge.norberg@svt.se>
Wed, 26 Aug 2015 16:53:26 +0000 (18:53 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Wed, 26 Aug 2015 16:53:26 +0000 (18:53 +0200)
* Made screen consumer poll the second field from the yadif filter after the first field has been displayed to better utilize the cpu time.
* Buffer more audio in oal_consumer when higher frame rates are used to reduce the possibility of audio pops.

common/os/linux/prec_timer.cpp
modules/oal/consumer/oal_consumer.cpp
modules/screen/consumer/screen_consumer.cpp

index 57f38ef1e45c69c4b570d602a609ee15dd9c7574..9a700740c4d95ef46cdde1d9a6dddbe2895c5034 100644 (file)
 #include <boost/thread.hpp>
 #include <boost/chrono/system_clocks.hpp>
 
+#include <time.h>
+
+#include <cmath>
+
 using namespace boost::chrono;
 
 namespace caspar {
@@ -37,7 +41,8 @@ prec_timer::prec_timer()
 
 void prec_timer::tick_millis(int64_t ticks_to_wait)
 {
-       auto t = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
+       ticks_to_wait *= 1000000;
+       auto t = duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
 
        if (time_ != 0)
        {
@@ -54,20 +59,23 @@ void prec_timer::tick_millis(int64_t ticks_to_wait)
 
                        if (!done)
                        {
-                               // if > 0.002s left, do Sleep(1), which will actually sleep some 
-                               //   steady amount, probably 1-2 ms,
-                               //   and do so in a nice way (cpu meter drops; laptop battery spared).
-                               // otherwise, do a few Sleep(0)'s, which just give up the timeslice,
-                               //   but don't really save cpu or battery, but do pass a tiny
-                               //   amount of time.
-                               if (ticks_left > 2)
-                                       boost::this_thread::sleep_for(milliseconds(1));
-                               /*else
-                                       for (int i = 0; i < 10; ++i)
-                                               Sleep(0);  // causes thread to give up its timeslice*/
+                               timespec spec;
+
+                               if (ticks_left > 2000000)
+                               {
+                                       spec.tv_sec = ticks_left / 1000000000;
+                                       spec.tv_nsec = 1000000;
+                               }
+                               else
+                               {
+                                       spec.tv_sec = 0;
+                                       spec.tv_nsec = ticks_left / 100;
+                               }
+
+                               nanosleep(&spec, nullptr);
                        }
 
-                       t = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
+                       t = duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
                } while (!done);
        }
 
index e74b4953de819e56af76f00c4c2ce0caff532a83..387c490f6cab549555450b52ce91e633a715cd50 100644 (file)
@@ -49,8 +49,6 @@
 #include <AL/alc.h>
 #include <AL/al.h>
 
-#include <array>
-
 namespace caspar { namespace oal {
 
 typedef cache_aligned_vector<int16_t> audio_buffer_16;
@@ -114,14 +112,13 @@ struct oal_consumer : public core::frame_consumer
        core::video_format_desc                         format_desc_;
 
        ALuint                                                          source_                         = 0;
-       std::array<ALuint, 3>                           buffers_;
+       std::vector<ALuint>                                     buffers_;
 
        executor                                                        executor_                       { L"oal_consumer" };
 
 public:
        oal_consumer() 
        {
-               buffers_.fill(0);
                presentation_age_ = 0;
 
                init_device();
@@ -134,7 +131,7 @@ public:
 
        ~oal_consumer()
        {
-               executor_.begin_invoke([=]
+               executor_.invoke([=]
                {               
                        if(source_)
                        {
@@ -157,15 +154,16 @@ public:
                format_desc_    = format_desc;          
                channel_index_  = channel_index;
                graph_->set_text(print());
-               
+
                executor_.begin_invoke([=]
                {               
+                       buffers_.resize(format_desc_.fps > 30 ? 8 : 4);
                        alGenBuffers(static_cast<ALsizei>(buffers_.size()), buffers_.data());
                        alGenSources(1, &source_);
 
                        for(std::size_t n = 0; n < buffers_.size(); ++n)
                        {
-                               std::vector<int16_t> audio(format_desc_.audio_cadence[n % format_desc_.audio_cadence.size()]*format_desc_.audio_channels, 0);
+                               audio_buffer_16 audio(format_desc_.audio_cadence[n % format_desc_.audio_cadence.size()]*format_desc_.audio_channels, 0);
                                alBufferData(buffers_[n], AL_FORMAT_STEREO16, audio.data(), static_cast<ALsizei>(audio.size()*sizeof(int16_t)), format_desc_.audio_sample_rate);
                                alSourceQueueBuffers(source_, 1, &buffers_[n]);
                        }
@@ -250,7 +248,7 @@ public:
 
        int delay_millis() const
        {
-               return 160;
+               return 213;
        }
        
        int buffer_depth() const override
index c57cb6b397a5705c09d78d3f0cce5f18dc428ac2..814db6e3239eec8f075bd30226bbb4bd73a62313 100644 (file)
@@ -425,9 +425,9 @@ public:
                return av_frame;
        }
 
-       void render_and_draw_frame(core::const_frame frame)
+       void render_and_draw_frame(core::const_frame input_frame)
        {
-               if(static_cast<size_t>(frame.image_data().size()) != format_desc_.size)
+               if(static_cast<size_t>(input_frame.image_data().size()) != format_desc_.size)
                        return;
 
                if(screen_width_ == 0 && screen_height_ == 0)
@@ -435,30 +435,31 @@ public:
                                        
                perf_timer_.restart();
                auto av_frame = get_av_frame();
-               av_frame->data[0] = const_cast<uint8_t*>(frame.image_data().begin());
+               av_frame->data[0] = const_cast<uint8_t*>(input_frame.image_data().begin());
 
                filter_.push(av_frame);
-               auto frames = filter_.poll_all();
+               auto frame = filter_.poll();
 
-               if (frames.empty())
+               if (!frame)
                        return;
 
-               if (frames.size() == 1)
+               if (!filter_.is_double_rate())
                {
-                       render(frames[0]);
+                       render(spl::make_shared_ptr(frame));
                        graph_->set_value("frame-time", perf_timer_.elapsed() * format_desc_.fps * 0.5);
 
                        wait_for_vblank_and_display(); // progressive frame
                }
-               else if (frames.size() == 2)
+               else
                {
-                       render(frames[0]);
+                       render(spl::make_shared_ptr(frame));
                        double perf_elapsed = perf_timer_.elapsed();
 
                        wait_for_vblank_and_display(); // field1
 
                        perf_timer_.restart();
-                       render(frames[1]);
+                       frame = filter_.poll();
+                       render(spl::make_shared_ptr(frame));
                        perf_elapsed += perf_timer_.elapsed();
                        graph_->set_value("frame-time", perf_elapsed * format_desc_.fps * 0.5);