0 简介
Linux中使用海康相机sdk预览抓图,使用c++、QT
1 导入海康SDK、头文件
1.1 linux
在pro文件中添加如下,导入sdk库。(要将海康的库原封不动的复制)
linux-*{LIBS+=-lhcnetsdk-lPlayCtrl-lAudioRender-lSuperRender}在头文件中包含头文件
#ifdefWIN32#include"hcnetsdk/win32/include/HCNetSDK.h"#include"hcnetsdk/win32/include/PlayM4.h"#else#include"hcnetsdk/linux64/include/HCNetSDK.h"#include"hcnetsdk/linux64/include/PlayM4.h"#endif2 新建类
类对象中新建
private:intuserIdM;NET_DVR_DEVICEINFO deviceInfoM;intplayHandleM;LONG realPlayPortM;boolisStartDecodingPlay;| 变量名 | 含义 |
|---|---|
| userIdM | 海康相机的句柄 |
| deviceInfoM | 海康相机的设备信息 |
| playHandleM | 海康相机的预览句柄 |
| realPlayPortM | 实时预览的播放库通道号 |
| isStartDecodingPlay | 判断是否开始播放 |
3 登录
登录相机
intHkCameraMedia::login(QString ipAddrP,QString portP,QString userNameP,QString passwordP){interror=NET_DVR_NOERROR;QByteArrayipAddr(ipAddrP.toLatin1());QByteArrayuserName(userNameP.toLatin1());QByteArraypassword(passwordP.toLatin1());char*pszIpAddr=ipAddr.data();char*pszUserName=userName.data();char*pszPassowrd=password.data();unsignedshortport=portP.toUShort();qDebug()<<"{"<<ipAddrP<<"}"<<"HkCameraMedia::login() BEGIN, ipAddrP: "<<pszIpAddr<<", portP: "<<port<<", userNameP: "<<pszUserName<<", passwordP: "<<pszPassowrd;do{if(false==NET_DVR_Init()){qDebug()<<"["<<ipAddrP<<"]"<<"HkCameraMedia::login(), failed to call NET_DVR_Init";error=NET_DVR_GetLastError();break;}if(false==NET_DVR_SetConnectTime(2000,0xFFFFFFFF)){qDebug()<<"["<<ipAddrP<<"]"<<"HkCameraMedia::login(), failed to call NET_DVR_SetConnectTime";error=NET_DVR_GetLastError();break;}if(false==NET_DVR_SetReconnect(10000)){qDebug()<<"["<<ipAddrP<<"]"<<"HkCameraMedia::login(), failed to call NET_DVR_SetReconnect";error=NET_DVR_GetLastError();break;}if(false==NET_DVR_SetExceptionCallBack_V30(0,NULL,NULL,NULL)){qDebug()<<"["<<ipAddrP<<"]"<<"HkCameraMedia::login(), failed to call NET_DVR_SetExceptionCallBack_V30";error=NET_DVR_GetLastError();break;}userIdM=NET_DVR_Login(pszIpAddr,port,pszUserName,pszPassowrd,&deviceInfoM);if(userIdM<0){error=NET_DVR_GetLastError();qDebug()<<"["<<ipAddrP<<"]"<<"CameraMedia::connect(), failed to connect to camera, ip:"<<ipAddrP<<",username: "<<userNameP<<", password: "<<passwordP<<", port: "<<portP<<", error code: "<<error;}}while(false);returnerror;}voidHkCameraMedia::logout(){if(userIdM>=0){NET_DVR_Logout(userIdM);NET_DVR_Cleanup();userIdM=-1;}}4 开始预览
4.1 开始预览时,直接传入回调函数
NET_DVR_RealPlay_V40(userId, &struPlayInfo, fRealDataCallBackOfCapture, this);
boolHkCameraMedia::startPreview(WId hPlayWndP,int&playHandlerP){boolretVal=false;intuserId=getUserId();qDebug()<<"HkCameraMedia::startPreview() BEGIN";do{// Q_ASSERT(hPlayWndP != 0);NET_DVR_PREVIEWINFO struPlayInfo;memset(&struPlayInfo,0,sizeof(struPlayInfo));struPlayInfo.hPlayWnd=(HWND)hPlayWndP;//需要 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/HTTPstruPlayInfo.bBlocked=1;//0- 非阻塞取流,1- 阻塞取流playHandlerP=NET_DVR_RealPlay_V40(userId,&struPlayInfo,fRealDataCallBackOfCapture,this);retVal=(playHandlerP>=0)?true:false;if(retVal==false){LONG errorNo=NET_DVR_NOERROR;char*pszErrorMsg=NET_DVR_GetErrorMsg(&errorNo);qCritical()<<"HkCameraMedia::startPreview(), errorNo: "<<errorNo<<", error msg: "<<pszErrorMsg;}setPlayHandle(playHandlerP);}while(false);qDebug()<<"HkCameraMedia::startPreview() END, retVal: "<<retVal;returnretVal;}4.2 回调函数
///////////////////////////////realplay capture ////////////////////////////////////voidCALLBACKfRealDataCallBackOfCapture(__attribute__((unused))LONG lRealHandle,DWORD dwDataType,BYTE*pBuffer,DWORD dwBufSize,void*pUser){DWORD dRet=0;switch(dwDataType){caseNET_DVR_SYSHEAD:if(((HkCameraMedia*)pUser)->realPlayPortM>=0){break;//同一路码流不需要多次调用开流接口}if(!PlayM4_GetPort(&((HkCameraMedia*)pUser)->realPlayPortM)){break;}if(!PlayM4_OpenStream(((HkCameraMedia*)pUser)->realPlayPortM,pBuffer,dwBufSize,1024*1024)){dRet=PlayM4_GetLastError(((HkCameraMedia*)pUser)->realPlayPortM);qDebug("HkCameraMedia::fRealDataCallBackOfCapture PlayM4_OpenStream return error:%d",dRet);break;}//设置显示回调if(!PlayM4_SetDisplayCallBack(((HkCameraMedia*)pUser)->realPlayPortM,NULL)){dRet=PlayM4_GetLastError(((HkCameraMedia*)pUser)->realPlayPortM);qDebug("HkCameraMedia::fRealDataCallBackOfCapture PlayM4_SetDisplayCallBack return error:%d",dRet);break;}//开始解码播放if(!PlayM4_Play(((HkCameraMedia*)pUser)->realPlayPortM,0)){dRet=PlayM4_GetLastError(((HkCameraMedia*)pUser)->realPlayPortM);qDebug("HkCameraMedia::fRealDataCallBackOfCapture PlayM4_Play return error:%d",dRet);break;}((HkCameraMedia*)pUser)->isStartDecodingPlay=true;break;caseNET_DVR_STREAMDATA:PlayM4_InputData(((HkCameraMedia*)pUser)->realPlayPortM,pBuffer,dwBufSize);break;default:break;}return;}5 开始预览采图
intHkCameraMedia::realPlayCapture(QString pathP){if(!isPlaying(deviceInfoM.byStartChan)&&!startPreview(WId(NULL),playHandleM)){returnNET_DVR_ORDER_ERROR;}if(realPlayPortM<0||!isStartDecodingPlay){qDebug()<<"HkCameraMedia::realPlayCapture() Not open real play port or not start decoding play!";returnNET_DVR_ORDER_ERROR;}//获取当前视频文件的分辨率BOOL bFlag=FALSE;LONG dwWidth=0;LONG dwHeight=0;bFlag=PlayM4_GetPictureSize(realPlayPortM,&dwWidth,&dwHeight);if(bFlag==FALSE){qDebug()<<"HkCameraMedia::realPlayCapture() PlayM4_GetPictureSize error:"<<PlayM4_GetLastError(realPlayPortM);returnNET_DVR_ORDER_ERROR;}DWORD dwSize=dwWidth*dwHeight*5;std::unique_ptr<BYTE[]>capBuf(newBYTE[dwSize]);if(nullptr==capBuf){qDebug()<<"HkCameraMedia::realPlayCapture() New capture buffer fail!";returnNET_DVR_ORDER_ERROR;}DWORD dwCapSize=0;bFlag=PlayM4_GetJPEG(realPlayPortM,capBuf.get(),dwSize,&dwCapSize);if(bFlag==FALSE){qDebug()<<"HkCameraMedia::realPlayCapture() PlayM4_GetBMP error:"<<PlayM4_GetLastError(realPlayPortM);returnNET_DVR_ORDER_ERROR;}QFilefile(pathP);if(!file.open(QIODevice::WriteOnly)){qDebug()<<"HkCameraMedia::realPlayCapture() fopen fail!";returnNET_DVR_ORDER_ERROR;}qint64 bytesWritten=file.write(reinterpret_cast<constchar*>(capBuf.get()),dwSize);if(bytesWritten==-1){qDebug()<<"HkCameraMedia::realPlayCapture() Write picture fail!";returnNET_DVR_ORDER_ERROR;}returnNET_DVR_NOERROR;}boolHkCameraMedia::isPlaying(intiChannlID){Q_UNUSED(iChannlID);returnplayHandleM>=0;}6 停止预览
boolHkCameraMedia::stopPreview(int&rPlayHandlerP){boolretVal=false;qDebug()<<"HkCameraMedia::stopPreview() BEGIN";if(realPlayPortM<0){qDebug()<<"HkCameraMedia::stopPreview() Not start preview, no need stop.";returntrue;}retVal=NET_DVR_StopRealPlay(rPlayHandlerP);if(retVal==false){LONG errorNo=NET_DVR_NOERROR;char*pszErrorMsg=NET_DVR_GetErrorMsg(&errorNo);qCritical()<<"HkCameraMedia::stopPreview(), errorNo: "<<errorNo<<", error msg: "<<pszErrorMsg;}//停止解码if(!PlayM4_Stop(rPlayHandlerP)){qDebug("PlayM4_Stop error:%d",PlayM4_GetLastError(rPlayHandlerP));}if(!PlayM4_CloseStream(rPlayHandlerP)){qDebug("PlayM4_CloseStream error:%d",PlayM4_GetLastError(rPlayHandlerP));}PlayM4_FreePort(rPlayHandlerP);rPlayHandlerP=-1;setPlayHandle(rPlayHandlerP);qDebug()<<"HkCameraMedia::stopPreview() END, retVal: "<<retVal;returnretVal;}