部分海康网络摄像头无法实现视频流解码与实时预览

1. 问题描写

最近在搭建1个可视传感网,在调试早期就遇到了1个很奇怪的问题:

一样的型号的摄像机,一样的程序,有1部份摄像头正常工作,而有1大部份的不能正常解码显示。这个小demo是我使用海康SDK里面实例写的。文章的最后给出项目的代码,有兴趣的也能够跑跑程序,其实只是1个简单的例程而已,写在这里只是为了方便往后归纳总结。这里使用的海康网络摄像头型号是:DS⑵CD852MF-E。

代码中,摄像头的登录函数为:NET_DVR_Login_V30,播放函数:NET_DVR_RealPlay_V40。

这里写图片描述

在回调解码函数处设置断点,能跳到此函数中:

这里写图片描述

但是除ip为192.168.2.21和192.168.2.22这两个网络摄像机,换成其他的摄像机都显示不了。但是另外一方面,网络摄像头的登录没有问题,但是就是没有画面。

这里写图片描述

单步调试,看到lRealHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);lRealHandle值为0,表示没有问题的啊…但是在回调函数设置断点却进不去,就说明没有回调解码。跟上面的区分就在这里。但是代码是1模1样的,摄像机型号都是1样的852MF-E,因此不知道问题出在哪里。

2. 解决方法

以上问题可简单描写为,1个可用的程序,但对1部份摄像头硬件可用,这些摄像头型号均是1样的,因此第1时间的想法是查看这些摄像机软件版本或硬件固件版本是不是1致,答案是不是定的:

这里写图片描述

因此我又试了多个摄像机,只要是v2.0 build 100521 和v4.0 build 090220,这样的都能显示,但是其他的软件版本都显示不了。1时半会要更新软件或固件版本也是1大工程,因此继续查阅SDK开发文档,发现其实可以查看装备登录预览的SDK日志,在代码中,只需在SDK初始化后调用NET_DVR_SetLogToFile()函数便可保存日志信息。启用写日志文件的函数定义以下:

BOOL NET_DVR_SetLogToFile(
DWORD nLogLevel, char *strLogDir, BOOL bAutoDel
);

其中,nLogLevel 表示日志的等级(默许为0):0-表示关闭日志,1-表示只输出ERROR毛病日志,2-输出ERROR毛病信息和DEBUG调试信息,3-输出ERROR毛病信息、DEBUG调试信息和INFO普通讯息等所有信息;
strLogDir 表示日志文件的路径,windows默许值为”C:SdkLog”;linux默许值”/home/sdklog/”;
bAutoDel 表示是不是删除超越的文件数,默许值为TRUE。

生成日志文件,发现实际上是缺少了必要的dll文件。

SDK V4.3.0.6
[2015⑴0⑵0 14:58:00.599][INF] version:This hcnetsdk version is 4.3.0.6 Version 2014_07_22.
SDK V4.3.0.6[2015⑴0⑵0 14:58:00.599][INF] LogonDev1 192.168.3.22:8000 in
[2015⑴0⑵0 14:58:00.601][INF] Private connect 192.168.3.22:8000 sock=496 this=0xf115e8 cmd=0x10000 port=30473
[2015⑴0⑵0 14:58:00.601][INF] OpenCommandConnection ptr=0xf115e8 id=4096
[2015⑴0⑵0 14:58:00.601][INF] [SendCommandWithRecv] this=0xf115e8, cmd_id=0x1000, cmd=0x10000
[2015⑴0⑵0 14:58:00.615][INF] [CloseCommandConnection] this=0xf115e8, cmd_id=0x1000
[2015⑴0⑵0 14:58:00.615][INF] StopLinkInConnection sock=496 this=0xf115e8, command=0x10000
[2015⑴0⑵0 14:58:00.620][INF] LogonDev1 192.168.3.22:8000 in
[2015⑴0⑵0 14:58:00.630][INF] Private connect 192.168.3.22:8000 sock=496 this=0xf115e8 cmd=0x10010 port=30474
[2015⑴0⑵0 14:58:00.630][INF] OpenCommandConnection ptr=0xf115e8 id=8192
[2015⑴0⑵0 14:58:00.630][INF] [SendCommandWithRecv] this=0xf115e8, cmd_id=0x2000, cmd=0x10010
[2015⑴0⑵0 14:58:00.631][DBG] MainStream 0xf0
[2015⑴0⑵0 14:58:00.631][INF] SubStream 0x0, RTP/RTSP[0], Private and RTSP[0], streamPacketType[0x0]
[2015⑴0⑵0 14:58:00.631][INF] [CloseCommandConnection] this=0xf115e8, cmd_id=0x2000
[2015⑴0⑵0 14:58:00.631][INF] StopLinkInConnection sock=496 this=0xf115e8, command=0x10010
[2015⑴0⑵0 14:58:00.636][INF] LogonDev1 192.168.3.22:8000 out, dev_ver=020220090317, protocol=0xf0f0 sn=DS2CD852MF-E0020100721BCCH401124400WC
[2015⑴0⑵0 14:58:00.636][INF] [UserCtrlInstance::AddUser] m_nCurrentUserIndex=0, i=0, m_nTotalUserNum=1
[2015⑴0⑵0 14:58:00.636][INF] Login success. UserID=0, DevIP=192.168.3.22
[2015⑴0⑵0 14:58:02.095][DBG] BaseEngine[class CNetPreviewSession / 1 / 1]::AllocSession[0] get instance[00F177C0]
[2015⑴0⑵0 14:58:02.095][INF] Preview Session=0 channel[1], UserID[0]
[2015⑴0⑵0 14:58:02.095][DBG] [0] userid[0] this[f177c0]PreviewStart in block[0] cbreal[13018cf]stand[0] userdatap[0] dw[0], hwnd[1905a2]
[2015⑴0⑵0 14:58:02.095][INF] StreamMode[0], StreamProtocol[0xf0f0]
[2015⑴0⑵0 14:58:02.095][DBG] [0] PreviewStart out
[2015⑴0⑵0 14:58:02.095][DBG] [0][192.168.3.22:8000]preview LinkToDvr
[2015⑴0⑵0 14:58:02.095][INF] StreamMode[0], StreamProtocol[0xf0f0]
[2015⑴0⑵0 14:58:02.125][ERR] GlobalCtrl load [E:Herbert Project单个摄像机解码并显示DebugStreamTransClient.dll] with sdk path failed and get handle[0]
[2015⑴0⑵0 14:58:02.129][ERR] Load StreamTransClient failed[syserr: 126]
[2015⑴0⑵0 14:58:02.129][ERR] Preview Session=0 link proto=4
[2015⑴0⑵0 14:58:02.129][ERR] [0] preview MainPreview link failed!!!
[2015⑴0⑵0 14:58:02.129][DBG] userid[0] Preview[0] AysoNonBlockThread callback exception
[2015⑴0⑵0 14:58:09.918][INF] [0]PreviewStop begin
[2015⑴0⑵0 14:58:09.918][DBG] [0] NetPreview SessionStop in, player nPort[⑴]
[2015⑴0⑵0 14:58:09.918][ERR] (IExchangeProxy::RigisterCommandIndex)this preview[0] is not registered.
[2015⑴0⑵0 14:58:09.918][DBG] [0] NetPreview SessionStop out
[2015⑴0⑵0 14:58:09.918][DBG] BaseEngine[class CNetPreviewSession / 512 / 1 / 1]::DestroySessionByIndex[0] instance[00F177C0]
[2015⑴0⑵0 14:58:12.274][DBG] FiniSDK begin SDK fini[1]
[2015⑴0⑵0 14:58:12.274][DBG] [0] DelUser CurrentUserIndex ⑴ total[0]
[2015⑴0⑵0 14:58:13.135][DBG] stop time thread

后面的操作就很简单了,在海康的SDK库文件中找到StreamTransClient.dll和SystemTransform.dll并添加到工程项目底下,问题解决。

3. 项目部份代码

上传时发现文件过大,因此只贴出部份代码:

// SingleCamDlg.cpp : 实现文件 // #include “stdafx.h” #include “SingleCamApp.h” #include “SingleCamDlg.h” #include “afxdialogex.h” #include “HCNetSDK.h” #include “plaympeg4.h” #ifdef _DEBUG #define new DEBUG_NEW #endif // CSingleCamDlg 对话框 LONG nPort = –1;
HWND hPlayWnd = NULL;//播放句柄 LONG lUserID = –1;
LONG lRealHandle = –1;
CString IPToStr(DWORD dwIP); void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2); void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser);
CSingleCamDlg::CSingleCamDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CSingleCamDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CSingleCamDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_CAM_IP, m_ctrlDeviceIP);//界面网址控件与类变量绑定 }
BEGIN_MESSAGE_MAP(CSingleCamDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_Login, &CSingleCamDlg::OnBnClickedBtnLogin)
ON_BN_CLICKED(IDC_BTN_PlayCam, &CSingleCamDlg::OnBnClickedBtnPlaycam)
ON_BN_CLICKED(IDC_BTN_StopCam, &CSingleCamDlg::OnBnClickedBtnStopcam)
END_MESSAGE_MAP()
BOOL CSingleCamDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 设置此对话框的图标。当利用程序主窗口不是对话框时,框架将自动 // 履行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 //此处需要对SDK进行init初始化 NET_DVR_Init();
isLogin = FALSE;
isPlaying = FALSE;
hPlayWnd = GetDlgItem(IDC_ViewWindow)->m_hWnd; //在程序初始化的时候就获得播放窗口的句柄 m_ctrlDeviceIP.SetAddress(192, 168, 2, 21);
GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(FALSE); //初始状态,播放和停止按钮都是失能的 GetDlgItem(IDC_BTN_StopCam)->EnableWindow(FALSE); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CSingleCamDlg::OnPaint()
{ if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的装备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect); int x = (rect.Width() – cxIcon + 1) / 2; int y = (rect.Height() – cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon);
} else {
CDialogEx::OnPaint();
}
}
HCURSOR CSingleCamDlg::OnQueryDragIcon()
{ return static_cast(m_hIcon);
} /////////////////////////////全局函数的定义/////////////////////// CString IPToStr(DWORD dwIP)
{
CString strIP = _T(“”);
WORD add1,add2,add3,add4;
add1=(WORD)(dwIP&255);
add2=(WORD)((dwIP>>8)&255);
add3=(WORD)((dwIP>>16)&255);
add4=(WORD)((dwIP>>24)&255);
strIP.Format(“%d.%d.%d.%d”,add4,add3,add2,add1); return strIP;
} void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser)
{ switch (dwDataType)
{ case NET_DVR_SYSHEAD: //系统头 if (!PlayM4_GetPort(&nPort)) //获得播放库未使用的通道号 { break;
} //m_iPort = lPort; //第1次回调的是系统头,将获得的播放库port号赋值给全局port,下次回调数据时即便用此port号播放 if (dwBufSize > 0)
{ if (!PlayM4_SetStreamOpenMode(nPort, STREAME_REALTIME)) //设置实时流播放模式 { break;
} if (!PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024*1024)) //打开流接口 { break;
} //设置解码回调函数 只解码不显示 //if (!PlayM4_SetDecCallBack(lPort,DecCBFun)) //{ // //dRet=PlayM4_GetLastError(nPort); // break; //} //设置解码回调函数 解码且显示在窗口句柄中 if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))
{ break;
} if (!PlayM4_SetDisplayBuf(nPort, 4))//设置缓冲区大小,2⑸ { break;
} if (!PlayM4_Play(nPort,hPlayWnd)) //播放开始 { break;
}
} case NET_DVR_STREAMDATA: //码流数据 if (dwBufSize > 0 && nPort != –1) if (!PlayM4_InputData(nPort, pBuffer, dwBufSize)) break;
}
} void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
{
} //////////////////////////////////////////////////////////////// void CSingleCamDlg::OnBnClickedBtnLogin()//登录 { if (isLogin) //如果已登录,就需要履行注销 {
NET_DVR_Logout(lUserID);
isLogin = FALSE;
GetDlgItem(IDC_BTN_Login)->SetWindowTextA(“登录”);
GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(FALSE); //播放按钮 失效 } else { char DeviceIP[16] = {0};
DWORD dwDeviceIP = 0;
m_ctrlDeviceIP.GetAddress(dwDeviceIP);
CString csTemp = IPToStr(dwDeviceIP);
sprintf_s(DeviceIP, “%s”, csTemp.GetBuffer(0));
NET_DVR_DEVICEINFO_V30 struDeviceInfo;
lUserID = NET_DVR_Login_V30(DeviceIP, 8000, “admin”, “12345”, &struDeviceInfo); if (lUserID < 0) //登录失败时,其他几个按钮都需要disable {
AfxMessageBox(“登录失败!”);
isLogin = FALSE;
} else {
isLogin = TRUE;
GetDlgItem(IDC_BTN_Login)->SetWindowTextA(“注销”); //登录成功, 变成注销 GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(TRUE); //播放按钮 有效 }
}
} void CSingleCamDlg::OnBnClickedBtnPlaycam() //播放 {
NET_DVR_PREVIEWINFO struPlayInfo = {0};
struPlayInfo.hPlayWnd = NULL; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空 struPlayInfo.lChannel = 1; //预览通道号 struPlayInfo.dwStreamType = 0; //0-主码流,1-子码流,2-码流3,3-码流4,以此类推 struPlayInfo.dwLinkMode = 0; //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP lRealHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL); if (lRealHandle < 0)
{
AfxMessageBox(“播放失败!”);
isPlaying = FALSE;//播放标志位设置为假 } else {
GetDlgItem(IDC_BTN_Login)->EnableWindow(FALSE); //登录按钮失效 GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(FALSE); //播放按钮失效 GetDlgItem(IDC_BTN_StopCam)->EnableWindow(TRUE); //停止按钮 有效 isPlaying = TRUE;
}
} void CSingleCamDlg::OnBnClickedBtnStopcam()//停止 {
NET_DVR_StopRealPlay(lRealHandle); //释放播放库资源 PlayM4_Stop(nPort);
PlayM4_CloseStream(nPort);
PlayM4_FreePort(nPort);
GetDlgItem(IDC_BTN_Login)->EnableWindow(TRUE); //登录按钮失效 GetDlgItem(IDC_BTN_PlayCam)->EnableWindow(TRUE); //播放按钮 有效 GetDlgItem(IDC_BTN_StopCam)->EnableWindow(FALSE); //停止按钮 失效 }
波比源码 – 精品源码模版分享 | www.bobi11.com
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

波比源码 » 部分海康网络摄像头无法实现视频流解码与实时预览

发表评论

Hi, 如果你对这款模板有疑问,可以跟我联系哦!

联系站长
赞助VIP 享更多特权,建议使用 QQ 登录
喜欢我嘛?喜欢就按“ctrl+D”收藏我吧!♡