标签:海康
概要:
海康威视是目前中国领先的监控产品供应商,在我们很多项目中需要使用到他的产品;所以接入他的流变得很有必要。本文记录了如何接入海康威视的SDK,并获私有码流,随后得到NV12序列。本文出自CSDN-固本培元。转载注明出处,交流邮箱:leoluopy@gmail.com。
准备:
海康SDK的下载地址:我下载的win64的。根据你自己的需求下载吧。
http://www.hikvision.com/cn/download_more_570.html
这里笔者还推荐一个很有用的海康的客户端软件:
http://www.hikvision.com/cn/download_more_390.html
4200/4000在DVS配置以及DVS密码丢失后可以起到很大帮助作用。(笔者对DVS的开发是接手以前一个同事的工作,密码丢失了,如果你的密码也忘记了的话,可以这样获取,有的DVS拆开后也同样没有复位键,通过将设备的序列号给售后后,他给你一个超级密码,用这个超级密码通过这个客户端就可以重置密码了。)
sdk下载后有一个clientDemo可以直接运行。通过它就可以预览和检测DVS的运行状态了。细节不用说了,很简单。
然后就是他官网文档的一些标志调用过程和示例代码需要看看,逼着推荐看这个:
设备网络SDK编程指南(DVR).pdf
其中有一节:预览模块的示例代码 好好看看就可以很好完成本文叙述的主题。
注意事项:
如果仅仅有如下dll库,编译和运行时都不会报错,但是解码回调会直接没有反应,坑爹啊。所以必须加上其他的dll库
加上所有的dll库后如下图所示了。所以以后不要自作聪明,直接减去个人觉得没有用的dll库了。。分析原因:回调的函数实体在运行时需要调用。不过,个人觉得正常情况下应报错才对啊。
最后通过海康SDK获取到的IYUV位图数据通过yuvviewer看到的图像如下图所示:
参考代码:
注: 在使用下面代码时,配置项部分,需要略微修改。
-
#include <iostream>
-
#include "Windows.h"
-
#include <DataType.h>
-
#include <DecodeCardSdk.h>
-
#include "HCNetSDK.h"
-
#include "plaympeg4.h"
-
#include <time.h>
-
-
#include <ProcessFun.h>
-
#include <HKRequest.h>
-
-
#include <H264Decoder.h>
-
-
using namespace std;
-
-
-
typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
-
PROCGETCONSOLEWINDOW ConsoleWindow;
-
-
LONG lPort=-1; //全局的播放库port号
-
HWND hWnd ;
-
-
-
-
static char HK_Addr[100] ;
-
static int HK_Port ;
-
static char HK_USR[100] ;
-
static char HK_PASSWORD[100] ;
-
static int HK_PreViewChannel ;
-
-
-
void Fprintf_Binary(const char * Path,char* buf,int Len,const char* Mode)
-
{
-
FILE * pFile;
-
// Mode binary "wb" binary append "ab+"
-
pFile = fopen (Path, Mode);
-
-
fwrite (buf , sizeof(char), Len, pFile);
-
-
fclose (pFile);
-
}
-
//////////////////////////////////////////////////////////////////////////
-
////解码回调
-
void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
-
{
-
//printf(" @@@@Calling DecCBFun!\n");
-
long lFrameType = pFrameInfo->nType;
-
if (lFrameType ==T_AUDIO16)
-
{
-
//printf("Audio nStamp:%d\n",pFrameInfo->nStamp);
-
}
-
else if(lFrameType ==T_YV12)
-
{
-
//printf("Video nStamp:%d\n",pFrameInfo->nStamp);
-
-
//Fprintf_Binary("HK.yuv",pBuf,nSize,"ab+");
-
if(!CheckShmOccupy(SHM_OCCUPY_BY_HK)){
-
memcpy(g_shm_addr[VIDEO_CHANNEL_0]+SHM_OFFSET,pBuf,nSize);
-
SetSHM_Ready(g_shm_addr[VIDEO_CHANNEL_0],SHM_IMG_READY_BIT,SHM_IMG_STATUS_READY);
-
}
-
}
-
else
-
{
-
-
}
-
}
-
-
void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser)
-
{
-
hWnd = GetConsoleWindow();
-
static int count =0 ;
-
-
//printf("RealDataCallBack %d !\n",count++);
-
-
switch (dwDataType)
-
{
-
case NET_DVR_SYSHEAD: //系统头
-
printf(" NET_DVR_SYSHEAD\n");
-
if (!PlayM4_GetPort(&lPort)) //获取播放库未使用的通道号
-
{
-
break;
-
}
-
//m_iPort = lPort;
-
//第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放
-
if (dwBufSize > 0)
-
{
-
if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) //设置实时流播放模式
-
{
-
printf("PlayM4_SetStreamOpenMode Error\n");
-
break;
-
}
-
if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024)) //打开流接口
-
{
-
printf("PlayM4_OpenStream Error\n");
-
break;
-
}
-
//////////////////////////////////////////////////////////////////////////
-
///设置解码回调函数
-
if (!PlayM4_SetDecCallBackMend(lPort,DecCBFun,(long)dwUser))
-
//if (!PlayM4_SetDecCallBack(lPort,DecCBFun))
-
{
-
printf("Decode CallBack Set Error!\n");
-
PlayM4_GetLastError(lPort);
-
break;
-
}
-
else{
-
printf("DecCallBack Set OK!!!\n");
-
}
-
if (!PlayM4_Play(lPort, hWnd)) //播放开始
-
{
-
printf("PlayM4_Play Error\n");
-
break;
-
}
-
}
-
break;
-
case NET_DVR_STREAMDATA: //码流数据
-
//printf(" NET_DVR_STREAMDATA\n");
-
if (dwBufSize > 0 && lPort != -1)
-
{
-
if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
-
{
-
break;
-
}
-
}
-
break;
-
default: //其他数据
-
printf(" OTHERS\n");
-
if (dwBufSize > 0 && lPort != -1)
-
{
-
if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
-
{
-
break;
-
}
-
}
-
break;
-
}
-
}
-
void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
-
{
-
char tempbuf[256] = {0};
-
switch(dwType)
-
{
-
case EXCEPTION_RECONNECT: //预览时重连
-
printf("----------reconnect--------%d\n", time(NULL));
-
break;
-
default:
-
break;
-
}
-
}
-
void LoadConfiguration()
-
{
-
char ConfigVal[100] ;
-
-
// HK Width and Height
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_WIDTH",ConfigVal,"GettingHKWidth","GettingHKWidthError!!!\n")){
-
HK_RAW_VIDEO_WIDTH = atoi(ConfigVal);
-
}else{
-
printf("Loading HK Configuration Width Error!!!\n");
-
exit(-1);
-
}
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_HEIGHT",ConfigVal,"GettingHKHeight","GettingHKHeightError!!!\n")){
-
HK_RAW_VIDEO_HEIGHT = atoi(ConfigVal);
-
}else{
-
printf("Loading HK Configuration Height Error!!!\n");
-
exit(-1);
-
}
-
-
// Addr and Port
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_Addr",ConfigVal,"GettingHK_Addr","GettingHK_AddrError!!!\n")){
-
strcpy(HK_Addr,ConfigVal);
-
}else{
-
printf("Loading HK Configuration HK_Addr Error!!!\n");
-
exit(-1);
-
}
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_Port",ConfigVal,"GettingHK_Port","GettingHK_PortError!!!\n")){
-
HK_Port = atoi(ConfigVal);
-
}else{
-
printf("Loading HK Configuration HK_Port Error!!!\n");
-
exit(-1);
-
}
-
-
//USR and Password
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_USR",ConfigVal,"GettingHK_USR","GettingHK_USRError!!!\n")){
-
strcpy(HK_USR,ConfigVal);
-
}else{
-
printf("Loading HK Configuration HK_USR Error!!!\n");
-
exit(-1);
-
}
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_PASSWORD",ConfigVal,"GettingHK_PASSWORD","GettingHK_PASSWORDError!!!\n")){
-
strcpy(HK_PASSWORD,ConfigVal);
-
}else{
-
printf("Loading HK Configuration HK_PASSWORD Error!!!\n");
-
exit(-1);
-
}
-
-
//PreviewChannel
-
if(GetConfigVal("CenDVCGenConfig.ini","HK_PreViewChannel",ConfigVal,"GettingHK_PreViewChannel","GettingHK_PreViewChannelError!!!\n")){
-
HK_PreViewChannel = atoi(ConfigVal);
-
}else{
-
printf("Loading HK Configuration HK_PreViewChannel Error!!!\n");
-
exit(-1);
-
}
-
-
-
}
-
void main() {
-
// 初始化
-
-
LoadConfiguration();
-
InitSys();
-
NET_DVR_Init();
-
//设置连接时间与重连时间
-
NET_DVR_SetConnectTime(2000, 1);
-
NET_DVR_SetReconnect(10000, true);
-
-
//---------------------------------------
-
// 获取控制台窗口句柄
-
//HMODULE hKernel32 = GetModuleHandle("kernel32");
-
//GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
-
HMODULE hKernel32 = GetModuleHandle("kernel32");
-
ConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
-
-
-
//---------------------------------------
-
// 注册设备
-
LONG lUserID;
-
NET_DVR_DEVICEINFO_V30 struDeviceInfo;
-
//lUserID = NET_DVR_Login_V30("172.16.1.251", 8000, "admin", "12345", &struDeviceInfo);
-
//lUserID = NET_DVR_Login_V30("192.168.4.237", 8000, "admin", "12345", &struDeviceInfo);
-
lUserID = NET_DVR_Login_V30(HK_Addr,HK_Port, HK_USR,HK_PASSWORD, &struDeviceInfo);
-
if (lUserID < 0)
-
{
-
printf("Login error, %d\n", NET_DVR_GetLastError());
-
NET_DVR_Cleanup();
-
return;
-
}
-
//---------------------------------------
-
//设置异常消息回调函数
-
NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);
-
//---------------------------------------
-
//启动预览并设置回调数据流
-
LONG lRealPlayHandle;
-
NET_DVR_PREVIEWINFO struPlayInfo = {0};
-
struPlayInfo.hPlayWnd = hWnd; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
-
//struPlayInfo.hPlayWnd = 0; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
-
struPlayInfo.lChannel = HK_PreViewChannel; //预览通道号
-
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
-
struPlayInfo.bBlocked = 0; //0- 非阻塞取流,1- 阻塞取流
-
-
unsigned long lpdwVideoStandard;
-
-
//bool ret = NET_DVR_MatrixGetVideoStandard(lUserID, struPlayInfo.lChannel,&lpdwVideoStandard );
-
//DWORD error = NET_DVR_GetLastError();
-
-
lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);
-
-
-
-
if (lRealPlayHandle < 0)
-
{
-
printf("NET_DVR_RealPlay_V40 error\n");
-
NET_DVR_Logout(lUserID);
-
NET_DVR_Cleanup();
-
return;
-
}
-
while(1)
-
Sleep(10000);
-
-
//---------------------------------------
-
//关闭预览
-
NET_DVR_StopRealPlay(lRealPlayHandle);
-
//注销用户
-
NET_DVR_Logout(lUserID);
-
NET_DVR_Cleanup();
-
return;
-
}
参考文章:http://blog.csdn.net/gubenpeiyuan/article/details/24346125
海康设备获取YV12图像
标签:海康
原文地址:http://blog.csdn.net/zhouyongku/article/details/45691391