Source code of Windows XP (NT5)
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.

452 lines
18 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // INTEL Corporation Proprietary Information
  3. // This listing is supplied under the terms of a license agreement with Intel
  4. // Corporation and many not be copied nor disclosed except in accordance
  5. // with the terms of that agreement.
  6. // Copyright (c) 1995, 1996 Intel Corporation.
  7. //
  8. //
  9. // Module Name: PPMRcv.h
  10. // Abstract: Header file for PPM Receive COM Object
  11. // Environment: MSVC 4.0, OLE 2
  12. /////////////////////////////////////////////////////////////////////////////////
  13. // NOTES:
  14. //
  15. // The three functions that are members of the IUnknown interface need to be
  16. // implemented in the most derived class. (Generally the class derived from
  17. // this one.) This is done because if one of your super classes
  18. // is derived from more than one interface, each of which derive from IUnknown,
  19. // the compiler will be confused as to which implementation of the IUnknown
  20. // interface to use. So, by requiring that only the most derived class implement
  21. // these functions then you will never run into this problem.
  22. //
  23. //
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // //This code goes into your class declaration, it defines three functions
  26. // //IUnknown Functions (Overrides)
  27. //
  28. // STDMETHODIMP GetInterface( REFIID riid, LPVOID FAR* ppvObj );
  29. // STDMETHODIMP_( ULONG )AddRef( void );
  30. // STDMETHODIMP_( ULONG )Release( void );
  31. //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // This code is the implementation of
  34. // CUnknown Functions (Overrides)
  35. //
  36. // //Three Cases:
  37. // //
  38. // //1. If you multiply derive from ppmReceive and another interface you would have to
  39. // //write your own QueryInterface and call CUnknown::QueryInterface AND handle
  40. // //the interface you derived from. As well as having the GetInterface function
  41. // //as shown below.
  42. //
  43. // //2. If you derive from another object and ppmReceive you would need to write your
  44. // //own QueryInterface to call CUnknown::QueryInterface and
  45. // //OtherObject::QueryInterface. As well as having the GetInterface function shown
  46. // //below.
  47. //
  48. // //3. If you are only derived from ppmReceive then all you need is the code below.
  49. //
  50. // STDMETHODIMP GetInterface( void REFIID riid, LPVOID FAR* ppvObj )
  51. // {
  52. // return ppmReceive::GetInterface( riid, ppvObj );
  53. // }
  54. //
  55. // STDMETHODIMP_( ULONG )AddRef( void )
  56. // {
  57. // return CUnknown::AddRef();
  58. // }
  59. //
  60. // STDMETHODIMP_( ULONG )Release( void )
  61. // {
  62. // return CUnknown::Release();
  63. // }
  64. //
  65. /////////////////////////////////////////////////////////////////////////////
  66. #ifndef PPMRCV_H
  67. #define PPMRCV_H
  68. #include "isubmit.h"
  69. #include "ippm.h"
  70. #include "ppm.h"
  71. #include "freelist.h"
  72. #include "core.h"
  73. #include "llist.h"
  74. #include "wrap.h"
  75. ////////////////////////////////////////////////////////////////////////////////////////
  76. //MsgHeader Class
  77. ////////////////////////////////////////////////////////////////////////////////////////
  78. class MsgHeader
  79. {
  80. public:
  81. MsgHeader *m_pNext;
  82. MsgHeader *m_pPrev;
  83. LList *m_pFragList;
  84. int m_NumFragments;
  85. DWORD m_TimeOfLastPacket;
  86. DWORD m_MessageID;
  87. BOOL m_MarkerBitIn;
  88. MsgHeader();
  89. ~MsgHeader(){ if (m_pFragList) delete m_pFragList; } //inline function
  90. DWORD GetMsgID();
  91. }; //end MsgHeader class
  92. inline MsgHeader::MsgHeader() //inline function
  93. {
  94. m_pNext = NULL;
  95. m_pPrev = NULL;
  96. m_pFragList = new LList;
  97. m_NumFragments = 0;
  98. m_TimeOfLastPacket = 0;
  99. m_MessageID = 0;
  100. m_MarkerBitIn = FALSE;
  101. };
  102. ////////////////////////////////////////////////////////////////////////////////////////
  103. //PPMReceive Class:
  104. ////////////////////////////////////////////////////////////////////////////////////////
  105. class ppmReceive :
  106. public ppm,
  107. public IPPMReceive,
  108. public IPPMReceiveExperimental,
  109. public IPPMReceiveSession,
  110. public ISubmit,
  111. public ISubmitCallback,
  112. public ISubmitUser,
  113. public IPPMData,
  114. public CUnknown
  115. {
  116. protected:
  117. ////////////////////////////
  118. //Members
  119. //
  120. //NOTE: Any member with the tag _reg_ in it, means its value comes from the registry.
  121. ISubmitCallback *m_pSubmitCallback;
  122. ISubmit *m_pSubmit;
  123. IMalloc *m_pIMalloc;
  124. FreeList *m_pBufPool; //List of Fragment buffers if necessary.
  125. FreeList *m_pMsgHeaderPool; //Points to a free list of MsgHeaders
  126. MsgHeader *m_pMsgHeadersHead; //Points to the beginning of list of MsgHeaders.
  127. MsgHeader *m_pMsgHeadersTail; //Points to the end of list of MsgHeaders.
  128. int m_MaxBufferSize; //Max size the reassemble buffers should be
  129. int m_reg_NumMsgHeaders; //Number of MessageHeaders.
  130. DWORD m_GlobalLastSeqNum; //Last Sequence Number of last Message
  131. DWORD m_GlobalLastMsgID; //Last Message ID (i.e. Time Stamp)
  132. DWORD m_GlobalLastSSRC; //Last Message SSRC
  133. MMRESULT m_TimerID;
  134. DWORD m_reg_TimerInterval;
  135. DWORD m_reg_TimerResolution;
  136. DWORD m_reg_DeltaTime; //Amount of time one should wait before tossing
  137. //a packet.
  138. BOOL m_FirstPacket;
  139. BOOL m_inFlushMode;
  140. BOOL m_GlobalLastFrameDropped; //Keeps track of frame drops for notifications
  141. BOOL m_DataOutstanding; // Is there data outstanding via
  142. // ReportOutstandingData call
  143. OutstandingDataHdr*
  144. m_OutstandingDataPtr; // Pointer to last chunk of data sent via
  145. // ReportOutstandingData call
  146. int m_OutstandingMsgCount; // Indicates count of message we had info
  147. // during the last ReportOutstandingData
  148. long m_PacketsHold; // Number of packets (CMediaSample)
  149. // we keep (i.e. AddRef)
  150. /////////////////////////////////////////////////////////////////////////////
  151. /////////////////////////////////////////////////////////////////////////////
  152. //External PPMReceive Functions
  153. /////////////////////////////////////////////////////////////////////////////
  154. /////////////////////////////////////////////////////////////////////////////
  155. public:
  156. //////////////////////////////////////////////////////////////////////////////
  157. // PPMReceive Functions (Overrides)
  158. //constructor
  159. ppmReceive(int PayloadTypeArg, int MaxBufferSizeArg, int ProfileHdrSizeArg, IUnknown* pUnkOuter, IUnknown** ppUnkInner);
  160. //destructor,
  161. ~ppmReceive();
  162. //////////////////////////////////////////////////////////////////////////////
  163. // IPPMReceive Functions (Overrides)
  164. //see documentation (PHEPS.DOC)
  165. STDMETHOD(InitPPMReceive)(THIS_ int MaxBufferSize,
  166. int iBuffers,
  167. int iPackets,
  168. DWORD dwCookie);
  169. STDMETHOD(InitPPMReceive)(THIS_ int MaxBufferSize, DWORD dwCookie)
  170. {
  171. m_LimitBuffers = FALSE;
  172. return InitPPMReceive(MaxBufferSize,
  173. DEFAULT_MSG_COUNT_RCV,
  174. DEFAULT_FRAG_COUNT,
  175. m_dwCookie);
  176. }
  177. STDMETHOD(SetSession)(THIS_ PPMSESSPARAM_T *pSessparam);
  178. STDMETHOD(SetAlloc)(THIS_ IMalloc *pIMalloc);
  179. //////////////////////////////////////////////////////////////////////////////
  180. // IPPMReceiveSession Functions (Overrides)
  181. //see documentation (PHEPS.DOC)
  182. STDMETHOD(GetPayloadType)(THIS_ LPBYTE lpcPayloadType);
  183. STDMETHOD(SetPayloadType)(THIS_ BYTE cPayloadType);
  184. STDMETHOD(GetTimeoutDuration)(THIS_ LPDWORD lpdwLostPacketTime);
  185. STDMETHOD(SetTimeoutDuration)(THIS_ DWORD dwLostPacketTime);
  186. STDMETHOD(GetResiliency)(THIS_ LPBOOL lpbResiliency);
  187. STDMETHOD(SetResiliency)(THIS_ BOOL pbResiliency);
  188. //////////////////////////////////////////////////////////////////////////////
  189. // IPPMData Functions (Overrides)
  190. //////////////////////////////////////////////////////////////////////////////////////////
  191. //FlushData:
  192. //////////////////////////////////////////////////////////////////////////////////////////
  193. STDMETHOD(FlushData)(THIS_ void );
  194. //////////////////////////////////////////////////////////////////////////////
  195. ////////////////////////////////////////////////////////////////////////////////////////
  196. // ReportOutstandingData: Walks through the message and fragment lists and reports back
  197. // to caller via callback
  198. // Returns TRUE if data was delivered
  199. // returns FALSE if an error occurred - values in parameters will be invalid
  200. ////////////////////////////////////////////////////////////////////////////////////////
  201. STDMETHOD(ReportOutstandingData)(THIS_ DWORD** pDataHdr, DWORD* DataCount);
  202. ////////////////////////////////////////////////////////////////////////////////////////
  203. // ReleaseOutstandingDataBuffer - will release the buffer given to the caller
  204. // during a previous ReportOutstandingData call
  205. ////////////////////////////////////////////////////////////////////////////////////////
  206. STDMETHOD(ReleaseOutstandingDataBuffer)(THIS_ DWORD *pData );
  207. // ISubmit Functions (Overrides)
  208. //see documentation (PHEPS.DOC)
  209. STDMETHOD(InitSubmit)(ISubmitCallback *pSubmitCallback);
  210. //see documentation (PHEPS.DOC)
  211. STDMETHOD(Submit)(WSABUF *pWSABuffer, DWORD BufferCount,
  212. void *pUserToken, HRESULT Error);
  213. //see documentation (PHEPS.DOC)
  214. //Stubs for now; overriding both ISubmit calls and ISubmitCallback
  215. //calls for ReportError
  216. STDMETHOD_(void,ReportError)(THIS_ HRESULT Error){}
  217. STDMETHOD(Flush)(THIS);
  218. //////////////////////////////////////////////////////////////////////////////
  219. // ISubmitCallback Functions (Overrides)
  220. //see documentation (PHEPS.DOC)
  221. STDMETHOD_(void,SubmitComplete)(void *pUserToken, HRESULT Error);
  222. STDMETHOD_(void,ReportError)(THIS_ HRESULT Error, int=0){}
  223. //////////////////////////////////////////////////////////////////////////////
  224. // ISubmitUser Functions (Overrides)
  225. STDMETHOD(SetOutput)(THIS_ IUnknown *pSubmit);
  226. //////////////////////////////////////////////////////////////////////////////////////////
  227. //TimeOut: Calls Staleness check then calls process msgs.
  228. //////////////////////////////////////////////////////////////////////////////////////////
  229. virtual HRESULT TimeOut(void);
  230. /////////////////////////////////////////////////////////////////////////////
  231. /////////////////////////////////////////////////////////////////////////////
  232. //Internal PPMReceive Functions
  233. /////////////////////////////////////////////////////////////////////////////
  234. /////////////////////////////////////////////////////////////////////////////
  235. protected:
  236. /////////////////////////////////////////////////////////////////////////////
  237. // CUnknown Functions
  238. /////////////////////////////////////////////////////////////////////////////
  239. // CUnknown Functions (Overrides)
  240. //
  241. // Call this method to get interface pointers supported by derived objects
  242. // called by CInnerUnknown::QueryInterface; should return S_FALSE
  243. // if interface is AddRef'd, S_OK if caller needs to AddRef the interface.
  244. STDMETHOD(GetInterface)( REFIID riid, LPVOID FAR* ppvObj );
  245. //////////////////////////
  246. //inline functions
  247. MsgHeader * GetMsgHeader(); //gets a new MsgHeader from the free pool
  248. void FreeMsgHeader(MsgHeader *pMsg);
  249. MsgHeader * TakeMsgHeader(); //takes the first MsgHeader from the enqueued list
  250. /////////////////////////////////////////////////////////////////////////////
  251. // PPMReceive Functions
  252. //
  253. ////////////////////////////////////////////////////////////////////////////////
  254. //////////////////////////////////////////////////////////////////////////////////////////
  255. //VoidToFragment: Given a buffer with an RTP header and a Profile specific
  256. //header return pointer to data. This function should definitely be overridden by the
  257. //payload specific class. The overriding function would call this one and then it would
  258. //set the profile header
  259. //////////////////////////////////////////////////////////////////////////////////////////
  260. virtual void VoidToFragment(WSABUF *pWSABuffer, DWORD BufferCount,
  261. FragDescriptor *pFragDescrip, void *pUserToken);
  262. //////////////////////////////////////////////////////////////////////////////////////////
  263. //SetupTimer: Sets up Timer and returns a Timer ID.If null is returned function failed
  264. // to initialize a timer.
  265. //////////////////////////////////////////////////////////////////////////////////////////
  266. MMRESULT SetupTimer();
  267. //////////////////////////////////////////////////////////////////////////////////////////
  268. //EnqueByMessage: Finds the MsgHeader and calls EnqueueByFrag.
  269. //////////////////////////////////////////////////////////////////////////////////////////
  270. virtual HRESULT EnqueByMessage(FragDescriptor *pFragDescrip);
  271. //////////////////////////////////////////////////////////////////////////////////////////
  272. //EnqueueByFrag: Enqueues frag, calls ProcessMessages if appropriate
  273. //////////////////////////////////////////////////////////////////////////////////////////
  274. virtual HRESULT EnqueueByFrag(FragDescriptor *pFragDescrip, MsgHeader *pMsgHdr);
  275. //////////////////////////////////////////////////////////////////////////////////////////
  276. //TimeToProcessMessages:
  277. //////////////////////////////////////////////////////////////////////////////////////////
  278. virtual BOOL TimeToProcessMessages(FragDescriptor *pFragDescrip, MsgHeader *pMsgHdr);
  279. //////////////////////////////////////////////////////////////////////////////////////////
  280. //ProcessMessages:
  281. //////////////////////////////////////////////////////////////////////////////////////////
  282. virtual HRESULT ProcessMessages(void);
  283. //////////////////////////////////////////////////////////////////////////////////////////
  284. //CheckMessageComplete:
  285. //////////////////////////////////////////////////////////////////////////////////////////
  286. virtual BOOL CheckMessageComplete(MsgHeader *pMsgHdr);
  287. //////////////////////////////////////////////////////////////////////////////////////////
  288. //CheckMessageStale:
  289. //////////////////////////////////////////////////////////////////////////////////////////
  290. virtual BOOL CheckMessageStale(MsgHeader *pMsgHdr);
  291. //////////////////////////////////////////////////////////////////////////////////////////
  292. //PrepMessage: Sets global variables, calls DataCopy
  293. //////////////////////////////////////////////////////////////////////////////////////////
  294. virtual HRESULT PrepMessage(BOOL);
  295. //////////////////////////////////////////////////////////////////////////////////////////
  296. //DataCopy: Copies data fragments into client's buffer
  297. //////////////////////////////////////////////////////////////////////////////////////////
  298. virtual HRESULT DataCopy(MsgHeader *const pMsgHdr);
  299. //////////////////////////////////////////////////////////////////////////////////////////
  300. //PartialMessageHandler: deals with partial messages
  301. //////////////////////////////////////////////////////////////////////////////////////////
  302. virtual HRESULT PartialMessageHandler(MsgHeader *pMsgHdr);
  303. //////////////////////////////////////////////////////////////////////////////////////////
  304. //FreeFragList: Re-posts fragment buffers and frees header memory.
  305. //////////////////////////////////////////////////////////////////////////////////////////
  306. HRESULT FreeFragList(MsgHeader *pMsgHdr);
  307. //////////////////////////////////////////////////////////////////////////////////////////
  308. //InitProfileHeader: Given a buffer as type void, sets up a profile header.
  309. //////////////////////////////////////////////////////////////////////////////////////////
  310. virtual void *InitProfileHeader(void *pBuffer);
  311. //////////////////////////////////////////////////////////////////////////////////////////
  312. //FreeProfileHeader: Given a buffer as type void, frees up a profile header.
  313. //////////////////////////////////////////////////////////////////////////////////////////
  314. virtual void FreeProfileHeader(void *pBuffer);
  315. ///////////////////////////////////////////////////////////////////////////////////////////
  316. //FindMsgHeader: Walks the list of MsgHeaders. If it finds MsgHeader it wants then it
  317. // a pointer to it. If one is not found, one is created and put in place.
  318. //////////////////////////////////////////////////////////////////////////////////////////
  319. MsgHeader* FindMsgHeader(DWORD MessageID);
  320. ///////////////////////////////////////////////////////////////////////////////////////////
  321. //Make this function a friend so that this function can access protect and private member
  322. //functions. The prototype of the function is after the class declaration.
  323. //
  324. friend void CALLBACK PPM_Timer(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
  325. }; //end of ppmReceive class
  326. /////////////////////////////////////////////////////////////////////////////
  327. //FreeMsgHeader: This function just hides the implementation of the free list of
  328. // MsgHeaders.
  329. /////////////////////////////////////////////////////////////////////////////
  330. inline void ppmReceive::FreeMsgHeader(MsgHeader *pMsg)
  331. {
  332. if (pMsg->m_pFragList) delete pMsg->m_pFragList;
  333. m_pMsgHeaderPool->Free((void *)pMsg);
  334. }
  335. //////////////////////////////////////////////////////////////////////////////////////////
  336. //PPM_MMTimer: timer callback
  337. //////////////////////////////////////////////////////////////////////////////////////////
  338. void CALLBACK PPM_Timer(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
  339. //////////////////////////////////////////////////////////////////////////////////////////
  340. //Helpers for H.26x sbit/ebit. These may not belong here, but too small to justify a
  341. //seperate header.
  342. inline unsigned char
  343. GetSMask(int sbits)
  344. {
  345. #ifdef ASSERT
  346. ASSERT((sbits >= 0) && (sbits <= 8));
  347. #endif
  348. // Unsigned type req'd for right shift to ensure that zero values
  349. // are shifted in. Int req'd to allow shifting of more than 7 bits.
  350. return (unsigned int) 0xff >> sbits;
  351. }
  352. inline unsigned char
  353. GetEMask(int ebits)
  354. {
  355. #ifdef ASSERT
  356. ASSERT((ebits >= 0) && (ebits <= 8));
  357. #endif
  358. // Unsigned type req'd to ensure correct conversion to return type.
  359. return (unsigned int) 0xff << ebits;
  360. }
  361. #endif