[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