📄 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 + -