GB28181协议是视频监控领域的国家标准,本文将解析如何在FFmpeg中增加对GB28181协议的支持,使其可以与支持GB28181协议的设备进行通信与控制,实现设备的注册、保活以及流媒体的传输。
GB28181协议指的是国家标准GB/T 28181—2016《公共安全视频监控联网系统信息传输、交换、控制技术要求》1,该标准规定了公共安全视频监控联网系统的互联结构, 传输、交换、控制的基本要求和安全性要求, 以及控制、传输流程和协议接口等技术要求,是视频监控领域的国家标准。GB28181协议信令层面使用的是SIP(Session Initiation Protocol)协议2,流媒体传输层面使用的是实时传输协议(Real-time Transport Protocol,RTP)协议3,因此可以理解为GB28181是在国际通用标准的基础之上进行了私有化定制以满足视频监控联网系统互联传输的标准化需求。本文旨在说明在FFmpeg中增加对GB28181协议的支持,使其可以与支持GB28181协议的设备进行通信与控制,实现设备的注册、保活以及流媒体的传输。
GB28181协议会话通道实际上使用的是SIP协议,并且在SIP协议的基础之上做了些私有化处理。SIP是一个由IETF MMUSIC工作组开发的协议,作为标准被提议用于创建,修改和终止包括视频,语音,即时通信,在线游戏和虚拟现实等多种多媒体元素在内的交互式用户会话。SIP中一个比较重要的概念是用户代理(User Agent),指的是一个SIP逻辑网络端点,用于创建、发送、接收SIP消息并管理一个SIP会话。SIP用户代理又可分为用户代理客户端UAC(User Agent Client)和用户代理服务端UAS(User Agent Server)。UAC创建并发送SIP请求,UAS接收处理SIP请求,发送SIP响应。SIP协议会与许多其它的协议协同工作,如SIP报文内容发送会话描述协议(Session Description Protocol,SDP)4,SDP协议描述了会话所使用流媒体细节,如:使用哪个IP端口,采用哪种编解码器等等。SIP的一个典型用途是:SIP会话传输一些简单的经过报文的实时传输协议流,RTP本身才是语音或视频的载体。在GB28181协议中,联网系统在进行视音频传输及控制时应建立两个传输通道: 会话通道和媒体流通道。会话通道用于在设备之间建立会话并传输系统控制命令; 媒体流通道用于传输视音频数据, 经过压缩编码的视音频流采用流媒体协议RTP/RTCP传输。GB28181协议中具体通信协议结构图如下图1所示:
图1 通信协议结构图
会话通道中,注册、实时视音频点播、历史视音频的回放等应用的会话控制采用SIP协议IETF RFC3261中规定的REGISTER、INVITE等请求和响应方法实现, 历史视音频回放控制采用SIP扩展协议IETF RFC29765规定的INFO方法实现,前端设备控制、信息查询、报警事件通知和分发等应用的会话控制采用SIP扩展协议IETF RFC34287规定的MESSAGE方法实现。下面详细介绍下注册、保活和实时视音频点播的SIP消息结构。
注册指的是设备或系统进入联网系统时向SIP服务器(SIP UAS)进行注册登记的工作模式,在本文中FFmpeg即为一个SIP服务器,设备向FFmpeg发送注册请求,FFmpeg在接收到设备的注册请求后返回相应的回复消息,则完成设备注册流程。GB28181协议中基于数字摘要的挑战应答式安全技术进行注册流程如下图2所示:
图2 基本注册流程示意图
注册流程描述如下:
(a) SIP代理向SIP服务器发送Register请求;
(b) SIP服务器向SIP代理发送响应401,并在响应的消息头WWW_Authenticate字段中给出适合SIP代理的认证体制和参数;
(c) SIP代理重新向SIP服务器发送REGISTER请求, 在请求的Authorization字段给出信任书,包含认证信息;
(d) SIP服务器对请求进行验证,如果检查出SIP代理身份合法,向SIP代理发送成功响应200OK,如果身份不合法则发送拒绝服务应答。
注册的请求消息内容范例如下:
1 REGISTER sip:34020000002000000001@3402000000 SIP/2.0
2 Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1371463273
3 From: sip:34020000001320000003@3402000000;tag=2043466181
4 To: sip:34020000001320000003@3402000000
5 Call-ID: 1011047669
6 CSeq: 1 REGISTER
7 Contact: sip:34020000001320000003@192.168.137.11:5060
8 Max-Forwards: 70
9 User-Agent: IP Camera
10 Expires: 3600
11 Content-Length: 0
注册的回复消息内容范例如下,各头信息含义见上面:
1 SIP/2.0 200 OK
2 Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1371463273
3 From: sip:34020000001320000003@3402000000
4 To: sip:34020000001320000003@3402000000
5 CSeq: 1 REGISTER
6 Call-ID: 1011047669
7 Contact: sip:34020000001320000003@192.168.137.11:5060
8 User-Agent: FFmpeg GB28181 v1.0
9 Expires: 3600
10 Content-Length: 0
当UA发现工作异常时, 应立即向本SIP监控域的SIP服务器发送状态信息; 无异常时,应定时向本SIP监控域的SIP服务器发送状态信息。状态信息报送采用IETF RFC3427中定义的方法MESSAGE实现。通过周期性的状态信息报送,实现注册服务器与源设备之间的状态检测即心跳机制。心跳发送方、接收方需统一配置“心跳间隔”参数,按照“心跳间隔”定时发送心跳消息,默认心跳间隔60s。心跳发送方、接收方需统一配置“心跳超时次数”参数,心跳消息连续超时达到“心跳超时次数”则认为对方下线,默认心跳超时次数3次。心跳接收方在心跳发送方上线状态下检测到心跳消息连续超时达到商定次数则认为心跳发送方离线; 心跳发送方在心跳接收方上线状态下检测到心跳消息响应消息连续超时达到商定次数则认为心跳接收方离线。具体命令流程如图3:
图3 保活命令流程
命令流程描述如下:
(a) 源设备向SIP服务器发送设备状态信息报送命令。设备状态信息报送命令采用MESSAGE方法携带;
(b) SIP服务器收到命令后返回200 OK。
保活消息内容范例如下:
1 MESSAGE sip:34020000002000000001@3402000000 SIP/2.0
2 Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1066375804
3 From: sip:34020000001320000003@3402000000;tag=1925919231
4 To: sip:34020000002000000001@3402000000
5 Call-ID: 1185236415
6 CSeq: 20 MESSAGE
7 Content-Type: Application/MANSCDP+xml
8 Max-Forwards: 70
9 User-Agent: IP Camera
10 Content-Length: 175
11 <?xml version="1.0" encoding="UTF-8"?>
12 <Notify>
13 <CmdType>Keepalive
14 <SN>1
15 <DeviceID>34020000001320000003
16 <Status>OK
17 <Info>
18 </Info>
19 </Notify>
MESSAGE消息头Content-type头为Content-type: Application/MANSCDP+xml。状态信息报送命令采用MANSCDP(监控报警联网系统控制描述协议,Monitoringand Alarming Network System Control Description Protocol)协议格式定义, 详细描述见GB/T 28181—2016中A.2.5状态信息报送。状态信息报送命令应包括命令类型(CmdType)、设备/系统编码(DeviceID)、是否正常工作(Status)等, 采用MESSAGE方法的消息体携带。Message消息的成功和错误应答均无消息体,Message回复消息内容范例如下:
1 SIP/2.0 200 OK
2 Via: SIP/2.0/UDP 192.168.137.11:5060;rport;branch=z9hG4bK1066375804
3 From: sip:34020000001320000003@3402000000
4 To: sip:34020000002000000001@3402000000
5 CSeq: 20 MESSAGE
6 Call-ID: 1185236415
7 User-Agent: FFmpeg GB28181 v1.0
8 Content-Length: 0
实时视音频点播采用SIP协议中的INVITE方法实现会话连接,采用RTP/RTCP协议(IETF RFC3550)实现媒体传输。需要注意的是,实时视音频点播需要上述的媒体流保活机制。客户端主动发起的实时视音频点播流程见图4:
图4 客户端主动发起的实时视音频点播流程图
其中,信令1、8、9、10、11、12为SIP服务器接收到客户端的呼叫请求后通过B2BUA代理方式建立媒体流接收者与媒体服务器之间的媒体流信令过程,信令2-7为SIP服务器通过三方呼叫控制建立媒体服务器与媒体流发送者之间的媒体流信令过程,信令13-16为媒体流接收者断开与媒体服务器之间的媒体流信令过程,信令17-20为SIP服务器断开媒体服务器与媒体流发送者之间的媒体流信令过程。
命令流程描述如下:
(a) 媒体流接收者向SIP服务器发送INVITE消息, 消息头域中携带Subject字段, 表明点播的视频源ID、发送方媒体流序列号、媒体流接收者ID、接收端媒体流序列号等参数,SDP消息体中s字段为“Play”代表实时点播。
(b) SIP服务器收到INVITE请求后,通过三方呼叫控制建立媒体服务器和媒体流发送者之间的媒体连接。向媒体服务器发送INVITE消息,此消息不携带SDP消息体。
(c) 媒体服务器收到SIP服务器的INVITE请求后,回复200 OK响应,携带SDP消息体,消息体中描述了媒体服务器接收媒体流的IP、端口、媒体格式等内容。
(d) SIP服务器收到媒体服务器返回的200 OK响应后,向媒体流发送者发送INVITE请求,请求中携带消息3中媒体服务器回复的200 OK响应消息体,s字段为“Play”代表实时点播, 增加y字段描述SSRC值,f字段描述媒体参数。
(e) 媒体流发送者收到SIP服务器的INVITE请求后,回复200 OK响应,携带SDP消息体,消息体中描述了媒体流发送者发送媒体流的IP、端口、媒体格式、SSRC字段等内容。
(f) SIP服务器收到媒体流发送者返回的200 OK响应后,向媒体服务器发送ACK请求,请求中携带消息5中媒体流发送者回复的200 OK响应消息体, 完成与媒体服务器的INVITE会话建立过程。
(g) SIP服务器收到媒体流发送者返回的200 OK响应后,向媒体流发送者发送ACK请求,请求中不携带消息体,完成与媒体流发送者的INVITE会话建立过程。
(h) 完成三方呼叫控制后,SIP服务器通过B2BUA代理方式建立媒体流接收者和媒体服务器之间的媒体连接。在消息1中增加SSRC值,转发给媒体服务器。
(i) 媒体服务器收到INVITE请求,回复200OK响应,携带SDP消息体,消息体中描述了媒体服务器发送媒体流的IP、端口、媒体格式、SSRC值等内容。
(j) SIP服务器将消息9转发给媒体流接收者。
(k) 媒体流接收者收到200 OK响应后,回复ACK消息,完成与SIP服务器的INVITE会话建立过程。
(l) SIP服务器将消息11转发给媒体服务器,完成与媒体服务器的INVITE会话建立过程。
(m) 媒体流接收者向SIP服务器发送BYE消息,断开消息1、10、11建立的同媒体流接收者的INVITE会话。
(n) SIP服务器收到BYE消息后回复200 OK响应, 会话断开。
(o) SIP服务器收到BYE消息后向媒体服务器发送BYE消息,断开消息8、9、12建立的同媒体服务器的INVITE会话。
(p) 媒体服务器收到BYE消息后回复200 OK响应, 会话断开。
(q) SIP服务器向媒体服务器发送BYE消息,断开消息2、3、6建立的同媒体服务器的INVITE会话。
(r) 媒体服务器收到BYE消息后回复200 OK响应,会话断开。
(s) SIP服务器向媒体流发送者发送BYE消息,断开消息4、5、7建立的同媒体流发送者的INVITE会话。
(t) 媒体流发送者收到BYE消息后回复200 OK响应, 会话断开。
上述流程较为复杂,原因是在实际视频监控系统中,用户不是直接跟前端监控设备交互,而是与监控管理平台交互。媒体流接收者通常是用户的客户端,SIP服务器是单独的服务器,媒体服务器通常是监控系统中的媒体网关,媒体流发送者为前端摄像机。本文中FFmpeg既作为SIP服务器,也作为用户客户端向前端设备发送INVITE请求,因此可以简化为FFmpeg向前端设备发送INVITE请求后,前端设备向FFmpeg回复200OK,然后FFmpeg再向前端设备回复ACK,这样前端设备即开始发送媒体流。
INVITE消息范例如下:
1 INVITE sip:34020000001320000003@3402000000 SIP/2.0
2 Via: SIP/2.0/UDP 39.100.155.146:15063;rport;branch=z9hG4bK34208805
3 From: sip:34020000002000000001@39.100.155.146:15063;tag=512358805
4 To: sip:34020000001320000003@3402000000
5 Call-ID: 200008805
6 CSeq: 20 INVITE
7 Content-Type: Application/SDP
8 Contact: sip:34020000001320000003@3402000000
9 Max-Forwards: 70
10 User-Agent: FFmpeg GB28181 v1.0
11 Subject: 34020000001320000003:630886,34020000002000000001:0
12 Content-Length: 164
13 v=0
14 o=34020000001320000003 0 0 IN IP4 39.100.155.146
15 s=Play
16 c=IN IP4 39.100.155.146
17 t=0 0
18 m=video 9000 RTP/AVP 96
19 a=recvonly
20 a=rtpmap:96 PS/90000
21 y=630886
SIP消息头部分上述已经解释过了,这里解释下SDP相关字段含义。
INVITE回复消息范例如下:
1 SIP/2.0 200 OK
2 Via: SIP/2.0/UDP 39.100.155.146:15063;rport=15063;branch=z9hG4bK34208805
3 From: sip:34020000002000000001@39.100.155.146:15063;tag=512358805
4 To: sip:34020000001320000003@3402000000;tag=1083111311
5 Call-ID: 200008805
6 CSeq: 20 INVITE
7 Contact: sip:34020000001320000003@192.168.137.11:5060
8 Content-Type: application/sdp
9 User-Agent: IP Camera
10 Content-Length: 263
11 v=0
12 o=34020000001320000003 1073 1073 IN IP4 192.168.137.11
13 s=Play
14 c=IN IP4 192.168.137.11
15 t=0 0
16 m=video 15060 RTP/AVP 96
17 a=setup:active
18 a=sendonly
19 a=rtpmap:96 PS/90000
20 y=0000630886
ACK消息范例如下:
1 ACK sip:34020000001320000003@3402000000 SIP/2.0
2 Via: SIP/2.0/UDP 39.100.155.146:15063;rport;branch=z9hG4bK34208805
3 From: sip:34020000002000000001@39.100.155.146:15063;tag=512358805
4 To: sip:34020000001320000003@3402000000
5 Call-ID: 200008805
6 CSeq: 20 ACK
7 Max-Forwards: 70
8 User-Agent: FFmpeg GB28181 v1.0
9 Content-Length: 0
BYE消息范例如下:
1 BYE sip:34020000001320000003@3402000000 SIP/2.0
2 Via: SIP/2.0/UDP 39.100.155.146:15063;rport;branch=z9hG4bK34208805
3 From: sip:34020000002000000001@3402000000;tag=512358805
4 To: sip:34020000001320000003@3402000000;tag=1083111311
5 Call-ID: 200008805
6 CSeq: 79 BYE
7 Max-Forwards: 70
8 User-Agent: FFmpeg GB28181 v1.0
9 Content-Length: 0
2.2 RTP协议
RTP是一个网络传输协议,IETF RFC3550详细描述了RTP协议内容。GB28181协议中规定了两种方式传输媒体流,一种是将音视频数据打包成MPEG2-PS流然后再通过RTP协议传输,另外一种是直接使用RTP传输裸的音视频流,在实际应用中主要以第一种方式为主,因此本文着重介绍下第一种方式。基于RTP的PS封装首先按照ISO/IEC13818-1:20008将视音频流封装成PES包,然后再将PES包封装成PS包, 再将PS包以负载的方式封装成RTP包。进行PS封装时,应将每个视频帧封装为一个PS包,且每个关键帧的PS包中应包含系统头(System Header)和PSM(Program Stream Map),系统头和PSM放置于PS包头之后、第一个PES包之前。典型的视频关键帧PS包结构如图6所示,其中PESV为视频PES包,PESA为音频PES包,视频非关键帧的PS包结构中一般不包含系统头和PSM。PS包中各部分的具体数据结构参见ISO/IEC13818-1:2000中的相关描述。
图5 典型的视频关键帧PS包结构
系统头应包含对PS包中码流种类的描述, 其中视频和音频的流ID(stream_id)取值如下:
(a) 视频流ID:0xE0;
(b) 音频流ID:0xC0。
针对几种视音频格式,PSM中流类型(stream_type)的取值如下:
(a) MPEG-4 视频流:0x10;
(b) H.264 视频流:0x1B;
(c) SVAC 视频流:0x80;
(d) G.711 音频流:0x90;
(e) G.722.1 音频流:0x92;
(f) G.723.1 音频流:0x93;
(g) G.729 音频流:0x99;
(h) SVAC 音频流:0x9B。
PS包的RTP封装格式参照IETF RFC2250,RTP的主要参数设置如下:
(a) 负载类型(payloadtype):96;
(b) 编码名称(encoding_name):PS;
(c) 时钟频率(clockrate):90 kHz;
(d) SDP描述中“m”字段的“media”项:video。
首先我们在FFmpeg中实现了GB28181协议的demuxer,方案的框架图如图6所示。主要包含两个子模块,一个是SIP stack模块,负责SIP协议功能,一个GB28181 demuxer模块,负责调用SIP接口与前端设备IPC进行交互,同时解析IPC通过RTP发送过来的MPEG2-PS流,得到音视频数据流后以packet的形式返回给lavf上层,再依次往FFmpeg上层传。SIP stack模块提供单一功能的SIP接口,比如发送回复消息,发送INVITE/BYE/ACK请求;GB28181 demuxer模块需要按照FFmpeg上层接口调用顺序与IPC进行相关的交互,同时创建与设备之间的RTP链接,在拿到MPEG2-PS流后进行解析。
图6 demuxer方案的框架图
由于FFmpeg只有解析PS流封装的本地视频demuxer,并没有解析PS流的demuxer,因此本文也在本地PS流封装视频demuxer的基础之上实现了PS流的demuxer。核心思路是从RTP包中解析PS头信息,再根据PS头信息找到PES头,从PES头中取出每个PES包的长度。由于RTP长度限制,一个PES包会被切分成很多份分成多个RTP包传输过来,因此PS demuxer需要缓存这些PES切片,等一个完整的PES包凑齐后再解析取出音视频流并以packet格式返回上FFmpeg上层模块。由于IETF RFC22509并没有规定PS流应该如何封装到RTP中,因此PES头可能出现在RTP包的任何位置,demuxer也针对不同的情况做了处理。
上述方案存在局限性,只能对单一设备进行管理和拉流,但实际场景中一个SIP域中存在众多设备。因此在上述GB28181 demuxer的基础之上,我们也实现了GB28181 server,方案的框架图如下图7所示。
图7 server方案的框架图
GB28181 server功能包括:
GB28181 server可以使用户不感知GB28181协议的存在,用户只需要对感兴趣的设备进行操作即可。具体实现中,我们对上述GB28181 demuxer进行了功能扩展,使其具备两种工作模式,一种就是上述的单一设备模式,一种就是多设备管理模式。后者将设备状态信息、发送拉流/停止拉流接口暴露出来供GB28181 server调用。因此当GB28181 server运行后,其自动会对发出注册请求的设备进行管理,监控设备是否在线或离线并更新设备信息。同时监听用户请求,当接收到用户的HTTP请求时做相应的拉流/停止拉流等操作。
[1] GB/T 28181—2016. 安全防范视频监控联网系统信息传输, 交换, 控制技术要求[D]. , 2016.
[2] Rosenberg J, Schulzrinne H, Camarillo G, et al. RFC3261: SIP: session initiation protocol[J]. 2002.
[3] Casner S, Frederick R, Jacobson V, et al. RFC 3550, RTP: A Transport Protocol for Real-Time Applications[J]. Network Working Group, 2003.
[4] Handley M, Jacobson V, Perkins C. RFC 4566: SDP: session description protocol[J]. 2006.
[5] Donovan S. IETF RFC 2976 the SIP INFO Method[J]. 2000.
[6] RFC3428 I. SIP extension for instant messaging[J]. 2002.
[7] Rosenberg J, Schulzrinne H. IETF RFC 3581[J]. An Extension to the Session Initiation, 2003.
[8] Rec I. H. 222.0| ISO/IEC 13818-1: 2000[J]. Information Technology—Generic coding of moving pictures and associated audio—Part, 1.
[9] Hoffman D, Fernando G, Goyal V, et al. RFC2250: RTP payload format for MPEG1/MPEG2 video[J]. 1998.