revplaymdichildwnd.cpp
资源名称:VC++视频传输.rar [点击查看]
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:24k
源码类别:
VC书籍
开发平台:
Visual C++
- // RevPlayMDIChildWnd.cpp : implementation file
- //
- #include "stdafx.h"
- #include "RevPlayThread.h"
- #include "RevPlayMDIChildWnd.h"
- #include "ConnectDlg.h"
- #include "resource.h"
- #include "asyncio.h"
- #include "asyncrdr.h"
- #include "mainfrm.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- //#define IDC_REVPLAY_WND 1
- #define LISTEN_PORT 1500
- #define BUFSIZE 32768
- #define WSA_CONNECT WM_USER+200
- #define WSA_READ WM_USER+300 //读取视频数据
- //{ 36a5f771-fe4c-11ce-a8ed-00aa002feab5 }
- const CLSID CLSID_Stream = {
- 0x36a5f771, 0xfe4c, 0x11ce, 0xa8, 0xed, 0x00, 0xaa, 0x00, 0x2f, 0xea, 0xb5
- };
- const AMOVIESETUP_MEDIATYPE sudPinTypes =
- {
- &MEDIATYPE_NULL, // Major type
- &MEDIASUBTYPE_NULL // Minor type
- };
- const AMOVIESETUP_PIN sudPins =
- {
- L"Input", // Pin string name
- FALSE, // Is it rendered
- FALSE, // Is it an output
- FALSE, // Allowed none
- FALSE, // Likewise many
- &CLSID_NULL, // Connects to filter
- L"Output", // Connects to pin
- 1, // Number of types
- &sudPinTypes // Pin information
- };
- const AMOVIESETUP_FILTER sudStream =
- {
- &CLSID_Stream, // Filter CLSID
- L"Stream", // String name
- MERIT_DO_NOT_USE, // Filter merit
- 1, // Number pins
- &sudPins // Pin details
- };
- //
- // Object creation stuff
- //
- CFactoryTemplate g_Templates[]= {
- L"Stream", &CLSID_Stream, NULL, NULL, &sudStream
- };
- int g_cTemplates = 1;
- class CMemStream : public CAsyncStream
- {
- public:
- CRevPlayWnd* pWnd; //接收播放窗口指针
- public:
- BOOL PeekAndPump();
- CMemStream( LPBYTE pbData, LONGLONG llLength, DWORD dwKBPerSec = INFINITE) :
- m_pbData(pbData),
- m_llLength(llLength),
- m_llPosition(0),
- m_dwKBPerSec(dwKBPerSec)
- {
- m_dwTimeStart = timeGetTime();
- }
- //设置当前位置
- HRESULT SetPointer(LONGLONG llPos)
- {
- if (llPos < 0 || llPos > m_llLength) {
- return S_FALSE;
- } else {
- m_llPosition = llPos;
- return S_OK;
- }
- }
- //当MPEG1 Stream Splitter请求数据时,由Read函数提供
- HRESULT Read(PBYTE pbBuffer,
- DWORD dwBytesToRead,
- BOOL bAlign,
- LPDWORD pdwBytesRead)
- {
- CAutoLock lck(&m_csLock);
- DWORD dwReadLength, cbRet;
- DWORD dwTime = timeGetTime();
- //如果要求读取的字节数大于剩余的字节数,则只直接读取剩余的字节
- if (m_llPosition + dwBytesToRead > m_llLength)
- {
- dwReadLength = (DWORD)(m_llLength - m_llPosition);
- }
- else
- {
- dwReadLength = dwBytesToRead;
- }
- DWORD dwTimeToArrive =
- ((DWORD)m_llPosition + dwReadLength) / m_dwKBPerSec;
- if (dwTime - m_dwTimeStart < dwTimeToArrive) {
- Sleep(dwTimeToArrive - dwTime + m_dwTimeStart);
- }
- static int rwIndex =0;
- static int Block = pWnd->Block;
- int temp=pWnd->rIndex;
- // if (pWnd->m_RenderOk)
- // {
- /* while (rwIndex>temp)
- PeekAndPump();*/
- //将存放接收的数据缓冲区数组中的数据拷贝到pbBuffer中,传给Splitter
- CopyMemory((PVOID)pbBuffer, (PVOID)(pWnd->pRevMem[rwIndex]), pWnd->RevLen);
- rwIndex = (rwIndex + 1) % 100;
- TRACE1("Read Addr = %dn",rwIndex);
- cbRet=pWnd->RevLen;
- // }
- /* else
- {
- if (Block == 0)
- {
- CopyMemory((PVOID)pbBuffer, (PVOID)(m_pbData),
- dwReadLength);
- Block ++;
- }
- else
- {
- CopyMemory((PVOID)pbBuffer, (PVOID)(m_pbData + dwReadLength),
- dwReadLength);
- Block = 0;
- }
- cbRet = dwReadLength;
- }*/
- //当前位置向后移读出的字节数
- m_llPosition += cbRet;
- *pdwBytesRead = cbRet;
- if (cbRet != dwReadLength)
- m_llLength = m_llPosition;
- return S_OK;
- }
- //得到当前的数据总长度
- LONGLONG Size(LONGLONG *pSizeAvailable)
- {
- LONGLONG llCurrentAvailable =
- Int32x32To64((timeGetTime() - m_dwTimeStart),m_dwKBPerSec);
- *pSizeAvailable = min(m_llLength, llCurrentAvailable);
- return m_llLength;
- }
- DWORD Alignment()
- {
- //按1字节对齐
- return 1;
- }
- void Lock()
- {
- m_csLock.Lock();
- }
- void Unlock()
- {
- m_csLock.Unlock();
- }
- private:
- CCritSec m_csLock; //数据操作的同步对象
- const PBYTE m_pbData; //读写的内存数据指针
- LONGLONG m_llLength; //数据总长度
- LONGLONG m_llPosition; //实际读写的内存数据位置指针
- DWORD m_dwKBPerSec; //播放的的速率
- DWORD m_dwTimeStart;//开始时间
- };
- class CMemReader : public CAsyncReader
- {
- public:
- STDMETHODIMP Register()
- {
- return S_OK;
- }
- STDMETHODIMP Unregister()
- {
- return S_OK;
- }
- CMemReader(CMemStream *pStream, CMediaType *pmt, HRESULT *phr) :
- CAsyncReader(NAME("Mem Reader"), NULL, pStream, phr)
- {
- m_mt = *pmt;
- }
- };
- /////////////////////////////////////////////////////////////////////////////
- // CRevPlayMDIChildWnd
- CMenu CRevPlayMDIChildWnd::menu;
- IMPLEMENT_DYNCREATE(CRevPlayMDIChildWnd, CMDIChildWnd)
- CRevPlayMDIChildWnd::CRevPlayMDIChildWnd()
- {
- }
- CRevPlayMDIChildWnd::~CRevPlayMDIChildWnd()
- {
- }
- BEGIN_MESSAGE_MAP(CRevPlayMDIChildWnd, CMDIChildWnd)
- //{{AFX_MSG_MAP(CRevPlayMDIChildWnd)
- ON_WM_SIZE()
- //}}AFX_MSG_MAP
- ON_MESSAGE(WM_USER_PREPARE_TO_CLOSE, OnPrepareToClose)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CRevPlayMDIChildWnd message handlers
- BOOL CRevPlayMDIChildWnd::Create(LPCTSTR szTitle, const RECT &rect, CMDIFrameWnd *parent)
- {
- if (menu.m_hMenu == NULL)
- menu.LoadMenu(IDR_REVPLAY);
- m_hMenuShared = menu.m_hMenu;
- //创建子窗口
- if (!CMDIChildWnd::Create(NULL, szTitle, WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW, rect, parent))
- return FALSE;
- //生成UI线程对象
- CRevPlayThread* pRevPlayThread = new CRevPlayThread(m_hWnd);
- //创建线程
- pRevPlayThread->CreateThread();
- return TRUE;
- }
- BOOL CRevPlayMDIChildWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
- {
- // TODO: Add your specialized code here and/or call the base class
- CWnd* pRevPlayWnd = (CRevPlayWnd*)GetDlgItem(IDC_REVPLAY_WND);
- if (pRevPlayWnd == NULL)
- return FALSE;
- COnCmdMsg oncmdmsg;
- oncmdmsg.m_nID = nID;
- oncmdmsg.m_nCode = nCode;
- oncmdmsg.m_pExtra = pExtra;
- oncmdmsg.m_pHandlerInfo = pHandlerInfo;
- return pRevPlayWnd->SendMessage(WM_USER_ONCMDMSG,
- 0, (LPARAM)&oncmdmsg);
- }
- void CRevPlayMDIChildWnd::OnSize(UINT nType, int cx, int cy)
- {
- CMDIChildWnd::OnSize(nType, cx, cy);
- // TODO: Add your message handler code here
- CWnd* pRevPlayWnd = GetDlgItem(IDC_REVPLAY_WND);
- if (pRevPlayWnd == NULL)
- return; // child CBounceWnd not created yet
- CRect rect;
- GetClientRect(&rect);
- pRevPlayWnd->SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
- }
- BOOL CRevPlayMDIChildWnd::DestroyWindow()
- {
- // TODO: Add your specialized code here and/or call the base class
- OnPrepareToClose();
- return CMDIChildWnd::DestroyWindow();
- }
- LRESULT CRevPlayMDIChildWnd::OnPrepareToClose(WPARAM wParam, LPARAM lParam)
- {
- CWnd* pRevPlayWnd = (CRevPlayWnd*)GetDlgItem(IDC_REVPLAY_WND);
- pRevPlayWnd->SendMessage(WM_USER_PREPARE_TO_CLOSE);
- WaitForSingleObject(CRevPlayThread::m_hEventRevPlayThreadKilled, INFINITE);
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CRevPlayWnd
- CRevPlayWnd::CRevPlayWnd()
- {
- m_LostBlock=0;
- m_Receive=FALSE;
- m_Save=FALSE;
- m_FirstRead=TRUE;
- m_RenderOk=FALSE;
- m_Stop=FALSE;
- rIndex=0; //pRevMem数组的标记
- g_rwIndex=0;
- m_pStream=NULL;
- m_rdr=NULL;
- m_pifg = NULL;
- m_pigb = NULL;
- m_pimc = NULL;
- m_pivw = NULL;
- m_ppos = NULL;
- hmmioSave = NULL;
- }
- CRevPlayWnd::~CRevPlayWnd()
- {
- }
- BEGIN_MESSAGE_MAP(CRevPlayWnd, CWnd)
- //{{AFX_MSG_MAP(CRevPlayWnd)
- ON_WM_CREATE()
- ON_COMMAND(IDR_SAVE, OnSave)
- ON_WM_CONTEXTMENU()
- ON_COMMAND(ID_STOP_RECEIVE, OnStopReceive)
- ON_COMMAND(IDR_REV_PLAY, OnRevPlay)
- ON_UPDATE_COMMAND_UI(IDR_SAVE, OnUpdateSave)
- ON_UPDATE_COMMAND_UI(ID_STOP_RECEIVE, OnUpdateStopReceive)
- ON_WM_SIZE()
- //}}AFX_MSG_MAP
- ON_MESSAGE(WM_USER_ONCMDMSG, OnDelegatedCmdMsg)
- ON_MESSAGE(WM_USER_PREPARE_TO_CLOSE, OnPrepareToClose)
- ON_MESSAGE(WSA_CONNECT,OnConnect)
- ON_MESSAGE(WSA_READ,OnRead)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CRevPlayWnd message handlers
- LRESULT CRevPlayWnd::OnConnect(WPARAM wParam,LPARAM lParam)
- {
- int status;
- int SendLen;
- int socket;
- char szRev[80];
- char szBuff[80];
- char Msg[]="请发送数据";
- u_long block=0;
- socket=(SOCKET)wParam;
- if (WSAGETSELECTERROR(lParam))
- {//建立连接失败
- MessageBox("不能连接服务器", "连接失败", MB_OK);
- if(WaitDlg)
- WaitDlg.EndDialog(IDCANCEL);
- //关闭socket
- closesocket(socket);
- return -1;
- }
- if (WSAGETSELECTEVENT(lParam) == FD_CONNECT)
- {//成功建立连接
- if(WaitDlg)
- WaitDlg.EndDialog(IDCANCEL);
- //发送请求发送数据命令给发送端
- SendLen=send(socket,Msg,sizeof(Msg),0);
- if(SendLen!=sizeof(Msg))
- {//请求数据发送失败
- MessageBox("请求错误" "Send");
- closesocket(socket);
- return -1;
- }
- if(SendLen==sizeof(Msg))
- {
- WSAAsyncSelect(socket,m_hWnd, 0, 0 );
- status=ioctlsocket(socket,FIONBIO,&block);
- if(status==SOCKET_ERROR)
- {
- sprintf(szBuff,"Err: %d",WSAGetLastError());
- MessageBox(szBuff);
- return -1;
- }
- //接收数据
- status =recv(socket, szRev,sizeof(szRev),0);
- if (status)
- {
- //得到组播IP地址和端口
- sscanf(szRev,"%s%d",strDestAddr,&DestPort);
- sprintf(szBuff,"请加入组:%s,端口:%d",strDestAddr,DestPort);
- MessageBox(szBuff,"接收请求");
- sprintf(szBuff,"接收播放:组:%s,端口:%d",strDestAddr,DestPort);
- ::SetWindowText(GetParent()->m_hWnd,szBuff);
- //关闭socket
- closesocket(socket);
- }
- if(status==0)
- {
- MessageBox("对方关闭连接");
- closesocket(socket);
- return -1;
- }
- }
- }
- return 0;
- }
- LRESULT CRevPlayWnd::OnRead(WPARAM wParam,LPARAM lParam)
- {
- DWORD dwRet;
- REFTIME fTime;
- REFERENCE_TIME llClock;
- HRESULT hr;
- RECT rect;
- //接收组播数据,存放到缓冲区stWSABuf中
- RevLen=ReceiveData();
- //将缓冲区stWSABuf中的数据拷贝到存放接收的数据的数组pRevMem中,
- //以供DirectShow读取
- CopyMemory((PVOID)pRevMem[rIndex],(PVOID)stWSABuf.buf,RevLen);
- rIndex=(rIndex+1)%100;
- //将接收到的数据保存到文件中
- if(hmmioSave)
- mmioWrite(hmmioSave,stWSABuf.buf,RevLen);
- if(m_FirstRead)
- {//如果是第一次接收到数据,启动DirectShow
- fTime = 0.0;
- dwRet = Parse ((PBYTE)stWSABuf.buf, stWSABuf.len, &llClock);
- fTime = llClock / 90000.0;
- if(dwRet == 0)
- return -1;
- if(InitGraph()==-1)
- return -1;
- if (abs (dwRet - 2048000) <= 16000) {
- RenderFrom ((PBYTE)achInBuf, "2mpal.dat");
- }
- if (abs (dwRet - 1152000) <= 16000) {
- RenderFrom ((PBYTE)achInBuf, "1mpal.dat");
- }
- if (abs (dwRet - 512000) <= 16000) {
- RenderFrom ((PBYTE)achInBuf, "512pal.dat");
- }
- if (abs (dwRet - 256000) <= 16000) {
- RenderFrom ((PBYTE)achInBuf, "256pal.dat");
- }
- Block = 0;
- //使用智能连接,将Source Filter的输出Pin连出去
- if (FAILED(hr = m_pigb -> Render(m_rdr -> GetPin(0))))
- {
- if (hr != VFW_S_AUDIO_NOT_RENDERED && hr != VFW_E_NO_AUDIO_HARDWARE )
- {
- MessageBox ("Render Error");
- WSAAsyncSelect(MultiSock,m_hWnd,WSA_READ,0);
- HELPER_RELEASE(m_pifg);
- HELPER_RELEASE(m_pigb);
- HELPER_RELEASE(m_pimc);
- HELPER_RELEASE(m_pivw);
- HELPER_RELEASE(m_ppos);
- return -1;
- }
- }
- m_RenderOk = true;
- //设置视频窗口属性
- m_pivw -> put_Owner((OAHWND)m_hWnd);
- m_pivw -> put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
- GetClientRect(&rect);
- m_pivw -> SetWindowPosition(rect.left, rect.top, rect.right, rect.bottom);
- //开始播放
- m_pimc -> Run();
- m_ppos->put_CurrentPosition(fTime + 0.4);
- m_Stop = TRUE;
- }
- m_FirstRead=FALSE;
- return 0;
- }
- LRESULT CRevPlayWnd::OnDelegatedCmdMsg(WPARAM, LPARAM lParam)
- {
- COnCmdMsg* pOnCmdMsg = (COnCmdMsg*)lParam;
- return CWnd::OnCmdMsg(pOnCmdMsg->m_nID, pOnCmdMsg->m_nCode, pOnCmdMsg->m_pExtra,
- pOnCmdMsg->m_pHandlerInfo);
- }
- LRESULT CRevPlayWnd::OnPrepareToClose(WPARAM, LPARAM)
- {
- StopReceive();
- if( stWSABuf.buf)
- {
- delete stWSABuf.buf;
- stWSABuf.buf=NULL;
- }
- if(achInBuf)
- {
- delete achInBuf;
- achInBuf=NULL;
- }
- DestroyWindow();
- return 0;
- }
- BOOL CRevPlayWnd::Create(LPCTSTR szTitle, LONG style, const RECT& rect, CWnd* parent)
- {
- // Register a custom WndClass and create a window.
- // This must be done because CBounceWnd has a custom cursor, and
- // no icon.
- LPCTSTR lpszRevPlayClass =
- AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
- LoadCursor(NULL, IDC_UPARROW),
- (HBRUSH)(COLOR_WINDOW+1),
- NULL);
- return CWnd::Create(lpszRevPlayClass, szTitle, style, rect, parent,
- IDC_REVPLAY_WND);
- }
- int CRevPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CWnd::OnCreate(lpCreateStruct) == -1)
- return -1;
- // TODO: Add your specialized creation code here
- int status;
- int sock;
- CConnectDlg ConnectDlg;
- stWSABuf.buf = new char[BUFSIZE];
- stWSABuf.len = BUFSIZE;
- achInBuf = new BYTE [BUFSIZE*2];
- if(ConnectDlg.DoModal()==IDOK)
- {
- status=Connect(m_hWnd,AddressIp,LISTEN_PORT,sock);
- if(status<0)
- return -1;
- }
- return 0;
- }
- int CRevPlayWnd::Connect(HWND hwnd, const char *Addr, short Port, int &sock)
- {
- SOCKADDR_IN send_sin;
- int status;
- //创建一个socket
- sock = socket(AF_INET,SOCK_STREAM,0);
- if (sock == INVALID_SOCKET)
- {
- MessageBox("Socket Error");
- closesocket(sock);
- return -1;
- }
- else
- {
- send_sin.sin_family=AF_INET;
- send_sin.sin_addr.s_addr=inet_addr(Addr);
- send_sin.sin_port=htons(Port);
- //设置响应的网络事件为FD_CONNECT,即建立连接
- //发送WSA_CONNECT消息给窗口
- status=WSAAsyncSelect(sock,hwnd,WSA_CONNECT,FD_CONNECT);
- if(status<0)
- {//连接建立失败,关闭socket
- MessageBox("Error on WSAAsyncSelect()");
- WSAAsyncSelect(sock, hwnd, 0, 0);
- closesocket(sock);
- return -1;
- }
- }
- //连接发送端
- connect(sock,(struct sockaddr FAR *)&send_sin, sizeof(send_sin));
- int error=WSAGetLastError();
- //有阻塞,弹出等待对话框
- if (error==WSAEWOULDBLOCK)
- WaitDlg.DoModal();
- return 0;
- }
- void CRevPlayWnd::InitMultiSock()
- {
- int RevBuf;
- int status;
- BOOL bFlag;
- CString ErrMsg;
- SOCKADDR_IN stLocalAddr;
- SOCKADDR_IN stDestAddr;
- SOCKET hNewSock;
- int RevLen=sizeof(RevBuf);
- //创建一个IP组播套接字
- MultiSock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
- (LPWSAPROTOCOL_INFO)NULL, 0,
- WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
- if (MultiSock == INVALID_SOCKET)
- {
- MessageBox("WSASocket() failed");
- return;
- }
- //允许对同一地址bind多次
- bFlag = TRUE;
- status = setsockopt(
- MultiSock, /* socket */
- SOL_SOCKET, /* socket level */
- SO_REUSEADDR, /* socket option */
- (char *)&bFlag, /* option value */
- sizeof (bFlag)); /* size of value */
- if (status == SOCKET_ERROR)
- {
- ErrMsg.Format ("set SO_REUSEADDR failed, Err: %d",WSAGetLastError());
- MessageBox(ErrMsg);
- return;
- }
- // 将套接字绑定到用户指定端口
- stLocalAddr.sin_family = AF_INET;
- // stLocalAddr.sin_port = htons (DestPort);
- stLocalAddr.sin_port = htons (201);
- stLocalAddr.sin_addr.s_addr = INADDR_ANY;
- status = bind (
- MultiSock,
- (struct sockaddr FAR *)&stLocalAddr,
- sizeof(struct sockaddr));
- if (status == SOCKET_ERROR)
- {
- ErrMsg.Format ("Bind(socket: %d, port: %d) failed, Err: %d",
- MultiSock, DestPort, WSAGetLastError());
- MessageBox(ErrMsg);
- }
- //设定接收缓冲区为64k
- RevBuf=65536;
- status = setsockopt(
- MultiSock, /* socket */
- SOL_SOCKET, /* socket level */
- SO_RCVBUF, /* socket option */
- (char *)&RevBuf, /* option value */
- sizeof(RevBuf)); /* size of value */
- if (status == SOCKET_ERROR)
- {
- MessageBox("set SO_REVBUF error");
- return;
- }
- //加入组播组
- stDestAddr.sin_family = PF_INET;
- stDestAddr.sin_port = htons (201);
- stDestAddr.sin_addr.s_addr = inet_addr("234.5.6.7");
- hNewSock = WSAJoinLeaf (MultiSock, /* socket */
- (PSOCKADDR)&stDestAddr, /* multicast address */
- sizeof (stDestAddr), /* length of addr struct */
- NULL, /* caller data buffer */
- NULL, /* callee data buffer */
- NULL, /* socket QOS setting */
- NULL, /* socket group QOS */
- JL_RECEIVER_ONLY); /* do both: send *and* receive */
- if (hNewSock == INVALID_SOCKET)
- {
- ErrMsg.Format ("WSAJoinLeaf() failed, Err: %d",WSAGetLastError());
- MessageBox(ErrMsg);
- }
- }
- int CRevPlayWnd::ReceiveData()
- {//接收组播数据
- CString msg;
- int status;
- DWORD cbRet;
- DWORD dFlag;
- int iLen;
- SOCKADDR_IN stSrcAddr;
- cbRet = 0;
- iLen = sizeof (stSrcAddr);
- dFlag = 0;
- //接收组播数据,存放到缓冲区stWSABuf中
- status = WSARecvFrom (MultiSock, /* socket */
- &stWSABuf, /* input buffer structure */
- 1, /* buffer count */
- &cbRet, /* number of bytes recv'd */
- &dFlag, /* flags */
- (struct sockaddr *)&stSrcAddr,/* source address */
- &iLen, /* size of addr structure */
- NULL, /* overlapped structure */
- NULL); /* overlapped callback function */
- if (status == SOCKET_ERROR)
- {
- //数据丢失,丢失的块数计数加1
- m_LostBlock++;
- msg.Format ("WSARecvFrom() failed, Err:%d", WSAGetLastError());
- MessageBox (msg);
- return -1;
- }
- return cbRet;
- }
- void CRevPlayWnd::OnSave()
- {
- // TODO: Add your command handler code here
- m_Save=!m_Save;
- DWORD dwFlags;
- CString SaveFileName;
- CString strSave;
- TCHAR Driver;
- CFileDialog dlg(TRUE,NULL,"temp.mpg",NULL,"mpeg文件(*.mpg)|*.mpg|AVI文件(*.avi)|*.avi");
- dlg.m_ofn.lpstrTitle="保存到...";
- if(dlg.DoModal()==IDOK)
- {
- SaveFileName=dlg.GetPathName();
- Driver=SaveFileName.GetAt(0);
- CWnd* pParent = GetOwner();
- strSave.Format("保存到:%s",SaveFileName);
- CMainFrame* pFrame=(CMainFrame*)pParent->GetOwner();
- // pFrame->m_wndStatusBar.SetPaneText(1,strSave);
- }
- dwFlags = MMIO_CREATE | MMIO_WRITE;
- hmmioSave = mmioOpen(SaveFileName.GetBuffer(_MAX_PATH), (LPMMIOINFO)NULL, dwFlags);
- SaveFileName.ReleaseBuffer();
- }
- void CRevPlayWnd::OnContextMenu(CWnd* pWnd, CPoint point)
- {
- // TODO: Add your message handler code here
- CMenu menu;
- menu.LoadMenu(IDR_POP_MENU);
- menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this);
- }
- void CRevPlayWnd::OnStopReceive()
- {
- // TODO: Add your command handler code here
- StopReceive();
- m_Save=FALSE;
- m_FirstRead=TRUE;
- m_RenderOk=FALSE;
- m_Stop=FALSE;
- rIndex=0;
- }
- int CRevPlayWnd::InitGraph()
- {//构建Filter Graph
- HRESULT hr;
- hr = S_OK;
- //设置媒体类型,为MPEG1数据流
- mt.majortype = MEDIATYPE_Stream;
- mt.subtype = MEDIASUBTYPE_MPEG1System;
- //创建Source Filter
- m_pStream = new CMemStream(achInBuf, 0x80000000, INFINITE);
- m_pStream->pWnd=this;
- m_rdr = new CMemReader(m_pStream, &mt, &hr);
- if(FAILED(hr) || m_rdr == NULL)
- {
- MessageBox("CMemReader Error");
- return -1;
- }
- m_rdr -> AddRef();
- //创建Filter Graph
- CHECK_ERROR(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IFilterGraph, (void**)&m_pifg),"CoCreateInstance Error") ;
- //将Source Filter加入到Filter Graph中
- CHECK_ERROR(m_pifg -> AddFilter(m_rdr, NULL), "AddFilter Error");
- //查询IGraphBuilder接口
- CHECK_ERROR(m_pifg -> QueryInterface(IID_IGraphBuilder, (void **)&m_pigb),"QueryInterface(IGraphBuilder) Error");
- m_pigb->AddRef ();
- //查询IMediaControl接口
- CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaControl, (void **)&m_pimc),"QueryInterface(IMediaControl) Error");
- m_pimc->AddRef ();
- //查询IVideoWindow接口
- CHECK_ERROR(m_pigb -> QueryInterface(IID_IVideoWindow, (void **)&m_pivw),"QueryInterface(IVideoWindow) Error");
- m_pivw->AddRef ();
- //查询IMediaPosition接口
- CHECK_ERROR(m_pigb -> QueryInterface(IID_IMediaPosition, (void **)&m_ppos),"QueryInterface(IMediaPosition) Error");
- m_ppos->AddRef ();
- return 0;
- }
- void CRevPlayWnd::OnRevPlay()
- {
- // TODO: Add your command handler code here
- int status;
- //建立组播socket,加入组播组
- InitMultiSock();
- //设置响应的网络事件为FD_READ,即读数据
- //发送WSA_READ消息给窗口
- status=WSAAsyncSelect(MultiSock,m_hWnd,WSA_READ,FD_READ);
- if(status<0)
- {
- MessageBox("Error on WSAAsyncSelect()");
- closesocket(MultiSock);
- return;
- }
- //初始化存放接收数据的缓冲区
- for (int i = 0; i< 100; i++ )
- pRevMem[i] =new BYTE[BUFSIZE]; //32k
- m_Receive=TRUE;
- }
- BOOL CMemStream::PeekAndPump()
- {
- static MSG msg;
- while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
- if (!AfxGetApp()->PumpMessage()) {
- ::PostQuitMessage(0);
- return FALSE;
- }
- }
- return TRUE;
- }
- void CRevPlayWnd::RenderFrom(PBYTE Buf, LPCTSTR File)
- {
- CFile f;
- CString MyPath;
- char path[MAX_PATH];
- GetModuleFileName (AfxGetInstanceHandle(), path, _MAX_PATH);
- MyPath = path;
- int index = MyPath.ReverseFind ('\');
- MyPath = MyPath.Left (index+1);
- MyPath += File;
- int r = f.Open (MyPath, CFile::modeRead);
- if(r>0)
- r = f.Read (Buf, BUFSIZE*2);
- else
- return;
- f.Close ();
- }
- DWORD CRevPlayWnd::Parse(PBYTE Ptr, DWORD dwSize, LONGLONG *llTime)
- {
- DWORD RetV;
- DWORD LeftBytes = dwSize;
- while ((LONGLONG)LeftBytes >= 4 ) {
- if (!NextStartCode ((const BYTE **)&Ptr, &LeftBytes))
- break;
- DWORD Code = DWORD_SWAP(*(UNALIGNED DWORD *)Ptr);
- if (VALID_PACKET(Code)) {
- PBYTE PcktPtr;
- DWORD Remain;
- DWORD PtsPos;
- RetV = ParseMPEG1Packet(Ptr, LeftBytes, &PacketData, &PtsPos);
- PcktPtr = Ptr+4;
- Remain = RetV;
- while ((LONG)Remain > 4) {
- if (!NextStartCode ((const BYTE **)&PcktPtr, &Remain))
- break;
- DWORD PcktCode = DWORD_SWAP(*(UNALIGNED DWORD *)PcktPtr);
- switch (PcktCode) {
- case SEQUENCE_HEADER_CODE:
- ParseSequenceHeader(PcktPtr, 0, &SeqInfo);
- return (SeqInfo.dwBitRate);
- }
- PcktPtr += 4;
- Remain -=4 ;
- }
- } else {
- switch (Code) {
- case PACK_START_CODE:
- GetClock (Ptr+4, llTime);
- RetV = PACK_HEADER_LENGTH;
- break;
- case SYSTEM_HEADER_START_CODE:
- RetV = ParseSystemHeader(Ptr, LeftBytes);
- break;
- default:
- RetV = 4;
- break;
- }
- }
- Ptr += RetV;
- LeftBytes -= RetV;
- if (RetV <=0)
- break;
- }
- return 0;
- }
- void CRevPlayWnd::OnUpdateSave(CCmdUI* pCmdUI)
- {
- // TODO: Add your command update UI handler code here
- pCmdUI->Enable (!m_Stop);
- pCmdUI->SetCheck (m_Save);
- }
- void CRevPlayWnd::OnUpdateStopReceive(CCmdUI* pCmdUI)
- {
- // TODO: Add your command update UI handler code here
- pCmdUI->Enable (m_Stop);
- }
- void CRevPlayWnd::StopReceive()
- {
- WSAAsyncSelect(MultiSock,m_hWnd,WSA_READ,0);
- closesocket(MultiSock);
- if (hmmioSave)
- {
- mmioClose(hmmioSave, NULL);
- hmmioSave = NULL;
- }
- if(m_pimc)
- {
- m_pimc -> Pause ();
- m_pimc ->StopWhenReady();
- m_pimc -> Stop();
- }
- if(m_pivw)
- {
- m_pivw -> put_Visible(OAFALSE);
- m_pivw -> put_Owner(NULL);
- }
- HELPER_RELEASE(m_pifg);
- HELPER_RELEASE(m_pigb);
- HELPER_RELEASE(m_pimc);
- HELPER_RELEASE(m_pivw);
- HELPER_RELEASE(m_ppos);
- if(m_pStream)
- {
- delete m_pStream;
- m_pStream = NULL;
- }
- if(m_rdr)
- {
- delete m_rdr;
- m_rdr = NULL;
- }
- for (int i = 0; i< 100; i++)
- {
- if (m_Receive) //表示按了Receive菜单
- if(pRevMem[i])
- delete pRevMem[i];
- pRevMem[i] = NULL;
- }
- }
- void CRevPlayWnd::OnSize(UINT nType, int cx, int cy)
- {
- CWnd::OnSize(nType, cx, cy);
- // TODO: Add your message handler code here
- CRect rect;
- GetClientRect(&rect);
- if(m_pivw)
- m_pivw -> SetWindowPosition(rect.left, rect.top, rect.right, rect.bottom);
- }