海康设备获取YV12图像

概要:

准备:

海康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看到的图像如下图所示:

参考代码:

注: 在使用下面代码时,配置项部分,需要略微修改。

[plain] view
plain
copy

  1. #include <iostream>
  2. #include "Windows.h"
  3. #include <DataType.h>
  4. #include <DecodeCardSdk.h>
  5. #include "HCNetSDK.h"
  6. #include "plaympeg4.h"
  7. #include <time.h>
  8. #include <ProcessFun.h>
  9. #include <HKRequest.h>
  10. #include <H264Decoder.h>
  11. using namespace std;
  12. typedef HWND (WINAPI *PROCGETCONSOLEWINDOW)();
  13. PROCGETCONSOLEWINDOW ConsoleWindow;
  14. LONG lPort=-1; //全局的播放库port号
  15. HWND hWnd ;
  16. static char HK_Addr[100]  ;
  17. static int  HK_Port  ;
  18. static char HK_USR[100]  ;
  19. static char HK_PASSWORD[100]  ;
  20. static int  HK_PreViewChannel ;
  21. void Fprintf_Binary(const char * Path,char* buf,int Len,const char* Mode)
  22. {
  23. FILE * pFile;
  24. // Mode binary "wb" binary append "ab+"
  25. pFile = fopen (Path, Mode);
  26. fwrite (buf , sizeof(char), Len, pFile);
  27. fclose (pFile);
  28. }
  29. //////////////////////////////////////////////////////////////////////////
  30. ////解码回调
  31. void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
  32. {
  33. //printf("            @@@@Calling DecCBFun!\n");
  34. long lFrameType = pFrameInfo->nType;
  35. if (lFrameType ==T_AUDIO16)
  36. {
  37. //printf("Audio nStamp:%d\n",pFrameInfo->nStamp);
  38. }
  39. else if(lFrameType ==T_YV12)
  40. {
  41. //printf("Video nStamp:%d\n",pFrameInfo->nStamp);
  42. //Fprintf_Binary("HK.yuv",pBuf,nSize,"ab+");
  43. if(!CheckShmOccupy(SHM_OCCUPY_BY_HK)){
  44. memcpy(g_shm_addr[VIDEO_CHANNEL_0]+SHM_OFFSET,pBuf,nSize);
  45. SetSHM_Ready(g_shm_addr[VIDEO_CHANNEL_0],SHM_IMG_READY_BIT,SHM_IMG_STATUS_READY);
  46. }
  47. }
  48. else
  49. {
  50. }
  51. }
  52. void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer,DWORD dwBufSize,void* dwUser)
  53. {
  54. hWnd = GetConsoleWindow();
  55. static int count =0 ;
  56. //printf("RealDataCallBack %d !\n",count++);
  57. switch (dwDataType)
  58. {
  59. case NET_DVR_SYSHEAD: //系统头
  60. printf("                        NET_DVR_SYSHEAD\n");
  61. if (!PlayM4_GetPort(&lPort)) //获取播放库未使用的通道号
  62. {
  63. break;
  64. }
  65. //m_iPort = lPort;
  66. //第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放
  67. if (dwBufSize > 0)
  68. {
  69. if (!PlayM4_SetStreamOpenMode(lPort, STREAME_REALTIME)) //设置实时流播放模式
  70. {
  71. printf("PlayM4_SetStreamOpenMode Error\n");
  72. break;
  73. }
  74. if (!PlayM4_OpenStream(lPort, pBuffer, dwBufSize, 1024*1024)) //打开流接口
  75. {
  76. printf("PlayM4_OpenStream Error\n");
  77. break;
  78. }
  79. //////////////////////////////////////////////////////////////////////////
  80. ///设置解码回调函数
  81. if (!PlayM4_SetDecCallBackMend(lPort,DecCBFun,(long)dwUser))
  82. //if (!PlayM4_SetDecCallBack(lPort,DecCBFun))
  83. {
  84. printf("Decode CallBack Set Error!\n");
  85. PlayM4_GetLastError(lPort);
  86. break;
  87. }
  88. else{
  89. printf("DecCallBack Set OK!!!\n");
  90. }
  91. if (!PlayM4_Play(lPort, hWnd)) //播放开始
  92. {
  93. printf("PlayM4_Play Error\n");
  94. break;
  95. }
  96. }
  97. break;
  98. case NET_DVR_STREAMDATA: //码流数据
  99. //printf("    NET_DVR_STREAMDATA\n");
  100. if (dwBufSize > 0 && lPort != -1)
  101. {
  102. if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
  103. {
  104. break;
  105. }
  106. }
  107. break;
  108. default: //其他数据
  109. printf("        OTHERS\n");
  110. if (dwBufSize > 0 && lPort != -1)
  111. {
  112. if (!PlayM4_InputData(lPort, pBuffer, dwBufSize))
  113. {
  114. break;
  115. }
  116. }
  117. break;
  118. }
  119. }
  120. void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
  121. {
  122. char tempbuf[256] = {0};
  123. switch(dwType)
  124. {
  125. case EXCEPTION_RECONNECT: //预览时重连
  126. printf("----------reconnect--------%d\n", time(NULL));
  127. break;
  128. default:
  129. break;
  130. }
  131. }
  132. void LoadConfiguration()
  133. {
  134. char ConfigVal[100] ;
  135. // HK Width  and Height
  136. if(GetConfigVal("CenDVCGenConfig.ini","HK_WIDTH",ConfigVal,"GettingHKWidth","GettingHKWidthError!!!\n")){
  137. HK_RAW_VIDEO_WIDTH = atoi(ConfigVal);
  138. }else{
  139. printf("Loading HK Configuration Width Error!!!\n");
  140. exit(-1);
  141. }
  142. if(GetConfigVal("CenDVCGenConfig.ini","HK_HEIGHT",ConfigVal,"GettingHKHeight","GettingHKHeightError!!!\n")){
  143. HK_RAW_VIDEO_HEIGHT = atoi(ConfigVal);
  144. }else{
  145. printf("Loading HK Configuration Height Error!!!\n");
  146. exit(-1);
  147. }
  148. // Addr and Port
  149. if(GetConfigVal("CenDVCGenConfig.ini","HK_Addr",ConfigVal,"GettingHK_Addr","GettingHK_AddrError!!!\n")){
  150. strcpy(HK_Addr,ConfigVal);
  151. }else{
  152. printf("Loading HK Configuration HK_Addr Error!!!\n");
  153. exit(-1);
  154. }
  155. if(GetConfigVal("CenDVCGenConfig.ini","HK_Port",ConfigVal,"GettingHK_Port","GettingHK_PortError!!!\n")){
  156. HK_Port = atoi(ConfigVal);
  157. }else{
  158. printf("Loading HK Configuration HK_Port Error!!!\n");
  159. exit(-1);
  160. }
  161. //USR  and Password
  162. if(GetConfigVal("CenDVCGenConfig.ini","HK_USR",ConfigVal,"GettingHK_USR","GettingHK_USRError!!!\n")){
  163. strcpy(HK_USR,ConfigVal);
  164. }else{
  165. printf("Loading HK Configuration HK_USR Error!!!\n");
  166. exit(-1);
  167. }
  168. if(GetConfigVal("CenDVCGenConfig.ini","HK_PASSWORD",ConfigVal,"GettingHK_PASSWORD","GettingHK_PASSWORDError!!!\n")){
  169. strcpy(HK_PASSWORD,ConfigVal);
  170. }else{
  171. printf("Loading HK Configuration HK_PASSWORD Error!!!\n");
  172. exit(-1);
  173. }
  174. //PreviewChannel
  175. if(GetConfigVal("CenDVCGenConfig.ini","HK_PreViewChannel",ConfigVal,"GettingHK_PreViewChannel","GettingHK_PreViewChannelError!!!\n")){
  176. HK_PreViewChannel = atoi(ConfigVal);
  177. }else{
  178. printf("Loading HK Configuration HK_PreViewChannel Error!!!\n");
  179. exit(-1);
  180. }
  181. }
  182. void main() {
  183. // 初始化
  184. LoadConfiguration();
  185. InitSys();
  186. NET_DVR_Init();
  187. //设置连接时间与重连时间
  188. NET_DVR_SetConnectTime(2000, 1);
  189. NET_DVR_SetReconnect(10000, true);
  190. //---------------------------------------
  191. // 获取控制台窗口句柄
  192. //HMODULE hKernel32 = GetModuleHandle("kernel32");
  193. //GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
  194. HMODULE hKernel32 = GetModuleHandle("kernel32");
  195. ConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");
  196. //---------------------------------------
  197. // 注册设备
  198. LONG lUserID;
  199. NET_DVR_DEVICEINFO_V30 struDeviceInfo;
  200. //lUserID = NET_DVR_Login_V30("172.16.1.251", 8000, "admin", "12345", &struDeviceInfo);
  201. //lUserID = NET_DVR_Login_V30("192.168.4.237", 8000, "admin", "12345", &struDeviceInfo);
  202. lUserID = NET_DVR_Login_V30(HK_Addr,HK_Port, HK_USR,HK_PASSWORD, &struDeviceInfo);
  203. if (lUserID < 0)
  204. {
  205. printf("Login error, %d\n", NET_DVR_GetLastError());
  206. NET_DVR_Cleanup();
  207. return;
  208. }
  209. //---------------------------------------
  210. //设置异常消息回调函数
  211. NET_DVR_SetExceptionCallBack_V30(0, NULL,g_ExceptionCallBack, NULL);
  212. //---------------------------------------
  213. //启动预览并设置回调数据流
  214. LONG lRealPlayHandle;
  215. NET_DVR_PREVIEWINFO struPlayInfo = {0};
  216. struPlayInfo.hPlayWnd = hWnd; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
  217. //struPlayInfo.hPlayWnd = 0; //需要SDK解码时句柄设为有效值,仅取流不解码时可设为空
  218. struPlayInfo.lChannel = HK_PreViewChannel; //预览通道号
  219. struPlayInfo.dwStreamType = 0; //0-主码流,1-子码流,2-码流3,3-码流4,以此类推
  220. struPlayInfo.dwLinkMode = 0; //0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
  221. struPlayInfo.bBlocked = 0; //0- 非阻塞取流,1- 阻塞取流
  222. unsigned long lpdwVideoStandard;
  223. //bool ret = NET_DVR_MatrixGetVideoStandard(lUserID, struPlayInfo.lChannel,&lpdwVideoStandard );
  224. //DWORD error = NET_DVR_GetLastError();
  225. lRealPlayHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, g_RealDataCallBack_V30, NULL);
  226. if (lRealPlayHandle < 0)
  227. {
  228. printf("NET_DVR_RealPlay_V40 error\n");
  229. NET_DVR_Logout(lUserID);
  230. NET_DVR_Cleanup();
  231. return;
  232. }
  233. while(1)
  234. Sleep(10000);
  235. //---------------------------------------
  236. //关闭预览
  237. NET_DVR_StopRealPlay(lRealPlayHandle);
  238. //注销用户
  239. NET_DVR_Logout(lUserID);
  240. NET_DVR_Cleanup();
  241. return;
  242. }

参考文章:http://blog.csdn.net/gubenpeiyuan/article/details/24346125

时间: 2024-08-28 20:20:51

海康设备获取YV12图像的相关文章

海康API——获取监控点预览取流URL,获取的rtmp流不能播放

取rtmp流时,不要expand这一句 原文地址:https://www.cnblogs.com/nana-qiu/p/12120519.html

java实现海康NVR/DVR设备工作状态获取

该功能需要到JNA的知识. 通过查阅海康设备网络SDK编程指南(DVR&NVR)可以知道海康SDK的调用方法都要同过如下过程: 虚线框的流程是可选部分,不会影响其他流程和模块的功能使用.具体的模块说明可以自行参考SDK开发文件. 主要功能代码: 测试例子,因此虚线部分功能不实现 1.初始化设备SDK:对整个网络SDK 系统的初始化,内存预分配等操作. 代码:HCNetSDK sdk = HCNetSDK.INSTANCE;    sdk.NET_DVR_Init();//返回booleaan值

海康SDK编程指南(C#二次开发版本)

海康SDK编程指南 目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息.本文仅对视频监控常用功能的使用进行说明,其它未实现功能请参看设备网络SDK使用手册和播放库编程指南V7.2. IPC_SDK编程指南 (一)    SDK的引用 由于IPC_SDK没有SDK安装程序,所以需手工把下面图表中的DLL放入Debug或者Release文件夹的根目录下供程序调用,或者加入系统环

海康摄像头配置固定IP

前言 首先要海康设备连接好网线,电脑客户端跟海康设备在同一个局域网络. 1.直接在海康网站下载SADP工具软件,安装SADP工具,如图所示: 2.安装成功后,桌面的出现设备网络搜索, 面板介绍:这里将SADP软件打开的面板分为两部分,在①号区域,主要显示设备的一些基本信息.包括型号,激活状态,IP地址,端口号等. ①号区域 激活状态 未激活:设备需要激活设置8-16位数字和字母组合的密码才可以使用,勾选编号前的小框,②号区域会弹出激活界面. 已激活:设备已有密码.如果不知道需要密码重置. 端口

海康视频下载,以及实时视频预览

一,前言 公司一项目需要拿到海康刻录机里面某时间段的视频去刻录.遇到问题第一时间看官网有么有demo可以套用,哎,一言难尽,打开官网看到文档后,感觉长得不像,就没继续看了,不知道怎么弄的我,迷茫着在网上找答案,网上这方面的资料也少的厉害.最终还是硬着头皮把官网上的看着像的全下载了,终于找到了自己想要目标 二,下载 官网文档 https://www.hikvision.com/cn/download_61.html 请根据需要下载,这里我下载的是 设备网络SDK_Win64 : 三,整理成项目并运

Java实现 海康摄像头抓拍图像

先抱怨一下,打死都想不到,海康的摄像头SDK居然是一个Java类,还有必须的两个jar包(jna.jar,examples.jar).鬼能想得到会这么命名. 下面开始吧. 把从官网下载的SDK(和当前系统对应)解压,把库文件整个拷贝到某个目录(我是D:\hik\lib),然后把D:\hik\lib和D:\hik\lib\HCNetSDKCom加入到系统环境变量path中.可以尝试从代码中把这两个文件夹加入path,我没有试成功. 项目引入jna.jar和examples.jar这两个jar包.注

(转)从海康7816的ps流里获取数据h264数据

海康7816使用ps流来封装h.264数据,这里使用的解码器无法识别ps流,因此需要将h264数据从ps流里提取出来 对于ps流的规定可以参考13818-1文档 这里从7816里获取到一些数据取样 00 00 01 BA 44 73 26 B8 34 01 00 00 03 FE FF FF 00 00 00 0100 00 01 BC00 5A E0 FF 00 24 40 0E 48 4B 00 01 0D AF C5 D3 E0 07 FF FF FF FF 41 12 48 4B 00

海康网络摄像机调用SDK解码Java版

两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.dll interface PlayCtrl extends StdCallLibrary { PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("lib\\PlayCtrl", PlayCtrl.class); public static

[rtsp]海康IPC监控摄像头远程外网监控配置(DDNS)

本来这个DDNS服务正是我想要的,但是配置了之后海康提示不再提供这个服务了,以后统一使用萤石云了,看来有必要去学习下萤石开放平台的api,看都提供哪些服务. 海康威视网络摄像机出厂的默认IP地址:为192.0.0.64.需要将IPC的IP地址设置为和电脑在同一网段. 1.    使用摄像机IP地址搜索软件: 1.可以使用官方提供的专用SADP软件,下载链接如下:http://www.hikvision.com/Cn/download_more.asp?cid=140011#Menu=ChildM