DsDemoDlg.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:10k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // DsDemoDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "DsDemo.h"
  5. #include "DsDemoDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CDsDemoDlg dialog
  13. CDsDemoDlg::CDsDemoDlg(CWnd* pParent /*=NULL*/)
  14. : CDialog(CDsDemoDlg::IDD, pParent)
  15. {
  16. //{{AFX_DATA_INIT(CDsDemoDlg)
  17. // NOTE: the ClassWizard will add member initialization here
  18. //}}AFX_DATA_INIT
  19. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  20. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  21. }
  22. void CDsDemoDlg::DoDataExchange(CDataExchange* pDX)
  23. {
  24. CDialog::DoDataExchange(pDX);
  25. //{{AFX_DATA_MAP(CDsDemoDlg)
  26. // NOTE: the ClassWizard will add DDX and DDV calls here
  27. //}}AFX_DATA_MAP
  28. }
  29. BEGIN_MESSAGE_MAP(CDsDemoDlg, CDialog)
  30. //{{AFX_MSG_MAP(CDsDemoDlg)
  31. ON_WM_PAINT()
  32. ON_WM_QUERYDRAGICON()
  33. //}}AFX_MSG_MAP
  34. END_MESSAGE_MAP()
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CDsDemoDlg message handlers
  37. BOOL CDsDemoDlg::OnInitDialog()
  38. {
  39. CDialog::OnInitDialog();
  40. // Set the icon for this dialog.  The framework does this automatically
  41. //  when the application's main window is not a dialog
  42. SetIcon(m_hIcon, TRUE); // Set big icon
  43. SetIcon(m_hIcon, FALSE); // Set small icon
  44. // TODO: Add extra initialization here
  45. return TRUE;  // return TRUE  unless you set the focus to a control
  46. }
  47. // If you add a minimize button to your dialog, you will need the code below
  48. //  to draw the icon.  For MFC applications using the document/view model,
  49. //  this is automatically done for you by the framework.
  50. void CDsDemoDlg::OnPaint() 
  51. {
  52. if (IsIconic())
  53. {
  54. CPaintDC dc(this); // device context for painting
  55. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  56. // Center icon in client rectangle
  57. int cxIcon = GetSystemMetrics(SM_CXICON);
  58. int cyIcon = GetSystemMetrics(SM_CYICON);
  59. CRect rect;
  60. GetClientRect(&rect);
  61. int x = (rect.Width() - cxIcon + 1) / 2;
  62. int y = (rect.Height() - cyIcon + 1) / 2;
  63. // Draw the icon
  64. dc.DrawIcon(x, y, m_hIcon);
  65. }
  66. else
  67. {
  68. CDialog::OnPaint();
  69. }
  70. }
  71. // The system calls this to obtain the cursor to display while the user drags
  72. //  the minimized window.
  73. HCURSOR CDsDemoDlg::OnQueryDragIcon()
  74. {
  75. return (HCURSOR) m_hIcon;
  76. }
  77. /////////////////////////////////////////////////////////////////////////
  78. // 枚举Filter上的Pin
  79. IPin * CDsDemoDlg::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
  80. {
  81.     BOOL       bFound = FALSE;
  82.     IEnumPins  *pEnum;
  83.     IPin       *pPin;
  84.     HRESULT hr = pFilter->EnumPins(&pEnum);
  85.     if (FAILED(hr))
  86.     {
  87.         return NULL;
  88.     }
  89.     while(pEnum->Next(1, &pPin, 0) == S_OK)
  90.     {
  91.         PIN_DIRECTION PinDirThis;
  92.         pPin->QueryDirection(&PinDirThis);
  93.         if (bFound = (PinDir == PinDirThis))
  94.             break;
  95.         pPin->Release();
  96.     }
  97.     pEnum->Release();
  98.     return (bFound ? pPin : NULL); 
  99. }
  100. // 枚举Pin上的媒体类型
  101. BOOL CDsDemoDlg::GetMediaType(IPin * inPin)
  102. {
  103. IEnumMediaTypes * pMTEnum = NULL; 
  104. AM_MEDIA_TYPE *   pAMType = NULL;
  105. if (SUCCEEDED(inPin->EnumMediaTypes(&pMTEnum)))
  106. {
  107. ASSERT(pMTEnum);
  108. while (pMTEnum->Next(1, &pAMType, 0) == S_OK)
  109. {
  110. // 对取得的媒体类型进行处理
  111. // ...
  112. DeleteMediaType(pAMType);
  113. }
  114. pMTEnum->Release();
  115. return TRUE;
  116. }
  117. return FALSE;
  118. }
  119. // 判断某个Filter是否已经注册
  120. BOOL CDsDemoDlg::IsFilterRegistered(CLSID inFilterId)
  121. {
  122. IBaseFilter * pFilter = NULL;
  123. if (SUCCEEDED(CoCreateInstance(inFilterId, NULL, CLSCTX_INPROC_SERVER,
  124. IID_IBaseFilter, (void **)&pFilter)))
  125. {
  126. pFilter->Release();
  127. return TRUE;
  128. }
  129. return FALSE;
  130. }
  131. // 在程序中注册某个Filter文件
  132. BOOL CDsDemoDlg::RegisterFilter(const char * inFilterAx)
  133. {
  134. typedef (WINAPI * REGISTER_FUNC) (void);
  135. REGISTER_FUNC   MyFunc = NULL;
  136. HMODULE hModule = ::LoadLibrary(inFilterAx);
  137. if (hModule)
  138. {
  139. MyFunc = (REGISTER_FUNC) GetProcAddress(hModule, "DllRegisterServer");
  140. BOOL pass = (MyFunc != NULL);
  141. if (pass)
  142. {
  143. MyFunc();
  144. }
  145. ::FreeLibrary(hModule);
  146. return pass;
  147. }
  148. return FALSE;
  149. }
  150. // 修改Filter的Merit值
  151. BOOL CDsDemoDlg::SetFilterMerit(const char * inClsid, DWORD inMerit)
  152. {
  153. typedef struct
  154. {
  155. DWORD dwVersion;    // 版本号
  156. DWORD dwMerit;      // Merit值
  157. DWORD dwPinCount;   // Pin的数量
  158. DWORD dwReserved;   // 保留
  159. } FILTER_HEADER;
  160. const char *  cRegistryEntry = "CLSID\{083863F1-70DE-11d0-BD40-00A0C911CE86}\Instance\";
  161. const long    cMaxLength = 1024 * 16;
  162. BYTE          filterData[cMaxLength];
  163. DWORD         actualLength = 0;
  164. // 生成Filter信息注册部分的注册表入口
  165. char   szEntry[1000];
  166. strcpy(szEntry, cRegistryEntry);
  167. strcat(szEntry, inClsid);
  168. HKEY hKey   = NULL;
  169. LONG result = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, szEntry, 0, KEY_ALL_ACCESS, &hKey);
  170. BOOL pass = (result == ERROR_SUCCESS);
  171. if (pass)
  172. {
  173. // 读取FilterData的值
  174. actualLength = actualLength;
  175. result = ::RegQueryValueEx(hKey, "FilterData", NULL, NULL, filterData, &actualLength);
  176. pass   = (result == ERROR_SUCCESS);
  177. }
  178. if (pass)
  179. {
  180. // 修改FiterData中Merit部分,然后写回到注册表
  181. FILTER_HEADER * filterHeader = (FILTER_HEADER *) filterData;
  182. filterHeader->dwMerit = inMerit;
  183. result = ::RegSetValueEx(hKey, "FilterData", NULL, REG_BINARY, filterData, actualLength);
  184. pass   = (result == ERROR_SUCCESS);
  185. }
  186. if (hKey)
  187. {
  188. ::RegCloseKey(hKey);
  189. }
  190. return pass;
  191. }
  192. // 判断采集卡类型:VFW or WDM
  193. BOOL CDsDemoDlg::IsVFWCard(IBaseFilter * pDeviceFilter)
  194. {
  195. ASSERT(pDeviceFilter);
  196. IAMVfwCaptureDialogs * pVfw = NULL;
  197. HRESULT hr = pDeviceFilter->QueryInterface(IID_IAMVfwCaptureDialogs, (void**)&pVfw);
  198. if (SUCCEEDED(hr))
  199. {
  200. // This is a VFW card...
  201. pVfw->Release();
  202. return TRUE;
  203. }
  204. else
  205. {
  206. // Maybe this is a WDM card...
  207. return FALSE;
  208. }
  209. }
  210. BOOL CDsDemoDlg::IsWDMCard(IBaseFilter * pDeviceFilter)
  211. {
  212. ASSERT(pDeviceFilter);
  213. IAMAnalogVideoDecoder * pWdm = NULL;
  214. HRESULT hr = pDeviceFilter->QueryInterface(IID_IAMAnalogVideoDecoder, (void**)&pWdm);
  215. if (SUCCEEDED(hr))
  216. {
  217. // This is a WDM card...
  218. pWdm->Release();
  219. return TRUE;
  220. }
  221. else
  222. {
  223. // Maybe this is a VFW card...
  224. return FALSE;
  225. }
  226. }
  227. HRESULT InitCaptureGraphBuilder(
  228.   IGraphBuilder **ppGraph,  // Receives the pointer.
  229.   ICaptureGraphBuilder2 **ppBuild  // Receives the pointer.
  230. )
  231. {
  232.     if (!ppGraph || !ppBuild)
  233.     {
  234.         return E_POINTER;
  235.     }
  236.     IGraphBuilder *pGraph = NULL;
  237.     ICaptureGraphBuilder2 *pBuild = NULL;
  238.     // Create the Capture Graph Builder.
  239.     HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
  240.         CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pGraph);
  241.     if (SUCCEEDED(hr))
  242.     {
  243.         // Create the Filter Graph Manager.
  244.         hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
  245.             IID_IGraphBuilder, (void**)&pGraph);
  246.         if (SUCCEEDED(hr))
  247.         {
  248.             // Initialize the Capture Graph Builder.
  249.             pBuild->SetFiltergraph(pGraph);
  250.             // Return both interface pointers to the caller.
  251.             *ppBuild = pBuild;
  252.             *ppGraph = pGraph; // The caller must release both interfaces.
  253.             return S_OK;
  254.         }
  255.         else
  256.         {
  257.             pBuild->Release();
  258.         }
  259.     }
  260.     return hr; // Failed
  261. }
  262. // 辅助函数:在Crossbar Filter上查找指定类型的Pin
  263. HRESULT FindCrossbarPin(
  264.     IAMCrossbar *pXBar,                 // Pointer to the crossbar.
  265.     PhysicalConnectorType PhysicalType, // Pin type to match.
  266.     PIN_DIRECTION Dir,                  // Pin direction.
  267.     long *pIndex)       // Receives the index of the pin, if found.
  268. {
  269.     BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);
  270.     // Find out how many pins the crossbar has.
  271.     long cOut, cIn;
  272.     HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
  273.     if (FAILED(hr)) return hr;
  274.     // Enumerate pins and look for a matching pin.
  275.     long count = (bInput ? cIn : cOut);
  276.     for (long i = 0; i < count; i++)
  277.     {
  278.         long iRelated = 0;
  279.         long ThisPhysicalType = 0;
  280.         hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
  281.             &ThisPhysicalType);
  282.         if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
  283.         {
  284.             // Found a match, return the index.
  285.             *pIndex = i;
  286.             return S_OK;
  287.         }
  288.     }
  289.     // Did not find a matching pin.
  290.     return E_FAIL;
  291. }
  292. // 辅助函数:在Crossbar Filter上查找Audio Decoder Out Pin和Audio Tuner In Pin,
  293. // 调用IAMCrossbar::Route函数进行电视声音的导通或者断开
  294. HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
  295. {
  296.     // Look for the Audio Decoder output pin.
  297.     long i = 0;
  298.     HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
  299.         PINDIR_OUTPUT, &i);
  300.     if (SUCCEEDED(hr))
  301.     {
  302.         if (bActivate)  // Activate the audio. 
  303.         {
  304.             // Look for the Audio Tuner input pin.
  305.             long j = 0;
  306.             hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, 
  307.                 PINDIR_INPUT, &j);
  308.             if (SUCCEEDED(hr))
  309.             {
  310.                 return pXBar->Route(i, j);
  311.             }
  312.         }
  313.         else  // Mute the audio
  314.         {
  315.             return pXBar->Route(i, -1);
  316.         }
  317.     }
  318.     return E_FAIL;
  319. }
  320. // 激活(或者关闭)电视声音,考虑到采集卡带有两个Crossbar Filter的情况
  321. HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
  322.   BOOL bActivate)
  323. {
  324.     // Search upstream for a crossbar.
  325.     IAMCrossbar *pXBar1 = NULL;
  326.     HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
  327.         IID_IAMCrossbar, (void**)&pXBar1);
  328.     if (SUCCEEDED(hr)) 
  329.     {
  330.         hr = ConnectAudio(pXBar1, bActivate);
  331.         if (FAILED(hr))
  332.         {
  333.             // Look for another crossbar.
  334.             IBaseFilter *pF = NULL;
  335.             hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
  336.             if (SUCCEEDED(hr)) 
  337.             {
  338.                 // Search upstream for another one.
  339.                 IAMCrossbar *pXBar2 = NULL;
  340.                 hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
  341.                     IID_IAMCrossbar, (void**)&pXBar2);
  342.                 pF->Release();
  343.                 if (SUCCEEDED(hr))
  344.                 {
  345.                     hr = ConnectAudio(pXBar2, bActivate);
  346.                     pXBar2->Release();
  347.                 }
  348.             }
  349.         }
  350.         pXBar1->Release();
  351.     }
  352.     return hr;
  353. }