webrtc QOS方法五.2(发送端帧率调整原理及实现流程)

    视频采集帧率是发送端能够发送的最大帧率,但是当码率太高冲击上行带宽时,或者编码性能跟不上采集帧率,发送端都会通过降帧率方式缓解这些问题。

    当码率太高冲击上行带宽时,通过MediaOptimization类调节帧率进而平滑码率;另外若使用webrtc自带VPX、openh264编码器,在编码器码控模块有接口配置是否掉帧调节码率功能。参见VideoCodecVP8/VideoCodecVP9/VideoCodecH264的frameDroppingOn参数定义。

    当编码性能跟不上采集帧率时,webrtc是通过直接掉帧方式解决,参见下面第三节《采集速度大于编码速度掉帧处理》描述。

一、MediaOptimization作用

MediaOptimization类作用是调节发送端码率,使用两种方式调节:

1、配置编码器输入帧率调整码率:编码器根据输入帧率和码率计算分配给每一帧的字节数。所以实时调节帧率,会调整码率。

2、编码前判断是否掉帧调整码率:实时监控编码后数据量,当检测到码率过高,通过主动掉帧方式降低码率,缓解网络冲击。

函数调用关系图如下:

二、MediaOptimization实现

1)计算编码帧率

  • 计算帧率

       每次编码前,调用MediaOptimization::DropFrame->MediaOptimization::ProcessIncomingFrameRate函数,将当前系统时间加入incoming_frame_times_队列。然后根据一段时间接收到的帧数和持续时间,计算输入视频的帧率。

  • 获取帧率

      每次编码前,调用VideoSender::UpdateEncoderParameters->MediaOptimization::InputFrameRate函数,更新encoder_params_,获取当前编码帧率,配置到编码器中。

2)判断是否掉帧

      判断是否掉帧在FrameDropper类里面实现。

  • 核心参数

       accumulator_max_:漏桶容积,其值为targetbps*kLeakyBucketSizeSeconds,随目标码率改变而改变;
       accumulator_:漏桶累积,漏桶累积字节数,Fill增加,Leak减少,最大值为targetbps*kAccumulatorCapBufferSizeSecs;
       drop_ratio_:丢帧率,指数滤波器,使丢帧率保持一个平滑的变化过程,每次Leak()后更新丢帧率;
       key_frame_ratio_:关键帧率,指数滤波器,使关键帧率保持一个平滑的变化过程,每次Fill()后更新;
      delta_frame_size_avg_kbits_:差分帧码率,指数滤波器,使关键帧率保持一个平滑的变化过程,每次Fill()后更新。

  • 核心函数

       FrameDropper::Fill      

H264EncoderImpl::Encode
->VCMEncodedFrameCallback::OnEncodedImage
->MediaOptimization::UpdateWithEncodedData
->FrameDropper::Fill

     当视频帧被编码后,MediaOptimization类会调用Fill()方法来填充漏桶。

     1、将大帧拆分为large_frame_accumulation_count_个小块,并不累加accumulator_;

     2、将小帧直接累计accumulator_。

     Fill()方法同时更新key_frame_ratio_和delta_frame_size_avg_kbits_,用以计算大帧拆分块数和大帧判断。 

      FrameDropper::Leak

VideoStreamEncoder::EncodeVideoFrame
->VideoSender::AddVideoFrame
->MediaOptimization::DropFrame
->FrameDropper::Leak

       Leak()操作按照编码器输入帧率的频率来执行,每次Leak的大小为targetbps/input_fps,每次Leak时需要判断是否需要累计Fill()方法拆分的块,进而更新drop_ratio_。drop_ratio_的更新遵循下列原则:
       当accumulator_ > 1.3f*accumulator_max_,drop_ratio_基数调整为0.8f*,提高丢帧率调整加速度;
       当accumulator_ < 1.3f*accumulator_max_,drop_ratio_基数调整为0.9f*,降低丢帧率调整加速度。

       FrameDropper::DropFrame

VideoStreamEncoder::EncodeVideoFrame
->VideoSender::AddVideoFrame
->MediaOptimization::DropFrame
->FrameDropper::DropFrame

      DropFrame()操作用来判断是否需要将输入到编码器的这一帧丢弃,其利用drop_ratio_来使丢帧率保持一个平滑的变化过程。

      当drop_ratio_.filtered() >= 0.5f时,表明连续丢弃多个帧(至少一个帧)

      当0.0f < drop_ratio_.filtered() < 0.5f时,表明多个帧才会丢弃一个帧。

三、采集速度大于编码速度掉帧处理

发送端若出现采集帧率大于编码帧率也会主动掉帧,这个掉帧在VideoStreamEncoder::EncodeTask::Run函数处理。

没有使用平滑算法,仅仅判断当前编码器是否空闲,空闲可以正常编码,不会丢帧,否则就会丢弃当前帧。

 

四、参考

https://www.jianshu.com/p/e2a9740b9877
http://www.enkichen.com/2017/07/29/webrtc-drop-frame/
https://www.freehacker.cn/media/webrtc-frame/

 

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值