/content/media/wmf/WMFUtils.cpp

https://github.com/marcussaad/firefox · C++ · 384 lines · 340 code · 37 blank · 7 comment · 12 complexity · c1f162f5b21fc78b455aec56965e14a8 MD5 · raw file

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim:set ts=2 sw=2 sts=2 et cindent: */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #include "WMFUtils.h"
  7. #include "mozilla/StandardInteger.h"
  8. #include "mozilla/RefPtr.h"
  9. #include "prlog.h"
  10. #include "nsThreadUtils.h"
  11. namespace mozilla {
  12. struct GuidToName {
  13. GUID guid;
  14. const char* name;
  15. };
  16. #define GUID_TO_NAME_ENTRY(g) { g, #g }
  17. #define INTERFACE_TO_NAME_ENTRY(i) {IID_##i, #i }
  18. GuidToName GuidToNameTable[] = {
  19. GUID_TO_NAME_ENTRY(MF_MT_MAJOR_TYPE),
  20. GUID_TO_NAME_ENTRY(MF_MT_MAJOR_TYPE),
  21. GUID_TO_NAME_ENTRY(MF_MT_SUBTYPE),
  22. GUID_TO_NAME_ENTRY(MF_MT_ALL_SAMPLES_INDEPENDENT),
  23. GUID_TO_NAME_ENTRY(MF_MT_FIXED_SIZE_SAMPLES),
  24. GUID_TO_NAME_ENTRY(MF_MT_COMPRESSED),
  25. GUID_TO_NAME_ENTRY(MF_MT_SAMPLE_SIZE),
  26. GUID_TO_NAME_ENTRY(MF_MT_WRAPPED_TYPE),
  27. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
  28. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
  29. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND),
  30. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_AVG_BYTES_PER_SECOND),
  31. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_BLOCK_ALIGNMENT),
  32. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_BITS_PER_SAMPLE),
  33. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE),
  34. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_SAMPLES_PER_BLOCK),
  35. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
  36. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_FOLDDOWN_MATRIX),
  37. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_PEAKREF),
  38. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_PEAKTARGET),
  39. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_AVGREF),
  40. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_WMADRC_AVGTARGET),
  41. GUID_TO_NAME_ENTRY(MF_MT_AUDIO_PREFER_WAVEFORMATEX),
  42. GUID_TO_NAME_ENTRY(MF_MT_AAC_PAYLOAD_TYPE),
  43. GUID_TO_NAME_ENTRY(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION),
  44. GUID_TO_NAME_ENTRY(MF_MT_FRAME_SIZE),
  45. GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE),
  46. GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE_RANGE_MAX),
  47. GUID_TO_NAME_ENTRY(MF_MT_FRAME_RATE_RANGE_MIN),
  48. GUID_TO_NAME_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
  49. GUID_TO_NAME_ENTRY(MF_MT_DRM_FLAGS),
  50. GUID_TO_NAME_ENTRY(MF_MT_PAD_CONTROL_FLAGS),
  51. GUID_TO_NAME_ENTRY(MF_MT_SOURCE_CONTENT_HINT),
  52. GUID_TO_NAME_ENTRY(MF_MT_VIDEO_CHROMA_SITING),
  53. GUID_TO_NAME_ENTRY(MF_MT_INTERLACE_MODE),
  54. GUID_TO_NAME_ENTRY(MF_MT_TRANSFER_FUNCTION),
  55. GUID_TO_NAME_ENTRY(MF_MT_VIDEO_PRIMARIES),
  56. GUID_TO_NAME_ENTRY(MF_MT_CUSTOM_VIDEO_PRIMARIES),
  57. GUID_TO_NAME_ENTRY(MF_MT_YUV_MATRIX),
  58. GUID_TO_NAME_ENTRY(MF_MT_VIDEO_LIGHTING),
  59. GUID_TO_NAME_ENTRY(MF_MT_VIDEO_NOMINAL_RANGE),
  60. GUID_TO_NAME_ENTRY(MF_MT_GEOMETRIC_APERTURE),
  61. GUID_TO_NAME_ENTRY(MF_MT_MINIMUM_DISPLAY_APERTURE),
  62. GUID_TO_NAME_ENTRY(MF_MT_PAN_SCAN_APERTURE),
  63. GUID_TO_NAME_ENTRY(MF_MT_PAN_SCAN_ENABLED),
  64. GUID_TO_NAME_ENTRY(MF_MT_AVG_BITRATE),
  65. GUID_TO_NAME_ENTRY(MF_MT_AVG_BIT_ERROR_RATE),
  66. GUID_TO_NAME_ENTRY(MF_MT_MAX_KEYFRAME_SPACING),
  67. GUID_TO_NAME_ENTRY(MF_MT_DEFAULT_STRIDE),
  68. GUID_TO_NAME_ENTRY(MF_MT_PALETTE),
  69. GUID_TO_NAME_ENTRY(MF_MT_USER_DATA),
  70. GUID_TO_NAME_ENTRY(MF_MT_AM_FORMAT_TYPE),
  71. GUID_TO_NAME_ENTRY(MF_MT_MPEG_START_TIME_CODE),
  72. GUID_TO_NAME_ENTRY(MF_MT_MPEG2_PROFILE),
  73. GUID_TO_NAME_ENTRY(MF_MT_MPEG2_LEVEL),
  74. GUID_TO_NAME_ENTRY(MF_MT_MPEG2_FLAGS),
  75. GUID_TO_NAME_ENTRY(MF_MT_MPEG_SEQUENCE_HEADER),
  76. GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_SRC_PACK_0),
  77. GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_CTRL_PACK_0),
  78. GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_SRC_PACK_1),
  79. GUID_TO_NAME_ENTRY(MF_MT_DV_AAUX_CTRL_PACK_1),
  80. GUID_TO_NAME_ENTRY(MF_MT_DV_VAUX_SRC_PACK),
  81. GUID_TO_NAME_ENTRY(MF_MT_DV_VAUX_CTRL_PACK),
  82. GUID_TO_NAME_ENTRY(MF_MT_ARBITRARY_HEADER),
  83. GUID_TO_NAME_ENTRY(MF_MT_ARBITRARY_FORMAT),
  84. GUID_TO_NAME_ENTRY(MF_MT_IMAGE_LOSS_TOLERANT),
  85. GUID_TO_NAME_ENTRY(MF_MT_MPEG4_SAMPLE_DESCRIPTION),
  86. GUID_TO_NAME_ENTRY(MF_MT_MPEG4_CURRENT_SAMPLE_ENTRY),
  87. GUID_TO_NAME_ENTRY(MF_MT_ORIGINAL_4CC),
  88. GUID_TO_NAME_ENTRY(MF_MT_ORIGINAL_WAVE_FORMAT_TAG),
  89. GUID_TO_NAME_ENTRY(MFMediaType_Audio),
  90. GUID_TO_NAME_ENTRY(MFMediaType_Video),
  91. GUID_TO_NAME_ENTRY(MFMediaType_Protected),
  92. GUID_TO_NAME_ENTRY(MFMediaType_SAMI),
  93. GUID_TO_NAME_ENTRY(MFMediaType_Script),
  94. GUID_TO_NAME_ENTRY(MFMediaType_Image),
  95. GUID_TO_NAME_ENTRY(MFMediaType_HTML),
  96. GUID_TO_NAME_ENTRY(MFMediaType_Binary),
  97. GUID_TO_NAME_ENTRY(MFMediaType_FileTransfer),
  98. GUID_TO_NAME_ENTRY(MFVideoFormat_AI44),
  99. GUID_TO_NAME_ENTRY(MFVideoFormat_ARGB32),
  100. GUID_TO_NAME_ENTRY(MFVideoFormat_AYUV),
  101. GUID_TO_NAME_ENTRY(MFVideoFormat_DV25),
  102. GUID_TO_NAME_ENTRY(MFVideoFormat_DV50),
  103. GUID_TO_NAME_ENTRY(MFVideoFormat_DVH1),
  104. GUID_TO_NAME_ENTRY(MFVideoFormat_DVSD),
  105. GUID_TO_NAME_ENTRY(MFVideoFormat_DVSL),
  106. GUID_TO_NAME_ENTRY(MFVideoFormat_H264),
  107. GUID_TO_NAME_ENTRY(MFVideoFormat_I420),
  108. GUID_TO_NAME_ENTRY(MFVideoFormat_IYUV),
  109. GUID_TO_NAME_ENTRY(MFVideoFormat_M4S2),
  110. GUID_TO_NAME_ENTRY(MFVideoFormat_MJPG),
  111. GUID_TO_NAME_ENTRY(MFVideoFormat_MP43),
  112. GUID_TO_NAME_ENTRY(MFVideoFormat_MP4S),
  113. GUID_TO_NAME_ENTRY(MFVideoFormat_MP4V),
  114. GUID_TO_NAME_ENTRY(MFVideoFormat_MPG1),
  115. GUID_TO_NAME_ENTRY(MFVideoFormat_MSS1),
  116. GUID_TO_NAME_ENTRY(MFVideoFormat_MSS2),
  117. GUID_TO_NAME_ENTRY(MFVideoFormat_NV11),
  118. GUID_TO_NAME_ENTRY(MFVideoFormat_NV12),
  119. GUID_TO_NAME_ENTRY(MFVideoFormat_P010),
  120. GUID_TO_NAME_ENTRY(MFVideoFormat_P016),
  121. GUID_TO_NAME_ENTRY(MFVideoFormat_P210),
  122. GUID_TO_NAME_ENTRY(MFVideoFormat_P216),
  123. GUID_TO_NAME_ENTRY(MFVideoFormat_RGB24),
  124. GUID_TO_NAME_ENTRY(MFVideoFormat_RGB32),
  125. GUID_TO_NAME_ENTRY(MFVideoFormat_RGB555),
  126. GUID_TO_NAME_ENTRY(MFVideoFormat_RGB565),
  127. GUID_TO_NAME_ENTRY(MFVideoFormat_RGB8),
  128. GUID_TO_NAME_ENTRY(MFVideoFormat_UYVY),
  129. GUID_TO_NAME_ENTRY(MFVideoFormat_v210),
  130. GUID_TO_NAME_ENTRY(MFVideoFormat_v410),
  131. GUID_TO_NAME_ENTRY(MFVideoFormat_WMV1),
  132. GUID_TO_NAME_ENTRY(MFVideoFormat_WMV2),
  133. GUID_TO_NAME_ENTRY(MFVideoFormat_WMV3),
  134. GUID_TO_NAME_ENTRY(MFVideoFormat_WVC1),
  135. GUID_TO_NAME_ENTRY(MFVideoFormat_Y210),
  136. GUID_TO_NAME_ENTRY(MFVideoFormat_Y216),
  137. GUID_TO_NAME_ENTRY(MFVideoFormat_Y410),
  138. GUID_TO_NAME_ENTRY(MFVideoFormat_Y416),
  139. GUID_TO_NAME_ENTRY(MFVideoFormat_Y41P),
  140. GUID_TO_NAME_ENTRY(MFVideoFormat_Y41T),
  141. GUID_TO_NAME_ENTRY(MFVideoFormat_YUY2),
  142. GUID_TO_NAME_ENTRY(MFVideoFormat_YV12),
  143. GUID_TO_NAME_ENTRY(MFVideoFormat_YVYU),
  144. GUID_TO_NAME_ENTRY(MFAudioFormat_PCM),
  145. GUID_TO_NAME_ENTRY(MFAudioFormat_Float),
  146. GUID_TO_NAME_ENTRY(MFAudioFormat_DTS),
  147. GUID_TO_NAME_ENTRY(MFAudioFormat_Dolby_AC3_SPDIF),
  148. GUID_TO_NAME_ENTRY(MFAudioFormat_DRM),
  149. GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudioV8),
  150. GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudioV9),
  151. GUID_TO_NAME_ENTRY(MFAudioFormat_WMAudio_Lossless),
  152. GUID_TO_NAME_ENTRY(MFAudioFormat_WMASPDIF),
  153. GUID_TO_NAME_ENTRY(MFAudioFormat_MSP1),
  154. GUID_TO_NAME_ENTRY(MFAudioFormat_MP3),
  155. GUID_TO_NAME_ENTRY(MFAudioFormat_MPEG),
  156. GUID_TO_NAME_ENTRY(MFAudioFormat_AAC),
  157. GUID_TO_NAME_ENTRY(MFAudioFormat_ADTS),
  158. // Interfaces which may be implemented by WMFByteStream.
  159. INTERFACE_TO_NAME_ENTRY(IUnknown),
  160. INTERFACE_TO_NAME_ENTRY(IMFByteStream),
  161. INTERFACE_TO_NAME_ENTRY(IMFMediaSource),
  162. INTERFACE_TO_NAME_ENTRY(IMFAttributes),
  163. INTERFACE_TO_NAME_ENTRY(IMFByteStreamBuffering),
  164. };
  165. nsCString GetGUIDName(const GUID& guid)
  166. {
  167. unsigned numTypes = NS_ARRAY_LENGTH(GuidToNameTable);
  168. for (unsigned i = 0; i < numTypes; i++) {
  169. if (guid == GuidToNameTable[i].guid) {
  170. return nsDependentCString(GuidToNameTable[i].name);
  171. }
  172. }
  173. WCHAR* name = nullptr;
  174. HRESULT hr = StringFromCLSID(guid , &name);
  175. if (FAILED(hr)) {
  176. return nsDependentCString("GuidUnknown");
  177. }
  178. nsCString name_u8(NS_ConvertUTF16toUTF8(nsDependentString((PRUnichar*)(name))));
  179. CoTaskMemFree(name);
  180. return name_u8;
  181. }
  182. bool
  183. SourceReaderHasStream(IMFSourceReader* aReader, const DWORD aIndex)
  184. {
  185. RefPtr<IMFMediaType> nativeType;
  186. HRESULT hr = aReader->GetNativeMediaType(aIndex, 0, byRef(nativeType));
  187. return FAILED(hr) ? false : true;
  188. }
  189. namespace wmf {
  190. static bool sDLLsLoaded = false;
  191. static bool sFailedToLoadDlls = false;
  192. struct WMFModule {
  193. const char* name;
  194. HMODULE handle;
  195. };
  196. static WMFModule sDLLs[] = {
  197. { "mfplat.dll", NULL },
  198. { "mfreadwrite.dll", NULL },
  199. { "propsys.dll", NULL },
  200. { "mf.dll", NULL }
  201. };
  202. HRESULT
  203. LoadDLLs()
  204. {
  205. NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
  206. if (sDLLsLoaded) {
  207. return S_OK;
  208. }
  209. if (sFailedToLoadDlls) {
  210. return E_FAIL;
  211. }
  212. // Try to load all the required DLLs.
  213. uint32_t dllLength = NS_ARRAY_LENGTH(sDLLs);
  214. for (uint32_t i = 0; i < dllLength; i++) {
  215. sDLLs[i].handle = LoadLibraryA(sDLLs[i].name);
  216. if (!sDLLs[i].handle) {
  217. sFailedToLoadDlls = true;
  218. UnloadDLLs();
  219. wmf::MFShutdown();
  220. return E_FAIL;
  221. }
  222. }
  223. sDLLsLoaded = true;
  224. return S_OK;
  225. }
  226. HRESULT
  227. UnloadDLLs()
  228. {
  229. NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
  230. uint32_t length = NS_ARRAY_LENGTH(sDLLs);
  231. for (uint32_t i = 0; i < length; i++) {
  232. if (sDLLs[i].handle) {
  233. FreeLibrary(sDLLs[i].handle);
  234. sDLLs[i].handle = NULL;
  235. }
  236. sDLLsLoaded = false;
  237. }
  238. return S_OK;
  239. }
  240. #define ENSURE_FUNCTION_PTR(FunctionName, DLL) \
  241. static FunctionName##Ptr_t FunctionName##Ptr = nullptr; \
  242. if (!FunctionName##Ptr) { \
  243. FunctionName##Ptr = (FunctionName##Ptr_t)GetProcAddress(GetModuleHandle( #DLL ), #FunctionName ); \
  244. if (!FunctionName##Ptr) { \
  245. NS_WARNING("Failed to get GetProcAddress of " #FunctionName " from " #DLL ); \
  246. return E_FAIL; \
  247. } \
  248. }
  249. #define DECL_FUNCTION_PTR(FunctionName, ...) \
  250. typedef HRESULT (STDMETHODCALLTYPE * FunctionName##Ptr_t)(__VA_ARGS__)
  251. HRESULT
  252. MFStartup()
  253. {
  254. DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
  255. ENSURE_FUNCTION_PTR(MFStartup, Mfplat.dll)
  256. return MFStartupPtr(MF_VERSION, MFSTARTUP_FULL);
  257. }
  258. HRESULT
  259. MFShutdown()
  260. {
  261. DECL_FUNCTION_PTR(MFShutdown);
  262. ENSURE_FUNCTION_PTR(MFShutdown, Mfplat.dll)
  263. return (MFShutdownPtr)();
  264. }
  265. HRESULT MFCreateAsyncResult(IUnknown *aUnkObject,
  266. IMFAsyncCallback *aCallback,
  267. IUnknown *aUnkState,
  268. IMFAsyncResult **aOutAsyncResult)
  269. {
  270. DECL_FUNCTION_PTR(MFCreateAsyncResult, IUnknown*, IMFAsyncCallback*, IUnknown*, IMFAsyncResult**);
  271. ENSURE_FUNCTION_PTR(MFCreateAsyncResult, Mfplat.dll)
  272. return (MFCreateAsyncResultPtr)(aUnkObject, aCallback, aUnkState, aOutAsyncResult);
  273. }
  274. HRESULT
  275. MFInvokeCallback(IMFAsyncResult *aAsyncResult)
  276. {
  277. DECL_FUNCTION_PTR(MFInvokeCallback, IMFAsyncResult*);
  278. ENSURE_FUNCTION_PTR(MFInvokeCallback, Mfplat.dll);
  279. return (MFInvokeCallbackPtr)(aAsyncResult);
  280. }
  281. HRESULT
  282. MFCreateMediaType(IMFMediaType **aOutMFType)
  283. {
  284. DECL_FUNCTION_PTR(MFCreateMediaType, IMFMediaType**);
  285. ENSURE_FUNCTION_PTR(MFCreateMediaType, Mfplat.dll)
  286. return (MFCreateMediaTypePtr)(aOutMFType);
  287. }
  288. HRESULT
  289. MFCreateSourceReaderFromByteStream(IMFByteStream *aByteStream,
  290. IMFAttributes *aAttributes,
  291. IMFSourceReader **aOutSourceReader)
  292. {
  293. DECL_FUNCTION_PTR(MFCreateSourceReaderFromByteStream, IMFByteStream*, IMFAttributes*, IMFSourceReader**);
  294. ENSURE_FUNCTION_PTR(MFCreateSourceReaderFromByteStream, Mfreadwrite.dll)
  295. return (MFCreateSourceReaderFromByteStreamPtr)(aByteStream,
  296. aAttributes,
  297. aOutSourceReader);
  298. }
  299. HRESULT
  300. PropVariantToUInt32(REFPROPVARIANT aPropvar, ULONG *aOutUL)
  301. {
  302. DECL_FUNCTION_PTR(PropVariantToUInt32, REFPROPVARIANT, ULONG *);
  303. ENSURE_FUNCTION_PTR(PropVariantToUInt32, Propsys.dll)
  304. return (PropVariantToUInt32Ptr)(aPropvar, aOutUL);
  305. }
  306. HRESULT PropVariantToInt64(REFPROPVARIANT aPropVar, LONGLONG *aOutLL)
  307. {
  308. DECL_FUNCTION_PTR(PropVariantToInt64, REFPROPVARIANT, LONGLONG *);
  309. ENSURE_FUNCTION_PTR(PropVariantToInt64, Propsys.dll)
  310. return (PropVariantToInt64Ptr)(aPropVar, aOutLL);
  311. }
  312. HRESULT MFTGetInfo(CLSID aClsidMFT,
  313. LPWSTR *aOutName,
  314. MFT_REGISTER_TYPE_INFO **aOutInputTypes,
  315. UINT32 *aOutNumInputTypes,
  316. MFT_REGISTER_TYPE_INFO **aOutOutputTypes,
  317. UINT32 *aOutNumOutputTypes,
  318. IMFAttributes **aOutAttributes)
  319. {
  320. DECL_FUNCTION_PTR(MFTGetInfo, CLSID, LPWSTR*, MFT_REGISTER_TYPE_INFO**, UINT32*, MFT_REGISTER_TYPE_INFO**, UINT32*, IMFAttributes**);
  321. ENSURE_FUNCTION_PTR(MFTGetInfo, Mfplat.dll)
  322. return (MFTGetInfoPtr)(aClsidMFT,
  323. aOutName,
  324. aOutInputTypes,
  325. aOutNumInputTypes,
  326. aOutOutputTypes,
  327. aOutNumOutputTypes,
  328. aOutAttributes);
  329. }
  330. HRESULT MFGetStrideForBitmapInfoHeader(DWORD aFormat,
  331. DWORD aWidth,
  332. LONG *aOutStride)
  333. {
  334. DECL_FUNCTION_PTR(MFGetStrideForBitmapInfoHeader, DWORD, DWORD, LONG*);
  335. ENSURE_FUNCTION_PTR(MFGetStrideForBitmapInfoHeader, Mfplat.dll)
  336. return (MFGetStrideForBitmapInfoHeaderPtr)(aFormat, aWidth, aOutStride);
  337. }
  338. HRESULT MFCreateSourceReaderFromURL(LPCWSTR aURL,
  339. IMFAttributes *aAttributes,
  340. IMFSourceReader **aSourceReader)
  341. {
  342. DECL_FUNCTION_PTR(MFCreateSourceReaderFromURL, LPCWSTR, IMFAttributes*, IMFSourceReader**);
  343. ENSURE_FUNCTION_PTR(MFCreateSourceReaderFromURL, Mfreadwrite.dll)
  344. return (MFCreateSourceReaderFromURLPtr)(aURL, aAttributes, aSourceReader);
  345. }
  346. } // end namespace wmf
  347. } // end namespace mozilla