Leaked source code of windows server 2003
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.

260 lines
9.6 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 ANACAP_H
  8. #define ANACAP_H
  9. #pragma once
  10. #include <uuids.h>
  11. #include "bdamedia.h"
  12. #include "MSVidTVTuner.h"
  13. #include "resource.h" // main symbols
  14. #include <winerror.h>
  15. #include <algorithm>
  16. #include <compimpl.h>
  17. #include <seg.h>
  18. #include <objectwithsiteimplsec.h>
  19. #include "devices.h"
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CAnaCapComp
  22. class ATL_NO_VTABLE __declspec(uuid("E18AF75A-08AF-11d3-B64A-00C04F79498E")) CAnaCapComp :
  23. public CComObjectRootEx<CComSingleThreadModel>,
  24. public CComCoClass<CAnaCapComp, &__uuidof(CAnaCapComp)>,
  25. public IObjectWithSiteImplSec<CAnaCapComp>,
  26. public IMSVidCompositionSegmentImpl<CAnaCapComp>
  27. {
  28. public:
  29. CAnaCapComp() {}
  30. virtual ~CAnaCapComp() {}
  31. REGISTER_NONAUTOMATION_OBJECT(IDS_PROJNAME,
  32. IDS_REG_ANACAPCOMP_DESC,
  33. LIBID_MSVidCtlLib,
  34. __uuidof(CAnaCapComp));
  35. DECLARE_PROTECT_FINAL_CONSTRUCT()
  36. BEGIN_COM_MAP(CAnaCapComp)
  37. COM_INTERFACE_ENTRY(IMSVidCompositionSegment)
  38. COM_INTERFACE_ENTRY(IMSVidGraphSegment)
  39. COM_INTERFACE_ENTRY(IObjectWithSite)
  40. COM_INTERFACE_ENTRY(IPersist)
  41. END_COM_MAP()
  42. // IMSVidComposition
  43. public:
  44. // IMSVidGraphSegment
  45. // IMSVidCompositionSegment
  46. STDMETHOD(Compose)(IMSVidGraphSegment * upstream, IMSVidGraphSegment * downstream)
  47. {
  48. if (m_fComposed) {
  49. return NOERROR;
  50. }
  51. ASSERT(m_pGraph);
  52. try {
  53. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose()");
  54. VWGraphSegment up(upstream);
  55. ASSERT(up.Graph() == m_pGraph);
  56. VWGraphSegment down(downstream);
  57. ASSERT(down.Graph() == m_pGraph);
  58. if (up.begin() == up.end()) {
  59. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() can't compose empty up segment");
  60. return E_INVALIDARG;
  61. }
  62. if (down.begin() == down.end()) {
  63. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() can't compose empty down segment");
  64. return E_INVALIDARG;
  65. }
  66. VWGraphSegment::iterator iOv;
  67. for (iOv = down.begin(); iOv != down.end(); ++iOv) {
  68. if (IsVideoRenderer(*iOv)) {
  69. break;
  70. }
  71. }
  72. if (iOv == down.end()) {
  73. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() downstream segment has no ov mixer filter");
  74. return E_FAIL;
  75. }
  76. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found vr");
  77. ASSERT((*iOv).GetGraph() == m_pGraph);
  78. DSFilter pOv(*iOv);
  79. CComQIPtr<IMSVidAnalogTuner> qiITV(upstream);
  80. CMSVidTVTuner* qiTV;
  81. qiTV = static_cast<CMSVidTVTuner*>(qiITV.p);
  82. DSPin pVidPin;
  83. VWGraphSegment::iterator iCap;
  84. for (iCap = up.begin(); iCap != up.end(); ++iCap) {
  85. if (IsAnalogVideoCapture(*iCap)) {
  86. break;
  87. }
  88. }
  89. if (iCap == up.end()) {
  90. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() upstream segment has no capture filter");
  91. return E_FAIL;
  92. }
  93. ASSERT((*iCap).GetGraph() == m_pGraph);
  94. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found capture filter");
  95. DSFilter pCap(*iCap);
  96. DSFilter::iterator iCapPin;
  97. DSPin pCapPin;
  98. DSPin pVPMPin;
  99. DSPin pPrePin;
  100. for (iCapPin = pCap.begin(); iCapPin != pCap.end(); ++iCapPin) {
  101. if (IsAnalogVideoCaptureViewingPin(*iCapPin)) {
  102. if((*iCapPin).HasCategory(PIN_CATEGORY_VIDEOPORT)){
  103. _ASSERT(pVPMPin == NULL);
  104. pVPMPin = (*iCapPin);
  105. continue;
  106. }
  107. else{
  108. _ASSERT(pCapPin == NULL);
  109. pCapPin = (*iCapPin);
  110. continue;
  111. }
  112. }
  113. if (IsAnalogVideoCapturePreviewPin(*iCapPin)) {
  114. _ASSERT(pPrePin == NULL);
  115. pPrePin = (*iCapPin);
  116. continue;
  117. }
  118. }
  119. if (!pCapPin && !pPrePin && !pVPMPin) {
  120. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no video pin on capture");
  121. bool fDeMux = false;
  122. // See if this is an error or not
  123. PQVidCtl pqCtl;
  124. if(!!m_pContainer){
  125. HRESULT hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl));
  126. if(FAILED(hr)){
  127. return hr;
  128. }
  129. PQFeatures fa;
  130. hr = pqCtl->get_FeaturesActive(&fa);
  131. if(FAILED(hr)){
  132. return hr;
  133. }
  134. CFeatures* pC = static_cast<CFeatures *>(fa.p);
  135. DeviceCollection::iterator i;
  136. for(i = pC->m_Devices.begin(); i != pC->m_Devices.end(); ++i){
  137. if(VWGraphSegment(*i).ClassID() == CLSID_MSVidEncoder){
  138. break;
  139. }
  140. }
  141. if(i != pC->m_Devices.end()){
  142. fDeMux = true;
  143. }
  144. }
  145. if (fDeMux){
  146. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() no viewing or previewing pin found but encoder active");
  147. return NOERROR;
  148. }
  149. else{
  150. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no viewing or previewing pin found");
  151. return E_FAIL;
  152. }
  153. }
  154. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found viewing or previewing pin");
  155. // this is an intelligent connect so that we can bring in xforms
  156. // for example certain usb tuners want to have media type jpg not yuv which
  157. // means we need a jpg/yuv xform between capture and render
  158. // this will also bring in the vpm if necessary
  159. HRESULT hr = E_FAIL;
  160. DSFilterList intermediates;
  161. if(pVPMPin){
  162. DSFilter vpm;
  163. bool fVPMalreadyloaded = false;
  164. for (DSGraph::iterator i = m_pGraph.begin(); i != m_pGraph.end(); ++i) {
  165. DSFilter f(*i);
  166. if (IsVPM(f)) {
  167. vpm = f;
  168. fVPMalreadyloaded = true;
  169. break;
  170. }
  171. }
  172. if (!fVPMalreadyloaded) {
  173. HRESULT hr = vpm.CoCreateInstance(CLSID_VideoPortManager);
  174. if (FAILED(hr)) {
  175. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't create vpm");
  176. return E_UNEXPECTED;
  177. }
  178. CString csName;
  179. hr = m_pGraph.AddFilter(vpm, csName);
  180. if (FAILED(hr)) {
  181. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't insert vpm in graph");
  182. return E_UNEXPECTED;
  183. }
  184. }
  185. if (vpm && !fVPMalreadyloaded) {
  186. m_Filters.push_back(vpm);
  187. }
  188. DSFilter::iterator iVPVBI;
  189. for (iVPVBI = pCap.begin(); iVPVBI != pCap.end(); ++iVPVBI) {
  190. DSPin pVPVBI(*iVPVBI);
  191. if (pVPVBI.HasCategory(PIN_CATEGORY_VIDEOPORT_VBI)) {
  192. HRESULT hr = pVPVBI.IntelligentConnect(vpm, m_Filters);
  193. if (SUCCEEDED(hr)) {
  194. break;
  195. }
  196. }
  197. }
  198. hr = pVPMPin.IntelligentConnect(pOv, intermediates);
  199. if(FAILED(hr)){
  200. return Error(IDS_CANT_CONNECT_CAP_VR, __uuidof(IMSVidCtl), E_UNEXPECTED);
  201. }
  202. }
  203. else if(pCapPin){
  204. hr = pCapPin.IntelligentConnect(pOv, intermediates);
  205. }
  206. if(FAILED(hr)){
  207. if(pPrePin){
  208. hr = pPrePin.IntelligentConnect(pOv, intermediates);
  209. }
  210. }
  211. if (FAILED(hr)) {
  212. return Error(IDS_CANT_CONNECT_CAP_VR, __uuidof(IMSVidCtl), E_UNEXPECTED);
  213. }
  214. m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
  215. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() SUCCEEDED");
  216. m_fComposed = true;
  217. return NOERROR;
  218. } catch (ComException &e) {
  219. HRESULT hr = e;
  220. TRACELSM(TRACE_ERROR, (dbgDump << "CAnaCapComp::Compose() exception = " << hexdump(hr)), "");
  221. return e;
  222. } catch (...) {
  223. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() exception ... ");
  224. return E_UNEXPECTED;
  225. }
  226. }
  227. };
  228. #endif // ANACAP_H
  229. // end of file - anacap.h