美文网首页
iOS WebRTC 杂谈之 peerConnection关闭流

iOS WebRTC 杂谈之 peerConnection关闭流

作者: 王沐凡 | 来源:发表于2020-04-01 18:49 被阅读0次

    为啥要写这个呢,因为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,否,则返回解码错误。

    相关文章

      网友评论

          本文标题:iOS WebRTC 杂谈之 peerConnection关闭流

          本文链接:https://www.haomeiwen.com/subject/yjnauhtx.html