海康 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,打包后同样只包含一种数据。

获取数据

按照以下步骤获取数据:

  1. NET_DVR_Init
  2. NET_DVR_Login_V40
  3. NET_DVR_RealPlay_V40 并设置 OnRealplayData 回调
  4. 在 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
2
3
4
00 00 01 E0 00 22
8C 80 08 23 30 BF 46 D1 FF FF FC 00 00 00 01 67 4D 40 1E 8B 95 01 60 24 D0 80 00 03 84 00 00 AF C8 42
...

data size = (0x00 << 8) + 0x22

Untitled.png

data header size = header[8]

Untitled.png

参考资料

http://dvd.sourceforge.net/dvdinfo/pes-hdr.htmlhttps://blog.csdn.net/jisuanji_wjfioj/article/details/40430455

作者

zi

发布于

2018-01-26

更新于

2018-01-26

许可协议