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.

346 lines
9.8 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 - 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: vplayer.h
  6. * Content: Voice Player Entry
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 03/26/00 rodtoll Created
  12. * 03/29/2000 rodtoll Bug #30753 - Added volatile to the class definition
  13. * 07/09/2000 rodtoll Added signature bytes
  14. * 11/28/2000 rodtoll Bug #47333 - DPVOICE: Server controlled targetting - invalid targets are not removed automatically
  15. * 09/05/2001 simonpow Bug #463972. Added constuct/destruct methods to enable
  16. * allocations and de-allocations via CFixedPool objects
  17. * 02/21/2002 simonpow Bug #549974. Added rate control for incoming speech pkts
  18. ***************************************************************************/
  19. #ifndef __VPLAYER_H
  20. #define __VPLAYER_H
  21. #define VOICEPLAYER_FLAGS_DISCONNECTED 0x00000001 // Player has disconnected
  22. #define VOICEPLAYER_FLAGS_INITIALIZED 0x00000002 // Player is initialized
  23. #define VOICEPLAYER_FLAGS_ISRECEIVING 0x00000004 // Player is currently receiving audio
  24. #define VOICEPLAYER_FLAGS_ISSERVERPLAYER 0x00000008 // Player is the server player
  25. #define VOICEPLAYER_FLAGS_TARGETIS8BIT 0x00000010 // Is the target 8-bit?
  26. #define VOICEPLAYER_FLAGS_ISAVAILABLE 0x00000020 // Is player available
  27. //defines the maximum number of speech packets that
  28. //can be received in a single speech packet bucket. Together
  29. //with the VOICEPLAYER_SPEECHPKTS_BUCKET_WIDTH value below this
  30. //defines the maximum rate speech packets can be received at
  31. #define VOICEPLAYER_MAX_SPEECHPKTS_BUCKET 40ul
  32. //defines how 'wide' (in msec) each bucket is when calculating
  33. //a maximum rate for receiving speech packets.
  34. //For example, a 1000 msec value means we count the number of
  35. //packets over each second, and when it exceeds the value
  36. //VOICEPLAYER_MAX_SPEECHPKTS_BUCKET we return false for any
  37. //new speech packets in the remainder of that second
  38. #define VOICEPLAYER_SPEECHPKTS_BUCKET_WIDTH 1000ul
  39. typedef struct _VOICEPLAYER_STATISTICS
  40. {
  41. DWORD dwNumSilentFrames;
  42. DWORD dwNumSpeechFrames;
  43. DWORD dwNumReceivedFrames;
  44. DWORD dwNumLostFrames;
  45. QUEUE_STATISTICS queueStats;
  46. } VOICEPLAYER_STATISTICS, *PVOICEPLAYER_STATISTICS;
  47. #define VSIG_VOICEPLAYER 'YLPV'
  48. #define VSIG_VOICEPLAYER_FREE 'YLP_'
  49. #define ASSERT_VPLAYER(pv) DNASSERT((pv != NULL) && (pv->m_dwSignature == VSIG_VOICEPLAYER))
  50. volatile class CVoicePlayer
  51. {
  52. public: // Init / destruct
  53. //called from CFixedPool class to to build/destroy CVoicePlayer's
  54. static BOOL PoolAllocFunction(void * pvItem, void * pvContext);
  55. static void PoolDeallocFunction(void * pvItem);
  56. HRESULT Initialize( const DVID dvidPlayer, const DWORD dwHostOrder, DWORD dwFlags,
  57. PVOID pvContext, CFixedPool *pOwner );
  58. HRESULT CreateQueue( PQUEUE_PARAMS pQueueParams );
  59. HRESULT CreateInBoundConverter( const GUID &guidCT, PWAVEFORMATEX pwfxTargetFormat );
  60. virtual HRESULT DeInitialize();
  61. void FreeResources();
  62. HRESULT SetPlayerTargets( PDVID pdvidTargets, DWORD dwNumTargets );
  63. BOOL FindAndRemovePlayerTarget( DVID dvidTargetToRemove );
  64. inline void AddRef()
  65. {
  66. InterlockedIncrement( &m_lRefCount );
  67. }
  68. inline void Release()
  69. {
  70. if( InterlockedDecrement( &m_lRefCount ) == 0 )
  71. {
  72. DeInitialize();
  73. }
  74. }
  75. public: // Speech Handling
  76. HRESULT HandleReceive( PDVPROTOCOLMSG_SPEECHHEADER pdvSpeechHeader, PBYTE pbData, DWORD dwSize );
  77. HRESULT GetNextFrameAndDecompress( PVOID pvBuffer, PDWORD pdwBufferSize, BOOL *pfLost, BOOL *pfSilence, DWORD *pdwSeqNum, DWORD *pdwMsgNum );
  78. HRESULT DeCompressInBound( CFrame *frCurrentFrame, PVOID pvBuffer, PDWORD pdwBufferSize );
  79. CFrame *Dequeue(BOOL *pfLost, BOOL *pfSilence);
  80. void GetStatistics( PVOICEPLAYER_STATISTICS pStats );
  81. inline DVID GetPlayerID() const
  82. {
  83. return m_dvidPlayer;
  84. }
  85. inline DWORD GetFlags() const
  86. {
  87. return m_dwFlags;
  88. }
  89. inline BOOL IsInBoundConverterInitialized() const
  90. {
  91. return (m_lpInBoundAudioConverter != NULL);
  92. }
  93. inline BOOL Is8BitUnCompressed() const
  94. {
  95. return (m_dwFlags & VOICEPLAYER_FLAGS_TARGETIS8BIT );
  96. }
  97. inline BOOL IsReceiving() const
  98. {
  99. return (m_dwFlags & VOICEPLAYER_FLAGS_ISRECEIVING);
  100. }
  101. inline void SetReceiving( const BOOL fReceiving )
  102. {
  103. Lock();
  104. if( fReceiving )
  105. m_dwFlags |= VOICEPLAYER_FLAGS_ISRECEIVING;
  106. else
  107. m_dwFlags &= ~VOICEPLAYER_FLAGS_ISRECEIVING;
  108. UnLock();
  109. }
  110. inline void SetAvailable( const BOOL fAvailable )
  111. {
  112. Lock();
  113. if( fAvailable )
  114. m_dwFlags |= VOICEPLAYER_FLAGS_ISAVAILABLE;
  115. else
  116. m_dwFlags &= ~VOICEPLAYER_FLAGS_ISAVAILABLE;
  117. UnLock();
  118. }
  119. inline BOOL IsAvailable() const
  120. {
  121. return (m_dwFlags & VOICEPLAYER_FLAGS_ISAVAILABLE);
  122. }
  123. inline BOOL IsInitialized() const
  124. {
  125. return (m_dwFlags & VOICEPLAYER_FLAGS_INITIALIZED);
  126. }
  127. inline BOOL IsServerPlayer() const
  128. {
  129. return (m_dwFlags & VOICEPLAYER_FLAGS_ISSERVERPLAYER);
  130. }
  131. inline void SetServerPlayer()
  132. {
  133. Lock();
  134. m_dwFlags |= VOICEPLAYER_FLAGS_ISSERVERPLAYER;
  135. UnLock();
  136. }
  137. inline BOOL IsDisconnected() const
  138. {
  139. return (m_dwFlags & VOICEPLAYER_FLAGS_DISCONNECTED);
  140. }
  141. inline void SetDisconnected()
  142. {
  143. Lock();
  144. m_dwFlags |= VOICEPLAYER_FLAGS_DISCONNECTED;
  145. UnLock();
  146. }
  147. inline void SetHostOrder( const DWORD dwHostOrder )
  148. {
  149. Lock();
  150. m_dwHostOrderID = dwHostOrder;
  151. UnLock();
  152. }
  153. inline DWORD GetHostOrder() const
  154. {
  155. return m_dwHostOrderID;
  156. }
  157. inline void Lock()
  158. {
  159. DNEnterCriticalSection( &m_csLock );
  160. }
  161. inline void UnLock()
  162. {
  163. DNLeaveCriticalSection( &m_csLock );
  164. }
  165. inline void *GetContext()
  166. {
  167. return m_pvPlayerContext;
  168. }
  169. inline void SetContext( void *pvContext )
  170. {
  171. Lock();
  172. m_pvPlayerContext = pvContext;
  173. UnLock();
  174. }
  175. inline BYTE GetLastPeak() const
  176. {
  177. return m_bLastPeak;
  178. }
  179. inline DWORD GetTransportFlags() const
  180. {
  181. return m_dwTransportFlags;
  182. }
  183. inline void AddToPlayList( CBilink *pblBilink )
  184. {
  185. m_blPlayList.InsertAfter( pblBilink );
  186. }
  187. inline void AddToNotifyList( CBilink *pblBilink )
  188. {
  189. m_blNotifyList.InsertAfter( pblBilink );
  190. }
  191. inline void RemoveFromNotifyList()
  192. {
  193. m_blNotifyList.RemoveFromList();
  194. }
  195. inline void RemoveFromPlayList()
  196. {
  197. m_blPlayList.RemoveFromList();
  198. }
  199. inline DWORD_PTR GetLastPlayback() const
  200. {
  201. return m_dwLastPlayback;
  202. }
  203. inline DWORD GetNumTargets() const
  204. {
  205. return m_dwNumTargets;
  206. }
  207. inline PDVID GetTargetList()
  208. {
  209. return m_pdvidTargets;
  210. }
  211. //returns true if receiving a speech packet at this point
  212. //in time would not exceed the allowable data rate
  213. //from this player (see #defs for pkt buckets at top of file
  214. //for defintion of allowable rate)
  215. inline BOOL ValidateSpeechPacketForDataRate();
  216. DWORD m_dwSignature;
  217. CBilink m_blNotifyList;
  218. CBilink m_blPlayList;
  219. protected:
  220. //protected to ensure all allocations done via fixed pool objects
  221. CVoicePlayer();
  222. virtual ~CVoicePlayer();
  223. virtual void Reset();
  224. PDVID m_pdvidTargets; // The player's current target
  225. DWORD m_dwNumTargets;
  226. DWORD m_dwTransportFlags;
  227. DWORD m_dwFlags;
  228. DWORD m_dwNumSilentFrames;
  229. DWORD m_dwNumSpeechFrames;
  230. DWORD m_dwNumReceivedFrames;
  231. DWORD m_dwNumLostFrames;
  232. DVID m_dvidPlayer; // Player's ID
  233. DWORD m_dwHostOrderID; // Host ORDER ID
  234. LONG m_lRefCount; // Reference count on the player
  235. PDPVCOMPRESSOR m_lpInBoundAudioConverter; // Converter for this player's audio
  236. CInputQueue2 *m_lpInputQueue; // Input queue for this player's audio
  237. PVOID m_pvPlayerContext;
  238. CFixedPool *m_pOwner;
  239. DWORD_PTR m_dwLastData; // GetTickCount() value when last data received
  240. DWORD_PTR m_dwLastPlayback; // GetTickCount() when last non-silence from this player
  241. DNCRITICAL_SECTION m_csLock;
  242. BYTE m_bLastPeak; // Last peak value for this player.
  243. //used to track the rate at which speech packets are being
  244. //received from this player.
  245. long m_lSpeechPktsInCurrentBucket;
  246. long m_lCurrentSpeechPktBucket;
  247. };
  248. /*
  249. * Inline methods from CVoicePlayer
  250. */
  251. #undef DPF_MODNAME
  252. #define DPF_MODNAME "CVoicePlayer::ValidateSpeechPacketForDataRate"
  253. BOOL CVoicePlayer::ValidateSpeechPacketForDataRate()
  254. {
  255. //calculate pkt bucket number
  256. long lPktBucket=(long ) (GETTIMESTAMP() / VOICEPLAYER_SPEECHPKTS_BUCKET_WIDTH);
  257. //if this packet falls into the current bucket then check
  258. //if we've reached our maximum limit for that bucket
  259. if (lPktBucket==m_lCurrentSpeechPktBucket)
  260. {
  261. if (m_lSpeechPktsInCurrentBucket==VOICEPLAYER_MAX_SPEECHPKTS_BUCKET)
  262. {
  263. //hit rate limit so don't validate this packet
  264. return FALSE;
  265. }
  266. //bucket isn't full yet so we can confirm packet is good to use
  267. InterlockedIncrement(&m_lSpeechPktsInCurrentBucket);
  268. return TRUE;
  269. }
  270. //new bucket, reset state to start filling it and confirm
  271. //this packet is good to use
  272. InterlockedExchange(&m_lSpeechPktsInCurrentBucket, 1);
  273. InterlockedExchange(&m_lCurrentSpeechPktBucket, lPktBucket);
  274. return TRUE;
  275. }
  276. #endif