Source code of Windows XP (NT5)
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.

311 lines
8.4 KiB

  1. // Copyright (c) 1997 - 1998 Microsoft Corporation. All Rights Reserved.
  2. // mss.cpp : Implementation of CAMMediaTypeStream
  3. #include "stdafx.h"
  4. #include "project.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CAMMediaTypeStream
  7. CAMMediaTypeStream::CAMMediaTypeStream()
  8. {
  9. InitMediaType(&m_MediaType);
  10. m_AllocatorProperties.cBuffers = 1;
  11. m_AllocatorProperties.cbBuffer = 0x1000;
  12. m_AllocatorProperties.cbAlign = 1;
  13. // We don't require any prefix. If there is a prefix we don't
  14. // need to add it in GetPointer - it's hidden unless we want to
  15. // access it.
  16. m_AllocatorProperties.cbPrefix = 0;
  17. }
  18. STDMETHODIMP CAMMediaTypeStream::AllocateSample(DWORD dwFlags, IStreamSample **ppSample)
  19. {
  20. TRACEINTERFACE(_T("IDirectDrawStream::AllocateSample(0x%8.8X, 0x%8.8X)\n"),
  21. dwFlags, ppSample);
  22. HRESULT hr;
  23. if (!ppSample) {
  24. hr = E_POINTER;
  25. } else {
  26. *ppSample = NULL;
  27. if (dwFlags) {
  28. hr = E_INVALIDARG;
  29. } else {
  30. hr = CreateSample(m_AllocatorProperties.cbBuffer, NULL, 0, NULL,
  31. (IAMMediaTypeSample **)ppSample);
  32. }
  33. }
  34. return hr;
  35. }
  36. STDMETHODIMP CAMMediaTypeStream::CreateSharedSample(IStreamSample *pExistingSample,
  37. DWORD dwFlags,
  38. IStreamSample **ppNewSample)
  39. {
  40. return E_NOTIMPL; // There really is no way to share data since the actual
  41. // size of the data can not be transfered.
  42. }
  43. STDMETHODIMP CAMMediaTypeStream::SetSameFormat(IMediaStream *pStream, DWORD dwFlags)
  44. {
  45. TRACEINTERFACE(_T("IAMMediaSampleStream::SetSameFormat(0x%8.8X, 0x%8.8X)\n"),
  46. pStream, dwFlags);
  47. CComQIPtr<IAMMediaTypeStream, &IID_IAMMediaTypeStream> pSource(pStream);
  48. HRESULT hr;
  49. if (!pSource) {
  50. hr = MS_E_INCOMPATIBLE;
  51. } else {
  52. AM_MEDIA_TYPE MediaType;
  53. hr = pSource->GetFormat(&MediaType, 0);
  54. if (SUCCEEDED(hr)) {
  55. hr = SetFormat(&MediaType, 0);
  56. FreeMediaType(MediaType);
  57. }
  58. }
  59. return hr;
  60. }
  61. ////////////////////////////////////
  62. STDMETHODIMP CAMMediaTypeStream::GetFormat(AM_MEDIA_TYPE *pMediaType, DWORD dwFlags)
  63. {
  64. AUTO_CRIT_LOCK;
  65. HRESULT hr = S_OK;
  66. if (m_pConnectedPin) {
  67. CopyMediaType(pMediaType, &m_MediaType);
  68. } else {
  69. hr = MS_E_NOSTREAM;
  70. }
  71. return hr;
  72. }
  73. STDMETHODIMP CAMMediaTypeStream::SetFormat(AM_MEDIA_TYPE *pMediaType, DWORD dwFlags)
  74. {
  75. AUTO_CRIT_LOCK;
  76. HRESULT hr = S_OK;
  77. if (m_cAllocated) {
  78. if (!IsEqualMediaType(*pMediaType, m_MediaType)) {
  79. hr = MS_E_SAMPLEALLOC;
  80. }
  81. } else {
  82. FreeMediaType(m_MediaType);
  83. CopyMediaType(&m_MediaType, pMediaType);
  84. }
  85. return hr;
  86. }
  87. STDMETHODIMP CAMMediaTypeStream::CreateSample(long lSampleSize, BYTE * pbBuffer,
  88. DWORD dwFlags,
  89. IUnknown * pUnkOuter,
  90. IAMMediaTypeSample **ppSample)
  91. {
  92. AUTO_CRIT_LOCK;
  93. HRESULT hr;
  94. if (!ppSample) {
  95. hr = E_POINTER;
  96. } else {
  97. *ppSample = NULL;
  98. CComPolyObject<CAMMediaTypeSample> * pATLSampleObject = new CComPolyObject<CAMMediaTypeSample>(pUnkOuter);
  99. if (!pATLSampleObject) {
  100. hr = E_OUTOFMEMORY;
  101. } else {
  102. CAMMediaTypeSample *pNewSample = &pATLSampleObject->m_contained;
  103. hr = pNewSample->Initialize(this, lSampleSize, pbBuffer);
  104. if (SUCCEEDED(hr)) {
  105. pNewSample->GetControllingUnknown()->QueryInterface(IID_IAMMediaTypeSample, (void **)ppSample);
  106. } else {
  107. delete pATLSampleObject;
  108. }
  109. }
  110. }
  111. return hr;
  112. }
  113. STDMETHODIMP CAMMediaTypeStream::GetStreamAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
  114. {
  115. return E_FAIL;
  116. }
  117. STDMETHODIMP CAMMediaTypeStream::SetStreamAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
  118. {
  119. return E_FAIL;
  120. }
  121. //
  122. // IPin implementation
  123. //
  124. STDMETHODIMP CAMMediaTypeStream::ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt)
  125. {
  126. // Check the type is accepted and then save the connected pin
  127. HRESULT hr = QueryAccept(pmt);
  128. if (FAILED(hr)) {
  129. return hr;
  130. }
  131. AUTO_CRIT_LOCK;
  132. m_pConnectedPin = pConnector;
  133. return hr;
  134. }
  135. STDMETHODIMP CAMMediaTypeStream::QueryAccept(const AM_MEDIA_TYPE *pmt)
  136. {
  137. AUTO_CRIT_LOCK;
  138. return (IsEqualMediaType(*pmt, m_MediaType) ? S_OK : VFW_E_TYPE_NOT_ACCEPTED);
  139. }
  140. STDMETHODIMP CAMMediaTypeStream::Receive(IMediaSample *pMediaSample)
  141. {
  142. if (m_bFlushing || m_bStopIfNoSamples && m_cAllocated == 0) {
  143. EndOfStream();
  144. return S_FALSE;
  145. }
  146. HRESULT hr = S_OK;
  147. // Send quality message if clocked
  148. REFERENCE_TIME CurTime;
  149. if (S_OK == m_pFilter->GetCurrentStreamTime(&CurTime)) {
  150. REFERENCE_TIME rtStart, rtStop;
  151. if (m_pQC && SUCCEEDED(pMediaSample->GetTime(&rtStart, &rtStop))) {
  152. Quality msg;
  153. msg.Proportion = 1000;
  154. msg.Type = Famine;
  155. msg.Late = CurTime - rtStart;
  156. msg.TimeStamp = rtStart;
  157. // Call Notify on our connected pin
  158. m_pQC->Notify(m_pBaseFilter, msg);
  159. }
  160. }
  161. #ifdef DEBUG
  162. if (bDbgTraceTimes) {
  163. REFERENCE_TIME rtStart, rtStop;
  164. if (SUCCEEDED(pMediaSample->GetTime(&rtStart, &rtStop))) {
  165. ATLTRACE(_T("AMSTREAM.DLL : Video sample received - start %dms, end %dms\n"),
  166. (LONG)(rtStart / 10000), (LONG)(rtStop / 10000));
  167. }
  168. }
  169. #endif
  170. if (m_bUsingMyAllocator) {
  171. CAMMediaTypeSample *pSrcSample = (CAMMediaTypeSample *)((CMediaSample *)pMediaSample)->m_pSample;
  172. pSrcSample->m_bReceived = true;
  173. } else {
  174. CAMMediaTypeSample *pDestSample;
  175. REFERENCE_TIME rtStart, rtEnd;
  176. pMediaSample->GetTime(&rtStart, &rtEnd);
  177. hr = AllocMTSampleFromPool(&rtStart, &pDestSample);
  178. Lock();
  179. // This is a media sample coming from a different allocator.
  180. // Because QueryAccept only accepts our type the format should
  181. // be compatible
  182. if (SUCCEEDED(hr)) {
  183. hr = pDestSample->SetCompletionStatus(pDestSample->CopyFrom(pMediaSample));
  184. // Warning! The SetCompletionStatus may delete pDestSample. Don't touch it after this point!
  185. }
  186. Unlock();
  187. }
  188. #ifdef DEBUG
  189. if (bDbgTraceTimes) {
  190. REFERENCE_TIME CurTime;
  191. m_pFilter->GetCurrentStreamTime(&CurTime);
  192. ATLTRACE(_T("AMSTREAM.DLL : Got sample at %dms\n"),
  193. (LONG)(CurTime / 10000));
  194. }
  195. #endif
  196. return hr;
  197. }
  198. //
  199. // IMemAllocator implementation
  200. //
  201. //
  202. // IMemAllocator
  203. //
  204. STDMETHODIMP CAMMediaTypeStream::SetProperties(ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual)
  205. {
  206. HRESULT hr;
  207. AUTO_CRIT_LOCK;
  208. ZeroMemory(pActual, sizeof(*pActual));
  209. if (pRequest->cbAlign == 0) {
  210. hr = VFW_E_BADALIGN;
  211. } else {
  212. if (m_bCommitted == TRUE) {
  213. hr = VFW_E_ALREADY_COMMITTED;
  214. } else {
  215. m_AllocatorProperties = *pRequest;
  216. hr = GetProperties(pActual);
  217. }
  218. }
  219. return hr;
  220. }
  221. STDMETHODIMP CAMMediaTypeStream::GetProperties(ALLOCATOR_PROPERTIES* pProps)
  222. {
  223. AUTO_CRIT_LOCK;
  224. CopyMemory(pProps, &m_AllocatorProperties, sizeof(*pProps));
  225. return S_OK;
  226. }
  227. STDMETHODIMP CAMMediaTypeStream::GetBuffer(IMediaSample **ppBuffer, REFERENCE_TIME * pStartTime,
  228. REFERENCE_TIME * pEndTime, DWORD dwFlags)
  229. {
  230. *ppBuffer = NULL;
  231. CAMMediaTypeSample *pSample;
  232. if (m_bStopIfNoSamples && m_cAllocated == 0) {
  233. return E_FAIL;
  234. }
  235. #ifdef DEBUG
  236. if (bDbgTraceTimes) {
  237. ATLTRACE(_T("AMSTREAM.DLL : GetBuffer for %dms\n"),
  238. pStartTime ? (LONG)(*pStartTime / 10000) : 0);
  239. }
  240. #endif
  241. HRESULT hr = AllocMTSampleFromPool(pStartTime, &pSample);
  242. if (SUCCEEDED(hr)) {
  243. pSample->m_bReceived = false;
  244. pSample->m_bModified = true;
  245. *ppBuffer = (IMediaSample *)(pSample->m_pMediaSample);
  246. (*ppBuffer)->AddRef();
  247. }
  248. return hr;
  249. }
  250. //
  251. // Special CStream methods
  252. //
  253. HRESULT CAMMediaTypeStream::GetMediaType(ULONG Index, AM_MEDIA_TYPE **ppMediaType)
  254. {
  255. if (Index != 0) {
  256. return S_FALSE;
  257. }
  258. *ppMediaType = CreateMediaType(&m_MediaType);
  259. return (*ppMediaType) ? S_OK : E_OUTOFMEMORY;
  260. }