问题
通过海思芯片编码后,将编码的数据通过UDP网口发送到UDP 服务端,UDP服务端收到后保存成文件。
保存的文件有时候用VLC软件可以打开。有时候不能打开,同时用Elecard HEVC Analyer工具打开,发现VLC不能打开时丢帧。如下图,实际为858帧,而此处只有846帧。
分析
UDP包丢包
实际统计,收发两端一致。
海思编码芯片异常
通过 /proc/h265 节点查看,编码没有问题。
H265 协议
和 H264 的码流结构一样,也是通过启始码(0x000001
或者0x00000001
)进行分割压缩数据,每一个称为NAL单元(NAL Unit,简称NALU
)。NALU有不同的类型,主要是对数据内容进行区分。
对于一个码流文件来说,和H264一样,有一系列的NALU的类型定义,可以分为VPS,SPS,PPS,SEI,I帧,P帧 6种类型。码流结构如下所示:
启始码+VPS+启始码+SPS+启始码+PPS+启始码+SEI+启始码+I帧+启始码+P帧+启始码+P帧+.....
如上就是一个图像系列的组成,为什么这么说呢? 一般我们在网络上发送数据,比如采集端一般在发送压缩数据的I帧前先发送 VPS,SPS,PPS。解码端不可能先启动后等着发送端数据到来吧,只有解码器拿到 VPS,SPS,PPS 后才可以解码 H265 的数据。VPS,SPS,PPS,SEI,一个I帧,一个P帧都可以常委一个 NALU。
从上面可以看到 h265 比 h264 多了一个 VPS,VPS 是视频参数集。
我们这里看一下经过 h265 编码器编码后的码流文件,截取文件开头的数据,
因为 h265 码流最开始永远是 VPS,SPS,PPS,可能含有 SEI,后面接着是I帧P帧数据。
16进制打开文件如下:
0000 0001 4001 0c01 ffff 0160 0000 0300 // 4001
b000 0003 0000 0300 5aac 0900 0000 0142 // 4201
0101 0160 0000 0300 b000 0003 0000 0300
5aa0 0442 00f0 77e5 aee4 c92e a520 a0c0
c05d a142 5000 0000 0144 01c0 e30f 0330 // 4401
840a 0000 0001 2601 af0b e075 8d53 b010 // 2601
af65 bfb4 0b53 823d e91c ad66 f973 ce21
5d92 9227 9159 3dc6 2cae 5adf 4cda f9b5
6105 3165 97cd 64cd f04d 09d5 5e10 d231
// ...省略其它数据
2f04 c9cc 1e01 700a 0000 0001 0201 d08f // 0201
// ...省略其它数据
两次文件内容对比
正常文件
异常文件
Elecard HEVC Analyer回看
打开异常的数据,鼠标点到最左边的I帧,可以看到下面偏移量为0x2ce87。而正常的偏移量为0。即在0x2ce87之前的帧都没有解析出来。
回顾
在整个文件分析中,数据路径上的字节数目并没有丢失。但是最终解析软件解析出问题。一直从字节丢失来分析,这条路走不下去。
从协议角度分析,就容易多了。
同时,如果采用UDP传输,丢了关键的数据,则可能一次性丢失很多帧。这点在实际业务中要重点考虑。