MMSGraph.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:21k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19. #include "stdafx.h"
  20. #include "mmsgraph.h"
  21. #include "configFile.h"
  22. #include "string.h"
  23. //  {6B6D0800-9ADA-11d0-A520-00A0D10129C0}
  24. DEFINE_GUID(CLSID_NetShowSource, 
  25. 0x6b6d0800, 0x9ada, 0x11d0, 0xa5, 0x20, 0x0, 0xa0, 0xd1, 0x1, 0x29, 0xc0);
  26. //////////////////////////////////////////////
  27. // Only for Debug
  28. static DWORD g_dwRegister;
  29. static HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
  30. {
  31. #ifdef _DEBUG
  32.     IMoniker * pMoniker;
  33.     IRunningObjectTable *pROT;
  34.     HRESULT hr;
  35.     hr = GetRunningObjectTable(0, &pROT);
  36.     if (FAILED(hr)) return hr;
  37.     WCHAR wsz[128];
  38.     wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
  39.     hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  40.     if (SUCCEEDED(hr)) 
  41. {
  42.         hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
  43.         pMoniker->Release();
  44.     }
  45.     pROT->Release(); 
  46.     return hr;
  47. #endif
  48. return S_OK;
  49. }
  50. static void RemoveGraphFromRot(DWORD pdwRegister)
  51. {
  52. #ifdef _DEBUG
  53.     IRunningObjectTable *pROT;
  54.     if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) 
  55. {
  56.         pROT->Revoke(pdwRegister);
  57.         pROT->Release();
  58.     }
  59. #endif
  60. }
  61. /////////////////////////////////////////////////////////////////
  62. // CMMSGraph
  63. CMMSGraph::CMMSGraph(string strChannel, string strMMSAddr, HRESULT *hr)
  64. {
  65. m_pGB = NULL;
  66. m_pMC = NULL;
  67. m_pMMSSource = NULL;
  68. m_pSink = NULL;
  69. m_pAsfAcmHandler = NULL;
  70. m_pAsfIcmHandler = NULL;
  71. m_pAudioSmartTee = NULL;
  72. m_pTVConfig = NULL;
  73. m_pMMSInfo = new MMSGRAPHINFO;
  74. m_pMMSInfo->fDataRate = 0.0;
  75. m_pMMSInfo->fTotalBytes=0;
  76. m_pMMSInfo->m_oldtotalbyte=0;
  77. m_pMMSInfo->mmsState = INIT;
  78. m_pMMSInfo->llTimeEscaped = 0;
  79. m_pMMSInfo->strChannelName = strChannel;
  80. m_pMMSInfo->strMMSAddr = strMMSAddr;
  81. m_pMMSInfo->llTimeEscaped = 0;
  82.     m_pMMSInfo->m_time=0;
  83.     m_bReconnecting = false;
  84. *hr = Initialize();
  85. }
  86. CMMSGraph::~CMMSGraph()
  87. {
  88.     m_bReconnecting = false;
  89. SAFE_RELEASE(m_pSink);
  90. SAFE_RELEASE(m_pTVConfig);
  91. Uninitialize();
  92. if(m_pMMSInfo)
  93. {
  94. delete m_pMMSInfo;
  95. m_pMMSInfo = NULL;
  96. }
  97. }
  98. STDMETHODIMP CMMSGraph::Run()
  99. {
  100. if(m_pMC)
  101. return m_pMC->Run();
  102. return E_FAIL;
  103. }
  104. STDMETHODIMP CMMSGraph::Stop()
  105. {
  106. if(m_pMC)
  107. return m_pMC->Stop();
  108. return E_FAIL;
  109. }
  110. STDMETHODIMP CMMSGraph::Pause()
  111. {
  112. if(m_pMC)
  113. return m_pMC->Pause();
  114. return E_FAIL;
  115. }
  116. STDMETHODIMP CMMSGraph::Uninitialize()
  117. {
  118. RemoveGraphFromRot(g_dwRegister);
  119. DisassembleGraph();
  120. // release all objects
  121. SAFE_RELEASE(m_pGB);
  122. SAFE_RELEASE(m_pMC);
  123. // release COM lib
  124. CoUninitialize();
  125. return S_OK;
  126. }
  127. STDMETHODIMP CMMSGraph::BuildGraph(bool bAssumeAudioFirst)
  128. {
  129. // add/config source filter
  130. if(FAILED(CreateAddFilter(CLSID_NetShowSource, &m_pMMSSource)))
  131. {
  132. AfxMessageBox("can not create & add mms source filter!");
  133. return E_FAIL;
  134. }
  135. IFileSourceFilter *pSF;
  136. if(FAILED(m_pMMSSource->QueryInterface(IID_IFileSourceFilter, (VOID**)&pSF)))
  137. {
  138. AfxMessageBox("can not query interface of mms source filter!");
  139. return E_FAIL;
  140. }
  141. WCHAR wstrAddr[1024];
  142. MultiByteToWideChar(CP_ACP, 
  143. MB_PRECOMPOSED | MB_USEGLYPHCHARS,
  144. m_pMMSInfo->strMMSAddr.data(),
  145. -1, 
  146. wstrAddr, 
  147. sizeof(wstrAddr) / sizeof(WCHAR));
  148. HRESULT hr;
  149. hr =  pSF->Load(wstrAddr, NULL);  
  150. if(FAILED(hr))
  151. {
  152. string strError;
  153. char s[100];
  154. wsprintf(s, "无法读取mms流:%s,请检查这个流是否可用。", m_pMMSInfo->strMMSAddr.data());
  155.    strError.append(s);
  156.   //AfxMessageBox(strError.data());
  157.     return FALSE;
  158.  
  159. }
  160. pSF->Release();
  161.     /*
  162.     IEnumPins* enumPin = NULL;
  163.     hr = m_pMMSSource->EnumPins(&enumPin);
  164.     IPin* pins = NULL
  165.     hr = enumPin->Next(1, &pins, NULL);
  166.     AM_MEDIA_TYPE type;
  167.     hr = pins->ConnectionMediaType(&type);
  168.     if(type.formattype == FORMAT_VideoInfo) {
  169.         pins->ConnectedTo(
  170.     }
  171.     */
  172.     if(m_pSink == NULL) {
  173.     // add our sink filter
  174.       if(FAILED(CreateAddFilter(CLSID_TVStreamSink, &m_pSink)))
  175.     {
  176.     AfxMessageBox("can not create & add capture filter!");
  177.     return E_FAIL;
  178.     }
  179.      
  180.     if(FAILED(m_pSink->QueryInterface(IID_ITVSouceConfig, (VOID**)&m_pTVConfig)))
  181.     {
  182.     AfxMessageBox("can not query interface of captureserver!");
  183.     return E_FAIL;
  184.     }
  185.     }
  186.     else {
  187. // No filter name specified, cannot convert
  188. // try to add it to the filter graph
  189. hr = m_pGB->AddFilter(m_pSink, NULL);
  190.         if(hr != S_OK)
  191.     {
  192.     AfxMessageBox("can not add capture filter!");
  193.     return E_FAIL;
  194.     }
  195.     }
  196. // connect graph
  197. // audio channel
  198. BOOL bHasAudio = TRUE;
  199. BOOL bHasVideo = TRUE;
  200. if(SUCCEEDED(FindASFHandler("ASF ACM Handler")))
  201. {
  202. VERIFY(SUCCEEDED(m_pGB->AddFilter(m_pAsfAcmHandler, NULL)));
  203.         hr = ConnectPins(m_pMMSSource, bAssumeAudioFirst?__T("Stream 1"):__T("Stream 2"), m_pAsfAcmHandler,NULL);
  204.         if(hr != S_OK) {
  205.             DisassembleGraph();
  206.             hr = BuildGraph(false);
  207.             return hr;
  208.         }
  209.         hr = ConnectPins(m_pAsfAcmHandler, NULL, m_pSink, __T("Audio"));
  210.         if(hr != S_OK) {
  211.         ASSERT(0);
  212. bHasAudio = FALSE;
  213. RemoveFilter(m_pAsfAcmHandler);
  214. SAFE_RELEASE(m_pAsfAcmHandler);
  215.         }
  216.         /*
  217.         if((FAILED(ConnectPins(m_pMMSSource, __T("Stream 1"), m_pAsfAcmHandler,NULL) && 
  218.            FAILED(ConnectPins(m_pMMSSource, __T("Stream 2"), m_pAsfAcmHandler,NULL)) || 
  219.            FAILED(ConnectPins(m_pAsfAcmHandler, NULL, m_pSink, __T("Audio"))))))
  220. {
  221.         ASSERT(0);
  222. bHasAudio = FALSE;
  223. RemoveFilter(m_pAsfAcmHandler);
  224. SAFE_RELEASE(m_pAsfAcmHandler);
  225. }
  226.         */
  227. }
  228. else
  229. bHasAudio = FALSE;
  230. // video channel
  231. if(SUCCEEDED(FindASFHandler("ASF ICM Handler")))
  232. {
  233.         VERIFY(SUCCEEDED(m_pGB->AddFilter(m_pAsfIcmHandler, NULL)));
  234.         hr = ConnectPins(m_pMMSSource, bAssumeAudioFirst?__T("Stream 2"):__T("Stream 1"), m_pAsfIcmHandler,NULL);
  235.         if(hr != S_OK) {
  236.             DisassembleGraph();
  237.             hr = BuildGraph(false);
  238.             return hr;
  239.         }
  240.         hr = ConnectPins(m_pAsfIcmHandler, NULL, m_pSink, __T("Video"));
  241.         if(hr != S_OK) {
  242.             ASSERT(0);
  243.             bHasVideo = FALSE;
  244.             RemoveFilter(m_pAsfIcmHandler);
  245.             SAFE_RELEASE(m_pAsfIcmHandler);
  246.         }
  247.         /*
  248. if((FAILED(ConnectPins(m_pMMSSource, __T("Stream 2"), m_pAsfIcmHandler,NULL) &&
  249.            FAILED(ConnectPins(m_pMMSSource, __T("Stream 1"), m_pAsfIcmHandler,NULL)) ||
  250.    FAILED(ConnectPins(m_pAsfIcmHandler, NULL, m_pSink, __T("Video"))))))
  251.         ASSERT(0);
  252. bHasVideo = FALSE;
  253. RemoveFilter(m_pAsfIcmHandler);
  254. SAFE_RELEASE(m_pAsfIcmHandler);
  255. }
  256.         */
  257. #ifdef TIME_EXPIRE
  258.         /// 如果过了2006-03-21日,就返回错误
  259.         tm expire_tm;
  260.         memset(&expire_tm, 0, sizeof(expire_tm));
  261.         expire_tm.tm_year = 106;
  262.         expire_tm.tm_mon = 2;
  263.         expire_tm.tm_mday = 21;
  264.         time_t expire_seconds = mktime(&expire_tm);
  265.         time_t now;
  266.         time( &now );                /* Get time as long integer. */
  267.         if(now > expire_seconds)
  268.             return E_FAIL;
  269. #endif
  270. }
  271. else
  272. bHasVideo = FALSE;
  273. if(!bHasVideo && !bHasAudio)
  274. {
  275. AfxMessageBox("Sorry, MMS Server cant get media. plz check mms address is right!");
  276. return E_FAIL;
  277. }
  278. if(!bHasVideo)
  279. {
  280. // AfxMessageBox("warning:no video captured!");
  281. //return S_FALSE;
  282.   m_pTVConfig->SetAudioOrVideoOnly(TRUE); // set audio only
  283. }
  284. if(!bHasAudio)
  285. {
  286. AfxMessageBox("warning:no audio captured!");
  287. return S_FALSE;
  288. }
  289. return 1 ; 
  290. }
  291. STDMETHODIMP CMMSGraph::DisassembleGraph()
  292. {
  293. Stop();
  294. // remove all filters from graph
  295. RemoveFilter(m_pMMSSource);
  296. RemoveFilter(m_pSink);
  297. if(m_pAsfAcmHandler)
  298. RemoveFilter(m_pAsfAcmHandler);
  299. if(m_pAsfAcmHandler)
  300. RemoveFilter(m_pAsfIcmHandler);
  301. if(m_pAudioSmartTee)
  302. RemoveFilter(m_pAudioSmartTee);
  303. SAFE_RELEASE(m_pMMSSource);
  304. SAFE_RELEASE(m_pAsfIcmHandler);
  305. SAFE_RELEASE(m_pAsfAcmHandler);
  306. SAFE_RELEASE(m_pAudioSmartTee);
  307. return S_OK;
  308. }
  309. MMSGRAPHINFO *CMMSGraph::GetMMSGraphInfo()
  310.     ////////////Get  the  value of  the ResStartTime 
  311. CString str_path;
  312. GetModuleFileName(NULL,str_path.GetBuffer(MAX_PATH),MAX_PATH);
  313. str_path.ReleaseBuffer();
  314. int index = str_path.ReverseFind('\');
  315.     str_path=  str_path.Left(index+1);
  316.     int ResStartTime = 10;
  317.     static bool reconnecting = false;
  318. // speed
  319. m_pMMSInfo->fDataRate = m_pTVConfig->GetCompressedSpeed();
  320.     m_pMMSInfo->fTotalBytes=m_pTVConfig->GetTotalBytes(); //get current totalbytes
  321.  
  322.  if(m_pMMSInfo->fTotalBytes>m_pMMSInfo->m_oldtotalbyte) //if we got new data
  323. {
  324. if (m_pMMSInfo->mmsState==RUNNING)
  325.  m_pMMSInfo->llTimeEscaped++;
  326.      m_pMMSInfo->m_time=0;   //recount
  327.  }
  328.  else  if(m_pMMSInfo->mmsState != STOPPED )//if data stopped
  329.  {
  330.  m_pMMSInfo->m_time++;
  331.          if(m_pTVConfig->EndOfStream() || m_pMMSInfo->m_time >= ResStartTime) {
  332.             if(!m_bReconnecting) {
  333.                 m_bReconnecting = true;
  334.                 HRESULT ret = this->DisassembleGraph();
  335.                 ret = this->BuildGraph();
  336.                 ret = this->Run();
  337.                 m_bReconnecting = false;
  338.             }
  339. m_pMMSInfo->m_time=0;  //recount
  340.         }
  341.  }
  342.  
  343.  if (m_pMMSInfo->m_time==0)  
  344.  m_pMMSInfo->m_oldtotalbyte=m_pMMSInfo->fTotalBytes;
  345.  
  346.     // state
  347.  OAFilterState os;
  348.  m_pMC->GetState(100, &os);
  349.  
  350.  if(os == State_Running)
  351.  m_pMMSInfo->mmsState = RUNNING;
  352.      else if(os == State_Stopped) {
  353.  m_pMMSInfo->mmsState = STOPPED;
  354.          if(m_bReconnecting)
  355.              m_pMMSInfo->mmsState = RECONNECTING;
  356.      }
  357.  else if(os == State_Paused)
  358.  m_pMMSInfo->mmsState = PAUSED;
  359.  else
  360.  m_pMMSInfo->mmsState = INIT;
  361.  
  362.  // time escaped 
  363.  return m_pMMSInfo;
  364. }
  365. STDMETHODIMP CMMSGraph::CreateAddFilter(CLSID clsidFilter,    
  366.  IBaseFilter** ppIFilter,
  367.  LPCTSTR pstrFilterName)
  368. {
  369. HRESULT hr;
  370. ASSERT(m_pGB);
  371. ASSERT(ppIFilter);
  372. (*ppIFilter) = NULL;
  373. // try to instantiate the filter
  374. hr = CoCreateInstance(clsidFilter, 
  375.  NULL, 
  376.  CLSCTX_INPROC, 
  377.  IID_IBaseFilter,
  378.  (LPVOID*)(ppIFilter));
  379. if(FAILED(hr))
  380. {
  381. TRACE("Could not instantiate filter");
  382. return hr;
  383. }
  384. // Check for unicode or not
  385. #ifndef _UNICODE
  386. if(pstrFilterName)
  387. {
  388. // not unicode, we need to unicodify the string
  389. WCHAR wstrFilterName[256];
  390. MultiByteToWideChar(CP_ACP, 
  391. MB_PRECOMPOSED | MB_USEGLYPHCHARS,
  392.     pstrFilterName,
  393. -1, 
  394.     wstrFilterName, 
  395. sizeof(wstrFilterName) / sizeof(WCHAR));
  396. // try to add it to the filter graph
  397. hr = m_pGB->AddFilter(*ppIFilter, wstrFilterName);
  398. }
  399. else
  400. {
  401. // No filter name specified, cannot convert
  402. // try to add it to the filter graph
  403. hr = m_pGB->AddFilter(*ppIFilter, NULL);
  404. }
  405. #else
  406. // already unicode, no need to change anything
  407. // try to add it to the filter graph
  408. hr = m_pGB->AddFilter(*ppIFilter, pstrFilterName);
  409. #endif
  410. // check the result of the operation
  411. if(FAILED(hr))
  412. {
  413. TRACE("Could not add filter to filter graphn");
  414. // free the filter definitely
  415. (*ppIFilter)->Release();
  416. (*ppIFilter) = NULL;
  417. return hr;
  418. }
  419. // that's it
  420. return hr;
  421. }
  422. STDMETHODIMP CMMSGraph::RemoveFilter(IBaseFilter* pIFilter)
  423. {
  424. HRESULT hr;
  425.    // Parameters...
  426.    if(!pIFilter)
  427.       // DON'T return an error, this is expected
  428.       return NOERROR;
  429.    ASSERT(m_pGB);
  430.    // Just remove it from the graph
  431.    hr = m_pGB->RemoveFilter(pIFilter);
  432.    // Check the result
  433.    if(FAILED(hr))
  434.       TRACE("Could not remove filter from filter graphn");
  435.    return hr;
  436. }
  437. STDMETHODIMP CMMSGraph::ConnectPins(IBaseFilter* pIFilterOutput, 
  438.    LPCTSTR pstrPinNameOutput,
  439.    IBaseFilter* pIFilterInput, 
  440.    LPCTSTR pstrPinNameInput,
  441.    AM_MEDIA_TYPE* pmt)
  442. {
  443. HRESULT hr;
  444. ASSERT(m_pGB);
  445. // Parameters...
  446. if((!pIFilterOutput) || (!pIFilterInput))
  447. {
  448. //ASSERT(pIFilterOutput && pIFilterInput);
  449. TRACE("ConnectPins called with NULL parametern");
  450. return E_INVALIDARG;
  451. }
  452. // Find the first pin
  453. IPin* pIPinOutput = FindPinOnFilter(pIFilterOutput, 
  454. pstrPinNameOutput,
  455.     PINDIR_OUTPUT);
  456. if(!pIPinOutput)
  457. {
  458. // ASSERT(pIPinOutput);
  459. return E_FAIL;
  460. }
  461. // Find the second pin
  462. IPin* pIPinInput = FindPinOnFilter(pIFilterInput,
  463.    pstrPinNameInput,
  464.    PINDIR_INPUT);
  465. if(!pIPinInput)
  466. {
  467. //ASSERT(pIPinInput);
  468. // release the other pin
  469. pIPinOutput->Release();
  470. return E_FAIL;
  471. }
  472. if(FAILED(pIPinOutput->Disconnect()))
  473. {
  474. //ASSERT(FALSE);
  475. return E_FAIL;
  476. }
  477. if(FAILED(pIPinInput->Disconnect()))
  478. {
  479. //ASSERT(FALSE);
  480. return E_FAIL;
  481. }
  482. // Now just connect the two pins
  483.     if(NULL == pmt || pmt->cbFormat == 0)
  484.        hr = m_pGB->Connect(pIPinOutput, pIPinInput);
  485. else
  486. hr = m_pGB->ConnectDirect(pIPinOutput, pIPinInput, pmt);
  487. if(FAILED(hr))
  488.   TRACE("Could not connect pins!");
  489. // Release the two pins and return the result
  490. pIPinOutput->Release();
  491. pIPinInput->Release();
  492. return hr;
  493. }
  494. STDMETHODIMP CMMSGraph::DisconnectPin(IBaseFilter *pIFilter, 
  495.  LPCTSTR pstrPinName,
  496.  PIN_DIRECTION dir)
  497. {
  498. HRESULT hr;
  499. ASSERT(m_pGB);
  500. // Parameters...
  501. if(!pIFilter)
  502.   // DON'T fail on this, it is expected
  503.   return NOERROR;
  504. // Find the pin
  505. IPin* pIPin = FindPinOnFilter(pIFilter, pstrPinName, dir);
  506. if(!pIPin)
  507. {
  508. TRACE("Could not find specified filter pinn");
  509. return E_FAIL;
  510. }
  511. // Find the pin it's connected to
  512. IPin* pIPinConnected;
  513. hr = pIPin->ConnectedTo(&pIPinConnected);
  514. if((FAILED(hr)) || (!pIPinConnected))
  515. {
  516. // Function call failed, pin not connected, nothing to do!
  517. pIPin->Release();
  518. return NOERROR;
  519. }
  520. // Try to disconnect the input pin first
  521. if (dir == PINDIR_INPUT)
  522. {
  523. // ok now disconnect both of them
  524. hr = m_pGB->Disconnect(pIPin);
  525. if(FAILED(hr))
  526. {
  527. // just forget everything
  528. ASSERT(SUCCEEDED(hr));
  529. pIPin->Release();
  530. pIPinConnected->Release();
  531. TRACE("Disconnect failed on input pinn");
  532. return hr;
  533. }
  534. hr = m_pGB->Disconnect(pIPinConnected);
  535. if(FAILED(hr))
  536. {
  537. ASSERT(SUCCEEDED(hr));
  538. TRACE("Disconnect failed on output pinn");
  539. }
  540. }
  541.    else
  542.    {
  543. // ok now disconnect both of them
  544. hr = m_pGB->Disconnect(pIPinConnected);
  545. if(FAILED(hr))
  546. {
  547. ASSERT(SUCCEEDED(hr));
  548. // just forget everything
  549. pIPin->Release();
  550. pIPinConnected->Release();
  551. TRACE("Disconnect failed on input pinn");
  552. return hr;
  553. }
  554. hr = m_pGB->Disconnect(pIPin);
  555. if(FAILED(hr))
  556. {
  557. ASSERT(SUCCEEDED(hr));
  558. TRACE("Disconnect failed on output pinn");
  559. }
  560.    }
  561.    // Just release the two pins and return last result
  562.    pIPin->Release();
  563.    pIPinConnected->Release();
  564.    return hr;
  565. }
  566. STDMETHODIMP_(BOOL) CMMSGraph::IsConnected(IBaseFilter *pFilter,
  567.                         LPCTSTR pstrPinName, 
  568. PIN_DIRECTION pd)
  569. {
  570. ASSERT(m_pGB);
  571. // Parameters...
  572. if((!pFilter))
  573. {
  574. ASSERT(pFilter);
  575. TRACE("ConnectPins called with NULL parametern");
  576. return FALSE;
  577. }
  578. // Find the pin
  579. IPin* pIPin = FindPinOnFilter(pFilter, 
  580.   pstrPinName,
  581.   pd);
  582. if(!pIPin)
  583. {
  584. ASSERT(pIPin);
  585. return FALSE;
  586. }
  587. IPin  *pNextPin = NULL;
  588. pIPin->ConnectedTo(&pNextPin);
  589. if(!pNextPin)
  590. {
  591. return FALSE;
  592. }
  593. pIPin->Release();
  594. pNextPin->Release();
  595. //That's it...
  596. return TRUE;
  597. }
  598. STDMETHODIMP_(IPin*) CMMSGraph::FindPinOnFilter(IBaseFilter* pIFilter, 
  599.              LPCTSTR pstrPinName,
  600.              PIN_DIRECTION dir)
  601. {
  602. HRESULT     hr;
  603. IEnumPins*  pIEnumPins;
  604. IPin*       pIPin;
  605. PIN_INFO    pi;
  606. ASSERT(m_pGB);
  607. // Parameters...
  608. if(!pIFilter)
  609.   return NULL;
  610. // Enumerate pins on the filter
  611. hr = pIFilter->EnumPins(&pIEnumPins);
  612. if(FAILED(hr))
  613.   // pin was not found!
  614.   return NULL;
  615. // Loop till we find no more pins
  616. IPin* pIPinFound = NULL;
  617. while( (!pIPinFound) && (pIEnumPins->Next(1, &pIPin, NULL)==S_OK) )
  618. {
  619. // Is this the pin?
  620. hr = pIPin->QueryPinInfo(&pi);
  621. if(!FAILED(hr))
  622. {
  623. // check if it is the right direction
  624. if(pi.dir == dir)
  625. {
  626. // Let the graph builder find the right filter
  627. TCHAR strFoundPinName[256];
  628. #ifndef _UNICODE
  629.    // not unicode, we need to de-unicodify the returned pin name
  630.    WideCharToMultiByte(CP_ACP, NULL,
  631.    pi.achName, -1,
  632.    strFoundPinName, sizeof(strFoundPinName),
  633.    NULL, NULL);
  634. #else
  635.    // just make a copy of the string
  636.    lstrcpyn(strFoundPinName, pi.achName, sizeof(strFoundPinName));
  637. #endif
  638. // check if there is a pin name specified
  639. if(!pstrPinName)
  640. {
  641. // no name specified, take the first pin found
  642. pIPinFound = pIPin;
  643. pIPinFound->AddRef();
  644. }
  645. // check if we have the right pin name
  646. else if(lstrcmp(strFoundPinName, pstrPinName)==0)
  647. {
  648. // yes we have!
  649. pIPinFound = pIPin;
  650. pIPinFound->AddRef();
  651. }
  652. }
  653. // release the PIN_INFO data
  654. pi.pFilter->Release();
  655. }
  656. // release the IPin pointer
  657. pIPin->Release();
  658. }
  659. // Finished with the enumerator, let it go (be free)
  660. pIEnumPins->Release();
  661. // Return whatever we have found
  662. return pIPinFound;
  663. }
  664. HRESULT CMMSGraph::FindASFHandler(string strFilterName)
  665. {
  666. HRESULT hr;
  667.     IMoniker *pMoniker =NULL;
  668.     ULONG cFetched;
  669.     // Create the system device enumerator
  670.     ICreateDevEnum* pDevEnum = NULL;
  671.     hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
  672.                            IID_ICreateDevEnum, (void **) &pDevEnum);
  673.     if (FAILED(hr))
  674.     {
  675.         TRACE1(TEXT("Couldn't create system enumerator!  hr=0x%x"), hr);
  676.         return hr;
  677.     }
  678.     IEnumMoniker *pClassEnum = NULL;
  679.     hr = pDevEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory, &pClassEnum, 0);
  680.     if (FAILED(hr))
  681.     {
  682. pDevEnum->Release();
  683.         TRACE1(TEXT("Couldn't create class enumerator!  hr=0x%x"), hr);
  684.         return hr;
  685.     }
  686.     if (pClassEnum == NULL)
  687. {
  688. pDevEnum->Release();
  689.         return E_FAIL;
  690. }
  691. BOOL bFinded = FALSE;
  692.     while (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
  693.     {
  694. IPropertyBag *pPropBag;
  695.         hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
  696.                                      (void **)&pPropBag);
  697.         if (SUCCEEDED(hr))
  698.         {
  699.             VARIANT varName;
  700.             VariantInit(&varName);
  701.             hr = pPropBag->Read(L"FriendlyName", &varName, 0);
  702.             if (SUCCEEDED(hr))
  703.             {
  704.                 int cch = lstrlenW(varName.bstrVal) + 1;
  705. CHAR* lpszFilterName = new char[cch * 2];
  706. if (!lpszFilterName) 
  707.        return E_OUTOFMEMORY;
  708. WideCharToMultiByte(GetACP(), 0, varName.bstrVal, -1,
  709.      lpszFilterName, cch, NULL, NULL);
  710. string str;
  711. str.append(lpszFilterName);
  712. if(strFilterName == str)
  713. {
  714. if(str == "ASF ACM Handler")
  715. {
  716. pMoniker->BindToObject(NULL, NULL, 
  717. IID_IBaseFilter,
  718. (VOID**)&m_pAsfAcmHandler);
  719. bFinded = TRUE;
  720. }
  721. else if(str == "ASF ICM Handler")
  722. {
  723. pMoniker->BindToObject(NULL, NULL, 
  724. IID_IBaseFilter,
  725. (VOID**)&m_pAsfIcmHandler);
  726. bFinded = TRUE;
  727. }
  728. else
  729. ASSERT(FALSE);
  730. delete [] lpszFilterName;
  731. VariantClear(&varName);
  732. pPropBag->Release();
  733. pMoniker->Release();
  734. break;
  735. }
  736. delete [] lpszFilterName;
  737.             }
  738.             VariantClear(&varName);
  739. pPropBag->Release();
  740. }
  741. pMoniker->Release();
  742.     }
  743. pClassEnum->Release();
  744. pDevEnum->Release();
  745. if(bFinded)
  746.     return S_OK;
  747. return E_FAIL;
  748. }
  749. STDMETHODIMP CMMSGraph::Initialize()
  750. {
  751.     HRESULT hr = CoInitialize(NULL);
  752.     if (FAILED(hr))
  753.     {
  754.         TRACE0("ERROR - Could not initialize COM library");
  755.         return hr;
  756.     }
  757. // Create the filter graph manager and query for interfaces.
  758.     hr = CoCreateInstance(CLSID_FilterGraph, 
  759.                   NULL, 
  760.   CLSCTX_INPROC_SERVER, 
  761.                           IID_IGraphBuilder, 
  762.   (void **)&m_pGB);
  763.     if (FAILED(hr))
  764.     {
  765.         TRACE0("ERROR - Could not create the Filter Graph Manager.");
  766.         return hr;
  767.     }
  768. hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
  769. if (FAILED(hr))
  770.     {
  771.         TRACE0("ERROR - Could not Get IMediaControl");
  772.         return hr;
  773.     }
  774. AddGraphToRot(m_pGB, &g_dwRegister);  
  775.   
  776. if(!BuildGraph())
  777. {
  778.  return -1 ;
  779. }
  780. return S_OK;
  781. }