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

📄 clientdlg.cpp

📁 利用rtp库实现实时语音传送
💻 CPP
字号:
// ClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Client.h"
#include "ClientDlg.h"
static CLSID const CLSID_DIVX={
	0x78766964, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//extern CAsyncFilter *pFilter;
/////////////////////////////////////////////////////////////////////////////
// CClientDlg dialog

CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CClientDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CClientDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pGraphBuilder = NULL;
	m_pMediaControl = NULL;
	m_pMediaEventEx = NULL;
	m_pMediaSeeking = NULL;
	m_pVideoWindow = NULL;
	m_pBasicVideo = NULL;
	m_pBasicAudio = NULL;
	m_pAsyncFilter = NULL;
	m_currentStatus = statusEmpty;
}

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClientDlg)
	DDX_Control(pDX, SLIDER_TIMER, mSliderGraph);
	DDX_Control(pDX, IDC_VIEW, m_View);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
	//{{AFX_MSG_MAP(CClientDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTPlay, OnBUTPlay)
	ON_BN_CLICKED(IDC_BUTSETRATE, OnButSetRate)
	ON_WM_TIMER()
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientDlg message handlers

BOOL CClientDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	mSliderGraph.SetRange(0,1000);
	mSliderGraph.SetPos(0);
	mSliderTimer = 0;
	SetDlgItemText(IDC_RATE,"30");
	
	if (FAILED(CoInitialize(NULL)))
	{
		AfxMessageBox("Failed to initialze COM", MB_ICONSTOP);
		return FALSE;
	}
	if (FAILED(BuildGraph()))
	{
		AfxMessageBox("Failed to BuildGraph", MB_ICONSTOP);
		return FALSE;
	}
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CClientDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CClientDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
HRESULT CClientDlg::BuildGraph()
{
	HRESULT hr;
	hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraphBuilder);
	if (FAILED(hr))
	{
		MessageBox("Failed to create an instance of FilterGraph\n");
		return hr;
	}

	m_pAsyncFilter = (CAsyncFilter*)CAsyncFilter::CreateInstance(&hr);
	if (FAILED(hr))
	{
		MessageBox("Failed to create an instance of AsyncFilter\n");
		return hr;
	}
	hr = m_pGraphBuilder->AddFilter(m_pAsyncFilter, L"Source Filter");
	if (SUCCEEDED(hr))
	{
		MessageBox("Source inserted in graph\n");
	}
	return S_OK;
}/*
void CClientDlg::OnBUTPlay()
{

	unsigned long remoteIP = inet_addr(MCAST_IP);
		_ASSERT(remoteIP != INADDR_NONE);
  // 创建RTP会话
  status = m_rtpSession.Create(LOCAL_PORT,localIP);
  //checkerror(status);
   m_rtpSession.JoinMulticastGroup(remoteIP);
   int index=0;
   MessageBox("ok1");
  do {
    // 接受RTP数据
    status = sess.PollData();
	// 检索RTP数据源
    if (sess.GotoFirstSourceWithData()) {
      do {
        RTPPacket* packet;
        // 获取RTP数据报
        while ((packet = sess.GetNextPacket()) != NULL) {
         // printf("Got packet !\n");
			index index++;
			MessageBox("ok");
          // 删除RTP数据报
          delete packet;
        }
      } while (sess.GotoNextSourceWithData());
    }
  } while(1);
}*/
IPin *CClientDlg::GetPin(IBaseFilter *pFilter,PIN_DIRECTION PinDir)
{
	BOOL bFound=FALSE;
	IEnumPins *pEnum;
	IPin *pPin;
	pFilter->EnumPins(&pEnum);
	while(pEnum->Next(1,&pPin,0)==S_OK)
	{
		PIN_DIRECTION PinDirThis;
		pPin->QueryDirection(&PinDirThis);
		if(bFound=(PinDir=PinDirThis))
			break;
		pPin->Release();
	}
	pEnum->Release();
	return(bFound?pPin:0);
}

void CClientDlg::OnBUTPlay() 
{
	// TODO: Add your control notification handler code here
    HRESULT   hr;
		MessageBox("succeeded to begin\n");
			IBaseFilter *pDecoderFilter = NULL;
		/*	hr = CoCreateInstance(CLSID_RM_MPEG2_VIDEO_SUBPICTURE, NULL, CLSCTX_INPROC_SERVER,
			IID_IBaseFilter, (LPVOID *) &pDecoderFilter);
		if (FAILED(pigb->AddFilter(pDecoderFilter, L"MPEG4 Source")))
		{
		//	MessageBox(ghApp, "Cannot load decoder filter in Graph!!!", "Error", MB_ICONSTOP);
			return;
		}*/
		 hr=CoCreateInstance(CLSID_DIVX,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void **)&pDecoderFilter);
	if(FAILED(hr))
	{
		MessageBox("Decoder failed111");
	}
	hr =  m_pGraphBuilder->AddFilter(pDecoderFilter, L"Video Decoder");
	if(FAILED(hr))
	{
		MessageBox("Decoder failed1");
	}

//m_pAsyncFilter=pFilter;
		IPin *pPin = GetPin(m_pAsyncFilter, PINDIR_OUTPUT);
		if(pPin!=NULL)
		{
				MessageBox("SUCCEEDED to PIN the Async Filter\n");
//	hr = m_pGraphBuilder->Render(m_pAsyncFilter->GetPin(0));
//IGraphBuilder::Render从某输出PIN开始,建立Graph剩余部分。此函数在下一级添加必要的
				//Filter直到到达Renderer Filter.

	hr = m_pGraphBuilder->Render(pPin);
		}
	if (FAILED(hr))
	{
		MessageBox("Failed to render the Async Filter\n");
	}
	else
		MessageBox("succeeded to render\n");
	if (FAILED(m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&m_pMediaControl)) ||
		FAILED(m_pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void**)&m_pMediaEventEx)) ||
		FAILED(m_pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)&m_pMediaSeeking)) ||
		FAILED(m_pGraphBuilder->QueryInterface(IID_IBasicVideo, (void**)&m_pBasicVideo)) ||
		FAILED(m_pGraphBuilder->QueryInterface(IID_IBasicAudio, (void**)&m_pBasicAudio)) ||
		FAILED(m_pGraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&m_pVideoWindow)))
	{
		MessageBox("Failed to obtain at least one DirectShow interface\n");
		ReleaseMediaInterfaces();
		return ;
	}
	else 
			MessageBox("succeeded to filter\n");
	hr = m_pVideoWindow->put_Visible(OAFALSE);	
	hr = m_pVideoWindow->put_Owner((OAHWND)m_View.m_hWnd);
	hr = m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
	hr = m_pVideoWindow->put_MessageDrain((OAHWND)m_View.m_hWnd);
	hr = m_pVideoWindow->put_Visible(OATRUE);
	ResizeVideoWindow();
#ifdef REGISTER_FILTERGRAPH
    hr = AddGraphToRot(m_pGraphBuilder, &m_dwGraphRegister);
    if (FAILED(hr))
    {
        TRACE("Failed to register filter graph with ROT!  hr=0x%x", hr);
        m_dwGraphRegister = 0;
    }
#endif
	m_pMediaControl->Run();
	
	if (mSliderTimer == 0)
	{
		mSliderTimer = SetTimer(SLIDER_TIMER,100,NULL);
	}

	return ;
}

void CClientDlg::ResizeVideoWindow(void)
{
    // Resize the video preview window to match owner window size
    if (m_pVideoWindow)
    {
        CRect rect;
        
        // Make the preview video fill our window
		::GetClientRect(m_View.m_hWnd,&rect);
        m_pVideoWindow->SetWindowPosition(rect.left,rect.top,
			rect.right,rect.bottom);
    }
}

void CClientDlg::RemoveGraphFromRot(DWORD pdwRegister)
{
    IRunningObjectTable *pROT;
    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
}

void CClientDlg::ReleaseMediaInterfaces()
{
	// Release the graph registration
    if (m_dwGraphRegister)
    {
        RemoveGraphFromRot(m_dwGraphRegister);
        m_dwGraphRegister = 0;
    }

	// Release all COM interfaces to DirectShow
	if(m_pAsyncFilter)
		m_pAsyncFilter->Release();
	m_pAsyncFilter = NULL;

	if (m_pMediaControl)
		m_pMediaControl->Release();
	m_pMediaControl = NULL;
	if (m_pMediaEventEx)
		m_pMediaEventEx->Release();
	m_pMediaEventEx = NULL;
	if (m_pMediaSeeking)
		m_pMediaSeeking->Release();
	m_pMediaSeeking = NULL;
	if (m_pVideoWindow)
		m_pVideoWindow->Release();
	m_pVideoWindow = NULL;
	if (m_pBasicVideo)
		m_pBasicVideo->Release();
	m_pBasicVideo = NULL;
	if (m_pBasicAudio)
		m_pBasicAudio->Release();
	m_pBasicAudio = NULL;

	if (m_pGraphBuilder)
		m_pGraphBuilder->Release();
	m_pGraphBuilder = NULL;
}

HRESULT CClientDlg::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
    IMoniker * pMoniker;
    IRunningObjectTable *pROT;
    if (FAILED(GetRunningObjectTable(0, &pROT))) {
        return E_FAIL;
    }
    WCHAR wsz[128];
    wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
    HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) {
        hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
        pMoniker->Release();
    }
    pROT->Release();
    return hr;
}

void CClientDlg::OnButSetRate() 
{
	// TODO: Add your control notification handler code here
	double oldRefTime;
	UINT Fps = GetDlgItemInt(IDC_RATE);
	//m_pMediaControl->Pause();
	//CComQIPtr<IBasicVideo , &IID_IBasicVideo > spBaseVideo(m_pGraphBuilder);
	HRESULT hr = m_pBasicVideo->get_AvgTimePerFrame(&oldRefTime);

	//CComQIPtr<IMediaSeeking , &IID_IMediaSeeking > spMediaCSeeking(m_pGraphBuilder);
	if(SUCCEEDED(hr)) {
		double dblNewRat = 1./(1./(double)Fps/oldRefTime);

		m_pMediaSeeking->SetRate(dblNewRat);
	}
	//m_pMediaControl->Run();
	return;
}

void CClientDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if ( nIDEvent == mSliderTimer) {
		double pos = 0, duration = 1;
		m_pMediaSeeking->GetCurrentPosition((__int64*)&pos);
		m_pMediaSeeking->GetDuration((__int64*)&duration);
		int newPos = int(pos * 1000 / duration);
		if(mSliderGraph.GetPos() != newPos)
			mSliderGraph.SetPos(newPos);
	}
	CDialog::OnTimer(nIDEvent);
}

void CClientDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	if (pScrollBar->GetSafeHwnd() == mSliderGraph.GetSafeHwnd()) {
		if (m_pMediaSeeking) {
			double duration = 1.;
			m_pMediaSeeking->GetDuration((__int64*)&duration);
			double pos = duration * mSliderGraph.GetPos() / 1000.;
			m_pMediaSeeking->SetPositions((__int64*)&pos,AM_SEEKING_AbsolutePositioning,
				NULL,AM_SEEKING_NoFlush);

		}
	} else
		CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -