Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
8.7 KiB

  1. //==========================================================================;
  2. //
  3. // Composition.h : Declaration of the custom composition class for gluing analog capture to ovmixer
  4. // Copyright (c) Microsoft Corporation 1999.
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7. #ifndef ANADATA_H
  8. #define ANADATA_H
  9. #pragma once
  10. #include <winerror.h>
  11. #include <algorithm>
  12. #include <compimpl.h>
  13. #include <seg.h>
  14. #include "resource.h" // main symbols
  15. #include <objectwithsiteimplsec.h>
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CAnaDataComp
  18. class ATL_NO_VTABLE __declspec(uuid("C5702CD6-9B79-11d3-B654-00C04F79498E")) CAnaDataComp :
  19. public CComObjectRootEx<CComSingleThreadModel>,
  20. public CComCoClass<CAnaDataComp, &__uuidof(CAnaDataComp)>,
  21. public IObjectWithSiteImplSec<CAnaDataComp>,
  22. public IMSVidCompositionSegmentImpl<CAnaDataComp>
  23. {
  24. public:
  25. CAnaDataComp() {}
  26. virtual ~CAnaDataComp() {}
  27. REGISTER_NONAUTOMATION_OBJECT(IDS_PROJNAME,
  28. IDS_REG_ANADATACOMP_DESC,
  29. LIBID_MSVidCtlLib,
  30. __uuidof(CAnaDataComp));
  31. DECLARE_PROTECT_FINAL_CONSTRUCT()
  32. BEGIN_COM_MAP(CAnaDataComp)
  33. COM_INTERFACE_ENTRY(IMSVidCompositionSegment)
  34. COM_INTERFACE_ENTRY(IMSVidGraphSegment)
  35. COM_INTERFACE_ENTRY(IObjectWithSite)
  36. COM_INTERFACE_ENTRY(IPersist)
  37. END_COM_MAP()
  38. public:
  39. PQCreateDevEnum m_pSystemEnum;
  40. //////////////
  41. HRESULT ConnectCodecPin(DSPin& pCodecPin, DSFilter& pCap, DSFilter& pIPSink) {
  42. // if this fails we just skip the pin not the whole filter so we don't need
  43. // to check the return code from the connect
  44. if (pCodecPin.IsInput()) {
  45. pCodecPin.IntelligentConnect(pCap, m_Filters, 0, UPSTREAM);
  46. } else {
  47. pCodecPin.IntelligentConnect(pIPSink, m_Filters, DSGraph::ATTEMPT_MERIT_DO_NOT_USE);
  48. }
  49. return NOERROR;
  50. }
  51. //////////////
  52. HRESULT AddCodec(const DSFilterMoniker& pCodecMkr, DSFilter& pCap, DSFilter& pIPSink) {
  53. DSFilter pCodec = m_pGraph.AddMoniker(pCodecMkr);
  54. if (!pCodec) {
  55. // this can happen if a codec is uninstalled or the driver file is removed
  56. // but the registry doesn't get cleaned up.
  57. // also can happen on an upgrade if a codec has been removed from the product.
  58. TRACELSM(TRACE_ERROR, (dbgDump << "CAnaDataComp::AddCodec() can't add mkr" << pCodecMkr), "");
  59. return S_FALSE;
  60. }
  61. m_Filters.push_back(pCodec);
  62. //connect all input pins including hw slicing support
  63. std::for_each(pCodec.begin(),
  64. pCodec.end(),
  65. bndr_obj_2_3<arity3pmf<CAnaDataComp, DSPin&, DSFilter&, DSFilter&, HRESULT> >(
  66. *this,
  67. arity3pmf<CAnaDataComp,
  68. DSPin&,
  69. DSFilter&,
  70. DSFilter&,
  71. HRESULT>(&CAnaDataComp::ConnectCodecPin),
  72. pCap,
  73. pIPSink
  74. ));
  75. return NOERROR;
  76. }
  77. //////////////
  78. HRESULT CapturePinPrep(DSPin& pCapPin, DSFilter& pMSTee, DSFilter& pVPM) {
  79. if (pCapPin.GetConnection() || pCapPin.GetDirection() == PINDIR_INPUT) {
  80. return NOERROR; // skip connected pins
  81. }
  82. HRESULT hr;
  83. DSPin targ;
  84. if (pCapPin.HasCategory(PIN_CATEGORY_VBI)) {
  85. if (!pMSTee) {
  86. DSDevices teelist(m_pSystemEnum, KSCATEGORY_SPLITTER);
  87. pMSTee = m_pGraph.AddMoniker(*(teelist.begin()));
  88. if (!pMSTee) {
  89. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() can't add mstee moniker to graph");
  90. THROWCOM(E_UNEXPECTED);
  91. }
  92. }
  93. targ = pMSTee.FirstPin(PINDIR_INPUT);
  94. ASSERT(targ);
  95. hr = pCapPin.Connect(targ);
  96. if (FAILED(hr)) {
  97. TRACELSM(TRACE_ERROR, (dbgDump << "CAnaDataComp::CapturePinPrep() can't connect " << pCapPin << " " << pCapPin.GetFilter() << " to " << targ << " " << targ.GetFilter() << " hr = " << std::hex << hr), "");
  98. THROWCOM(E_UNEXPECTED);
  99. }
  100. } else if (pCapPin.HasCategory(PIN_CATEGORY_VIDEOPORT_VBI)) {
  101. // hook up vbi surf to pincat_vpvbi
  102. if (!pVPM) {
  103. CString csName(_T("VideoPort Manager"));
  104. pVPM = m_pGraph.AddFilter(CLSID_VideoPortManager, csName);
  105. if (!pVPM) {
  106. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() can't create vbisurf");
  107. THROWCOM(E_UNEXPECTED);
  108. }
  109. }
  110. DSFilterList intermediates;
  111. hr = pCapPin.IntelligentConnect(pVPM, intermediates);
  112. if (FAILED(hr)) {
  113. TRACELSM(TRACE_ERROR, (dbgDump << "CAnaDataComp::CapturePinPrep() can't connect " << pCapPin << " " << pCapPin.GetFilter() << " to " << targ << " " << targ.GetFilter() << " hr = " << std::hex << hr), "");
  114. THROWCOM(E_UNEXPECTED);
  115. }
  116. m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
  117. }
  118. return NOERROR;
  119. }
  120. // IMSVidGraphSegment
  121. // IMSVidCompositionSegment
  122. STDMETHOD(Compose)(IMSVidGraphSegment * upstream, IMSVidGraphSegment * downstream)
  123. {
  124. if (m_fComposed) {
  125. return NOERROR;
  126. }
  127. ASSERT(m_pGraph);
  128. try {
  129. VWGraphSegment up(upstream);
  130. ASSERT(up.Graph() == m_pGraph);
  131. VWGraphSegment down(downstream);
  132. ASSERT(down.Graph() == m_pGraph);
  133. if (up.begin() == up.end()) {
  134. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() can't compose empty up segment");
  135. return E_INVALIDARG;
  136. }
  137. if (down.begin() == down.end()) {
  138. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() can't compose empty down segment");
  139. return E_INVALIDARG;
  140. }
  141. VWGraphSegment::iterator iCap = std::find_if(up.begin(),
  142. up.end(),
  143. arity1_pointer(&IsAnalogVideoCapture));
  144. if (iCap == up.end()) {
  145. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() upstream segment has no capture filter");
  146. return E_FAIL;
  147. }
  148. ASSERT((*iCap).GetGraph() == m_pGraph);
  149. VWGraphSegment::iterator iIPSink = std::find_if(down.begin(),
  150. down.end(),
  151. arity1_pointer(&IsIPSink));
  152. if (iIPSink == down.end()) {
  153. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() downstream segment has no ip sink filter");
  154. return E_FAIL;
  155. }
  156. if (!m_pSystemEnum) {
  157. HRESULT hr = m_pSystemEnum.CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER);
  158. if (FAILED(hr)) {
  159. return E_UNEXPECTED;
  160. }
  161. }
  162. DSFilter ipsink(*iIPSink);
  163. ASSERT(!!ipsink);
  164. ASSERT(ipsink.GetGraph() == m_pGraph);
  165. PQVidCtl pqCtl;
  166. HRESULT hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl));
  167. if(FAILED(hr)){
  168. return hr;
  169. }
  170. CComQIPtr<IMSVidVideoRenderer> spVidVid;
  171. hr = pqCtl->get_VideoRendererActive(&spVidVid);
  172. if(FAILED(hr)){
  173. return hr;
  174. }
  175. DSFilter vpm;
  176. bool fVPMalreadyloaded = false;
  177. if(spVidVid){
  178. for (DSGraph::iterator i = m_pGraph.begin(); i != m_pGraph.end(); ++i) {
  179. DSFilter f(*i);
  180. if (IsVPM(f)) {
  181. vpm = f;
  182. fVPMalreadyloaded = true;
  183. break;
  184. }
  185. }
  186. }
  187. DSFilter mstee;
  188. #if 0
  189. std::for_each((*iCap).begin(),
  190. (*iCap).end(),
  191. bndr_obj_2_3<arity3pmf<CAnaDataComp, DSPin&, DSFilter&, DSFilter&, HRESULT> >(
  192. *this,
  193. arity3pmf<CAnaDataComp,
  194. DSPin&,
  195. DSFilter&,
  196. DSFilter&,
  197. HRESULT>(&CAnaDataComp::CapturePinPrep),
  198. mstee,
  199. vpm
  200. ));
  201. #else
  202. DSFilter::iterator i2;
  203. for (i2 = (*iCap).begin(); i2 != (*iCap).end(); ++i2) {
  204. CapturePinPrep(*i2, mstee, vpm);
  205. }
  206. #endif
  207. if (!mstee) {
  208. TRACELM(TRACE_ERROR, "CAnaDataComp::Compose() no vbi pins on capture filter");
  209. return Error(IDS_E_NOVBI, __uuidof(CAnaCapComp), E_FAIL);
  210. }
  211. if (vpm && !fVPMalreadyloaded) {
  212. m_Filters.push_back(vpm);
  213. }
  214. m_Filters.push_back(mstee);
  215. //m_Filters.push_back(ipsink);
  216. // create codec enumerator
  217. DSDevices codeclist(m_pSystemEnum, KSCATEGORY_VBICODEC);
  218. std::for_each(codeclist.begin(),
  219. codeclist.end(),
  220. bndr_obj_2_3<arity3pmf<CAnaDataComp, const DSFilterMoniker&, DSFilter&, DSFilter&, HRESULT> >(
  221. *this,
  222. arity3pmf<CAnaDataComp,
  223. const DSFilterMoniker&,
  224. DSFilter&,
  225. DSFilter&,
  226. HRESULT>(&CAnaDataComp::AddCodec),
  227. (*iCap),
  228. ipsink
  229. ));
  230. return NOERROR;
  231. } catch (ComException &e) {
  232. return e;
  233. } catch (...) {
  234. return E_UNEXPECTED;
  235. }
  236. }
  237. };
  238. #endif // ANADATA_H
  239. // end of file - anadata.h