1
//------------------------------------------------------------------------------
4
// Desc: DirectShow base classes - implements class hierarchy for creating
7
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8
//------------------------------------------------------------------------------
10
#include <pjmedia-videodev/config.h>
12
#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0
15
#pragma warning( disable : 4514 ) // Disable warnings re unused inline functions
18
/* Define the static member variable */
20
LONG CBaseObject::m_cObjects = 0;
25
CBaseObject::CBaseObject(__in_opt LPCTSTR pName)
27
/* Increment the number of active objects */
28
InterlockedIncrement(&m_cObjects);
33
m_dwCookie = DbgRegisterObjectCreation(0, pName);
35
m_dwCookie = DbgRegisterObjectCreation(pName, 0);
42
CBaseObject::CBaseObject(const char *pName)
44
/* Increment the number of active objects */
45
InterlockedIncrement(&m_cObjects);
48
m_dwCookie = DbgRegisterObjectCreation(pName, 0);
53
HINSTANCE hlibOLEAut32;
57
CBaseObject::~CBaseObject()
59
/* Decrement the number of objects active */
60
if (InterlockedDecrement(&m_cObjects) == 0) {
62
FreeLibrary(hlibOLEAut32);
70
DbgRegisterObjectDestruction(m_dwCookie);
74
static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll");
76
HINSTANCE LoadOLEAut32()
78
if (hlibOLEAut32 == 0) {
80
hlibOLEAut32 = LoadLibrary(szOle32Aut);
89
// We know we use "this" in the initialization list, we also know we don't modify *phr.
90
#pragma warning( disable : 4355 4100 )
91
CUnknown::CUnknown(__in_opt LPCTSTR pName, __in_opt LPUNKNOWN pUnk)
93
/* Start the object with a reference count of zero - when the */
94
/* object is queried for it's first interface this may be */
95
/* incremented depending on whether or not this object is */
96
/* currently being aggregated upon */
98
/* Set our pointer to our IUnknown interface. */
99
/* If we have an outer, use its, otherwise use ours. */
100
/* This pointer effectivly points to the owner of */
101
/* this object and can be accessed by the GetOwner() method. */
102
, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
103
/* Why the double cast? Well, the inner cast is a type-safe cast */
104
/* to pointer to a type from which we inherit. The second is */
105
/* type-unsafe but works because INonDelegatingUnknown "behaves */
106
/* like" IUnknown. (Only the names on the methods change.) */
108
// Everything we need to do has been done in the initializer list
111
// This does the same as above except it has a useless HRESULT argument
112
// use the previous constructor, this is just left for compatibility...
113
CUnknown::CUnknown(__in_opt LPCTSTR pName, __in_opt LPUNKNOWN pUnk, __inout_opt HRESULT *phr) :
116
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
121
CUnknown::CUnknown(__in_opt LPCSTR pName, __in_opt LPUNKNOWN pUnk)
122
: CBaseObject(pName), m_cRef(0),
123
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
126
CUnknown::CUnknown(__in_opt LPCSTR pName, __in_opt LPUNKNOWN pUnk, __inout_opt HRESULT *phr) :
127
CBaseObject(pName), m_cRef(0),
128
m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast<LPUNKNOWN>( static_cast<PNDUNKNOWN>(this) ) )
133
#pragma warning( default : 4355 4100 )
138
STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv)
140
CheckPointer(ppv,E_POINTER);
141
ValidateReadWritePtr(ppv,sizeof(PVOID));
143
/* We know only about IUnknown */
145
if (riid == IID_IUnknown) {
146
GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv);
150
return E_NOINTERFACE;
154
/* We have to ensure that we DON'T use a max macro, since these will typically */
155
/* lead to one of the parameters being evaluated twice. Since we are worried */
156
/* about concurrency, we can't afford to access the m_cRef twice since we can't */
157
/* afford to run the risk that its value having changed between accesses. */
159
template<class T> inline static T ourmax( const T & a, const T & b )
161
return a > b ? a : b;
166
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef()
168
LONG lRef = InterlockedIncrement( &m_cRef );
170
DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"),
171
m_dwCookie, m_cRef));
172
return ourmax(ULONG(m_cRef), 1ul);
178
STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease()
180
/* If the reference count drops to zero delete ourselves */
182
LONG lRef = InterlockedDecrement( &m_cRef );
185
DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"),
186
m_dwCookie, m_cRef));
189
// COM rules say we must protect against re-entrancy.
190
// If we are an aggregator and we hold our own interfaces
191
// on the aggregatee, the QI for these interfaces will
192
// addref ourselves. So after doing the QI we must release
193
// a ref count on ourselves. Then, before releasing the
194
// private interface, we must addref ourselves. When we do
195
// this from the destructor here it will result in the ref
196
// count going to 1 and then back to 0 causing us to
197
// re-enter the destructor. Hence we add an extra refcount here
198
// once we know we will delete the object.
199
// for an example aggregator see filgraph\distrib.cpp.
206
// Don't touch m_cRef again even in this leg as the object
207
// may have just been released on another thread too
208
return ourmax(ULONG(lRef), 1ul);
213
/* Return an interface pointer to a requesting client
214
performing a thread safe AddRef as necessary */
216
STDAPI GetInterface(LPUNKNOWN pUnk, __out void **ppv)
218
CheckPointer(ppv, E_POINTER);
225
/* Compares two interfaces and returns TRUE if they are on the same object */
227
BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond)
229
/* Different objects can't have the same interface pointer for
232
if (pFirst == pSecond) {
235
/* OK - do it the hard way - check if they have the same
236
IUnknown pointers - a single object can only have one of these
238
LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface
239
LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface
240
HRESULT hr; // General OLE return code
245
/* See if the IUnknown pointers match */
247
hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1);
253
/* Release the extra interface we hold */
255
pUnknown1->Release();
257
hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2);
263
/* Release the extra interface we hold */
265
pUnknown2->Release();
266
return (pUnknown1 == pUnknown2);
269
#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */