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.

438 lines
10 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <objbase.h>
  4. #include <qos.h>
  5. #include <mmsystem.h>
  6. #include "ibitmap.h"
  7. #include "ividpool.h"
  8. #include "vidpool.h"
  9. #include <confdbg.h>
  10. #include <avutil.h>
  11. #include "..\nac\utils.h"
  12. #ifdef DEBUG
  13. extern "C" BOOL g_pooldebug = TRUE;
  14. #endif
  15. STDMETHODIMP
  16. CBitmap::QueryInterface(
  17. REFIID riid,
  18. LPVOID * ppvObj
  19. )
  20. {
  21. if (riid == IID_IUnknown || riid == IID_IBitmapSurface)
  22. *ppvObj = (IBitmapSurface*)this;
  23. else
  24. {
  25. *ppvObj = 0;
  26. return E_NOINTERFACE;
  27. }
  28. ((IUnknown*)*ppvObj)->AddRef();
  29. return NOERROR;
  30. }
  31. STDMETHODIMP_(ULONG)
  32. CBitmap::AddRef(
  33. void
  34. )
  35. {
  36. FX_ENTRY("CBitmap::AddRef");
  37. DEBUGMSG(ZONE_NMCAP_REFCOUNT,("%s: refcnt+(0x%08lX [CBitmap])=%d\r\n", _fx_, this, m_cRef+1));
  38. return InterlockedIncrement(&m_cRef)+1; // make sure that we return something > 0
  39. }
  40. STDMETHODIMP_(ULONG)
  41. CBitmap::Release(
  42. void
  43. )
  44. {
  45. LONG res;
  46. FX_ENTRY("CBitmap::Release");
  47. DEBUGMSG(ZONE_NMCAP_REFCOUNT,("%s: refcnt-(0x%08lX [CBitmap])=%d\r\n", _fx_, this, m_cRef-1));
  48. res = InterlockedDecrement(&m_cRef);
  49. if (res == 0) {
  50. if (m_factory) {
  51. m_factory->AddToFreeList(this);
  52. }
  53. else {
  54. if (!m_ext)
  55. LocalFree((HANDLE)m_bits);
  56. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: released (0x%08lX [CBitmap]) from vidpool (0x%08lX [m_factory])\r\n", _fx_, this, m_factory));
  57. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: deleting (0x%08lX [CBitmap])\r\n", _fx_, this));
  58. delete this;
  59. }
  60. }
  61. return res;
  62. }
  63. STDMETHODIMP
  64. CBitmap::Clone(
  65. IBitmapSurface** ppBitmapSurface
  66. )
  67. {
  68. return E_NOTIMPL;
  69. }
  70. STDMETHODIMP
  71. CBitmap::GetFormat(
  72. BFID* pBFID
  73. )
  74. {
  75. *pBFID = *(m_factory->GetFormat());
  76. return NOERROR;
  77. }
  78. STDMETHODIMP
  79. CBitmap::GetFactory(
  80. IBitmapSurfaceFactory** ppBitmapSurfaceFactory
  81. )
  82. {
  83. *ppBitmapSurfaceFactory = (IBitmapSurfaceFactory*)m_factory;
  84. m_factory->AddRef();
  85. return NOERROR;
  86. }
  87. STDMETHODIMP
  88. CBitmap::GetSize(
  89. long* pWidth,
  90. long* pHeight
  91. )
  92. {
  93. *pWidth = m_factory->GetWidth();
  94. *pHeight = m_factory->GetHeight();
  95. return NOERROR;
  96. }
  97. STDMETHODIMP
  98. CBitmap::LockBits(
  99. RECT* prcBounds,
  100. DWORD dwLockFlags,
  101. void** ppBits,
  102. long* pPitch
  103. )
  104. {
  105. if (!prcBounds) {
  106. *ppBits = m_bits;
  107. *pPitch = m_pitch;
  108. m_lockcount++;
  109. return NO_ERROR;
  110. }
  111. return E_NOTIMPL;
  112. }
  113. STDMETHODIMP
  114. CBitmap::UnlockBits(
  115. RECT* prcBounds,
  116. void* pBits
  117. )
  118. {
  119. if (!prcBounds && pBits == m_bits) {
  120. m_lockcount--;
  121. return NO_ERROR;
  122. }
  123. return E_NOTIMPL;
  124. }
  125. CVidPool::CVidPool(void)
  126. {
  127. m_cRef = 0;
  128. m_growable = FALSE;
  129. m_nbufs = 0;
  130. m_free = NULL;
  131. m_pitch = 0;
  132. ZeroMemory(&m_format, sizeof(BFID));
  133. InitializeCriticalSection(&m_cs);
  134. m_pAddingToFree = NULL;
  135. }
  136. STDMETHODIMP
  137. CVidPool::QueryInterface(
  138. REFIID riid,
  139. LPVOID * ppvObj
  140. )
  141. {
  142. if (riid == IID_IUnknown || riid == IID_IBitmapSurfaceFactory)
  143. *ppvObj = (IBitmapSurfaceFactory*)this;
  144. else
  145. {
  146. *ppvObj = 0;
  147. return E_NOINTERFACE;
  148. }
  149. ((IUnknown*)*ppvObj)->AddRef();
  150. return NOERROR;
  151. }
  152. STDMETHODIMP_(ULONG)
  153. CVidPool::AddRef(
  154. void
  155. )
  156. {
  157. FX_ENTRY("CVidPool::AddRef");
  158. DEBUGMSG(ZONE_NMCAP_REFCOUNT,("%s: refcnt+(0x%08lX [CVidPool])=%d\r\n", _fx_, this, m_cRef+1));
  159. return InterlockedIncrement(&m_cRef);
  160. }
  161. STDMETHODIMP_(ULONG)
  162. CVidPool::Release(
  163. void
  164. )
  165. {
  166. CBitmap* pbs;
  167. FX_ENTRY("CVidPool::Release");
  168. DEBUGMSG(ZONE_NMCAP_REFCOUNT,("%s: refcnt-(0x%08lX [CVidPool])=%d\r\n", _fx_, this, m_cRef-1));
  169. if (InterlockedDecrement(&m_cRef) == 0) {
  170. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: freeing (0x%08lX [CVidPool])\r\n", _fx_, this));
  171. EnterCriticalSection(&m_cs);
  172. while (m_free) {
  173. pbs = m_free->m_next;
  174. m_free->AddRef(); // ref the buffer so that release will cause a delete
  175. m_free->Release(); // this will cause the buffer to be deleted
  176. m_free = pbs;
  177. #ifdef DEBUG
  178. m_nbufs--;
  179. #endif
  180. }
  181. LeaveCriticalSection(&m_cs);
  182. LocalFree((HANDLE)m_pbmh);
  183. DeleteCriticalSection(&m_cs);
  184. // Buffers not all released
  185. ASSERT(!m_nbufs);
  186. delete this;
  187. return 0;
  188. }
  189. return m_cRef;
  190. }
  191. STDMETHODIMP
  192. CVidPool::CreateBitmapSurface(
  193. long width,
  194. long height,
  195. BFID* pBFID,
  196. DWORD dwHintFlags,
  197. IBitmapSurface** ppBitmapSurface
  198. )
  199. {
  200. return E_NOTIMPL;
  201. }
  202. STDMETHODIMP
  203. CVidPool::GetSupportedFormatsCount(
  204. long* pcFormats
  205. )
  206. {
  207. return E_NOTIMPL;
  208. }
  209. STDMETHODIMP
  210. CVidPool::GetSupportedFormats(
  211. long cFormats,
  212. BFID* pBFIDs
  213. )
  214. {
  215. return E_NOTIMPL;
  216. }
  217. STDMETHODIMP
  218. CVidPool::InitPool(
  219. int nBuffers,
  220. LPBITMAPINFOHEADER lpcap
  221. )
  222. {
  223. CBitmap* pbs;
  224. void *pbuf;
  225. FX_ENTRY("CVidPool::InitPool");
  226. if (m_pbmh = (LPBITMAPINFOHEADER)LocalAlloc(LPTR, lpcap->biSize)) {
  227. CopyMemory(m_pbmh, lpcap, lpcap->biSize);
  228. if (lpcap->biCompression == BI_RGB) {
  229. m_pitch = lpcap->biWidth*lpcap->biBitCount/8;
  230. switch (lpcap->biBitCount) {
  231. case 1:
  232. m_format = (BFID*)&BFID_MONOCHROME;
  233. break;
  234. case 4:
  235. m_format = (BFID*)&BFID_RGB_4;
  236. break;
  237. case 8:
  238. m_format = (BFID*)&BFID_RGB_8;
  239. break;
  240. case 16:
  241. m_format = (BFID*)&BFID_RGB_555;
  242. break;
  243. case 24:
  244. m_format = (BFID*)&BFID_RGB_24;
  245. break;
  246. case 32:
  247. m_format = (BFID*)&BFID_RGB_32;
  248. }
  249. }
  250. else {
  251. m_format = (BFID*)&BFID_PRIVATEDIB;
  252. m_pitch = 1;
  253. }
  254. for (m_nbufs = 0; m_nbufs < nBuffers; m_nbufs++) {
  255. if (pbuf = LocalAlloc(LMEM_FIXED, lpcap->biSizeImage)) {
  256. if (pbs = new CBitmap) {
  257. // pbs->AddRef(); - don't AddRef, we want inpool objects to be 0 based
  258. pbs->m_bits = (LPBYTE)pbuf;
  259. pbs->m_pitch = m_pitch;
  260. EnterCriticalSection(&m_cs);
  261. pbs->m_next = m_free;
  262. m_free = pbs;
  263. LeaveCriticalSection(&m_cs);
  264. }
  265. else {
  266. LocalFree((HANDLE)pbuf);
  267. break;
  268. }
  269. }
  270. else
  271. break;
  272. }
  273. if (m_nbufs == nBuffers) {
  274. m_growable = (nBuffers > 0);
  275. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: init vidpool (0x%08lX [CVidPool])\r\n", _fx_, this));
  276. return NO_ERROR;
  277. }
  278. EnterCriticalSection(&m_cs);
  279. while (m_free) {
  280. pbs = m_free->m_next;
  281. m_free->Release();
  282. m_free = pbs;
  283. }
  284. LeaveCriticalSection(&m_cs);
  285. }
  286. return E_OUTOFMEMORY;
  287. }
  288. STDMETHODIMP
  289. CVidPool::AddExternalBuffer(
  290. void* pBits,
  291. void* refdata
  292. )
  293. {
  294. CBitmap* pbs;
  295. FX_ENTRY("CVidPool::AddExternalBuffer");
  296. if (pbs = new CBitmap) {
  297. // pbs->AddRef(); - don't AddRef, because we want inpool objects to be 0 based
  298. pbs->m_bits = (LPBYTE)pBits;
  299. pbs->m_pitch = m_pitch;
  300. pbs->m_ext = TRUE;
  301. EnterCriticalSection(&m_cs);
  302. pbs->m_next = m_free;
  303. pbs->m_refdata = refdata;
  304. m_free = pbs;
  305. m_nbufs++;
  306. LeaveCriticalSection(&m_cs);
  307. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: added bitmap (0x%08lX [CBitmap]) to vidpool (0x%08lX [CVidPool])\r\n", _fx_, pbs, this));
  308. }
  309. return E_OUTOFMEMORY;
  310. }
  311. STDMETHODIMP
  312. CVidPool::GetBuffer(
  313. CBitmap** ppBitmap,
  314. void** prefdata
  315. )
  316. {
  317. CBitmap* pbs = NULL;
  318. void *pbuf;
  319. FX_ENTRY("CVidPool::GetBuffer");
  320. if (ppBitmap) {
  321. if (prefdata)
  322. *prefdata = NULL;
  323. EnterCriticalSection(&m_cs);
  324. if (pbs = m_free) {
  325. m_free = pbs->m_next;
  326. LeaveCriticalSection(&m_cs);
  327. }
  328. else {
  329. LeaveCriticalSection(&m_cs);
  330. if (m_growable) {
  331. if (pbuf = LocalAlloc(LMEM_FIXED, m_pbmh->biSizeImage)) {
  332. if (pbs = new CBitmap) {
  333. pbs->m_bits = (LPBYTE)pbuf;
  334. pbs->m_pitch = m_pitch;
  335. pbs->m_next = m_free;
  336. m_nbufs++;
  337. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: grew vidpool (0x%08lX [CVidPool]) to %d with cbitmap (0x%08lX [CBitmap])\r\n", _fx_, this, m_nbufs, pbs));
  338. }
  339. else
  340. LocalFree((HANDLE)pbuf);
  341. }
  342. }
  343. }
  344. if (*ppBitmap = pbs) {
  345. pbs->m_factory = this;
  346. AddRef();
  347. pbs->AddRef();
  348. if (prefdata)
  349. *prefdata = pbs->m_refdata;
  350. return NO_ERROR;
  351. }
  352. else
  353. return E_OUTOFMEMORY;
  354. }
  355. return E_INVALIDARG;
  356. }
  357. STDMETHODIMP
  358. CVidPool::GetBuffer(
  359. IBitmapSurface** ppBitmap,
  360. void** prefdata
  361. )
  362. {
  363. CBitmap* pbs = NULL;
  364. GetBuffer (&pbs, prefdata);
  365. *ppBitmap = (IBitmapSurface*)pbs;
  366. return NO_ERROR;
  367. }
  368. void
  369. CVidPool::AddToFreeList(
  370. CBitmap* pBitmap
  371. )
  372. {
  373. FX_ENTRY("CVidPool::AddToFreeList");
  374. DEBUGMSG(ZONE_NMCAP_CDTOR,("%s: queuing cbitmap (0x%08lX [CBitmap]) to vidpool (0x%08lX [CVidPool])\r\n", _fx_, pBitmap, this));
  375. // notify pool creator, if interested
  376. if (m_pAddingToFree)
  377. m_pAddingToFree(pBitmap, m_refdata);
  378. EnterCriticalSection(&m_cs);
  379. pBitmap->m_next = m_free;
  380. m_free = pBitmap;
  381. LeaveCriticalSection(&m_cs);
  382. pBitmap->m_factory = NULL;
  383. Release();
  384. }