onvif 添加H265开发流程
一、onvif简介
2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布 携手共同成立一个国际开放型网络视频产品标准网络接口开发论坛,取名为ONVIF(Open Network Video Interface Forum,开放型网络视频接口论坛),并以公开、开放的原则共同制定开放性行业标准。ONVIF标准将为网络视频设备之间的信息交换定义通用协议,包括装置搜寻、实时视频、音频、元数据和控制信息等。截止到2011年3月,已有279个公司加入ONVIF成为会员
而要用ONVIF协议和设备通信,绕不过soap协议。ONVIF规范中设备管理和控制部 分所定义的接口均以Web Services的形式提供。ONVIF规范涵盖了完全的 XML及WSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。除音视频传输外,服务端与客户端的数据交互采用SOAP协议,而音视频流则通过RTP/RTSP进行 。
SOAP是一个基于xml的简易协议,可使应用程序在 HTTP 之上进行信息交换。
二、onvif一般开发流程
GSOAP是一个用来生成SOAP协议接口的C/C++代码框架的工具,它可以将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构。其使用过程如下
1)所需材料
GSOAP下载路径 : http://sourceforge.net/projects/gsoap2/files/gSOAP(我使用的版本是 GSOAP-2.8)
wsdl文件下载路径: https://www.onvif.org/profiles/specifications/ ,(根据自己需要开发 的模块下载对应的wsdl文件,后面流程我都以media2模块的开发为例,也就是需要下 载media2.wsdl文件)
下载必须的xsd文件:common.xsd,onvif.xsd(否则生成onvif.h时会报错)
将下载好的media2.wsdl、common.xsd、onvif.xsd都放在gsoap-2.8\gsoap\bin\win32目录 下
2)使用wsdl2h生成onvif.h
生成头文件命令:wsdl2h -o -c onvif.h -t typemap.dat media2.wsdl
wsdl2h后面可以加编译参数,如 -S -c -C -x等。可以用 --help了解。其中比较重要的 如下:
-c:生成.c文件(默认是.cpp文件);
-s:不生成STL标准库代码
-C:只生成客户端文件
- -S:只生成服务器端文件(注意大小写)
使用soapcpp2 以及上一步生成的onvif.h生成源文件
(soapC.c、soapH.h、soapClient.c、 soapClientLib、soapStub.h、soapServer.c、 soapServerLib.c。)
如要包含鉴权功能,在onvif.h里面添加 #import “wsse.h”
生成源文件命令:soapcpp2 -c -I…/…/import onvif.h
4)除了上面两步生成的文件,再根据实际需要拷贝一些GSOAP工具中带的一些文件 (根目录下)到自己的工程中,这些也可以后面开发的时候根据报错,然后自己慢慢添 加,增加印象,如下
复制soapClient.c soapServer.c soapServerLib.c soapC.c soapH.h soapStub.h
Media2Binding.nsmap
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\ stdsoap2.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\ stdsoap2.h
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\ dom.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\custom\duration.h
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\custom\duration.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ threads.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ threads.h
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ wsaapi.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ wsaapi.h
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ wsddpi.c
复制D:\gsoap_2.8.27\gsoap-2.8\gsoap\plugin\ wsddpi.h
5) 添加服务端main函数,接收命令(其实需要自己写的也就只有main函数,还有后 面每个功能对应的具体的业务处理函数,以及建立一个架构将之前的GSOAP工具生成 的接口联系起来,而业务处理函数,则跟产品的SDK相关)
int main(int argc, char **argv)
{
int m, s;
struct soap add_soap;
soap_init(&add_soap);
soap_set_namespaces(&add_soap, namespaces);
if (argc < 2) {
printf(“usage: %s <server_port> \n”, argv[0]);
exit(1);
} else {
m = soap_bind(&add_soap, NULL, atoi(argv[1]), 100);
if (m < 0) {
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, “Socket connection successful: master socket = %d\n”, m);
for (;???? {
s = soap_accept(&add_soap);
if (s < 0) {
soap_print_fault(&add_soap, stderr);
exit(-1);
}
fprintf(stderr, “Socket connection successful: slave socket = %d\n”, s);
soap_serve(&add_soap);
soap_end(&add_soap);
}
return 0;
}
三、H265功能添加详细步骤
在onvif标准的协议中,其实并没有H265功能,媒体只支持H264和MJPEG两种编码方式,且无法扩展,这就导致添加H265需要额外添加一个模块media2,而无法直接在原来的协议基础上增加一种编码类型,下面针对服务端和客户端两边加media2模块的方式加以说明
1、服务端添加media2模块
相对客户端添加功能,onvif服务端添加功能要简单很多,因为soap协议是基于http协 议交互的,属于无状态协议,每条信令都是建立的短连接。服务端只需要针对客户端的 请求,依次完成对应的每个功能就行
开发步骤如下:
1)在onvifserver.cpp文件下soap_serve_request接口添加media2接口,或者添加media2 接口到哈希表,选择一种方式就行(添加的接口对应在GSOAP生成的soapServer.cpp)
哈希表
2)添加media2对应的命令空间
命令空间的添加需要修改两个地方,一个是stdsoap2.h,一个是onvif.nsmap(改动的 地方对应GSOAP生成的Media2Binding.nsmap),两个文件添加关于media2的参数 的位置必须保持一致,因为存在对应关系
3)移植media2对应的soap接口以及结构体,这一部分改动量较大
结构体添加主要在onvifstub.h(添加的内容对应在GSOAP生成的soapStub.h)
Soap接口添加主要在onvifH.h以及OnvifC.cpp(添加的内容对应在GSOAP生成的 soapH.h,soapC.c)
4)在onvif会话管理器注册媒体相关的消息
对于服务端来说,会话管理器的作用主要就是建立SDK接口与onvif协议之间的 交互,方便客户端能通过onvif协议访问服务端
注册消息接口:
会话管理器必须为单例模式,保证参数的同步:
调用会话管理器接口,实现onvif业务功能,(业务接口声明在GSOAP生成的 soapStub.h中)
2、客户端添加media2模块
客户端添加media2模块,就复杂一些,因为不同功能之间需要考虑业务逻辑,开发步骤如下:
1)添加media2对应的命令空间
同服务端一样,stdsoap2.h和onvif.nsmp两个文件添加的位置需要对应起来
2)移植media2对应的soap接口
同服务端一样,media2需要的结构体在Gsoap生成的SoapStub,h中,需要的接口在 soapH.h,soapC.c中
3)onvif会话管理器注册媒体相关接口
与服务端不同,客户端会话管理器除了提供SDK接口和onvif协议间的交互,还需要 管理与服务端连接的状态,但是这个跟media2模块添加没有关系,就不多加赘述,当 前只需要注册与媒体相关的消息就行
4)按照逻辑实现onvif客户端业务功能
onvif建立连接相关业务:
第一步,需要判断服务端是否支持media2,如果支持,后续媒体相关的交互就使用 media2,如果服务器不支持,后续媒体相关的交互就使用media。第二步,需要校时, 设备交互之前一般都需要保证时间同步。第三步,获取profile,也就是判断服务器支持 几路码流。第四步,根据上一步获取的码流数,获取每路码流的编码参数。第五步,获 取完编码参数后,建立RTSP连接,拉取音视频流
四、相关文档
1、media2模块对应的具体功能可参照文档《ONVIF-Media2-Service-Spec.pdf》
2、GSOAP操作流程,可参照gsoap-2.8\README.txt