Leaked source code of windows server 2003
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.

276 lines
9.6 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: frame.h
  6. * Content: declaration of the CFrame and CFramePool classes
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/16/99 pnewson Created
  12. * 07/22/99 rodtoll Updated target to be DWORD
  13. * 08/03/99 pnewson General clean up, updated target to DVID
  14. * 01/14/2000 rodtoll Updated to support multiple targets. Frame will
  15. * automatically allocate memory as needed for targets.
  16. * rodtoll Added SetEqual function to making copying of frame
  17. * in Queue easier.
  18. * rodtoll Added support for "user controlled memory" frames.
  19. * When the default constructor is used with the UserOwn_XXXX
  20. * functions the frames use user specified buffers.
  21. * (Removes a buffer copy when queueing data).
  22. * 01/31/2000 pnewson replace SAssert with DNASSERT
  23. * 03/29/2000 rodtoll Bug #30753 - Added volatile to the class definition
  24. * 07/09/2000 rodtoll Added signature bytes
  25. * 02/28/2002 rodtoll WINBUG #550105 SECURITY: DPVOICE: Dead code
  26. * - Remove unused GetTargets() function
  27. *
  28. ***************************************************************************/
  29. #ifndef _FRAME_H_
  30. #define _FRAME_H_
  31. // forward declaration
  32. class CFramePool;
  33. #define VSIG_FRAME 'MRFV'
  34. #define VSIG_FRAME_FREE 'MRF_'
  35. // This class is designed to manage one frame of sound data.
  36. //
  37. // tag: fr
  38. volatile class CFrame
  39. {
  40. private:
  41. DWORD m_dwSignature;
  42. // The critical section object which is used to protect the
  43. // return method. This is passed in by CInputQueue2 and/or CInnerQueue
  44. // class, so that the return method is serialized with calls to
  45. // Reset, Enqueue and Dequeue. If no critical section is passed,
  46. // the Return member should not be used, and this frame should
  47. // not be part of a managed pool.
  48. DNCRITICAL_SECTION *m_pCriticalSection;
  49. // Length of the data within the frame. There may be less then a whole
  50. // frame worth of data in the buffer due to compression/decompression may
  51. // result in a slightly different size buffer.
  52. WORD m_wFrameLength;
  53. // The size of this frame. It would be easier to make
  54. // this a class constant, but we're probably going to want to
  55. // toy with the frame sizes while we're optimizing, and
  56. // we may even get really fancy in the future and have
  57. // the client and server negotiate the frame size at connection
  58. // time, all of which will be easier if we bite the bullet now
  59. // and make this a member variable. Note this is constant,
  60. // so once a frame is instantiated, it's size is permanently set.
  61. WORD m_wFrameSize;
  62. // The client number this frame is coming from or
  63. // going to.
  64. WORD m_wClientId;
  65. // The frame sequence number.
  66. BYTE m_wSeqNum;
  67. // The message number the frame is part of
  68. BYTE m_bMsgNum;
  69. // The target of the frame
  70. PDVID m_pdvidTargets;
  71. DWORD m_dwNumTargets;
  72. DWORD m_dwMaxTargets;
  73. bool m_fOwned;
  74. // A flag to specify that this frame contains nothing but silence.
  75. // When this flag is set, the data in the frame buffer should not
  76. // be used - it's probably not valid.
  77. BYTE m_bIsSilence;
  78. // A pointer to the frame's data
  79. BYTE* m_pbData;
  80. // If this frame is part of a managed frame pool, this
  81. // member will be non-null.
  82. CFramePool* m_pFramePool;
  83. // If this frame is part of a managed frame pool, this
  84. // points to the "primary" pointer to this frame.
  85. // When the frame is unlocked, and therefore returned
  86. // to the pool, the pointer this member points to will
  87. // be set to null. This action is protected by the
  88. // critical section passed to the class.
  89. CFrame** m_ppfrPrimary;
  90. // A flag to indicate if this frame was "lost". This is
  91. // used to distinguish the silent frames pulled from the
  92. // queue between messages from the dead space caused by
  93. // a known lost packet.
  94. bool m_fIsLost;
  95. // don't allow copy construction or assignment of these
  96. // structures, as this would kill our performance, and
  97. // we don't want to do it by accident
  98. CFrame(const CFrame& fr);
  99. CFrame& operator=(const CFrame& fr);
  100. public:
  101. // This constructor sets all the frame's info, and allocates
  102. // the data buffer, but does not set the data inside the buffer
  103. // to anything. Defaults are provided for all the parameters
  104. // except for the frame size. Note: no default constructor,
  105. // since you must specify the frame size.
  106. CFrame(WORD wFrameSize,
  107. WORD wClientNum = 0,
  108. BYTE wSeqNum = 0,
  109. BYTE bMsgNum = 0,
  110. BYTE bIsSilence = 0,
  111. CFramePool *pFramePool = NULL,
  112. DNCRITICAL_SECTION* pCriticalSection = NULL,
  113. CFrame** ppfrPrimary = NULL);
  114. // A frame which manages user ownded memory
  115. CFrame();
  116. // The destructor cleans up the memory allocated by the
  117. // constructor
  118. ~CFrame();
  119. inline DWORD GetNumTargets() const { return m_dwNumTargets; };
  120. inline const PDVID const GetTargetList() const { return m_pdvidTargets; };
  121. // Length of the data within the buffer
  122. WORD GetFrameLength() const { return m_wFrameLength; }
  123. // returns the frame size, (the length of the data buffer)
  124. WORD GetFrameSize() const { return m_wFrameSize; }
  125. HRESULT SetEqual( const CFrame &frSourceFrame );
  126. // These are just a bunch of set and get functions for
  127. // the simple parts of the class, the client id, the
  128. // sequence number, the silence flag, etc.
  129. HRESULT SetTargets( PDVID pdvidTargets, DWORD dwNumTargets );
  130. BYTE GetMsgNum() const { return m_bMsgNum; }
  131. void SetMsgNum( BYTE msgNum ) { m_bMsgNum = msgNum; }
  132. void SetClientId(WORD wClientId) { m_wClientId = wClientId; }
  133. WORD GetClientId() const { return m_wClientId; }
  134. void SetSeqNum(BYTE wSeqNum) { m_wSeqNum = wSeqNum; }
  135. BYTE GetSeqNum() const { return m_wSeqNum; }
  136. void SetIsSilence(BYTE bIsSilence) { m_bIsSilence = bIsSilence; }
  137. void SetFrameLength(const WORD &length) { m_wFrameLength = length; }
  138. BYTE GetIsSilence() const { return m_bIsSilence; }
  139. bool GetIsLost() const { return m_fIsLost; }
  140. void SetIsLost(bool fIsLost) { m_fIsLost = fIsLost; }
  141. // Now we have the functions which handle the data. This
  142. // class is pretty trusting, because it will give out the
  143. // pointer to it's data. This is to avoid all non-required
  144. // buffer copies. For example, when you hand a buffer to
  145. // a wave in function, you can give it the pointer to this
  146. // buffer, and it will fill in the frame's buffer directly.
  147. // Between this function and the GetFrameSize() and
  148. // GetFrameLength() functions, you can do anything you want
  149. // with the buffer.
  150. BYTE* GetDataPointer() const { return m_pbData; }
  151. // This copies the data from another frame into this frame
  152. void CopyData(const CFrame& fr)
  153. {
  154. memcpy(m_pbData, fr.GetDataPointer(), fr.GetFrameLength() );
  155. m_wFrameLength = fr.GetFrameLength();
  156. }
  157. void UserOwn_SetData( BYTE *pbData, DWORD dwLength )
  158. {
  159. m_pbData = pbData;
  160. m_wFrameLength = dwLength;
  161. m_wFrameSize = dwLength;
  162. }
  163. void UserOwn_SetTargets( PDVID pdvidTargets, DWORD dwNumTargets )
  164. {
  165. m_pdvidTargets = pdvidTargets;
  166. m_dwNumTargets = dwNumTargets;
  167. m_dwMaxTargets = dwNumTargets;
  168. }
  169. // This copies data from a buffer into this frame's
  170. // buffer.
  171. void CopyData(const BYTE* pbData, WORD wFrameLength);
  172. // If this frame is part of a frame pool managed by a
  173. // CFramePool object, then call this function when you
  174. // are done with the frame and want to return it to the
  175. // pool.
  176. void Return();
  177. void SetCriticalSection(DNCRITICAL_SECTION* pCrit) { m_pCriticalSection = pCrit; }
  178. void SetPrimaryPointer(CFrame** ppfrPrimary) { m_ppfrPrimary = ppfrPrimary; }
  179. void SetFramePool(CFramePool* pFramePool) { m_pFramePool = pFramePool; }
  180. };
  181. // This class manages a pool of frames, to reduce memory requirements.
  182. // Only a few buffers are actually in use at any time by the queue
  183. // class, and yet it may have to allocate hundreds of them unless
  184. // a class such as this is used to manage their reuse.
  185. volatile class CFramePool
  186. {
  187. private:
  188. // the pool is simply a vector of frame objects
  189. std::vector<CFrame *> m_vpfrPool;
  190. // All the frames in the pool must be the same size,
  191. // which is stored here.
  192. WORD m_wFrameSize;
  193. // This critical section is used to exclude the Get()
  194. // and return members from each other.
  195. DNCRITICAL_SECTION m_lock;
  196. BOOL m_fCritSecInited;
  197. public:
  198. // Each frame pool manages frames of a certain size,
  199. // so they can be easily reused. If you need multiple
  200. // different frame sizes, you'll need more than one
  201. // frame pool.
  202. CFramePool(WORD wFrameSize);
  203. ~CFramePool();
  204. BOOL Init()
  205. {
  206. if (DNInitializeCriticalSection( &m_lock ))
  207. {
  208. m_fCritSecInited = TRUE;
  209. return TRUE;
  210. }
  211. else
  212. {
  213. return FALSE;
  214. }
  215. }
  216. // Use Get to retrieve a frame from the pool. ppfrPrimary
  217. // is a pointer to a point that you want set to null when
  218. // this frame is returned to the pool. pCriticalSection
  219. // points to a critical section that will be entered before
  220. // setting the pointer to null, and left after setting the
  221. // pointer to null. This is so external classes (such as
  222. // CInnerQueue) can pass in a critical section that they also
  223. // use to before examining the pointer referred to by ppfrPrimary
  224. CFrame* Get(DNCRITICAL_SECTION* pCriticalSection, CFrame** ppfrPrimary);
  225. // Call Return to give a frame back to the frame pool.
  226. // This may set a pointer to null and enter a critical
  227. // section, as described in Get() above.
  228. void Return(CFrame* pFrame);
  229. };
  230. #endif /* _FRAME_H_ */