iOS WebRTC 杂谈之 peerConnection关闭流程

为啥要写这个呢,因为WebRTC有个关闭房间卡死主线程的问题,真的困扰了我好久。经过我和同事的不懈努力,不断地跟踪源码,终于解决了这个bug,今天先简单记录下,后面有时间再详细整理解决过程吧。

问题背景

在音视频通话过程中,当有设备退出房间时,iOS会发生概率性卡死情况。

分析过程

卡死问题在之前版本的解决过程中,已排除上层调用、内存实例清理和videoView渲染的影响。

从测试复现的场景上看,当操作切换音频的外放和听筒模式时,极易复现卡死现象,通过查代码发现切换音频模式时,会调用

[[AVAudioSession sharedInstance]setActive:YES error:nil];而该方法是会阻塞主线程的,因此将该方法放在了子线程。这在很大程度上减少了一对一音视频的卡死情况,

但是在多人音视频上却并未有很大效果。

通过阅读跟踪WebRTC底层代码逻辑,PC有个media_controller,关闭pc的时候,要在worker_thread中执行media_controller的析构函数,先删除media_controller中的video_receive_stream,video_receive_stream中有个decoder,是H264_Video_toolbox_decoder,删除decoder的时候,如果解码器在子线程中解码的当前帧未完成,那么此时解码器是加了锁的,主线程worker_thread要执行删除decoder操作,因此进入了wait状态,也就卡死了主线程。修改后基本没有再次出现卡死情况,极偶现的一次卡死在了解码线程的pthread_join上,待后续继续跟进。

分析过程中对底层的代码梳理在https://www.processon.com/view/link/5e551997e4b02bc3ad6148e6中可以看到。

PeerConnection关闭逻辑.jpg

解决方案

从最终的调查结果看,造成卡死现象的原因是多方面的。包括音频模式在主线程的切换,解码线程的阻塞和解码器的释放。目前的解决的方案是从三点进行优化解决:

1、音频模式切换放在子线程中进行,以免阻塞主线程;

2、H264解码器进行异步等待解码完成后释放;

3、解码的sampleBuffer判断其CMItemCount是否大于0,否,则返回解码错误。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 4,859评论 0 3
  • 随着互联网技术的飞速发展,移动端播放视频的需求如日中天,由此也催生了一批开源/闭源的播放器,但是无论这个播放器功能...
    金山视频云阅读 46,627评论 28 170
  • 生活方式包含了衣食住行的方方面面,如何让信仰成为你的生活方式呢? 信仰不是迷信,信就是要认真的信,而不是稀里糊涂的...
    楊小咩阅读 2,412评论 0 1
  • 秋之烁烁,草之离离,路之幽幽,叶之黄黄。总有离愁别绪,似要踏歌而行,远远无际,渺渺云空,旷野四顾,谁知去处。只见黄...
    鑫垚淼阅读 254评论 0 2
  • 感赏儿子今天陪爷爷吃饭、去逛公园,真是非常有孝心的娃。感赏我心情愉悦,去花市买了花,丰富生活,人生要活得多姿...
    zhangxiaoyu阅读 251评论 0 2