海康 H264 流分析
目标
本文记录通过海康 SDK 从 IPC 获取视频流数据并从中提取 H264 数据的过程
海康 IPC 的视频采用的是 H264 编码并打包成了 PS 流,下面先了解一下相关基本概念
基本概念
TS 和 PS 是 MPEG-2 定义的容器格式,用于存储音视频数据。
TS - Transport Stream
TS 采用固定包长度,当传输时由于误码破坏了部分 TS 包的同步信息时,接收端可以通过计算恢复同步,所以 TS 一般用在信道环境较恶劣的情况。
PS - Program Stream
PS 包长度不固定,较多用于存储,或者信道环境较好的传输中。
PS 由一个或者多个 PES(Packetized Elementary Streams)组成
ES - Elementary Stream
ES 是音、视频信号经过编码器输出后得到的基本码流,只包含一种内容。
将 ES 打包后即可得到 PES,打包后同样只包含一种数据。
获取数据
按照以下步骤获取数据:
- NET_DVR_Init
- NET_DVR_Login_V40
- NET_DVR_RealPlay_V40 并设置 OnRealplayData 回调
- 在 OnRealplayData 中传入的 type == NET_DVR_STREAMDATA 的 buffer 即为视频数据
分析
每次拿到的数据从几十字节到 5 KB 不等,数据中有明显的 PES 包头 00 00 01
第四个字节表示包类型:
- BA: first block
header_size = 14, data_size = header[13] & 0x07 - BB: system header
header_size = 6, data_size = header[5] - BC: program stream map
header_size = 6, data_size = (header[4] << 8) + header[5] - C0 ~ DF: audio data
header_size = 6, data_size = (header[4] << 8) + header[5] - BD: hik private data
header_size = 6, data_size = (header[4] << 8) + header[5] - E0 ~ EF: video stream
header_size = 6, data_size = (header[4] << 8) + header[5]
从 E0 类型的 PES 的包中获取到的数据(data)进一步拆分,举例说明:
1 | 00 00 01 E0 00 22 |
data size = (0x00 << 8) + 0x22
data header size = header[8]
参考资料
海康 H264 流分析