调用宇视摄像机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肯定不如这些库的作者对它们的研究来的深入和全面。
上一篇: 【鲲鹏来了】鲲鹏迁移过程案例分享