[vlc-commits] demux: adaptive: use template class for moving average

Francois Cartegnie git at videolan.org
Wed Sep 21 18:52:31 CEST 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Sep 20 23:13:33 2016 +0200| [4ac75b1f7c2c7b1147377ed7772ef2f81eca8dfe] | committer: Francois Cartegnie

demux: adaptive: use template class for moving average

better, more efficient

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4ac75b1f7c2c7b1147377ed7772ef2f81eca8dfe
---

 modules/demux/Makefile.am                          |  1 +
 .../adaptive/logic/RateBasedAdaptationLogic.cpp    | 39 +---------
 .../adaptive/logic/RateBasedAdaptationLogic.h      | 10 +--
 modules/demux/adaptive/tools/MovingAverage.hpp     | 91 ++++++++++++++++++++++
 4 files changed, 95 insertions(+), 46 deletions(-)

diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 2afe779..0569948 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -358,6 +358,7 @@ libadaptive_plugin_la_SOURCES = \
     demux/adaptive/tools/Debug.hpp \
     demux/adaptive/tools/Helper.cpp \
     demux/adaptive/tools/Helper.h \
+    demux/adaptive/tools/MovingAverage.hpp \
     demux/adaptive/tools/Properties.hpp \
     demux/adaptive/tools/Retrieve.cpp \
     demux/adaptive/tools/Retrieve.hpp \
diff --git a/modules/demux/adaptive/logic/RateBasedAdaptationLogic.cpp b/modules/demux/adaptive/logic/RateBasedAdaptationLogic.cpp
index efef4bb..2388c83 100644
--- a/modules/demux/adaptive/logic/RateBasedAdaptationLogic.cpp
+++ b/modules/demux/adaptive/logic/RateBasedAdaptationLogic.cpp
@@ -46,9 +46,6 @@ RateBasedAdaptationLogic::RateBasedAdaptationLogic  (vlc_object_t *p_obj_, int w
     usedBps = 0;
     dllength = 0;
     p_obj = p_obj_;
-    for(unsigned i=0; i<10; i++) window[i].bw = window[i].diff = 0;
-    window_idx = 0;
-    prevbps = 0;
     dlsize = 0;
     vlc_mutex_init(&lock);
 }
@@ -96,41 +93,8 @@ void RateBasedAdaptationLogic::updateDownloadRate(const ID &, size_t size, mtime
 
     const size_t bps = CLOCK_FREQ * dlsize * 8 / dllength;
 
-    /* set window value */
-    if(window[0].bw == 0)
-    {
-        for(unsigned i=0; i<TOTALOBS; i++) window[i].bw = bps;
-    }
-    else
-    {
-        window_idx = (window_idx + 1) % TOTALOBS;
-        window[window_idx].bw = bps;
-        window[window_idx].diff = bps >= prevbps ? bps - prevbps : prevbps - bps;
-    }
-
-    /* compute for deltamax */
-    size_t diffsum = 0;
-    size_t omin = SIZE_MAX;
-    size_t omax = 0;
-    for(unsigned i=0; i < TOTALOBS; i++)
-    {
-        /* Find max and min */
-        if(window[i].bw > omax)
-            omax = window[i].bw;
-        if(window[i].bw < omin)
-            omin = window[i].bw;
-        diffsum += window[i].diff;
-    }
-
-    /* Vertical Horizontal Filter / Moving Average
-     *
-     * Bandwidth stability during observation window alters the alpha parameter
-     * and then defines how fast we adapt to current bandwidth */
-    const size_t deltamax = omax - omin;
-    double alpha = (diffsum) ? 0.33 * ((double)deltamax / diffsum) : 0.5;
-
     vlc_mutex_lock(&lock);
-    bpsAvg = alpha * bpsAvg + (1.0 - alpha) * bps;
+    bpsAvg = average.push(bps);
 
     BwDebug(msg_Dbg(p_obj, "alpha1 %lf alpha0 %lf dmax %ld ds %ld", alpha,
                     (double)deltamax / diffsum, deltamax, diffsum));
@@ -139,7 +103,6 @@ void RateBasedAdaptationLogic::updateDownloadRate(const ID &, size_t size, mtime
 
     currentBps = bpsAvg * 3/4;
     dlsize = dllength = 0;
-    prevbps = bps;
 
     BwDebug(msg_Info(p_obj, "Current bandwidth %zu KiB/s using %u%%",
                     (bpsAvg / 8192), (bpsAvg) ? (unsigned)(usedBps * 100.0 / bpsAvg) : 0));
diff --git a/modules/demux/adaptive/logic/RateBasedAdaptationLogic.h b/modules/demux/adaptive/logic/RateBasedAdaptationLogic.h
index d7b9bc6..f5130aa 100644
--- a/modules/demux/adaptive/logic/RateBasedAdaptationLogic.h
+++ b/modules/demux/adaptive/logic/RateBasedAdaptationLogic.h
@@ -26,6 +26,7 @@
 #define RATEBASEDADAPTATIONLOGIC_H_
 
 #include "AbstractAdaptationLogic.h"
+#include "../tools/MovingAverage.hpp"
 
 namespace adaptive
 {
@@ -50,14 +51,7 @@ namespace adaptive
                 size_t                  usedBps;
                 vlc_object_t *          p_obj;
 
-                static const unsigned   TOTALOBS = 10;
-                struct
-                {
-                    size_t bw;
-                    size_t diff;
-                } window[TOTALOBS];
-                unsigned                window_idx;
-                size_t                  prevbps;
+                MovingAverage<size_t>   average;
 
                 size_t                  dlsize;
                 mtime_t                 dllength;
diff --git a/modules/demux/adaptive/tools/MovingAverage.hpp b/modules/demux/adaptive/tools/MovingAverage.hpp
new file mode 100644
index 0000000..79f42ce
--- /dev/null
+++ b/modules/demux/adaptive/tools/MovingAverage.hpp
@@ -0,0 +1,91 @@
+/*
+ * MovingAverage.cpp
+ *****************************************************************************
+ * Copyright (C) 2015 - 2016 VideoLAN Authors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef MOVINGAVERAGE_HPP
+#define MOVINGAVERAGE_HPP
+
+#include <list>
+#include <algorithm>
+
+namespace adaptive
+{
+    template <class T>
+    class MovingAverageSum
+    {
+        public:
+            MovingAverageSum<T>(T i): sum(0), prev(i) { }
+            void operator()(T n) {
+                sum += (n > prev) ? n - prev : prev - n;
+                prev = n;
+            }
+            T sum;
+        private:
+            T prev;
+    };
+
+    template <class T>
+    class MovingAverage
+    {
+        public:
+            MovingAverage(unsigned = 10);
+            T push(T);
+
+        private:
+            std::list<T> values;
+            T previous;
+            unsigned maxobs;
+            T avg;
+    };
+
+    template <class T>
+    MovingAverage<T>::MovingAverage(unsigned nbobs)
+    {
+        if(nbobs < 1)
+            throw new std::exception();
+        this->maxobs = nbobs;
+        previous = 0;
+    }
+
+    template <class T>
+    T MovingAverage<T>::push(T v)
+    {
+        if(values.size() >= maxobs)
+        {
+            previous = values.front();
+            values.pop_front();
+        }
+        values.push_back(v);
+
+        /* compute for deltamax */
+        T omin = *std::min_element(values.begin(), values.end());
+        T omax = *std::max_element(values.begin(), values.end());
+        MovingAverageSum<T> diffsums = std::for_each(values.begin(), values.end(),
+                                                     MovingAverageSum<T>(previous));
+        /* Vertical Horizontal Filter / Moving Average
+         *
+         * stability during observation window alters the alpha parameter
+         * and then defines how fast we adapt */
+        const T deltamax = omax - omin;
+        double alpha = (diffsums.sum) ? 0.33 * ((double)deltamax / diffsums.sum) : 0.5;
+        avg = alpha * avg + (1.0 - alpha) * (*values.rbegin());
+        return avg;
+    }
+}
+
+#endif // MOVINGAVERAGE_HPP



More information about the vlc-commits mailing list