tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WMFUtils.cpp (22775B)


      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 
      7 #include "WMFUtils.h"
      8 
      9 #include <initguid.h>
     10 #include <mfidl.h>
     11 #include <shlobj.h>
     12 #include <shlwapi.h>
     13 #include <stdint.h>
     14 
     15 #ifdef MOZ_AV1
     16 #  include "AOMDecoder.h"
     17 #endif
     18 #include "MP4Decoder.h"
     19 #include "VPXDecoder.h"
     20 #include "VideoUtils.h"
     21 #include "mozilla/CheckedInt.h"
     22 #include "mozilla/Logging.h"
     23 #include "mozilla/mscom/EnsureMTA.h"
     24 #include "nsTArray.h"
     25 #include "nsThreadUtils.h"
     26 #include "nsWindowsHelpers.h"
     27 #include "prenv.h"
     28 
     29 #ifndef WAVE_FORMAT_OPUS
     30 #  define WAVE_FORMAT_OPUS 0x704F
     31 #endif
     32 DEFINE_GUID(MEDIASUBTYPE_OPUS, WAVE_FORMAT_OPUS, 0x000, 0x0010, 0x80, 0x00,
     33            0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
     34 
     35 namespace mozilla {
     36 
     37 using media::TimeUnit;
     38 
     39 bool StreamTypeIsVideo(const WMFStreamType& aType) {
     40  switch (aType) {
     41    case WMFStreamType::H264:
     42    case WMFStreamType::VP8:
     43    case WMFStreamType::VP9:
     44    case WMFStreamType::AV1:
     45    case WMFStreamType::HEVC:
     46      return true;
     47    default:
     48      return false;
     49  }
     50 }
     51 
     52 bool StreamTypeIsAudio(const WMFStreamType& aType) {
     53  switch (aType) {
     54    case WMFStreamType::MP3:
     55    case WMFStreamType::AAC:
     56    case WMFStreamType::OPUS:
     57    case WMFStreamType::VORBIS:
     58      return true;
     59    default:
     60      return false;
     61  }
     62 }
     63 
     64 WMFStreamType GetStreamTypeFromMimeType(const nsCString& aMimeType) {
     65  if (MP4Decoder::IsH264(aMimeType)) {
     66    return WMFStreamType::H264;
     67  }
     68  if (VPXDecoder::IsVP8(aMimeType)) {
     69    return WMFStreamType::VP8;
     70  }
     71  if (VPXDecoder::IsVP9(aMimeType)) {
     72    return WMFStreamType::VP9;
     73  }
     74 #ifdef MOZ_AV1
     75  if (AOMDecoder::IsAV1(aMimeType)) {
     76    return WMFStreamType::AV1;
     77  }
     78 #endif
     79  if (MP4Decoder::IsHEVC(aMimeType)) {
     80    return WMFStreamType::HEVC;
     81  }
     82  if (aMimeType.EqualsLiteral("audio/mp4a-latm") ||
     83      aMimeType.EqualsLiteral("audio/mp4")) {
     84    return WMFStreamType::AAC;
     85  }
     86  if (aMimeType.EqualsLiteral("audio/mpeg")) {
     87    return WMFStreamType::MP3;
     88  }
     89  if (aMimeType.EqualsLiteral("audio/opus")) {
     90    return WMFStreamType::OPUS;
     91  }
     92  if (aMimeType.EqualsLiteral("audio/vorbis")) {
     93    return WMFStreamType::VORBIS;
     94  }
     95  return WMFStreamType::Unknown;
     96 }
     97 
     98 GUID GetOutputSubType(const gfx::ColorDepth& aColorDepth,
     99                      bool aIsHardwareDecoding) {
    100  switch (aColorDepth) {
    101    case gfx::ColorDepth::COLOR_8:
    102      return aIsHardwareDecoding ? MFVideoFormat_NV12 : MFVideoFormat_YV12;
    103    case gfx::ColorDepth::COLOR_10:
    104      return MFVideoFormat_P010;
    105    case gfx::ColorDepth::COLOR_12:
    106    case gfx::ColorDepth::COLOR_16:
    107      return MFVideoFormat_P016;
    108    default:
    109      MOZ_ASSERT_UNREACHABLE("Unexpected color depth");
    110      return GUID_NULL;
    111  }
    112 }
    113 
    114 #define ENUM_TO_STR(enumVal)          \
    115  if (aSubtype == enumVal) {          \
    116    return nsPrintfCString{#enumVal}; \
    117  }
    118 
    119 // Audio :
    120 // https://learn.microsoft.com/en-us/windows/win32/medfound/audio-subtype-guids
    121 // Video :
    122 // https://learn.microsoft.com/en-us/windows/win32/medfound/video-subtype-guids
    123 nsCString GetSubTypeStr(const GUID& aSubtype) {
    124  // output format
    125  ENUM_TO_STR(MFAudioFormat_PCM)
    126  ENUM_TO_STR(MFAudioFormat_Float)
    127  ENUM_TO_STR(MFVideoFormat_NV12)
    128  ENUM_TO_STR(MFVideoFormat_YV12)
    129  ENUM_TO_STR(MFVideoFormat_IYUV)
    130  ENUM_TO_STR(MFVideoFormat_P010)
    131  ENUM_TO_STR(MFVideoFormat_P016)
    132  ENUM_TO_STR(MFVideoFormat_ARGB32)
    133  ENUM_TO_STR(MFVideoFormat_RGB32)
    134  ENUM_TO_STR(MFVideoFormat_A2R10G10B10)
    135  ENUM_TO_STR(MFVideoFormat_A16B16G16R16F)
    136  ENUM_TO_STR(MFVideoFormat_I420)
    137  ENUM_TO_STR(MFVideoFormat_YUY2)
    138  // codec
    139  ENUM_TO_STR(MFAudioFormat_MP3)
    140  ENUM_TO_STR(MFAudioFormat_AAC)
    141  ENUM_TO_STR(MFAudioFormat_Vorbis)
    142  ENUM_TO_STR(MFAudioFormat_Opus)
    143  ENUM_TO_STR(MFVideoFormat_H264)
    144  ENUM_TO_STR(MFVideoFormat_VP80)
    145  ENUM_TO_STR(MFVideoFormat_VP90)
    146  ENUM_TO_STR(MFVideoFormat_AV1)
    147  ENUM_TO_STR(MFVideoFormat_HEVC)
    148  LPOLESTR subtypeStr;
    149  StringFromCLSID(aSubtype, &subtypeStr);
    150  nsPrintfCString errorMsg("Unknown output subtype: %S", subtypeStr);
    151  CoTaskMemFree(subtypeStr);
    152  return errorMsg;
    153 }
    154 
    155 #undef ENUM_TO_STR
    156 
    157 HRESULT
    158 HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames) {
    159  MOZ_ASSERT(aOutFrames);
    160  const int64_t HNS_PER_S = USECS_PER_S * 10;
    161  CheckedInt<int64_t> i = aHNs;
    162  i *= aRate;
    163  i /= HNS_PER_S;
    164  NS_ENSURE_TRUE(i.isValid(), E_FAIL);
    165  *aOutFrames = i.value();
    166  return S_OK;
    167 }
    168 
    169 HRESULT
    170 GetDefaultStride(IMFMediaType* aType, uint32_t aWidth, uint32_t* aOutStride) {
    171  // Try to get the default stride from the media type.
    172  HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, aOutStride);
    173  if (SUCCEEDED(hr)) {
    174    return S_OK;
    175  }
    176 
    177  // Stride attribute not set, calculate it.
    178  GUID subtype = GUID_NULL;
    179 
    180  hr = aType->GetGUID(MF_MT_SUBTYPE, &subtype);
    181  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
    182 
    183  hr = wmf::MFGetStrideForBitmapInfoHeader(subtype.Data1, aWidth,
    184                                           (LONG*)(aOutStride));
    185  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
    186 
    187  return hr;
    188 }
    189 
    190 Maybe<gfx::YUVColorSpace> GetYUVColorSpace(IMFMediaType* aType) {
    191  UINT32 yuvColorMatrix;
    192  HRESULT hr = aType->GetUINT32(MF_MT_YUV_MATRIX, &yuvColorMatrix);
    193  NS_ENSURE_TRUE(SUCCEEDED(hr), {});
    194 
    195  switch (yuvColorMatrix) {
    196    case MFVideoTransferMatrix_BT2020_10:
    197    case MFVideoTransferMatrix_BT2020_12:
    198      return Some(gfx::YUVColorSpace::BT2020);
    199    case MFVideoTransferMatrix_BT709:
    200      return Some(gfx::YUVColorSpace::BT709);
    201    case MFVideoTransferMatrix_BT601:
    202      return Some(gfx::YUVColorSpace::BT601);
    203    default:
    204      MOZ_ASSERT_UNREACHABLE("Unhandled MFVideoTransferMatrix_?");
    205      return {};
    206  }
    207 }
    208 
    209 int32_t MFOffsetToInt32(const MFOffset& aOffset) {
    210  return AssertedCast<int32_t>(AssertedCast<float>(aOffset.value) +
    211                               (AssertedCast<float>(aOffset.fract) / 65536.0f));
    212 }
    213 
    214 TimeUnit GetSampleDuration(IMFSample* aSample) {
    215  NS_ENSURE_TRUE(aSample, TimeUnit::Invalid());
    216  int64_t duration = 0;
    217  HRESULT hr = aSample->GetSampleDuration(&duration);
    218  NS_ENSURE_TRUE(SUCCEEDED(hr), TimeUnit::Invalid());
    219  return TimeUnit::FromMicroseconds(HNsToUsecs(duration));
    220 }
    221 
    222 TimeUnit GetSampleTime(IMFSample* aSample) {
    223  NS_ENSURE_TRUE(aSample, TimeUnit::Invalid());
    224  LONGLONG timestampHns = 0;
    225  HRESULT hr = aSample->GetSampleTime(&timestampHns);
    226  NS_ENSURE_TRUE(SUCCEEDED(hr), TimeUnit::Invalid());
    227  return TimeUnit::FromMicroseconds(HNsToUsecs(timestampHns));
    228 }
    229 
    230 // Gets the sub-region of the video frame that should be displayed.
    231 // See:
    232 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
    233 HRESULT
    234 GetPictureRegion(IMFMediaType* aMediaType, gfx::IntRect& aOutPictureRegion) {
    235  // Determine if "pan and scan" is enabled for this media. If it is, we
    236  // only display a region of the video frame, not the entire frame.
    237  BOOL panScan =
    238      !!MFGetAttributeUINT32(aMediaType, MF_MT_PAN_SCAN_ENABLED, FALSE);
    239 
    240  // If pan and scan mode is enabled. Try to get the display region.
    241  HRESULT hr = E_FAIL;
    242  MFVideoArea videoArea;
    243  memset(&videoArea, 0, sizeof(MFVideoArea));
    244  if (panScan) {
    245    hr = aMediaType->GetBlob(MF_MT_PAN_SCAN_APERTURE, (UINT8*)&videoArea,
    246                             sizeof(MFVideoArea), nullptr);
    247  }
    248 
    249  // If we're not in pan-and-scan mode, or the pan-and-scan region is not set,
    250  // check for a minimimum display aperture.
    251  if (!panScan || hr == MF_E_ATTRIBUTENOTFOUND) {
    252    hr = aMediaType->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&videoArea,
    253                             sizeof(MFVideoArea), nullptr);
    254  }
    255 
    256  if (hr == MF_E_ATTRIBUTENOTFOUND) {
    257    // Minimum display aperture is not set, for "backward compatibility with
    258    // some components", check for a geometric aperture.
    259    hr = aMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&videoArea,
    260                             sizeof(MFVideoArea), nullptr);
    261  }
    262 
    263  if (SUCCEEDED(hr)) {
    264    // The media specified a picture region, return it.
    265    aOutPictureRegion = gfx::IntRect(MFOffsetToInt32(videoArea.OffsetX),
    266                                     MFOffsetToInt32(videoArea.OffsetY),
    267                                     videoArea.Area.cx, videoArea.Area.cy);
    268    return S_OK;
    269  }
    270 
    271  // No picture region defined, fall back to using the entire video area.
    272  UINT32 width = 0, height = 0;
    273  hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
    274  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
    275  NS_ENSURE_TRUE(width <= MAX_VIDEO_WIDTH, E_FAIL);
    276  NS_ENSURE_TRUE(height <= MAX_VIDEO_HEIGHT, E_FAIL);
    277 
    278  aOutPictureRegion = gfx::IntRect(0, 0, width, height);
    279  return S_OK;
    280 }
    281 
    282 nsString GetProgramW6432Path() {
    283  char* programPath = PR_GetEnvSecure("ProgramW6432");
    284  if (!programPath) {
    285    programPath = PR_GetEnvSecure("ProgramFiles");
    286  }
    287 
    288  if (!programPath) {
    289    return u"C:\\Program Files"_ns;
    290  }
    291  return NS_ConvertUTF8toUTF16(programPath);
    292 }
    293 
    294 const char* MFTMessageTypeToStr(MFT_MESSAGE_TYPE aMsg) {
    295  switch (aMsg) {
    296    case MFT_MESSAGE_COMMAND_FLUSH:
    297      return "MFT_MESSAGE_COMMAND_FLUSH";
    298    case MFT_MESSAGE_COMMAND_DRAIN:
    299      return "MFT_MESSAGE_COMMAND_DRAIN";
    300    case MFT_MESSAGE_COMMAND_MARKER:
    301      return "MFT_MESSAGE_COMMAND_MARKER";
    302    case MFT_MESSAGE_SET_D3D_MANAGER:
    303      return "MFT_MESSAGE_SET_D3D_MANAGER";
    304    case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
    305      return "MFT_MESSAGE_NOTIFY_BEGIN_STREAMING";
    306    case MFT_MESSAGE_NOTIFY_END_STREAMING:
    307      return "MFT_MESSAGE_NOTIFY_END_STREAMING";
    308    case MFT_MESSAGE_NOTIFY_END_OF_STREAM:
    309      return "MFT_MESSAGE_NOTIFY_END_OF_STREAM";
    310    case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
    311      return "MFT_MESSAGE_NOTIFY_START_OF_STREAM";
    312    case MFT_MESSAGE_DROP_SAMPLES:
    313      return "MFT_MESSAGE_DROP_SAMPLES";
    314    case MFT_MESSAGE_COMMAND_TICK:
    315      return "MFT_MESSAGE_COMMAND_TICK";
    316    case MFT_MESSAGE_NOTIFY_RELEASE_RESOURCES:
    317      return "MFT_MESSAGE_NOTIFY_RELEASE_RESOURCES";
    318    case MFT_MESSAGE_NOTIFY_REACQUIRE_RESOURCES:
    319      return "MFT_MESSAGE_NOTIFY_REACQUIRE_RESOURCES";
    320    case MFT_MESSAGE_NOTIFY_EVENT:
    321      return "MFT_MESSAGE_NOTIFY_EVENT";
    322    case MFT_MESSAGE_COMMAND_SET_OUTPUT_STREAM_STATE:
    323      return "MFT_MESSAGE_COMMAND_SET_OUTPUT_STREAM_STATE";
    324    case MFT_MESSAGE_COMMAND_FLUSH_OUTPUT_STREAM:
    325      return "MFT_MESSAGE_COMMAND_FLUSH_OUTPUT_STREAM";
    326    default:
    327      return "Invalid message?";
    328  }
    329 }
    330 
    331 GUID AudioMimeTypeToMediaFoundationSubtype(const nsACString& aMimeType) {
    332  if (aMimeType.EqualsLiteral("audio/mpeg")) {
    333    return MFAudioFormat_MP3;
    334  }
    335  if (MP4Decoder::IsAAC(aMimeType)) {
    336    return MFAudioFormat_AAC;
    337  }
    338  if (aMimeType.EqualsLiteral("audio/vorbis")) {
    339    return MFAudioFormat_Vorbis;
    340  }
    341  if (aMimeType.EqualsLiteral("audio/opus")) {
    342    return MFAudioFormat_Opus;
    343  }
    344  NS_WARNING("Unsupport audio mimetype");
    345  return GUID_NULL;
    346 }
    347 
    348 GUID VideoMimeTypeToMediaFoundationSubtype(const nsACString& aMimeType) {
    349  if (MP4Decoder::IsH264(aMimeType)) {
    350    return MFVideoFormat_H264;
    351  }
    352  if (VPXDecoder::IsVP8(aMimeType)) {
    353    return MFVideoFormat_VP80;
    354  }
    355  if (VPXDecoder::IsVP9(aMimeType)) {
    356    return MFVideoFormat_VP90;
    357  }
    358 #ifdef MOZ_AV1
    359  if (AOMDecoder::IsAV1(aMimeType)) {
    360    return MFVideoFormat_AV1;
    361  }
    362 #endif
    363  if (MP4Decoder::IsHEVC(aMimeType)) {
    364    return MFVideoFormat_HEVC;
    365  }
    366  NS_WARNING(nsAutoCString(nsDependentCString("Unsupported video mimetype ") +
    367                           aMimeType)
    368                 .get());
    369  return GUID_NULL;
    370 }
    371 
    372 void AACAudioSpecificConfigToUserData(uint8_t aAACProfileLevelIndication,
    373                                      const uint8_t* aAudioSpecConfig,
    374                                      uint32_t aConfigLength,
    375                                      nsTArray<BYTE>& aOutUserData) {
    376  MOZ_ASSERT(aOutUserData.IsEmpty());
    377 
    378  // The MF_MT_USER_DATA for AAC is defined here:
    379  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd742784%28v=vs.85%29.aspx
    380  //
    381  // For MFAudioFormat_AAC, MF_MT_USER_DATA contains the portion of
    382  // the HEAACWAVEINFO structure that appears after the WAVEFORMATEX
    383  // structure (that is, after the wfx member). This is followed by
    384  // the AudioSpecificConfig() data, as defined by ISO/IEC 14496-3.
    385  // [...]
    386  // The length of the AudioSpecificConfig() data is 2 bytes for AAC-LC
    387  // or HE-AAC with implicit signaling of SBR/PS. It is more than 2 bytes
    388  // for HE-AAC with explicit signaling of SBR/PS.
    389  //
    390  // The value of audioObjectType as defined in AudioSpecificConfig()
    391  // must be 2, indicating AAC-LC. The value of extensionAudioObjectType
    392  // must be 5 for SBR or 29 for PS.
    393  //
    394  // HEAACWAVEINFO structure:
    395  //    typedef struct heaacwaveinfo_tag {
    396  //      WAVEFORMATEX wfx;
    397  //      WORD         wPayloadType;
    398  //      WORD         wAudioProfileLevelIndication;
    399  //      WORD         wStructType;
    400  //      WORD         wReserved1;
    401  //      DWORD        dwReserved2;
    402  //    }
    403  const UINT32 heeInfoLen = 4 * sizeof(WORD) + sizeof(DWORD);
    404 
    405  // The HEAACWAVEINFO must have payload and profile set,
    406  // the rest can be all 0x00.
    407  BYTE heeInfo[heeInfoLen] = {0};
    408  WORD* w = (WORD*)heeInfo;
    409  // If extradata has been provided, assume raw AAC packets (0). Otherwise,
    410  // assume ADTS (1)
    411  w[0] = aConfigLength ? 0 : 1;
    412  w[1] = aAACProfileLevelIndication;
    413 
    414  aOutUserData.AppendElements(heeInfo, heeInfoLen);
    415 
    416  if (aAACProfileLevelIndication == 2 && aConfigLength > 2) {
    417    // The AudioSpecificConfig is TTTTTFFF|FCCCCGGG
    418    // (T=ObjectType, F=Frequency, C=Channel, G=GASpecificConfig)
    419    // If frequency = 0xf, then the frequency is explicitly defined on 24 bits.
    420    uint8_t frequency =
    421        (aAudioSpecConfig[0] & 0x7) << 1 | (aAudioSpecConfig[1] & 0x80) >> 7;
    422    uint8_t channels = (aAudioSpecConfig[1] & 0x78) >> 3;
    423    uint8_t gasc = aAudioSpecConfig[1] & 0x7;
    424    if (frequency != 0xf && channels && !gasc) {
    425      // We enter this condition if the AudioSpecificConfig should theorically
    426      // be 2 bytes long but it's not.
    427      // The WMF AAC decoder will error if unknown extensions are found,
    428      // so remove them.
    429      aConfigLength = 2;
    430    }
    431  }
    432  aOutUserData.AppendElements(aAudioSpecConfig, aConfigLength);
    433 }
    434 
    435 namespace wmf {
    436 
    437 static const wchar_t* sDLLs[] = {
    438    L"mfplat.dll",
    439    L"mf.dll",
    440    L"dxva2.dll",
    441    L"evr.dll",
    442 };
    443 
    444 HRESULT
    445 LoadDLLs() {
    446  static bool sDLLsLoaded = false;
    447  static bool sFailedToLoadDlls = false;
    448 
    449  if (sDLLsLoaded) {
    450    return S_OK;
    451  }
    452  if (sFailedToLoadDlls) {
    453    return E_FAIL;
    454  }
    455 
    456  // Try to load all the required DLLs. If we fail to load any dll,
    457  // unload the dlls we succeeded in loading.
    458  nsTArray<const wchar_t*> loadedDlls;
    459  for (const wchar_t* dll : sDLLs) {
    460    if (!LoadLibrarySystem32(dll)) {
    461      NS_WARNING("Failed to load WMF DLLs");
    462      for (const wchar_t* loadedDll : loadedDlls) {
    463        FreeLibrary(GetModuleHandleW(loadedDll));
    464      }
    465      sFailedToLoadDlls = true;
    466      return E_FAIL;
    467    }
    468    loadedDlls.AppendElement(dll);
    469  }
    470  sDLLsLoaded = true;
    471 
    472  return S_OK;
    473 }
    474 
    475 #define ENSURE_FUNCTION_PTR_HELPER(FunctionType, FunctionName, DLL) \
    476  static FunctionType FunctionName##Ptr = nullptr;                  \
    477  if (!FunctionName##Ptr) {                                         \
    478    FunctionName##Ptr = (FunctionType)GetProcAddress(               \
    479        GetModuleHandleW(L## #DLL), #FunctionName);                 \
    480    if (!FunctionName##Ptr) {                                       \
    481      NS_WARNING("Failed to get GetProcAddress of " #FunctionName   \
    482                 " from " #DLL);                                    \
    483      return E_FAIL;                                                \
    484    }                                                               \
    485  }
    486 
    487 #define ENSURE_FUNCTION_PTR(FunctionName, DLL) \
    488  ENSURE_FUNCTION_PTR_HELPER(decltype(::FunctionName)*, FunctionName, DLL)
    489 
    490 #define ENSURE_FUNCTION_PTR_(FunctionName, DLL) \
    491  ENSURE_FUNCTION_PTR_HELPER(FunctionName##Ptr_t, FunctionName, DLL)
    492 
    493 #define DECL_FUNCTION_PTR(FunctionName, ...) \
    494  typedef HRESULT(STDMETHODCALLTYPE* FunctionName##Ptr_t)(__VA_ARGS__)
    495 
    496 HRESULT
    497 MediaFoundationInitializer::MFStartup() {
    498  HRESULT hr = LoadDLLs();
    499  if (FAILED(hr)) {
    500    return hr;
    501  }
    502 
    503  const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
    504 
    505  // decltype is unusable for functions having default parameters
    506  DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
    507  ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
    508 
    509  hr = E_FAIL;
    510  mozilla::mscom::EnsureMTA(
    511      [&]() -> void { hr = MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL); });
    512  return hr;
    513 }
    514 
    515 HRESULT
    516 MediaFoundationInitializer::MFShutdown() {
    517  ENSURE_FUNCTION_PTR(MFShutdown, Mfplat.dll)
    518  HRESULT hr = E_FAIL;
    519  mozilla::mscom::EnsureMTA([&]() -> void { hr = (MFShutdownPtr)(); });
    520  return hr;
    521 }
    522 
    523 HRESULT
    524 MFCreateMediaType(IMFMediaType** aOutMFType) {
    525  ENSURE_FUNCTION_PTR(MFCreateMediaType, Mfplat.dll)
    526  return (MFCreateMediaTypePtr)(aOutMFType);
    527 }
    528 
    529 HRESULT
    530 MFGetStrideForBitmapInfoHeader(DWORD aFormat, DWORD aWidth, LONG* aOutStride) {
    531  ENSURE_FUNCTION_PTR(MFGetStrideForBitmapInfoHeader, evr.dll)
    532  return (MFGetStrideForBitmapInfoHeaderPtr)(aFormat, aWidth, aOutStride);
    533 }
    534 
    535 HRESULT MFGetService(IUnknown* punkObject, REFGUID guidService, REFIID riid,
    536                     LPVOID* ppvObject) {
    537  ENSURE_FUNCTION_PTR(MFGetService, mf.dll)
    538  return (MFGetServicePtr)(punkObject, guidService, riid, ppvObject);
    539 }
    540 
    541 HRESULT
    542 DXVA2CreateDirect3DDeviceManager9(UINT* pResetToken,
    543                                  IDirect3DDeviceManager9** ppDXVAManager) {
    544  ENSURE_FUNCTION_PTR(DXVA2CreateDirect3DDeviceManager9, dxva2.dll)
    545  return (DXVA2CreateDirect3DDeviceManager9Ptr)(pResetToken, ppDXVAManager);
    546 }
    547 
    548 HRESULT
    549 MFCreateSample(IMFSample** ppIMFSample) {
    550  ENSURE_FUNCTION_PTR(MFCreateSample, mfplat.dll)
    551  return (MFCreateSamplePtr)(ppIMFSample);
    552 }
    553 
    554 HRESULT
    555 MFCreateAlignedMemoryBuffer(DWORD cbMaxLength, DWORD fAlignmentFlags,
    556                            IMFMediaBuffer** ppBuffer) {
    557  ENSURE_FUNCTION_PTR(MFCreateAlignedMemoryBuffer, mfplat.dll)
    558  return (MFCreateAlignedMemoryBufferPtr)(cbMaxLength, fAlignmentFlags,
    559                                          ppBuffer);
    560 }
    561 
    562 HRESULT
    563 MFCreateDXGIDeviceManager(UINT* pResetToken,
    564                          IMFDXGIDeviceManager** ppDXVAManager) {
    565  ENSURE_FUNCTION_PTR(MFCreateDXGIDeviceManager, mfplat.dll)
    566  return (MFCreateDXGIDeviceManagerPtr)(pResetToken, ppDXVAManager);
    567 }
    568 
    569 HRESULT
    570 MFCreateDXGISurfaceBuffer(REFIID riid, IUnknown* punkSurface,
    571                          UINT uSubresourceIndex, BOOL fButtomUpWhenLinear,
    572                          IMFMediaBuffer** ppBuffer) {
    573  ENSURE_FUNCTION_PTR(MFCreateDXGISurfaceBuffer, mfplat.dll)
    574  return (MFCreateDXGISurfaceBufferPtr)(riid, punkSurface, uSubresourceIndex,
    575                                        fButtomUpWhenLinear, ppBuffer);
    576 }
    577 
    578 HRESULT
    579 MFTEnumEx(GUID guidCategory, UINT32 Flags,
    580          const MFT_REGISTER_TYPE_INFO* pInputType,
    581          const MFT_REGISTER_TYPE_INFO* pOutputType,
    582          IMFActivate*** pppMFTActivate, UINT32* pnumMFTActivate) {
    583  ENSURE_FUNCTION_PTR(MFTEnumEx, mfplat.dll)
    584  return (MFTEnumExPtr)(guidCategory, Flags, pInputType, pOutputType,
    585                        pppMFTActivate, pnumMFTActivate);
    586 }
    587 
    588 HRESULT MFTGetInfo(CLSID clsidMFT, LPWSTR* pszName,
    589                   MFT_REGISTER_TYPE_INFO** ppInputTypes, UINT32* pcInputTypes,
    590                   MFT_REGISTER_TYPE_INFO** ppOutputTypes,
    591                   UINT32* pcOutputTypes, IMFAttributes** ppAttributes) {
    592  ENSURE_FUNCTION_PTR(MFTGetInfo, mfplat.dll)
    593  return (MFTGetInfoPtr)(clsidMFT, pszName, ppInputTypes, pcInputTypes,
    594                         ppOutputTypes, pcOutputTypes, ppAttributes);
    595 }
    596 
    597 HRESULT
    598 MFCreateAttributes(IMFAttributes** ppMFAttributes, UINT32 cInitialSize) {
    599  ENSURE_FUNCTION_PTR(MFCreateAttributes, mfplat.dll)
    600  return (MFCreateAttributesPtr)(ppMFAttributes, cInitialSize);
    601 }
    602 
    603 HRESULT MFCreateEventQueue(IMFMediaEventQueue** ppMediaEventQueue) {
    604  ENSURE_FUNCTION_PTR(MFCreateEventQueue, mfplat.dll)
    605  return (MFCreateEventQueuePtr)(ppMediaEventQueue);
    606 }
    607 
    608 HRESULT MFCreateStreamDescriptor(DWORD dwStreamIdentifier, DWORD cMediaTypes,
    609                                 IMFMediaType** apMediaTypes,
    610                                 IMFStreamDescriptor** ppDescriptor) {
    611  ENSURE_FUNCTION_PTR(MFCreateStreamDescriptor, mfplat.dll)
    612  return (MFCreateStreamDescriptorPtr)(dwStreamIdentifier, cMediaTypes,
    613                                       apMediaTypes, ppDescriptor);
    614 }
    615 
    616 HRESULT MFCreateAsyncResult(IUnknown* punkObject, IMFAsyncCallback* pCallback,
    617                            IUnknown* punkState,
    618                            IMFAsyncResult** ppAsyncResult) {
    619  ENSURE_FUNCTION_PTR(MFCreateAsyncResult, mfplat.dll)
    620  return (MFCreateAsyncResultPtr)(punkObject, pCallback, punkState,
    621                                  ppAsyncResult);
    622 }
    623 
    624 HRESULT MFCreatePresentationDescriptor(
    625    DWORD cStreamDescriptors, IMFStreamDescriptor** apStreamDescriptors,
    626    IMFPresentationDescriptor** ppPresentationDescriptor) {
    627  ENSURE_FUNCTION_PTR(MFCreatePresentationDescriptor, mfplat.dll)
    628  return (MFCreatePresentationDescriptorPtr)(cStreamDescriptors,
    629                                             apStreamDescriptors,
    630                                             ppPresentationDescriptor);
    631 }
    632 
    633 HRESULT MFCreateMemoryBuffer(DWORD cbMaxLength, IMFMediaBuffer** ppBuffer) {
    634  ENSURE_FUNCTION_PTR(MFCreateMemoryBuffer, mfplat.dll);
    635  return (MFCreateMemoryBufferPtr)(cbMaxLength, ppBuffer);
    636 }
    637 
    638 HRESULT MFLockDXGIDeviceManager(UINT* pResetToken,
    639                                IMFDXGIDeviceManager** ppManager) {
    640  ENSURE_FUNCTION_PTR(MFLockDXGIDeviceManager, mfplat.dll);
    641  return (MFLockDXGIDeviceManagerPtr)(pResetToken, ppManager);
    642 }
    643 
    644 HRESULT MFUnlockDXGIDeviceManager() {
    645  ENSURE_FUNCTION_PTR(MFUnlockDXGIDeviceManager, mfplat.dll);
    646  return (MFUnlockDXGIDeviceManagerPtr)();
    647 }
    648 
    649 HRESULT MFPutWorkItem(DWORD dwQueue, IMFAsyncCallback* pCallback,
    650                      IUnknown* pState) {
    651  ENSURE_FUNCTION_PTR(MFPutWorkItem, mfplat.dll);
    652  return (MFPutWorkItemPtr)(dwQueue, pCallback, pState);
    653 }
    654 
    655 HRESULT MFSerializeAttributesToStream(IMFAttributes* pAttr, DWORD dwOptions,
    656                                      IStream* pStm) {
    657  ENSURE_FUNCTION_PTR(MFSerializeAttributesToStream, mfplat.dll);
    658  return (MFSerializeAttributesToStreamPtr)(pAttr, dwOptions, pStm);
    659 }
    660 
    661 HRESULT MFWrapMediaType(IMFMediaType* pOrig, REFGUID MajorType, REFGUID SubType,
    662                        IMFMediaType** ppWrap) {
    663  ENSURE_FUNCTION_PTR(MFWrapMediaType, mfplat.dll);
    664  return (MFWrapMediaTypePtr)(pOrig, MajorType, SubType, ppWrap);
    665 }
    666 
    667 }  // end namespace wmf
    668 }  // end namespace mozilla