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(×tampHns); 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