问题简述
最近项目开发过程中,测试同学反馈了一个华为手机在WebRTC连接建立的h264音视频流会卡住无法恢复问题。具体的现象是音视频连接可以连接上去一会,但是过一会之后就会无法继续播放。整个画面卡住不动,浏览器没有报错,WebRTC的指标参数可以看到还在继续收包,但是pliCount在持续增加,说明一直在丢帧。然后做了比较多的排查,接下来说下各个排查项
排查经历
码率调整
我这边的产品默认使用的高分辨率1080p的一个产品,初始码率会在8M,出问题那几台手机都是华为的hisi编解码器,所以有所怀疑是不是hisi编解码器在编解码能力上是不是有所欠缺,然后缓慢调小码率,6M,4M都会出现问题,后面就没有在调了,(在这里埋了坑),然后接着排查其他的问题
分辨率调整
由于之前使用与手机不同的分辨率比例的音视频画面的时候会出现sdp设置失败的问题,所以怀疑分辨率有所影响,将画面降至720p的时候,发现画面可以保持播放的时间变长了,但是还是会卡住,降至540p之后发现可以长时间保持播放不卡顿了。可是究竟是什么问题呢?如果想保持高分辨画面需要怎么处理呢?
控制变量
我们排查问题,往往需要具体是什么变量引起的问题。说下我们的问题机器环境:
- HarmonyOS: 4.0.0
- 华为浏览器版本号: 14.0.3.340
- Huawei WebView: 14.0.0.331
- WebRTC H264 音视频连接
- 分辨率 1080P
- 最大码率 8M
- 画面帧率 60fps
这边借用了不少台机器,发现这个问题存在于华为Mate30和Mate40机器中,并且发现在同台机器中的X5内核浏览器并无该问题。这样的话我们可以稍微判断一下这个问题会跟我们的浏览器内核相关,也就是会和我们的WebView相关。那我们需要怎么继续深入问题?
排查日志
因为浏览器没有任何报错,然后变量又出现在了WebViews层,那我们排查问题就没办法从浏览器层入手了,得通过抓包和排查系统日志入手了。虽然是鸿蒙4.0的机器,但是抓取系统日志和android的差不多,我们装一个adb工具,抓取系统日志
bash
adb logcat -c // 清除日志,排查干扰
adb logcat *:W // 打印WARN级别以上的日志
我一般喜欢打印警告以上的日志,如果只需要打印报错日志可以使用 adb logcat *:E
,然后在冻屏的时候可以看到系统确实打印了错误日志,贴一下关键点
bash
11-30 15:33:33.722 31795 32495 W CAWARENESS_32425_ThreadPool: thread pool CompatibleFenceTrigger(1) is busy label:null add to queue 1/1/2
11-30 15:33:34.255 8112 8388 E HWBR-O-1023|hwbr_engine_mainprocess-11362: [ERROR:media_codec_bridge_impl.cc(713)] Input buffer size 240162 exceeds MediaCodec input buffer capacity: 230400
11-30 15:33:34.257 8112 22809 W hwbr_engine_MediaCodecBridge: Releasing: OMX.hisi.video.decoder.avc
11-30 15:33:34.268 8112 32449 E Surface : freeAllBuffers: 6 buffers were freed while being dequeued!
11-30 15:33:34.269 8112 32450 W ACodec : forcing OMX state to Idle when received shutdown in ExecutingState
11-30 15:33:34.278 8112 22809 W hwbr_engine_MediaCodecBridge: Codec released
11-30 15:33:34.302 1316 1521 E ScreemCommon: perf_db# perf db has been closed
11-30 15:33:34.322 1573 1671 E system_server: Cannot read thread CPU times for PID 1573
可以看到指标参数出现一个关键问题,
arduino
Input buffer size 240162 exceeds MediaCodec input buffer capacity: 230400
提示输入的buffer size超过了限定的大小230400(225k),继而做出判断,应该是输入的I帧超过了webview 设置的的限定大小,这样就大概知道了什么问题,应该是webview层限制了I帧的输入大小,不能超过2M的带宽(之前都没想到会限制这么低的码率)。这样我们就知道大概问题了,虽然不知道为什么会存在这种问题,怎么解决这个问题呢?直接改webview是不现实的,限制码率?限制分辨率?,限制帧率?应该都是有用的,只要目标视频码率不超过2M就不会出这个问题了,但是否有办法放开这个限制,这个就比较麻烦了,给华为提了工单,但是没有回应,后续问题就暂时限定了鸿蒙手机的输出码率和分辨率,不是一个很好的方案,希望有大佬看到能给个建议。