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.

362 lines
9.3 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: VMRAllocator.cpp
  3. *
  4. *
  5. *
  6. *
  7. * Created: Tue 02/15/2000
  8. * Author: Stephen Estrop [StEstrop]
  9. *
  10. * Copyright (c) 2000 Microsoft Corporation
  11. \**************************************************************************/
  12. #include <streams.h>
  13. #include <dvdmedia.h>
  14. #include <windowsx.h>
  15. #include "VMRenderer.h"
  16. #if defined(CHECK_FOR_LEAKS)
  17. #include "ifleak.h"
  18. #endif
  19. /******************************Public*Routine******************************\
  20. * CVMRPinAllocator::CVMRPinAllocator
  21. *
  22. *
  23. *
  24. * History:
  25. * Fri 02/25/2000 - StEstrop - Created
  26. *
  27. \**************************************************************************/
  28. CVMRPinAllocator::CVMRPinAllocator(
  29. CVMRInputPin* pPin,
  30. CCritSec *pLock,
  31. HRESULT *phr
  32. ) :
  33. CBaseAllocator(NAME("Video Allocator"), NULL, phr, true, true),
  34. m_pPin(pPin),
  35. m_pInterfaceLock(pLock)
  36. {
  37. AMTRACE((TEXT("CVMRPinAllocator::CVMRPinAllocator")));
  38. }
  39. /******************************Public*Routine******************************\
  40. * NonDelegatingAddRef
  41. *
  42. * Overriden to increment the owning object's reference count
  43. *
  44. * History:
  45. * Fri 02/25/2000 - StEstrop - Created
  46. *
  47. \**************************************************************************/
  48. STDMETHODIMP_(ULONG)
  49. CVMRPinAllocator::NonDelegatingAddRef()
  50. {
  51. AMTRACE((TEXT("CVMRPinAllocator::NonDelegatingAddRef")));
  52. return m_pPin->AddRef();
  53. }
  54. /******************************Public*Routine******************************\
  55. * NonDelegatingQueryInterface
  56. *
  57. *
  58. *
  59. * History:
  60. * Thu 12/14/2000 - StEstrop - Created
  61. *
  62. \**************************************************************************/
  63. STDMETHODIMP
  64. CVMRPinAllocator::NonDelegatingQueryInterface(REFIID riid,VOID **ppv)
  65. {
  66. HRESULT hr = E_NOINTERFACE;
  67. *ppv = NULL;
  68. hr = CBaseAllocator::NonDelegatingQueryInterface(riid,ppv);
  69. #if defined(CHECK_FOR_LEAKS)
  70. if (hr == S_OK) {
  71. _pIFLeak->AddThunk((IUnknown **)ppv, "VMR Allocator Object", riid);
  72. }
  73. #endif
  74. return hr;
  75. }
  76. /******************************Public*Routine******************************\
  77. * NonDelegatingRelease
  78. *
  79. *
  80. *
  81. * History:
  82. * Fri 02/25/2000 - StEstrop - Created
  83. *
  84. \**************************************************************************/
  85. STDMETHODIMP_(ULONG)
  86. CVMRPinAllocator::NonDelegatingRelease()
  87. {
  88. AMTRACE((TEXT("CVMRPinAllocator::NonDelegatingRelease")));
  89. return m_pPin->Release();
  90. }
  91. /******************************Public*Routine******************************\
  92. * SetProperties
  93. *
  94. *
  95. *
  96. * History:
  97. * Fri 02/25/2000 - StEstrop - Created
  98. *
  99. \**************************************************************************/
  100. STDMETHODIMP
  101. CVMRPinAllocator::SetProperties(
  102. ALLOCATOR_PROPERTIES* pRequest,
  103. ALLOCATOR_PROPERTIES* pActual
  104. )
  105. {
  106. AMTRACE((TEXT("CVMRPinAllocator::SetProperties")));
  107. HRESULT hr = CBaseAllocator::SetProperties(pRequest, pActual);
  108. if (SUCCEEDED(hr)) {
  109. hr = m_pPin->OnSetProperties(pRequest, pActual);
  110. }
  111. else {
  112. DbgLog((LOG_ERROR, 1,
  113. TEXT("CBaseAllocator::SetProperties failed hr=%#X"), hr));
  114. }
  115. if (SUCCEEDED(hr)) {
  116. hr = m_pPin->m_pRenderer->OnSetProperties(m_pPin);
  117. }
  118. return hr;
  119. }
  120. /******************************Public*Routine******************************\
  121. * CVMRPinAllocator::GetBuffer
  122. *
  123. *
  124. *
  125. * History:
  126. * Fri 02/25/2000 - StEstrop - Created
  127. *
  128. \**************************************************************************/
  129. STDMETHODIMP
  130. CVMRPinAllocator::GetBuffer(
  131. IMediaSample **ppSample,
  132. REFERENCE_TIME *pStartTime,
  133. REFERENCE_TIME *pEndTime,
  134. DWORD dwFlags
  135. )
  136. {
  137. AMTRACE((TEXT("CVMRPinAllocator::GetBuffer")));
  138. HRESULT hr = S_OK;
  139. IMediaSample *pSample = NULL;
  140. hr = CBaseAllocator::GetBuffer(&pSample, pStartTime, pEndTime, dwFlags);
  141. DbgLog((LOG_TRACE, 2, TEXT("pSample= %#X"), pSample));
  142. if (SUCCEEDED(hr)) {
  143. hr = m_pPin->OnGetBuffer(pSample, pStartTime, pEndTime, dwFlags);
  144. if (FAILED(hr)) {
  145. DbgLog((LOG_ERROR, 1, TEXT("CVMRPin::OnGetBuffer failed hr= %#X"), hr));
  146. }
  147. }
  148. else {
  149. DbgLog((LOG_ERROR, 1, TEXT("CBaseAllocator::GetBuffer failed hr= %#X"), hr));
  150. }
  151. if (FAILED(hr) && pSample) {
  152. pSample->Release();
  153. pSample = NULL;
  154. }
  155. *ppSample = pSample;
  156. return hr;
  157. }
  158. /******************************Public*Routine******************************\
  159. * CVMRPinAllocator::ReleaseBuffer
  160. *
  161. *
  162. *
  163. * History:
  164. * Fri 02/25/2000 - StEstrop - Created
  165. *
  166. \**************************************************************************/
  167. STDMETHODIMP
  168. CVMRPinAllocator::ReleaseBuffer(
  169. IMediaSample *pMediaSample
  170. )
  171. {
  172. AMTRACE((TEXT("CVMRPinAllocator::ReleaseBuffer")));
  173. DbgLog((LOG_TRACE, 2, TEXT("pMediaSample= %#X"), pMediaSample));
  174. CVMRMediaSample* pVMRSample = (CVMRMediaSample*)pMediaSample;
  175. LPBYTE lpSample;
  176. HRESULT hr = S_OK;
  177. if (m_pPin->m_pVidSurfs) {
  178. CAutoLock l(&m_pPin->m_DeinterlaceLock);
  179. DWORD i = pVMRSample->GetIndex();
  180. m_pPin->m_pVidSurfs[i].InUse = FALSE;
  181. }
  182. if (S_OK == pVMRSample->IsSurfaceLocked()) {
  183. hr = pVMRSample->UnlockSurface();
  184. if (hr == DDERR_SURFACELOST) {
  185. hr = S_OK;
  186. }
  187. }
  188. if (SUCCEEDED(hr)) {
  189. // Copy of base class code - put at end of the list
  190. CheckPointer(pMediaSample, E_POINTER);
  191. ValidateReadPtr(pMediaSample, sizeof(IMediaSample));
  192. BOOL bRelease = FALSE;
  193. {
  194. CAutoLock cal(this);
  195. /* Put back on the free list */
  196. CMediaSample **ppTail;
  197. for (ppTail = &m_lFree.m_List; *ppTail;
  198. ppTail = &((CVMRMediaSample *)(*ppTail))->Next()) {
  199. }
  200. *ppTail = (CMediaSample *)pMediaSample;
  201. ((CVMRMediaSample *)pMediaSample)->Next() = NULL;
  202. m_lFree.m_nOnList++;
  203. if (m_lWaiting != 0) {
  204. NotifySample();
  205. }
  206. // if there is a pending Decommit, then we need to complete it by
  207. // calling Free() when the last buffer is placed on the free list
  208. LONG l1 = m_lFree.GetCount();
  209. if (m_bDecommitInProgress && (l1 == m_lAllocated)) {
  210. Free();
  211. m_bDecommitInProgress = FALSE;
  212. bRelease = TRUE;
  213. }
  214. }
  215. if (m_pNotify) {
  216. m_pNotify->NotifyRelease();
  217. }
  218. // For each buffer there is one AddRef, made in GetBuffer and released
  219. // here. This may cause the allocator and all samples to be deleted
  220. if (bRelease)
  221. {
  222. Release();
  223. }
  224. }
  225. return hr;
  226. }
  227. /******************************Public*Routine******************************\
  228. * CVMRPinAllocator::Alloc
  229. *
  230. *
  231. *
  232. * History:
  233. * Fri 02/25/2000 - StEstrop - Created
  234. *
  235. \**************************************************************************/
  236. HRESULT
  237. CVMRPinAllocator::Alloc()
  238. {
  239. AMTRACE((TEXT("CVMRPinAllocator::Alloc")));
  240. ASSERT(m_lAllocated == 0);
  241. HRESULT hr = S_OK;
  242. CVMRMediaSample** ppSampleList = NULL;
  243. LONG lToAllocate;
  244. lToAllocate = m_lCount;
  245. if (m_pPin->m_dwBackBufferCount > 1) {
  246. lToAllocate++;
  247. }
  248. ppSampleList = new CVMRMediaSample*[lToAllocate];
  249. if (!ppSampleList) {
  250. DbgLog((LOG_ERROR, 1, TEXT("new failed - trying to allocate %d bytes"), lToAllocate));
  251. return E_OUTOFMEMORY;
  252. }
  253. for (LONG i = 0; i < lToAllocate; i++) {
  254. ppSampleList[i] = new CVMRMediaSample(TEXT("VMRMediaSample"),
  255. this, &hr, NULL, 0);
  256. if (!ppSampleList[i]) {
  257. DbgLog((LOG_ERROR, 1, TEXT("new failed - trying to allocate %d bytes"),
  258. sizeof(CVMRMediaSample)));
  259. DbgLog((LOG_ERROR, 1, TEXT("new failed")));
  260. for (LONG j = 0; j < i; j++ )
  261. delete ppSampleList[j];
  262. delete [] ppSampleList;
  263. return E_OUTOFMEMORY;
  264. }
  265. if (FAILED(hr)) {
  266. delete ppSampleList[i];
  267. DbgLog((LOG_ERROR, 1, TEXT("CVMRMediaSample constructor failed")));
  268. break;
  269. }
  270. // Add the completed sample to the available list
  271. m_lAllocated++;
  272. m_lFree.Add(ppSampleList[i]);
  273. }
  274. if (SUCCEEDED(hr)) {
  275. hr = m_pPin->OnAlloc(ppSampleList, lToAllocate);
  276. if (FAILED(hr)) {
  277. DbgLog((LOG_ERROR, 1, TEXT("m_pPin->OnAlloc(), hr = 0x%x"), hr));
  278. Free();
  279. }
  280. }
  281. delete [] ppSampleList;
  282. return hr;
  283. }
  284. /******************************Public*Routine******************************\
  285. * CVMRPinAllocator::Free()
  286. *
  287. *
  288. *
  289. * History:
  290. * Fri 02/25/2000 - StEstrop - Created
  291. *
  292. \**************************************************************************/
  293. void
  294. CVMRPinAllocator::Free()
  295. {
  296. AMTRACE((TEXT("CVMRPinAllocator::Free")));
  297. ASSERT(m_lAllocated == m_lFree.GetCount());
  298. CVMRMediaSample *pSample;
  299. while (m_lFree.GetCount() != 0) {
  300. pSample = (CVMRMediaSample *) m_lFree.RemoveHead();
  301. delete pSample;
  302. }
  303. m_lAllocated = 0;
  304. DbgLog((LOG_TRACE,2,TEXT("All buffers free on pin#%d"), m_pPin->m_dwPinID));
  305. }