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.

286 lines
6.1 KiB

  1. // Copyright (c) 1996 - 1999 Microsoft Corporation. All Rights Reserved.
  2. #include <streams.h>
  3. #include <initguid.h>
  4. #include "fw.h"
  5. // ------------------------------------------------------------------------
  6. // filter
  7. #pragma warning(disable:4355)
  8. CBaseWriterFilter::CBaseWriterFilter(LPUNKNOWN pUnk, HRESULT *pHr) :
  9. CBaseFilter(NAME("fw filter"), pUnk, &m_cs, CLSID_FileWriter),
  10. m_inputPin(NAME("fw inpin"), this, &m_cs, pHr)
  11. {
  12. ASSERT(m_mtSet.majortype == GUID_NULL);
  13. ASSERT(m_mtSet.subtype == GUID_NULL);
  14. }
  15. CBaseWriterFilter::~CBaseWriterFilter()
  16. {
  17. }
  18. STDMETHODIMP
  19. CBaseWriterFilter::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  20. {
  21. if(riid == IID_IAMFilterMiscFlags)
  22. return GetInterface((IAMFilterMiscFlags *)this, ppv);
  23. else
  24. return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
  25. }
  26. int CBaseWriterFilter::GetPinCount()
  27. {
  28. return 1;
  29. }
  30. CBasePin *CBaseWriterFilter::GetPin(int pin)
  31. {
  32. return pin == 0 ? &m_inputPin : 0;
  33. }
  34. HRESULT CBaseWriterFilter::Pause()
  35. {
  36. CAutoLock lock(&m_cs);
  37. if(m_State == State_Stopped)
  38. {
  39. m_fEosSignaled = FALSE;
  40. m_fErrorSignaled = FALSE;
  41. HRESULT hr = CanPause();
  42. if(FAILED(hr))
  43. {
  44. m_fErrorSignaled = TRUE;
  45. return hr;
  46. }
  47. // send an EC_COMPLETE event first time we run with input
  48. // disconnected
  49. if(!m_inputPin.IsConnected())
  50. {
  51. m_fEosSignaled = TRUE;
  52. }
  53. hr = Open();
  54. if(FAILED(hr))
  55. {
  56. m_fErrorSignaled = TRUE;
  57. return hr;
  58. }
  59. }
  60. return CBaseFilter::Pause();
  61. }
  62. HRESULT CBaseWriterFilter::Run(REFERENCE_TIME rtStart)
  63. {
  64. CAutoLock Lock(&m_cs);
  65. HRESULT hr = CBaseFilter::Run(rtStart);
  66. // every time we transition to Run, need to send EC_COMPLETE if
  67. // we're done.
  68. if(m_fEosSignaled && !m_fErrorSignaled)
  69. {
  70. NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this);
  71. }
  72. return hr;
  73. }
  74. HRESULT CBaseWriterFilter::Stop()
  75. {
  76. CAutoLock lock(&m_cs);
  77. HRESULT hrClose = Close();
  78. HRESULT hrStop = CBaseFilter::Stop();
  79. if(m_fErrorSignaled)
  80. return hrStop;
  81. else
  82. return FAILED(hrClose) ? hrClose : hrStop;
  83. }
  84. // could be used to close asynchronous file handle (used by
  85. // IMemInputPin) early
  86. STDMETHODIMP CBaseWriterFilter::EndOfStream()
  87. {
  88. DbgLog((LOG_TRACE, 3, TEXT("CBaseWriterFilter: EOS")));
  89. CAutoLock lock(&m_cs);
  90. ASSERT(!m_fEosSignaled);
  91. m_fEosSignaled = TRUE;
  92. if(!m_fErrorSignaled)
  93. {
  94. if(m_State == State_Running)
  95. {
  96. NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this);
  97. }
  98. else if(m_State == State_Paused)
  99. {
  100. // m_fEosSignaled set, so will be signaled on run
  101. }
  102. else
  103. {
  104. ASSERT(m_State == State_Stopped);
  105. // we could have stopped already; ignore EOS
  106. }
  107. }
  108. return S_OK;
  109. }
  110. // ------------------------------------------------------------------------
  111. // input pin
  112. CBaseWriterInput::CBaseWriterInput(
  113. TCHAR *pObjectName,
  114. CBaseWriterFilter *pFilter,
  115. CCritSec *pLock,
  116. HRESULT *phr) :
  117. CBaseInputPin(pObjectName, pFilter, pLock, phr, L"in"),
  118. m_pFwf(pFilter)
  119. {
  120. }
  121. STDMETHODIMP
  122. CBaseWriterInput::NonDelegatingQueryInterface(REFIID riid, void ** pv)
  123. {
  124. if(riid == IID_IStream)
  125. {
  126. return m_pFwf->CreateIStream(pv);
  127. }
  128. else
  129. {
  130. return CBaseInputPin::NonDelegatingQueryInterface(riid, pv);
  131. }
  132. }
  133. HRESULT CBaseWriterInput::CheckMediaType(const CMediaType *pmt)
  134. {
  135. // accept what's set or anything if not set
  136. if((m_pFwf->m_mtSet.majortype == pmt->majortype ||
  137. m_pFwf->m_mtSet.majortype == GUID_NULL) &&
  138. (m_pFwf->m_mtSet.subtype == pmt->subtype ||
  139. m_pFwf->m_mtSet.subtype == GUID_NULL))
  140. {
  141. return S_OK;
  142. }
  143. else
  144. {
  145. return S_FALSE;
  146. }
  147. }
  148. STDMETHODIMP
  149. CBaseWriterInput::BeginFlush(void)
  150. {
  151. return E_UNEXPECTED;
  152. }
  153. STDMETHODIMP
  154. CBaseWriterInput::EndFlush(void)
  155. {
  156. return E_UNEXPECTED;
  157. }
  158. STDMETHODIMP CBaseWriterInput::GetAllocator(IMemAllocator **ppA)
  159. {
  160. *ppA = 0;
  161. // what do you want with my allocator.... you can't set the data
  162. // pointer on it...
  163. return E_INVALIDARG;
  164. }
  165. // return disk sector size through here
  166. STDMETHODIMP CBaseWriterInput::GetAllocatorRequirements(
  167. ALLOCATOR_PROPERTIES *pAp)
  168. {
  169. ULONG cb;
  170. ZeroMemory(pAp, sizeof(*pAp));
  171. HRESULT hr = m_pFwf->GetAlignReq(&cb);
  172. ASSERT(hr == S_OK);
  173. pAp->cbAlign = cb;
  174. return S_OK;
  175. }
  176. STDMETHODIMP CBaseWriterInput::Receive(IMediaSample *pSample)
  177. {
  178. CAutoLock l(&m_pFwf->m_cs);
  179. if(m_pFwf->m_fErrorSignaled)
  180. return S_FALSE;
  181. ASSERT(!m_pFwf->m_fEosSignaled);
  182. REFERENCE_TIME rtStart, rtEnd;
  183. HRESULT hr = pSample->GetTime(&rtStart, &rtEnd);
  184. if(hr != S_OK)
  185. {
  186. m_pFwf->m_fErrorSignaled = TRUE;
  187. m_pFwf->NotifyEvent(EC_ERRORABORT, hr, 0);
  188. return hr;
  189. }
  190. // ULONG cb = pSample->GetActualDataLength();
  191. // if(rtStart + cb != rtEnd)
  192. // {
  193. // DbgBreak("start, stop, and size don't mathc");
  194. // return E_INVALIDARG;
  195. // }
  196. ULONG cb = (ULONG)(rtEnd - rtStart);
  197. BYTE *pb;
  198. hr = pSample->GetPointer(&pb);
  199. ASSERT(hr == S_OK);
  200. pSample->AddRef();
  201. hr = m_pFwf->AsyncWrite(rtStart, cb, pb, Callback, pSample);
  202. if(hr != S_OK)
  203. {
  204. DbgLog((LOG_ERROR, 5, TEXT("CBaseWriterInput: AsyncWrite returned %08x"),
  205. hr));
  206. // the call back is called only if AsyncWrite succeeds.
  207. pSample->Release();
  208. if(FAILED(hr))
  209. {
  210. DbgLog((LOG_ERROR, 1, TEXT("fw Receive: signalling error")));
  211. m_pFwf->m_fErrorSignaled = TRUE;
  212. m_pFwf->NotifyEvent(EC_ERRORABORT, hr, 0);
  213. }
  214. }
  215. return hr;
  216. }
  217. STDMETHODIMP CBaseWriterInput::EndOfStream()
  218. {
  219. return m_pFwf->EndOfStream();
  220. }
  221. STDMETHODIMP
  222. CBaseWriterInput::NotifyAllocator(
  223. IMemAllocator * pAllocator,
  224. BOOL bReadOnly)
  225. {
  226. HRESULT hr = CBaseInputPin::NotifyAllocator(pAllocator, bReadOnly);
  227. if(FAILED(hr))
  228. return hr;
  229. else
  230. return m_pFwf->NotifyAllocator(pAllocator, bReadOnly);
  231. }
  232. void CBaseWriterInput::Callback(void *pMisc)
  233. {
  234. IMediaSample *pSample = (IMediaSample *)pMisc;
  235. pSample->Release();
  236. }