一、onvif服务器的运行机制
onvif服务器与客户端不同,onvif服务器端至少要存在两条线程,一条线程通过UDP协议的socket去监听239.255.255.250:3702的Probe探测信息;另一条线程通过TCP协议的socket去接收客户端发来的报文,服务器端接收到报文后再调用soap_serve_request函数去进入不同的分支,这些分支就是前面提到的需要自己填充的函数,这些函数在《onvif服务器篇之设备发现(onvif discover)》第二部分编程环境里的onvifServerInterface.c接口函数那里有进行介绍。
二、rtsp实时视频流的对接
1. rtsp流对接实现流程
- 设备能被发现;
- 设备支持rtsp协议,能通过VLC软件打开rtsp链接进行预览(即设备的rtsp流功能已完成);
2. onvif服务器端具体实现步骤
- 实现设备发现功能,填充
__wsdd__Probe
函数,告诉客户端提供服务的http地址,如"http://192.168.24.129:5000/onvif/device_service"(注意:这里的/onvif/device_service
在onvif中只是相当于一个标识符,并不是具体存在的路径); - 获取设备能力,填充
__tds__GetCapabilities
函数,这个函数将会告诉客户端服务器支持哪些功能,比如device manager、media等; - 获取服务器功能,这里和步骤2的
__tds__GetCapabilities
实质上类似, 填充__tds__GetServices
函数,要根据__tds__GetCapabilities
提供的功能来填充; - 获取设备的配置信息,包括视频流的各项参数等,填充
__trt__GetProfiles
以及__trt__GetProfile
函数,两个函数的实现一致; - 获取视频编码和视频源的配置信息,填充
__trt__GetVideoEncoderConfiguration
、__trt__GetVideoEncoderConfigurations
、__trt__GetVideoSourceConfiguration
、__trt__GetVideoSourceConfigurations
等4个函数; - 获取rtsp实时视频流,填充
__trt__GetStreamUri
函数,该函数会返回rtsp实时视频流的访问链接,通过这个uri去获取视频流。
二、代码的实现
1. __wsdd__Probe函数的实现
__wsdd__Probe函数的实现在前一篇博客《onvif服务器篇之设备发现(onvif discover)》中已完成,复制粘贴便可。
2. __tds__GetCapabilities函数的实现
#define IP 192.168.10.1 //这里的IP是服务器的IP,根据自己的实际情况修改
SOAP_FMAC5 int SOAP_FMAC6 __tds__GetCapabilities(struct soap* soap, struct _tds__GetCapabilities *tds__GetCapabilities, struct _tds__GetCapabilitiesResponse *tds__GetCapabilitiesResponse)
{
if (tds__GetCapabilities->Category[0] == tt__CapabilityCategory__Device ||
tds__GetCapabilities->Category[0] == tt__CapabilityCategory__All) {
//<Capabilities>
tds__GetCapabilitiesResponse->Capabilities = (struct tt__Capabilities *)soap_malloc(soap, sizeof(struct tt__Capabilities));
memset(tds__GetCapabilitiesResponse->Capabilities, 0, sizeof(struct tt__Capabilities));
//<Device>
tds__GetCapabilitiesResponse->Capabilities->Device = (struct tt__DeviceCapabilities *)soap_malloc(soap, sizeof(struct tt__DeviceCapabilities));
memset(tds__GetCapabilitiesResponse->Capabilities->Device, 0, sizeof(struct tt__DeviceCapabilities));
tds__GetCapabilitiesResponse->Capabilities->Device->XAddr = (char *)soap_malloc(soap, sizeof(char) * 100 );
memset(tds__GetCapabilitiesResponse->Capabilities->Device->XAddr, 0, sizeof(char) * 100);
sprintf(tds__GetCapabilitiesResponse->Capabilities->Device->XAddr, "http://%s:%d/onvif/device_service", IP, ONVIF_TCP_PORT);
//<Device><Network>
tds__GetCapabilitiesResponse->Capabilities->Device->Network = (struct tt__NetworkCapabilities *)soap_malloc(soap, sizeof(struct tt__NetworkCapabilities ));
memset(tds__GetCapabilitiesResponse->Capabilities->Device->Network, 0, sizeof(struct tt__NetworkCapabilities ));
tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPFilter = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));
*(tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPFilter) = xsd__boolean__false_; //关闭功能 xsd__boolean__true_
tds__GetCapabilitiesResponse->Capabilities->Device->Network->ZeroConfiguration= (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));
*(tds__GetCapabilitiesResponse->Capabilities->Device->Network->ZeroConfiguration) = xsd__boolean__false_; //打开功能 xsd__boolean__false_
tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPVersion6 = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));
*(tds__GetCapabilitiesResponse->Capabilities->Device->Network->IPVersion6) = xsd__boolean__false_; //关闭功能 xsd__boolean__true_
tds__GetCapabilitiesResponse->Capabilities->Device->Network->DynDNS = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));
*(tds__GetCapabilitiesResponse->Capabilities->Device->Network->DynDNS) = xsd__boolean__false_; //打开功能 xsd__boolean__false_
//<Device><Network><Extension>
tds__GetCapabilitiesResponse->Capabilities->Device->Network->Extension = (struct tt__NetworkCapabilitiesExtension *)soap_malloc(soap, sizeof(struct tt__NetworkCapabilitiesExtension));
memset(tds__GetCapabilitiesResponse->Capabilities->Device->Network->Extension, 0, sizeof(struct tt__NetworkCapabilitiesExtension ));
tds__GetCapabilitiesResponse->Capabilities->Device->Network->Extension->__size = 1;
tds__GetCapabilitiesResponse->Capabilities->Device->Network->Extension->Dot11Configuration = (enum xsd__boolean *)soap_malloc(soap, sizeof(enum xsd__boolean));
*(tds__GetCapabilitiesResponse->Capabilities->Device->Network->Extension->Dot11Configuration) = xsd__boolean__false_;
//<Device><System>
tds__GetCapabilitiesResponse->Capabilities->Device->System = (struct tt__SystemCapabilities *)soap_malloc(soap, sizeof(struct tt__SystemCapabilities));
memset( tds__GetCapabilitiesResponse->Capabilities->Device->System, 0, sizeof(struct tt__SystemCapabilities));
tds__GetCapabilitiesResponse->Capabilities->Device->System->DiscoveryResolve = xsd__boolean__true_;
td