問題
海康NVR接入正常,但接入海康解碼器出不來圖像;
分析海康解碼器是以rtp over udp的方式進行取流;
如果運行streamingServer的PC, 網絡設置爲以下兩種情況,則都可以正常上牆顯示:
- 本機僅設置一個IP, 且和解碼器在同一網段;
- 本機有兩個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信息,解碼器即可正常解碼顯示;