#include "stdafx.h" #include "Fast.h" #include "PlayWnd.h" #include "PtzScreen.h" #include "DrawImage.h" #include "ImageCalibrator.h" #include "dhplay.h" //#include "RealPlayAndPTZControlDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define LOGIN_TIMER 1 ///////////////////////////////////////////////////////////////////////////// // CPlayWnd dialog CPlayWnd::CPlayWnd():m_nWndID(0), m_FlagRect(FALSE),bIsPlaying(false) { //{{AFX_DATA_INIT(CPlayWnd) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_nIndex = 0; m_nPlayPort = 0; //cv::namewindow("fsf"); } BEGIN_MESSAGE_MAP(CPlayWnd, CWnd) //{{AFX_MSG_MAP(CPlayWnd) ON_WM_ERASEBKGND() ON_WM_CONTEXTMENU() ON_WM_LBUTTONDOWN() ON_WM_MBUTTONUP() ON_WM_MOUSEMOVE() ON_WM_ACTIVATE() ON_WM_CREATE() ON_WM_TIMER() ON_WM_ACTIVATEAPP() //}}AFX_MSG_MAP ON_COMMAND_RANGE(VIDEO_MENU_BASE, VIDEO_MENU_END, OnVideoMenu) ON_MESSAGE(VIDEO_REPAINT, OnRepaintWnd) //}}AFX_MSG_MAP ON_WM_CREATE() END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPlayWnd message handlers BOOL CPlayWnd::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default CRect rt; GetClientRect(&rt); CBrush br; br.CreateSolidBrush(VIDEO_BACK_COLOR); pDC->FillRect(&rt,&br); return TRUE; } LRESULT CPlayWnd::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class CPtzScreen *pContainer = (CPtzScreen *)GetParent(); // CRealPlayAndPTZControlDlg *pMainWnd = (CRealPlayAndPTZControlDlg *)(AfxGetApp()->GetMainWnd()); // CDialogTransmit * pTransWnd = (CDialogTransmit *)pMainWnd->m_pTabTransmit; if(pContainer) { switch(message) { case WM_LBUTTONUP: { pointEnd.x = LOWORD(lParam); pointEnd.y = HIWORD(lParam); if(m_FlagRect == TRUE) { m_FlagRect =FALSE; KillTimer(2); RECT rt; GetClientRect(&rt); pContainer->m_pRectEventFunc(rt,pointStart,pointEnd,pContainer->m_dwRectEvent); } } break; case WM_MOUSEMOVE: { RECT rt; GetClientRect(&rt); long x = LOWORD(lParam); long y = HIWORD(lParam); x = x>rt.right?rt.right:x; x = xrt.bottom?rt.bottom:y; y = ySetActivePage(this); // 设备窗口选择框 if (pContainer->m_pMessageProc) // 选择对应播放画面 { pContainer->m_pMessageProc(m_nWndID, WM_RBUTTONDOWN, pContainer->m_dwMessageUser); } if (bIsPlaying == false) { break; } pointStart.x = LOWORD(lParam); pointStart.y = HIWORD(lParam); m_FlagRect =TRUE; SetTimer(2,16,NULL); break; } case WM_LBUTTONDBLCLK: { BOOL bMulti = pContainer->GetMultiScreen(); pContainer->SetMultiScreen(!bMulti); } break; default: break; } } return CWnd::DefWindowProc(message, wParam, lParam); } void CPlayWnd::OnContextMenu(CWnd* pWnd, CPoint point) { // TODO: Add your message handler code here /*CPtzScreen *pContainer = (CPtzScreen *)GetParent(); pContainer->SetActivePage(this); CMenu menu; menu.CreatePopupMenu(); menu.AppendMenu(MF_STRING | pContainer->GetFullScreen() ? MF_CHECKED : MF_UNCHECKED, VIDEO_MENU_FULLSCREEN, ConvertString(NAME_MENU_FULLSCREEN)); menu.AppendMenu(MF_STRING | pContainer->GetMultiScreen() ? MF_CHECKED : MF_UNCHECKED, VIDEO_MENU_MULTISCREEN, ConvertString(NAME_MENU_MULTISCREEN)); menu.AppendMenu(MF_STRING | pContainer->GetAutoAdjustPos() ? MF_CHECKED : MF_UNCHECKED, VIDEO_MENU_AUTOADJUST, ConvertString(NAME_MENU_AUTOADJUST)); menu.AppendMenu(MF_STRING | pContainer->m_pGetParams(m_nWndID, 0, pContainer->m_dwGetParams) ? MF_CHECKED : MF_UNCHECKED, VIDEO_MENU_EXITDECODE, ConvertString(NAME_MENU_EXITDECODE)); menu.AppendMenu(MF_STRING | pContainer->m_pGetParams(m_nWndID, 1, pContainer->m_dwGetParams) ? MF_CHECKED : MF_UNCHECKED, VIDEO_MENU_EXITCYCLE, ConvertString(NAME_MENU_EXITCYCLE)); TrackPopupMenu( menu.m_hMenu, TPM_LEFTALIGN, point.x, point.y, 0, m_hWnd, NULL);*/ } void CPlayWnd::OnVideoMenu(UINT nID) { CPtzScreen *pContainer = (CPtzScreen *)GetParent(); switch(nID) { case VIDEO_MENU_FULLSCREEN: pContainer->SetFullScreen(!pContainer->GetFullScreen()); break; case VIDEO_MENU_MULTISCREEN: pContainer->SetMultiScreen(!pContainer->GetMultiScreen()); break; case VIDEO_MENU_AUTOADJUST: pContainer->SetAutoAdjustPos(!pContainer->GetAutoAdjustPos()); break; case VIDEO_MENU_PRINTSCREEN: break; case VIDEO_MENU_RECORDVIDEO: break; case VIDEO_MENU_EXITDECODE: pContainer->m_pSetParams(m_nWndID, 0, pContainer->m_dwSetParams); break; case VIDEO_MENU_EXITCYCLE: pContainer->m_pSetParams(m_nWndID, 1, pContainer->m_dwSetParams); break; default: break; } } LRESULT CPlayWnd::OnRepaintWnd(WPARAM wParam, LPARAM lParam) { Invalidate(); return 0; } BOOL CPlayWnd::DestroyWindow() { return CWnd::DestroyWindow(); } void CPlayWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) { CWnd::OnActivate(nState, pWndOther, bMinimized); // TODO: Add your message handler code here } void CPlayWnd::OnTimer(UINT_PTR nIDEvent) { switch (nIDEvent) { case 1: m_llLoginId = Login(); KillTimer(1); break; } CWnd::OnTimer(nIDEvent); } void CPlayWnd::OnActivateApp(BOOL bActive, DWORD hTask) { CWnd::OnActivateApp(bActive, hTask); } //Display log in failure reason void CPlayWnd::ShowLoginErrorReason(int nError) { if (1 == nError) MessageBox(ConvertString("Invalid password!"), ConvertString("Prompt")); else if (2 == nError) MessageBox(ConvertString("Invalid account!"), ConvertString("Prompt")); else if (3 == nError) MessageBox(ConvertString("Timeout!"), ConvertString("Prompt")); else if (4 == nError) MessageBox(ConvertString("The user has logged in!"), ConvertString("Prompt")); else if (5 == nError) MessageBox(ConvertString("The user has been locked!"), ConvertString("Prompt")); else if (6 == nError) MessageBox(ConvertString("The user has listed into illegal!"), ConvertString("Prompt")); else if (7 == nError) MessageBox(ConvertString("The system is busy!"), ConvertString("Prompt")); else if (9 == nError) MessageBox(ConvertString("You Can't find the network server!"), ConvertString("Prompt")); else MessageBox(ConvertString("Login failed!"), ConvertString("Prompt")); } // netsdk 实时回调函数 void CALL_METHOD fRealDataCB(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser) { CPlayWnd *pWnd = (CPlayWnd*)dwUser; if (pWnd->m_lRealHandle != lRealHandle)return; // 把大华实时码流数据送到playsdk中 PLAY_InputData(pWnd->m_nWndID, pBuffer, dwBufSize); return; } LLONG CPlayWnd::Login() { //依次登录摄像机,获取登录ID //m_strCameraIp, m_nCameraPort, m_strUserName, m_strPassWord); char *pchDVRIP; //CString strDvrIP = GetDvrIP(); pchDVRIP = (LPSTR)(LPCSTR)m_strCameraIp; WORD wDVRPort = (WORD)m_nCameraPort; char *pchUserName = (LPSTR)(LPCSTR)m_strUserName; char *pchPassword = (LPSTR)(LPCSTR)m_strPassWord; /* NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam; memset(&stInparam, 0, sizeof(stInparam)); stInparam.dwSize = sizeof(stInparam); strncpy(stInparam.szIP, pchDVRIP, sizeof(stInparam.szIP) - 1); strncpy(stInparam.szPassword, pchPassword, sizeof(stInparam.szPassword) - 1); strncpy(stInparam.szUserName, pchUserName, sizeof(stInparam.szUserName) - 1); stInparam.nPort = wDVRPort; stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP; NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam; memset(&stOutparam, 0, sizeof(stOutparam)); stOutparam.dwSize = sizeof(stOutparam); LLONG lRet = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam); if (0 == lRet) { //Display log in failure reason ShowLoginErrorReason(stOutparam.nError); return -1; } else { //m_LoginID = lRet; int nRetLen = 0; NET_DEV_CHN_COUNT_INFO stuChn = { sizeof(NET_DEV_CHN_COUNT_INFO) }; stuChn.stuVideoIn.dwSize = sizeof(stuChn.stuVideoIn); stuChn.stuVideoOut.dwSize = sizeof(stuChn.stuVideoOut); BOOL bRet = CLIENT_QueryDevState(lRet, DH_DEVSTATE_DEV_CHN_COUNT, (char*)&stuChn, stuChn.dwSize, &nRetLen); if (!bRet) { DWORD dwError = CLIENT_GetLastError() & 0x7fffffff; } return lRet; } //SetWindowText(ConvertString("CapturePicture"));*/ PLAY_GetFreePort(&m_nWndID); PLAY_SetStreamOpenMode(m_nWndID, STREAME_REALTIME); PLAY_OpenStream(m_nWndID, NULL, 0, 1024 * 512 * 6); //设置视频抓图回调函数 可以回调出YUV数据 PLAY_SetDisplayCallBack(m_nWndID, fDisplayCB, this); PLAY_Play(m_nWndID, NULL); NET_DEVICEINFO_Ex stLoginInfo = { 0 }; int nErrcode = 0; LLONG lLoginHandle = CLIENT_LoginEx2(pchDVRIP, m_nCameraPort, pchUserName, pchPassword, (EM_LOGIN_SPAC_CAP_TYPE)0, NULL, &stLoginInfo, &nErrcode); if (0 == lLoginHandle) { //cout << "Login device failed" << endl; //cin >> szIpAddr; return -1; } else { //cout << "Login device success" << endl; } //拉流 m_lRealHandle = CLIENT_RealPlayEx(lLoginHandle, 0, 0); if (0 == m_lRealHandle) { //cout << "CLIENT_RealPlayEx fail!" << endl; Sleep(100000); return -1; } //cout << "CLIENT_RealPlayEx success!" << endl; //设置拉流回调 CLIENT_SetRealDataCallBack(m_lRealHandle, fRealDataCB, (LDWORD)this); return lLoginHandle; } int CPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; if (m_strCameraIp.IsEmpty()) { return -1; } SetTimer(1, 5000, NULL); return 0; } void CPlayWnd::StopPlayForServerMode() { /* BOOL bRealPlay = CLIENT_StopRealPlayEx(m_DispHanle); if (bRealPlay) { this->SetWndPlaying(false); //And then close PLAY_Play BOOL bPlay = g_PlayAPI.PLAY_Stop(m_nWndID); if (bPlay) { //At last close PLAY_OpenStream BOOL bStream = g_PlayAPI.PLAY_CloseStream(m_nWndID); } }*/ } // playsdk 回调 yuv数据 void CALL_METHOD CPlayWnd::fDisplayCB(LONG nPort, char * pBuf, LONG nSize, LONG nWidth, LONG nHeight, LONG nStamp, LONG nType, void* pReserved) { CPlayWnd *pShowWnd = (CPlayWnd *)(pReserved); if (pShowWnd->m_nWndID != nPort)return; //TRACE("%d\n", pThis->m_nWndID); //if (pThis->m_nWndID > 1)return; pShowWnd->m_nIndex++; if (pShowWnd->m_nIndex == 24) { cv::Mat cv_img; cv::Mat cv_yuv(nHeight + nHeight / 2, nWidth, CV_8UC1, pBuf);//pFrame为YUV数据地址,另外这里就是用 CV_8UC1非 CV_8UC3. cv_img = cv::Mat(nHeight, nWidth, CV_8UC3); cv::cvtColor(cv_yuv, cv_img, cv::COLOR_YUV2BGR_I420); //cv::COLOR_YUV2BGR_I420 //cv::imshow("video", cv_img); cv::Mat imgTmp; CRect rect; pShowWnd->GetClientRect(&rect); // 获取控件大小 int nWidth = cv_img.cols * rect.Height() *1.0 / cv_img.rows; if (rect.Width() == 0)return; //鱼眼照片站展平 if (theApp.m_bCalibrator) { cv_img = CImageCalibrator::imageCalibration(cv_img); } cv::resize(cv_img, imgTmp, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 pShowWnd->m_nIndex = 0; pShowWnd->DrawMat(imgTmp, (rect.Width() - nWidth) / 2); cv::waitKey(10); } return; } //参数1:opencv即将读的图, //参数2:需要展示的Picture Control的ID void CPlayWnd::DrawMat(cv::Mat& imageMat, int nOffset) { /*cv::Mat img; CRect rect; GetClientRect(&rect); // 获取控件大小 int nWidth = imageMat.cols * rect.Height() *1.0 / imageMat.rows; cv::resize(imageMat, img, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 // 转一下格式 ,这段可以放外面,*/ /*switch (imgTmp.channels()) { case 1: cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道 break; case 3: cv::cvtColor(imgTmp, imgTmp, CV_BGR2BGRA); // BGR三通道 break; default: break; } int pixelBytes = imgTmp.channels() * (imgTmp.depth() + 1); // 计算一个像素多少个字节 // 制作bitmapinfo(数据头) BITMAPINFO bitInfo; bitInfo.bmiHeader.biBitCount = 8 * pixelBytes; bitInfo.bmiHeader.biWidth = imgTmp.cols; bitInfo.bmiHeader.biHeight = -imgTmp.rows; bitInfo.bmiHeader.biPlanes = 1; bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitInfo.bmiHeader.biCompression = BI_RGB; bitInfo.bmiHeader.biClrImportant = 0; bitInfo.bmiHeader.biClrUsed = 0; bitInfo.bmiHeader.biSizeImage = 0; bitInfo.bmiHeader.biXPelsPerMeter = 0; bitInfo.bmiHeader.biYPelsPerMeter = 0; // Mat.data + bitmap数据头 -> MFC CDC* pDC = GetDC(); ::StretchDIBits( pDC->GetSafeHdc(), (rect.Width()-nWidth)/2, 0, nWidth, rect.Height(), 0, 0, nWidth, rect.Height(), imgTmp.data, &bitInfo, DIB_RGB_COLORS, SRCCOPY ); ReleaseDC(pDC);*/ CImage image; image.Create(imageMat.cols, imageMat.rows, 24); for (int y = 0; y < imageMat.rows; ++y) { const uchar* src = imageMat.ptr(y); uchar* dst = reinterpret_cast(image.GetBits()) + y * image.GetPitch(); for (int x = 0; x < imageMat.cols; ++x) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; src += 3; dst += 3; } } HDC hdc = ::GetDC(m_hWnd); image.Draw(hdc, CRect(CPoint(nOffset, 0), CSize(imageMat.cols, imageMat.rows))); image.Destroy(); ::ReleaseDC(m_hWnd, hdc); }