?? playview.cpp
字號:
// playView.cpp : implementation of the CPlayView class
//
#include "stdafx.h"
#include "play.h"
#include "playDoc.h"
#include "playView.h"
#include "MainFrm.h"
#include "av8api.h"
#include "Define.h"
#include "Dos.h"
#include "direct.h"
#include "Afxmt.h"
#include "Windowsx.h"
#include "StopModeDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BLOCKNUM 50
#define BLOCKLEN 32768 //32k
#define FILE_CLOSE(x) if(x) { mmioClose(x, NULL);x=NULL;}
#define RELEASE_AV8BUFFER if(g_pBuffer) {g_pBuffer->Stop();delete g_pBuffer;g_pBuffer = NULL;}
#define RELEASE_CVIDEOPLAY if(pVideoPlay){pVideoPlay->StopPlay();delete pVideoPlay;pVideoPlay=NULL;}
extern CMenu PopMenu;
BOOL m_Capture=FALSE; //是否采集
CAV8Buffer *g_pBuffer = NULL;
HMMIO hmmioOutput; //采集文件的句斌
HMMIO hmmioSendOutput; //發送時保存文件的句斌
CString CapFileName; //采集文件名
BOOL m_FileSend=FALSE; //是否在發送文件數據
CEvent g_eventFileStopSend; //停止發送文件標志,自動設置
CEvent g_eventRealSend(FALSE,TRUE,NULL,NULL); //開始實時發送標志,手工設置
CEvent g_eventClearup; //完成清除工作,可以Destory窗口標志
HWND hWnd ;//發送數窗口的句斌
float m_size=0.00; //采集數據大小
CString SendFilePath="";
#define WM_CAPTURE_STOP WM_USER+1000 //采集大小到,停止采集
//發送組播數據
DWORD SendData(LPWSABUF stWSABuf)
{
CString msg;
DWORD cbRet;
cbRet = 0;
CPlayApp* pApp=(CPlayApp*)AfxGetApp();
//向指定地址發送數據
int status = WSASendTo (MultiSock, /* socket */
stWSABuf, /* output buffer structure */
1, /* buffer count */
&cbRet, /* number of bytes sent */
0, /* flags */
(struct sockaddr FAR *)&DestAddr,/* destination address */
sizeof(DestAddr), /* size of addr structure */
NULL, /* overlapped structure */
NULL); /* overlapped callback function */
if (status == SOCKET_ERROR)
{
AfxMessageBox("WSASendTo() Error");
return -1;
}
return cbRet;
}
//視頻文件發送線程
UINT FileSendThread(LPVOID pParam)
{
CFile hFile;
DWORD dwFlags;
DWORD SendLen;
DWORD dwReadLength;
DWORD dwBytesRead;
int status;
WSABUF SendBuf;
dwReadLength=BUFSIZE;
//分配發送緩沖區
SendBuf.buf=(char *)malloc(BUFSIZE);
status=hFile.Open(SendFilePath,CFile::modeRead);
dwFlags = MMIO_CREATE | MMIO_WRITE;
if(status==0)
{
//釋放發送緩沖區
free(SendBuf.buf);
return -1;
}
else
{
while(1)
{
//每次讀數據32k
dwBytesRead=hFile.Read(SendBuf.buf,dwReadLength);
if(dwBytesRead==0)
{//發送完成
//關閉文件
hFile.Close();
//釋放發送緩沖區
free(SendBuf.buf);
AfxMessageBox("發送完成");
break;
}
SendBuf.len = dwBytesRead;
//發送數據
SendLen=SendData(&SendBuf);
if(::WaitForSingleObject(g_eventFileStopSend,0)==WAIT_OBJECT_0)
{
hFile.Close();
free(SendBuf.buf);
AfxMessageBox("停止發送");
break;
}
Sleep(250);
}
}
//文件發送標志置為FALSE
m_FileSend=FALSE;
return 0;
}
//實時視頻流發送線程
UINT RealSendThread(LPVOID pParam)
{
int temp;
//發送緩沖區
LPWSABUF RealSendBuf = (LPWSABUF)pParam;
//開始實時發送
g_eventRealSend.ResetEvent();
//發送數據
temp=SendData(RealSendBuf);
//實時保存視頻流到指定文件中
if(hmmioSendOutput)
mmioWrite(hmmioSendOutput, (LPSTR) RealSendBuf->buf,temp);
free(RealSendBuf->buf);
GlobalFreePtr(RealSendBuf);
g_eventRealSend.SetEvent();
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CPlayView
IMPLEMENT_DYNCREATE(CPlayView, CView)
BEGIN_MESSAGE_MAP(CPlayView, CView)
//{{AFX_MSG_MAP(CPlayView)
ON_WM_SIZE()
ON_WM_CONTEXTMENU()
ON_COMMAND(ID_POP_FILE_SEND, OnPopFileSend)
ON_COMMAND(ID_POP_REAL_SEND, OnPopRealSend)
ON_COMMAND(ID_POP_SEND_STOP, OnPopSendStop)
ON_COMMAND(ID_CAPTURE_SAVE, OnCaptureSave)
ON_COMMAND(ID_BEGIN_CAPTURE, OnBeginCapture)
ON_COMMAND(ID_STOP_CAPTURE, OnStopCapture)
ON_COMMAND(ID_OPEN_PLAYFILE, OnOpenPlayfile)
ON_COMMAND(ID_PLAYFILE, OnPlayfile)
ON_COMMAND(ID_FILE_STOP, OnFileStop)
ON_COMMAND(ID_REALPLAY, OnRealplay)
ON_COMMAND(ID_REAL_STOP, OnRealStop)
ON_WM_TIMER()
ON_COMMAND(ID_PAUSE_PLAY, OnPausePlay)
ON_COMMAND(ID_RESUME_PLAY, OnResumePlay)
ON_WM_ERASEBKGND()
ON_COMMAND(ID_PAUSE_CAPTURE, OnPauseCapture)
ON_COMMAND(ID_RESUME_CAPTURE, OnResumeCapture)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_VIEW_OUTBAR_NOTIFY, OnOutbarNotify)
ON_MESSAGE(WM_PLAYOVER,OnPlayOver)
ON_MESSAGE(WM_READYSEND,OnReadyRealSend)
ON_MESSAGE(WM_PREPARE_CLOSE,OnPrepareClose)
ON_MESSAGE(WM_CAPTURE_STOP,OnCaptureStop)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPlayView construction/destruction
//響應WM_CAPTURE_STOP消息,采集大小到,停止采集
LRESULT CPlayView::OnCaptureStop(WPARAM wParam, LPARAM lParam)
{
//停止采集
OnStopCapture();
MessageBox("采集數量到,停止采集");
//采集大小標志置為FALSE
m_SizeCheck=FALSE;
return 0;
}
LRESULT CPlayView::OnOutbarNotify(WPARAM wParam, LPARAM lParam)
{
CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
switch (wParam)
{
case NM_OB_ITEMCLICK:
{
int nFolder =pFrame->m_wndOutlookBar.GetSelFolder();
int nIndex = (int)lParam;
switch (nFolder)
{
case PLAY:
{
switch (nIndex)
{
case Play_Set:
break;
case Play_Open:
OnOpenPlayfile();
break;
case Play_Begin:
OnPlayfile();
break;
case Play_Pause:
pVideoPlay->PausePlay();
KillTimer(ID_TIMER);
pFrame->m_wndStatusBar.SetPaneText(0,"暫停");
break;
case Play_Resume:
pVideoPlay->ResumePlay();
SetTimer(ID_TIMER,1000,NULL);
pFrame->m_wndStatusBar.SetPaneText(0,"播放");
break;
case Play_Stop:
OnFileStop();
break;
}
}
break;
case CAPTURE: // Management folder is selected...
{
switch (nIndex)
{
case Cap_Preview:
OnRealplay();
break;
case Cap_Set:
OnCaptureSave();
break;
case Cap_Begin:
OnBeginCapture();
break;
case Cap_Stop:
OnStopCapture();
break;
}
}
break;
}
}
}
return 0;
}
LRESULT CPlayView::OnPrepareClose(WPARAM wParam, LPARAM lParam)
{
RELEASE_CVIDEOPLAY;
//關閉設備
ClearDriver();
if(m_FileSend)
g_eventFileStopSend.SetEvent();
//如果在發送實時視頻流,等待線程結束,釋放文件句斌
if(m_RealSend)
::WaitForSingleObject(g_eventRealSend,INFINITE);
RELEASE_AV8BUFFER;
//關閉采集文件句柄
FILE_CLOSE(hmmioOutput);
//關閉保存文件句柄
FILE_CLOSE(hmmioSendOutput);
g_eventClearup.SetEvent();
return 0;
}
CPlayView::CPlayView()
{
// TODO: add construction code here
pVideoPlay=NULL;
SendCounter=0;
hWnd=m_hWnd;
m_hVFDrv=NULL;
m_RealSend=FALSE;
m_TPlayFile=FALSE;
m_TCapture=FALSE;
m_SizeCheck=FALSE;
m_TimeCheck=FALSE;
m_time=0;
m_TimeIndex=0;
Fname="";
Ts=CTimeSpan(0,0,0,0);
Pos=0;
m_font.CreatePointFont(90, "宋體");
}
CPlayView::~CPlayView()
{
}
/////////////////////////////////////////////////////////////////////////////
// CPlayView drawing
void CPlayView::OnDraw(CDC* pDC)
{
CPlayDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/////////////////////////////////////////////////////////////////////////////
// CPlayView diagnostics
#ifdef _DEBUG
void CPlayView::AssertValid() const
{
CView::AssertValid();
}
void CPlayView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CPlayDoc* CPlayView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPlayDoc)));
return (CPlayDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPlayView message handlers
void CPlayView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
// TODO: Add your specialized code here and/or call the base class
CView::CalcWindowRect(lpClientRect, nAdjustType);
}
void CPlayView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
RECT grc;
// TODO: Add your message handler code here
if(pVideoPlay)
{
if(pVideoPlay->pivw)
{
GetClientRect(&grc);
pVideoPlay->pivw->SetWindowPosition(grc.left, grc.top, grc.right, grc.bottom);
}
}
}
void CPlayView::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
PopMenu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,point.x,point.y,this);
}
//響應發送視頻文件命令
void CPlayView::OnPopFileSend()
{
// TODO: Add your command handler code here
CFileDialog dlg(TRUE,NULL,NULL,NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
dlg.m_ofn.lpstrTitle="打開多媒體文件";
if(dlg.DoModal()==IDOK)
{
SendFilePath=dlg.GetPathName();
m_FileSend=TRUE;
//開始文件發送線程
AfxBeginThread(FileSendThread,NULL);
// if(!pVideoPlay)
// {
// pVideoPlay=new CVideoPlay(this->m_hWnd);
// pVideoPlay->PlayFromFile(SendFilePath);
// }
CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
pFrame->m_wndStatusBar.SetPaneText(1,"在發送文件數據");
}
}
//響應WM_READYSEND消息,啟動發送線程
LRESULT CPlayView::OnReadyRealSend(WPARAM wParam,LPARAM lParam)
{
LPWSABUF stWSABuf;
stWSABuf=(LPWSABUF)GlobalAllocPtr(GHND,sizeof(WSABUF));
stWSABuf->buf = (char *)malloc(BUFSIZE);
if (g_pBuffer)
g_pBuffer->PopOut ((LPSTR)stWSABuf->buf, BUFSIZE);
stWSABuf->len = BUFSIZE;
::WaitForSingleObject(g_eventRealSend,INFINITE);
AfxBeginThread(RealSendThread,stWSABuf);
return 0;
}
//響應實時發送命令
void CPlayView::OnPopRealSend()
{
DWORD dwFlags;
//如果視頻流緩沖區尚未建立,分配視頻流緩沖區
if (! g_pBuffer)
g_pBuffer = new CAV8Buffer(BLOCKNUM, BLOCKLEN);
//如果當前不在實時采集數據,啟動視頻采集卡采集數據
if((!m_RealSend)&&(!m_Capture))
{
if(InitDriver()<0)
return;
}
//打開一個本地存放文件
dwFlags = MMIO_CREATE | MMIO_WRITE;
hmmioSendOutput = mmioOpen("temp.mpg", (LPMMIOINFO)NULL, dwFlags);
//實時發送標志置為TRUE
m_RealSend=TRUE;
//設置實時發送事件就緒
g_eventRealSend.SetEvent();
CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
pFrame->m_wndStatusBar.SetPaneText(1,"在發送實時數據");
}
void CPlayView::OnPopSendStop()
{
// TODO: Add your command handler code here
if(m_FileSend)
g_eventFileStopSend.SetEvent();
if(m_RealSend)
{
if(!m_Capture)
ClearDriver();
RELEASE_AV8BUFFER;
::WaitForSingleObject(g_eventRealSend,INFINITE);//等待線程結束,釋放文件句斌
FILE_CLOSE(hmmioSendOutput);
m_RealSend=FALSE;
}
CMainFrame* pFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
pFrame->m_wndStatusBar.SetPaneText(1,"停止發送");
}
//回調函數,實現對視頻采集卡傳遞進來的數據流的處理
WORD CALLBACK _loadds MyCallBack(HDRVR hdrvr, UINT msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
if(msg==VF_MSGUSER_BUF_WRITE)
{
LONG lRet;
MMIOINFO mmioinfoIn;
LPVF_BUFWRITE_STRUCT lpBufWrite = (LPVF_BUFWRITE_STRUCT)dwParam1;
//將傳遞進來的數據壓入視頻流緩沖區隊列
if (g_pBuffer)
DWORD dwBytes = g_pBuffer->PushIn((LPSTR)lpBufWrite -> lpBuffer, (DWORD)lpBufWrite -> dwBufferWrite);
//如果現在在采集數據,將數據寫入到采集文件中
if (m_Capture)
if(hmmioOutput)
{
lRet = mmioWrite(hmmioOutput, (LPSTR)lpBufWrite -> lpBuffer, (LONG)lpBufWrite -> dwBufferWrite);
mmioGetInfo(hmmioOutput,&mmioinfoIn, 0);
//采集文件滿,發送停止采集消息
if(mmioinfoIn.lDiskOffset>(m_size*1024*1024))
::SendMessage(hWnd,WM_CAPTURE_STOP,0,0);
}
if (lRet == -1L)
return (FALSE);
}
return 1;
}
int CPlayView::InitDriver()
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -