磕磕绊绊的做了出来,也算为自己留个资料吧。先讲理论再上代码。挑些重点讲。
1. 首先就是获取到 rtp 包,rtp包的结构是:rtp包头+payload,payload就是我们要的ps包,rtp包头的长度是12个字节,所以rtp包去掉前12字节就是ps包了。
比如这个 rtp 包,跳过12个字节,从00 00 01 ba 开始就是ps包了。
2. 找到ps包之后就要从它的格式入手开始解析,ps荷载h264是把一帧帧的数据打包传过来,一个完整的ps包会包含一帧的数据。
而h264的帧分为 i 帧和 p 帧,i 帧的结构是 ps header + ps system header + ps system map + pes + h264 (+ pes + 音频)。
p 帧的结构为 ps header + pes + h264 (+ pes + 音频)。
3. 首先我们要找到第一个 i 帧,找到ps头 00 00 01 ba,ps头长度为14个字节,最后一个字节的后三位的数字标识扩展字节,
这里最后一个字节是 fe ,所以跳过6个字节,到00 00 01 bb。
4. 00 00 01 bb标识 ps system header,它后面的两个字节共同表示ps system header的长度,注意是表示这之后的数据长度,
比如这里ps system header 表示长度的两个字节是 00 12,换算成十进制,就是后面还有18个字节,跳过这18个字节就到了 00 00 01 bc。
5. 00 00 01 bc表示ps system map,它后面的两个字节代表ps system map 的长度。也是这之后的数据长度。
比如这个长度是 00 5e,跳过这 94 个字节就到了 00 00 01 e0,
6,00 00 01 e0就是我们要找的pes 数据包,它后面的两个字节表示pes包剩余数据的长度,跳过两个字节的下一个字节代码pes包的扩展长度。
比如这里 00 22表示后面还有 34个字节,08表示有8个扩展字节,扩展字节之后就是h264的数据,h264数据的长度为pes的长度减去到扩展字节的长度再减去扩展字节。也就是34-3-8 = 23个字节。
如图我们就取到了一个h264的数据了。看到后面又是00 00 01 e0开始的,所以又是一个视频帧。循环往复即可。
下面上代码,这里我使用的是 jrtp,方便获取 rtp 包,测试过海康和大华的两款设备都是没问题的。
代码已上传优快云:https://download.youkuaiyun.com/download/qq_39805297/12566110
MyRTPSession.h
#ifndef MYRTPSESSION_H
#define MYRTPSESSION_H
#include <jrtplib3/rtpsession.h>
#include <jrtplib3/rtppacket.h>
#include <jrtplib3/rtpudpv4transmitter.h>
#include <jrtplib3/rtpipv4address.h>
#i