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.

1319 lines
47 KiB

  1. //==========================================================================;
  2. //
  3. // dsextend.h : additional infrastructure to extend the dshow stuff so that it
  4. // works nicely from c++
  5. // Copyright (c) Microsoft Corporation 1995-1999.
  6. //
  7. /////////////////////////////////////////////////////////////////////////////
  8. #pragma once
  9. #ifndef DSEXTEND_H
  10. #define DSEXTEND_H
  11. #include <algorithm>
  12. #include <functional>
  13. #include <utility>
  14. #include <vector>
  15. #include <list>
  16. #include <map>
  17. #include <trace.h>
  18. #include <throw.h>
  19. #include <stextend.h>
  20. #include <w32extend.h>
  21. #include <ksextend.h>
  22. #include <fwdseq.h>
  23. #include <control.h>
  24. #include <mpconfig.h>
  25. #include <vptype.h>
  26. #include <vpnotify.h>
  27. #include <il21dec.h>
  28. #include <mtype.h>
  29. #include <tuner.h>
  30. #include <bdaiface.h>
  31. #include <errors.h>
  32. #include <winerror.h>
  33. #include <evcode.h>
  34. struct DECLSPEC_NOVTABLE DECLSPEC_UUID("6E8D4A21-310C-11d0-B79A-00AA003767A7") IAMLine21Decoder;
  35. #define LINE21_BY_MAGIC
  36. #define FILTERDATA
  37. // #define ATTEMPT_DIRECT_CONNECT
  38. // we'd like to check to see if two filters can be connected by just trying to connect them
  39. // this is less work and techinically more accurate since pins aren't required to enumerate all
  40. // of the media types they potentiall could support.
  41. // however, this exposes bugs in the filters and causes random hangs and crashes. instead
  42. // we manually check mediums and media types and only attempt the connection when we find a match.
  43. // this turns out to be much more stable.
  44. //#define FORWARD_TRACE
  45. const PIN_DIRECTION DOWNSTREAM = PINDIR_OUTPUT;
  46. const PIN_DIRECTION UPSTREAM = PINDIR_INPUT;
  47. typedef CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> PQFileSourceFilter;
  48. #ifndef POLYMORPHIC_TUNERS
  49. typedef CComQIPtr<IAMTVTuner, &IID_IAMTVTuner> PQTVTuner;
  50. //typedef CComQIPtr<ISatelliteTuner, &IID_ISatelliteTuner> PQSatelliteTuner;
  51. #else
  52. typedef CComQIPtr<IAMTuner, &IID_IAMTuner> PQTuner;
  53. typedef CComQIPtr<IAMTVTuner, &IID_IAMTVTuner> PQTVTuner;
  54. typedef CComQIPtr<IBPCSatelliteTuner, &IID_IBPCSatelliteTuner> PQSatelliteTuner;
  55. #endif
  56. #if 0
  57. typedef CComQIPtr<IVideoWindow, &IID_IVideoWindow> PQVideoWindow;
  58. typedef CComQIPtr<IBasicVideo, &IID_IBasicVideo> PQBasicVideo;
  59. #else
  60. typedef CComQIPtr<IVMRWindowlessControl, &IID_IVMRWindowlessControl> PQVMRWindowlessControl;
  61. #endif
  62. typedef CComQIPtr<IPin, &IID_IPin> PQPin;
  63. typedef CComQIPtr<IBaseFilter, &IID_IBaseFilter> PQFilter;
  64. typedef CComQIPtr<IFilterInfo, &IID_IFilterInfo> PQFilterInfo;
  65. typedef CComQIPtr<IEnumPins, &IID_IEnumPins> PQEnumPins;
  66. typedef CComQIPtr<IEnumFilters, &IID_IEnumFilters> PQEnumFilters;
  67. typedef CComQIPtr<IBasicAudio, &IID_IBasicAudio> PQBasicAudio;
  68. typedef CComQIPtr<IAMCrossbar, &IID_IAMCrossbar> PQCrossbarSwitch;
  69. typedef CComQIPtr<IMediaEventEx, &IID_IMediaEventEx> PQMediaEventEx;
  70. typedef CComQIPtr<IMediaControl, &IID_IMediaControl> PQMediaControl;
  71. typedef CComQIPtr<IMediaPosition, &IID_IMediaPosition> PQMediaPosition;
  72. typedef CComQIPtr<IMediaSeeking, &IID_IMediaSeeking> PQMediaSeeking;
  73. typedef CComQIPtr<IGraphBuilder, &IID_IGraphBuilder> PQGraphBuilder;
  74. typedef CComQIPtr<ICreateDevEnum, &IID_ICreateDevEnum> PQCreateDevEnum;
  75. typedef CComQIPtr<IEnumMoniker, &IID_IEnumMoniker> PQEnumMoniker;
  76. typedef CComQIPtr<IFilterMapper2, &IID_IFilterMapper2> PQFilterMapper;
  77. typedef CComQIPtr<IEnumMediaTypes, &IID_IEnumMediaTypes> PQEnumMediaTypes;
  78. typedef CComQIPtr<IAMAnalogVideoDecoder, &IID_IAMAnalogVideoDecoder> PQAnalogVideoDecoder;
  79. typedef CComQIPtr<IMixerPinConfig, &IID_IMixerPinConfig> PQMixerPinConfig;
  80. typedef CComQIPtr<IAMAudioInputMixer, &IID_IAMAudioInputMixer> PQAudioInputMixer;
  81. typedef CComQIPtr<IAMLine21Decoder, &IID_IAMLine21Decoder> PQLine21Decoder;
  82. typedef CComQIPtr<IVPNotify2, &IID_IVPNotify2> PQVPNotify2;
  83. typedef CComQIPtr<ITuner> PQBDATuner;
  84. typedef CComQIPtr<IBDA_IPSinkControl> PQBDA_IPSinkControl;
  85. typedef CComQIPtr<IDvdControl, &IID_IDvdControl> PQDVDNavigator;
  86. typedef CComQIPtr<IVideoFrameStep> PQVideoFrameStep;
  87. typedef CComQIPtr<IMediaEventSink> PQMediaEventSink;
  88. typedef CComQIPtr<IVMRMonitorConfig> PQVMRMonitorConfig;
  89. typedef CComQIPtr<IDirectDraw7, &IID_IDirectDraw7> PQDirectDraw7;
  90. typedef CComQIPtr<IRegisterServiceProvider, &IID_IRegisterServiceProvider> PQRegisterServiceProvider;
  91. typedef std::vector<GUID2> MediaMajorTypeList;
  92. #if 0
  93. typedef std::pair<PQCrossbarSwitch, long> PQBasePoint;
  94. inline void clear(PQBasePoint &p) {p.first.Release(); p.second = 0;}
  95. class PQPoint : public PQBasePoint {
  96. public:
  97. //PQBasePoint p;
  98. inline PQPoint() : PQBasePoint(PQCrossbarSwitch(), 0) {}
  99. inline PQPoint(const PQBasePoint &p2) : PQBasePoint(p2) {}
  100. inline PQPoint(const PQPoint &p2) : PQBasePoint(p2) {}
  101. inline PQPoint(const PQCrossbarSwitch &s, long i) : PQBasePoint(s, i) {}
  102. virtual ~PQPoint() { ::clear(*this); }
  103. inline void clear(void) { ::clear(*this); }
  104. };
  105. #else
  106. typedef std::pair<PQCrossbarSwitch, long> PQPoint;
  107. #endif
  108. class CDevices;
  109. class DSFilter;
  110. class DSPin;
  111. typedef std::vector< DSFilter, stl_smart_ptr_allocator<DSFilter> > DSFilterList;
  112. typedef std::vector< DSPin, stl_smart_ptr_allocator<DSPin> > DSPinList;
  113. typedef std::pair< DSFilter, CString> DSFilterID;
  114. typedef std::vector< DSFilterID > DSFilterIDList;
  115. typedef PQPoint XBarInputPoint, PQInputPoint;
  116. typedef PQPoint XBarOutputPoint, PQOutputPoint;
  117. typedef PQPoint XBarPoint;
  118. typedef std::pair<XBarInputPoint, XBarOutputPoint> CIOPoint;
  119. typedef std::list<CIOPoint> VWGraphPath;
  120. class VWStream : public VWGraphPath {
  121. public:
  122. //PQBasePoint p;
  123. VWStream() {}
  124. VWStream(const VWGraphPath &p2) : VWGraphPath(p2) {}
  125. VWStream(const VWStream &p2) : VWGraphPath(p2) {}
  126. virtual ~VWStream() {}
  127. void Route(void);
  128. };
  129. typedef std::list<VWStream> VWStreamList;
  130. #ifdef _DEBUG
  131. class DSREGPINMEDIUM;
  132. class DSMediaType;
  133. inline tostream &operator<<(tostream &dc, const DSREGPINMEDIUM &g);
  134. inline tostream& operator<<(tostream &d, const PQPin &pin);
  135. inline tostream &operator<<(tostream &dc, const DSREGPINMEDIUM &g);
  136. inline tostream& operator<<(tostream &d, const PQPin &pin);
  137. inline tostream& operator<<(tostream &d, const _AMMediaType *pmt);
  138. #endif
  139. // AM_MEDIA_TYPE:
  140. // GUID majortype;
  141. // GUID subtype;
  142. // BOOL bFixedSizeSamples;
  143. // BOOL bTemporalCompression;
  144. // ULONG lSampleSize;
  145. // GUID formattype;
  146. // IUnknown *pUnk;
  147. // ULONG cbFormat;
  148. #define GUID0 0L, 0, 0, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
  149. const AM_MEDIA_TYPE NULL_AMMEDIATYPE = {
  150. GUID0,
  151. GUID0,
  152. 0,
  153. 0,
  154. 0L,
  155. GUID0,
  156. NULL,
  157. 0L
  158. };
  159. // this is basically a CComQIPtr with allocate/copy semantics instead of
  160. // refcount semantics and without the QI stuff.
  161. // i don't know why they didn't just implement media types as an
  162. // com object with an IMediaType interface instead of this weird alloc stuff
  163. // REV2: investigate inheriting from CMediaType class in mtype.h. but, i'm not using anything
  164. // from the filter implementation class hierarchy. and, i'd like to keep this interface division
  165. // clean. right now we only use dshow sdk \include which is the external interface stuff.
  166. class DSMediaType {
  167. public:
  168. AM_MEDIA_TYPE *p;
  169. inline DSMediaType() : p(NULL) {}
  170. DSMediaType(GUID majortype, GUID subtype = GUID_NULL, GUID formattype = GUID_NULL) : p(NULL) {
  171. try {
  172. p = CreateMediaType(&NULL_AMMEDIATYPE);
  173. if (p) {
  174. p->majortype = majortype;
  175. p->subtype = subtype;
  176. p->formattype = formattype;
  177. }
  178. } catch(...) {
  179. TRACELM(TRACE_ERROR, "DSMediaType::DSMediaType(const DSMediaType) Exception");
  180. }
  181. }
  182. DSMediaType(const DSMediaType &d) : p(NULL) {
  183. try {
  184. if (d.p) {
  185. p = CreateMediaType(d.p);
  186. }
  187. } catch(...) {
  188. TRACELM(TRACE_ERROR, "DSMediaType::DSMediaType(const DSMediaType) Exception");
  189. }
  190. }
  191. DSMediaType(int a) : p(NULL) {}
  192. ~DSMediaType() {
  193. try {
  194. if (p) {
  195. DeleteMediaType(p);
  196. p = NULL;
  197. }
  198. } catch(...) {
  199. TRACELM(TRACE_ERROR, "DSMediaType::~DSMediaType() Exception");
  200. }
  201. }
  202. inline operator AM_MEDIA_TYPE*() const {return p;}
  203. inline AM_MEDIA_TYPE& operator*() const {_ASSERTE(p!=NULL); return *p; }
  204. inline AM_MEDIA_TYPE ** operator&() {ASSERT(p == NULL); return &p; }
  205. inline AM_MEDIA_TYPE * operator->() const {_ASSERTE(p!=NULL); return p; }
  206. inline DSMediaType * address(void) { return this; }
  207. inline const DSMediaType * const_address(void) const { return this; }
  208. typedef stl_smart_ptr_allocator<DSMediaType> stl_allocator;
  209. DSMediaType& operator=(const AM_MEDIA_TYPE &d) {
  210. if (&d != p) {
  211. try {
  212. if (p) {
  213. DeleteMediaType(p);
  214. p = NULL;
  215. }
  216. if (&d) {
  217. p = CreateMediaType(&d);
  218. }
  219. } catch(...) {
  220. TRACELM(TRACE_ERROR, "DSMediaType::operator=(const AM_MEDIA_TYPE &) Exception");
  221. }
  222. }
  223. return *this;
  224. }
  225. DSMediaType& operator=(const AM_MEDIA_TYPE *pd) {
  226. try {
  227. if (pd != p) {
  228. if (p) {
  229. DeleteMediaType(p);
  230. p = NULL;
  231. }
  232. if (pd) {
  233. p = CreateMediaType(pd);
  234. }
  235. }
  236. } catch(...) {
  237. TRACELM(TRACE_ERROR, "DSMediaType::operator=(const AM_MEDIA_TYPE *) Exception");
  238. }
  239. return *this;
  240. }
  241. DSMediaType& operator=(const DSMediaType &d) {
  242. try {
  243. if (d.const_address() != this) {
  244. if (p) {
  245. DeleteMediaType(p);
  246. p = NULL;
  247. }
  248. if (d.p) {
  249. p = CreateMediaType(d.p);
  250. }
  251. }
  252. } catch(...) {
  253. TRACELM(TRACE_ERROR, "DSMediaType::operator=(DSMediaType &)Exception");
  254. }
  255. return *this;
  256. }
  257. DSMediaType& operator=(int d) {
  258. ASSERT(d == 0);
  259. try {
  260. if (p) {
  261. DeleteMediaType(p);
  262. p = NULL;
  263. }
  264. } catch(...) {
  265. TRACELM(TRACE_ERROR, "DSMediaType::operator=(int) Exception");
  266. }
  267. return *this;
  268. }
  269. inline bool operator==(const DSMediaType &d) const {
  270. if (!p && !d.p) {
  271. // both null then they're the same
  272. return true;
  273. }
  274. if (!p || !d.p) {
  275. // if either one null but not both then they aren't the same
  276. return false;
  277. }
  278. TRACELSM(TRACE_DETAIL, (dbgDump << "DSMediaType::operator==() this = " << *this << " d = " << d), "");
  279. return p->majortype == d.p->majortype &&
  280. (p->subtype == GUID_NULL || d.p->subtype == GUID_NULL || p->subtype == d.p->subtype);
  281. }
  282. inline bool operator==(const AM_MEDIA_TYPE &d) const {
  283. if (!p && !&d) {
  284. return true;
  285. }
  286. return p && (&d) && p->majortype == d.majortype &&
  287. (p->subtype == GUID_NULL || d.subtype == GUID_NULL || p->subtype == d.subtype);
  288. }
  289. inline bool operator==(const AM_MEDIA_TYPE *d) const {
  290. if (!p && !d) {
  291. return true;
  292. }
  293. return p && d && p->majortype == d->majortype &&
  294. (p->subtype == GUID_NULL || d->subtype == GUID_NULL || p->subtype == d->subtype);
  295. }
  296. inline bool operator!=(const DSMediaType &d) const {
  297. return !(*this == d);
  298. }
  299. inline bool operator!() const {
  300. return (p == NULL);
  301. }
  302. inline bool MatchingMajor(const AM_MEDIA_TYPE *prhs) const {
  303. if (!p && !prhs) {
  304. return true;
  305. }
  306. TRACELSM(TRACE_DETAIL, (dbgDump << "DSMediaType::MatchingMajor() this = " << *this << "\rprhs = " << prhs), "");
  307. return p && prhs && p->majortype == prhs->majortype;
  308. }
  309. inline bool MatchingMajor(const DSMediaType &rhs) const {
  310. return MatchingMajor(rhs.p);
  311. }
  312. #ifdef _DEBUG
  313. inline tostream& operator<<(tostream &d) {
  314. d << p;
  315. if (p) {
  316. d << _T(" major = ") << GUID2(p->majortype) << _T(" sub = ") << GUID2(p->subtype);
  317. }
  318. return d;
  319. }
  320. #endif
  321. };
  322. class DSFilterMoniker : public W32Moniker {
  323. public:
  324. inline DSFilterMoniker() {}
  325. inline DSFilterMoniker(const PQMoniker &a) : W32Moniker(a) {}
  326. inline DSFilterMoniker(const W32Moniker &a) : W32Moniker(a) {}
  327. inline DSFilterMoniker(IMoniker *p) : W32Moniker(p) {}
  328. inline DSFilterMoniker(IUnknown *p) : W32Moniker(p) {}
  329. inline DSFilterMoniker(const DSFilterMoniker &a) : W32Moniker(a) {}
  330. CComBSTR GetName() const {
  331. CComVariant vName;
  332. vName.vt = VT_BSTR;
  333. HRESULT hr = (GetPropertyBag())->Read(OLESTR("FriendlyName"), &vName, NULL);
  334. if (FAILED(hr)) {
  335. TRACELM(TRACE_ERROR, "DSFilterMoniker::GetName() can't read friendly name");
  336. return CComBSTR();
  337. }
  338. USES_CONVERSION;
  339. ASSERT(vName.vt == VT_BSTR);
  340. CComBSTR Name(vName.bstrVal);
  341. return Name;
  342. }
  343. DSFilter GetFilter() const;
  344. };
  345. typedef Forward_Sequence<
  346. PQCreateDevEnum,
  347. PQEnumMoniker,
  348. DSFilterMoniker,
  349. ICreateDevEnum,
  350. IEnumMoniker,
  351. IMoniker*> DSDeviceSequence;
  352. typedef Forward_Sequence<
  353. PQFilterMapper,
  354. PQEnumMoniker,
  355. DSFilterMoniker,
  356. IFilterMapper2,
  357. IEnumMoniker,
  358. IMoniker*> DSFilterMapperSequence;
  359. typedef Forward_Sequence<
  360. PQPin,
  361. PQEnumMediaTypes,
  362. DSMediaType,
  363. IPin,
  364. IEnumMediaTypes,
  365. AM_MEDIA_TYPE*> DSPinSequence;
  366. class DSGraph;
  367. class DSPin : public DSPinSequence {
  368. public:
  369. DSPin() {}
  370. DSPin(const PQPin &a) : DSPinSequence(a) {}
  371. DSPin(IPin *p) : DSPinSequence(p) {}
  372. DSPin(IUnknown *p) : DSPinSequence(p) {}
  373. DSPin(const DSPin &a) : DSPinSequence(a) {}
  374. CString GetName() const {
  375. CString csPinName;
  376. PIN_INFO pinfo;
  377. HRESULT hr = (*this)->QueryPinInfo(&pinfo);
  378. if (SUCCEEDED(hr)) {
  379. csPinName = pinfo.achName;
  380. if (pinfo.pFilter) pinfo.pFilter->Release();
  381. }
  382. return csPinName;
  383. }
  384. PIN_DIRECTION GetDirection() const {
  385. PIN_DIRECTION pin1dir;
  386. HRESULT hr = (*this)->QueryDirection(&pin1dir);
  387. if (FAILED(hr)) {
  388. TRACELM(TRACE_ERROR, "DSPin::GetDirection() can't call QueryDirection");
  389. THROWCOM(E_UNEXPECTED);
  390. }
  391. return pin1dir;
  392. }
  393. bool IsConnected() const {
  394. return GetConnection() != DSPin();
  395. }
  396. bool IsRenderable() {
  397. CString csName(GetName());
  398. if (!csName.IsEmpty() && csName.GetAt(0) == '~') {
  399. return false;
  400. }
  401. return true;
  402. }
  403. bool IsInput() const {
  404. return GetDirection() == PINDIR_INPUT;
  405. }
  406. static inline bool IsInput(const DSPin pin) {
  407. PIN_DIRECTION pin1dir = pin.GetDirection();
  408. return pin1dir == PINDIR_INPUT;
  409. }
  410. bool IsKsProxied() const;
  411. HRESULT GetMediums(KSMediumList &MediumList) const {
  412. TRACELSM(TRACE_DETAIL, (dbgDump << "DSPin::GetMediums() " << this), "");
  413. PQKSPin pin(*this);
  414. if (!pin) {
  415. TRACELM(TRACE_DETAIL, "DSPin::GetMedium() can't get IKsPin");
  416. return E_FAIL;
  417. }
  418. HRESULT hr = pin->KsQueryMediums(&MediumList);
  419. // undone: in win64 mediumlist.size is really __int64. fix output operator for
  420. // that type and remove cast
  421. TRACELSM(TRACE_DETAIL, (dbgDump <<
  422. "DSPin::GetMediums() hr = " <<
  423. hr <<
  424. " size = " <<
  425. (long) MediumList.size()), "");
  426. return hr;
  427. }
  428. static inline bool HasCategory(DSPin& pin, const GUID2 &clsCategory, const PIN_DIRECTION pd) {
  429. return pin.HasCategory(clsCategory, pd);
  430. }
  431. static inline bool HasCategory(DSPin& pin, const GUID2 &clsCategory) {
  432. return pin.HasCategory(clsCategory);
  433. }
  434. void GetCategory(CLSID &clsCategory) const {
  435. ULONG outcount;
  436. PQKSPropertySet ps(*this);
  437. if (!ps) {
  438. TRACELM(TRACE_ERROR, "DSPin::GetCategory() can't get IKsPropertySet");
  439. clsCategory = GUID_NULL;
  440. return;
  441. }
  442. HRESULT hr = ps->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
  443. NULL, 0, &clsCategory, sizeof(clsCategory), &outcount);
  444. if (FAILED(hr)) {
  445. TRACELSM(TRACE_ERROR, (dbgDump << "DSPin::GetCategory() can't get pin category hr = " << hr), "");
  446. clsCategory = GUID_NULL;
  447. }
  448. return;
  449. }
  450. DSPin GetConnection(void) const {
  451. DSPin pConn;
  452. HRESULT hr = (*this)->ConnectedTo(&pConn);
  453. if (FAILED(hr) || !pConn) {
  454. return DSPin();
  455. }
  456. #ifdef _DEBUG
  457. DSPin pConn2;
  458. hr = pConn->ConnectedTo(&pConn2);
  459. if (FAILED(hr) || pConn2.IsEqualObject(*this)) {
  460. TRACELSM(TRACE_DETAIL, (dbgDump << "DSPin::GetConnection() " << *this << " is Connected to " << pConn << " but not vice versa"), "");
  461. }
  462. #endif
  463. return pConn;
  464. }
  465. DSMediaType GetConnectionMediaType(void) const {
  466. DSMediaType amt(GUID_NULL);
  467. HRESULT hr = (*this)->ConnectionMediaType(amt);
  468. if (SUCCEEDED(hr)) {
  469. return amt;
  470. } else {
  471. return DSMediaType();
  472. }
  473. }
  474. DSGraph GetGraph(void) const;
  475. DSFilter GetFilter(void) const;
  476. bool HasCategory(const GUID2 &clsCategory, const PIN_DIRECTION pd) const;
  477. bool HasCategory(const GUID2 &clsCategory) const;
  478. HRESULT Connect(DSPin ConnectTo, const AM_MEDIA_TYPE *pMediaType = NULL);
  479. HRESULT IntelligentConnect(DSPin ConnectTo, const AM_MEDIA_TYPE *pMediaType = NULL) {
  480. // undone: implement this via igb2, currently we're just connecting directly via graph mgr.
  481. return Connect(ConnectTo, pMediaType);
  482. }
  483. HRESULT IntelligentConnect(DSFilter& Filter1, DSFilterList &intermediates, const DWORD dwFlags = 0, const PIN_DIRECTION pd = DOWNSTREAM);
  484. HRESULT Disconnect(void);
  485. bool CanRoute(const DSPin pin2) const;
  486. protected:
  487. bool Routable(const DSPin pin2) const;
  488. };
  489. typedef Forward_Sequence<
  490. PQFilter,
  491. PQEnumPins,
  492. DSPin,
  493. IBaseFilter ,
  494. IEnumPins,
  495. IPin*> DSFilterSequence;
  496. inline bool _cdecl operator==(const CString &cs, const DSFilterSequence& pF);
  497. inline bool _cdecl operator==(const CLSID &cls, const DSFilterSequence& pF);
  498. class DSFilter : public DSFilterSequence {
  499. public:
  500. DSFilter() {}
  501. DSFilter(const PQFilter &a) : DSFilterSequence(a) {}
  502. DSFilter(const DSFilterSequence &a) : DSFilterSequence(a) {}
  503. DSFilter(IBaseFilter *p) : DSFilterSequence(p) {}
  504. DSFilter(IUnknown *p) : DSFilterSequence(p) {}
  505. DSFilter(const DSFilter &a) : DSFilterSequence(a) {}
  506. DSFilter(REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) : DSFilterSequence(rclsid, pUnkOuter, dwClsContext) {}
  507. DSGraph GetGraph(void);
  508. void GetPinCounts(ULONG &ulIn, ULONG &ulOut) const;
  509. ULONG PinCount(PIN_DIRECTION pd) {
  510. ULONG in, out;
  511. GetPinCounts(in, out);
  512. if (pd == PINDIR_INPUT) {
  513. return in;
  514. } else {
  515. return out;
  516. }
  517. }
  518. ULONG OutputPinCount() const {
  519. ULONG in, out;
  520. GetPinCounts(in, out);
  521. return out;
  522. }
  523. ULONG InputPinCount() const {
  524. ULONG in, out;
  525. GetPinCounts(in, out);
  526. return in;
  527. }
  528. bool HasFreePins(PIN_DIRECTION pd) const {
  529. int count = 0;
  530. for (iterator i = begin(); i != end(); ++i) {
  531. DSPin p(*i);
  532. if (p.GetDirection() != pd) {
  533. continue;
  534. }
  535. if (p.IsConnected()) {
  536. continue;
  537. }
  538. ++count;
  539. }
  540. return !!count;
  541. }
  542. bool IsKsProxied() const {
  543. CLSID cls;
  544. HRESULT hr = (*this)->GetClassID(&cls);
  545. if (FAILED(hr)) {
  546. TRACELM(TRACE_ERROR, "DSFilter::IsKsProxied() can't get class id");
  547. return false; // if it doesn't have a clsid it can't be the proxy
  548. }
  549. #pragma warning(disable: 4800)
  550. return (cls == CLSID_Proxy);
  551. #pragma warning(default: 4800)
  552. }
  553. #if 0
  554. DSFilter *operator&() { // using vector instead of list so don't need this
  555. return this;
  556. }
  557. #endif
  558. bool IsXBar() const;
  559. CString GetName(void) const;
  560. DSPin FirstPin(PIN_DIRECTION pd = PINDIR_INPUT) const {
  561. for (DSFilter::iterator i = begin(); i != end(); ++i) {
  562. if ((*i).GetDirection() == pd) {
  563. return *i;
  564. }
  565. }
  566. return DSPin();
  567. }
  568. GUID2 ClassID() const {
  569. PQPersist p(*this);
  570. GUID2 g;
  571. p->GetClassID(&g);
  572. return g;
  573. }
  574. };
  575. typedef Forward_Sequence<
  576. PQGraphBuilder,
  577. PQEnumFilters,
  578. DSFilter,
  579. IGraphBuilder,
  580. IEnumFilters,
  581. IBaseFilter*> DSGraphContainer;
  582. typedef std_arity3pmf<
  583. ICreateDevEnum, REFCLSID, IEnumMoniker **, ULONG, HRESULT
  584. > DSDevicesMFType;
  585. typedef std_bndr_mf_1_3<DSDevicesMFType> DSDevicesFetchType;
  586. class DSDevices : public DSDeviceSequence {
  587. public:
  588. DSDevicesFetchType * Fetch;
  589. DSDevices(DSDeviceSequence &p, REFCLSID clsid) : Fetch(NULL), DSDeviceSequence(p) {
  590. SetFetch(clsid);
  591. }
  592. DSDevices(PQCreateDevEnum &p, REFCLSID clsid) : Fetch(NULL), DSDeviceSequence(p) {
  593. SetFetch(clsid);
  594. }
  595. DSDevices(DSDevices &d) : DSDeviceSequence(d) {
  596. SetFetch((d.Fetch)->arg1val);
  597. }
  598. virtual DSDeviceSequence::FetchType * GetFetch() const { return Fetch; }
  599. ~DSDevices() { if (Fetch) delete Fetch; }
  600. protected:
  601. // NOTE: this invalidates all currently outstanding iterators
  602. // don't use outside of construction
  603. void SetFetch(REFCLSID clsid) {
  604. if (Fetch) {
  605. delete Fetch;
  606. }
  607. Fetch =
  608. new DSDevicesFetchType(std_arity3_member(&ICreateDevEnum::CreateClassEnumerator),
  609. clsid,
  610. 0);
  611. }
  612. };
  613. typedef std_arity15pmf<
  614. IFilterMapper2,
  615. IEnumMoniker **, // enumerator returned
  616. DWORD, // 0 flags
  617. BOOL, // don't match wildcards
  618. DWORD, // at least this merit needed
  619. BOOL, // need at least one input pin
  620. DWORD, // input media type count
  621. const GUID *, // input major+sub pair array
  622. const REGPINMEDIUM *, // input medium
  623. const CLSID*, // input pin category
  624. BOOL, // must the input be rendered?
  625. BOOL, // need at least one output pin
  626. DWORD, // output media type count
  627. const GUID *, // output major type
  628. const REGPINMEDIUM *, // output medium
  629. const CLSID*, // output pin category
  630. HRESULT
  631. > DSFilterMapperMFType;
  632. typedef std_bndr_mf_2_3_4_5_6_7_8_9_10_11_12_13_14_15<DSFilterMapperMFType> DSFilterMapperFetchType;
  633. class DSFilterMapper : public DSFilterMapperSequence {
  634. public:
  635. DSFilterMapperFetchType *Fetch;
  636. protected:
  637. // NOTE: this invalidates all currently outstanding iterators
  638. // don't use outside of construction
  639. void SetFetch(
  640. DWORD dwFlags, // 0
  641. BOOL bExactMatch, // don't match wildcards
  642. DWORD dwMerit, // at least this merit needed
  643. BOOL bInputNeeded, // need at least one input pin
  644. DWORD cInputTypes, // Number of input types to match
  645. // Any match is OK
  646. const GUID *pInputTypes, // input major+subtype pair array
  647. const REGPINMEDIUM *pMedIn, // input medium
  648. const CLSID *pPinCategoryIn, // input pin category
  649. BOOL bRender, // must the input be rendered?
  650. BOOL bOutputNeeded, // need at least one output pin
  651. DWORD cOutputTypes, // Number of output types to match
  652. // Any match is OK
  653. const GUID *pOutputTypes, // output major+subtype pair array
  654. const REGPINMEDIUM *pMedOut, // output medium
  655. const CLSID *pPinCategoryOut // output pin category
  656. ) {
  657. if (Fetch) {
  658. delete Fetch;
  659. }
  660. Fetch =
  661. new DSFilterMapperFetchType(std_arity15_member(&IFilterMapper2::EnumMatchingFilters),
  662. dwFlags, // 0
  663. bExactMatch,
  664. dwMerit,
  665. bInputNeeded,
  666. cInputTypes, // Number of input types to match
  667. pInputTypes, // input major+subtype pair array
  668. // Any match is OK
  669. pMedIn,
  670. pPinCategoryIn,
  671. bRender,
  672. bOutputNeeded,
  673. cOutputTypes, // Number of output types to match
  674. // Any match is OK
  675. pOutputTypes, // output major+subtype pair array
  676. pMedOut,
  677. pPinCategoryOut
  678. );
  679. }
  680. public:
  681. DSFilterMapper(PQFilterMapper &p,
  682. DWORD dwFlags, // 0
  683. BOOL bExactMatch, // don't match wildcards
  684. DWORD dwMerit, // at least this merit needed
  685. BOOL bInputNeeded, // need at least one input pin
  686. DWORD cInputTypes, // Number of input types to match
  687. // Any match is OK
  688. const GUID *pInputTypes, // input major+subtype pair array
  689. const REGPINMEDIUM *pMedIn, // input medium
  690. const CLSID* pInCat, // input pin category
  691. BOOL bRender, // must the input be rendered?
  692. BOOL bOutputNeeded, // need at least one output pin
  693. DWORD cOutputTypes, // Number of output types to match
  694. // Any match is OK
  695. const GUID *pOutputTypes, // output major+subtype pair array
  696. const REGPINMEDIUM *pMedOut, // output medium
  697. const CLSID* pOutCat // output pin category
  698. ) : Fetch(NULL), DSFilterMapperSequence(p) {
  699. SetFetch(
  700. dwFlags, // 0
  701. bExactMatch,
  702. dwMerit,
  703. bInputNeeded,
  704. cInputTypes, // Number of input types to match
  705. // Any match is OK
  706. pInputTypes, // input major+subtype pair array
  707. pMedIn,
  708. pInCat,
  709. bRender,
  710. bOutputNeeded,
  711. cOutputTypes, // Number of output types to match
  712. // Any match is OK
  713. pOutputTypes, // output major+subtype pair array
  714. pMedOut,
  715. pOutCat
  716. );
  717. }
  718. DSFilterMapper(DSFilterMapperSequence &p,
  719. DWORD dwFlags, // 0
  720. BOOL bExactMatch, // don't match wildcards
  721. DWORD dwMerit, // at least this merit needed
  722. BOOL bInputNeeded, // need at least one input pin
  723. DWORD cInputTypes, // Number of input types to match
  724. // Any match is OK
  725. const GUID *pInputTypes, // input major+subtype pair array
  726. const REGPINMEDIUM *pMedIn, // input medium
  727. const CLSID* pInCat, // input pin category
  728. BOOL bRender, // must the input be rendered?
  729. BOOL bOutputNeeded, // need at least one output pin
  730. DWORD cOutputTypes, // Number of output types to match
  731. // Any match is OK
  732. const GUID *pOutputTypes, // output major+subtype pair array
  733. const REGPINMEDIUM *pMedOut, // output medium
  734. const CLSID* pOutCat // output pin category
  735. ) : Fetch(NULL), DSFilterMapperSequence(p) {
  736. SetFetch(
  737. dwFlags, // 0
  738. bExactMatch,
  739. dwMerit,
  740. bInputNeeded,
  741. cInputTypes, // Number of input types to match
  742. // Any match is OK
  743. pInputTypes, // input major+subtype pair array
  744. pMedIn,
  745. pInCat,
  746. bRender,
  747. bOutputNeeded,
  748. cOutputTypes, // Number of output types to match
  749. // Any match is OK
  750. pOutputTypes, // output major+subtype pair array
  751. pMedOut,
  752. pOutCat
  753. );
  754. }
  755. DSFilterMapper(DSFilterMapper &d) : DSFilterMapperSequence(d) {
  756. SetFetch((d.Fetch)->arg2val, (d.Fetch)->arg3val, (d.Fetch)->arg4val, (d.Fetch)->arg5val,
  757. (d.Fetch)->arg6val, (d.Fetch)->arg7val, (d.Fetch)->arg8val, (d.Fetch)->arg9val,
  758. (d.Fetch)->arg10val, (d.Fetch)->arg11val, (d.Fetch)->arg12val,
  759. (d.Fetch)->arg13val, (d.Fetch)->arg14val, (d.Fetch)->arg15val
  760. );
  761. }
  762. virtual DSFilterMapperSequence::FetchType *GetFetch() const { return Fetch; }
  763. ~DSFilterMapper() { if (Fetch) delete Fetch; }
  764. };
  765. class DSREGPINMEDIUM : public REGPINMEDIUM {
  766. public:
  767. DSREGPINMEDIUM() { memset(this, 0, sizeof(*this)); }
  768. DSREGPINMEDIUM(REFGUID SetInit, ULONG IdInit, ULONG FlagsInit) {
  769. clsMedium = SetInit;
  770. dw1 = IdInit;
  771. dw2 = FlagsInit;
  772. }
  773. DSREGPINMEDIUM(DSREGPINMEDIUM &rhs) {
  774. clsMedium = rhs.clsMedium;
  775. dw1 = rhs.dw1;
  776. dw2 = rhs.dw2;
  777. }
  778. DSREGPINMEDIUM(KSPinMedium &rhs) {
  779. clsMedium = rhs.Set;
  780. dw1 = rhs.Id;
  781. dw2 = rhs.Flags;
  782. }
  783. DSREGPINMEDIUM& operator=(const KSPinMedium &rhs) {
  784. if (reinterpret_cast<const REGPINMEDIUM *>(&rhs) != this) {
  785. clsMedium = rhs.Set;
  786. dw1 = rhs.Id;
  787. dw2 = rhs.Flags;
  788. }
  789. return *this;
  790. }
  791. DSREGPINMEDIUM& operator=(const DSREGPINMEDIUM &rhs) {
  792. if (&rhs != this) {
  793. clsMedium = rhs.clsMedium;
  794. dw1 = rhs.dw1;
  795. dw2 = rhs.dw2;
  796. }
  797. return *this;
  798. }
  799. bool operator==(const DSREGPINMEDIUM &rhs) const {
  800. // NOTE: at some point there will be a flag in Flags to
  801. // indicate whether or not Id is significant for this object
  802. // at that point this method will need to change
  803. return (dw1 == rhs.dw1 && clsMedium == rhs.clsMedium);
  804. }
  805. bool operator!=(const DSREGPINMEDIUM &rhs) const {
  806. // NOTE: at some point there will be a flag in Flags to
  807. // indicate whether or not Id is significant for this object
  808. // at that point this method will need to change
  809. return !(*this == rhs);
  810. }
  811. };
  812. const long DEFAULT_GRAPH_STATE_TIMEOUT = 5000;
  813. class DSGraph : public DSGraphContainer {
  814. public:
  815. DSGraph() {}
  816. DSGraph(const DSGraph &a) : DSGraphContainer(a) {}
  817. DSGraph(const PQGraphBuilder &a) : DSGraphContainer(a) {}
  818. DSGraph(const DSGraphContainer &a) : DSGraphContainer(a) {}
  819. DSGraph(IGraphBuilder *p) : DSGraphContainer(p) {}
  820. DSGraph(IUnknown *p) : DSGraphContainer(p) {}
  821. HRESULT AddToROT(DWORD *pdwObjectRegistration);
  822. void RemoveFromROT(DWORD dwObjectRegistration);
  823. // graph operation
  824. inline OAFilterState GetState(long timeout = DEFAULT_GRAPH_STATE_TIMEOUT) {
  825. PQMediaControl pMC(*this);
  826. if(!pMC) {
  827. THROWCOM(E_UNEXPECTED);
  828. }
  829. OAFilterState state;
  830. HRESULT hr = pMC->GetState(timeout, &state);
  831. if (hr == VFW_S_CANT_CUE) {
  832. state = State_Paused;
  833. } else if (hr == VFW_S_STATE_INTERMEDIATE) {
  834. THROWCOM(HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  835. } else if (FAILED(hr)) {
  836. TRACELSM(TRACE_ERROR, (dbgDump << "DSGraph::GetState() can't get graph state hr = " << hr), "");
  837. THROWCOM(hr);
  838. }
  839. return state;
  840. }
  841. inline bool IsPlaying() {
  842. try {
  843. return GetState() == State_Running;
  844. } catch(...) {
  845. return false;
  846. }
  847. }
  848. inline bool IsPaused() {
  849. try {
  850. return GetState() == State_Paused;
  851. } catch(...) {
  852. return false;
  853. }
  854. }
  855. inline bool IsStopped() {
  856. try {
  857. return GetState() == State_Stopped;
  858. } catch(...) {
  859. return false;
  860. }
  861. }
  862. // graph building helpers
  863. HRESULT Connect(DSFilter &pStart, DSFilter &pStop, DSFilterList &Added, const DWORD dwFlags = 0, PIN_DIRECTION pFilter1Direction = DOWNSTREAM);
  864. bool Connect(DSFilter &pFilter1, DSFilterMoniker &pMoniker, DSFilter &pAdded, DSFilterList &NewIntermediateFilters, const DWORD dwFlags = 0, PIN_DIRECTION pFilter1Direction = DOWNSTREAM);
  865. typedef bool (DSGraph::*ConnectPred_t)(DSPin&, DSFilter&, DWORD dwFlags);
  866. typedef arity5pmf<DSGraph, DSPin&, DSFilterMoniker&, DSFilter&, DSFilterIDList &, ConnectPred_t, bool> LoadCheck_t;
  867. typedef arity5pmf<DSGraph, DSPin&, DSFilter&, DSFilter&, DSFilterIDList &, ConnectPred_t, bool> ConnectCheck_t;
  868. bool DisconnectPin(DSPin &pPin, const bool fRecurseInputs, const bool fRecurseOutputs);
  869. bool DisconnectFilter(DSFilter &pFilter, const bool fRecurseInputs, const bool fRecurseOutputs);
  870. bool RemoveFilter(DSFilter &pFilter);
  871. bool IsConnectable(DSPin &pPin1, DSFilter &Mapper, DSFilter &Destination, DSFilterIDList &NewFilters, const DWORD dwFlags, ConnectPred_t ConnPred);
  872. bool IsLoadable(DSPin &pPin1, DSFilterMoniker &Mapper, DSFilter &Destination, DSFilterIDList &IntermediateFilters, const DWORD dwFlags, ConnectPred_t ConnPred);
  873. bool IsPinConnected(const DSPin &pPin1, const DSFilter &pFDestination, DSFilterIDList &IntermediateFilters, const PIN_DIRECTION destdir) const;
  874. // generic recursive build functions
  875. #ifdef ATTEMPT_DIRECT_CONNECT
  876. bool ConnectPinDirect(DSPin &pPin, DSFilter &pFilter2, DWORD dwFlags);
  877. #else
  878. bool HasMediaType(const DSMediaType &LeftMedia, const DSPin &pPinRight) const;
  879. bool HasMedium(const KSPinMedium &Medium1, const DSPin &pPin2) const;
  880. bool HasUnconnectedMedium(const DSPin &pPinLeft, const DSPin &pPin2, int& cUseable) const;
  881. bool HasUnconnectedMediaType(const DSPin &pPinLeft, const DSPin &pPin2, DWORD dwFlags) const;
  882. bool ConnectPinByMedium(DSPin &pPin, DSFilter &pFilter2, DWORD dwFlags);
  883. bool ConnectPinByMediaType(DSPin &pPin1, DSFilter &pFilter1, DWORD dwFlags);
  884. #endif
  885. bool FindPinByMedium(DSPin &pPin, DSFilter &pFilter2, DSFilterIDList &InterediateFilters, const DWORD dwFlags);
  886. bool LoadPinByMedium(KSPinMedium &medium, DSPin &pPinLeft, DSFilter &pFilter2, DSFilterIDList &IntermediateFilters, const DWORD dwFlags);
  887. bool LoadPinByAnyMedium(DSPin &pPin, DSFilter &pFilter2, DSFilterIDList &IntermediateFilters, const DWORD dwFlags);
  888. bool FindPinByMediaType(DSPin &pPin, DSFilter &pFilter2, DSFilterIDList &InterediateFilters, const DWORD dwFlags);
  889. bool LoadPinByMediaType(DSPin &pPin1, DSFilter &pFilter1, DSFilterIDList &IntermediatesAdded, const DWORD dwFlags, const DWORD dwMerit);
  890. bool LoadPinByAnyMediaType(DSPin &pPin, DSFilter &pFilter2, DSFilterIDList &IntermediateFilters, const DWORD dwFlags);
  891. enum {
  892. RENDER_ALL_PINS = 0x01,
  893. IGNORE_EXISTING_CONNECTIONS = 0x02,
  894. DO_NOT_LOAD = 0x04,
  895. ATTEMPT_MERIT_DO_NOT_USE = 0x08,
  896. ATTEMPT_MERIT_UNLIKELY = 0x10,
  897. ALLOW_WILDCARDS = 0x20,
  898. IGNORE_MEDIATYPE_ERRORS = 0x40,
  899. DONT_TERMINATE_ON_RENDERER= 0x80,
  900. BIDIRECTIONAL_MEDIATYPE_MATCHING = 0x100,
  901. }; // render flags
  902. bool ConnectPin(DSPin &pPin1, DSFilter &pFilter2, DSFilterIDList &NewFilters, const DWORD dwFlags, PIN_DIRECTION pin1dir);
  903. bool ConnectPin(DSPin &pPin1, DSFilter &pFilter2, DSFilterList &NewFilters, const DWORD dwFlags, PIN_DIRECTION pin1dir) {
  904. DSFilterIDList AddedIDs;
  905. bool rc = ConnectPin(pPin1, pFilter2, AddedIDs, dwFlags, pin1dir);
  906. if (rc) {
  907. for (DSFilterIDList::iterator i = AddedIDs.begin(); i != AddedIDs.end(); ++i) {
  908. NewFilters.push_back((*i).first);
  909. }
  910. }
  911. return rc;
  912. }
  913. DSFilter LoadFilter(const DSFilterMoniker &pM, CString &csName);
  914. DSFilter AddMoniker(const DSFilterMoniker &pM);
  915. HRESULT AddFilter(DSFilter &pFilter, CString &csName);
  916. DSFilter AddFilter(const CLSID &cls, CString &csName);
  917. bool ConnectFilters(DSFilter &pFilter1, DSFilter &pFilter2, DSFilterIDList &NewIntermediateFilters, const DWORD dwFlags = 0, PIN_DIRECTION pFilter1Direction = DOWNSTREAM);
  918. int BuildGraphPath(const DSFilter& pStart, const DSFilter& pStop,
  919. VWStream &path, MediaMajorTypeList& MediaList, PIN_DIRECTION direction, const DSPin &InitialInput);
  920. HRESULT SetMediaEventNotificationWindow(HWND h, UINT msg, long lInstance) {
  921. // If windowless, WM_MEDIAEVENT is processed by the timer in OnTimer
  922. PQMediaEventEx pme(*this);
  923. if (!pme) {
  924. return E_UNEXPECTED;
  925. }
  926. HRESULT hr = pme->CancelDefaultHandling(EC_STATE_CHANGE);
  927. ASSERT(SUCCEEDED(hr));
  928. return pme->SetNotifyWindow((OAHWND) h, msg, lInstance);
  929. }
  930. };
  931. class DSXBarPin : public DSPin {
  932. public:
  933. DSXBarPin() {}
  934. DSXBarPin(const DSPin &p) : DSPin(p) {
  935. PQCrossbarSwitch px1(GetFilter());
  936. if (!px1) {
  937. THROWCOM(E_FAIL);
  938. }
  939. }
  940. DSXBarPin(const PQPin &p) : DSPin(p) {
  941. PQCrossbarSwitch px1(GetFilter());
  942. if (!px1) {
  943. THROWCOM(E_FAIL);
  944. }
  945. }
  946. DSXBarPin(const DSXBarPin &p) : DSPin(p) {
  947. PQCrossbarSwitch px1(GetFilter());
  948. if (!px1) {
  949. THROWCOM(E_FAIL);
  950. }
  951. }
  952. DSXBarPin(IUnknown *p) : DSPin(p) {
  953. PQCrossbarSwitch px1(GetFilter());
  954. if (!px1) {
  955. THROWCOM(E_FAIL);
  956. }
  957. }
  958. DSXBarPin(IAMCrossbar *p) : DSPin(p) {
  959. PQCrossbarSwitch px1(GetFilter());
  960. if (!px1) {
  961. THROWCOM(E_FAIL);
  962. }
  963. }
  964. #if 0
  965. static const DSXBarPin Find(const CPinPoints &pinpoints, const PQPoint &point, PIN_DIRECTION pindir);
  966. #endif
  967. // static DSPin DSPinFromIndex(const DSFilter XBar, const ULONG index);
  968. const PQPoint GetPoint() const;
  969. bool CanRoute(const DSXBarPin pin2) const;
  970. #if 0
  971. void GetRelations(const CPinPoints &pinpoint,
  972. CString &csName, CString &csType, CString &csRelName) const;
  973. #endif
  974. };
  975. inline DSFilter DSFilterMoniker::GetFilter() const {
  976. DSFilter pFilter;
  977. HRESULT hr = (*this)->BindToObject(0, 0, __uuidof(IBaseFilter), reinterpret_cast<LPVOID *>(&pFilter));
  978. if (FAILED(hr)) {
  979. // undone: it would be useful to dump the mkr display name here....
  980. TRACELSM(TRACE_ERROR, (dbgDump << "DSFilterMoniker::GetFilter() can't bind to object. hr = " << hexdump(hr)), "");
  981. return DSFilter();
  982. }
  983. return pFilter;
  984. }
  985. #ifdef _DEBUG
  986. //void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel);
  987. inline tostream &operator<<(tostream &dc, const DSREGPINMEDIUM &g) {
  988. //TRACELM(TRACE_DETAIL, "operator<<(tostream, DSREGPINMEDIUM)");
  989. const GUID2 g2(g.clsMedium);
  990. dc << _T("DSREGPINMEDIUM( ") << g2 << _T(", ") << hexdump(g.dw1) << _T(", ") << hexdump(g.dw2) << _T(")");
  991. return dc;
  992. }
  993. inline tostream& operator<<(tostream &d, const PQPin &pin) {
  994. const CString csPinName(const DSPin(pin).GetName());
  995. d << (csPinName.IsEmpty() ? CString(_T("**** UNKNOWN PIN NAME ****")) : csPinName) << " " << reinterpret_cast<void *>(pin.p);
  996. return d;
  997. }
  998. inline tostream& operator<<(tostream &d, const DSFilter &filt) {
  999. d << filt.GetName() << _T(" ") << reinterpret_cast<void *>(filt.p);
  1000. return d;
  1001. }
  1002. inline tostream& operator<<(tostream &d, const _AMMediaType *pamt) {
  1003. d << reinterpret_cast<const void *>(pamt);
  1004. if (pamt) {
  1005. d << _T(" major = ") << GUID2(pamt->majortype) << _T(" sub = ") << GUID2(pamt->subtype);
  1006. }
  1007. return d;
  1008. }
  1009. inline tostream& operator<<(tostream &d, const PQPoint &p) {
  1010. const DSFilter pF(p.first);
  1011. d << _T("PQPoint( ") << pF << _T(", ") << p.second << _T(")");
  1012. return d;
  1013. }
  1014. inline tostream& operator<<(tostream &d, const CIOPoint &p) {
  1015. d << _T("CIOPoint( ") << p.first << _T(", ") << p.second << _T(")");
  1016. return d;
  1017. }
  1018. void DumpMediaTypes(DSPin &p1, DSPin &p2);
  1019. #endif
  1020. inline bool _cdecl operator==(const CString &cs, const DSFilterSequence& pF) {
  1021. // filter name
  1022. FILTER_INFO fi;
  1023. HRESULT hr = pF->QueryFilterInfo(&fi);
  1024. if (SUCCEEDED(hr)) {
  1025. USES_CONVERSION;
  1026. if (fi.pGraph) fi.pGraph->Release();
  1027. return (cs == OLE2T(fi.achName));
  1028. }
  1029. return false;
  1030. }
  1031. inline bool _cdecl operator!=(const CString &cs, const DSFilterSequence& pF) {
  1032. return !(cs == pF);
  1033. }
  1034. inline bool _cdecl operator==(const DSFilterSequence& pF, const CString &cs) {
  1035. return (cs == pF);
  1036. }
  1037. inline bool _cdecl operator!=(const DSFilterSequence& pF, const CString &cs) {
  1038. return !(cs == pF);
  1039. }
  1040. inline bool _cdecl operator==(const CLSID &cls, const DSFilterSequence& pF) {
  1041. // filter name
  1042. CLSID cid;
  1043. HRESULT hr = pF->GetClassID(&cid);
  1044. if (SUCCEEDED(hr)) {
  1045. #pragma warning(disable: 4800)
  1046. return (cid == cls);
  1047. #pragma warning(default: 4800)
  1048. }
  1049. return false;
  1050. }
  1051. inline bool _cdecl operator!=(const CLSID &cls, const DSFilterSequence& pF) {
  1052. return !(cls == pF);
  1053. }
  1054. inline bool _cdecl operator==(const DSFilterSequence& pF, const CLSID &cls) {
  1055. return (cls == pF);
  1056. }
  1057. inline bool _cdecl operator!=(const DSFilterSequence& pF, const CLSID &cls) {
  1058. return !(cls == pF);
  1059. }
  1060. typedef enum {
  1061. tempAMPROPERTY_OvMixerOwner = 0x01 //use AMOVMIXEROWNER
  1062. } tempAMPROPERTY_NOTIFYOWNER;
  1063. typedef enum {
  1064. tempAM_OvMixerOwner_Unknown = 0x01,
  1065. tempAM_OvMixerOwner_BPC = 0x02
  1066. } tempAMOVMIXEROWNER;
  1067. inline bool DSPin::IsKsProxied() const {
  1068. return GetFilter().IsKsProxied();
  1069. }
  1070. inline bool DSFilter::IsXBar() const {
  1071. PQCrossbarSwitch px(*this);
  1072. TRACELSM(TRACE_PAINT, (dbgDump << "DSFilter::IsXBar() " << *this << " is " << ((!px) ? " not " : "")), "crossbar");
  1073. return !!px;
  1074. }
  1075. void CtorStaticDSExtendFwdSeqPMFs(void);
  1076. void DtorStaticDSExtendFwdSeqPMFs(void);
  1077. bool IsVideoFilter(const DSFilter& f);
  1078. bool IsVideoPin(const DSPin& p);
  1079. inline PIN_DIRECTION OppositeDirection(PIN_DIRECTION pd) {
  1080. if (pd == PINDIR_INPUT) {
  1081. return PINDIR_OUTPUT;
  1082. } else {
  1083. return PINDIR_INPUT;
  1084. }
  1085. }
  1086. inline bool IsVideoMediaType(const DSMediaType& mt) {
  1087. GUID2 g(mt.p->majortype);
  1088. if ((g == MEDIATYPE_Video) || (g == MEDIATYPE_AnalogVideo)) {
  1089. return true;
  1090. }
  1091. return false;
  1092. }
  1093. inline bool IsAnalogVideoCapture(const DSFilter &f) {
  1094. return !!PQAnalogVideoDecoder(f);
  1095. }
  1096. inline bool IsIPSink(const DSFilter &f) {
  1097. return !!PQBDA_IPSinkControl(f);
  1098. }
  1099. inline bool IsVPM(const DSFilter &f) {
  1100. return f.ClassID() == CLSID_VideoPortManager;
  1101. }
  1102. inline bool IsVideoRenderer(const DSFilter &f) {
  1103. return f.ClassID() == CLSID_VideoMixingRenderer;
  1104. }
  1105. inline bool IsDigitalAudioRenderer(const DSFilter &f) {
  1106. return f.ClassID() == CLSID_DSoundRender;
  1107. }
  1108. inline bool IsAnalogVideoCaptureViewingPin(const DSPin &p) {
  1109. GUID2 pincat;
  1110. p.GetCategory(pincat);
  1111. return (pincat == PIN_CATEGORY_VIDEOPORT || pincat == PIN_CATEGORY_CAPTURE);
  1112. }
  1113. inline bool IsAnalogVideoCapturePreviewPin(const DSPin &p) {
  1114. GUID2 pincat;
  1115. p.GetCategory(pincat);
  1116. return (pincat == PIN_CATEGORY_PREVIEW);
  1117. }
  1118. inline bool IsDVDNavigator(const DSFilter &f) {
  1119. return !!PQDVDNavigator(f);
  1120. }
  1121. inline bool IsL21Decoder(const DSFilter &f) {
  1122. return !!PQLine21Decoder(f);
  1123. }
  1124. inline bool IsDVDNavigatorVideoOutPin(const DSPin &p) {
  1125. DSPin::iterator iMediaType;
  1126. for (iMediaType = p.begin(); iMediaType != p.end(); ++iMediaType) {
  1127. DSMediaType mt(*iMediaType);
  1128. if ((mt.p->majortype == MEDIATYPE_MPEG2_PES ||
  1129. mt.p->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK ) &&
  1130. mt.p->subtype == MEDIASUBTYPE_MPEG2_VIDEO)
  1131. return true;
  1132. // elementary stream
  1133. if ((mt.p->majortype == MEDIATYPE_Video) &&
  1134. (mt.p->subtype == MEDIASUBTYPE_MPEG2_VIDEO ||
  1135. mt.p->subtype == MEDIASUBTYPE_RGB8 ||
  1136. mt.p->subtype == MEDIASUBTYPE_RGB565 ||
  1137. mt.p->subtype == MEDIASUBTYPE_RGB555 ||
  1138. mt.p->subtype == MEDIASUBTYPE_RGB24 ||
  1139. mt.p->subtype == MEDIASUBTYPE_RGB32))
  1140. return true;
  1141. }
  1142. return false;
  1143. }
  1144. inline bool IsDVDNavigatorSubpictureOutPin(const DSPin &p) {
  1145. DSPin::iterator iMediaType;
  1146. for (iMediaType = p.begin(); iMediaType != p.end(); ++iMediaType) {
  1147. DSMediaType mt(*iMediaType);
  1148. if ((mt.p->majortype == MEDIATYPE_MPEG2_PES ||
  1149. mt.p->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK ) &&
  1150. mt.p->subtype == MEDIASUBTYPE_DVD_SUBPICTURE)
  1151. return true;
  1152. // elementary stream
  1153. if ((mt.p->majortype == MEDIATYPE_Video) &&
  1154. mt.p->subtype == MEDIASUBTYPE_DVD_SUBPICTURE)
  1155. return true;
  1156. }
  1157. return false;
  1158. }
  1159. ///////// DSPin
  1160. inline HRESULT DSPin::IntelligentConnect(DSFilter& Filter1, DSFilterList &intermediates, const DWORD dwFlags, const PIN_DIRECTION pd) {
  1161. bool rc = GetGraph().ConnectPin(*this, Filter1, intermediates, dwFlags, pd);
  1162. if (rc) {
  1163. return NOERROR;
  1164. }
  1165. return E_FAIL;
  1166. }
  1167. inline DSFilter DSPin::GetFilter(void) const {
  1168. PIN_INFO pinfo;
  1169. HRESULT hr = (*this)->QueryPinInfo(&pinfo);
  1170. if (FAILED(hr)) {
  1171. return DSFilter();
  1172. }
  1173. DSFilter pRet;
  1174. pRet.p = pinfo.pFilter; // directly transfer ownership of ref count
  1175. return pRet;
  1176. }
  1177. inline DSGraph DSPin::GetGraph(void) const {
  1178. DSFilter f = GetFilter();
  1179. return f.GetGraph();
  1180. }
  1181. inline bool DSPin::HasCategory(const GUID2 &clsCategory) const {
  1182. TRACELSM(TRACE_DETAIL, (dbgDump << "DSPin::IsPinCategory() pin = " << this), "");
  1183. GUID2 pincat2;
  1184. GetCategory(pincat2);
  1185. return clsCategory == pincat2;
  1186. }
  1187. #endif
  1188. // end of file - dsextend.h