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.

756 lines
24 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. DTFilter.h
  5. Abstract:
  6. This module contains the Encrypter/Tagger filter declarations
  7. Author:
  8. John Bradstreet (johnbrad)
  9. Revision History:
  10. 07-Mar-2002 created
  11. --*/
  12. #ifndef __EncDec__DTFilter_h
  13. #define __EncDec__DTFilter_h
  14. #include <tuner.h> // needed for IBroadcastEvent
  15. #include <ks.h>
  16. #include <ksmedia.h>
  17. #include <bdatypes.h>
  18. #include <bdamedia.h> // EVENTID_TuningChanged, XDS_RatingsPacket
  19. #include "DTFilter_res.h"
  20. #include "PackTvRat.h" // packed TvRating definitions
  21. #include "MediaSampleAttr.h" // from the IDL file
  22. //#include "MediaAttrib.h" // IMediaSampleAttrGet/Set definitions, CAttributedMediaSample
  23. #include "..\Attrib\MediaAttrib.h" // IMediaSampleAttrGet/Set definitions, CAttributedMediaSample
  24. #include "AttrBlock.h" // attributed block definitions
  25. #include "DRMEncDec.h" // drm encryption/decryption definitions...
  26. #include "DRMSecure.h" // IDRMSecureChannel
  27. #if 1
  28. #include "rateseg.h" // before integration - I stole the code
  29. #else
  30. #include "dvrutil.h" // when we eventually integrate
  31. #endif
  32. #define DT_FILTER_NAME "Decrypt/DeTag"
  33. #define DT_INPIN_NAME "In(Enc/Tag)"
  34. #define DT_OUTPIN_NAME "Out"
  35. extern AMOVIESETUP_FILTER g_sudDTFilter;
  36. // forward declarations
  37. class CDTFilter;
  38. class CDTFilterInput;
  39. class CDTFilterOutput;
  40. // --------------------------------------------------------------------
  41. // class CDTFilterInput
  42. // --------------------------------------------------------------------
  43. class CDTFilterInput :
  44. public IKsPropertySet,
  45. public CBaseInputPin
  46. {
  47. private:
  48. CDTFilter * m_pHostDTFilter ;
  49. CCritSec m_StreamingLock;
  50. DECLARE_IUNKNOWN; // needed when have IKsPropertySet
  51. public :
  52. CDTFilterInput (
  53. IN TCHAR * pszPinName,
  54. IN CDTFilter * pDTFilter,
  55. IN CCritSec * pFilterLock, // NULL or a passed in lock
  56. OUT HRESULT * phr
  57. ) ;
  58. ~CDTFilterInput ();;
  59. STDMETHODIMP
  60. NonDelegatingQueryInterface (
  61. IN REFIID riid,
  62. OUT void ** ppv
  63. ) ;
  64. // --------------------------------------------------------------------
  65. // CBasePin methods
  66. HRESULT
  67. CheckMediaType (
  68. IN const CMediaType *
  69. ) ;
  70. HRESULT
  71. CompleteConnect (
  72. IN IPin * pIPin
  73. ) ;
  74. HRESULT
  75. BreakConnect (
  76. ) ;
  77. // --------------------------------------------------------------------
  78. // CBaseInputPin methods
  79. STDMETHODIMP
  80. Receive (
  81. IN IMediaSample * pIMediaSample
  82. ) ;
  83. STDMETHODIMP
  84. BeginFlush (
  85. ) ;
  86. STDMETHODIMP
  87. EndFlush (
  88. ) ;
  89. STDMETHODIMP
  90. EndOfStream (
  91. );
  92. // --------------------------------------------------------------------
  93. // IKSPropertySet methods (Forward all calls to the output pin)
  94. STDMETHODIMP
  95. Set(
  96. IN REFGUID guidPropSet,
  97. IN DWORD dwPropID,
  98. IN LPVOID pInstanceData,
  99. IN DWORD cbInstanceData,
  100. IN LPVOID pPropData,
  101. IN DWORD cbPropData
  102. );
  103. STDMETHODIMP
  104. Get(
  105. IN REFGUID guidPropSet,
  106. IN DWORD dwPropID,
  107. IN LPVOID pInstanceData,
  108. IN DWORD cbInstanceData,
  109. OUT LPVOID pPropData,
  110. IN DWORD cbPropData,
  111. OUT DWORD *pcbReturned
  112. );
  113. STDMETHODIMP
  114. QuerySupported(
  115. IN REFGUID guidPropSet,
  116. IN DWORD dwPropID,
  117. OUT DWORD *pTypeSupport
  118. );
  119. // --------------------------------------------------------------------
  120. // class methods
  121. HRESULT
  122. StreamingLock (
  123. );
  124. HRESULT
  125. StreamingUnlock (
  126. );
  127. HRESULT
  128. SetAllocatorProperties (
  129. IN ALLOCATOR_PROPERTIES * ppropInputRequest
  130. ) ;
  131. HRESULT
  132. GetRefdConnectionAllocator (
  133. OUT IMemAllocator ** ppAlloc
  134. ) ;
  135. } ;
  136. // --------------------------------------------------------------------
  137. // class CDTFilterOutput
  138. // --------------------------------------------------------------------
  139. class CDTFilterOutput :
  140. public CBaseOutputPin
  141. {
  142. CDTFilter * m_pHostDTFilter ;
  143. // void FilterLock_ () { m_pLock -> Lock () ; }
  144. // void FilterUnlock_ () { m_pLock -> Unlock () ; }
  145. public :
  146. CDTFilterOutput (
  147. IN TCHAR * pszPinName,
  148. IN CDTFilter * pDTFilter,
  149. IN CCritSec * pFilterLock,
  150. OUT HRESULT * phr
  151. ) ;
  152. ~CDTFilterOutput (
  153. );
  154. DECLARE_IUNKNOWN ;
  155. HRESULT
  156. SendSample (
  157. IN IMediaSample * pIMS
  158. ) ;
  159. STDMETHODIMP
  160. NonDelegatingQueryInterface (
  161. IN REFIID riid,
  162. OUT void ** ppv
  163. ) ;
  164. // --------------------------------------------------------------------
  165. // CBasePin methods
  166. HRESULT
  167. DecideBufferSize (
  168. IN IMemAllocator * pAlloc,
  169. IN ALLOCATOR_PROPERTIES * ppropInputRequest
  170. ) ;
  171. HRESULT
  172. GetMediaType (
  173. IN int iPosition,
  174. OUT CMediaType * pmt
  175. ) ;
  176. HRESULT
  177. CheckMediaType (
  178. IN const CMediaType *
  179. ) ;
  180. HRESULT
  181. CompleteConnect (
  182. IN IPin * pIPin
  183. ) ;
  184. HRESULT
  185. BreakConnect (
  186. ) ;
  187. HRESULT
  188. DecideAllocator (
  189. IN IMemInputPin * pPin,
  190. IN IMemAllocator ** ppAlloc
  191. ) ;
  192. STDMETHOD(Notify) (
  193. IBaseFilter *pSender,
  194. Quality q
  195. );
  196. // Class methods
  197. /* HRESULT
  198. SendLock (
  199. );
  200. HRESULT
  201. SendUnlock (
  202. );
  203. */
  204. // IKSPropertySet forwarding methods....
  205. HRESULT
  206. IsInterfaceOnPinConnectedTo_Supported(
  207. IN REFIID riid
  208. );
  209. HRESULT
  210. KSPropSetFwd_Set(
  211. IN REFGUID guidPropSet,
  212. IN DWORD dwPropID,
  213. IN LPVOID pInstanceData,
  214. IN DWORD cbInstanceData,
  215. IN LPVOID pPropData,
  216. IN DWORD cbPropData
  217. );
  218. HRESULT
  219. KSPropSetFwd_Get(
  220. IN REFGUID guidPropSet,
  221. IN DWORD dwPropID,
  222. IN LPVOID pInstanceData,
  223. IN DWORD cbInstanceData,
  224. OUT LPVOID pPropData,
  225. IN DWORD cbPropData,
  226. OUT DWORD *pcbReturned
  227. );
  228. HRESULT
  229. KSPropSetFwd_QuerySupported(
  230. IN REFGUID guidPropSet,
  231. IN DWORD dwPropID,
  232. OUT DWORD *pTypeSupport
  233. );
  234. } ;
  235. // --------------------------------------------------------------------
  236. // class CDTFilter
  237. // --------------------------------------------------------------------
  238. class CDTFilter :
  239. public CBaseFilter, // dshow base class
  240. public ISpecifyPropertyPages,
  241. public IDTFilter,
  242. public IDTFilterConfig,
  243. public IBroadcastEvent
  244. {
  245. friend CDTFilterInput; // so input pin can call FlushDropQueue on BeginFlush()
  246. CDTFilterInput * m_pInputPin ;
  247. CDTFilterOutput * m_pOutputPin ;
  248. CCritSec m_CritSecDropQueue;
  249. CCritSec m_CritSecAdviseTime;
  250. BOOL
  251. CompareConnectionMediaType_ (
  252. IN const AM_MEDIA_TYPE * pmt,
  253. IN CBasePin * pPin
  254. ) ;
  255. BOOL
  256. CheckInputMediaType_ (
  257. IN const AM_MEDIA_TYPE * pmt
  258. ) ;
  259. BOOL
  260. CheckOutputMediaType_ (
  261. IN const AM_MEDIA_TYPE * pmt
  262. ) ;
  263. public :
  264. CDTFilter (
  265. IN TCHAR * pszFilterName,
  266. IN IUnknown * punkControlling,
  267. IN REFCLSID rCLSID,
  268. OUT HRESULT * phr
  269. ) ;
  270. ~CDTFilter () ;
  271. static
  272. CUnknown *
  273. CreateInstance (
  274. IN IUnknown * punk,
  275. OUT HRESULT * phr
  276. ) ;
  277. static void CALLBACK // used to create a global crit sec
  278. InitInstance (
  279. IN BOOL bLoading,
  280. IN const CLSID *rclsid
  281. );
  282. STDMETHODIMP
  283. NonDelegatingQueryInterface (
  284. IN REFIID riid,
  285. OUT void ** ppv
  286. ) ;
  287. DECLARE_IUNKNOWN ;
  288. // =====================================================================
  289. // Worker Methods
  290. // tell folk we got something...
  291. HRESULT FireBroadcastEvent(IN const GUID &eventID);
  292. HRESULT ProposeNewOutputMediaType (
  293. IN CMediaType * pmt,
  294. OUT CMediaType * pmtOut
  295. );
  296. HRESULT BindDRMLicense(
  297. IN LONG cbKID,
  298. IN BYTE * pbKID
  299. );
  300. HRESULT UnBindDRMLicenses(
  301. );
  302. // =====================================================================
  303. // IDTFilter
  304. STDMETHODIMP
  305. get_EvalRatObjOK(
  306. OUT HRESULT *pHrCoCreateRetVal
  307. );
  308. STDMETHOD(GetCurrRating)(
  309. OUT EnTvRat_System *pEnSystem,
  310. OUT EnTvRat_GenericLevel *pEnRating,
  311. OUT LONG *plbfEnAttr //BfEnTvRat_GenericAttributes
  312. );
  313. STDMETHOD(get_BlockedRatingAttributes)(
  314. IN EnTvRat_System enSystem,
  315. IN EnTvRat_GenericLevel enLevel,
  316. OUT LONG *plbfEnAttr // BfEnTvRat_GenericAttributes
  317. );
  318. STDMETHOD(put_BlockedRatingAttributes)(
  319. IN EnTvRat_System enSystem,
  320. IN EnTvRat_GenericLevel enLevel,
  321. IN LONG lbfEnAttrs // BfEnTvRat_GenericAttributes
  322. );
  323. STDMETHOD(get_BlockUnRated)(
  324. OUT BOOL *pmfBlockUnRatedShows
  325. );
  326. STDMETHOD(put_BlockUnRated)(
  327. IN BOOL fBlockUnRatedShows
  328. );
  329. STDMETHOD(get_BlockUnRatedDelay)(
  330. OUT LONG *pmsecsDelayBeforeBlock
  331. );
  332. STDMETHOD(put_BlockUnRatedDelay)(
  333. IN LONG msecsDelayBeforeBlock
  334. );
  335. HRESULT // helper non interface method - returns S_FALSE if cahgned
  336. SetCurrRating(
  337. IN EnTvRat_System enSystem,
  338. IN EnTvRat_GenericLevel enRating,
  339. IN LONG lbfEnAttr
  340. );
  341. // ====================================================================
  342. // IDTFilterConfig
  343. STDMETHOD(GetSecureChannelObject)(
  344. OUT IUnknown **ppUnkDRMSecureChannel // an IDRMSecureChannel
  345. )
  346. {
  347. if(NULL == ppUnkDRMSecureChannel)
  348. return E_POINTER;
  349. #ifdef BUILD_WITH_DRM
  350. *ppUnkDRMSecureChannel = NULL;
  351. if(m_spDRMSecureChannel == NULL)
  352. return E_NOINTERFACE;
  353. return m_spDRMSecureChannel->QueryInterface(IID_IUnknown, (void**)ppUnkDRMSecureChannel);
  354. #else
  355. return E_NOINTERFACE; // not supported..
  356. #endif
  357. }
  358. // ====================================================================
  359. // CFilterBase virtual methods in base class
  360. int
  361. GetPinCount (
  362. ) ;
  363. CBasePin *
  364. GetPin (
  365. IN int
  366. ) ;
  367. STDMETHOD(JoinFilterGraph) (
  368. IFilterGraph *pGraph,
  369. LPCWSTR pName
  370. );
  371. STDMETHOD(Stop) (
  372. ) ;
  373. STDMETHOD(Pause) (
  374. ) ;
  375. STDMETHOD(Run) (
  376. REFERENCE_TIME tStart
  377. );
  378. // ====================================================================
  379. // class methods
  380. HRESULT
  381. DeliverBeginFlush (
  382. ) ;
  383. HRESULT
  384. DeliverEndFlush (
  385. ) ;
  386. HRESULT
  387. DeliverEndOfStream(
  388. );
  389. BOOL
  390. CheckDecrypterMediaType (
  391. IN PIN_DIRECTION, // caller
  392. IN const CMediaType *
  393. ) ;
  394. HRESULT
  395. Process (
  396. IN IMediaSample *
  397. ) ;
  398. HRESULT
  399. OnCompleteConnect (
  400. IN PIN_DIRECTION // caller
  401. ) ;
  402. HRESULT
  403. OnBreakConnect (
  404. IN PIN_DIRECTION // caller
  405. ) ;
  406. HRESULT
  407. UpdateAllocatorProperties (
  408. IN ALLOCATOR_PROPERTIES *
  409. ) ;
  410. HRESULT
  411. OnOutputGetMediaType (
  412. OUT CMediaType * pmt
  413. ) ;
  414. HRESULT
  415. GetRefdInputAllocator (
  416. OUT IMemAllocator **
  417. ) ;
  418. // ISpecifyPropertyPages --------------------------------------------
  419. STDMETHODIMP
  420. GetPages (
  421. CAUUID * pPages
  422. ) ;
  423. // IKSPropertySet forwarding from the input pin to the output pin (or visa versa)
  424. HRESULT
  425. IsInterfaceOnPinConnectedTo_Supported(
  426. IN PIN_DIRECTION PinDir, // either PINDIR_INPUT of PINDIR_OUTPUT
  427. IN REFIID riid
  428. );
  429. HRESULT
  430. KSPropSetFwd_Set(
  431. IN PIN_DIRECTION PinDir,
  432. IN REFGUID guidPropSet,
  433. IN DWORD dwPropID,
  434. IN LPVOID pInstanceData,
  435. IN DWORD cbInstanceData,
  436. IN LPVOID pPropData,
  437. IN DWORD cbPropData
  438. );
  439. HRESULT
  440. KSPropSetFwd_Get(
  441. IN PIN_DIRECTION PinDir,
  442. IN REFGUID guidPropSet,
  443. IN DWORD dwPropID,
  444. IN LPVOID pInstanceData,
  445. IN DWORD cbInstanceData,
  446. OUT LPVOID pPropData,
  447. IN DWORD cbPropData,
  448. OUT DWORD *pcbReturned
  449. );
  450. HRESULT
  451. KSPropSetFwd_QuerySupported(
  452. IN PIN_DIRECTION PinDir,
  453. IN REFGUID guidPropSet,
  454. IN DWORD dwPropID,
  455. OUT DWORD *pTypeSupport
  456. );
  457. // IBroadcastEvent
  458. STDMETHOD(Fire)(GUID eventID); // this comes from the Graph's events - call our own method
  459. private:
  460. // global filter CritSec (to keep multiple instances of this filter from colliding)
  461. static CCritSec *m_pCritSectGlobalFilt; // ***always*** inside the FilterLock (m_pLock)
  462. static LONG m_gFilterID; // used to distinqish instances from each other...
  463. LONG m_FilterID; // actual one for this filter
  464. // graph broadcast events
  465. HRESULT HookupGraphEventService();
  466. HRESULT UnhookGraphEventService();
  467. CComPtr<IBroadcastEvent> m_spBCastEvents;
  468. HRESULT RegisterForBroadcastEvents();
  469. HRESULT UnRegisterForBroadcastEvents();
  470. enum {kBadCookie = -1};
  471. DWORD m_dwBroadcastEventsCookie;
  472. BOOL m_fFireEvents; // set to false to avoid firing (duplicate) events
  473. // current rating
  474. CComPtr<IEvalRat> m_spEvalRat;
  475. HRESULT m_hrEvalRatCoCreateRetValue;
  476. BOOL m_fRatingsValid; // have they been set yet?
  477. EnTvRat_System m_EnSystemCurr;
  478. EnTvRat_GenericLevel m_EnLevelCurr;
  479. LONG m_lbfEnAttrCurr; // bitfield of BfEnTvRat_GenericAttributes
  480. CComPtr<ITuner> m_spTuner;
  481. //CComQIPtr<IMSVidTuner> m_spVidTuner;
  482. // block delay
  483. BOOL m_fHaltedDelivery; // halting delivery
  484. LONG m_milsecsDelayBeforeBlock; // delay time before blocking in micro-secs
  485. BOOL m_fDoingDelayBeforeBlock;
  486. BOOL m_fRunningInSlowMo; // set to true to turn of delay in starting the Ratings block
  487. REFERENCE_TIME m_refTimeToStartBlock;
  488. BOOL m_fForceNoRatBlocks; // special flag (SUPPORT_REGISTRY_KEY_TO_TURN_OFF_RATINGS) to avoid blocks
  489. BOOL m_fDataFormatHasBeenBad; // set when get bad data (toggle for ok/failure event pair)
  490. //
  491. LONG m_milsecsNoRatingsBeforeUnrated; // delay time before no ratings count as don't know
  492. REFERENCE_TIME m_refTimeFreshRating; // get ClockTime for last 'fresh' rating
  493. enum {kMax10kSpeedToCountAsSlowMo = 9001}; // abs(speed)* 10,000 to count as slow motion for delayed block
  494. REFERENCE_TIME m_refTimeLastEvent;
  495. GUID m_lastEventID;
  496. enum {kMaxMSecsBetweenEvents = 10*1000}; // max time between ratings events (in 10^-3 secs)
  497. HRESULT PossiblyUpdateBroadcastEvent();
  498. // media sample attributes
  499. CAttrSubBlock_List m_attrSB;
  500. // DRM
  501. BOOL m_3fDRMLicenseFailure; // 3 state logic (unitialized, true, and false)
  502. #ifdef BUILD_WITH_DRM
  503. CDRMLite m_cDRMLite;
  504. BYTE* m_pszKID; // only used to see if it changed and need to ReBind
  505. LONG m_cbKID;
  506. CComPtr<IDRMSecureChannel> m_spDRMSecureChannel; // authenticator...
  507. #endif
  508. HRESULT CheckIfSecureServer(IFilterGraph *pGraph=NULL); // return S_OK only if trust the server registered in the graph service provider
  509. HRESULT InitializeAsSecureClient();
  510. #ifdef FILTERS_CAN_CREATE_THEIR_OWN_TRUST
  511. HRESULT RegisterSecureServer(IFilterGraph *pGraph=NULL); // return S_OK only if trust the server registered in the graph service provider
  512. HRESULT CheckIfSecureClient(IUnknown *pUnk); // prototype for VidControl method to see if it trusts the filter
  513. #endif
  514. // Restarting the upstream delivery
  515. HRESULT OnRestartDelivery(IMediaSample *pSample);
  516. // Rate Segment
  517. enum {kMaxRateSegments = 32};
  518. enum {kSecsPurgeThreshold = 5 };
  519. CTTimestampRate<REFERENCE_TIME> m_PTSRate ;
  520. // stopping and flushing
  521. HRESULT DoEndOfStreamDuringDrop();
  522. BOOL m_fCompleteNotified;
  523. // DropQueue (circular buffer)
  524. HRESULT CreateDropQueueThread();
  525. HRESULT KillDropQueueThread();
  526. DWORD m_dwDropQueueThreadId; // Thread used to queue up/process dropped packets
  527. HANDLE m_hDropQueueThread; // Thread used to queue up/process dropped packets
  528. HANDLE m_hDropQueueThreadAliveEvent; // Signal from thread that its ready
  529. HANDLE m_hDropQueueThreadDieEvent; // Signal from thread that its ready
  530. HANDLE m_hDropQueueEmptySemaphore; // Waited on in DropQueue, inits to zero, goes when non-zero
  531. HANDLE m_hDropQueueFullSemaphore; // Waited on in Main Thread, inits to N, stops when goes to zero
  532. HANDLE m_hDropQueueAdviseTimeEvent; // Wait until some time passes
  533. DWORD m_dwDropQueueEventCookie; // cookie for the TimeEvent
  534. // and a new sample
  535. HRESULT AddSampleToDropQueue(IMediaSample *pSample);
  536. // add the top sample
  537. void AddMaxSampleToDropQueue(IMediaSample *pSample);
  538. // remove the bottom sample
  539. void DropMinSampleFromDropQueue();
  540. // return the oldest version
  541. IMediaSample * GetMinDropQueueSample();
  542. // flush all samples (when pause or stop)
  543. HRESULT FlushDropQueue();
  544. // drop samples from drop queue
  545. static void DropQueueThreadProc (CDTFilter *pcontext);
  546. HRESULT DropQueueThreadBody();
  547. enum {kMaxQueuePackets = 10}; // maximum number of packets to queue up
  548. IMediaSample * m_rgMedSampDropQueue[kMaxQueuePackets];
  549. int m_cDropQueueMin; // first sample filled
  550. int m_cDropQueueMax; // next sample we will fill
  551. // minimal stats
  552. void InitStats()
  553. {
  554. CAutoLock cLock(m_pLock);
  555. m_cPackets = 0;
  556. m_clBytesTotal = 0;
  557. m_cSampsDropped = 0;
  558. m_cSampsDroppedOverflowed = 0;
  559. m_cBlockedWhileDroppingASample = 0;
  560. m_cRestarts++;
  561. }
  562. LONG m_cPackets; // total stamples processed
  563. LONG64 m_clBytesTotal; // total number of bytes processed
  564. LONG m_cSampsDropped; // total dropped
  565. LONG m_cBlockedWhileDroppingASample; // total times paused due to DropQueue thread being full
  566. LONG m_cSampsDroppedOverflowed; // total dropped and didn't time out (should be zero)
  567. LONG m_cRestarts; // total number of reinits
  568. Timeit m_tiAuthenticate; // time in authentication methods
  569. Timeit m_tiProcess; // total ::process time
  570. Timeit m_tiProcessIn; // total ::process time minus the final 'SendSample'
  571. Timeit m_tiProcessDRM; // :process time of just the DRM code
  572. Timeit m_tiRun; // total run time
  573. Timeit m_tiStartup; // creating the license and similar startup
  574. Timeit m_tiTeardown; // closing things down
  575. } ;
  576. #endif // __EncDec__DTFilter_h