欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

调用宇视摄像机SDK获取IPC的音视频码流

程序员文章站 2022-07-14 18:47:53
...

通过调取宇视摄像机SDK,获取的音视频码流,其格式为标准的h264 over rtp或h265 over rtp。需通过解析rtp从而提取出纯H264/H265及音频帧数据。获得的数据均是裸的视频帧或音频帧。

第1步:调用sdk获取实况码流

	NETDEV_PREVIEWINFO_S stNetInfo;
	memset(&stNetInfo, 0, sizeof stNetInfo);
	stNetInfo.dwChannelID = m_nChannel;
	stNetInfo.hPlayWnd = NULL;
	stNetInfo.dwStreamType = 0;//main
	stNetInfo.dwLinkMode = NETDEV_TRANSPROTOCAL_RTPTCP;

	m_lRealplayHandle = NETDEV_RealPlay(m_lpDevLoginHandle, &stNetInfo, RealDataCallBack, (LPVOID)this);

第2步:在码流回调函数中解析rtp

void CALLBACK RealDataCallBack(IN LPVOID        lpPlayHandle,
								IN const BYTE    *pucBuffer,
								IN INT32         dwBufSize,
								IN INT32         dwMediaDataType,
								IN LPVOID        lpUserParam
								) 
{
	RTP_HDR *pHdr = (RTP_HDR*)pucBuffer;	//可通过其他方式解析得到rtp头部

	/*
	宇视摄像机的负载类型 pHdr->pt:
	108 H265
	105 H264
	26	MJPEG
	8	PCMA
	0	PCMU
	104 AAC
	*/
	if (pHdr->pt == 105)
	{
		ProcessV_H264(lpPlayHandle, pucBuffer, dwBufSize);
	}
	else if (pHdr->pt == 108)
	{
		ProcessV_H265(lpPlayHandle, pucBuffer, dwBufSize);
	}
	if (pHdr->pt == 8)
	{
		ProcessA_PCMA(lpPlayHandle, pucBuffer, dwBufSize);
	}
	else if (pHdr->pt == 0)
	{
		ProcessA_PCMU(lpPlayHandle, pucBuffer, dwBufSize);
	}
	else if (pHdr->pt == 104)
	{
		ProcessA_AAC(lpPlayHandle, pucBuffer, dwBufSize);
	}
}

第3步:解析rtp负载,获取H264/H265/AUDIO帧
获取H264依据:rfc3984 (最新的h264 over rtp 已经是rfc6184)
获取H265依据:rfc7798

一探究竟
其实我们也可以通过Wireshark抓包来一探宇视SDK这种回调数据包格式的秘密。从下图可以看出,宇视SDK取流其实就走的rtsp协议。因此说,SDK给回调函数RealDataCallBack()的buffer其实就是rtp。从这个思路讲,我们解析宇视的码流其实就跟解析rtsp是一个道理。我们费劲调用它的sdk获取并解析码流,还不如使用live555等库直接获取码流。毕竟我们自己研究解析h264/h265 over rtp肯定不如这些库的作者对它们的研究来的深入和全面。
调用宇视摄像机SDK获取IPC的音视频码流