📄 revplaymdichildwnd.cpp
字号:
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -