ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-05-08 15:43:33  阅读:520  来源: 互联网

标签:编码 编码器 ratio 码率 drop 发送 QOS MediaOptimization webrtc


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

    当码率太高冲击上行带宽时,通过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/

 

标签:编码,编码器,ratio,码率,drop,发送,QOS,MediaOptimization,webrtc
来源: https://blog.csdn.net/CrystalShaw/article/details/105965190

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有