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.

475 lines
12 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dvcsplay.cpp
  6. * Content: Implementation of CDVCSPlayer class
  7. * History:
  8. * Date By Reason
  9. * ============
  10. * 07/22/99 rodtoll created
  11. * 10/05/99 rodtoll Added comments, dpf's.
  12. * 10/29/99 rodtoll Bug #113726 - Integrate Voxware Codecs, updating to use new
  13. * pluggable codec architecture.
  14. * 01/14/2000 rodtoll Updated to support multiple targets
  15. * 03/28/2000 rodtoll Updated to use new player class as base
  16. * rodtoll Moved a bunch of logic out of server into this class
  17. * 11/16/2000 rodtoll Bug #40587 - DPVOICE: Mixing server needs to use multi-processors
  18. * 09/05/2001 simonpow Bug #463972. Added constuct/destruct methods to enable
  19. * allocations and de-allocations via CFixedPool objects
  20. * 02/28/2002 rodtoll WINBUG #549959 - SECURITY: DPVOICE: Voice server trusts client's target list
  21. * - When server controlled targetting is enabled, use server's copy of client
  22. * target list instead of list specified in incoming packet.
  23. * - Fixed crashed caused by updated bilink code.
  24. ***************************************************************************/
  25. #include "dxvoicepch.h"
  26. #undef DPF_MODNAME
  27. #define DPF_MODNAME "CDVCSPlayer::Construct"
  28. BOOL CDVCSPlayer::PoolAllocFunction(void * pvItem, void * pvContext)
  29. {
  30. ((CDVCSPlayer * ) pvItem)->CDVCSPlayer::CDVCSPlayer();
  31. return TRUE;
  32. }
  33. #undef DPF_MODNAME
  34. #define DPF_MODNAME "CDVCSPlayer::Destruct"
  35. void CDVCSPlayer::PoolDeallocFunction(void * pvItem)
  36. {
  37. ((CDVCSPlayer * ) pvItem)->CDVCSPlayer::~CDVCSPlayer();
  38. }
  39. CDVCSPlayer::CDVCSPlayer()
  40. :CVoicePlayer()
  41. {
  42. m_lpOutBoundAudioConverter=NULL;
  43. m_bLastSent=NULL;
  44. m_bMsgNum=(BYTE)-1;
  45. m_bSeqNum=0;
  46. m_targetSize=0;
  47. m_pblMixingActivePlayers=NULL;
  48. m_pblMixingSpeakingPlayers=NULL;
  49. m_pblMixingHearingPlayers=NULL;
  50. m_pdwHearCount=NULL;
  51. m_pfDecompressed=NULL;
  52. m_pfSilence=NULL;
  53. m_pfNeedsDecompression=NULL;
  54. m_pppCanHear=NULL;
  55. m_pdwMaxCanHear=NULL;
  56. m_pSourceFrame=NULL;
  57. m_sourceUnCompressed=NULL;
  58. m_targetCompressed=NULL;
  59. m_pfMixed=NULL;
  60. m_dwNumMixingThreads=0;
  61. m_pbMsgNumToSend=NULL;
  62. m_pbSeqNumToSend=NULL;
  63. m_pdwResultLength=NULL;
  64. m_pfMixToBeReused=NULL;
  65. }
  66. CDVCSPlayer::~CDVCSPlayer()
  67. {
  68. //this space intentionally left blank
  69. }
  70. #undef DPF_MODNAME
  71. #define DPF_MODNAME "CDVCSPlayer::ComparePlayerMix"
  72. //
  73. // ComparePlayerMix
  74. //
  75. // Compares the mix of one player to the mix of another.
  76. //
  77. BOOL CDVCSPlayer::ComparePlayerMix( DWORD dwThreadIndex, const CDVCSPlayer *lpdvPlayer )
  78. {
  79. DNASSERT( lpdvPlayer != NULL );
  80. if( lpdvPlayer->m_pdwHearCount[dwThreadIndex] != m_pdwHearCount[dwThreadIndex] )
  81. {
  82. return FALSE;
  83. }
  84. for( int index = 0; index < m_pdwHearCount[dwThreadIndex]; index++ )
  85. {
  86. if( lpdvPlayer->m_pppCanHear[dwThreadIndex][index] != m_pppCanHear[dwThreadIndex][index] )
  87. {
  88. return FALSE;
  89. }
  90. }
  91. return TRUE;
  92. }
  93. #undef DPF_MODNAME
  94. #define DPF_MODNAME "CDVCSPlayer::CompleteRun"
  95. void CDVCSPlayer::CompleteRun( DWORD dwThreadIndex )
  96. {
  97. if( m_pSourceFrame[dwThreadIndex] )
  98. {
  99. m_pSourceFrame[dwThreadIndex]->Return();
  100. m_pSourceFrame[dwThreadIndex] = NULL;
  101. }
  102. }
  103. #undef DPF_MODNAME
  104. #define DPF_MODNAME "CDVCSPlayer::ResetForNextRun"
  105. void CDVCSPlayer::ResetForNextRun( DWORD dwThreadIndex, BOOL fDequeue )
  106. {
  107. BOOL fLostFrame;
  108. m_pdwHearCount[dwThreadIndex] = 0;
  109. m_pfSilence[dwThreadIndex] = FALSE;
  110. m_pReuseMixFromThisPlayer[dwThreadIndex] = NULL;
  111. if( !fDequeue )
  112. {
  113. m_pSourceFrame[dwThreadIndex] = NULL;
  114. }
  115. else
  116. {
  117. DNASSERT( !m_pSourceFrame[dwThreadIndex] );
  118. m_pSourceFrame[dwThreadIndex] = Dequeue(&fLostFrame, &m_pfSilence[dwThreadIndex]);
  119. }
  120. m_pfMixed[dwThreadIndex] = FALSE;
  121. m_pfNeedsDecompression[dwThreadIndex] = FALSE;
  122. m_pfDecompressed[dwThreadIndex] = FALSE;
  123. m_pfMixToBeReused[dwThreadIndex] = FALSE;
  124. m_pdwResultLength[dwThreadIndex] = NULL;
  125. RemoveFromHearingList(dwThreadIndex);
  126. RemoveFromSpeakingList(dwThreadIndex);
  127. }
  128. #undef DPF_MODNAME
  129. #define DPF_MODNAME "CDVCSPlayer::Initialize"
  130. HRESULT CDVCSPlayer::Initialize( const DVID dvidPlayer, const DWORD dwHostOrder, DWORD dwFlags, PVOID pvContext,
  131. DWORD dwCompressedSize, DWORD dwUnCompressedSize,
  132. CFixedPool *pCSOwner,
  133. DWORD dwNumMixingThreads )
  134. {
  135. HRESULT hr;
  136. DWORD dwIndex;
  137. m_pCSOwner = pCSOwner;
  138. hr = CVoicePlayer::Initialize( dvidPlayer, dwHostOrder, dwFlags, pvContext, NULL );
  139. if( FAILED( hr ) )
  140. {
  141. DPFX(DPFPREP, 0, "Initialize failed on player hr=0x%x", hr );
  142. return hr;
  143. }
  144. m_pdwHearCount = new DWORD[dwNumMixingThreads];
  145. m_pfSilence = new BOOL[dwNumMixingThreads];
  146. m_pdwMaxCanHear = new DWORD[dwNumMixingThreads];
  147. m_pSourceFrame = new CFrame*[dwNumMixingThreads];
  148. m_pfMixed = new BOOL[dwNumMixingThreads];
  149. m_pblMixingActivePlayers = new CBilinkPlusObject[dwNumMixingThreads];
  150. m_pblMixingHearingPlayers = new CBilinkPlusObject[dwNumMixingThreads];
  151. m_pblMixingSpeakingPlayers = new CBilinkPlusObject[dwNumMixingThreads];
  152. m_sourceUnCompressed = new BYTE[dwNumMixingThreads*dwUnCompressedSize];
  153. m_targetCompressed = new BYTE[dwNumMixingThreads*dwCompressedSize];
  154. m_pfNeedsDecompression = new BOOL[dwNumMixingThreads];
  155. m_pfDecompressed = new BOOL[dwNumMixingThreads];
  156. m_dwNumMixingThreads = dwNumMixingThreads;
  157. m_pbMsgNumToSend = new BYTE[dwNumMixingThreads];
  158. m_pbSeqNumToSend = new BYTE[dwNumMixingThreads];
  159. m_pdwUnCompressedBufferOffset = new DWORD[dwNumMixingThreads];
  160. m_pdwCompressedBufferOffset = new DWORD[dwNumMixingThreads];
  161. m_pReuseMixFromThisPlayer = new CDVCSPlayer*[dwNumMixingThreads];
  162. m_pdwResultLength = new DWORD[dwNumMixingThreads];
  163. m_pfMixToBeReused = new BOOL[dwNumMixingThreads];
  164. if( !m_pblMixingActivePlayers || !m_pdwHearCount || !m_pfSilence ||
  165. !m_pdwMaxCanHear || !m_pSourceFrame || !m_sourceUnCompressed ||
  166. !m_targetCompressed || !m_pfMixed || !m_pfNeedsDecompression ||
  167. !m_pfDecompressed || !m_pbMsgNumToSend || !m_pbSeqNumToSend ||
  168. !m_pdwUnCompressedBufferOffset || !m_pdwCompressedBufferOffset ||
  169. !m_pReuseMixFromThisPlayer || !m_pdwResultLength || !m_pfMixToBeReused ||
  170. !m_pblMixingHearingPlayers || !m_pblMixingSpeakingPlayers )
  171. {
  172. DPFX(DPFPREP, 0, "Memory alloc failure" );
  173. hr = DVERR_OUTOFMEMORY;
  174. goto INITIALIZE_FAILURE;
  175. }
  176. // Create the Can Hear arrays
  177. m_pppCanHear = new CDVCSPlayer**[dwNumMixingThreads];
  178. ZeroMemory( m_pppCanHear, sizeof(CDVCSPlayer*)*dwNumMixingThreads );
  179. // Resize canhear arrays and setup compressed/uncompressed offsets
  180. for( dwIndex = 0; dwIndex < dwNumMixingThreads; dwIndex++ )
  181. {
  182. m_pdwUnCompressedBufferOffset[dwIndex] = dwIndex * dwUnCompressedSize;
  183. m_pdwCompressedBufferOffset[dwIndex] = dwIndex * dwCompressedSize;
  184. m_pSourceFrame[dwIndex] = 0;
  185. m_pdwMaxCanHear[dwIndex] = 0;
  186. m_pblMixingActivePlayers[dwIndex].m_pPlayer = this;
  187. m_pblMixingActivePlayers[dwIndex].m_bl.Initialize();
  188. m_pblMixingSpeakingPlayers[dwIndex].m_pPlayer = this;
  189. m_pblMixingSpeakingPlayers[dwIndex].m_bl.Initialize();
  190. m_pblMixingHearingPlayers[dwIndex].m_pPlayer = this;
  191. m_pblMixingHearingPlayers[dwIndex].m_bl.Initialize();
  192. ResetForNextRun(dwIndex,FALSE);
  193. hr = ResizeIfRequired(dwIndex,1);
  194. if( FAILED( hr ) )
  195. {
  196. DPFX(DPFPREP, 0, "Error resizing target array hr=0x%x", hr );
  197. goto INITIALIZE_FAILURE;
  198. }
  199. }
  200. return hr;
  201. INITIALIZE_FAILURE:
  202. DeInitialize();
  203. return hr;
  204. }
  205. #undef DPF_MODNAME
  206. #define DPF_MODNAME "CDVCSPlayer::DeInitialize"
  207. HRESULT CDVCSPlayer::DeInitialize()
  208. {
  209. DWORD dwIndex;
  210. if( m_pblMixingActivePlayers )
  211. {
  212. #ifdef DEBUG
  213. for( dwIndex = 0; dwIndex < m_dwNumMixingThreads; dwIndex++ )
  214. {
  215. DNASSERT( m_pblMixingActivePlayers[dwIndex].m_bl.IsEmpty() );
  216. DNASSERT( !m_pSourceFrame[dwIndex] );
  217. }
  218. #endif
  219. delete [] m_pblMixingActivePlayers;
  220. m_pblMixingActivePlayers = NULL;
  221. }
  222. if( m_pblMixingSpeakingPlayers )
  223. {
  224. for( dwIndex = 0; dwIndex < m_dwNumMixingThreads; dwIndex++ )
  225. {
  226. this->RemoveFromSpeakingList( dwIndex );
  227. }
  228. delete [] m_pblMixingSpeakingPlayers;
  229. m_pblMixingSpeakingPlayers = NULL;
  230. }
  231. if( m_pblMixingHearingPlayers )
  232. {
  233. for( dwIndex = 0; dwIndex < m_dwNumMixingThreads; dwIndex++ )
  234. {
  235. this->RemoveFromHearingList( dwIndex );
  236. }
  237. delete [] m_pblMixingHearingPlayers;
  238. m_pblMixingHearingPlayers = NULL;
  239. }
  240. if( m_lpOutBoundAudioConverter )
  241. {
  242. m_lpOutBoundAudioConverter->Release();
  243. m_lpOutBoundAudioConverter = NULL;
  244. }
  245. if( m_pppCanHear )
  246. {
  247. for( dwIndex = 0; dwIndex < m_dwNumMixingThreads; dwIndex++ )
  248. {
  249. if( m_pppCanHear[dwIndex] )
  250. {
  251. delete [] m_pppCanHear[dwIndex];
  252. m_pppCanHear[dwIndex] = NULL;
  253. }
  254. }
  255. delete [] m_pppCanHear;
  256. m_pppCanHear = NULL;
  257. }
  258. if( m_pdwHearCount )
  259. {
  260. delete [] m_pdwHearCount;
  261. m_pdwHearCount = NULL;
  262. }
  263. if( m_pdwResultLength )
  264. {
  265. delete [] m_pdwResultLength;
  266. m_pdwResultLength = NULL;
  267. }
  268. if( m_pfSilence )
  269. {
  270. delete [] m_pfSilence;
  271. m_pfSilence = NULL;
  272. }
  273. if( m_pdwUnCompressedBufferOffset )
  274. {
  275. delete [] m_pdwUnCompressedBufferOffset;
  276. m_pdwUnCompressedBufferOffset = NULL;
  277. }
  278. if( m_pReuseMixFromThisPlayer )
  279. {
  280. delete [] m_pReuseMixFromThisPlayer;
  281. m_pReuseMixFromThisPlayer = NULL;
  282. }
  283. if( m_pdwCompressedBufferOffset )
  284. {
  285. delete [] m_pdwCompressedBufferOffset;
  286. m_pdwCompressedBufferOffset = NULL;
  287. }
  288. if( m_pdwMaxCanHear )
  289. {
  290. delete [] m_pdwMaxCanHear;
  291. m_pdwMaxCanHear = NULL;
  292. }
  293. if( m_sourceUnCompressed )
  294. {
  295. delete [] m_sourceUnCompressed;
  296. m_sourceUnCompressed = NULL;
  297. }
  298. if( m_pfMixToBeReused )
  299. {
  300. delete [] m_pfMixToBeReused;
  301. m_pfMixToBeReused = NULL;
  302. }
  303. if( m_pbMsgNumToSend )
  304. {
  305. delete [] m_pbMsgNumToSend;
  306. m_pbMsgNumToSend = NULL;
  307. }
  308. if( m_pbSeqNumToSend )
  309. {
  310. delete [] m_pbSeqNumToSend;
  311. m_pbSeqNumToSend = NULL;
  312. }
  313. if( m_targetCompressed )
  314. {
  315. delete [] m_targetCompressed;
  316. m_targetCompressed = NULL;
  317. }
  318. if( m_pfMixed )
  319. {
  320. delete [] m_pfMixed;
  321. m_pfMixed = NULL;
  322. }
  323. if( m_pfNeedsDecompression )
  324. {
  325. delete [] m_pfNeedsDecompression;
  326. m_pfNeedsDecompression = NULL;
  327. }
  328. if( m_pfDecompressed )
  329. {
  330. delete [] m_pfDecompressed;
  331. m_pfDecompressed = NULL;
  332. }
  333. if( m_pSourceFrame )
  334. {
  335. delete [] m_pSourceFrame;
  336. m_pSourceFrame = NULL;
  337. }
  338. FreeResources();
  339. m_pCSOwner->Release( this );
  340. return DV_OK;
  341. }
  342. #undef DPF_MODNAME
  343. #define DPF_MODNAME "CDVCSPlayer::HandleMixingReceive"
  344. HRESULT CDVCSPlayer::HandleMixingReceive(
  345. PDVPROTOCOLMSG_SPEECHHEADER pdvSpeechHeader, PBYTE pbData,
  346. DWORD dwSize, PDVID pdvidTargets, DWORD dwNumTargets,
  347. BOOL fServerTargetting )
  348. {
  349. CFrame tmpFrame;
  350. tmpFrame.SetSeqNum( pdvSpeechHeader->bSeqNum );
  351. tmpFrame.SetMsgNum( pdvSpeechHeader->bMsgNum );
  352. tmpFrame.SetIsSilence( FALSE );
  353. tmpFrame.SetFrameLength( dwSize );
  354. tmpFrame.UserOwn_SetData( pbData, dwSize );
  355. Lock();
  356. // If the server is controlling the targets, take targets for the speech
  357. // packet from the local user record instead of the packet. Prevents
  358. // clients from being hacked to get around client-side targetting.
  359. //
  360. if( fServerTargetting )
  361. tmpFrame.UserOwn_SetTargets( GetTargetList(), GetNumTargets() );
  362. else
  363. tmpFrame.UserOwn_SetTargets( pdvidTargets, dwNumTargets );
  364. // STATSBLOCK: Begin
  365. //m_pStatsBlob->m_dwPRESpeech++;
  366. // STATSBLOCK: End
  367. m_lpInputQueue->Enqueue( tmpFrame );
  368. m_dwLastData = GetTickCount();
  369. DPFX(DPFPREP, DVF_MIXER_DEBUG_LEVEL, "Received speech is buffered!" );
  370. m_dwNumReceivedFrames++;
  371. UnLock();
  372. return DV_OK;
  373. }
  374. #undef DPF_MODNAME
  375. #define DPF_MODNAME "CDVCSPlayer::CompressOutBound"
  376. HRESULT CDVCSPlayer::CompressOutBound( PVOID pvInputBuffer, DWORD dwInputBufferSize, PVOID pvOutputBuffer, DWORD *pdwOutputSize )
  377. {
  378. HRESULT hr;
  379. hr = m_lpOutBoundAudioConverter->Convert( pvInputBuffer, dwInputBufferSize, pvOutputBuffer, pdwOutputSize, FALSE );
  380. if( FAILED( hr ) )
  381. {
  382. DPFX(DPFPREP, 0, "Failed converting audio hr=0x%x", hr );
  383. return hr;
  384. }
  385. return hr;
  386. }