ubuntu环境使用海康威视SDK获取视频流
#include <stdio.h>
#include <sys/time.h>
#include <chrono>
#include <opencv2/opencv.hpp>
#include <unistd.h>
#include <errno.h>
#include "HCNetSDK.h"
#include "iniFile.h"
#include "PlayM4.h"
//解码回调 视频为YUV数据(YV12),音频为PCM数据
void CALLBACK G_DecCBFun(int nPort, char * pBuf, int nSize, FRAME_INFO * pFrameInfo, void* nReserved1, int nReserved2)
{
// std::cout << "****************" << std::endl;
long lFrameType = pFrameInfo->nType;
if (lFrameType == T_YV12)
{
cv::Mat pImg(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3);
cv::Mat src(pFrameInfo->nHeight + pFrameInfo->nHeight / 2, pFrameInfo->nWidth, CV_8UC1, pBuf);
cv::cvtColor(src, pImg, cv::COLOR_YUV2BGR_YV12);
cv::Mat img = pImg.clone();
cv::resize(img, img, cv::Size(0, 0), 0.5, 0.5);
cv::imshow("image", img);
cv::waitKey(10);
}
}
LONG G_nPort = -1;
void PsDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pPacketBuffer, DWORD nPacketSize, void* pUser)
{
switch (dwDataType)
{
case NET_DVR_SYSHEAD: //系统头
if (!PlayM4_GetPort(&G_nPort)) //获取播放库未使用的通道号
{
break;
}
//m_iPort = lPort; //第一次回调的是系统头,将获取的播放库port号赋值给全局port,下次回调数据时即使用此port号播放
if (nPacketSize > 0)
{
if (!PlayM4_SetStreamOpenMode(G_nPort, STREAME_REALTIME)) //设置实时流播放模式
{
break;
}
if (!PlayM4_OpenStream(G_nPort, pPacketBuffer, nPacketSize, 10 * 1024 * 1024)) //打开流接口
{
break;
}
if (!PlayM4_Play(G_nPort, NULL)) //播放开始
{
break;
}
if (!PlayM4_SetDecCallBack(G_nPort, G_DecCBFun))
{
break;
}
}
break;
case NET_DVR_STREAMDATA: //码流数据
if (nPacketSize > 0 && G_nPort != -1)
{
if (!PlayM4_InputData(G_nPort, pPacketBuffer, nPacketSize))
{
// std::cout << "error" << PlayM4_GetLastError(G_nPort) << std::endl;
break;
}
}
break;
default: //其他数据
if (nPacketSize > 0 && G_nPort != -1)
{
if (!PlayM4_InputData(G_nPort, pPacketBuffer, nPacketSize))
{
break;
}
}
break;
}
}
void GetStream()
{
std::vector<std::string> paths;
paths.push_back("../config/Device.ini"); // 配置信息
for(int k=0; k<1; k++)
{
// 从配置文件读取设备信息
IniFile ini(paths.at(k).c_str());
unsigned int dwSize = 0;
char sSection[16] = "DEVICE";
char *sIP = ini.readstring(sSection, "ip", "error", dwSize);
int iPort = ini.readinteger(sSection, "port", 0);
char *sUserName = ini.readstring(sSection, "username", "error", dwSize);
char *sPassword = ini.readstring(sSection, "password", "error", dwSize);
int iChannel = ini.readinteger(sSection, "channel", 0);
NET_DVR_DEVICEINFO_V30 struDeviceInfo;
int iUserID = NET_DVR_Login_V30(sIP, iPort, sUserName, sPassword, &struDeviceInfo);
std::cout << iUserID << std::endl;
if(iUserID >= 0)
{
NET_DVR_PREVIEWINFO struPreviewInfo = {0};
struPreviewInfo.lChannel =iChannel;
struPreviewInfo.dwStreamType = 0;
struPreviewInfo.dwLinkMode = 0;
struPreviewInfo.bBlocked = 1;
struPreviewInfo.bPassbackRecord = 1;
LONG nPort = -1;
int iRealPlayHandle = NET_DVR_RealPlay_V40(iUserID, &struPreviewInfo, PsDataCallBack, &nPort);
if(iRealPlayHandle >= 0)
{
printf("[GetStream]---RealPlay %s:%d success, \n", sIP, iChannel, NET_DVR_GetLastError());
}
else
{
printf("[GetStream]---RealPlay %s:%d failed, error = %d\n", sIP, iChannel, NET_DVR_GetLastError());
}
}
else
{
printf("[GetStream]---Login %s failed, error = %d\n", sIP, NET_DVR_GetLastError());
}
}
}
int main()
{
NET_DVR_Init();
GetStream();
char c = 0;
while('q' != c)
{
printf("input 'q' to quit\n");
printf("input: ");
scanf("%c", &c);
}
NET_DVR_Cleanup();
return 0;
}