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.

333 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: mxfilter.h
  8. //
  9. //--------------------------------------------------------------------------
  10. ///////////////////////////////////////////////////////////////////////////////
  11. //
  12. // File: mxfilter.h
  13. //
  14. // Description: Defines the mixer filter & pin classes
  15. //
  16. ///////////////////////////////////////////////////////////////////////////////
  17. #include <mixflter.h> // for the CLSID
  18. // If more than X packets are delivered with the time interval of a packet
  19. // the overflow will be disgarded
  20. const DWORD MAX_QUEUE_STORAGE = 8;
  21. //
  22. // These should not change anyway.
  23. //
  24. enum { OUTPUT_PIN, INPUT_PIN0 };
  25. const TCHAR MIXER_KEY[] =
  26. TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DxmRTP\\MIXER");
  27. const TCHAR JITTERBUFFER[] = TEXT("JitterBuffer");
  28. const TCHAR MIXBUFFER[] = TEXT("MixDelay");
  29. const DWORD MAX_QUEUES = 32;
  30. const DWORD MAX_TIMEDELTA = 180; // 180ms
  31. const DWORD DEFAULT_JITTERBUFFERTIME = 60; // 60ms of jitter buffer.
  32. const DWORD DEFAULT_MIXDELAYTIME = 40; // 40ms of mix delay.
  33. class CMixer;
  34. class CMixerInputPin;
  35. class CMixerOutputPin;
  36. #ifndef CBufferQueue_DEFINED
  37. #include "queue.h"
  38. #endif // #ifndef CBufferQueue_DEFINED
  39. ///////////////////////////////////////////////////////////////////////////////
  40. //***************************************************************************//
  41. //***************************************************************************//
  42. ///////////////////////////////////////////////////////////////////////////////
  43. class CMixerOutputPin : public CBaseOutputPin
  44. {
  45. CMixer *m_pMixer;
  46. public:
  47. CMixerOutputPin(
  48. TCHAR *pObjName,
  49. CMixer *pMixer,
  50. HRESULT *phr,
  51. LPCWSTR pPinName
  52. );
  53. //
  54. // Connection helpers
  55. //
  56. virtual HRESULT DecideBufferSize(IMemAllocator * pAlloc,
  57. ALLOCATOR_PROPERTIES * ppropInputRequest);
  58. virtual HRESULT CheckMediaType(const CMediaType *pmt);
  59. virtual HRESULT DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc);
  60. virtual HRESULT CompleteConnect(IPin *pReceivePin);
  61. IMemInputPin *GetIMemInputPin() { return m_pInputPin; }
  62. //
  63. // Media Type related functions
  64. //
  65. HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);
  66. CMediaType &CurrentMediaType();
  67. };
  68. ///////////////////////////////////////////////////////////////////////////////
  69. //***************************************************************************//
  70. //***************************************************************************//
  71. ///////////////////////////////////////////////////////////////////////////////
  72. class CMixerInputPin : public CBaseInputPin
  73. {
  74. CMixer *m_pMixer; // Main filter object
  75. ULONG m_cOurRef; // Local ref count
  76. int m_iPinNumber; // Number of this pin
  77. // queues created for the input pins
  78. CBufferQueue *m_pQueue;
  79. public:
  80. //
  81. // Construction
  82. //
  83. CMixerInputPin(
  84. TCHAR * pObjName,
  85. CMixer * pMixer,
  86. HRESULT * phr,
  87. LPCWSTR pPinName,
  88. int iPin,
  89. CBufferQueue *pQueue
  90. );
  91. //
  92. // Methods dealing with media type
  93. //
  94. HRESULT CheckMediaType(const CMediaType *pmt);
  95. CMediaType &CurrentMediaType();
  96. // Connection stuff
  97. virtual HRESULT CompleteConnect(IPin *pReceivePin);
  98. virtual HRESULT STDMETHODCALLTYPE Disconnect();
  99. //
  100. // Methods dealing with the allocator
  101. //
  102. IMemAllocator *GetAllocator() { return m_pAllocator; }
  103. #if 0
  104. STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator);
  105. STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly);
  106. #endif
  107. STDMETHODIMP AllocatorProperties(ALLOCATOR_PROPERTIES * pprop);
  108. STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);
  109. // Handles the next block of data from the stream
  110. STDMETHODIMP Receive(IMediaSample *pSample);
  111. // Override since the life time of pins and filters are not the same
  112. STDMETHODIMP_(ULONG) NonDelegatingAddRef();
  113. STDMETHODIMP_(ULONG) NonDelegatingRelease();
  114. // We deal with these because we queue.
  115. STDMETHODIMP EndOfStream();
  116. STDMETHODIMP BeginFlush();
  117. STDMETHODIMP EndFlush();
  118. HRESULT Inactive();
  119. HRESULT Active();
  120. };
  121. ///////////////////////////////////////////////////////////////////////////////
  122. //***************************************************************************//
  123. //***************************************************************************//
  124. ///////////////////////////////////////////////////////////////////////////////
  125. class CMixer : public CCritSec, public CBaseFilter
  126. {
  127. typedef CGenericList <CMixerInputPin> CInputPinList;
  128. INT m_cInputPins; // Current Input pin count
  129. CInputPinList m_listInputPins; // List of the Input pins
  130. INT m_iNextInputPinNumber; // Increases monotonically.
  131. CMixerOutputPin *m_pMixerOutput; // Common Output Pin
  132. DWORD m_dwInputBytesPerMS;
  133. WORD m_wInputBitsPerSample;
  134. WORD m_wOutputBitsPerSample;
  135. WORD m_wInputFormatTag; // Input format tag
  136. WORD m_wPAD;
  137. #if USE_LOCK
  138. // Critical section for the queues.
  139. CCritSec m_cQueues;
  140. #endif
  141. // queues created for the input pins
  142. CBufferQueue * m_queues[MAX_QUEUES];
  143. // the size of the jitter buffer, in time and in bytes.
  144. long m_lJitterBufferTime;
  145. long m_lTotalDelayTime;
  146. long m_lTotalDelayBufferSize;
  147. // time reserved for mixing delay
  148. long m_lMixDelayTime;
  149. // the size of the sample measued in ms.
  150. long m_lSampleTime;
  151. // the dword value of the system clock of the last sample.
  152. DWORD m_dwLastTime;
  153. // the dword value of the start time of a spurt.
  154. DWORD m_dwSpurtStartTime;
  155. // the dword value of the difference between the wall clock and the
  156. // the samples played.
  157. long m_lTimeDelta;
  158. public:
  159. CMixer(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *hr);
  160. ~CMixer();
  161. //
  162. // Function needed for the class factory
  163. //
  164. static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
  165. //
  166. // External Utilities
  167. //
  168. FILTER_STATE GetState() { return m_State; }
  169. //
  170. // Exeternal methods for pin management
  171. //
  172. CBasePin *GetPin(int n);
  173. int GetPinCount() { return 1 + m_cInputPins; }
  174. int GetInputPinCount() { return m_cInputPins; }
  175. int GetConnectedPinCount() { return m_cInputPins - GetFreePinCount(); }
  176. int GetFreePinCount();
  177. BOOL SpawnNewInput();
  178. void DeleteInputPin(CMixerInputPin *pPin, CBufferQueue *pQueue);
  179. CMixerInputPin *GetInput0() { return (CMixerInputPin*)GetPin(INPUT_PIN0); }
  180. CMixerInputPin *GetInput(int n) { return (CMixerInputPin*)GetPin(INPUT_PIN0+n); }
  181. CMixerOutputPin *GetOutput() { return m_pMixerOutput; }
  182. //
  183. // Self Registration
  184. //
  185. LPAMOVIESETUP_FILTER GetSetupData();
  186. //
  187. // Media Type Methods
  188. //
  189. HRESULT CheckMediaType(const CMediaType *pmt);
  190. HRESULT CheckOutputMediaType(const CMediaType* pMediaType);
  191. CMediaType &CurrentMediaType();
  192. BOOL MediaTypeKnown();
  193. HRESULT CopyMTParams(const CMediaType *pmt);
  194. //
  195. // Allocator methods
  196. //
  197. HRESULT GetAgregateAllocatorProperties(ALLOCATOR_PROPERTIES * pprop);
  198. HRESULT CompleteConnect();
  199. HRESULT DecideBufferSize(IMemAllocator * pAlloc, ALLOCATOR_PROPERTIES * pprop);
  200. HRESULT DisconnectInput();
  201. // Streaming methods.
  202. STDMETHOD (Run)(REFERENCE_TIME tStart);
  203. // Public data
  204. public:
  205. //
  206. // Keep from rereconnecting the output
  207. //
  208. BOOL m_fReconnect;
  209. // called from the input pins.
  210. void FlushQueue(CBufferQueue *pQueue);
  211. HRESULT Receive(CBufferQueue *pQueue, IMediaSample * pSample);
  212. // The following manage the list of input pins
  213. protected:
  214. void InitInputPinsList();
  215. CMixerInputPin *GetInputPinNFromList(int n);
  216. HRESULT MixOneSample(
  217. IMediaSample *pMixedSample,
  218. IMediaSample ** ppSample,
  219. long lCount
  220. );
  221. HRESULT FillSilentBuffer(IMediaSample *, DWORD); // Fill a buffer with silence
  222. void FlushAllQueues();
  223. BOOL ResetQueuesIfNecessary();
  224. HRESULT PrePlay();
  225. HRESULT SendSample();
  226. };
  227. ///////////////////////////////////////////////////////////////////////////////
  228. //***************************************************************************//
  229. //*************************** Inline Function Section ***********************//
  230. //***************************************************************************//
  231. ///////////////////////////////////////////////////////////////////////////////
  232. ///////////////////////////////////////////////////////////////////////////////
  233. //
  234. // GetFreePinCount
  235. //
  236. ///////////////////////////////////////////////////////////////////////////////
  237. inline int CMixer::GetFreePinCount()
  238. {
  239. int n = 0;
  240. POSITION pos = m_listInputPins.GetHeadPosition();
  241. while(pos)
  242. {
  243. CBaseInputPin *pInputPin = (CBaseInputPin *)m_listInputPins.GetNext(pos);
  244. if (!pInputPin->IsConnected())
  245. n++;
  246. }
  247. return n;
  248. }
  249. ///////////////////////////////////////////////////////////////////////////////
  250. inline BOOL CMixer::MediaTypeKnown()
  251. {
  252. return GetPin(INPUT_PIN0)->IsConnected();
  253. }
  254. ///////////////////////////////////////////////////////////////////////////////
  255. //***************************************************************************//
  256. //***************************************************************************//
  257. ///////////////////////////////////////////////////////////////////////////////
  258. inline HRESULT CMixerInputPin::CheckMediaType(const CMediaType *pmt)
  259. {
  260. return m_pMixer->CheckMediaType(pmt);
  261. }
  262. ///////////////////////////////////////////////////////////////////////////////
  263. inline CMediaType &CMixerInputPin::CurrentMediaType()
  264. {
  265. return m_mt;
  266. }
  267. ///////////////////////////////////////////////////////////////////////////////
  268. inline CMediaType &CMixerOutputPin::CurrentMediaType()
  269. {
  270. return m_mt;
  271. }