home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / BaseClasses / wxutil.h < prev   
Encoding:
C/C++ Source or Header  |  2001-10-08  |  15.3 KB  |  534 lines

  1. //------------------------------------------------------------------------------
  2. // File: WXUtil.h
  3. //
  4. // Desc: DirectShow base classes - defines helper classes and functions for
  5. //       building multimedia filters.
  6. //
  7. // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
  8. //------------------------------------------------------------------------------
  9.  
  10.  
  11. #ifndef __WXUTIL__
  12. #define __WXUTIL__
  13.  
  14. // eliminate spurious "statement has no effect" warnings.
  15. #pragma warning(disable: 4705)
  16.  
  17. // wrapper for whatever critical section we have
  18. class CCritSec {
  19.  
  20.     // make copy constructor and assignment operator inaccessible
  21.  
  22.     CCritSec(const CCritSec &refCritSec);
  23.     CCritSec &operator=(const CCritSec &refCritSec);
  24.  
  25.     CRITICAL_SECTION m_CritSec;
  26.  
  27. #ifdef DEBUG
  28. public:
  29.     DWORD   m_currentOwner;
  30.     DWORD   m_lockCount;
  31.     BOOL    m_fTrace;        // Trace this one
  32. public:
  33.     CCritSec();
  34.     ~CCritSec();
  35.     void Lock();
  36.     void Unlock();
  37. #else
  38.  
  39. public:
  40.     CCritSec() {
  41.         InitializeCriticalSection(&m_CritSec);
  42.     };
  43.  
  44.     ~CCritSec() {
  45.         DeleteCriticalSection(&m_CritSec);
  46.     };
  47.  
  48.     void Lock() {
  49.         EnterCriticalSection(&m_CritSec);
  50.     };
  51.  
  52.     void Unlock() {
  53.         LeaveCriticalSection(&m_CritSec);
  54.     };
  55. #endif
  56. };
  57.  
  58. //
  59. // To make deadlocks easier to track it is useful to insert in the
  60. // code an assertion that says whether we own a critical section or
  61. // not.  We make the routines that do the checking globals to avoid
  62. // having different numbers of member functions in the debug and
  63. // retail class implementations of CCritSec.  In addition we provide
  64. // a routine that allows usage of specific critical sections to be
  65. // traced.  This is NOT on by default - there are far too many.
  66. //
  67.  
  68. #ifdef DEBUG
  69.     BOOL WINAPI CritCheckIn(CCritSec * pcCrit);
  70.     BOOL WINAPI CritCheckIn(const CCritSec * pcCrit);
  71.     BOOL WINAPI CritCheckOut(CCritSec * pcCrit);
  72.     BOOL WINAPI CritCheckOut(const CCritSec * pcCrit);
  73.     void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace);
  74. #else
  75.     #define CritCheckIn(x) TRUE
  76.     #define CritCheckOut(x) TRUE
  77.     #define DbgLockTrace(pc, fT)
  78. #endif
  79.  
  80.  
  81. // locks a critical section, and unlocks it automatically
  82. // when the lock goes out of scope
  83. class CAutoLock {
  84.  
  85.     // make copy constructor and assignment operator inaccessible
  86.  
  87.     CAutoLock(const CAutoLock &refAutoLock);
  88.     CAutoLock &operator=(const CAutoLock &refAutoLock);
  89.  
  90. protected:
  91.     CCritSec * m_pLock;
  92.  
  93. public:
  94.     CAutoLock(CCritSec * plock)
  95.     {
  96.         m_pLock = plock;
  97.         m_pLock->Lock();
  98.     };
  99.  
  100.     ~CAutoLock() {
  101.         m_pLock->Unlock();
  102.     };
  103. };
  104.  
  105.  
  106.  
  107. // wrapper for event objects
  108. class CAMEvent
  109. {
  110.  
  111.     // make copy constructor and assignment operator inaccessible
  112.  
  113.     CAMEvent(const CAMEvent &refEvent);
  114.     CAMEvent &operator=(const CAMEvent &refEvent);
  115.  
  116. protected:
  117.     HANDLE m_hEvent;
  118. public:
  119.     CAMEvent(BOOL fManualReset = FALSE);
  120.     ~CAMEvent();
  121.  
  122.     // Cast to HANDLE - we don't support this as an lvalue
  123.     operator HANDLE () const { return m_hEvent; };
  124.  
  125.     void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));};
  126.     BOOL Wait(DWORD dwTimeout = INFINITE) {
  127.     return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0);
  128.     };
  129.     void Reset() { ResetEvent(m_hEvent); };
  130.     BOOL Check() { return Wait(0); };
  131. };
  132.  
  133.  
  134. // wrapper for event objects that do message processing
  135. // This adds ONE method to the CAMEvent object to allow sent
  136. // messages to be processed while waiting
  137.  
  138. class CAMMsgEvent : public CAMEvent
  139. {
  140.  
  141. public:
  142.  
  143.     // Allow SEND messages to be processed while waiting
  144.     BOOL WaitMsg(DWORD dwTimeout = INFINITE);
  145. };
  146.  
  147. // old name supported for the time being
  148. #define CTimeoutEvent CAMEvent
  149.  
  150. // support for a worker thread
  151.  
  152. // simple thread class supports creation of worker thread, synchronization
  153. // and communication. Can be derived to simplify parameter passing
  154. class AM_NOVTABLE CAMThread {
  155.  
  156.     // make copy constructor and assignment operator inaccessible
  157.  
  158.     CAMThread(const CAMThread &refThread);
  159.     CAMThread &operator=(const CAMThread &refThread);
  160.  
  161.     CAMEvent m_EventSend;
  162.     CAMEvent m_EventComplete;
  163.  
  164.     DWORD m_dwParam;
  165.     DWORD m_dwReturnVal;
  166.  
  167. protected:
  168.     HANDLE m_hThread;
  169.  
  170.     // thread will run this function on startup
  171.     // must be supplied by derived class
  172.     virtual DWORD ThreadProc() = 0;
  173.  
  174. public:
  175.     CAMThread();
  176.     virtual ~CAMThread();
  177.  
  178.     CCritSec m_AccessLock;  // locks access by client threads
  179.     CCritSec m_WorkerLock;  // locks access to shared objects
  180.  
  181.     // thread initially runs this. param is actually 'this'. function
  182.     // just gets this and calls ThreadProc
  183.     static DWORD WINAPI InitialThreadProc(LPVOID pv);
  184.  
  185.     // start thread running  - error if already running
  186.     BOOL Create();
  187.  
  188.     // signal the thread, and block for a response
  189.     //
  190.     DWORD CallWorker(DWORD);
  191.  
  192.     // accessor thread calls this when done with thread (having told thread
  193.     // to exit)
  194.     void Close() {
  195.         HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0);
  196.         if (hThread) {
  197.             WaitForSingleObject(hThread, INFINITE);
  198.             CloseHandle(hThread);
  199.         }
  200.     };
  201.  
  202.     // ThreadExists
  203.     // Return TRUE if the thread exists. FALSE otherwise
  204.     BOOL ThreadExists(void) const
  205.     {
  206.         if (m_hThread == 0) {
  207.             return FALSE;
  208.         } else {
  209.             return TRUE;
  210.         }
  211.     }
  212.  
  213.     // wait for the next request
  214.     DWORD GetRequest();
  215.  
  216.     // is there a request?
  217.     BOOL CheckRequest(DWORD * pParam);
  218.  
  219.     // reply to the request
  220.     void Reply(DWORD);
  221.  
  222.     // If you want to do WaitForMultipleObjects you'll need to include
  223.     // this handle in your wait list or you won't be responsive
  224.     HANDLE GetRequestHandle() const { return m_EventSend; };
  225.  
  226.     // Find out what the request was
  227.     DWORD GetRequestParam() const { return m_dwParam; };
  228.  
  229.     // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if
  230.     // available. S_FALSE means it's not available.
  231.     static HRESULT CoInitializeHelper();
  232. };
  233.  
  234.  
  235. // CQueue
  236. //
  237. // Implements a simple Queue ADT.  The queue contains a finite number of
  238. // objects, access to which is controlled by a semaphore.  The semaphore
  239. // is created with an initial count (N).  Each time an object is added
  240. // a call to WaitForSingleObject is made on the semaphore's handle.  When
  241. // this function returns a slot has been reserved in the queue for the new
  242. // object.  If no slots are available the function blocks until one becomes
  243. // available.  Each time an object is removed from the queue ReleaseSemaphore
  244. // is called on the semaphore's handle, thus freeing a slot in the queue.
  245. // If no objects are present in the queue the function blocks until an
  246. // object has been added.
  247.  
  248. #define DEFAULT_QUEUESIZE   2
  249.  
  250. template <class T> class CQueue {
  251. private:
  252.     HANDLE          hSemPut;        // Semaphore controlling queue "putting"
  253.     HANDLE          hSemGet;        // Semaphore controlling queue "getting"
  254.     CRITICAL_SECTION CritSect;      // Thread seriallization
  255.     int             nMax;           // Max objects allowed in queue
  256.     int             iNextPut;       // Array index of next "PutMsg"
  257.     int             iNextGet;       // Array index of next "GetMsg"
  258.     T              *QueueObjects;   // Array of objects (ptr's to void)
  259.  
  260.     void Initialize(int n) {
  261.         iNextPut = iNextGet = 0;
  262.         nMax = n;
  263.         InitializeCriticalSection(&CritSect);
  264.         hSemPut = CreateSemaphore(NULL, n, n, NULL);
  265.         hSemGet = CreateSemaphore(NULL, 0, n, NULL);
  266.         QueueObjects = new T[n];
  267.     }
  268.  
  269.  
  270. public:
  271.     CQueue(int n) {
  272.         Initialize(n);
  273.     }
  274.  
  275.     CQueue() {
  276.         Initialize(DEFAULT_QUEUESIZE);
  277.     }
  278.  
  279.     ~CQueue() {
  280.         delete [] QueueObjects;
  281.         DeleteCriticalSection(&CritSect);
  282.         CloseHandle(hSemPut);
  283.         CloseHandle(hSemGet);
  284.     }
  285.  
  286.     T GetQueueObject() {
  287.         int iSlot;
  288.         T Object;
  289.         LONG lPrevious;
  290.  
  291.         // Wait for someone to put something on our queue, returns straight
  292.         // away is there is already an object on the queue.
  293.         //
  294.         WaitForSingleObject(hSemGet, INFINITE);
  295.  
  296.         EnterCriticalSection(&CritSect);
  297.         iSlot = iNextGet++ % nMax;
  298.         Object = QueueObjects[iSlot];
  299.         LeaveCriticalSection(&CritSect);
  300.  
  301.         // Release anyone waiting to put an object onto our queue as there
  302.         // is now space available in the queue.
  303.         //
  304.         ReleaseSemaphore(hSemPut, 1L, &lPrevious);
  305.         return Object;
  306.     }
  307.  
  308.     void PutQueueObject(T Object) {
  309.         int iSlot;
  310.         LONG lPrevious;
  311.  
  312.         // Wait for someone to get something from our queue, returns straight
  313.         // away is there is already an empty slot on the queue.
  314.         //
  315.         WaitForSingleObject(hSemPut, INFINITE);
  316.  
  317.         EnterCriticalSection(&CritSect);
  318.         iSlot = iNextPut++ % nMax;
  319.         QueueObjects[iSlot] = Object;
  320.         LeaveCriticalSection(&CritSect);
  321.  
  322.         // Release anyone waiting to remove an object from our queue as there
  323.         // is now an object available to be removed.
  324.         //
  325.         ReleaseSemaphore(hSemGet, 1L, &lPrevious);
  326.     }
  327. };
  328.  
  329. // miscellaneous string conversion functions
  330. // NOTE: as we need to use the same binaries on Win95 as on NT this code should
  331. // be compiled WITHOUT unicode being defined.  Otherwise we will not pick up
  332. // these internal routines and the binary will not run on Win95.
  333.  
  334. int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...);
  335.  
  336. LPWSTR
  337. WINAPI
  338. lstrcpyWInternal(
  339.     LPWSTR lpString1,
  340.     LPCWSTR lpString2
  341.     );
  342. LPWSTR
  343. WINAPI
  344. lstrcpynWInternal(
  345.     LPWSTR lpString1,
  346.     LPCWSTR lpString2,
  347.     int     iMaxLength
  348.     );
  349. int
  350. WINAPI
  351. lstrcmpWInternal(
  352.     LPCWSTR lpString1,
  353.     LPCWSTR lpString2
  354.     );
  355. int
  356. WINAPI
  357. lstrcmpiWInternal(
  358.     LPCWSTR lpString1,
  359.     LPCWSTR lpString2
  360.     );
  361. int
  362. WINAPI
  363. lstrlenWInternal(
  364.     LPCWSTR lpString
  365.     );
  366.  
  367. #ifndef UNICODE
  368. #define wsprintfW wsprintfWInternal
  369. #define lstrcpyW lstrcpyWInternal
  370. #define lstrcpynW lstrcpynWInternal
  371. #define lstrcmpW lstrcmpWInternal
  372. #define lstrcmpiW lstrcmpiWInternal
  373. #define lstrlenW lstrlenWInternal
  374. #endif
  375.  
  376. extern "C"
  377. void * __stdcall memmoveInternal(void *, const void *, size_t);
  378.  
  379. inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt)
  380. {
  381. #ifdef _X86_
  382.     void *pRet = NULL;
  383.  
  384.     _asm {
  385.         cld                 // make sure we get the direction right
  386.         mov     ecx, cnt    // num of bytes to scan
  387.         mov     edi, buf    // pointer byte stream
  388.         mov     eax, chr    // byte to scan for
  389.         repne   scasb       // look for the byte in the byte stream
  390.         jnz     exit_memchr // Z flag set if byte found
  391.         dec     edi         // scasb always increments edi even when it
  392.                             // finds the required byte
  393.         mov     pRet, edi
  394. exit_memchr:
  395.     }
  396.     return pRet;
  397.  
  398. #else
  399.     while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
  400.         buf = (unsigned char *)buf + 1;
  401.         cnt--;
  402.     }
  403.  
  404.     return(cnt ? (void *)buf : NULL);
  405. #endif
  406. }
  407.  
  408. void WINAPI IntToWstr(int i, LPWSTR wstr);
  409.  
  410. #define WstrToInt(sz) _wtoi(sz)
  411. #define atoiW(sz) _wtoi(sz)
  412. #define atoiA(sz) atoi(sz)
  413.  
  414. // These are available to help managing bitmap VIDEOINFOHEADER media structures
  415.  
  416. extern const DWORD bits555[3];
  417. extern const DWORD bits565[3];
  418. extern const DWORD bits888[3];
  419.  
  420. // These help convert between VIDEOINFOHEADER and BITMAPINFO structures
  421.  
  422. STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader);
  423. STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader);
  424. STDAPI_(WORD) GetBitCount(const GUID *pSubtype);
  425.  
  426. // strmbase.lib implements this for compatibility with people who
  427. // managed to link to this directly.  we don't want to advertise it.
  428. //
  429. // STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype);
  430.  
  431. STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype);
  432. STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype);
  433.  
  434. #ifdef UNICODE
  435. #define GetSubtypeName GetSubtypeNameW
  436. #else
  437. #define GetSubtypeName GetSubtypeNameA
  438. #endif
  439.  
  440. STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader);
  441. STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader);
  442. STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo);
  443. STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo);
  444.  
  445.  
  446. // Compares two interfaces and returns TRUE if they are on the same object
  447. BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond);
  448.  
  449. // This is for comparing pins
  450. #define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2)
  451.  
  452.  
  453. // Arithmetic helper functions
  454.  
  455. // Compute (a * b + rnd) / c
  456. LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd);
  457. LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd);
  458.  
  459.  
  460. // Avoids us dyna-linking to SysAllocString to copy BSTR strings
  461. STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc);
  462. STDAPI FreeBSTR(BSTR* pstr);
  463.  
  464. // Return a wide string - allocating memory for it
  465. // Returns:
  466. //    S_OK          - no error
  467. //    E_POINTER     - ppszReturn == NULL
  468. //    E_OUTOFMEMORY - can't allocate memory for returned string
  469. STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn);
  470.  
  471. // Special wait for objects owning windows
  472. DWORD WINAPI WaitDispatchingMessages(
  473.     HANDLE hObject,
  474.     DWORD dwWait,
  475.     HWND hwnd = NULL,
  476.     UINT uMsg = 0,
  477.     HANDLE hEvent = NULL);
  478.  
  479. // HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in
  480. // our use of HRESULT_FROM_WIN32, it typically means a function failed
  481. // to call SetLastError(), and we still want a failure code.
  482. //
  483. #define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x))
  484.  
  485. // call GetLastError and return an HRESULT value that will fail the
  486. // SUCCEEDED() macro.
  487. HRESULT AmGetLastErrorToHResult(void);
  488.  
  489. // duplicate of ATL's CComPtr to avoid linker conflicts.
  490.  
  491. IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  492.  
  493. template <class T>
  494. class QzCComPtr
  495. {
  496. public:
  497.     typedef T _PtrClass;
  498.     QzCComPtr() {p=NULL;}
  499.     QzCComPtr(T* lp)
  500.     {
  501.         if ((p = lp) != NULL)
  502.             p->AddRef();
  503.     }
  504.     QzCComPtr(const QzCComPtr<T>& lp)
  505.     {
  506.         if ((p = lp.p) != NULL)
  507.             p->AddRef();
  508.     }
  509.     ~QzCComPtr() {if (p) p->Release();}
  510.     void Release() {if (p) p->Release(); p=NULL;}
  511.     operator T*() {return (T*)p;}
  512.     T& operator*() {ASSERT(p!=NULL); return *p; }
  513.     //The assert on operator& usually indicates a bug.  If this is really
  514.     //what is needed, however, take the address of the p member explicitly.
  515.     T** operator&() { ASSERT(p==NULL); return &p; }
  516.     T* operator->() { ASSERT(p!=NULL); return p; }
  517.     T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);}
  518.     T* operator=(const QzCComPtr<T>& lp)
  519.     {
  520.         return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p);
  521.     }
  522. #if _MSC_VER>1020
  523.     bool operator!(){return (p == NULL);}
  524. #else
  525.     BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  526. #endif
  527.     T* p;
  528. };
  529.  
  530. MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );
  531. bool TimeKillSynchronousFlagAvailable( void );
  532.  
  533. #endif /* __WXUTIL__ */
  534.