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.

667 lines
18 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dpvaconv.cpp
  6. * Content: Header file for DirectPlayVoice compression provider (ACM)
  7. *
  8. * History:
  9. * Date By Reason
  10. * =========== =========== ====================
  11. * 10/27/99 rodtoll created
  12. * 02/03/2000 rodtoll Bug #130397 - Prefix detected memory leak
  13. * 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
  14. * 04/02/2001 simonpow Fixes for PREfast bugs #354859 (unitialised variables)
  15. * 06/27/2001 rodtoll RC2: DPVOICE: DPVACM's DllMain calls into acm -- potential hang
  16. * Move global initialization to first object creation
  17. ***************************************************************************/
  18. #include "dpvacmpch.h"
  19. #undef DPF_MODNAME
  20. #define DPF_MODNAME "CDPVACMConv::CDPVACMConv"
  21. CDPVACMConv::CDPVACMConv(
  22. ): m_fDirectConvert(FALSE), m_fValid(FALSE),
  23. m_pbInnerBuffer(NULL),m_dwInnerBufferSize(0),
  24. m_lRefCount(0), m_hacmSource(NULL),
  25. m_hacmTarget(NULL), m_pdvfci(NULL),
  26. m_fCritSecInited(FALSE)
  27. {
  28. }
  29. #undef DPF_MODNAME
  30. #define DPF_MODNAME "CDPVACMConv::InitClass"
  31. BOOL CDPVACMConv::InitClass( )
  32. {
  33. if (DNInitializeCriticalSection( &m_csLock ))
  34. {
  35. m_fCritSecInited = TRUE;
  36. return TRUE;
  37. }
  38. else
  39. {
  40. return FALSE;
  41. }
  42. }
  43. #undef DPF_MODNAME
  44. #define DPF_MODNAME "CDPVACMConv::~CDPVACMConv"
  45. CDPVACMConv::~CDPVACMConv()
  46. {
  47. if (m_fCritSecInited)
  48. {
  49. DNDeleteCriticalSection( &m_csLock );
  50. }
  51. if( m_pdvfci != NULL )
  52. {
  53. LPBYTE pTmp = (LPBYTE) m_pdvfci;
  54. delete [] pTmp;
  55. }
  56. if( m_pbInnerBuffer != NULL )
  57. {
  58. delete [] m_pbInnerBuffer;
  59. }
  60. if( m_hacmSource != NULL )
  61. {
  62. acmStreamClose( m_hacmSource, 0 );
  63. }
  64. if( m_hacmTarget != NULL )
  65. {
  66. acmStreamClose( m_hacmTarget, 0 );
  67. }
  68. }
  69. #undef DPF_MODNAME
  70. #define DPF_MODNAME "CDPVACMConv::I_QueryInterface"
  71. HRESULT CDPVACMConv::I_QueryInterface( DPVACMCONVOBJECT *This, REFIID riid, PVOID *ppvObj )
  72. {
  73. HRESULT hr = S_OK;
  74. if( ppvObj == NULL ||
  75. !DNVALID_WRITEPTR( ppvObj, sizeof(LPVOID) ) )
  76. {
  77. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer passed for object" );
  78. return DVERR_INVALIDPOINTER;
  79. }
  80. *ppvObj=NULL;
  81. DNEnterCriticalSection( &This->pObject->m_csLock );
  82. // hmmm, switch would be cleaner...
  83. if( IsEqualIID(riid, IID_IUnknown) ||
  84. IsEqualIID(riid, IID_IDPVConverter ) )
  85. {
  86. *ppvObj = This;
  87. This->pObject->I_AddRef( This );
  88. }
  89. else
  90. {
  91. hr = E_NOINTERFACE;
  92. }
  93. DNLeaveCriticalSection( &This->pObject->m_csLock );
  94. return hr;
  95. }
  96. #undef DPF_MODNAME
  97. #define DPF_MODNAME "CDPVACMConv::I_AddRef"
  98. HRESULT CDPVACMConv::I_AddRef( DPVACMCONVOBJECT *This )
  99. {
  100. LONG rc;
  101. DNEnterCriticalSection( &This->pObject->m_csLock );
  102. rc = ++This->pObject->m_lRefCount;
  103. DNLeaveCriticalSection( &This->pObject->m_csLock );
  104. return rc;
  105. }
  106. #undef DPF_MODNAME
  107. #define DPF_MODNAME "CDPVACMConv::I_Release"
  108. HRESULT CDPVACMConv::I_Release( DPVACMCONVOBJECT *This )
  109. {
  110. LONG rc;
  111. DNEnterCriticalSection( &This->pObject->m_csLock );
  112. rc = --This->pObject->m_lRefCount;
  113. if( rc == 0 )
  114. {
  115. DPFX(DPFPREP, DVF_INFOLEVEL, "Destroying object" );
  116. DNLeaveCriticalSection( &This->pObject->m_csLock );
  117. delete This->pObject;
  118. delete This;
  119. DecrementObjectCount();
  120. }
  121. else
  122. {
  123. DNLeaveCriticalSection( &This->pObject->m_csLock );
  124. }
  125. return rc;
  126. }
  127. #undef DPF_MODNAME
  128. #define DPF_MODNAME "CDPVACMConv::I_InitDeCompress"
  129. HRESULT CDPVACMConv::I_InitDeCompress( DPVACMCONVOBJECT *This, GUID guidSourceCT, LPWAVEFORMATEX lpwfxTargetFormat )
  130. {
  131. return This->pObject->InitDeCompress( guidSourceCT, lpwfxTargetFormat );
  132. }
  133. #undef DPF_MODNAME
  134. #define DPF_MODNAME "CDPVACMConv::InitDeCompress"
  135. HRESULT CDPVACMConv::InitDeCompress( GUID guidSourceCT, LPWAVEFORMATEX lpwfxTargetFormat )
  136. {
  137. HRESULT hr;
  138. DNEnterCriticalSection( &m_csLock );
  139. if( m_fValid )
  140. {
  141. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object already initialized" );
  142. DNLeaveCriticalSection( &m_csLock );
  143. return DVERR_INITIALIZED;
  144. }
  145. hr = GetCompressionInfo( guidSourceCT );
  146. if( FAILED( hr ) )
  147. {
  148. DPFX(DPFPREP, DVF_ERRORLEVEL, "GetCTInfo Failed hr=0x%x", hr );
  149. DNLeaveCriticalSection( &m_csLock );
  150. return hr;
  151. }
  152. hr = Initialize( m_pdvfci->lpwfxFormat, lpwfxTargetFormat, lpwfxTargetFormat );
  153. if( FAILED( hr ) )
  154. {
  155. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to init ct, hr = 0x%x", hr );
  156. delete [] m_pdvfci;
  157. m_pdvfci = NULL;
  158. DNLeaveCriticalSection( &m_csLock );
  159. return hr;
  160. }
  161. DNLeaveCriticalSection( &m_csLock );
  162. return DV_OK;
  163. }
  164. #undef DPF_MODNAME
  165. #define DPF_MODNAME "CDPVACMConv::GetCompressionInfo"
  166. HRESULT CDPVACMConv::GetCompressionInfo( GUID guidCT )
  167. {
  168. DWORD dwSize = 0;
  169. HRESULT hr;
  170. LPBYTE pBuffer = NULL;
  171. hr = CDPVCPI::GetCompressionInfo( NULL, guidCT, pBuffer, &dwSize );
  172. if( hr != DVERR_BUFFERTOOSMALL )
  173. {
  174. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error retrieving ct info, hr =0x%x", hr );
  175. return hr;
  176. }
  177. pBuffer = new BYTE[dwSize];
  178. if( pBuffer == NULL )
  179. {
  180. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error allocating memory" );
  181. return DVERR_OUTOFMEMORY;
  182. }
  183. hr = CDPVCPI::GetCompressionInfo( NULL, guidCT, pBuffer, &dwSize );
  184. if( FAILED( hr ) )
  185. {
  186. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error retrieving ct info after buff, hr =0x%x", hr );
  187. delete [] pBuffer;
  188. return hr;
  189. }
  190. m_pdvfci = (LPDVFULLCOMPRESSIONINFO) pBuffer;
  191. return DV_OK;
  192. }
  193. #undef DPF_MODNAME
  194. #define DPF_MODNAME "CDPVACMConv::I_InitCompress"
  195. HRESULT CDPVACMConv::I_InitCompress( DPVACMCONVOBJECT *This, LPWAVEFORMATEX lpwfxSourceFormat, GUID guidTargetCT )
  196. {
  197. return This->pObject->InitCompress( lpwfxSourceFormat, guidTargetCT );
  198. }
  199. #undef DPF_MODNAME
  200. #define DPF_MODNAME "CDPVACMConv::InitCompress"
  201. HRESULT CDPVACMConv::InitCompress( LPWAVEFORMATEX lpwfxSourceFormat, GUID guidTargetCT )
  202. {
  203. HRESULT hr;
  204. DNEnterCriticalSection( &m_csLock );
  205. if( m_fValid )
  206. {
  207. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object already initialized" );
  208. DNLeaveCriticalSection( &m_csLock );
  209. return DVERR_INITIALIZED;
  210. }
  211. hr = GetCompressionInfo( guidTargetCT );
  212. if( FAILED( hr ) )
  213. {
  214. DPFX(DPFPREP, DVF_ERRORLEVEL, "GetCTInfo Failed hr=0x%x", hr );
  215. DNLeaveCriticalSection( &m_csLock );
  216. return hr;
  217. }
  218. hr = Initialize( lpwfxSourceFormat, m_pdvfci->lpwfxFormat, lpwfxSourceFormat );
  219. if( FAILED( hr ) )
  220. {
  221. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to init ct, hr = 0x%x", hr );
  222. delete [] m_pdvfci;
  223. m_pdvfci = NULL;
  224. DNLeaveCriticalSection( &m_csLock );
  225. return hr;
  226. }
  227. DNLeaveCriticalSection( &m_csLock );
  228. return DV_OK;
  229. }
  230. #undef DPF_MODNAME
  231. #define DPF_MODNAME "CDPVACMConv::I_IsValid"
  232. HRESULT CDPVACMConv::I_IsValid( DPVACMCONVOBJECT *This, LPBOOL pfValid )
  233. {
  234. DNEnterCriticalSection( &This->pObject->m_csLock );
  235. *pfValid = This->pObject->m_fValid;
  236. DNLeaveCriticalSection( &This->pObject->m_csLock );
  237. return DV_OK;
  238. }
  239. #undef DPF_MODNAME
  240. #define DPF_MODNAME "CDPVACMConv::I_GetUnCompressedFrameSize"
  241. HRESULT CDPVACMConv::I_GetUnCompressedFrameSize( DPVACMCONVOBJECT *This, LPDWORD lpdwFrameSize )
  242. {
  243. DNEnterCriticalSection( &This->pObject->m_csLock );
  244. if( !This->pObject->m_fValid )
  245. {
  246. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object not initialized" );
  247. DNLeaveCriticalSection( &This->pObject->m_csLock );
  248. return DVERR_NOTINITIALIZED;
  249. }
  250. *lpdwFrameSize = This->pObject->m_dwUnCompressedFrameSize;
  251. DNLeaveCriticalSection( &This->pObject->m_csLock );
  252. return DV_OK;
  253. }
  254. #undef DPF_MODNAME
  255. #define DPF_MODNAME "CDPVACMConv::I_GetCompressedFrameSize"
  256. HRESULT CDPVACMConv::I_GetCompressedFrameSize( DPVACMCONVOBJECT *This, LPDWORD lpdwCompressedSize )
  257. {
  258. DNEnterCriticalSection( &This->pObject->m_csLock );
  259. if( !This->pObject->m_fValid )
  260. {
  261. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object not initialized" );
  262. DNLeaveCriticalSection( &This->pObject->m_csLock );
  263. return DVERR_NOTINITIALIZED;
  264. }
  265. *lpdwCompressedSize = This->pObject->m_dwCompressedFrameSize;
  266. DNLeaveCriticalSection( &This->pObject->m_csLock );
  267. return DV_OK;
  268. }
  269. #undef DPF_MODNAME
  270. #define DPF_MODNAME "CDPVACMConv::I_GetNumFramesPerBuffer"
  271. HRESULT CDPVACMConv::I_GetNumFramesPerBuffer( DPVACMCONVOBJECT *This, LPDWORD lpdwFramesPerBuffer )
  272. {
  273. DNEnterCriticalSection( &This->pObject->m_csLock );
  274. if( !This->pObject->m_fValid )
  275. {
  276. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object not initialized" );
  277. DNLeaveCriticalSection( &This->pObject->m_csLock );
  278. return DVERR_NOTINITIALIZED;
  279. }
  280. *lpdwFramesPerBuffer = This->pObject->m_dwNumFramesPerBuffer;
  281. DNLeaveCriticalSection( &This->pObject->m_csLock );
  282. return DV_OK;
  283. }
  284. #undef DPF_MODNAME
  285. #define DPF_MODNAME "CDPVACMConv::I_Convert"
  286. HRESULT CDPVACMConv::I_Convert( DPVACMCONVOBJECT *This, LPVOID lpInputBuffer, DWORD dwInputSize, LPVOID lpOutputBuffer, LPDWORD lpdwOutputSize, BOOL fSilence )
  287. {
  288. return This->pObject->Convert( lpInputBuffer, dwInputSize, lpOutputBuffer, lpdwOutputSize, fSilence );
  289. }
  290. #undef DPF_MODNAME
  291. #define DPF_MODNAME "CDPVACMConv::Convert"
  292. HRESULT CDPVACMConv::Convert( LPVOID lpInputBuffer, DWORD dwInputSize, LPVOID lpOutputBuffer, LPDWORD lpdwOutputSize, BOOL fSilence )
  293. {
  294. DWORD dwLengthUsed; // Used for storing tmp length values
  295. HRESULT hr;
  296. DNEnterCriticalSection( &m_csLock );
  297. if( !m_fValid )
  298. {
  299. DPFX(DPFPREP, DVF_ERRORLEVEL, "Object not initialized" );
  300. DNLeaveCriticalSection( &m_csLock );
  301. return DVERR_NOTINITIALIZED;
  302. }
  303. if( fSilence )
  304. {
  305. memset( lpOutputBuffer, m_fTargetEightBit ? 0x80 : 0x00, *lpdwOutputSize );
  306. DNLeaveCriticalSection( &m_csLock );
  307. return true;
  308. }
  309. if( m_fDirectConvert )
  310. {
  311. // Setup the acm function
  312. memset( &m_ashSource, 0, sizeof( ACMSTREAMHEADER ) );
  313. m_ashSource.cbStruct = sizeof( ACMSTREAMHEADER );
  314. m_ashSource.fdwStatus = 0;
  315. m_ashSource.dwUser = 0;
  316. m_ashSource.cbSrcLength = dwInputSize;
  317. m_ashSource.pbSrc = (LPBYTE) lpInputBuffer;
  318. m_ashSource.cbSrcLengthUsed = 0;
  319. m_ashSource.dwSrcUser = 0;
  320. m_ashSource.pbDst = (LPBYTE) lpOutputBuffer;
  321. m_ashSource.cbDstLength = *lpdwOutputSize;
  322. m_ashSource.cbDstLengthUsed = 0;
  323. m_ashSource.dwDstUser = 0;
  324. // Prepare the header for conversion
  325. hr = acmStreamPrepareHeader( m_hacmSource, &m_ashSource , 0);
  326. if( FAILED( hr ) )
  327. {
  328. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to prepare heade hr=0x%x", hr );
  329. DNLeaveCriticalSection( &m_csLock );
  330. return hr;
  331. }
  332. // Convert the data
  333. hr = acmStreamConvert( m_hacmSource, &m_ashSource, ACM_STREAMCONVERTF_BLOCKALIGN );
  334. if( FAILED( hr ) )
  335. {
  336. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to perform the conversion hr=0x%x", hr );
  337. DNLeaveCriticalSection( &m_csLock );
  338. return hr;
  339. }
  340. hr = acmStreamUnprepareHeader( m_hacmSource, &m_ashSource, 0 );
  341. if( FAILED( hr ) )
  342. {
  343. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to perform the conversion hr=0x%x", hr );
  344. DNLeaveCriticalSection( &m_csLock );
  345. return hr;
  346. }
  347. dwLengthUsed = m_ashSource.cbDstLengthUsed;
  348. }
  349. else
  350. {
  351. // Setup the acm header for conversion fro mthe source to the
  352. // inner format
  353. memset( &m_ashSource, 0, sizeof( ACMSTREAMHEADER ) );
  354. m_ashSource.cbStruct = sizeof( ACMSTREAMHEADER );
  355. m_ashSource.fdwStatus = 0;
  356. m_ashSource.dwUser = 0;
  357. m_ashSource.cbSrcLength = dwInputSize;
  358. m_ashSource.pbSrc = (LPBYTE) lpInputBuffer;
  359. m_ashSource.cbSrcLengthUsed = 0;
  360. m_ashSource.dwSrcUser = 0;
  361. m_ashSource.pbDst = m_pbInnerBuffer;
  362. m_ashSource.cbDstLength = m_dwInnerBufferSize;
  363. m_ashSource.cbDstLengthUsed = 0;
  364. m_ashSource.dwDstUser = 0;
  365. // Prepare the header for conversion
  366. hr = acmStreamPrepareHeader( m_hacmSource, &m_ashSource , 0);
  367. if( FAILED( hr ) )
  368. {
  369. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to prepare first stage header hr=0x%x", hr );
  370. DNLeaveCriticalSection( &m_csLock );
  371. return hr;
  372. }
  373. // Convert the data
  374. hr = acmStreamConvert( m_hacmSource, &m_ashSource, ACM_STREAMCONVERTF_BLOCKALIGN );
  375. if( FAILED( hr ) )
  376. {
  377. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to convert first stage hr=0x%x", hr );
  378. DNLeaveCriticalSection( &m_csLock );
  379. return hr;
  380. }
  381. hr = acmStreamUnprepareHeader( m_hacmSource, &m_ashSource, 0 );
  382. if( FAILED( hr ) )
  383. {
  384. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to unprepare first stage header hr=0x%x", hr );
  385. DNLeaveCriticalSection( &m_csLock );
  386. return hr;
  387. }
  388. DPFX(DPFPREP, DVF_INFOLEVEL, "CONVERTER: Filling in %d bytes", m_dwInnerBufferSize - m_ashSource.cbDstLengthUsed );
  389. memset( &m_ashTarget, 0, sizeof( ACMSTREAMHEADER ) );
  390. m_ashTarget.cbStruct = sizeof( ACMSTREAMHEADER );
  391. m_ashTarget.fdwStatus = 0;
  392. m_ashTarget.dwUser = 0;
  393. m_ashTarget.cbSrcLength = m_dwInnerBufferSize;
  394. m_ashTarget.pbSrc = m_pbInnerBuffer;
  395. m_ashTarget.cbSrcLengthUsed = 0;
  396. m_ashTarget.dwSrcUser = 0;
  397. m_ashTarget.pbDst = (LPBYTE) lpOutputBuffer;
  398. m_ashTarget.cbDstLength = *lpdwOutputSize;
  399. m_ashTarget.cbDstLengthUsed = 0;
  400. m_ashTarget.dwDstUser = 0;
  401. // Prepare the header for conversion
  402. hr = acmStreamPrepareHeader( m_hacmTarget, &m_ashTarget , 0);
  403. if( FAILED( hr ) )
  404. {
  405. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to prepare second stage header hr=0x%x", hr );
  406. DNLeaveCriticalSection( &m_csLock );
  407. return hr;
  408. }
  409. // Convert the data
  410. hr = acmStreamConvert( m_hacmTarget, &m_ashTarget, ACM_STREAMCONVERTF_BLOCKALIGN );
  411. if( FAILED( hr ) )
  412. {
  413. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to convert second stage hr=0x%x", hr );
  414. DNLeaveCriticalSection( &m_csLock );
  415. return hr;
  416. }
  417. hr = acmStreamUnprepareHeader( m_hacmTarget, &m_ashTarget, 0 );
  418. if( FAILED( hr ) )
  419. {
  420. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to unprepare second stage header hr=0x%x", hr );
  421. DNLeaveCriticalSection( &m_csLock );
  422. return hr;
  423. }
  424. dwLengthUsed = m_ashTarget.cbDstLengthUsed;
  425. }
  426. DWORD offset = *lpdwOutputSize - dwLengthUsed;
  427. if( offset > 0 )
  428. {
  429. LPBYTE lpbTmp = (LPBYTE) lpOutputBuffer;
  430. // memset( &lpbTmp[*lpdwOutputSize - offset], (m_fTargetEightBit) ? 0x80 : 0x00, offset );
  431. memset( &lpbTmp[*lpdwOutputSize - offset], lpbTmp[*lpdwOutputSize - offset-1], offset );
  432. }
  433. DNLeaveCriticalSection( &m_csLock );
  434. // Always return the right length
  435. return DV_OK;
  436. }
  437. #undef DPF_MODNAME
  438. #define DPF_MODNAME "CDPVACMConv::Initialize"
  439. HRESULT CDPVACMConv::Initialize( WAVEFORMATEX *pwfSrcFormat, WAVEFORMATEX *pwfTargetFormat, const WAVEFORMATEX *pwfUnCompressedFormat )
  440. {
  441. HRESULT retValue;
  442. // Attempt the conversion directly
  443. retValue = acmStreamOpen( &m_hacmSource, NULL, pwfSrcFormat, pwfTargetFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME );
  444. // If it's not possible, we'll have to do a two step conversion
  445. if( retValue == static_cast<HRESULT>(ACMERR_NOTPOSSIBLE) )
  446. {
  447. retValue = acmStreamOpen( &m_hacmSource, NULL, pwfSrcFormat, &CDPVACMI::s_wfxInnerFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME );
  448. if( FAILED( retValue ) )
  449. {
  450. DPFX(DPFPREP, DVF_ERRORLEVEL, "Source compressor failed init hr=0x%x", retValue );
  451. goto INITIALIZE_ERROR;
  452. }
  453. retValue = acmStreamOpen( &m_hacmTarget, NULL, &CDPVACMI::s_wfxInnerFormat, pwfTargetFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME );
  454. if( FAILED( retValue ) )
  455. {
  456. DPFX(DPFPREP, DVF_ERRORLEVEL, "Target compressor failed init hr=0x%x", retValue );
  457. goto INITIALIZE_ERROR;
  458. }
  459. m_fDirectConvert = FALSE;
  460. }
  461. // Still not possible
  462. else if( retValue != static_cast<HRESULT >(0))
  463. {
  464. DPFX(DPFPREP, DVF_ERRORLEVEL, "Compressor create error hr=0x%x", retValue );
  465. goto INITIALIZE_ERROR;
  466. }
  467. // Direct conversion was possible
  468. else
  469. {
  470. m_fDirectConvert = TRUE;
  471. }
  472. // If we're not direct converting, create an inner conversion
  473. // buffer
  474. if( !m_fDirectConvert )
  475. {
  476. m_dwInnerBufferSize = CalcUnCompressedFrameSize( &CDPVACMI::s_wfxInnerFormat );
  477. m_pbInnerBuffer = new BYTE[m_dwInnerBufferSize];
  478. if( m_pbInnerBuffer == NULL )
  479. {
  480. acmStreamClose( m_hacmSource, 0 );
  481. acmStreamClose( m_hacmTarget, 0 );
  482. m_fValid = FALSE;
  483. retValue = DVERR_OUTOFMEMORY;
  484. }
  485. }
  486. else
  487. {
  488. m_pbInnerBuffer = NULL;
  489. m_dwInnerBufferSize = 0;
  490. }
  491. m_dwUnCompressedFrameSize = CalcUnCompressedFrameSize( pwfUnCompressedFormat );
  492. m_dwCompressedFrameSize = m_pdvfci->dwFrameLength;
  493. m_dwNumFramesPerBuffer = m_pdvfci->dwFramesPerBuffer;
  494. if( pwfTargetFormat->wBitsPerSample == 8 )
  495. {
  496. m_fTargetEightBit = TRUE;
  497. }
  498. else
  499. {
  500. m_fTargetEightBit = FALSE;
  501. }
  502. m_fValid = TRUE;
  503. return DV_OK;
  504. INITIALIZE_ERROR:
  505. if( m_hacmSource != NULL )
  506. acmStreamClose( m_hacmSource, 0 );
  507. if( m_hacmTarget != NULL )
  508. acmStreamClose( m_hacmTarget, 0 );
  509. if( m_pbInnerBuffer != NULL )
  510. delete [] m_pbInnerBuffer;
  511. m_fValid = FALSE;
  512. return retValue;
  513. }
  514. #undef DPF_MODNAME
  515. #define DPF_MODNAME "CDPVACMConv::CalcUnCompressedFrameSize"
  516. DWORD CDPVACMConv::CalcUnCompressedFrameSize( const WAVEFORMATEX* lpwfxFormat ) const
  517. {
  518. DWORD frameSize;
  519. switch( lpwfxFormat->nSamplesPerSec )
  520. {
  521. case 8000: frameSize = m_pdvfci->dwFrame8Khz; break;
  522. case 11025: frameSize = m_pdvfci->dwFrame11Khz; break;
  523. case 22050: frameSize = m_pdvfci->dwFrame22Khz; break;
  524. case 44100: frameSize = m_pdvfci->dwFrame44Khz; break;
  525. default: return 0;
  526. }
  527. if( lpwfxFormat->wBitsPerSample == 16 )
  528. frameSize *= 2;
  529. frameSize *= lpwfxFormat->nChannels;
  530. return frameSize;
  531. }