草庐IT

直播案例剖析:手机降频对直播声音体验的影响

字节跳动视频云技术团队 2023-04-05 原文

背景

某次嘉宾直播重保项目中,直播中出现了声音卡顿、爆音问题,经过排查得出一个结论:嘉宾直播时手机处于充电状态,手机出现发热导致降频,发热降频导致系统采集线程调度出现问题,属于系统行为,影响到系统采集的输入输出,最终出现声音异常问题。

该结论乍一听似乎没什么说服力,很容易让人不认同这个结论,并且有一些质疑问题,比如:

  • 问题一:如果是性能问题,为什么她说话感觉不卡,而是爆音的现象?
  • 问题二:通过对音视频采集的埋点等信息能更精确的定位吗?“发热降频导致的系统采集线程调度出问题,属于系统行为”是明确结论还是推断?怎么判定的?
  • 问题三:CPU 为什么异常变高?

很多同学都知道 iOS 发热降频这个事情,但是可能不太清楚如何量化影响、如何系统化或者说量化去分析。

本文将基于这个典型案例,做一个系统性的分析,分享 iOS 发热降频的基本概念与处理经验,希望能够解决大家对 iOS 发热降频的一些疑惑,帮助大家在下次遇到类似问题时,能够知道如何分析问题、如何发现证据、如何解决问题。

基本概念

AURemoteIO 线程

AURemoteIO:IOThread 是系统创建专门用于采集和播放或者说是输入、输出的线程,有两个特点:

  • 输入输出是串行的,所以相互之间会受到影响;
  • 线程回调时间是稳定的,且要求实时性非常高,如果存在阻塞,会导致输入输出都受到影响,出现声音异常。异常现象会根据阻塞程度不同而不同,轻微阻塞采集数据不连续,严重一些会明显感觉卡顿、爆音,极其严重的情况会直接导致采集线程关掉出无声数据,这一点解释了背景中提到的问题一。

iOS 的线程调度

概述

由于 Mach 具有处理器集的抽象,所以从某个角度说,Mach 比 Linux 和 Windows 更擅长管理多核处理器。

上下文切换

暂停某个线程的执行,并且将其寄存器状态记录在某个预定义的内存位置中。当一个线程被抢占时,CPU 寄存器中会记住另一个线程保存的线程状态,从而恢复那个线程的执行。

一个线程在 CPU 上可以执行任意长的时间。CPU 寄存器中填满了线程的状态,这个执行过程一直在延续,直到发生下面某种情况:

  • 线程终止
  • 线程自愿放弃
  • 外部中断打断了线程的执行,外部中断要求 CPU 保存线程状态并且立即执行中断处理代码

优先级

每一个线程都被分配了优先级,优先级直接影响线程被调度的频率。每一个操作系统都提供了一个这种优先级的范围:Windows 有 32 个优先级,Linux 有 140 个优先级,Mach 有 128 个优先级。

内核线程的最低优先级为 80,比用户态线程的优先级要高。可以保证内核以及用户维护管理的线程能够抢占用户态的线程。

iPhone 性能与电池的关系

苹果系统在进入低电量模式时都会回收一部分系统资源,降低处理器主频来保证系统的稳定性,也就是我们俗称的降频。

在需要更极端的性能管理的情况下,用户可能会发现以下影响:

  • App 启动时间变长
  • 滚动时帧速率降低
  • 背光灯变暗(可在“控制中心”手动调整)
  • 扬声器音量降低幅度高达 -3dB
  • 部分 App 的帧速率逐渐降低
  • 在最极端的情况下,相机闪光灯会被停用(会显示在相机用户界面上)
  • 在后台刷新的 App 在启动时可能需要重新载入

iOS11.1 以上系统都有降频策略;系统>=iOS13.1,默认开启降频功能,但用户可以手动选择关闭。iOS 系统常见的降频策略有:

  • 如果主动设置了省电模式,系统会主动降频。
  • 如果硬件设备老化,如电池老化(设置->电池容量峰值<80%),也会出现降频。
  • CPU 占用上升较快时,会加快降频。

能效

苹果系统在发热严重时同样会降频甚至降核。

State/constantImpactRecommended action
Nominal /NSProcessInfoThermalStateNominalThe device's temperature-related conditions (thermals) are at an acceptable level. There is no noticeable negative impact to the user.No corrective action is necessary. As always, all apps should be proactive about optimizing energy use, in order to help ensure that thermals do not begin to rise. For example, discretionary background work should be assigned quality of service levels and scheduled for execution at optimal times using NSBackgroundActivityScheduler or an NSURLSession background session.
Fair /NSProcessInfoThermalStateFairThermals are minimally elevated. On devices with fans, those fans may become active, audible, and distracting to the user. Energy usage is elevated, potentially reducing battery life.Although no corrective action is required, reaching this level provides an opportunity for greater proactive action. An app can begin reducing CPU usage and enacting other energy-saving measures to help ensure that the thermal state doesn’t rise any further.
Serious /NSProcessInfoThermalStateSeriousThermals are highly elevated. Fans are active, running at maximum speed, audible, and distracting to the user. System performance may also be impacted as the system begins enacting countermeasures to reduce thermals to a more acceptable level.Apps should begin to take corrective action to help the system reduce thermals and create a more optimal user experience. To achieve this, wherever possible, apps should:Reduce CPU usage.Reduce GPU usage.Reduce I/O.Reduce frame rates.Use lower-quality visual effects.
Critical /NSProcessInfoThermalStateCriticalThermals are significantly elevated. The device needs to cool down.Apps can help the system by taking immediate corrective action to reduce usage of the CPU, GPU, and I/O to the absolute minimum level necessary in order to respond to user actions. Wherever possible, apps can stop using peripherals, such as the camera.

某嘉宾直播中 iOS 发热降频案例分析

某次嘉宾直播重保项目中,发现直播中出现了声音卡顿爆音问题。

排查沟通中,获得反馈:

在开播时没有出现相关问题,开播一段时间后,大概从20:36开始出现声音卡顿、爆音等问题。现象持续到 iPhone 手机换 Android 手机之前一直存在。过程中,强杀 APP 重开也不行。
过程中,存在充电和发热情况。

团队通过业务埋点发现,对应时刻(20:36),嘉宾的电池状态显示在充电(state=2),但不是低电量模式,CPU 占比 131%。

经验分析

从嘉宾侧反馈的信息中,可以抽出几个关键信息:

  1. 开播时没有出现问题,从 20:36 开始,说明:直播持续了一段时间后才出现;
  2. 强杀 APP 重开也不行,说明:出现异常后,无法恢复,都说重启大法好,其实就是为了排除或者说是恢复命中的异常条件导致的问题,结果这次不好用了;
  3. 存在充电和发热情况,且 CPU 占比达 131%;

从前两个点可以分析出,大概率原因不在代码里。第三点采集到的 CPU 数据异常高,过往经验正常的值应该在 50 - 60 左右。由此推测是命中降频了。

那怎么拿出证据呢?

系统分析

状态上报

通过观测系统通知,获取电流状态和发热情况,上报埋点可以判断设备及系统情况,也可以响应通知做一些降级策略。

//注册电流状态通知

[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(yourMethodName:) name: NSProcessInfoPowerStateDidChangeNotification object: nil];

if ([[NSProcessInfo processInfo] isLowPowerModeEnabled]) {
    // Low Power Mode is enabled. Start reducing activity to conserve energy.
} else {
    // Low Power Mode is not enabled.
};
//注册发热情况通知
[[NSNotificationCenter defaultCenter] addObserver:self
      selector: @selector(yourMethodName:)
      name: NSProcessInfoThermalStateDidChangeNotification
      object: nil];

NSProcessInfoThermalState state = [[NSProcessInfo processInfo] thermalState];
if (state == NSProcessInfoThermalStateFair) {
// Thermals are fair. Consider taking proactive measures to prevent higher thermals.
} else if (state == NSProcessInfoThermalStateSerious) {
// Thermals are highly elevated. Help the system by taking corrective action.
} else if (state == NSProcessInfoThermalStateCritical) {
// Thermals are seriously elevated. Help the system by taking immediate corrective action.
} else {
// Thermals are okay. Go about your business.
};

此外,在介绍 AURemoteIO 线程时讲到过,线程回调时间是稳定且要求实时性非常高,如果存在阻塞,会导致输入输出都受到影响。出现声音异常,我们利用内部 SDK 工具针对 io 线程的耗时做了上报,通过耗时的异常增加可以判断出线程时间片被抢占后的挂起现象。

下图中,三列数据,左侧是事件时间点,中间是输入,右侧是输出。可以看到,20:34:07-20:34:37 这段时间中,输入是正常状态,维持在 1.42-1.64 区间。从 20:34:47 开始的 1 秒时间内,输入出现了大幅提升,最低为 3.60,最高甚至达到了 50.89 ,超出了正常数值的很多倍。 20:34:47 - 20:35:47 这个时间点,也和嘉宾侧反馈的问题出现时间相近。

工具分析

降频情况:

正常情况:

从 System load 看降频下的黄色占了绝大部分,可以从中判断出,降频后绝大多数时刻线程负载都超出了 CPU 性能,接下来我们再看看线程调度情况。

降频情况:

正常情况:

从 audioMixerThread 线程看,发热情况下黄色被抢占的时间明显增多,在资源紧缺(发热降频、低端机、耗时任务数较多)的时候,低优先级线程会被高优先级的线程抢占的比较严重,比如,系统开辟的高优先级线程(UI 线程、coreanimation、AppleBCMWLANBusInterfacePCIe 等等)。当然, Mach 系统并不会让低优先级的线程一直处于饥饿状态,会根据系统实际情况去调整优先级,audioMixerThread 在后面从 27 的优先级调高到了 31。

正常情况:

降频情况:

另外,虽然 AURemoteIO 有较高的线程优先级,但依然有可能被更高优先级的线程抢占,且在资源紧缺的情况下,线程的执行时间明显减少至正常情况的三分之一。正常情况:1600us 左右 降频情况:500us 左右。(注:此次截图是基于 demo 模拟测试,如果在抖音上测试会更严重)

如何避免 iOS 发热降频导致直播声音卡顿、爆音问题

重保增加约束

  • 项目重保时,约束用户手机至少保持 80% 以上的电量,最好是充满。如果无法保证电量充足的条件,则需要指导用户手动设定低电流时禁止开启低电量模式(节能模式),建议用户不要一边直播一边充电。
  • 部分重保场景,推荐主播用水冷,降低手机发热出现几率;
  • 采用性能更好的 iPhone 机型,这里的性能更好并不完全等价于更高端,而是跟系统版本和特定机型都有关系,比如 14.5.1 版本系统就被吐槽降频严重,以及过往经验显示 iPhone X 发热后降频非常严重。

优化降低能耗

在正常情况下,我们可以进一步优化能耗,从而降低发热的可能性,或让发热来的更慢一些。这里提几点:

  • 为需要保证实时性的任务提供更高优先级的线程。
  • 有效地使用网络至关重要,尽可能通过减少调度事务以及使用高效的 API 来消除开销成本。网络传输是直播场景的能耗大头。
  • 对繁重开销大的线程任务进行分析,尝试优化线程执行任务的复杂度。例如避免不必要的数据拷贝,降低算法逻辑的时间控件复杂度(算法实时性简化),或者利用SIMD指令集进行并行化处理;以上这些手段的最终目的就是降低 CPU 在单个函数/线程上的执行周期。

结语

遇到这类案例,通常情况下解释难度较大,给出直播声音卡顿、爆音是由于 iOS 发热降频造成的这类结论,天然会给人一种甩锅的感觉。所以,我们更应该充分分析、拿出证据,在分析的过程中自身可以获得很多,也解决了实际问题,从一个小点展开去分析,发现越深入越有意思,很多点都可以深入挖掘。

关于字节跳动视频云技术团队

字节跳动视频云技术团队,负责字节跳动旗下抖音、西瓜视频、今日头条等多个业务视频点播、视频直播、Web多媒体等音视频技术方案建设、播放体验优化等工作,为数亿用户提供优质的音视频服务体验。

字节跳动视频云技术团队还致力于研究、探索多媒体领域的前沿技术,参与国际、国内多媒体方向标准化工作,为多媒体内容分析、处理、压缩、传输、创新交互等领域提供软硬件解决方案,众多创新算法已经广泛应用在抖音、西瓜视频等产品点播、直播、实时通信、图片等多媒体业务,并向火山引擎企业级客户提供技术服务。

有关直播案例剖析:手机降频对直播声音体验的影响的更多相关文章

  1. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  2. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  3. 怎样用一台手机做自媒体? - 2

    其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时

  4. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  5. .net - .NET 将如何影响 Python 和 Ruby 应用程序? - 2

    我很好奇.NET将如何影响Python和Ruby应用程序。用IronPython/IronRuby编写的应用程序是否会非常特定于.NET环境,以至于它们实际上将变得特定于平台?如果他们不使用任何.NET功能,那么IronPython/IronRuby相对于非.NET同类产品的优势是什么? 最佳答案 我不能说任何关于IronRuby的东西,但是大多数Python实现(如IronPython、Jython和PyPy)都试图尽可能忠实于CPython实现。不过,IronPython正在迅速成为这方面的佼佼者之一,并且在PlanetPyth

  6. 西安华为OD面试体验 - 2

    西安华为OD面试体验开始投简历技术面试进展工作进展开始投简历去年一整年一直在考研和工作之间纠结,感觉自己的状态好像当时的疫情一样差劲。之前刚毕业的时候投了个大厂的简历,结果一面写算法的时候太拉跨了,虽然知道时dfs但是代码熟练度不够,放在平时给足时间自己可以调试通过,但是熟练度不够那面试当时就写不出来被刷了。说真的算法学到后期我感觉最重要的是熟练度和背板子(对于我这种普通玩家来说),面试题如果一上来短时间内想不出思路就完蛋了。然后由于当时找的工作不是很理想就又想考研了。但是考研是有风险的,我自我感觉自己可能冲不上那个学校,而找工作一个没成可以继续找嘛。本着抱着试试看的态度在boss上投了简历,

  7. ruby &&= 边缘案例 - 2

    有点边缘情况,但知道为什么&&=会这样吗?我正在使用1.9.2。obj=Object.newobj.instance_eval{@bar&&=@bar}#=>nil,expectedobj.instance_variables#=>[],soobjhasno@barinstancevariableobj.instance_eval{@bar=@bar&&@bar}#ostensiblythesameas@bar&&=@barobj.instance_variables#=>[:@bar]#whywouldthisversioninitialize@bar?为了比较,||=将实例变量初始

  8. 如何使用手机远程访问自己的电脑? - 2

    手机访问电脑后AnyViewer可以做什么? 您成功将手机连接到Windows电脑后,然后您可以做任何您想做的事情,例如:查看文件和运行应用程序。电源管理:在远程会话中,点击电源管理,您可以看到三个项目:锁定、重启和关机,供您在不同情况下管理计算机。如果您需要暂时离开远程会话,可以锁定计算机。如果计算机死机,您可以重新启动它,然后再次连接。如果您已完成计算机上的所有工作,您可以使用手机远程关闭它。更改图像质量:当电脑和手机的网络都处于良好状态时,您可以选择高图像质量以获得更好的体验。当网络状况不佳时,您可以选择低图像质量以获得更流畅的操作。     显示桌面:我们无法在手机上按Windows+

  9. 手机 & 电脑数据,这样删除才彻底! - 2

    恢复出厂设置后数据还在吗?格式化真的彻底吗?数据到底该怎么删?文章目录前言为什么不能彻底删除数据?手机如何彻底删除数据?第一步:恢复出厂设置第二步:手动覆写数据电脑如何彻底删除数据?方法一:命令提示符方法二:文件粉碎方法三:低级格式化硬盘总结前言个人数据安全再次成为大家关注的热门话题:在日常使用手机和电脑时,我们可能需要删除一些敏感数据,例如银行账户信息、个人照片、聊天记录等。数据删除的目的是保护个人隐私,避免泄露。以下是一些关于如何删除数据的方法。恢复出厂设置,不一定彻底清除手机数据电子产品迭代升级速度越来越快,大家家中的旧手机、旧电脑也越来越多,一键删除、格式化、恢复出厂设置能彻底清除个人

  10. 「想体验ChatGPT中文聊天?」那快进来,你用不上算我输 - 2

    ♥️作者:白日参商🤵‍♂️个人主页:白日参商主页♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!!🎈🎈加油!加油!加油!加油🎈欢迎评论💬点赞👍🏻收藏📂加关注+!「想体验ChatGPT中文聊天?」那快进来,你用不上算我输项目场景:项目条件一、那就开始吧1、安装ChatGPT-Desktop2、OpenAPI设置二、使用实例恭喜你!!!配置成功了!!!API和URL都是博主免费提供给大家的!!!恭喜你!!!配置成功了!!!API和URL都是博主免费提供给大家的!!!🎈🎈加油!加油!加油!加油🎈欢迎评论💬点赞👍🏻收藏📂加关注+!项目场景:近几个月可以说ChatGPT是火得一

随机推荐