海康威视的摄像头非常常见。官网提供了的SDK。今天拿来一用,并且成功解码出视频流每一帧的图片了。
代码见github: cmPlayer

登录以及设备的注册

user = new NET_DVR_USER_LOGIN_INFO;
user->bUseAsynLogin = 0;
strncpy(user->sDeviceAddress, uinfo.ip.toStdString().c_str(),NET_DVR_DEV_ADDRESS_MAX_LEN);
user->wPort = uinfo.port;
strncpy(user->sUserName, uinfo.name.toStdString().c_str(),NET_DVR_LOGIN_USERNAME_MAX_LEN);
strncpy(user->sPassword, uinfo.password.toStdString().c_str(),NET_DVR_LOGIN_PASSWD_MAX_LEN);
NET_DVR_SetConnectTime(2000, 1);
NET_DVR_SetReconnect(10000, true);
NET_DVR_SetExceptionCallBack_V30(0, NULL,hkExceptionCallBack, NULL);
device = new NET_DVR_DEVICEINFO_V40;
lUserID = NET_DVR_Login_V40(user, device);

视频实时预览

NET_DVR_PREVIEWINFO struPlayInfo = {0};
struPlayInfo.hPlayWnd = (HWND)winId();
struPlayInfo.lChannel = device->struDeviceV30.byStartChan;
struPlayInfo.byPreviewMode = 0;
struPlayInfo.dwStreamType = 0;
struPlayInfo.dwLinkMode =4; //0- TCP 方式,1- UDP 方式,2- 多播方式,3- RTP 方式,4-RTP/RTSP,5-RSTP/HTTP
struPlayInfo.bBlocked = 0; //0- 非阻塞取流,1- 阻塞取流
lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, hkRealDataCallBack, NULL);

颜色空间转换

这里处理的就是每一帧的图片了。

static void CALLBACK DecCBFun(int nPort,char * pBuf,int nSize,FRAME_INFO * pFrameInfo, void* nReserved1,int nReserved2)
{
// qDebug("TYPE:%d-[%d*%d]",pFrameInfo->nType,pFrameInfo->nWidth,pFrameInfo->nHeight);
switch (pFrameInfo->nType) {
case T_YV12:
{
cv::Mat dst(pFrameInfo->nHeight,pFrameInfo->nWidth,CV_8UC3);
cv::Mat src(pFrameInfo->nHeight + pFrameInfo->nHeight/2,pFrameInfo->nWidth,CV_8UC1,(uchar*)pBuf);
cv::cvtColor(src,dst,CV_YUV2BGR_YV12);
updateImage(dst);
}
break;
case T_AUDIO8:
case T_AUDIO16:
break;
default:
break;
}
}