接口调用简单、多平台支持的RTSP-Server组件EasyRTSPServer如何修正多网卡多IP情况下解码器不能解码显示问题

EasyRTSPServer修正多网卡多IP情况下解码器不能解码显示问题

提出问题:

海康NVR接入正常,但接入海康解码器出不来图像。

分析问题:

海康解码器是以rtp over udp的方式进行取流,如果运行streamingServer的PC,网络设置为以下两种情况,则都可以正常上墙显示 :

  1. 本机仅设置一个IP,且和解码器在同一网段;
  2. 本机有两个IP, 如192.168.xx.xx 和 190.168.xx.xx,解码器网段为190.168.xx.xx;

当同一网卡设置了以下不同网段的IP,则会出现解码器不能解码上墙的问题,如:

192.168.100.8
192.168.5.8
190.168.100.1
190.168.12.8

经过分析,在setupDatagramSocket函数中,bind时填写的地址为0.0.0.0,而本机中有多个ip,猜想是因为在发送udp数据时,系统随机选用一个ip与解码器通信,导致解码器没有收到数据。

解决问题:

注: 必须将sps、pps、关键帧数据分开发送,否则海康解码器只能接收但不解码显示;

在setupDatagramSocket函数中增加参数 int clientSock, 用于获取当前解码器和streamingserver通信的ip, 将其绑定, 如下:

int setupDatagramSocket(UsageEnvironment& env, Port port, int clientSock, LIVE_IP_VER_ENUM ipVer)
{
  ...
	MAKE_SOCKADDR_IN(name, addr.sin_addr.s_addr, port.num());

	if (clientSock > 0)
	{
		int nSize = sizeof(struct sockaddr_in);
		struct sockaddr_in clientAddr;
		memset(&clientAddr, 0x00, sizeof(clientAddr));
		getsockname(clientSock, (struct sockaddr*)&clientAddr, &nSize);
		memcpy(&name.sin_addr, &clientAddr.sin_addr, sizeof(name.sin_addr));
	}

	if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
	  char tmpBuffer[100];
	  sprintf(tmpBuffer, "bind() error (port number: %d): ",
		  ntohs(port.num()));
	  socketErr(env, tmpBuffer);
	  closeSocket(newSocket);
	  return -1;
	}
	...
}

在调用setupDatagramSocket的地方全都加上int clientSock, 并在入口处将其传入;

注意事项:
在sdp信息中,可将sprop-parameter-sets为空,如下:

m=video 0 RTP/AVP 96  
c=IN IP4 0.0.0.0  
b=AS:1048576  
a=rtpmap:96 H264/90000  
a=fmtp:96 packetization-mode=1;sprop-parameter-sets=  
a=control:track1 

当sprop-parameter-sets为空时,只要在后面的rtp包中发送了sps,pps信息,解码器即可正常解码显示;

posted on 2019-10-15 16:57  TSINGSEE  阅读(477)  评论(0编辑  收藏  举报