WebRTC中使用CPU使用情况作为码率控制的依据之一。当CPU过度使用(overusing)时,进行视频编码的降级(adapt down);当CPU未充分使用(uderusing)时,进行视频编码的升级(adapt up)。目的是在当前设备性能条件下,尽可能地提供高质量的视频。这里的质量,包括清晰度、流畅度等综合指标。
WebRTC中关于CPU使用度检测的代码主要在 http://overuse_frame_detector.cc 的OveruseFrameDetector类中实现,其对象overuse_detector_在VideoStreamEncoder构造时作为参数传入。具体来说,OveruseFrameDetector负责实现检测数据的处理,VideoStreamEncoder负责初始化、提供数据、反馈回调等流程。
1.什么是“CPU使用度”
首先,我们需要明确什么是CPU使用度。顾名思义,往往我们会认为与CPU占用率有关。 但是阅读OveruseFrameDetector,除了注释中提到CPU,代码中并没有相关实现。实际上,所谓的“CPU使用度”是指编码耗时 / 采集耗时,是一个比值。当该比值越大时,表示编码跟不上采集,达到了编码器的性能瓶颈,需要对编码进行降级;反之,比值越小,表示编码能力有富余,还可以进行编码升级,提供更好的视频质量。换句话说,就是一个生产者与消费者的关系。
由此可见,CPU使用度并不与CPU产生直接关联,而是通过编码相对速率来衡量当前的运行性能。这样做的好处有几个:
不与CPU硬件绑定,与硬件平台解耦
兼顾当前软件运行环境的影响,比如其他应用对CPU的消耗、操作系统对各进程资源的调度策略
具体如何推导出该比值,将会在下文中介绍。
2.初始化与配置
和其他observer类型一样,OveruseFrameDetector在VideoStreamEncoder构造时注册。OveruseFrameDetector本身的构造中对配置项进行初始化,其中最重要的两个:
low_encode_usage_threshold_percent: Underusing的阈值,默认为42。低于该阈值,则认为Underusing。
high_encode_usage_threshold_percent:Overusing的阈值,默认为85。高于该阈值,则认为Overusing。
配置项的更改,只发生在编码器重新创建的时候(流初始化,或者编码格式变化):
void VideoStreamEncoder::ReconfigureEncoder() { // ... if (pending_encoder_creation_) { overuse_detector_->StopCheckForOveruse(); overuse_detector_->StartCheckForOveruse( &encoder_queue_, GetCpuOveruseOptions( settings_, encoder_->GetEncoderInfo().is_hardware_accelerated), this); pending_encoder_creation_ = false; } // ... } CpuOveruseOptions GetCpuOveruseOptions( const VideoStreamEncoderSettings& settings, bool full_overuse_time) { CpuOveruseOptions options; if (full_overuse_time) { opti