playView.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:25k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. // playView.cpp : implementation of the CPlayView class
  2. //
  3. #include "stdafx.h"
  4. #include "play.h"
  5. #include "playDoc.h"
  6. #include "playView.h"
  7. #include "MainFrm.h"
  8. #include "av8api.h"
  9. #include "Define.h"
  10. #include "Dos.h"
  11. #include "direct.h"
  12. #include "Afxmt.h"
  13. #include "Windowsx.h"
  14. #include "StopModeDlg.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. #define BLOCKNUM 50
  21. #define BLOCKLEN 32768 //32k
  22. #define FILE_CLOSE(x)  if(x) { mmioClose(x, NULL);x=NULL;}
  23. #define RELEASE_AV8BUFFER  if(g_pBuffer) {g_pBuffer->Stop();delete g_pBuffer;g_pBuffer = NULL;}
  24. #define RELEASE_CVIDEOPLAY if(pVideoPlay){pVideoPlay->StopPlay();delete pVideoPlay;pVideoPlay=NULL;}
  25.  
  26. extern CMenu PopMenu;
  27. BOOL m_Capture=FALSE;  //是否采集
  28. CAV8Buffer *g_pBuffer = NULL;
  29. HMMIO hmmioOutput;      //采集文件的句斌
  30. HMMIO hmmioSendOutput;      //发送时保存文件的句斌
  31. CString CapFileName;  //采集文件名
  32. BOOL m_FileSend=FALSE;   //是否在发送文件数据
  33. CEvent g_eventFileStopSend;  //停止发送文件标志,自动设置
  34. CEvent g_eventRealSend(FALSE,TRUE,NULL,NULL);   //开始实时发送标志,手工设置
  35. CEvent g_eventClearup;   //完成清除工作,可以Destory窗口标志
  36. HWND hWnd ;//发送数窗口的句斌 
  37. float  m_size=0.00;     //采集数据大小
  38. CString SendFilePath="";
  39. #define WM_CAPTURE_STOP WM_USER+1000    //采集大小到,停止采集
  40. //发送组播数据
  41. DWORD SendData(LPWSABUF stWSABuf)
  42. {
  43.     CString msg;
  44. DWORD cbRet;
  45.     cbRet = 0;
  46.     CPlayApp* pApp=(CPlayApp*)AfxGetApp();
  47. //向指定地址发送数据
  48. int status = WSASendTo (MultiSock,   /* socket */
  49.   stWSABuf, /* output buffer structure */
  50.   1,                       /* buffer count */
  51.   &cbRet,                  /* number of bytes sent */
  52.   0, /* flags */
  53.   (struct sockaddr FAR *)&DestAddr,/* destination address */
  54.   sizeof(DestAddr), /* size of addr structure */
  55.   NULL,                    /* overlapped structure */
  56.   NULL);                   /* overlapped callback function */
  57. if (status == SOCKET_ERROR) 
  58. {
  59.   AfxMessageBox("WSASendTo() Error");
  60.   return -1;
  61. }
  62. return cbRet;
  63. }
  64. //视频文件发送线程
  65. UINT FileSendThread(LPVOID pParam)
  66. {
  67. CFile  hFile; 
  68. DWORD dwFlags;
  69. DWORD SendLen;
  70. DWORD dwReadLength;
  71. DWORD dwBytesRead;
  72. int status;
  73. WSABUF SendBuf;
  74. dwReadLength=BUFSIZE;   
  75. //分配发送缓冲区
  76. SendBuf.buf=(char *)malloc(BUFSIZE);
  77. status=hFile.Open(SendFilePath,CFile::modeRead);
  78. dwFlags = MMIO_CREATE | MMIO_WRITE;
  79. if(status==0)
  80. {
  81. //释放发送缓冲区
  82. free(SendBuf.buf);
  83. return -1;
  84. }
  85. else
  86. {
  87. while(1)
  88. {
  89. //每次读数据32k
  90. dwBytesRead=hFile.Read(SendBuf.buf,dwReadLength);
  91. if(dwBytesRead==0)
  92. {//发送完成
  93. //关闭文件
  94. hFile.Close();
  95. //释放发送缓冲区
  96. free(SendBuf.buf);
  97. AfxMessageBox("发送完成");
  98. break;
  99. }
  100. SendBuf.len = dwBytesRead;
  101. //发送数据
  102. SendLen=SendData(&SendBuf);
  103. if(::WaitForSingleObject(g_eventFileStopSend,0)==WAIT_OBJECT_0)
  104. {
  105. hFile.Close();
  106. free(SendBuf.buf); 
  107. AfxMessageBox("停止发送");
  108. break;
  109. }
  110. Sleep(250);
  111. }
  112. }
  113. //文件发送标志置为FALSE
  114. m_FileSend=FALSE; 
  115. return 0;
  116. }
  117. //实时视频流发送线程
  118. UINT RealSendThread(LPVOID pParam)
  119. {
  120. int temp;
  121. //发送缓冲区
  122.     LPWSABUF RealSendBuf = (LPWSABUF)pParam;
  123. //开始实时发送
  124. g_eventRealSend.ResetEvent(); 
  125. //发送数据
  126. temp=SendData(RealSendBuf);
  127. //实时保存视频流到指定文件中
  128. if(hmmioSendOutput)
  129.     mmioWrite(hmmioSendOutput, (LPSTR) RealSendBuf->buf,temp);
  130.     free(RealSendBuf->buf);
  131. GlobalFreePtr(RealSendBuf);
  132. g_eventRealSend.SetEvent();
  133. return 0;
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. // CPlayView
  137. IMPLEMENT_DYNCREATE(CPlayView, CView)
  138. BEGIN_MESSAGE_MAP(CPlayView, CView)
  139. //{{AFX_MSG_MAP(CPlayView)
  140. ON_WM_SIZE()
  141. ON_WM_CONTEXTMENU()
  142. ON_COMMAND(ID_POP_FILE_SEND, OnPopFileSend)
  143. ON_COMMAND(ID_POP_REAL_SEND, OnPopRealSend)
  144. ON_COMMAND(ID_POP_SEND_STOP, OnPopSendStop)
  145. ON_COMMAND(ID_CAPTURE_SAVE, OnCaptureSave)
  146. ON_COMMAND(ID_BEGIN_CAPTURE, OnBeginCapture)
  147. ON_COMMAND(ID_STOP_CAPTURE, OnStopCapture)
  148. ON_COMMAND(ID_OPEN_PLAYFILE, OnOpenPlayfile)
  149. ON_COMMAND(ID_PLAYFILE, OnPlayfile)
  150. ON_COMMAND(ID_FILE_STOP, OnFileStop)
  151. ON_COMMAND(ID_REALPLAY, OnRealplay)
  152. ON_COMMAND(ID_REAL_STOP, OnRealStop)
  153. ON_WM_TIMER()
  154. ON_COMMAND(ID_PAUSE_PLAY, OnPausePlay)
  155. ON_COMMAND(ID_RESUME_PLAY, OnResumePlay)
  156. ON_WM_ERASEBKGND()
  157. ON_COMMAND(ID_PAUSE_CAPTURE, OnPauseCapture)
  158. ON_COMMAND(ID_RESUME_CAPTURE, OnResumeCapture)
  159. //}}AFX_MSG_MAP
  160. ON_MESSAGE(WM_VIEW_OUTBAR_NOTIFY, OnOutbarNotify)
  161. ON_MESSAGE(WM_PLAYOVER,OnPlayOver)
  162. ON_MESSAGE(WM_READYSEND,OnReadyRealSend)
  163. ON_MESSAGE(WM_PREPARE_CLOSE,OnPrepareClose)
  164. ON_MESSAGE(WM_CAPTURE_STOP,OnCaptureStop)
  165. END_MESSAGE_MAP()
  166. /////////////////////////////////////////////////////////////////////////////
  167. // CPlayView construction/destruction
  168. //响应WM_CAPTURE_STOP消息,采集大小到,停止采集
  169. LRESULT CPlayView::OnCaptureStop(WPARAM wParam, LPARAM lParam)
  170. {
  171. //停止采集
  172.     OnStopCapture();
  173. MessageBox("采集数量到,停止采集");
  174. //采集大小标志置为FALSE
  175.     m_SizeCheck=FALSE;
  176. return 0;  
  177. }
  178. LRESULT CPlayView::OnOutbarNotify(WPARAM wParam, LPARAM lParam)
  179. {
  180. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  181. switch (wParam)
  182. {
  183. case NM_OB_ITEMCLICK:
  184. {
  185. int nFolder =pFrame->m_wndOutlookBar.GetSelFolder();
  186. int nIndex  = (int)lParam;
  187. switch (nFolder)
  188. {
  189. case PLAY: 
  190. {
  191. switch (nIndex)
  192. {
  193. case Play_Set:
  194. break;
  195. case Play_Open:
  196. OnOpenPlayfile();
  197. break;
  198. case Play_Begin:
  199. OnPlayfile();
  200. break;
  201. case Play_Pause:
  202. pVideoPlay->PausePlay();
  203. KillTimer(ID_TIMER);
  204. pFrame->m_wndStatusBar.SetPaneText(0,"暂停");
  205. break;
  206. case Play_Resume:
  207. pVideoPlay->ResumePlay();
  208. SetTimer(ID_TIMER,1000,NULL);
  209. pFrame->m_wndStatusBar.SetPaneText(0,"播放");
  210. break;
  211. case Play_Stop:
  212. OnFileStop();
  213. break;
  214. }
  215. }
  216. break;
  217. case CAPTURE: // Management folder is selected...
  218. {
  219. switch (nIndex)
  220. {
  221. case Cap_Preview:
  222. OnRealplay();
  223. break;
  224. case Cap_Set:
  225. OnCaptureSave();
  226. break;
  227. case Cap_Begin:
  228. OnBeginCapture();
  229. break;
  230. case Cap_Stop:
  231. OnStopCapture();
  232. break;
  233. }
  234. }
  235. break;
  236. }
  237. }
  238. }
  239. return 0;
  240. }
  241. LRESULT CPlayView::OnPrepareClose(WPARAM wParam, LPARAM lParam)
  242. {
  243.     RELEASE_CVIDEOPLAY;
  244. //关闭设备
  245.     ClearDriver();
  246.     if(m_FileSend)
  247.        g_eventFileStopSend.SetEvent();
  248. //如果在发送实时视频流,等待线程结束,释放文件句斌
  249.     if(m_RealSend)
  250.       ::WaitForSingleObject(g_eventRealSend,INFINITE);
  251.     RELEASE_AV8BUFFER;
  252. //关闭采集文件句柄
  253. FILE_CLOSE(hmmioOutput);
  254. //关闭保存文件句柄
  255. FILE_CLOSE(hmmioSendOutput);
  256. g_eventClearup.SetEvent();
  257.     return 0;
  258. }
  259. CPlayView::CPlayView()
  260. {
  261. // TODO: add construction code here
  262. pVideoPlay=NULL;
  263. SendCounter=0; 
  264. hWnd=m_hWnd;
  265. m_hVFDrv=NULL;
  266. m_RealSend=FALSE; 
  267. m_TPlayFile=FALSE;
  268. m_TCapture=FALSE;
  269. m_SizeCheck=FALSE;
  270. m_TimeCheck=FALSE;
  271. m_time=0;
  272. m_TimeIndex=0;
  273. Fname="";
  274. Ts=CTimeSpan(0,0,0,0);
  275. Pos=0;
  276. m_font.CreatePointFont(90, "宋体");
  277.     
  278. }
  279. CPlayView::~CPlayView()
  280. {
  281.  
  282. }
  283. /////////////////////////////////////////////////////////////////////////////
  284. // CPlayView drawing
  285. void CPlayView::OnDraw(CDC* pDC)
  286. {
  287. CPlayDoc* pDoc = GetDocument();
  288. ASSERT_VALID(pDoc);
  289. // TODO: add draw code for native data here
  290. }
  291. /////////////////////////////////////////////////////////////////////////////
  292. // CPlayView diagnostics
  293. #ifdef _DEBUG
  294. void CPlayView::AssertValid() const
  295. {
  296. CView::AssertValid();
  297. }
  298. void CPlayView::Dump(CDumpContext& dc) const
  299. {
  300. CView::Dump(dc);
  301. }
  302. CPlayDoc* CPlayView::GetDocument() // non-debug version is inline
  303. {
  304. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPlayDoc)));
  305. return (CPlayDoc*)m_pDocument;
  306. }
  307. #endif //_DEBUG
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CPlayView message handlers
  310. void CPlayView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType) 
  311. {
  312. // TODO: Add your specialized code here and/or call the base class
  313. CView::CalcWindowRect(lpClientRect, nAdjustType);
  314. }
  315. void CPlayView::OnSize(UINT nType, int cx, int cy) 
  316. {
  317. CView::OnSize(nType, cx, cy);
  318. RECT grc;
  319. // TODO: Add your message handler code here
  320. if(pVideoPlay)
  321. {
  322. if(pVideoPlay->pivw)
  323. {
  324. GetClientRect(&grc); 
  325. pVideoPlay->pivw->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);
  326. }
  327. }
  328. }
  329. void CPlayView::OnContextMenu(CWnd* pWnd, CPoint point) 
  330. {
  331. // TODO: Add your message handler code here
  332. PopMenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,this);  
  333. }
  334. //响应发送视频文件命令
  335. void CPlayView::OnPopFileSend() 
  336. {
  337. // TODO: Add your command handler code here
  338. CFileDialog dlg(TRUE,NULL,NULL,NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
  339. dlg.m_ofn.lpstrTitle="打开多媒体文件";
  340. if(dlg.DoModal()==IDOK)
  341. {
  342.     SendFilePath=dlg.GetPathName();
  343. m_FileSend=TRUE;
  344. //开始文件发送线程
  345. AfxBeginThread(FileSendThread,NULL);
  346. // if(!pVideoPlay)
  347. // {
  348. // pVideoPlay=new CVideoPlay(this->m_hWnd);
  349. // pVideoPlay->PlayFromFile(SendFilePath);
  350. // }
  351. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  352. pFrame->m_wndStatusBar.SetPaneText(1,"在发送文件数据");
  353. }
  354. }
  355. //响应WM_READYSEND消息,启动发送线程
  356. LRESULT CPlayView::OnReadyRealSend(WPARAM wParam,LPARAM lParam)
  357. {
  358. LPWSABUF stWSABuf;
  359. stWSABuf=(LPWSABUF)GlobalAllocPtr(GHND,sizeof(WSABUF));
  360. stWSABuf->buf = (char *)malloc(BUFSIZE); 
  361. if (g_pBuffer) 
  362. g_pBuffer->PopOut ((LPSTR)stWSABuf->buf, BUFSIZE);
  363. stWSABuf->len = BUFSIZE;
  364. ::WaitForSingleObject(g_eventRealSend,INFINITE);
  365. AfxBeginThread(RealSendThread,stWSABuf); 
  366. return 0;
  367. }
  368. //响应实时发送命令
  369. void CPlayView::OnPopRealSend() 
  370. {
  371. DWORD dwFlags;
  372. //如果视频流缓冲区尚未建立,分配视频流缓冲区
  373. if (! g_pBuffer)
  374.     g_pBuffer = new CAV8Buffer(BLOCKNUM, BLOCKLEN);
  375. //如果当前不在实时采集数据,启动视频采集卡采集数据
  376. if((!m_RealSend)&&(!m_Capture))
  377. {
  378.     if(InitDriver()<0)
  379.     return;
  380. }
  381. //打开一个本地存放文件
  382. dwFlags = MMIO_CREATE | MMIO_WRITE;
  383. hmmioSendOutput = mmioOpen("temp.mpg", (LPMMIOINFO)NULL, dwFlags);
  384. //实时发送标志置为TRUE
  385. m_RealSend=TRUE;
  386. //设置实时发送事件就绪
  387. g_eventRealSend.SetEvent();
  388. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  389.     pFrame->m_wndStatusBar.SetPaneText(1,"在发送实时数据");
  390. }
  391. void CPlayView::OnPopSendStop() 
  392. {
  393. // TODO: Add your command handler code here
  394. if(m_FileSend)
  395. g_eventFileStopSend.SetEvent();
  396. if(m_RealSend)
  397. {
  398. if(!m_Capture)
  399. ClearDriver();
  400. RELEASE_AV8BUFFER;
  401. ::WaitForSingleObject(g_eventRealSend,INFINITE);//等待线程结束,释放文件句斌
  402. FILE_CLOSE(hmmioSendOutput);
  403. m_RealSend=FALSE;
  404. }
  405. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  406. pFrame->m_wndStatusBar.SetPaneText(1,"停止发送");   
  407. }
  408. //回调函数,实现对视频采集卡传递进来的数据流的处理
  409. WORD CALLBACK _loadds MyCallBack(HDRVR hdrvr, UINT msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
  410. {
  411. if(msg==VF_MSGUSER_BUF_WRITE)
  412. {
  413. LONG lRet;
  414. MMIOINFO    mmioinfoIn;
  415. LPVF_BUFWRITE_STRUCT lpBufWrite = (LPVF_BUFWRITE_STRUCT)dwParam1;
  416. //将传递进来的数据压入视频流缓冲区队列
  417. if (g_pBuffer)
  418. DWORD dwBytes = g_pBuffer->PushIn((LPSTR)lpBufWrite -> lpBuffer, (DWORD)lpBufWrite -> dwBufferWrite);
  419. //如果现在在采集数据,将数据写入到采集文件中
  420. if (m_Capture)
  421. if(hmmioOutput)
  422. {
  423. lRet = mmioWrite(hmmioOutput, (LPSTR)lpBufWrite -> lpBuffer, (LONG)lpBufWrite -> dwBufferWrite);
  424. mmioGetInfo(hmmioOutput,&mmioinfoIn, 0);
  425. //采集文件满,发送停止采集消息
  426. if(mmioinfoIn.lDiskOffset>(m_size*1024*1024))
  427. ::SendMessage(hWnd,WM_CAPTURE_STOP,0,0);
  428. }
  429. if (lRet == -1L)
  430. return (FALSE);
  431. }
  432. return 1;
  433. }
  434. int CPlayView::InitDriver()
  435. {
  436.     WORD flags;
  437. //打开设备驱动
  438.     m_hVFDrv = OpenDriver (L"av8api.dll", NULL, NULL);
  439.     if (!m_hVFDrv)
  440.     {
  441. MessageBox("Can't OpenDriver()");
  442.         return -1;
  443. }
  444. //检查是否有设备驱动可用,如有,将打开的设备与驱动程序关联起来
  445.     if (!HVFAssign(m_hVFDrv, 0))
  446.     {
  447.         MessageBox("没有合适的视频设备!");
  448.         return -1;
  449.     }
  450. //锁定设备
  451. HVFLock(m_hVFDrv, VF_CAP_ALL);
  452.     flags = VF_FLAG_MPEG | VF_FLAG_ENCODE | VF_FLAG_OUTBUF;
  453. //打开流数据
  454.     m_bStream = static_cast<BYTE> (HVFOpen(m_hVFDrv, flags, 
  455. reinterpret_cast<unsigned long>(MyCallBack)));
  456. //配置流数据的编码信息
  457.     InitEncodeVideoVxD();
  458.     InitEncodeAudioVxD(); 
  459. //开始采集数据
  460. if (m_bStream) 
  461.         HVFRecord(m_hVFDrv, m_bStream, NULL, NULL);
  462. return 0;
  463. }
  464. void CPlayView::ClearDriver()
  465. {
  466. //将流数据的大小置为0
  467.     m_bStream = 0;
  468.     if (m_hVFDrv)
  469.     {
  470.         //停止采集数据
  471. HVFStop(m_hVFDrv, m_bStream);
  472. //关闭流数据
  473.         HVFClose(m_hVFDrv, m_bStream);
  474. //释放设备
  475.         HVFUnlock(m_hVFDrv, VF_CAP_ALL);
  476. //关闭设备驱动
  477.         CloseDriver(m_hVFDrv, NULL, NULL);
  478. //将驱动句柄置为0
  479.         m_hVFDrv = 0;
  480. //采集标志设为FALSE
  481. m_Capture=FALSE;
  482.      }
  483. }
  484. //配置视频流的编码信息
  485. void CPlayView::InitEncodeVideoVxD()
  486. {
  487.    
  488.     DWORD dwValue;
  489.     WORD  wWidth, wHeight;
  490.     wWidth  = 352;
  491.     wHeight = 288;
  492.     dwValue = MAKELONG(wWidth, wHeight);
  493. //设置视频的输出大小,取MAKELONG(352, 288)
  494.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_OUTPUTSIZE, dwValue);
  495.     wWidth = (wWidth * 45) / 44; 
  496.     dwValue = MAKELONG(wWidth, wHeight);
  497. //设置视频的输入大小,取MAKELONG(360, 288)
  498. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_INPUTSIZE, dwValue);
  499. //设置视频的比特率,取1152000bits/s
  500.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_BITRATE, BITRATE_DEFAULT);
  501. //设置视频帧速,25帧/s
  502.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_RATE, VF_FLAG_VID_25);
  503. //设置MPEG压缩的I帧间隔,取15 
  504.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_IINTERVAL, IINTERVAL_DEFAULT);
  505. //设置MPEG压缩的P帧间隔,取3
  506.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_BINTERVAL, PINTERVAL_DEFAULT);
  507. //设置视频的制式,采用PAL制式
  508.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_MODE, VF_FLAG_VID_PAL);
  509. //设置视频的输入源的类型,采用混合类型
  510.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_SOURCE, VF_FLAG_VID_COMPOSITE);
  511. //设置视频的压缩算法,采用MPEG编码
  512.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_ALGORITHM, VF_FLAG_VID_MPEG);
  513. //设置视频的亮度
  514.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_BRIGHTNESS, BRIGHTNESS_DEFAULT);
  515. //设置视频的对比度
  516.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_CONTRAST, CONTRAST_DEFAULT);    
  517. //设置视频的色调
  518.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_HUE, HUE_DEFAULT);
  519. //设置视频的饱和度
  520.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_VID_SATURATION, SATURATION_DEFAULT);
  521. }
  522. void CPlayView::DiskSpace(TCHAR sDriver)
  523. {//检查磁盘空间
  524. struct _diskfree_t diskfree;
  525. int nDriver =sDriver-'A'+1; 
  526. if (_getdiskfree(nDriver, &diskfree) == 0)
  527. {
  528. FreeDiskSpace.Format("硬盘%c剩余:%luMB",sDriver,
  529. (DWORD)diskfree.avail_clusters *
  530. (DWORD)diskfree.sectors_per_cluster *
  531. (DWORD)diskfree.bytes_per_sector / ((DWORD)1024L*(DWORD)1024L));
  532. }
  533. else
  534. return;
  535. }
  536. void CPlayView::OnCaptureSave() 
  537. {
  538. // TODO: Add your command handler code here
  539. CString strCaptureSave;
  540. TCHAR Driver;
  541. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  542. CFileDialog FileDlg(TRUE,NULL,"temp",NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
  543. FileDlg.m_ofn.lpstrInitialDir="c:\temp";
  544. CStopModeDlg StopModeDlg;
  545. FileDlg.m_ofn.lpstrTitle="指定采集文件名";
  546. if(FileDlg.DoModal()==IDOK)
  547. {
  548. //选择采集文件
  549. CapFileName=FileDlg.GetPathName();
  550.         Driver=CapFileName.GetAt(0);
  551.         strCaptureSave.Format("采集到:%s",CapFileName);
  552. //检查磁盘剩余空间
  553. DiskSpace(Driver);
  554.         CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  555.         pFrame->m_wndStatusBar.SetPaneText(1,strCaptureSave);
  556. pFrame->m_wndStatusBar.SetPaneText(2,FreeDiskSpace);
  557. //选择自动停止采集方式
  558.         if(StopModeDlg.DoModal()==IDOK)
  559. if(StopModeDlg.m_SizeCheck)
  560. {//选择根据文件大小停止
  561. sscanf(StopModeDlg.m_size,"%f",&m_size);
  562. m_SizeCheck=StopModeDlg.m_SizeCheck;
  563. }
  564. if(StopModeDlg.m_TimeCheck)
  565. {//选择根据采集时间停止
  566. sscanf(StopModeDlg.m_time,"%d",&m_time);
  567. m_TimeCheck=StopModeDlg.m_TimeCheck;
  568. }
  569. }
  570. }
  571. }
  572. void CPlayView::OnBeginCapture() 
  573. {
  574. // TODO: Add your command handler code here
  575. DWORD dwFlags = 0;
  576.     RECT Srct,Erct,Prct;
  577.     int width;
  578.     UINT Sid;
  579.     UINT SStyle;
  580. //如果当前不在实时发送数据而且不在采集,
  581. //对设备进行初始化,开始采集数据
  582. if((!m_RealSend)&&(!m_Capture))
  583.    if(InitDriver()<0)
  584.      return;
  585. //采集标志设为TRUE
  586.     m_Capture=TRUE;
  587. LPSTR caFileName=CapFileName.GetBuffer(_MAX_PATH);
  588. CapFileName.ReleaseBuffer();
  589. dwFlags = MMIO_CREATE | MMIO_WRITE;
  590. //打开采集文件
  591. hmmioOutput = mmioOpen(caFileName, (LPMMIOINFO)NULL, dwFlags);
  592. //在状态栏中显示相关信息
  593.   CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  594. pFrame->m_wndStatusBar.SetPaneText(0,"");
  595. pFrame->m_wndStatusBar.GetPaneInfo(0,Sid,SStyle,width);
  596.   ::GetClientRect(pFrame->m_wndStatusBar.m_hWnd,&Prct);
  597. Srct.left=10;
  598.     Srct.top=4;
  599.     Srct.right=width/2-20;
  600.     Srct.bottom=Prct.bottom-1;
  601.     Erct.left=width/2;
  602.     Erct.top=4;
  603.   Erct.right=width-10;
  604.   Erct.bottom=Prct.bottom-1;
  605.     m_static.Create(_T("已采集(时:分:秒)"),WS_CHILD|WS_VISIBLE|SS_LEFT,
  606. Srct,&pFrame->m_wndStatusBar,ID_STATIC);
  607. m_static.SetFont(&m_font);
  608. m_edit.Create(ES_CENTER|WS_BORDER|WS_VISIBLE,Erct,&pFrame->m_wndStatusBar,ID_EDIT);
  609.     m_edit.SetWindowText("00:00:00");
  610. //采集定时器标志设为TRUE
  611.     m_TCapture=TRUE;
  612. //设定计时器
  613. SetTimer(ID_TIMER,1000,NULL);
  614. }
  615. void CPlayView::OnStopCapture() 
  616. {
  617. //关闭计时器
  618.     KillTimer(ID_TIMER);
  619. //采集定时器标志设为FALSE
  620.     m_TCapture=FALSE;
  621. //如果现在不在实时发送数据,
  622. //停止采集数据,并关闭相关设备
  623. if(!m_RealSend)
  624. ClearDriver();
  625. //关闭采集文件
  626.     FILE_CLOSE(hmmioOutput);
  627. Ts=CTimeSpan(0,0,0,0);
  628. m_static.DestroyWindow();
  629. m_edit.DestroyWindow();
  630. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  631.   pFrame->m_wndStatusBar.SetPaneText(0,"停止采集");
  632. }
  633. void CPlayView::OnPauseCapture() 
  634. {
  635. //关闭计时器
  636. KillTimer(ID_TIMER);
  637. //采集计时器标志设为FALSE
  638.     m_TCapture=FALSE;
  639. //暂停采集
  640. HVFPause(m_hVFDrv, m_bStream);
  641. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  642. pFrame->m_wndStatusBar.SetPaneText(0,"暂停采集");
  643. }
  644. void CPlayView::OnResumeCapture() 
  645. {
  646. // TODO: Add your command handler code here
  647. //继续采集
  648. HVFResume(m_hVFDrv, m_bStream);
  649. //采集计时器标志设为TRUE
  650. m_TCapture=TRUE;
  651. //设定计时器
  652. SetTimer(ID_TIMER,1000,NULL);
  653. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  654. pFrame->m_wndStatusBar.SetPaneText(0,"");
  655. }
  656. void CPlayView::OnOpenPlayfile() 
  657. {
  658. CString FTemp;  
  659. CFileDialog dlg(TRUE,NULL,NULL,NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
  660. dlg.m_ofn.lpstrTitle="打开多媒体文件";
  661. //dlg.m_ofn.lpstrInitialDir="c:\Windows\Temp";
  662. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  663. if(dlg.DoModal()==IDOK)
  664. {
  665.     Fname=dlg.GetPathName();
  666.     FTemp.Format("播放:%s",Fname);
  667. pFrame->m_wndStatusBar.SetPaneText(0,"停止");
  668.      pFrame->m_wndStatusBar.SetPaneText(1,FTemp);
  669. }
  670. void CPlayView::OnPlayfile() 
  671. {
  672. // TODO: Add your command handler code here
  673. RECT Srct,Prct;
  674.   int width;
  675.   UINT Sid;
  676.     UINT SStyle;
  677. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  678. if(!pVideoPlay)
  679. pVideoPlay=new CVideoPlay(this->m_hWnd);
  680.     pFrame->m_wndStatusBar.SetPaneText(0,"播放");
  681.   pFrame->m_wndStatusBar.GetPaneInfo(0,Sid,SStyle,width);
  682.   ::GetClientRect(pFrame->m_wndStatusBar.m_hWnd,&Srct);
  683.     Prct.left=40;
  684.   Prct.top=4;
  685.   Prct.right=width;
  686.   Prct.bottom=Srct.bottom-1;
  687.   m_prog.Create(PBS_SMOOTH,Prct,&pFrame->m_wndStatusBar,ID_PROGRESS);
  688.     pVideoPlay->PlayFromFile(Fname);  
  689. m_prog.SetRange(0,(int)pVideoPlay->tLength);
  690.     m_prog.ShowWindow(SW_SHOW);
  691. m_TPlayFile=TRUE;
  692.   SetTimer(ID_TIMER,1000,NULL);
  693. }
  694. LRESULT CPlayView::OnPlayOver(WPARAM wParam,LPARAM lParam)
  695. {
  696. int status;
  697. status=pVideoPlay->PlayOver();
  698. if(status==0)
  699. {
  700. KillTimer(ID_TIMER);
  701. m_prog.DestroyWindow();
  702. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  703. pFrame->m_wndStatusBar.SetPaneText(0,"停止");
  704. Pos=0;
  705. Ts=CTimeSpan(0,0,0,0);
  706. m_TPlayFile=FALSE;
  707. }
  708. return 0;
  709. }
  710. void CPlayView::OnFileStop() 
  711. {
  712. // TODO: Add your command handler code here
  713. KillTimer(ID_TIMER);
  714. m_prog.DestroyWindow();
  715. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  716. pFrame->m_wndStatusBar.SetPaneText(0,"停止");
  717.     Pos=0;
  718.     Ts=CTimeSpan(0,0,0,0);
  719. m_TPlayFile=FALSE;
  720. RELEASE_CVIDEOPLAY;
  721. }
  722. void CPlayView::OnRealplay() 
  723. {
  724. // TODO: Add your command handler code here
  725. int i,MenuCount;
  726. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  727.     pVideoPlay=new CVideoPlay(this->m_hWnd);
  728. pVideoPlay->RealPlay();
  729. pFrame->m_wndStatusBar.SetPaneText(0,"实时播放");
  730. pFrame->m_wndStatusBar.SetPaneText(1,"");
  731. CMenu* pSubMenu=PopMenu.GetSubMenu(0);
  732. MenuCount=pSubMenu->GetMenuItemCount();
  733. for(i=0;i<2;i++)
  734. pSubMenu->EnableMenuItem(i,MF_ENABLED|MF_BYPOSITION); 
  735. }
  736. void CPlayView::OnRealStop() 
  737. {
  738. // TODO: Add your command handler code here
  739. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  740. pFrame->m_wndStatusBar.SetPaneText(0,"");
  741. RELEASE_CVIDEOPLAY;
  742. }
  743. void CPlayView::OnTimer(UINT nIDEvent) 
  744. {
  745. // TODO: Add your message handler code here and/or call default
  746. CTimeSpan TsAdd(1);
  747. Ts=TsAdd+Ts;
  748. if(m_TPlayFile)
  749. {
  750. CString s1 =Ts.Format("已播放:%H:%M:%S");
  751. Pos=Pos+1;
  752. m_prog.SetPos(Pos);
  753. CDC* pControlDC=m_prog.GetDC();  
  754. CFont* pOldFont = (CFont*) pControlDC->SelectObject(&m_font); 
  755. //CPen* pOldPen =(CPen*) pControlDC->SelectObject(&Wpen);
  756. int iOld = pControlDC->GetBkMode();
  757. int iOldMode = pControlDC->GetROP2();
  758. pControlDC->SetROP2(R2_XORPEN);
  759. CRect rc;
  760. m_prog.GetClientRect(&rc);
  761. pControlDC->SetBkMode(TRANSPARENT);
  762. m_prog.Invalidate();
  763. m_prog.UpdateWindow();
  764. pControlDC->DrawText(s1, &rc, DT_CENTER | DT_VCENTER);
  765. pControlDC->SelectObject(pOldFont);
  766. pControlDC->SetROP2(iOldMode);
  767. pControlDC->SetBkMode(iOld);
  768. m_prog.ReleaseDC(pControlDC);
  769. }
  770. if(m_TCapture)
  771. {
  772. CString s2 =Ts.Format("%H:%M:%S");
  773. m_edit.SetWindowText(s2);
  774. if(m_TimeCheck)
  775. {
  776. m_TimeIndex++;
  777. if(m_TimeIndex==m_time+1)
  778. {
  779. OnStopCapture();
  780. MessageBox("采集时间到,停止采集");
  781. m_TimeCheck=FALSE;
  782. m_TimeIndex=0;
  783. }
  784. }
  785. }
  786. CView::OnTimer(nIDEvent);
  787. }
  788. void CPlayView::OnPausePlay() 
  789. {
  790. // TODO: Add your command handler code here
  791. pVideoPlay->PausePlay();
  792. KillTimer(ID_TIMER);
  793. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  794. pFrame->m_wndStatusBar.SetPaneText(0,"暂停");
  795. }
  796. void CPlayView::OnResumePlay() 
  797. {
  798. // TODO: Add your command handler code here
  799. pVideoPlay->ResumePlay();
  800. SetTimer(ID_TIMER,1000,NULL);
  801. CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
  802.     pFrame->m_wndStatusBar.SetPaneText(0,"播放");
  803. }
  804. void CPlayView::InitEncodeSystemVxD()
  805. {
  806.     HVFSet(m_hVFDrv, m_bStream, VF_INDEX_STM_TYPE, VF_FLAG_MPGSYS);
  807. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_STM_ENCODEMODE, VF_FLAG_STM_NORMAL);
  808. }
  809. /////////////////////////////////////////////////////////////////////////////
  810. // CMyEdit
  811. IMPLEMENT_DYNAMIC(CMyEdit,CEdit)
  812. CMyEdit::CMyEdit()
  813. {
  814. m_clrFont =RGB(0 , 255 , 0) ;   // yellow text 
  815. m_clrBack=RGB(0 , 0 , 0) ;    // blue background 
  816. m_brush.CreateSolidBrush(m_clrBack); 
  817. m_font.CreatePointFont(90, "宋体");
  818. }
  819. CMyEdit::~CMyEdit()
  820. {
  821. }
  822. BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
  823. //{{AFX_MSG_MAP(CMyEdit)
  824. ON_WM_CREATE()
  825. ON_WM_CTLCOLOR_REFLECT()
  826. //}}AFX_MSG_MAP
  827. END_MESSAGE_MAP()
  828. /////////////////////////////////////////////////////////////////////////////
  829. // CMyEdit message handlers
  830. int CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  831. {
  832. if (CEdit::OnCreate(lpCreateStruct) == -1)
  833. return -1;
  834. // TODO: Add your specialized creation code here
  835. SetFont(&m_font);
  836. return 0;
  837. }
  838. HBRUSH CMyEdit::CtlColor(CDC* pDC, UINT nCtlColor) 
  839. {
  840. // TODO: Change any attributes of the DC here
  841. pDC->SetTextColor (m_clrFont); 
  842.     pDC->SetBkMode(TRANSPARENT); 
  843.     return (HBRUSH)m_brush.GetSafeHandle (); 
  844. }
  845. //配置音频流的编码信息
  846. void CPlayView::InitEncodeAudioVxD()
  847. {
  848.     DWORD dwValue;
  849. //设置音频的采样率,取默认值44100 kHz
  850. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_SAMPLE, SAMPLE_RATE_DEFAULT);
  851. //设置音频的比特率,取默认值224000bits/s
  852. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_BITRATE, BIT_RATE_DEFAULT);
  853. dwValue=VF_FLAG_AUD_MPEG;
  854. dwValue=(dwValue<<16)+VF_FLAG_AUD_NONE;
  855. //设置音频的压缩算法,采用MPEG编码
  856. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_ALGORITHM, dwValue);
  857. //设置音频方式,为立体声
  858. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_MODE, MODE_DEFAULT);
  859. //设置音频的音量大小,取默认值100
  860. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_VOLUME, VOLUME_DEFAULT);
  861. //设置音频电平,取默认值0
  862. HVFSet(m_hVFDrv, m_bStream, VF_INDEX_AUD_GAIN, GAIN_DEFAULT);
  863. }
  864. BOOL CPlayView::OnEraseBkgnd(CDC* pDC) 
  865. {
  866. // TODO: Add your message handler code here and/or call default
  867. // Create a pruple brush. 
  868. CBrush Brush (RGB (0,0,255) ); 
  869. CBrush* pOldBrush = pDC->SelectObject(&Brush); 
  870. CRect reClip ; 
  871. pDC->GetClipBox(&reClip); 
  872. pDC->PatBlt (reClip.left , reClip.top , 
  873.     reClip.Width ( ) , reClip.Height ( ) , PATCOPY ); 
  874. pDC->SelectObject (pOldBrush ); 
  875. return TRUE; 
  876. }