⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playview.cpp

📁 <VC++视频音频开发>一书的光盘资料。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -