mf_utils.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* Copyright (C) 2013 Mamadou DIOP
  2. * Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
  3. *
  4. * This file is part of Open Source Doubango Framework.
  5. *
  6. * DOUBANGO is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * DOUBANGO is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with DOUBANGO.
  18. */
  19. #ifndef PLUGIN_WIN_MF_UTILS_H
  20. #define PLUGIN_WIN_MF_UTILS_H
  21. #include "../plugin_win_mf_config.h"
  22. #include <new>
  23. #include <mfapi.h>
  24. #include <mfidl.h>
  25. #include <Mferror.h>
  26. #include <shlwapi.h>
  27. #undef SafeRelease
  28. #define SafeRelease(ppT) \
  29. { \
  30. if (*ppT) \
  31. { \
  32. (*ppT)->Release(); \
  33. *ppT = NULL; \
  34. } \
  35. }
  36. #undef CHECK_HR
  37. // In CHECK_HR(x) When (x) is a function it will be executed twice when used in "TSK_DEBUG_ERROR(x)" and "If(x)"
  38. #define CHECK_HR(x) { HRESULT __hr__ = (x); if (FAILED(__hr__)) { TSK_DEBUG_ERROR("Operation Failed (%08x)", __hr__); goto bail; } }
  39. typedef struct VideoSubTypeGuidPair {
  40. enum tmedia_chroma_e chroma;
  41. const GUID& fourcc;
  42. }
  43. VideoSubTypeGuidPair;
  44. class MFUtils
  45. {
  46. public:
  47. static HRESULT Startup();
  48. static HRESULT Shutdown();
  49. static BOOL IsD3D9Supported();
  50. static BOOL IsLowLatencyH264Supported();
  51. static BOOL IsLowLatencyH264SupportsMaxSliceSize();
  52. static HRESULT IsAsyncMFT(
  53. IMFTransform *pMFT, // The MFT to check
  54. BOOL* pbIsAsync // Whether the MFT is Async
  55. );
  56. static HRESULT UnlockAsyncMFT(
  57. IMFTransform *pMFT // The MFT to unlock
  58. );
  59. static HRESULT CreatePCMAudioType(
  60. UINT32 sampleRate, // Samples per second
  61. UINT32 bitsPerSample, // Bits per sample
  62. UINT32 cChannels, // Number of channels
  63. IMFMediaType **ppType // Receives a pointer to the media type.
  64. );
  65. static HRESULT CreateVideoType(
  66. const GUID* subType, // video subType
  67. IMFMediaType **ppType, // Receives a pointer to the media type.
  68. UINT32 unWidth = 0, // Video width (0 to ignore)
  69. UINT32 unHeight = 0 // Video height (0 to ignore)
  70. );
  71. static HRESULT ConvertVideoTypeToUncompressedType(
  72. IMFMediaType *pType, // Pointer to an encoded video type.
  73. const GUID& subtype, // Uncompressed subtype (eg, RGB-32, AYUV)
  74. IMFMediaType **ppType // Receives a matching uncompressed video type.
  75. );
  76. static HRESULT CreateMediaSample(
  77. DWORD cbData, // Maximum buffer size
  78. IMFSample **ppSample // Receives the sample
  79. );
  80. static HRESULT ValidateVideoFormat(
  81. IMFMediaType *pmt
  82. );
  83. static HRESULT IsVideoProcessorSupported(BOOL *pbSupported);
  84. static HRESULT GetBestVideoProcessor(
  85. const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_I420)
  86. const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_NV12)
  87. IMFTransform **ppProcessor // Receives the video processor
  88. );
  89. static HRESULT GetBestCodec(
  90. BOOL bEncoder, // Whether we request an encoder or not (TRUE=encoder, FALSE=decoder)
  91. const GUID& mediaType, // The MediaType
  92. const GUID& inputFormat, // The input MediaFormat (e.g. MFVideoFormat_NV12)
  93. const GUID& outputFormat, // The output MediaFormat (e.g. MFVideoFormat_H264)
  94. IMFTransform **ppMFT // Receives the decoder/encoder transform
  95. );
  96. static HRESULT BindOutputNode(
  97. IMFTopologyNode *pNode // The Node
  98. );
  99. static HRESULT AddOutputNode(
  100. IMFTopology *pTopology, // Topology.
  101. IMFActivate *pActivate, // Media sink activation object.
  102. DWORD dwId, // Identifier of the stream sink.
  103. IMFTopologyNode **ppNode // Receives the node pointer.
  104. );
  105. static HRESULT AddTransformNode(
  106. IMFTopology *pTopology, // Topology.
  107. IMFTransform *pMFT, // MFT.
  108. DWORD dwId, // Identifier of the stream sink.
  109. IMFTopologyNode **ppNode // Receives the node pointer.
  110. );
  111. static HRESULT AddSourceNode(
  112. IMFTopology *pTopology, // Topology.
  113. IMFMediaSource *pSource, // Media source.
  114. IMFPresentationDescriptor *pPD, // Presentation descriptor.
  115. IMFStreamDescriptor *pSD, // Stream descriptor.
  116. IMFTopologyNode **ppNode // Receives the node pointer.
  117. );
  118. static HRESULT CreateTopology(
  119. IMFMediaSource *pSource, // Media source
  120. IMFTransform *pTransform, // Transform filter (e.g. encoder or decoder) to insert between the source and Sink. NULL is valid.
  121. IMFActivate *pSinkActivateMain, // Main sink (e.g. sample grabber or EVR).
  122. IMFActivate *pSinkActivatePreview, // Preview sink. Optional. Could be NULL.
  123. IMFMediaType *pIputTypeMain, // Main sink input MediaType
  124. IMFTopology **ppTopo // Receives the newly created topology
  125. );
  126. static HRESULT ResolveTopology(
  127. IMFTopology *pInputTopo, // A pointer to the IMFTopology interface of the partial topology to be resolved.
  128. IMFTopology **ppOutputTopo, // Receives a pointer to the IMFTopology interface of the completed topology. The caller must release the interface.
  129. IMFTopology *pCurrentTopo = NULL // A pointer to the IMFTopology interface of the previous full topology. The topology loader can re-use objects from this topology in the new topology. This parameter can be NULL.
  130. );
  131. static HRESULT FindNodeObject(
  132. IMFTopology *pInputTopo, // The Topology containing the node to find
  133. TOPOID qwTopoNodeID, //The identifier for the node
  134. void** ppObject // Receives the Object
  135. );
  136. static HRESULT CreateMediaSinkActivate(
  137. IMFStreamDescriptor *pSourceSD, // Pointer to the stream descriptor.
  138. HWND hVideoWindow, // Handle to the video clipping window.
  139. IMFActivate **ppActivate
  140. );
  141. static HRESULT SetMediaType(
  142. IMFMediaSource *pSource, // Media source.
  143. IMFMediaType* pMediaType // Media Type.
  144. );
  145. static HRESULT SetVideoWindow(
  146. IMFTopology *pTopology, // Topology.
  147. IMFMediaSource *pSource, // Media source.
  148. HWND hVideoWnd // Window for video playback.
  149. );
  150. static HRESULT RunSession(
  151. IMFMediaSession *pSession, // Session to run
  152. IMFTopology *pTopology // The toppology
  153. );
  154. static HRESULT ShutdownSession(
  155. IMFMediaSession *pSession, // The Session
  156. IMFMediaSource *pSource = NULL // Source to shutdown (optional)
  157. );
  158. static HRESULT PauseSession(
  159. IMFMediaSession *pSession, // The session
  160. IMFMediaSource *pSource = NULL// Source to pause (optional)
  161. );
  162. static INT GetSupportedSubTypeIndex(
  163. IMFMediaSource *pSource, // The source
  164. const GUID& mediaType, // The MediaType
  165. const VideoSubTypeGuidPair* subTypes, UINT subTypesCount // List of preferred subtypes (in ascending order)
  166. );
  167. static HRESULT IsSupported(
  168. IMFPresentationDescriptor *pPD,
  169. DWORD cStreamIndex,
  170. UINT32 nWidth,
  171. UINT32 nHeight,
  172. UINT32 nFps,
  173. const GUID& guidFormat,
  174. BOOL* pbSupportedSize,
  175. BOOL* pbSupportedFps,
  176. BOOL* pbSupportedFormat
  177. );
  178. static HRESULT IsSupported(
  179. IMFPresentationDescriptor *pPD,
  180. DWORD cStreamIndex,
  181. IMFMediaType* pMediaType,
  182. BOOL* pbSupportedSize,
  183. BOOL* pbSupportedFps,
  184. BOOL* pbSupportedFormat
  185. );
  186. static HRESULT IsSupportedByInput(
  187. IMFPresentationDescriptor *pPD,
  188. DWORD cStreamIndex,
  189. IMFTopologyNode *pNode,
  190. BOOL* pbSupportedSize,
  191. BOOL* pbSupportedFps,
  192. BOOL* pbSupportedFormat
  193. );
  194. static HRESULT ConnectConverters(
  195. IMFTopologyNode *pNode,
  196. DWORD dwOutputIndex,
  197. IMFTopologyNode *pNodeConvFrameRate,
  198. IMFTopologyNode *pNodeConvColor,
  199. IMFTopologyNode *pNodeConvSize
  200. );
  201. static HRESULT GetBestFormat(
  202. IMFMediaSource *pSource,
  203. const GUID *pSubType,
  204. UINT32 nWidth,
  205. UINT32 nHeight,
  206. UINT32 nFps,
  207. UINT32 *pnWidth,
  208. UINT32 *pnHeight,
  209. UINT32 *pnFps,
  210. const VideoSubTypeGuidPair **pSubTypeGuidPair
  211. );
  212. static HWND GetConsoleHwnd(void);
  213. template <class Q>
  214. static HRESULT GetTopoNodeObject(IMFTopologyNode *pNode, Q **ppObject) {
  215. IUnknown *pUnk = NULL; // zero output
  216. HRESULT hr = pNode->GetObject(&pUnk);
  217. if (SUCCEEDED(hr)) {
  218. pUnk->QueryInterface(IID_PPV_ARGS(ppObject));
  219. pUnk->Release();
  220. }
  221. return hr;
  222. }
  223. private:
  224. static BOOL g_bStarted;
  225. static DWORD g_dwMajorVersion;
  226. static DWORD g_dwMinorVersion;
  227. static BOOL g_bLowLatencyH264Checked;
  228. static BOOL g_bLowLatencyH264Supported;
  229. static BOOL g_bLowLatencyH264SupportsMaxSliceSize;
  230. static BOOL g_bD3D9Checked;
  231. static BOOL g_bD3D9Supported;
  232. public:
  233. static const TOPOID g_ullTopoIdSinkMain;
  234. static const TOPOID g_ullTopoIdSinkPreview;
  235. static const TOPOID g_ullTopoIdSource;
  236. static const TOPOID g_ullTopoIdVideoProcessor;
  237. };
  238. #endif /* PLUGIN_WIN_MF_UTILS_H */