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());