diff --git a/.DS_Store b/.DS_Store index 93a78cb2..6906a6c6 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.cproject b/.cproject index 4285f08a..324cecf6 100644 --- a/.cproject +++ b/.cproject @@ -7,10 +7,13 @@ + + + @@ -77,12 +80,15 @@ + + + @@ -155,10 +161,13 @@ + + + diff --git a/test/DeviceHK.cpp b/test/DeviceHK.cpp new file mode 100644 index 00000000..b8e93a5c --- /dev/null +++ b/test/DeviceHK.cpp @@ -0,0 +1,248 @@ +/* + * DeviceHK.cpp + * + * Created on: 2016年8月10日 + * Author: xzl + */ +#ifdef ENABLE_HKDEVICE +#include "DeviceHK.h" +#include "Util/TimeTicker.h" +#include "Util/MD5.h" +namespace ZL { +namespace DEV { + +#define HK_APP_NAME "live" + +DeviceHK::DeviceHK() { + InfoL << endl; + static onceToken token( []() { + NET_DVR_Init(); + NET_DVR_SetDVRMessageCallBack_V31([](LONG lCommand,NET_DVR_ALARMER *pAlarmer,char *pAlarmInfo,DWORD dwBufLen,void* pUser){ + WarnL< hkLoginCB; + loginInfo.bUseAsynLogin = TRUE; + weak_ptr weakSelf = shared_from_this(); + loginInfo.pUser = new hkLoginCB([weakSelf,cb](LONG lUserID, DWORD dwResult, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo ) { + //TraceL<sSerialNumber; + connectResult result; + if(dwResult==TRUE) { + result.strDevName=(char *)(lpDeviceInfo->sSerialNumber); + result.ui16ChnStart=lpDeviceInfo->byStartChan; + result.ui16ChnCount=lpDeviceInfo->byChanNum; + auto _strongSelf=weakSelf.lock(); + if(_strongSelf) { + auto strongSelf=dynamic_pointer_cast(_strongSelf); + strongSelf->onConnected(lUserID,lpDeviceInfo); + } + } else { + WarnL<<"connect deviceHK failed:"<(pUser); + (*fun)(lUserID,dwResult,lpDeviceInfo); + delete fun; + }; + NET_DVR_SetConnectTime(iTimeOut * 1000, 3); + NET_DVR_Login_V40(&loginInfo, &loginResult); +} + +void DeviceHK::disconnect(const relustCB& cb) { + m_mapChannels.clear(); + if (m_i64LoginId >= 0) { + NET_DVR_Logout(m_i64LoginId); + m_i64LoginId = -1; + Device::onDisconnected(true); + } + +} + +void DeviceHK::addChannel(int iChn, bool bMainStream) { + DevChannel::Ptr channel( new DevChannelHK(m_i64LoginId, (char *) m_deviceInfo.sSerialNumber, iChn, bMainStream)); + m_mapChannels[iChn] = channel; +} + +void DeviceHK::delChannel(int chn) { + m_mapChannels.erase(chn); +} + +void DeviceHK::onConnected(LONG lUserID, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo) { + m_i64LoginId = lUserID; + m_deviceInfo = *lpDeviceInfo; + Device::onConnected(); +} + +void DeviceHK::addAllChannel(bool bMainStream) { + InfoL << endl; + for (int i = 0; i < m_deviceInfo.byChanNum; i++) { + addChannel(m_deviceInfo.byStartChan + i, bMainStream); + } +} + +DevChannelHK::DevChannelHK(int64_t i64LoginId, const char* pcDevName, int iChn, bool bMainStream) : + DevChannel(HK_APP_NAME,(StrPrinter<(pUser); + if(self->m_i64PreviewHandle!=(int64_t)lPlayHandle) { + return; + } + self->onPreview(dwDataType,pBuffer,dwBufSize); + }, this); + if (m_i64PreviewHandle == -1) { + throw std::runtime_error( StrPrinter << "设备[" << pcDevName << "/" << iChn << "]开始实时预览失败:" + << NET_DVR_GetLastError() << endl); + } +} + +DevChannelHK::~DevChannelHK() { + InfoL << endl; + if (m_i64PreviewHandle >= 0) { + NET_DVR_StopRealPlay(m_i64PreviewHandle); + m_i64PreviewHandle = -1; + } + if (m_iPlayHandle >= 0) { + PlayM4_StopSoundShare(m_iPlayHandle); + PlayM4_Stop(m_iPlayHandle); + m_iPlayHandle = -1; + } +} + +void DevChannelHK::onPreview(DWORD dwDataType, BYTE* pBuffer, DWORD dwBufSize) { + //TimeTicker1(-1); + switch (dwDataType) { + case NET_DVR_SYSHEAD: { //系统头数据 + if (!PlayM4_GetPort(&m_iPlayHandle)) { //获取播放库未使用的通道号 + WarnL << "PlayM4_GetPort:" << NET_DVR_GetLastError(); + break; + } + if (dwBufSize > 0) { + if (!PlayM4_SetStreamOpenMode(m_iPlayHandle, STREAME_REALTIME)) { //设置实时流播放模式 + WarnL << "PlayM4_SetStreamOpenMode:" << NET_DVR_GetLastError(); + break; + } + if (!PlayM4_OpenStream(m_iPlayHandle, pBuffer, dwBufSize, + 1024 * 1024)) { //打开流接口 + WarnL << "PlayM4_OpenStream:" << NET_DVR_GetLastError(); + break; + } + + PlayM4_SetDecCallBackMend(m_iPlayHandle, + [](int nPort,char * pBuf,int nSize,FRAME_INFO * pFrameInfo, void* nUser,int nReserved2) { + DevChannelHK *chn=reinterpret_cast(nUser); + if(chn->m_iPlayHandle!=nPort) { + return; + } + chn->onGetDecData(pBuf,nSize,pFrameInfo); + }, this); + if (!PlayM4_Play(m_iPlayHandle, 0)) { //播放开始 + WarnL << "PlayM4_Play:" << NET_DVR_GetLastError(); + break; + } + InfoL << "设置解码器成功!" << endl; + //打开音频解码, 需要码流是复合流 + if (!PlayM4_PlaySoundShare(m_iPlayHandle)) { + WarnL << "PlayM4_PlaySound:" << NET_DVR_GetLastError(); + break; + } + } + } + break; + case NET_DVR_STREAMDATA: { //流数据(包括复合流或音视频分开的视频流数据) + if (dwBufSize > 0 && m_iPlayHandle != -1) { + if (!PlayM4_InputData(m_iPlayHandle, pBuffer, dwBufSize)) { + WarnL << "PlayM4_InputData:" << NET_DVR_GetLastError(); + break; + } + } + } + break; + case NET_DVR_AUDIOSTREAMDATA: { //音频数据 + } + break; + case NET_DVR_PRIVATE_DATA: { //私有数据,包括智能信息 + } + break; + default: + break; + } +} + +void DevChannelHK::onGetDecData(char* pBuf, int nSize, FRAME_INFO* pFrameInfo) { + //InfoL << pFrameInfo->nType; + switch (pFrameInfo->nType) { + case T_YV12: { + if (!m_bVideoSeted) { + m_bVideoSeted = true; + VideoInfo video; + video.iWidth = pFrameInfo->nWidth; + video.iHeight = pFrameInfo->nHeight; + video.iFrameRate = pFrameInfo->nFrameRate; + initVideo(video); + } + char *yuv[3]; + int yuv_len[3]; + yuv_len[0] = pFrameInfo->nWidth; + yuv_len[1] = pFrameInfo->nWidth / 2; + yuv_len[2] = pFrameInfo->nWidth / 2; + int dwOffset_Y = pFrameInfo->nWidth * pFrameInfo->nHeight; + yuv[0] = pBuf; + yuv[2] = yuv[0] + dwOffset_Y; + yuv[1] = yuv[2] + dwOffset_Y / 4; + inputYUV(yuv, yuv_len, pFrameInfo->nStamp); + } + break; + case T_AUDIO16: { + if (!m_bAudioSeted) { + m_bAudioSeted = true; + AudioInfo audio; + audio.iChannel = pFrameInfo->nWidth; + audio.iSampleBit = pFrameInfo->nHeight; + audio.iSampleRate = pFrameInfo->nFrameRate; + initAudio(audio); + } + inputPCM(pBuf, nSize, pFrameInfo->nStamp); + } + break; + default: + break; + } +} + +} /* namespace DEV */ +} /* namespace ZL */ + +#endif //ENABLE_HKDEVICE diff --git a/test/DeviceHK.h b/test/DeviceHK.h new file mode 100644 index 00000000..235bbe7b --- /dev/null +++ b/test/DeviceHK.h @@ -0,0 +1,117 @@ +/* + * DeviceHK.h + * + * Created on: 2016年8月10日 + * Author: xzl + */ + +#ifndef DEVICE_DEVICEHK_H_ +#define DEVICE_DEVICEHK_H_ + +#include +#include "HCNetSDK.h" +#include "PlayM4.h" +#include "Device/Device.h" +#include "Util/onceToken.h" +#include "Util/logger.h" +#include "Util/TimeTicker.h" + +using namespace ZL::Util; + +namespace ZL { +namespace DEV { + +class connectInfo { +public: + connectInfo(const char *_strDevIp, + uint16_t _ui16DevPort, + const char *_strUserName, + const char *_strPwd) { + strDevIp = _strDevIp; + ui16DevPort = _ui16DevPort; + strUserName = _strUserName; + strPwd = _strPwd; + } + string strDevIp; + uint16_t ui16DevPort; + string strUserName; + string strPwd; +}; + +class connectResult { +public: + string strDevName; + uint16_t ui16ChnStart; + uint16_t ui16ChnCount; +}; + +typedef function connectCB; +typedef function relustCB; + +class Device: public enable_shared_from_this { +public: + typedef std::shared_ptr Ptr; + Device() { + } + virtual ~Device(){ disconnect([](bool bSuccess){ + });}; + + virtual void connectDevice(const connectInfo &info, const connectCB &cb, int iTimeOut = 3)=0; + + virtual void disconnect(const relustCB &cb) { + } + + virtual void addChannel(int iChnIndex, bool bMainStream = true)=0; + + virtual void delChannel(int iChnIndex)=0; + + virtual void addAllChannel(bool bMainStream = true)=0; + +protected: + void onConnected() { + } + void onDisconnected(bool bSelfDisconnect) { + } + +}; + + +class DevChannelHK; +class DeviceHK: public Device { +public: + typedef std::shared_ptr Ptr; + DeviceHK(); + virtual ~DeviceHK(); + + void connectDevice(const connectInfo &info, const connectCB &cb, int iTimeOut = 3) override; + void disconnect(const relustCB &cb) override; + + void addChannel(int iChnIndex, bool bMainStream = true) override; + void delChannel(int iChnIndex) override; + void addAllChannel(bool bMainStream = true) override; +private: + map > m_mapChannels; + int64_t m_i64LoginId = -1; + NET_DVR_DEVICEINFO_V30 m_deviceInfo; + void onConnected(LONG lUserID, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo); +}; + +class DevChannelHK: public DevChannel { +public: + typedef std::shared_ptr Ptr; + DevChannelHK(int64_t i64LoginId, const char *pcDevName, int iChn, bool bMainStream = true); + virtual ~DevChannelHK(); +protected: + int64_t m_i64LoginId = -1; + int64_t m_i64PreviewHandle = -1; + int m_iPlayHandle = -1; + void onPreview(DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize); + void onGetDecData(char * pBuf, int nSize, FRAME_INFO * pFrameInfo); + bool m_bVideoSeted = false; + bool m_bAudioSeted = false; +}; + +} /* namespace DEV */ +} /* namespace ZL */ + +#endif /* DEVICE_DEVICEHK_H_ */ diff --git a/test.cpp b/test/test.cpp similarity index 84% rename from test.cpp rename to test/test.cpp index 9acb2ab5..eef8f62c 100644 --- a/test.cpp +++ b/test/test.cpp @@ -20,6 +20,9 @@ #include "Http/HttpSession.h" #include "Http/HttpsSession.h" #include "Util/SSLBox.h" +#ifdef ENABLE_HKDEVICE +#include "test/DeviceHK.h" +#endif //ENABLE_HKDEVICE using namespace std; using namespace ZL::Util; @@ -37,6 +40,16 @@ int main(int argc,char *argv[]){ Logger::Instance().add(std::make_shared("stdout", LTrace)); Logger::Instance().setWriter(std::make_shared()); + +#ifdef ENABLE_HKDEVICE + DeviceHK::Ptr dev(new DeviceHK()); + dev->connectDevice( connectInfo("192.168.0.211", 8000, "admin", "password"), [dev](bool success,const connectResult &result) { + if(success) { + dev->addAllChannel(); + } + }); +#endif //ENABLE_HKDEVICE + SSL_Initor::Instance().loadServerPem((exeDir() + ".HttpServer.pem").data()); TcpServer::Ptr rtspSrv(new TcpServer());