webRTC 框架下的视频主动丢帧

作者:付明旺。唐桥科技资深架构师。负责实时通信软件的技术创新与研发。曾就职于中兴通讯、诺基亚,在4G和IMS-webRTC等电信通信产品担任软件工程师、系统架构师等角色,具有丰富的无线/互联网通信、实时音视频通信产品技术经验。

唐桥科技,医疗云通信专家,是专业的智能视频PaaS及SaaS云服务提供商。致力于三网融合视频通讯平台的研发和在不同领域的应用,已经与医疗行业应用深度结合,推出了远程医疗、医学视频云会议、互动医教、医学线上峰会平台等一系列行业解决方案,为医疗行业提供专业音视频通讯服务。在此基础上,唐桥科技将多年积累的音视频技术以SDK/API的形式开放给企业及开发者,降低技术门槛,让企业跑得更快。

互联网之上的视频传输经常会遇到网络不稳定,终端性能不足等问题。将有限资源的能力最大化,提供良好的视频体验,是视频传输方案一直追逐的目标。除了不断优化软硬件的处理能力,可以采用的方法不外乎调整视频清晰度(分辨率),丢帧,调整编码码率等体验损伤性手段,来提供降级的服务。本文重点关注在丢帧的使用上,以webRTC m79基线h264编解码为参考探讨一下丢帧手段的使用。

视频传输关键路径

要了解丢帧的发生最好先了解视频传输的全路径,之前写了视频传输的关键路径,可以先行阅读https://xie.infoq.cn/article/738b8293dce86f7c8748e2629。这里借用关键路径的图放在这里,以供参考。

主动丢帧点

  丢帧可以发生在关键路径的任何一个地方,网络传输丢包导致的丢帧不在讨论范围之内。

摄像头丢帧

摄像头的硬件丢帧主要跟成像的曝光时间和对焦控制有关。过暗的光线条件下摄像头需要增加曝光的时间来补偿,帧率就会降低。具有自动对焦功能的摄像头在调整焦距时也会影响摄像头输出帧率。如果要确定保持帧率,可以考虑设置设备的曝光和对焦相关参数来调整帧率。

编码前丢帧(capture&adpater)

采集帧进入编码阶段前会做一系列检查,看当前状态是否适合编码当前帧,丢帧可能有这几类情况。

非法帧(kSource)

设置摄像头输出旋转一定角度(如90/180/270度),摄像头未来得及反应前输出的未旋转的非法帧会丢弃。摄像头输出帧到达时间过晚,根据帧率的设置,每个视频帧的到来要满足时间间隔的要求,来晚了丢帧。

超出分辨率-最小码率限制

编码器可以有这样的设置:每一级的分辨率可以设置最小的码率,当前评估出可分配给编码器的带宽如果小于该码率,则可以丢帧,不在将采集的视频帧送到编码器。比如320 * 240档下,当前可用带宽<300kbps则丢帧。

编码器暂停工作或超负荷(kEncoderQueue)

编码器超负荷工作一直疲于奔命,造成queue中有累积多个帧,则把时间上比较早的帧丢弃,最新的帧进入编码。导致编码器暂停编码又会有如下原因

无可用网络

网络发包器累积过多待发送包(一般在网络拥塞时,评估带宽比较低时发生)

编码器的输出码率超出对其的限制(kDroppedByMediaOptimizations)

编码器工作在目标码率的限制下,编码器会一直努力尝试控制在这个码率上下。由于种种原因(比如画面突然变得复杂,突然画面运动)编码器并不能完美的控制码率,webRTC在编码器之外设计了丢帧逻辑来追踪当前的码率设置和编码器的真实输出,如果编码真实输出明显超出限制,webRTC会主动丢帧。

编码器丢帧(endcoder)

进入编码器后,编码器会做一系列的合法检查,如果检查失败会中止该帧编码,等同于丢帧。正常情况下合法性检查都会通过,同时编码器内部维护了一个流控的模块来控制码率的输出。流控丢帧的四种条件如下:

  /* 4 cases for frame skipping

  1:skipping when buffer size larger than target threshold and current continual skip frames is allowed

  2:skipping when MaxBr buffer size + predict frame size - remaining bits in time window < 0 and current continual skip frames is allowed

  3:if in last ODD_TIME_WINDOW the MAX Br is overflowed, make more strict skipping conditions

  4:such as case 3 in the other window

  */

这部分的代码实现看起来比较费劲,根据自己的理解姑且总结一下。target_bitrate/max_bitrate分别设置了编码器的目标码率和最大码率,编码器尽自己的最大能力输出目标码率的码流,在视频帧真正编码前会对当前的统计量与target_bitrate/max_bitrate做算法比较,超出条件限制就会丢帧。比较规则就是上面的四条,结合代码略掉一些细节简化解释一下:

累积超出目标码率值:

BufferFullnessSkip=Σ(CodedBitsPerFrame−TargetBitsPerFrame)

累积超出最大码率值:

BufferMaxBRFullness=Σ(CodedBitsPerFrame−MaxBitsPerFrame)

上面两个统计量如果超过阈值,则丢帧。比如BufferFullnessSkip每帧编码都做检查,如果超过(target_bitrate*50%),则丢帧。BufferMaxBRFullness的判断逻辑更晦涩也更严厉些,具体就不讲了。总体而言,target_bitrate/max_bitrate是对编码器的期望和限制,编码器努力工作尽力满足这个要求,实际上总是会出现超出要求的情况,丢帧就是一种码率调整的手段。注意,丢帧只针对P帧,I帧不会丢掉。

网络发包器(pacer,未丢帧)

直觉上此处会有丢帧的逻辑,webRTC实际没有丢帧逻辑。极限情况下,网络带宽突然变的比较低,网络发包器有机会聚积很多待发包。但此时已经是编码后且封装好的RTP packets,实现丢帧的逻辑不太实际。

服务器丢帧

服务器侧丢帧一般仅存在于特定的场景下,有的路径不适合增加丢帧逻辑。比如服务器端只是做了包的路由,则没办法做丢帧。如果服务器有transcoding转码或者混流功能,会把发送端的码流解码再编码,服务器端可以根据发送链路情况做丢帧逻辑。

帧缓存丢帧(Frame queue)

插入缓存前丢弃:

webRTC不支持B帧,参考帧id如果比当前帧大,则丢弃。

当前缓存>=kMaxFramesBuffered(800),如果当前帧是P帧则丢弃,如果是I帧则清掉过往历史并且I帧入列。

当前帧id比上个解码的帧id小,但当前帧是I帧且时间戳比较新(一般是发送端的编码器重置了),则清空历史缓存,重新从当前帧开始处理。

当前帧id比上个解码的帧id小,且不满足3的条件则丢弃当前帧。(当前帧已过期)

重复帧丢弃

注: 帧id是标识一帧画面的唯一标识,具有时间递增性。

取出后丢弃:

从缓存的起始到最新的连续帧搜索,找出第下一个待解码帧。一个GOP内,没有收到I帧前所有的P帧全跳过。跳过的帧会被丢弃,不再渲染。

解码器丢帧

webrtc使用ffmpeg做为解码器,非异常情况下解码器不做主动丢帧的动作。

渲染丢帧

这部分不在webrtc的范畴内,一般不做主动丢帧,可以根据当前资源使用情况如CPU过高等增加丢帧策略。

总结

综上可以看出,丢帧主要发生在发送侧的摄像头采集、编码前适配和编码过程中,根据经验最经常发生的是网络问题、码率控制、客户端CPU过高等原因。而接收侧的丢帧主要还是应对网络环境导致的一些帧传输异常。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354