The DejaVU Framework -- hush 3.1

include: hush-src-multi-BaseClasses-wxutil.h /home/ae/media


- [up] [top] - index make include source logic grammar scripts html configure mx slides talks scenes reports projects
<body bgcolor="#FFFFFF" text="#000000">

//------------------------------------------------------------------------------
// File: WXUtil.h
//
// Desc: DirectShow base classes - defines helper classes and functions for
//       building multimedia filters.
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------

ifndef __WXUTIL__
define __WXUTIL__

// eliminate spurious "statement has no effect" warnings.
#pragma warning(disable: 4705)

// wrapper for whatever critical section we have
<h4 align=right text=red> CCritSec</h4><hr>
  class CCritSec {

    // make copy constructor and assignment operator inaccessible

    CCritSec(const CCritSec &refCritSec);
    CCritSec &operator=(const CCritSec &refCritSec);

    CRITICAL_SECTION m_CritSec;

ifdef DEBUG
public:
    DWORD   m_currentOwner;
    DWORD   m_lockCount;
    BOOL    m_fTrace;        // Trace this one
public:
    CCritSec();
    ~CCritSec();
    void Lock();
    void Unlock();
else

public:
    CCritSec() {
        InitializeCriticalSection(&m_CritSec);
    };
<hr>


    ~CCritSec() {
        DeleteCriticalSection(&m_CritSec);
    };
<hr>


    void Lock() {
        EnterCriticalSection(&m_CritSec);
    };
<hr>


    void Unlock() {
        LeaveCriticalSection(&m_CritSec);
    };
<hr>

endif
};
<hr>


//
// To make deadlocks easier to track it is useful to insert in the
// code an assertion that says whether we own a critical section or
// not.  We make the routines that do the checking globals to avoid
// having different numbers of member functions in the debug and
// retail class implementations of CCritSec.  In addition we provide
// a routine that allows usage of specific critical sections to be
// traced.  This is NOT on by default - there are far too many.
//

ifdef DEBUG
    BOOL WINAPI CritCheckIn(CCritSec * pcCrit);
    BOOL WINAPI CritCheckIn(const CCritSec * pcCrit);
    BOOL WINAPI CritCheckOut(CCritSec * pcCrit);
    BOOL WINAPI CritCheckOut(const CCritSec * pcCrit);
    void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace);
else
    #define CritCheckIn(x) TRUE
    #define CritCheckOut(x) TRUE
    #define DbgLockTrace(pc, fT)
endif

// locks a critical section, and unlocks it automatically
// when the lock goes out of scope
<hr>

CAutoLock</h4>
  class CAutoLock {
  
      // make copy constructor and assignment operator inaccessible
  
      CAutoLock(const CAutoLock &refAutoLock);
      CAutoLock &operator=(const CAutoLock &refAutoLock);
  
  protected:
      CCritSec * m_pLock;
  
  public:
      CAutoLock(CCritSec * plock)
      {
          m_pLock = plock;
          m_pLock->Lock();
      };


  
      ~CAutoLock() {
          m_pLock->Unlock();
      };


  };


  
  // wrapper for event objects
  

CAMEvent</h4>
  class CAMEvent
  {
  
      // make copy constructor and assignment operator inaccessible
  
      CAMEvent(const CAMEvent &refEvent);
      CAMEvent &operator=(const CAMEvent &refEvent);
  
  protected:
      HANDLE m_hEvent;
  public:
      CAMEvent(BOOL fManualReset = FALSE);
      ~CAMEvent();
  
      // Cast to HANDLE - we don't support this as an lvalue
      operator HANDLE () const { return m_hEvent; };


  
      void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));};


      BOOL Wait(DWORD dwTimeout = INFINITE) {
          return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0);
      };


      void Reset() { ResetEvent(m_hEvent); };


      BOOL Check() { return Wait(0); };


  };


  
  // wrapper for event objects that do message processing
  // This adds ONE method to the CAMEvent object to allow sent
  // messages to be processed while waiting
  
  

CAMMsgEvent</h4>
  class CAMMsgEvent : public CAMEvent
  {
  
  public:
  
      // Allow SEND messages to be processed while waiting
      BOOL WaitMsg(DWORD dwTimeout = INFINITE);
  };


  
  // old name supported for the time being
  define CTimeoutEvent CAMEvent
  
  // support for a worker thread
  
  // simple thread class supports creation of worker thread, synchronization
  // and communication. Can be derived to simplify parameter passing
  

AM_NOVTABLE</h4>
  class AM_NOVTABLE CAMThread {
  
      // make copy constructor and assignment operator inaccessible
  
      CAMThread(const CAMThread &refThread);
      CAMThread &operator=(const CAMThread &refThread);
  
      CAMEvent m_EventSend;
      CAMEvent m_EventComplete;
  
      DWORD m_dwParam;
      DWORD m_dwReturnVal;
  
  protected:
      HANDLE m_hThread;
  
      // thread will run this function on startup
      // must be supplied by derived class
      virtual DWORD ThreadProc() = 0;
  
  public:
      CAMThread();
      virtual ~CAMThread();
  
      CCritSec m_AccessLock;        // locks access by client threads
      CCritSec m_WorkerLock;        // locks access to shared objects
  
      // thread initially runs this. param is actually 'this'. function
      // just gets this and calls ThreadProc
      static DWORD WINAPI InitialThreadProc(LPVOID pv);
  
      // start thread running  - error if already running
      BOOL Create();
  
      // signal the thread, and block for a response
      //
      DWORD CallWorker(DWORD);
  
      // accessor thread calls this when done with thread (having told thread
      // to exit)
      void Close() {
          HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0);
          if (hThread) {
              WaitForSingleObject(hThread, INFINITE);
              CloseHandle(hThread);
          }
      };


  
      // ThreadExists
      // Return TRUE if the thread exists. FALSE otherwise
      BOOL ThreadExists(void) const
      {
          if (m_hThread == 0) {
              return FALSE;
          } else {
              return TRUE;
          }
      }
  
      // wait for the next request
      DWORD GetRequest();
  
      // is there a request?
      BOOL CheckRequest(DWORD * pParam);
  
      // reply to the request
      void Reply(DWORD);
  
      // If you want to do WaitForMultipleObjects you'll need to include
      // this handle in your wait list or you won't be responsive
      HANDLE GetRequestHandle() const { return m_EventSend; };


  
      // Find out what the request was
      DWORD GetRequestParam() const { return m_dwParam; };


  
      // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if
      // available. S_FALSE means it's not available.
      static HRESULT CoInitializeHelper();
  };


  
  // CQueue
  //
  // Implements a simple Queue ADT.  The queue contains a finite number of
  // objects, access to which is controlled by a semaphore.  The semaphore
  // is created with an initial count (N).  Each time an object is added
  // a call to WaitForSingleObject is made on the semaphore's handle.  When
  // this function returns a slot has been reserved in the queue for the new
  // object.  If no slots are available the function blocks until one becomes
  // available.  Each time an object is removed from the queue ReleaseSemaphore
  // is called on the semaphore's handle, thus freeing a slot in the queue.
  // If no objects are present in the queue the function blocks until an
  // object has been added.
  
  define DEFAULT_QUEUESIZE   2
  
  template 

CQueue</h4>
   class CQueue {
  private:
      HANDLE          hSemPut;        // Semaphore controlling queue "putting"
      HANDLE          hSemGet;        // Semaphore controlling queue "getting"
      CRITICAL_SECTION CritSect;      // Thread seriallization
      int             nMax;           // Max objects allowed in queue
      int             iNextPut;       // Array index of next "PutMsg"
      int             iNextGet;       // Array index of next "GetMsg"
      T              *QueueObjects;   // Array of objects (ptr's to void)
  
      void Initialize(int n) {
          iNextPut = iNextGet = 0;
          nMax = n;
          InitializeCriticalSection(&CritSect);
          hSemPut = CreateSemaphore(NULL, n, n, NULL);
          hSemGet = CreateSemaphore(NULL, 0, n, NULL);
          QueueObjects = new T[n];
      }
  
  public:
      CQueue(int n) {
          Initialize(n);
      }
  
      CQueue() {
          Initialize(DEFAULT_QUEUESIZE);
      }
  
      ~CQueue() {
          delete [] QueueObjects;
          DeleteCriticalSection(&CritSect);
          CloseHandle(hSemPut);
          CloseHandle(hSemGet);
      }
  
      T GetQueueObject() {
          int iSlot;
          T Object;
          LONG lPrevious;
  
          // Wait for someone to put something on our queue, returns straight
          // away is there is already an object on the queue.
          //
          WaitForSingleObject(hSemGet, INFINITE);
  
          EnterCriticalSection(&CritSect);
          iSlot = iNextGet++ % nMax;
          Object = QueueObjects[iSlot];
          LeaveCriticalSection(&CritSect);
  
          // Release anyone waiting to put an object onto our queue as there
          // is now space available in the queue.
          //
          ReleaseSemaphore(hSemPut, 1L, &lPrevious);
          return Object;
      }
  
      void PutQueueObject(T Object) {
          int iSlot;
          LONG lPrevious;
  
          // Wait for someone to get something from our queue, returns straight
          // away is there is already an empty slot on the queue.
          //
          WaitForSingleObject(hSemPut, INFINITE);
  
          EnterCriticalSection(&CritSect);
          iSlot = iNextPut++ % nMax;
          QueueObjects[iSlot] = Object;
          LeaveCriticalSection(&CritSect);
  
          // Release anyone waiting to remove an object from our queue as there
          // is now an object available to be removed.
          //
          ReleaseSemaphore(hSemGet, 1L, &lPrevious);
      }
  };


  
  // miscellaneous string conversion functions
  // NOTE: as we need to use the same binaries on Win95 as on NT this code should
  // be compiled WITHOUT unicode being defined.  Otherwise we will not pick up
  // these internal routines and the binary will not run on Win95.
  
  int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...);
  
  LPWSTR
  WINAPI
  lstrcpyWInternal(
      LPWSTR lpString1,
      LPCWSTR lpString2
      );
  LPWSTR
  WINAPI
  lstrcpynWInternal(
      LPWSTR lpString1,
      LPCWSTR lpString2,
      int     iMaxLength
      );
  int
  WINAPI
  lstrcmpWInternal(
      LPCWSTR lpString1,
      LPCWSTR lpString2
      );
  int
  WINAPI
  lstrcmpiWInternal(
      LPCWSTR lpString1,
      LPCWSTR lpString2
      );
  int
  WINAPI
  lstrlenWInternal(
      LPCWSTR lpString
      );
  
  ifndef UNICODE
  define wsprintfW wsprintfWInternal
  define lstrcpyW lstrcpyWInternal
  define lstrcpynW lstrcpynWInternal
  define lstrcmpW lstrcmpWInternal
  define lstrcmpiW lstrcmpiWInternal
  define lstrlenW lstrlenWInternal
  endif
  
  extern "C"
  void * __stdcall memmoveInternal(void *, const void *, size_t);
  
  inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt)
  {
  ifdef _X86_
      void *pRet = NULL;
  
      _asm {
          cld                 // make sure we get the direction right
          mov     ecx, cnt    // num of bytes to scan
          mov     edi, buf    // pointer byte stream
          mov     eax, chr    // byte to scan for
          repne   scasb       // look for the byte in the byte stream
          jnz     exit_memchr // Z flag set if byte found
          dec     edi         // scasb always increments edi even when it
                              // finds the required byte
          mov     pRet, edi
  exit_memchr:
      }
      return pRet;
  
  else
      while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
          buf = (unsigned char *)buf + 1;
          cnt--;
      }
  
      return(cnt ? (void *)buf : NULL);
  endif
  }
  
  void WINAPI IntToWstr(int i, LPWSTR wstr);
  
  define WstrToInt(sz) _wtoi(sz)
  define atoiW(sz) _wtoi(sz)
  define atoiA(sz) atoi(sz)
  
  // These are available to help managing bitmap VIDEOINFOHEADER media structures
  
  extern const DWORD bits555[3];
  extern const DWORD bits565[3];
  extern const DWORD bits888[3];
  
  // These help convert between VIDEOINFOHEADER and BITMAPINFO structures
  
  STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader);
  STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader);
  STDAPI_(WORD) GetBitCount(const GUID *pSubtype);
  
  // strmbase.lib implements this for compatibility with people who
  // managed to link to this directly.  we don't want to advertise it.
  //
  // STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype);
  
  STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype);
  STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype);
  
  ifdef UNICODE
  define GetSubtypeName GetSubtypeNameW
  else
  define GetSubtypeName GetSubtypeNameA
  endif
  
  STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader);
  STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader);
  STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo);
  STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo);
  
  // Compares two interfaces and returns TRUE if they are on the same object
  BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond);
  
  // This is for comparing pins
  define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2)
  
  // Arithmetic helper functions
  
  // Compute (a * b + rnd) / c
  LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd);
  LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd);
  
  // Avoids us dyna-linking to SysAllocString to copy BSTR strings
  STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc);
  STDAPI FreeBSTR(BSTR* pstr);
  
  // Return a wide string - allocating memory for it
  // Returns:
  //    S_OK          - no error
  //    E_POINTER     - ppszReturn == NULL
  //    E_OUTOFMEMORY - can't allocate memory for returned string
  STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn);
  
  // Special wait for objects owning windows
  DWORD WINAPI WaitDispatchingMessages(
      HANDLE hObject,
      DWORD dwWait,
      HWND hwnd = NULL,
      UINT uMsg = 0,
      HANDLE hEvent = NULL);
  
  // HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in
  // our use of HRESULT_FROM_WIN32, it typically means a function failed
  // to call SetLastError(), and we still want a failure code.
  //
  define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x))
  
  // call GetLastError and return an HRESULT value that will fail the
  // SUCCEEDED() macro.
  HRESULT AmGetLastErrorToHResult(void);
  
  // duplicate of ATL's CComPtr to avoid linker conflicts.
  
  IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp);
  
  template 
  

QzCComPtr</h4>
  class QzCComPtr
  {
  public:
          typedef T _PtrClass;
          QzCComPtr() {p=NULL;}
          QzCComPtr(T* lp)
          {
                  if ((p = lp) != NULL)
                          p->AddRef();
          }
          QzCComPtr(const QzCComPtr& lp)
          {
                  if ((p = lp.p) != NULL)
                          p->AddRef();
          }
          ~QzCComPtr() {if (p) p->Release();}
          void Release() {if (p) p->Release(); p=NULL;}
          operator T*() {return (T*)p;}
          T& operator*() {ASSERT(p!=NULL); return *p; }
          //The assert on operator& usually indicates a bug.  If this is really
          //what is needed, however, take the address of the p member explicitly.
          T** operator&() { ASSERT(p==NULL); return &p; }
          T* operator->() { ASSERT(p!=NULL); return p; }
          T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);}
          T* operator=(const QzCComPtr& lp)
          {
                  return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p);
          }
  if _MSC_VER>1020
          bool operator!(){return (p == NULL);}
  else
          BOOL operator!(){return (p == NULL) ? TRUE : FALSE;}
  endif
          T* p;
  };


  
  MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent );
  bool TimeKillSynchronousFlagAvailable( void );
  
  endif /* __WXUTIL__ */
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author. <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-2780434-1"; urchinTracker(); </script>

Hush Online Technology
hush@cs.vu.nl
03/12/09