]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: - audio_mixer: Optimized to use only integer math.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 19 May 2011 21:22:30 +0000 (21:22 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Thu, 19 May 2011 21:22:30 +0000 (21:22 +0000)
         - tbb_avcodec: Multithreading is disabled by default. Configured in config file.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@790 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/audio/audio_mixer.cpp
modules/ffmpeg/tbb_avcodec.cpp
shell/caspar.config

index 4904e1d03a150550d3abe8e564ae48e28587700b..ee0fe7c9b6e51fa800c7d86fc7860861ee10793d 100644 (file)
@@ -69,11 +69,16 @@ public:
                                \r
                next_audio_transforms_[tag] = next; // Store all active tags, inactive tags will be removed in end_pass.\r
                \r
-               auto next_gain = next.get_gain();\r
-               auto prev_gain = prev.get_gain();\r
                \r
-               if(next_gain < 0.001 && prev_gain < 0.001)\r
+               if(next.get_gain() < 0.001 && prev.get_gain() < 0.001)\r
                        return;\r
+               \r
+               static const int BASE = 1<<15;\r
+\r
+               auto next_gain = static_cast<int>(next.get_gain()*BASE);\r
+               auto prev_gain = static_cast<int>(prev.get_gain()*BASE);\r
+               \r
+               int n_samples = audio_data_.back().size();\r
 \r
                tbb::parallel_for\r
                (\r
@@ -82,10 +87,10 @@ public:
                        {\r
                                for(size_t n = r.begin(); n < r.end(); ++n)\r
                                {\r
-                                       double alpha = static_cast<double>(n)/static_cast<double>(audio_data_.back().size());\r
-                                       double sample_gain = prev_gain * (1.0 - alpha) + next_gain * alpha;\r
-                                       int sample = static_cast<int>(audio_data[n]);\r
-                                       sample = (static_cast<int>(sample_gain*static_cast<double>(1<<15))*sample)>>15;\r
+                                       int sample_gain = (prev_gain - (prev_gain * n)/n_samples) + (next_gain * n)/n_samples;\r
+                                       \r
+                                       int sample = (static_cast<int>(audio_data[n])*sample_gain)/BASE;\r
+                                       \r
                                        audio_data_.back()[n] = static_cast<short>((static_cast<int>(audio_data_.back()[n]) + sample) & 0xFFFF);\r
                                }\r
                        }\r
index 46b39c0a42f5f0f95adfca4bfb9ce91b3f76eb15..98b320c6adb6f6ce976b49bf499c8909b5d0eb7f 100644 (file)
@@ -5,10 +5,14 @@
 #include "tbb_avcodec.h"\r
 \r
 #include <common/log/log.h>\r
+#include <common/env.h>\r
 \r
 #include <tbb/task.h>\r
 #include <tbb/atomic.h>\r
 \r
+#include <regex>\r
+#include <boost/algorithm/string.hpp>\r
+\r
 extern "C" \r
 {\r
        #define __STDC_CONSTANT_MACROS\r
@@ -77,11 +81,30 @@ void thread_free(AVCodecContext* s)
        CASPAR_LOG(info) << "Released ffmpeg tbb context.";\r
 }\r
 \r
+std::regex get_slice_regex()\r
+{\r
+       auto s = env::properties().get("configuration.ffmpeg.slice-threads-regex", "");\r
+       boost::algorithm::erase_all(s, " ");\r
+       boost::algorithm::erase_all(s, "\n");\r
+       return std::regex(s);\r
+}\r
+\r
+bool allow_slice_thread(int id)\r
+{\r
+       static std::regex e = get_slice_regex();\r
+       return std::regex_match(boost::lexical_cast<std::string>(id), e);\r
+}\r
+\r
 int tbb_avcodec_open(AVCodecContext* avctx, AVCodec* codec)\r
 {\r
+       auto id = codec->id;\r
        avctx->thread_count = 1;\r
-       if((codec->capabilities & CODEC_CAP_SLICE_THREADS) && (avctx->thread_type & FF_THREAD_SLICE))\r
+       if(allow_slice_thread(id) && // Some codecs don't like to have multiple multithreaded decoding instances. Only enable for those we know work.\r
+         (codec->capabilities & CODEC_CAP_SLICE_THREADS) && \r
+         (avctx->thread_type & FF_THREAD_SLICE))\r
+       {\r
                thread_init(avctx);\r
+       }       \r
        // ff_thread_init will not be executed since thread_opaque != nullptr || thread_count == 1.\r
        return avcodec_open(avctx, codec); \r
 }\r
index 88ad3f880be92c4ecd6beab6a75233d29f404fbf..7932a17fdbee217469f73f60476d335885f241c1 100644 (file)
   <diagnostics>\r
     <graphs>true</graphs>\r
   </diagnostics>\r
+  <ffmpeg>\r
+    <slice-threads-regex>\r
+      <!-- Use slice threads only for tested codecs.-->\r
+      <!-- Match the provided regex expression against the codec-id.-->\r
+      2 <!-- mpeg2 --> | 28 <!-- h264 --> | 102 <!-- dnxhd -->\r
+    </slice-threads-regex>\r
+  </ffmpeg>\r
   <channels>\r
     <channel>\r
       <videomode>1080i5000</videomode>\r