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

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
DTFilter.h
Abstract:
This module contains the Encrypter/Tagger filter declarations
Author:
John Bradstreet (johnbrad)
Revision History:
07-Mar-2002 created
--*/
#ifndef __EncDec__DTFilter_h
#define __EncDec__DTFilter_h
#include <tuner.h> // needed for IBroadcastEvent
#include <ks.h>
#include <ksmedia.h>
#include <bdatypes.h>
#include <bdamedia.h> // EVENTID_TuningChanged, XDS_RatingsPacket
#include "DTFilter_res.h"
#include "PackTvRat.h" // packed TvRating definitions
#include "MediaSampleAttr.h" // from the IDL file
//#include "MediaAttrib.h" // IMediaSampleAttrGet/Set definitions, CAttributedMediaSample
#include "..\Attrib\MediaAttrib.h" // IMediaSampleAttrGet/Set definitions, CAttributedMediaSample
#include "AttrBlock.h" // attributed block definitions
#include "DRMEncDec.h" // drm encryption/decryption definitions...
#include "DRMSecure.h" // IDRMSecureChannel
#if 1
#include "rateseg.h" // before integration - I stole the code
#else
#include "dvrutil.h" // when we eventually integrate
#endif
#define DT_FILTER_NAME "Decrypt/DeTag"
#define DT_INPIN_NAME "In(Enc/Tag)"
#define DT_OUTPIN_NAME "Out"
extern AMOVIESETUP_FILTER g_sudDTFilter;
// forward declarations
class CDTFilter;
class CDTFilterInput;
class CDTFilterOutput;
// --------------------------------------------------------------------
// class CDTFilterInput
// --------------------------------------------------------------------
class CDTFilterInput :
public IKsPropertySet,
public CBaseInputPin
{
private:
CDTFilter * m_pHostDTFilter ;
CCritSec m_StreamingLock;
DECLARE_IUNKNOWN; // needed when have IKsPropertySet
public :
CDTFilterInput (
IN TCHAR * pszPinName,
IN CDTFilter * pDTFilter,
IN CCritSec * pFilterLock, // NULL or a passed in lock
OUT HRESULT * phr
) ;
~CDTFilterInput ();;
STDMETHODIMP
NonDelegatingQueryInterface (
IN REFIID riid,
OUT void ** ppv
) ;
// --------------------------------------------------------------------
// CBasePin methods
HRESULT
CheckMediaType (
IN const CMediaType *
) ;
HRESULT
CompleteConnect (
IN IPin * pIPin
) ;
HRESULT
BreakConnect (
) ;
// --------------------------------------------------------------------
// CBaseInputPin methods
STDMETHODIMP
Receive (
IN IMediaSample * pIMediaSample
) ;
STDMETHODIMP
BeginFlush (
) ;
STDMETHODIMP
EndFlush (
) ;
STDMETHODIMP
EndOfStream (
);
// --------------------------------------------------------------------
// IKSPropertySet methods (Forward all calls to the output pin)
STDMETHODIMP
Set(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
IN LPVOID pPropData,
IN DWORD cbPropData
);
STDMETHODIMP
Get(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
OUT LPVOID pPropData,
IN DWORD cbPropData,
OUT DWORD *pcbReturned
);
STDMETHODIMP
QuerySupported(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
OUT DWORD *pTypeSupport
);
// --------------------------------------------------------------------
// class methods
HRESULT
StreamingLock (
);
HRESULT
StreamingUnlock (
);
HRESULT
SetAllocatorProperties (
IN ALLOCATOR_PROPERTIES * ppropInputRequest
) ;
HRESULT
GetRefdConnectionAllocator (
OUT IMemAllocator ** ppAlloc
) ;
} ;
// --------------------------------------------------------------------
// class CDTFilterOutput
// --------------------------------------------------------------------
class CDTFilterOutput :
public CBaseOutputPin
{
CDTFilter * m_pHostDTFilter ;
// void FilterLock_ () { m_pLock -> Lock () ; }
// void FilterUnlock_ () { m_pLock -> Unlock () ; }
public :
CDTFilterOutput (
IN TCHAR * pszPinName,
IN CDTFilter * pDTFilter,
IN CCritSec * pFilterLock,
OUT HRESULT * phr
) ;
~CDTFilterOutput (
);
DECLARE_IUNKNOWN ;
HRESULT
SendSample (
IN IMediaSample * pIMS
) ;
STDMETHODIMP
NonDelegatingQueryInterface (
IN REFIID riid,
OUT void ** ppv
) ;
// --------------------------------------------------------------------
// CBasePin methods
HRESULT
DecideBufferSize (
IN IMemAllocator * pAlloc,
IN ALLOCATOR_PROPERTIES * ppropInputRequest
) ;
HRESULT
GetMediaType (
IN int iPosition,
OUT CMediaType * pmt
) ;
HRESULT
CheckMediaType (
IN const CMediaType *
) ;
HRESULT
CompleteConnect (
IN IPin * pIPin
) ;
HRESULT
BreakConnect (
) ;
HRESULT
DecideAllocator (
IN IMemInputPin * pPin,
IN IMemAllocator ** ppAlloc
) ;
STDMETHOD(Notify) (
IBaseFilter *pSender,
Quality q
);
// Class methods
/* HRESULT
SendLock (
);
HRESULT
SendUnlock (
);
*/
// IKSPropertySet forwarding methods....
HRESULT
IsInterfaceOnPinConnectedTo_Supported(
IN REFIID riid
);
HRESULT
KSPropSetFwd_Set(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
IN LPVOID pPropData,
IN DWORD cbPropData
);
HRESULT
KSPropSetFwd_Get(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
OUT LPVOID pPropData,
IN DWORD cbPropData,
OUT DWORD *pcbReturned
);
HRESULT
KSPropSetFwd_QuerySupported(
IN REFGUID guidPropSet,
IN DWORD dwPropID,
OUT DWORD *pTypeSupport
);
} ;
// --------------------------------------------------------------------
// class CDTFilter
// --------------------------------------------------------------------
class CDTFilter :
public CBaseFilter, // dshow base class
public ISpecifyPropertyPages,
public IDTFilter,
public IDTFilterConfig,
public IBroadcastEvent
{
friend CDTFilterInput; // so input pin can call FlushDropQueue on BeginFlush()
CDTFilterInput * m_pInputPin ;
CDTFilterOutput * m_pOutputPin ;
CCritSec m_CritSecDropQueue;
CCritSec m_CritSecAdviseTime;
BOOL
CompareConnectionMediaType_ (
IN const AM_MEDIA_TYPE * pmt,
IN CBasePin * pPin
) ;
BOOL
CheckInputMediaType_ (
IN const AM_MEDIA_TYPE * pmt
) ;
BOOL
CheckOutputMediaType_ (
IN const AM_MEDIA_TYPE * pmt
) ;
public :
CDTFilter (
IN TCHAR * pszFilterName,
IN IUnknown * punkControlling,
IN REFCLSID rCLSID,
OUT HRESULT * phr
) ;
~CDTFilter () ;
static
CUnknown *
CreateInstance (
IN IUnknown * punk,
OUT HRESULT * phr
) ;
static void CALLBACK // used to create a global crit sec
InitInstance (
IN BOOL bLoading,
IN const CLSID *rclsid
);
STDMETHODIMP
NonDelegatingQueryInterface (
IN REFIID riid,
OUT void ** ppv
) ;
DECLARE_IUNKNOWN ;
// =====================================================================
// Worker Methods
// tell folk we got something...
HRESULT FireBroadcastEvent(IN const GUID &eventID);
HRESULT ProposeNewOutputMediaType (
IN CMediaType * pmt,
OUT CMediaType * pmtOut
);
HRESULT BindDRMLicense(
IN LONG cbKID,
IN BYTE * pbKID
);
HRESULT UnBindDRMLicenses(
);
// =====================================================================
// IDTFilter
STDMETHODIMP
get_EvalRatObjOK(
OUT HRESULT *pHrCoCreateRetVal
);
STDMETHOD(GetCurrRating)(
OUT EnTvRat_System *pEnSystem,
OUT EnTvRat_GenericLevel *pEnRating,
OUT LONG *plbfEnAttr //BfEnTvRat_GenericAttributes
);
STDMETHOD(get_BlockedRatingAttributes)(
IN EnTvRat_System enSystem,
IN EnTvRat_GenericLevel enLevel,
OUT LONG *plbfEnAttr // BfEnTvRat_GenericAttributes
);
STDMETHOD(put_BlockedRatingAttributes)(
IN EnTvRat_System enSystem,
IN EnTvRat_GenericLevel enLevel,
IN LONG lbfEnAttrs // BfEnTvRat_GenericAttributes
);
STDMETHOD(get_BlockUnRated)(
OUT BOOL *pmfBlockUnRatedShows
);
STDMETHOD(put_BlockUnRated)(
IN BOOL fBlockUnRatedShows
);
STDMETHOD(get_BlockUnRatedDelay)(
OUT LONG *pmsecsDelayBeforeBlock
);
STDMETHOD(put_BlockUnRatedDelay)(
IN LONG msecsDelayBeforeBlock
);
HRESULT // helper non interface method - returns S_FALSE if cahgned
SetCurrRating(
IN EnTvRat_System enSystem,
IN EnTvRat_GenericLevel enRating,
IN LONG lbfEnAttr
);
// ====================================================================
// IDTFilterConfig
STDMETHOD(GetSecureChannelObject)(
OUT IUnknown **ppUnkDRMSecureChannel // an IDRMSecureChannel
)
{
if(NULL == ppUnkDRMSecureChannel)
return E_POINTER;
#ifdef BUILD_WITH_DRM
*ppUnkDRMSecureChannel = NULL;
if(m_spDRMSecureChannel == NULL)
return E_NOINTERFACE;
return m_spDRMSecureChannel->QueryInterface(IID_IUnknown, (void**)ppUnkDRMSecureChannel);
#else
return E_NOINTERFACE; // not supported..
#endif
}
// ====================================================================
// CFilterBase virtual methods in base class
int
GetPinCount (
) ;
CBasePin *
GetPin (
IN int
) ;
STDMETHOD(JoinFilterGraph) (
IFilterGraph *pGraph,
LPCWSTR pName
);
STDMETHOD(Stop) (
) ;
STDMETHOD(Pause) (
) ;
STDMETHOD(Run) (
REFERENCE_TIME tStart
);
// ====================================================================
// class methods
HRESULT
DeliverBeginFlush (
) ;
HRESULT
DeliverEndFlush (
) ;
HRESULT
DeliverEndOfStream(
);
BOOL
CheckDecrypterMediaType (
IN PIN_DIRECTION, // caller
IN const CMediaType *
) ;
HRESULT
Process (
IN IMediaSample *
) ;
HRESULT
OnCompleteConnect (
IN PIN_DIRECTION // caller
) ;
HRESULT
OnBreakConnect (
IN PIN_DIRECTION // caller
) ;
HRESULT
UpdateAllocatorProperties (
IN ALLOCATOR_PROPERTIES *
) ;
HRESULT
OnOutputGetMediaType (
OUT CMediaType * pmt
) ;
HRESULT
GetRefdInputAllocator (
OUT IMemAllocator **
) ;
// ISpecifyPropertyPages --------------------------------------------
STDMETHODIMP
GetPages (
CAUUID * pPages
) ;
// IKSPropertySet forwarding from the input pin to the output pin (or visa versa)
HRESULT
IsInterfaceOnPinConnectedTo_Supported(
IN PIN_DIRECTION PinDir, // either PINDIR_INPUT of PINDIR_OUTPUT
IN REFIID riid
);
HRESULT
KSPropSetFwd_Set(
IN PIN_DIRECTION PinDir,
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
IN LPVOID pPropData,
IN DWORD cbPropData
);
HRESULT
KSPropSetFwd_Get(
IN PIN_DIRECTION PinDir,
IN REFGUID guidPropSet,
IN DWORD dwPropID,
IN LPVOID pInstanceData,
IN DWORD cbInstanceData,
OUT LPVOID pPropData,
IN DWORD cbPropData,
OUT DWORD *pcbReturned
);
HRESULT
KSPropSetFwd_QuerySupported(
IN PIN_DIRECTION PinDir,
IN REFGUID guidPropSet,
IN DWORD dwPropID,
OUT DWORD *pTypeSupport
);
// IBroadcastEvent
STDMETHOD(Fire)(GUID eventID); // this comes from the Graph's events - call our own method
private:
// global filter CritSec (to keep multiple instances of this filter from colliding)
static CCritSec *m_pCritSectGlobalFilt; // ***always*** inside the FilterLock (m_pLock)
static LONG m_gFilterID; // used to distinqish instances from each other...
LONG m_FilterID; // actual one for this filter
// graph broadcast events
HRESULT HookupGraphEventService();
HRESULT UnhookGraphEventService();
CComPtr<IBroadcastEvent> m_spBCastEvents;
HRESULT RegisterForBroadcastEvents();
HRESULT UnRegisterForBroadcastEvents();
enum {kBadCookie = -1};
DWORD m_dwBroadcastEventsCookie;
BOOL m_fFireEvents; // set to false to avoid firing (duplicate) events
// current rating
CComPtr<IEvalRat> m_spEvalRat;
HRESULT m_hrEvalRatCoCreateRetValue;
BOOL m_fRatingsValid; // have they been set yet?
EnTvRat_System m_EnSystemCurr;
EnTvRat_GenericLevel m_EnLevelCurr;
LONG m_lbfEnAttrCurr; // bitfield of BfEnTvRat_GenericAttributes
CComPtr<ITuner> m_spTuner;
//CComQIPtr<IMSVidTuner> m_spVidTuner;
// block delay
BOOL m_fHaltedDelivery; // halting delivery
LONG m_milsecsDelayBeforeBlock; // delay time before blocking in micro-secs
BOOL m_fDoingDelayBeforeBlock;
BOOL m_fRunningInSlowMo; // set to true to turn of delay in starting the Ratings block
REFERENCE_TIME m_refTimeToStartBlock;
BOOL m_fForceNoRatBlocks; // special flag (SUPPORT_REGISTRY_KEY_TO_TURN_OFF_RATINGS) to avoid blocks
BOOL m_fDataFormatHasBeenBad; // set when get bad data (toggle for ok/failure event pair)
//
LONG m_milsecsNoRatingsBeforeUnrated; // delay time before no ratings count as don't know
REFERENCE_TIME m_refTimeFreshRating; // get ClockTime for last 'fresh' rating
enum {kMax10kSpeedToCountAsSlowMo = 9001}; // abs(speed)* 10,000 to count as slow motion for delayed block
REFERENCE_TIME m_refTimeLastEvent;
GUID m_lastEventID;
enum {kMaxMSecsBetweenEvents = 10*1000}; // max time between ratings events (in 10^-3 secs)
HRESULT PossiblyUpdateBroadcastEvent();
// media sample attributes
CAttrSubBlock_List m_attrSB;
// DRM
BOOL m_3fDRMLicenseFailure; // 3 state logic (unitialized, true, and false)
#ifdef BUILD_WITH_DRM
CDRMLite m_cDRMLite;
BYTE* m_pszKID; // only used to see if it changed and need to ReBind
LONG m_cbKID;
CComPtr<IDRMSecureChannel> m_spDRMSecureChannel; // authenticator...
#endif
HRESULT CheckIfSecureServer(IFilterGraph *pGraph=NULL); // return S_OK only if trust the server registered in the graph service provider
HRESULT InitializeAsSecureClient();
#ifdef FILTERS_CAN_CREATE_THEIR_OWN_TRUST
HRESULT RegisterSecureServer(IFilterGraph *pGraph=NULL); // return S_OK only if trust the server registered in the graph service provider
HRESULT CheckIfSecureClient(IUnknown *pUnk); // prototype for VidControl method to see if it trusts the filter
#endif
// Restarting the upstream delivery
HRESULT OnRestartDelivery(IMediaSample *pSample);
// Rate Segment
enum {kMaxRateSegments = 32};
enum {kSecsPurgeThreshold = 5 };
CTTimestampRate<REFERENCE_TIME> m_PTSRate ;
// stopping and flushing
HRESULT DoEndOfStreamDuringDrop();
BOOL m_fCompleteNotified;
// DropQueue (circular buffer)
HRESULT CreateDropQueueThread();
HRESULT KillDropQueueThread();
DWORD m_dwDropQueueThreadId; // Thread used to queue up/process dropped packets
HANDLE m_hDropQueueThread; // Thread used to queue up/process dropped packets
HANDLE m_hDropQueueThreadAliveEvent; // Signal from thread that its ready
HANDLE m_hDropQueueThreadDieEvent; // Signal from thread that its ready
HANDLE m_hDropQueueEmptySemaphore; // Waited on in DropQueue, inits to zero, goes when non-zero
HANDLE m_hDropQueueFullSemaphore; // Waited on in Main Thread, inits to N, stops when goes to zero
HANDLE m_hDropQueueAdviseTimeEvent; // Wait until some time passes
DWORD m_dwDropQueueEventCookie; // cookie for the TimeEvent
// and a new sample
HRESULT AddSampleToDropQueue(IMediaSample *pSample);
// add the top sample
void AddMaxSampleToDropQueue(IMediaSample *pSample);
// remove the bottom sample
void DropMinSampleFromDropQueue();
// return the oldest version
IMediaSample * GetMinDropQueueSample();
// flush all samples (when pause or stop)
HRESULT FlushDropQueue();
// drop samples from drop queue
static void DropQueueThreadProc (CDTFilter *pcontext);
HRESULT DropQueueThreadBody();
enum {kMaxQueuePackets = 10}; // maximum number of packets to queue up
IMediaSample * m_rgMedSampDropQueue[kMaxQueuePackets];
int m_cDropQueueMin; // first sample filled
int m_cDropQueueMax; // next sample we will fill
// minimal stats
void InitStats()
{
CAutoLock cLock(m_pLock);
m_cPackets = 0;
m_clBytesTotal = 0;
m_cSampsDropped = 0;
m_cSampsDroppedOverflowed = 0;
m_cBlockedWhileDroppingASample = 0;
m_cRestarts++;
}
LONG m_cPackets; // total stamples processed
LONG64 m_clBytesTotal; // total number of bytes processed
LONG m_cSampsDropped; // total dropped
LONG m_cBlockedWhileDroppingASample; // total times paused due to DropQueue thread being full
LONG m_cSampsDroppedOverflowed; // total dropped and didn't time out (should be zero)
LONG m_cRestarts; // total number of reinits
Timeit m_tiAuthenticate; // time in authentication methods
Timeit m_tiProcess; // total ::process time
Timeit m_tiProcessIn; // total ::process time minus the final 'SendSample'
Timeit m_tiProcessDRM; // :process time of just the DRM code
Timeit m_tiRun; // total run time
Timeit m_tiStartup; // creating the license and similar startup
Timeit m_tiTeardown; // closing things down
} ;
#endif // __EncDec__DTFilter_h