mf_custom_src.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. * Copyright (C) Microsoft Corporation. All rights reserved.
  3. * Copyright (C) 2013 Mamadou DIOP
  4. * Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
  5. *
  6. * This file is part of Open Source Doubango Framework.
  7. *
  8. * DOUBANGO is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * DOUBANGO is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with DOUBANGO.
  20. */
  21. #ifndef PLUGIN_WIN_MF_CUSTOM_SOURCE_H
  22. #define PLUGIN_WIN_MF_CUSTOM_SOURCE_H
  23. #include "../plugin_win_mf_config.h"
  24. #include <new>
  25. #include <windows.h>
  26. #include <assert.h>
  27. #include <mfapi.h>
  28. #include <mfobjects.h>
  29. #include <mfidl.h>
  30. #include <mferror.h>
  31. #include <shlwapi.h>
  32. class CMFStreamSource;
  33. class CMFSource;
  34. LONGLONG AudioDurationFromBufferSize(const WAVEFORMATEX *pWav, DWORD cbAudioDataSize);
  35. //////////////////////////////////////////////////////////////////////////
  36. // CMFSource
  37. // Description: Media source object.
  38. //////////////////////////////////////////////////////////////////////////
  39. class CMFSource : public IMFMediaSource
  40. {
  41. friend class CMFStreamSource;
  42. public:
  43. static HRESULT CreateInstance(REFIID iid, void **ppSource);
  44. static HRESULT CreateInstanceEx(REFIID iid, void **ppSource, IMFMediaType *pMediaType);
  45. // IMFCustomSource
  46. HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
  47. // IUnknown
  48. STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
  49. STDMETHODIMP_(ULONG) AddRef();
  50. STDMETHODIMP_(ULONG) Release();
  51. // IMFMediaEventGenerator
  52. STDMETHODIMP BeginGetEvent(IMFAsyncCallback* pCallback,IUnknown* punkState);
  53. STDMETHODIMP EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** ppEvent);
  54. STDMETHODIMP GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent);
  55. STDMETHODIMP QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue);
  56. // IMFMediaSource
  57. STDMETHODIMP CreatePresentationDescriptor(IMFPresentationDescriptor** ppPresentationDescriptor);
  58. STDMETHODIMP GetCharacteristics(DWORD* pdwCharacteristics);
  59. STDMETHODIMP Pause();
  60. STDMETHODIMP Shutdown();
  61. STDMETHODIMP Start(
  62. IMFPresentationDescriptor* pPresentationDescriptor,
  63. const GUID* pguidTimeFormat,
  64. const PROPVARIANT* pvarStartPosition
  65. );
  66. STDMETHODIMP Stop();
  67. private:
  68. enum State {
  69. STATE_STOPPED,
  70. STATE_PAUSED,
  71. STATE_STARTED
  72. };
  73. // Constructor is private - client should use static CreateInstance method.
  74. CMFSource(HRESULT &hr, IMFMediaType *pMediaType);
  75. virtual ~CMFSource();
  76. HRESULT CheckShutdown() const {
  77. if (m_IsShutdown) {
  78. return MF_E_SHUTDOWN;
  79. }
  80. else {
  81. return S_OK;
  82. }
  83. }
  84. HRESULT CreatePresentationDescriptor();
  85. HRESULT QueueNewStreamEvent(IMFPresentationDescriptor *pPD);
  86. HRESULT CreateCMFStreamSource(IMFStreamDescriptor *pSD);
  87. HRESULT ValidatePresentationDescriptor(IMFPresentationDescriptor *pPD);
  88. LONGLONG GetCurrentPosition() const;
  89. State GetState() const {
  90. return m_state;
  91. }
  92. IMFMediaEventQueue *m_pEventQueue; // Event generator helper
  93. IMFPresentationDescriptor *m_pPresentationDescriptor; // Default presentation
  94. CMFStreamSource *m_pStream; // Media stream. Can be NULL is no stream is selected.
  95. long m_nRefCount; // reference count
  96. CRITICAL_SECTION m_critSec;
  97. BOOL m_IsShutdown; // Flag to indicate if Shutdown() method was called.
  98. State m_state; // Current state (running, stopped, paused)
  99. IMFMediaType *m_pMediaType; // The supported mediaType
  100. };
  101. class SampleQueue
  102. {
  103. protected:
  104. // Nodes in the linked list
  105. struct Node {
  106. Node *prev;
  107. Node *next;
  108. IMFSample* item;
  109. Node() : prev(NULL), next(NULL) {
  110. }
  111. Node(IMFSample* item) : prev(NULL), next(NULL) {
  112. this->item = item;
  113. }
  114. IMFSample* Item() const {
  115. return item;
  116. }
  117. };
  118. protected:
  119. Node m_anchor; // Anchor node for the linked list.
  120. public:
  121. SampleQueue() {
  122. m_anchor.next = &m_anchor;
  123. m_anchor.prev = &m_anchor;
  124. }
  125. virtual ~SampleQueue() {
  126. Clear();
  127. }
  128. HRESULT Queue(IMFSample* item) {
  129. if (item == NULL) {
  130. return E_POINTER;
  131. }
  132. Node *pNode = new (std::nothrow) Node(item);
  133. if (pNode == NULL) {
  134. return E_OUTOFMEMORY;
  135. }
  136. item->AddRef();
  137. Node *pBefore = m_anchor.prev;
  138. Node *pAfter = pBefore->next;
  139. pBefore->next = pNode;
  140. pAfter->prev = pNode;
  141. pNode->prev = pBefore;
  142. pNode->next = pAfter;
  143. return S_OK;
  144. }
  145. HRESULT Dequeue(IMFSample**ppItem) {
  146. if (IsEmpty()) {
  147. return E_FAIL;
  148. }
  149. if (ppItem == NULL) {
  150. return E_POINTER;
  151. }
  152. Node *pNode = m_anchor.next;
  153. // The next node's previous is this node's previous.
  154. pNode->next->prev = m_anchor.next->prev;
  155. // The previous node's next is this node's next.
  156. pNode->prev->next = pNode->next;
  157. *ppItem = pNode->item;
  158. delete pNode;
  159. return S_OK;
  160. }
  161. BOOL IsEmpty() const {
  162. return m_anchor.next == &m_anchor;
  163. }
  164. void Clear() {
  165. Node *n = m_anchor.next;
  166. // Delete the nodes
  167. while (n != &m_anchor) {
  168. if (n->item) {
  169. n->item->Release();
  170. }
  171. Node *tmp = n->next;
  172. delete n;
  173. n = tmp;
  174. }
  175. // Reset the anchor to point at itself
  176. m_anchor.next = &m_anchor;
  177. m_anchor.prev = &m_anchor;
  178. }
  179. };
  180. //////////////////////////////////////////////////////////////////////////
  181. // CMFStreamSource
  182. // Description: Media stream object.
  183. //////////////////////////////////////////////////////////////////////////
  184. class CMFStreamSource : public IMFMediaStream
  185. {
  186. friend class CMFSource;
  187. public:
  188. // IMFCustomSource
  189. HRESULT CopyVideoBuffer(UINT32 nWidth, UINT32 nHeight, const void* pBufferPtr, UINT32 nBufferSize);
  190. // IUnknown
  191. STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
  192. STDMETHODIMP_(ULONG) AddRef();
  193. STDMETHODIMP_(ULONG) Release();
  194. // IMFMediaEventGenerator
  195. STDMETHODIMP BeginGetEvent(IMFAsyncCallback* pCallback,IUnknown* punkState);
  196. STDMETHODIMP EndGetEvent(IMFAsyncResult* pResult, IMFMediaEvent** ppEvent);
  197. STDMETHODIMP GetEvent(DWORD dwFlags, IMFMediaEvent** ppEvent);
  198. STDMETHODIMP QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT* pvValue);
  199. // IMFMediaStream
  200. STDMETHODIMP GetMediaSource(IMFMediaSource** ppMediaSource);
  201. STDMETHODIMP GetStreamDescriptor(IMFStreamDescriptor** ppStreamDescriptor);
  202. STDMETHODIMP RequestSample(IUnknown* pToken);
  203. private:
  204. CMFStreamSource(CMFSource *pSource, IMFStreamDescriptor *pSD, HRESULT& hr);
  205. ~CMFStreamSource();
  206. HRESULT CheckShutdown() const {
  207. if (m_IsShutdown) {
  208. return MF_E_SHUTDOWN;
  209. }
  210. else {
  211. return S_OK;
  212. }
  213. }
  214. HRESULT InitializeParams();
  215. HRESULT Shutdown();
  216. HRESULT CreateSample(IMFSample **pSample);
  217. HRESULT DeliverSample(IMFSample *pSample);
  218. HRESULT DeliverQueuedSamples();
  219. HRESULT Flush();
  220. LONGLONG GetCurrentPosition() const {
  221. return m_rtCurrentPosition;
  222. }
  223. HRESULT SetPosition(LONGLONG rtNewPosition);
  224. HRESULT CheckEndOfStream();
  225. long m_nRefCount; // reference count
  226. CRITICAL_SECTION m_critSec;
  227. BOOL m_IsShutdown; // Flag to indicate if source's Shutdown() method was called.
  228. LONGLONG m_rtCurrentPosition; // Current position in the stream, in 100-ns units
  229. UINT64 m_rtDuration; // Sample duration, in 100-ns units
  230. BOOL m_discontinuity; // Is the next sample a discontinuity?
  231. BOOL m_EOS; // Did we reach the end of the stream?
  232. IMFMediaEventQueue *m_pEventQueue; // Event generator helper.
  233. CMFSource *m_pSource; // Parent media source
  234. IMFStreamDescriptor *m_pStreamDescriptor; // Stream descriptor for this stream.
  235. SampleQueue m_sampleQueue; // Queue for samples while paused.
  236. GUID m_guidMajorType; // major media type (e.g. MFMediaType_Video or MFMediaType_Audio)
  237. GUID m_guidSubType; // Media subtype (e.g. MFVideoFormat_RGB32 or MFVideoFormat_H264)
  238. IMFMediaBuffer *m_pMediaBuffer; // Pointer to the data to deliver
  239. UINT32 m_nBufferSize; // Size of the data to deliver
  240. struct {
  241. UINT32 nWidth;
  242. UINT32 nHeigh;
  243. UINT32 nFps;
  244. }
  245. m_structVideoParams;
  246. };
  247. #endif /* PLUGIN_WIN_MF_CUSTOM_SOURCE_H */