VLC网速估计算法

ExoPlayer网速估计方法

在VLC播放器中有好几种自适应逻辑会估计网速,有NearOptimalAdaptationLogic、PredictiveAdaptationLogic、RateBasedAdaptationLogic这三种,网速估计方法在updateDownloadRate中进行,是通过一个叫MovingAverage类进行计算的

该类定义如下

    template <class T>
    class MovingAverage
    {
        public:
            MovingAverage(unsigned = 10);
            T push(T);

        private:
            std::list values;    //存储历史的下载网速(每次io会计算一次下载速度,命名为bps)
            T previous;     //最早加入list的网速值
            unsigned maxobs;    //list的最大存储空间
            T avg;          //估计出的当前网速值
    };
网速估计过程

这里网速估计采用的是EMA(Exponential moving average)
1.每次io完数据后会计算一次本次io的下载速度,定义为bps,这里bps变量的单位也是bps

2.调用MovingAverage类中的push函数将bps push到list里面(网速估计的更新是在这里进行的)

  • 如果values存储的值的个数超过(>=)maxobs时,将最先加入list的网速值存入previous变量中,并在list中剔除该值,然后将最新的bps添加入values中。如果values存储的值的个数小于maxobs时,则直接将最新的bps添加入values中。
    (上述类似于添加采样值的过程,比较好理解,下面的步骤比较玄学)

  • 找出values中的最小值omin与最大值omax,求出最大值减最小值deltamax = omax-omin

  • 计算diffsums.sum,计算方法是包括previous在内,values各个值的俩俩差值的绝对值的和,比如
    现有previous,values[0],values[1],values[2],values中的其他值为0
    diffsums.sum = | previous - values[0] |+| values[0] - values[1] |+| values[1] - values[2] |

  • 计算alpha(这个值就是EMA算法中的权重),计算方法为

double alpha = (diffsums.sum) ? 0.33 * ((double)deltamax / diffsums.sum) : 0.5;
  • 计算估计网速avg并返回(这里其实就是EMA公式),之前的avg值乘以alpha加上最新输入的bps乘以1-alpha
avg = alpha * avg + (1.0 - alpha) * (*values.rbegin());

到这里RateBasedAdaptationLogic中的网速估计就完成了

原理文档

没找到相应的文章解释,就连MovingAverage是谁写的在源码里都没写,查找历史记录查到了github作者账号,但是没有邮箱地址

个人理解

diffsums.sum的含义其实是在前几次采样过程中网速的波动大小。通过波动来决定alpha值的大小,进而控制估计的网速对之前估计值的依赖。若波动较大diffsums.sum就较大,alpha较小,估计出的网速对新的采样依赖较大对之前估计网速依赖较小,说明在网络波动大的情况下能更接近于最新的采样值。若波动较小,diffsums.sum就较小,alpha较大,估计出的网速对新的采样依赖较小对之前估计网速依赖较大,这样更好的保证了网速估计的平稳。

你可能感兴趣的:(音视频处理,VLC)