音视频汇总--视频问题汇总
共 3225字,需浏览 7分钟
·
2022-02-09 17:35
工作中经常碰到各种音视频问题,特地汇总一下,方便记录,也希望能够帮助大家,提供一个解决的思路。废话少说,直接上干货。
1. 网络问题
该问题大概范围为网络传输丢包、封包、解包等问题,
通常的解题思路是:首先查看发包是否正常,然后排查收包是否正常,排查编码后数据是否正常等。从而不同阶段判断不同的问题点,快速定位。
1.1 发包问题
1.1.1 问题描述
双方通话时候卡顿,马赛克、残影;但是rtsp确实正常的。
1.1.2 分析原因
(1)抓包查看P帧包非常小,如下图
工具分析:I帧和P帧数据量差好多,导致部分P帧解码异常,出现马赛克和残影
(3)中间文件保存
将编码后的数据进行文件储存,并导出分析,这时视频编码正常,播放也是OK的。
(4)到此基本上推测出来是发包的问题,只需要发包流程排查即可,最后发现是发包模式不一致导致的
1.1.3 解决方案
因为默认发送方式是 kH264SingleMode, 改用mpp编码后包变大了, 在这个模式下相关函数有阈值判断,导致部分视频帧封包时发送异常,只需要调整对应的值即可。
// Used for NACK and to spread out the transmission of packets.
if (_packetHistory->PutRTPPacket(buffer, rtp_header_length + payload_length,
1800, capture_time_ms, storage) != 0) {
_ return -1;
}
if (packet_length > max_packet_length_) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, -1,
"Failed to store RTP packet, length: %d", packet_length);
return -1;
}
1.2 发包问题
1.2.1 问题描述
由于iOS发包将SPS和PPS整合成stap-a方式发送,而旧的代码中该部分处理有问题,导致和iOS通话时有问题:
stap-a解包时,分别进行存储,然后再按照单独的nalu单元分别送jitterbuffer。
stap-a中nalu单元分开存储
1.2.2 分析原因
1.2.2.1 分析原因1—封包模式
实际场景中如果不开启NACK,直接送解码端是正常播放的,原因是:即使序列号重新计算了,但是由于时间戳和后面的I帧是一致的,因此仍然能够和后面的I帧拼接成一个完整的帧送解码端,这样可以完成解码。
但是一旦有丢包、如果开启NACK,由于序列号的不一致,同时I帧不完整,这时候该方案中的I帧就无法送到解码端进行解码,也就出现之前不开启NACK可以播放,但是开启NACK无法播放的原因。
举例:之前方案方案数据打印如下图,当前SPS和PPS重新计算为44和45,但是I帧的序列号为29336。一旦由丢包,同时启动NACK后,SPS和PPS在jitterbuffer中就没有办法和I帧进行序列号排序,这样这些参数无法送达解码端,也就没有办法解码了。
1.2.2.2 分析原因2--NACK整改后
在整改NACK时,引入STAP-A包封转不处理的方式,但是NALU解包流程没有修改,同时由于NALU单元需要插入起始码(即 0x00 00 00 01),但是旧的解包流程中这部分处理送jitterbuffer前就插入了一个起始码,在后面单独处理STAP-A包时,又重新插入一个起始码,导致送解码端数据异常,这时当时bink解决思路中碰到的问题。
1.2.3 解决办法
1.2.3.1 解决方案1
第一轮解决时,已经发现SPS和PPS重新计算序列号的问题了,为了规避这个问题,尝试一个骚操作,[捂脸]
,就是将SPS和PPS单独出来后,将SPS序列号手动减一(借用上一个P帧中最后一个包的序列号),这样和后面I帧的数据就保持一致了,同时将PPS设置mark标志位,这样将SPS和PPS单独送解码端,这样处理可以规避NACK请求时序列号不一致的问题。但是该方案时有风险的。
如果当前丢包正好时SPS和PPS的stap-a包,这时请求就会异常了。
如果上一个P帧中最后一个序列号丢包,也会出现异常。
1.2.3.3 解决方案2
借鉴iOS对于stap-a的处理方式,同时沿用之前的解包方式,最终方案能够满足现在的需求。
解包时判断如果时stap-a包,则不做处理,在jitterbuffer insertbuffer时候再做对应的处理;
stap-a包不插入起始码,如果时其他的封包方式,沿用之前的处理流程。
1.3 丢包问题
1.3.1 丢包现象
丢包就是由于网络环境问题导致部分数据包无法正常送达接收端,接收端不能正确接收到对应数据,则认为该视频帧不完整,要么直接丢弃,要么送解码器,以马赛克或者不完整的视频帧形式展现出来。造成视频卡顿、马赛克、半视频帧、绿屏、黑屏等现象。
目前很多sdk都支持NACK、FEC等方案来对抗丢包现象,特别是边缘节点、网络切换(从wifi切换到4G,从4G切换到wifi,从5G切换到4G,或者切换到更差的网络)。
这部分的具体解决方案就是采用更加丰富、更加健全的弱网对抗方案,以满足接收端尽可能多的获取到数据。
可以参考
Fenngton:音视频协议--NACK系列一Fenngton:音视频协议--FEC2 编码问题
2.1 熵编码
2.1.1 问题现象
由于新平台与客户话机通话时,无法正常解码,排查原因后发现是因为编码参数的不一致导致的。
2.1.2 分析原因和解决方案
参考
Fenngton:音视频编解码--H264熵编码H264中熵编码主要采用两种类型:CAVLA和CABAC。但是部分硬件厂商支持程度不一致导致无法兼容
2.2 新codec支持
2.2.1 问题描述
该类问题主要是新的codec 在现有的系统中不支持,或者支持度不够,需要增加新的支持
2.2.2 分析原因
freeswitch不支持H263转码,导致视频通话,选H263时视频协商失败
2.2.3 解决方案
该类型问题,一般要增加对应的支持,包括不限于SIP模块(sip和ip)、webrtc、FFMPEG(软解)、VPU库(硬件库)等。
2.3 时间戳问题
2.3.1 问题描述
客户反馈之前是画面卡顿严重,起初分析为分辨率太高4K,CPU带不动,解决的办法为调低分辨率,或者使用硬解,现在采用了调低分辨率的办法,仍然会浮现问题。
客户反馈问题:
视频通话中,出现两次卡顿,大概都会卡2秒,本地复现,发现建立视频后,在4秒左右,会有2秒时间的卡顿,且一直都有,搭环境处理,这边将环境记录。
2.3.2 分析原因
查看VLC源码,是在解码的时候修正pts时间戳出问题的,
2.3.3 解决方法
由于该时间戳是客户摄像头发送过来已经异常,会有一个跳变的过程,导致显示异常,或者修改vlc源码,兼容这种跳变的时间戳,但是对应的工作量增加,为了不影响客户使用,只能像客户说明原因,并修改摄像头部分参数以满足客户的需求。
3 录制相关
3.1 录制后音画不同步
3.1.1 问题描述
通过app录制通话的视频后,发现录制的内容,比较容易出现音画不同步现象。
3.1.2 分析原因
通过录制后的视频排查,以及代码分析,该问题是由于写文件时音频文件盒视频文件分别启用两个线程,按照AVI的文件格式单独写数据。每写一帧视频帧的时间大概是33ms,每写一阵音频帧时间大概是10ms,由于数据匹配过程中写时间戳的过程出现偏差,导致写入的音视频数据并没有按照具体时间间隔进行写入,因此出现音画不同步现象。
3.1.3 解决方案
在分别开启音频线程和视频线程时,一定要计算好相关的时间间隔,并严格按照时间间隔进行写入音视频文件,在播放端就不会出现异常了。
持续更新中。。。