⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 combase.cpp

📁 mpeg4 video codec mpeg4 video codec
💻 CPP
字号:
//------------------------------------------------------------------------------// File: ComBase.cpp//// Desc: DirectShow base classes - implements class hierarchy for creating//       COM objects.//// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.//------------------------------------------------------------------------------#include "stdafx.h"#include "combase.h"#include <assert.h>#define ASSERT assert/* Define the static member variable *//* Constructor */CBaseObject::CBaseObject(const TCHAR *pName){ /* Increment the number of active objects */}/* Destructor */CBaseObject::~CBaseObject(){ /* Decrement the number of objects active */}/* Constructor */// We know we use "this" in the initialization list, we also know we don't modify *phr.#pragma warning( disable : 4355 4100 )CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk)  : CBaseObject(pName)  /* Start the object with a reference count of zero - when the      */  /* object is queried for it's first interface this may be          */  /* incremented depending on whether or not this object is          */  /* currently being aggregated upon                                 */  , m_cRef(0)  /* Set our pointer to our IUnknown interface.                      */  /* If we have an outer, use its, otherwise use ours.               */  /* This pointer effectivly points to the owner of                  */  /* this object and can be accessed by the GetOwner() method.       */  , m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )  /* Why the double cast?  Well, the inner cast is a type-safe cast */  /* to pointer to a type from which we inherit.  The second is     */  /* type-unsafe but works because INonDelegatingUnknown "behaves   */  /* like" IUnknown. (Only the names on the methods change.)        */{ // Everything we need to do has been done in the initializer list}// This does the same as above except it has a useless HRESULT argument// use the previous constructor, this is just left for compatibility...CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) :CBaseObject(pName),m_cRef(0),m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) ){}#pragma warning( default : 4355 4100 )/* QueryInterface */#define CheckPointer(p,ret) {if((p)==NULL) return (ret);}#define ValidateReadPtr(p,cb) {if(IsBadReadPtr((PVOID)p,cb) == TRUE) perror("Invalid read pointer");}#define ValidateWritePtr(p,cb) {if(IsBadWritePtr((PVOID)p,cb) == TRUE) perror("Invalid write pointer");}#define ValidateReadWritePtr(p,cb) {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)}STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv){ CheckPointer(ppv,E_POINTER); ValidateReadWritePtr(ppv,sizeof(PVOID)); /* We know only about IUnknown */ if (riid == IID_IUnknown)  {   GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);   return NOERROR;  } else  {   *ppv = NULL;   return E_NOINTERFACE;  }}/* We have to ensure that we DON'T use a max macro, since these will typically   *//* lead to one of the parameters being evaluated twice.  Since we are worried    *//* about concurrency, we can't afford to access the m_cRef twice since we can't  *//* afford to run the risk that its value having changed between accesses.        */template<class T>inline static T ourmax( const T & a, const T & b ){ return a > b ? a : b;}/* AddRef */STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef(){ LONG lRef = InterlockedIncrement( (long*)&m_cRef ); ASSERT(lRef > 0); return ourmax(ULONG(m_cRef), 1ul);}/* Release */STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease(){ /* If the reference count drops to zero delete ourselves */ LONG lRef = InterlockedDecrement( (long*)&m_cRef ); if (lRef == 0)  {   // COM rules say we must protect against re-entrancy.   // If we are an aggregator and we hold our own interfaces   // on the aggregatee, the QI for these interfaces will   // addref ourselves. So after doing the QI we must release   // a ref count on ourselves. Then, before releasing the   // private interface, we must addref ourselves. When we do   // this from the destructor here it will result in the ref   // count going to 1 and then back to 0 causing us to   // re-enter the destructor. Hence we add an extra refcount here   // once we know we will delete the object.   // for an example aggregator see filgraph\distrib.cpp.   m_cRef++;   delete this;   return ULONG(0);  } else  {   return ourmax(ULONG(m_cRef), 1ul);  }}/* Return an interface pointer to a requesting client   performing a thread safe AddRef as necessary */STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv){ CheckPointer(ppv, E_POINTER); *ppv = pUnk; pUnk->AddRef(); return NOERROR;}/* Compares two interfaces and returns TRUE if they are on the same object */BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond){ /*  Different objects can't have the same interface pointer for     any interface */ if (pFirst == pSecond)  {   return TRUE;  } /*  OK - do it the hard way - check if they have the same     IUnknown pointers - a single object can only have one of these */ LPUNKNOWN pUnknown1;     // Retrieve the IUnknown interface LPUNKNOWN pUnknown2;     // Retrieve the other IUnknown interface HRESULT hr;              // General OLE return code ASSERT(pFirst); ASSERT(pSecond); /* See if the IUnknown pointers match */ hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1); ASSERT(SUCCEEDED(hr)); ASSERT(pUnknown1); hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2); ASSERT(SUCCEEDED(hr)); ASSERT(pUnknown2); /* Release the extra interfaces we hold */ pUnknown1->Release(); pUnknown2->Release(); return (pUnknown1 == pUnknown2);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -