将他的MFC工程相关的代码抠出来,重组。于是实现了捕获YV12格式的视频流的功能,光有YV12还是不行的,需要将YV12转成YUV4:4:4的,然后再将YUV色度空间转换成RGB色度空间,这个过程是在信件的DecBFun回调函数里面执行的。

#include <cstdio>
#include <cstring>
#include <iostream>
#include "Windows.h"
#include "HCNetSDK.h"
#include "PlayM4.h"
#include <opencv2\opencv.hpp>
#include "cv.h"
#include "highgui.h"
#include <time.h>
#define USECOLOR 1
using namespace std;
using namespace std;//--------------------------------------------
int iPicNum=0;//Set channel NO.
LONG nPort=-1;
HWND hWnd=NULL;void yv12toYUV(char *outYuv, char *inYv12, int width, int height,int widthStep)
{int col,row;unsigned int Y,U,V;int tmp;int idx;//printf("widthStep=%d.\n",widthStep);for (row=0; row<height; row++){idx=row * widthStep;int rowptr=row*width;for (col=0; col<width; col++){//int colhalf=col>>1;tmp = (row/2)*(width/2)+(col/2);
//         if((row==1)&&( col>=1400 &&col<=1600))
//         {
//          printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
//          printf("row*width+col=%d,width*height+width*height/4+tmp=%d,width*height+tmp=%d.\n",row*width+col,width*height+width*height/4+tmp,width*height+tmp);
//         } Y=(unsigned int) inYv12[row*width+col];U=(unsigned int) inYv12[width*height+width*height/4+tmp];V=(unsigned int) inYv12[width*height+tmp];
//         if ((col==200))
//         {
//         printf("col=%d,row=%d,width=%d,tmp=%d.\n",col,row,width,tmp);
//         printf("width*height+width*height/4+tmp=%d.\n",width*height+width*height/4+tmp);
//         return ;
//         }if((idx+col*3+2)> (1200 * widthStep)){//printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);} outYuv[idx+col*3]   = Y;outYuv[idx+col*3+1] = U;outYuv[idx+col*3+2] = V;}}//printf("col=%d,row=%d.\n",col,row);
}//解码回调 视频为YUV数据(YV12),音频为PCM数据
void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
{long lFrameType = pFrameInfo->nType;   if(lFrameType ==T_YV12){
#if USECOLOR//int start = clock();IplImage* pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);//得到图像的Y分量  yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth,pFrameInfo->nHeight,pImgYCrCb->widthStep);//得到全部RGB图像IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);  cvCvtColor(pImgYCrCb,pImg,CV_YCrCb2RGB);  //int end = clock();
#elseIplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 1);  memcpy(pImg->imageData,pBuf,pFrameInfo->nWidth*pFrameInfo->nHeight);
#endif//printf("%d\n",end-start);cvShowImage("IPCamera",pImg);cvWaitKey(1);
#if USECOLORcvReleaseImage(&pImgYCrCb);cvReleaseImage(&pImg);
#elsecvReleaseImage(&pImg);
#endif//此时是YV12格式的视频数据,保存在pBuf中,可以fwrite(pBuf,nSize,1,Videofile);//fwrite(pBuf,nSize,1,fp);}/***************else if (lFrameType ==T_AUDIO16){//此时是音频数据,数据保存在pBuf中,可以fwrite(pBuf,nSize,1,Audiofile);}else{}*******************/}///实时流回调
void CALLBACK fRealDataCallBack(LONG lRealHandle,DWORD dwDataType,BYTE *pBuffer,DWORD dwBufSize,void *pUser)
{DWORD dRet;switch (dwDataType){case NET_DVR_SYSHEAD:    //系统头if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号{break;}if(dwBufSize > 0){if (!PlayM4_OpenStream(nPort,pBuffer,dwBufSize,1024*1024)){dRet=PlayM4_GetLastError(nPort);break;}//设置解码回调函数 只解码不显示if (!PlayM4_SetDecCallBack(nPort,DecCBFun)){dRet=PlayM4_GetLastError(nPort);break;}//设置解码回调函数 解码且显示//if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL))//{//    dRet=PlayM4_GetLastError(nPort);// break;//}//打开视频解码if (!PlayM4_Play(nPort,hWnd)){dRet=PlayM4_GetLastError(nPort);break;}//打开音频解码, 需要码流是复合流if (!PlayM4_PlaySound(nPort)){dRet=PlayM4_GetLastError(nPort);break;}     }break;case NET_DVR_STREAMDATA:   //码流数据if (dwBufSize > 0 && nPort != -1){BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);while (!inData){Sleep(10);inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);OutputDebugString(L"PlayM4_InputData failed \n");    }}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 main() {//---------------------------------------// 初始化NET_DVR_Init();//设置连接时间与重连时间NET_DVR_SetConnectTime(2000, 1);NET_DVR_SetReconnect(10000, true);//---------------------------------------// 获取控制台窗口句柄//HMODULE hKernel32 = GetModuleHandle((LPCWSTR)"kernel32");//GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32,"GetConsoleWindow");//---------------------------------------// 注册设备LONG lUserID;NET_DVR_DEVICEINFO_V30 struDeviceInfo;lUserID = NET_DVR_Login_V30("10.102.7.88", 8000, "admin", "12345", &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);//cvNamedWindow("IPCamera");//---------------------------------------//启动预览并设置回调数据流 NET_DVR_CLIENTINFO ClientInfo;ClientInfo.lChannel = 1;        //Channel number 设备通道号ClientInfo.hPlayWnd = NULL;     //窗口为空,设备SDK不解码只取流ClientInfo.lLinkMode = 0;       //Main StreamClientInfo.sMultiCastIP = NULL;LONG lRealPlayHandle;lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID,&ClientInfo,fRealDataCallBack,NULL,TRUE);if (lRealPlayHandle<0){printf("NET_DVR_RealPlay_V30 failed! Error number: %d\n",NET_DVR_GetLastError());return;}//cvWaitKey(0);Sleep(-1);//fclose(fp);//---------------------------------------//关闭预览if(!NET_DVR_StopRealPlay(lRealPlayHandle)){printf("NET_DVR_StopRealPlay error! Error number: %d\n",NET_DVR_GetLastError());return;}//注销用户NET_DVR_Logout(lUserID);NET_DVR_Cleanup();return;
}

海康威视IPCamera图像捕获方法:捕获实时流,将实时流解码成YV12,然后转换成RGB相关推荐

  1. 海康威视IPCamera图像捕获 二种方法

    所使用海康威视摄像头型号:DS-2CD4026FWD-(A)(P) 海康威视IPCamera图像捕获方法有两种: (1)利用SDK里面的NET_DVR_CaptureJPEGPicture_NEW进行 ...

  2. 捕获海康威视IPCamera图像,转成OpenCV能够处理的图像(二)

    海康威视IPCamera图像捕获 捕获海康威视IPCamera图像.转成OpenCV能够处理的IplImage图像(一) 捕获海康威视IPCamera图像.转成OpenCV能够处理的IplImage图 ...

  3. 捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(二)

    捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(二) 标签: 捕获图像海康威视IPCameraOpenCVIplImage 2014-06-16 18:59 15424人阅读 评论( ...

  4. 捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(一)

    海康威视IPCamera图像捕获 捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图像(一) 捕获海康威视IPCamera图像,转成OpenCV可以处理的IplImage图 ...

  5. gbq6的文件能转换成gbq5_PPT文件转换成PDF怎么转?这些方法能实现快速转换

    PPT文件转换成PDF怎么转?我们在工作中经常会用到PPT幻灯片,很多PPT在使用过后也会转换成PDF格式文件再进行存档备份.PPT文件要怎么操作才能转换成PDF文件呢?如果文件数量很多,一份一份的转 ...

  6. badatatable转成json_C# DataTable 转换成JSON数据 三种方法

    在web开发中,我们可能会有这样的需求,为了便于前台的JS的处理,我们需要将查询出的数据源格式比如:List.DataTable转换为Json格式.特别在使用Extjs框架的时候,Ajax异步请求的数 ...

  7. et文件怎么转成excel_excel怎么转换成word格式的文件格式?这些方法应该掌握!...

    制作数据调查表的时候,不仅要有数据统计图,还要有文字总结,和调查结果等.但是直接将excel表格复制到word文档,完全行不通,乱码现象都没眼看.但我们也不能否定"复制"这一方法, ...

  8. ceb怎么转换成word_pdf怎么转换成Word?分享PDF转word3种方法!

    pdf怎么转换成Word?在工作中,我常常需要将写好的一份文件或者合同以PDF格式保存起来,然后发给对方,这样接收方就可以直接打印了.但是如果PDF文档需要修改的话,我们还得将PDF转为Word.今天 ...

  9. vue字符串转换成int_js 字符串转换成数字的三种方法

    方法主要有三种 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有 ...

最新文章

  1. vector、map删除当前记录
  2. 用nero刻录视频文件的时候不能添加文件
  3. CodeForces - 1220D Alex and Julian(思维+数论)
  4. ip转换软件在五八上能用吗?_交换机能当路由器用吗?浅谈交换器和路由器的区别...
  5. WPF 绘制对齐像素的清晰显示的线条
  6. 漫画:什么是机器学习
  7. JDK下载地址、SecureCRT中JDK安装和环境配置、SecureCRT窗口编程、linux下命令运行小程序
  8. mongodb 去重查询 Java,mongodb篇二:mongodb克隆远程数据库,去重查询的命令及对应java语句...
  9. mysql下载安装教程win7_win7系统安装MySQL软件的详细步骤
  10. Extjs window组件 拖动统制
  11. Citrix 整体架构 端口列表 Tcp Port
  12. Azkaban流2.0
  13. JNI中,getBytes()最好指明UTF-8
  14. 协议--SIP/SDP
  15. 毕业设计总结篇之终结篇——基于android的创意展示平台(混合app)
  16. python----小计买书问题
  17. Jugglefest
  18. 如何批量生成JAN13条码
  19. 毕业设计之路(6)——uip
  20. GitHub SSH设置与Permission denied问题解决方法

热门文章

  1. MySQL复合索引(联合索引)原理分析及使用
  2. 大二物竞金牌转北大计算机,靠竞赛进入清北的学生,都能选哪些专业?| 2019竞赛优惠专业分析...
  3. 3D引擎优化方法整理
  4. Twincat 3 初识
  5. 转载:Openssl生成rsa和椭圆曲线加密公钥密钥创建根ca签名https服务器证书签名...
  6. ENVI中出现tif文件无法直接打开
  7. Nullpoint及其相关的报错
  8. JAVA水晶报表从环境搭建到创建动态水晶报表
  9. 动力电池罗生门:“无钴”的一张大网
  10. 优质的计算机专业书籍有哪些?