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

📄 combase.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 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 (memcmp(&riid,&IID_IUnknown,sizeof(GUID))==0)
  {
   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 + -