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.

252 lines
9.1 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. DSFilter::iterator iPrePin;
  98. for (iCapPin = pCap.begin(); iCapPin != pCap.end(); ++iCapPin) {
  99. if (IsAnalogVideoCaptureViewingPin(*iCapPin)) {
  100. break;
  101. }
  102. }
  103. for (iPrePin = pCap.begin(); iPrePin != pCap.end(); ++iPrePin) {
  104. if (IsAnalogVideoCapturePreviewPin(*iPrePin)) {
  105. break;
  106. }
  107. }
  108. if (iCapPin == pCap.end() && iPrePin == pCap.end()) {
  109. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no video pin on capture");
  110. bool fDeMux = false;
  111. // See if this is an error or not
  112. PQVidCtl pqCtl;
  113. if(!!m_pContainer){
  114. HRESULT hr = m_pContainer->QueryInterface(IID_IMSVidCtl, reinterpret_cast<void**>(&pqCtl));
  115. if(FAILED(hr)){
  116. return hr;
  117. }
  118. PQFeatures fa;
  119. hr = pqCtl->get_FeaturesActive(&fa);
  120. if(FAILED(hr)){
  121. return hr;
  122. }
  123. CFeatures* pC = static_cast<CFeatures *>(fa.p);
  124. DeviceCollection::iterator i;
  125. for(i = pC->m_Devices.begin(); i != pC->m_Devices.end(); ++i){
  126. if(VWGraphSegment(*i).ClassID() == CLSID_MSVidEncoder){
  127. break;
  128. }
  129. }
  130. if(i != pC->m_Devices.end()){
  131. fDeMux = true;
  132. }
  133. }
  134. if (fDeMux){
  135. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() no viewing or previewing pin found but encoder active");
  136. return NOERROR;
  137. }
  138. else{
  139. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() no viewing or previewing pin found");
  140. return E_FAIL;
  141. }
  142. }
  143. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() found viewing or previewing pin");
  144. // this is an intelligent connect so that we can bring in xforms
  145. // for example certain usb tuners want to have media type jpg not yuv which
  146. // means we need a jpg/yuv xform between capture and render
  147. // this will also bring in the vpm if necessary
  148. DSPin pCapPin(*iCapPin);
  149. DSPin pPrePin(*iPrePin);
  150. if(iCapPin != pCap.end()){
  151. if (pCapPin.HasCategory(PIN_CATEGORY_VIDEOPORT)) {
  152. DSFilter vpm;
  153. bool fVPMalreadyloaded = false;
  154. for (DSGraph::iterator i = m_pGraph.begin(); i != m_pGraph.end(); ++i) {
  155. DSFilter f(*i);
  156. if (IsVPM(f)) {
  157. vpm = f;
  158. fVPMalreadyloaded = true;
  159. break;
  160. }
  161. }
  162. if (!fVPMalreadyloaded) {
  163. HRESULT hr = vpm.CoCreateInstance(CLSID_VideoPortManager);
  164. if (FAILED(hr)) {
  165. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't create vpm");
  166. return E_UNEXPECTED;
  167. }
  168. CString csName;
  169. hr = m_pGraph.AddFilter(vpm, csName);
  170. if (FAILED(hr)) {
  171. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() can't insert vpm in graph");
  172. return E_UNEXPECTED;
  173. }
  174. }
  175. if (vpm && !fVPMalreadyloaded) {
  176. m_Filters.push_back(vpm);
  177. }
  178. DSFilter::iterator iVPVBI;
  179. for (iVPVBI = pCap.begin(); iVPVBI != pCap.end(); ++iVPVBI) {
  180. DSPin pVPVBI(*iVPVBI);
  181. if (pVPVBI.HasCategory(PIN_CATEGORY_VIDEOPORT_VBI)) {
  182. HRESULT hr = pVPVBI.IntelligentConnect(vpm, m_Filters);
  183. if (SUCCEEDED(hr)) {
  184. break;
  185. }
  186. }
  187. }
  188. }
  189. }
  190. HRESULT hr = E_FAIL;
  191. DSFilterList intermediates;
  192. if(iCapPin != pCap.end()){
  193. hr = pCapPin.IntelligentConnect(pOv, intermediates);
  194. }
  195. if(FAILED(hr)){
  196. if(iPrePin != pCap.end()){
  197. pPrePin = *iPrePin;
  198. hr = pPrePin.IntelligentConnect(pOv, intermediates);
  199. }
  200. }
  201. if (FAILED(hr)) {
  202. return Error(IDS_CANT_CONNECT_CAP_VR, __uuidof(IMSVidCtl), E_UNEXPECTED);
  203. }
  204. m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
  205. TRACELM(TRACE_DETAIL, "CAnaCapComp::Compose() SUCCEEDED");
  206. m_fComposed = true;
  207. return NOERROR;
  208. } catch (ComException &e) {
  209. HRESULT hr = e;
  210. TRACELSM(TRACE_ERROR, (dbgDump << "CAnaCapComp::Compose() exception = " << hexdump(hr)), "");
  211. return e;
  212. } catch (...) {
  213. TRACELM(TRACE_ERROR, "CAnaCapComp::Compose() exception ... ");
  214. return E_UNEXPECTED;
  215. }
  216. }
  217. };
  218. #endif // ANACAP_H
  219. // end of file - anacap.h