www.pudn.com > rtptest.rar > ClientDlg.cpp


// ClientDlg.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "Client.h" 
#include "ClientDlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// 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)) 
	{ 
		TRACE0("Failed to create an instance of FilterGraph\n"); 
		return hr; 
	} 
 
	m_pAsyncFilter = (CAsyncFilter*)CAsyncFilter::CreateInstance(&hr); 
	if (FAILED(hr)) 
	{ 
		TRACE0("Failed to create an instance of AsyncFilter\n"); 
		return hr; 
	} 
	hr = m_pGraphBuilder->AddFilter(m_pAsyncFilter, L"Source Filter"); 
	if (SUCCEEDED(hr)) 
	{ 
		TRACE0("Source inserted in graph\n"); 
	} 
	return S_OK; 
} 
 
void CClientDlg::OnBUTPlay()  
{ 
	// TODO: Add your control notification handler code here 
	HRESULT hr; 
	hr = m_pGraphBuilder->Render(m_pAsyncFilter->GetPin(0)); 
	if (FAILED(hr)) 
	{ 
		TRACE0("Failed to render the Async Filter\n"); 
		return ; 
	} 
	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))) 
	{ 
		TRACE0("Failed to obtain at least one DirectShow interface\n"); 
		ReleaseMediaInterfaces(); 
		return ; 
	} 
	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 spBaseVideo(m_pGraphBuilder); 
	HRESULT hr = m_pBasicVideo->get_AvgTimePerFrame(&oldRefTime); 
 
	//CComQIPtr 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); 
}