You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
7.6 KiB
313 lines
7.6 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
MSPStrm.h
|
|
|
|
Abstract:
|
|
|
|
Definitions for CMSPStream class.
|
|
|
|
--*/
|
|
#ifndef _MSPSTRM_H_
|
|
#define _MSPSTRM_H_
|
|
|
|
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
Represents a stream in a call.
|
|
|
|
--*/
|
|
|
|
#define STRM_INITIAL 0x00000000
|
|
#define STRM_TERMINALSELECTED 0x00000001
|
|
#define STRM_CONFIGURED 0x00000002
|
|
#define STRM_RUNNING 0x00000004
|
|
#define STRM_PAUSED 0x00000008
|
|
#define STRM_STOPPED 0x00000010
|
|
|
|
class CMSPStream;
|
|
|
|
class ATL_NO_VTABLE CPTEventSink :
|
|
public CComObjectRootEx<CComMultiThreadModel>,
|
|
public ITPluggableTerminalEventSink
|
|
{
|
|
|
|
public:
|
|
CPTEventSink();
|
|
~CPTEventSink();
|
|
|
|
BEGIN_COM_MAP( CPTEventSink )
|
|
COM_INTERFACE_ENTRY( ITPluggableTerminalEventSink )
|
|
END_COM_MAP()
|
|
|
|
public:
|
|
// --- ITDTEventSink ---
|
|
STDMETHOD(FireEvent)(
|
|
/* in */ const MSP_EVENT_INFO *pMspEventInfo
|
|
);
|
|
|
|
|
|
public:
|
|
|
|
//
|
|
// set the stream which will be processing our events
|
|
//
|
|
// this method is called by the stream when it creates and initializes
|
|
// the sink object, and also when the stream is going away and want to
|
|
// tell us that it is no longer available to process our events.
|
|
//
|
|
|
|
HRESULT SetSinkStream( CMSPStream *pStream );
|
|
|
|
private:
|
|
|
|
|
|
//
|
|
// a nested structure that is used to pass event and stream to the
|
|
// asynchronous event processing routine.
|
|
//
|
|
|
|
struct AsyncEventStruct
|
|
{
|
|
|
|
//
|
|
// pointer to the stream on which to fire event
|
|
//
|
|
|
|
CMSPStream *pMSPStream;
|
|
|
|
|
|
//
|
|
// pointer to the event item to be processed
|
|
//
|
|
|
|
MSPEVENTITEM *pEventItem;
|
|
|
|
|
|
//
|
|
// as a public service, initialize structure's data members
|
|
//
|
|
|
|
AsyncEventStruct()
|
|
:pMSPStream(NULL),
|
|
pEventItem(NULL)
|
|
{
|
|
LOG((MSP_TRACE, "AsyncEventStruct::AsyncEventStruct[%p]", this));
|
|
}
|
|
|
|
|
|
//
|
|
// as a safety measure, set data members to NULL's in destructor
|
|
// to make sure no one attemopts to use them after the strcuture is
|
|
// gone.
|
|
//
|
|
// note: we don't free any data members here -- that's responsibility
|
|
// of the structure's client
|
|
//
|
|
|
|
~AsyncEventStruct()
|
|
{
|
|
pMSPStream = NULL;
|
|
pEventItem = NULL;
|
|
|
|
LOG((MSP_TRACE, "AsyncEventStruct::~AsyncEventStruct[%p]", this));
|
|
}
|
|
|
|
}; // AsyncEventStruct
|
|
|
|
|
|
//
|
|
// the callback function that is submitted to thread pool api for async
|
|
// event processing. The argument is the event structure containing stream
|
|
// and the actual event
|
|
//
|
|
|
|
static DWORD WINAPI FireEventCallBack(LPVOID pEventStructure);
|
|
|
|
|
|
private:
|
|
|
|
CMSPStream* m_pMSPStream;
|
|
};
|
|
|
|
class ATL_NO_VTABLE CMSPStream :
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
public IDispatchImpl<ITStream, &IID_ITStream, &LIBID_TAPI3Lib>
|
|
{
|
|
public:
|
|
|
|
BEGIN_COM_MAP(CMSPStream)
|
|
COM_INTERFACE_ENTRY(IDispatch)
|
|
COM_INTERFACE_ENTRY(ITStream)
|
|
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
|
|
END_COM_MAP()
|
|
|
|
DECLARE_GET_CONTROLLING_UNKNOWN()
|
|
|
|
CMSPStream();
|
|
~CMSPStream();
|
|
|
|
// methods of the CComObject
|
|
virtual void FinalRelease();
|
|
|
|
// ITStream methods, called by the app.
|
|
STDMETHOD (get_MediaType) (
|
|
OUT long * plMediaType
|
|
);
|
|
|
|
STDMETHOD (get_Direction) (
|
|
OUT TERMINAL_DIRECTION * pTerminalDirection
|
|
);
|
|
|
|
STDMETHOD (get_Name) (
|
|
OUT BSTR * ppName
|
|
) = 0;
|
|
|
|
STDMETHOD (SelectTerminal) (
|
|
IN ITTerminal * pTerminal
|
|
);
|
|
|
|
STDMETHOD (UnselectTerminal) (
|
|
IN ITTerminal * pTerminal
|
|
);
|
|
|
|
STDMETHOD (EnumerateTerminals) (
|
|
OUT IEnumTerminal ** ppEnumTerminal
|
|
);
|
|
|
|
STDMETHOD (get_Terminals) (
|
|
OUT VARIANT * pTerminals
|
|
);
|
|
|
|
STDMETHOD (StartStream) ();
|
|
|
|
STDMETHOD (PauseStream) ();
|
|
|
|
STDMETHOD (StopStream) ();
|
|
|
|
// methods called by the MSPCall object.
|
|
virtual HRESULT Init(
|
|
IN HANDLE hAddress,
|
|
IN CMSPCallBase * pMSPCall,
|
|
IN IMediaEvent * pGraph,
|
|
IN DWORD dwMediaType,
|
|
IN TERMINAL_DIRECTION Direction
|
|
);
|
|
|
|
virtual HRESULT ShutDown();
|
|
|
|
virtual HRESULT GetState(
|
|
OUT DWORD * pdwStatus
|
|
) { return E_NOTIMPL; }
|
|
|
|
virtual HRESULT HandleTSPData(
|
|
IN BYTE * pData,
|
|
IN DWORD dwSize
|
|
);
|
|
|
|
virtual HRESULT ProcessGraphEvent(
|
|
IN long lEventCode,
|
|
IN LONG_PTR lParam1,
|
|
IN LONG_PTR lParam2
|
|
);
|
|
|
|
protected:
|
|
// --- Helper functions ---
|
|
HRESULT RegisterPluggableTerminalEventSink(
|
|
/*[in]*/ ITTerminal* pTerminal
|
|
);
|
|
|
|
HRESULT UnregisterPluggableTerminalEventSink(
|
|
/*[in]*/ ITTerminal* pTerminal
|
|
);
|
|
|
|
|
|
HRESULT ReleaseSink();
|
|
|
|
|
|
//
|
|
// we want to have control over our addref and release logic: we need to do
|
|
// special tricks to avoid stream being accessed by the event sink while
|
|
// the stream is being deleted.
|
|
//
|
|
|
|
ULONG InternalAddRef();
|
|
|
|
ULONG InternalRelease();
|
|
|
|
|
|
public:
|
|
|
|
|
|
//
|
|
// this method is called by CPTEventSink when it has an event for us to
|
|
// process
|
|
//
|
|
|
|
HRESULT HandleSinkEvent(MSPEVENTITEM *pEventItem);
|
|
|
|
|
|
protected:
|
|
// Pointer to the free threaded marshaler.
|
|
IUnknown * m_pFTM;
|
|
|
|
// The current state of the stream.
|
|
DWORD m_dwState;
|
|
|
|
// The media type of this stream. Audio, video, or others.
|
|
DWORD m_dwMediaType;
|
|
|
|
// The direction of this stream. Incoming or outgoing.
|
|
TERMINAL_DIRECTION m_Direction;
|
|
|
|
// The address on which this stream is being used.
|
|
HANDLE m_hAddress;
|
|
|
|
// The reference to the call object.
|
|
CMSPCallBase * m_pMSPCall;
|
|
|
|
// The pointers to the graph object interfaces.
|
|
IGraphBuilder * m_pIGraphBuilder;
|
|
IMediaControl * m_pIMediaControl;
|
|
|
|
// The list of stream objects in the call.
|
|
CMSPArray <ITTerminal *> m_Terminals;
|
|
|
|
// The lock that protects the stream object. The stream object
|
|
// should never acquire the lock and then call a MSPCall method
|
|
// that might lock.
|
|
CMSPCritSection m_lock;
|
|
|
|
// The lock that protects refcounting on the stream object. this is a
|
|
// workaround needed to sync against event sink attempting to access the
|
|
// stream object while it is being deleted.
|
|
|
|
CMSPCritSection m_lockRefCount;
|
|
|
|
// The Event Sink for pluggable terminals
|
|
ITPluggableTerminalEventSink* m_pPTEventSink;
|
|
|
|
|
|
//
|
|
// we have to implement our own reference counting to work around the
|
|
// problem of event sink addreffing us after we saw our last release
|
|
//
|
|
|
|
long m_lMyPersonalRefcount;
|
|
|
|
|
|
//
|
|
// this is a flag that we use to distingush between first addref and the
|
|
// addref on the object whose refcount has gone down to 0.
|
|
//
|
|
|
|
BOOL m_bFirstAddRef;
|
|
|
|
};
|
|
|
|
#endif // __MSPSTRM_H_
|