MFMediaEngineUtils.h (7917B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_MEDIA_IPC_MFMEDIAENGINEUTILS_H_ 6 #define DOM_MEDIA_IPC_MFMEDIAENGINEUTILS_H_ 7 8 #include "MFMediaEngineExtra.h" 9 #include "ipc/EnumSerializer.h" 10 #include "mozilla/Logging.h" 11 #include "mozilla/ProfilerMarkerTypes.h" 12 #include "nsPrintfCString.h" 13 14 namespace mozilla { 15 16 inline LazyLogModule gMFMediaEngineLog{"MFMediaEngine"}; 17 18 // https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_event 19 using MFMediaEngineEvent = MF_MEDIA_ENGINE_EVENT; 20 21 // https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/ne-mfmediaengine-mf_media_engine_err 22 using MFMediaEngineError = MF_MEDIA_ENGINE_ERR; 23 24 #define LOG_AND_WARNING(msg, ...) \ 25 do { \ 26 NS_WARNING(nsPrintfCString(msg, rv).get()); \ 27 MOZ_LOG(gMFMediaEngineLog, LogLevel::Debug, \ 28 ("%s:%d, " msg, __FILE__, __LINE__, ##__VA_ARGS__)); \ 29 } while (false) 30 31 #ifndef LOG_IF_FAILED 32 # define LOG_IF_FAILED(x) \ 33 do { \ 34 HRESULT rv = x; \ 35 if (MOZ_UNLIKELY(FAILED(rv))) { \ 36 LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ 37 } \ 38 } while (false) 39 #endif 40 41 #ifndef RETURN_IF_FAILED 42 # define RETURN_IF_FAILED(x) \ 43 do { \ 44 HRESULT rv = x; \ 45 if (MOZ_UNLIKELY(FAILED(rv))) { \ 46 LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ 47 return rv; \ 48 } \ 49 } while (false) 50 #endif 51 52 #ifndef RETURN_VOID_IF_FAILED 53 # define RETURN_VOID_IF_FAILED(x) \ 54 do { \ 55 HRESULT rv = x; \ 56 if (MOZ_UNLIKELY(FAILED(rv))) { \ 57 LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ 58 return; \ 59 } \ 60 } while (false) 61 #endif 62 63 #ifndef RETURN_PARAM_IF_FAILED 64 # define RETURN_PARAM_IF_FAILED(x, defaultOut) \ 65 do { \ 66 HRESULT rv = x; \ 67 if (MOZ_UNLIKELY(FAILED(rv))) { \ 68 LOG_AND_WARNING("(" #x ") failed, rv=%lx", rv); \ 69 return defaultOut; \ 70 } \ 71 } while (false) 72 #endif 73 74 #ifndef SHUTDOWN_IF_POSSIBLE 75 # define SHUTDOWN_IF_POSSIBLE(class) \ 76 do { \ 77 IMFShutdown* pShutdown = nullptr; \ 78 HRESULT rv = class->QueryInterface(IID_PPV_ARGS(&pShutdown)); \ 79 if (SUCCEEDED(rv)) { \ 80 rv = pShutdown->Shutdown(); \ 81 if (FAILED(rv)) { \ 82 LOG_AND_WARNING(#class " failed to shutdown, rv=%lx", rv); \ 83 } else { \ 84 MOZ_LOG(gMFMediaEngineLog, LogLevel::Verbose, \ 85 ((#class " shutdowned successfully"))); \ 86 } \ 87 pShutdown->Release(); \ 88 } else { \ 89 LOG_AND_WARNING(#class " doesn't support IMFShutdown?, rv=%lx", rv); \ 90 } \ 91 } while (false) 92 #endif 93 94 #define ENGINE_MARKER(markerName) \ 95 PROFILER_MARKER(markerName, MEDIA_PLAYBACK, {}, MediaEngineMarker, Id()) 96 97 #define ENGINE_MARKER_TEXT(markerName, text) \ 98 PROFILER_MARKER(markerName, MEDIA_PLAYBACK, {}, MediaEngineTextMarker, Id(), \ 99 text) 100 101 #ifdef MOZ_WMF_CDM 102 // This eror can happen during OS sleep/resume, or moving video to different 103 // graphics adapters. 104 inline constexpr HRESULT DRM_E_TEE_INVALID_HWDRM_STATE = 105 static_cast<HRESULT>(0x8004CD12); 106 107 // PlayReady CDM failed to create a decryptor for the stream. This typically 108 // occurs when the system lacks hardware DRM support, such as a Trusted 109 // Execution Environment (TEE) or secure video path. Most common when the 110 // license requires a hardware decryptor, but the platform lacks secure decode 111 // or necessary hardware capability (e.g., most VMs). 112 inline constexpr HRESULT MSPR_E_NO_DECRYPTOR_AVAILABLE = 113 static_cast<HRESULT>(0x8004B895); 114 #endif 115 116 const char* MediaEventTypeToStr(MediaEventType aType); 117 const char* MediaEngineEventToStr(MF_MEDIA_ENGINE_EVENT aEvent); 118 const char* MFMediaEngineErrorToStr(MFMediaEngineError aError); 119 const char* GUIDToStr(GUID aGUID); 120 const char* MFVideoRotationFormatToStr(MFVideoRotationFormat aFormat); 121 const char* MFVideoTransferFunctionToStr(MFVideoTransferFunction aFunc); 122 const char* MFVideoPrimariesToStr(MFVideoPrimaries aPrimaries); 123 void ByteArrayFromGUID(REFGUID aGuidIn, nsTArray<uint8_t>& aByteArrayOut); 124 void GUIDFromByteArray(const nsTArray<uint8_t>& aByteArrayIn, GUID& aGuidOut); 125 BSTR CreateBSTRFromConstChar(const char* aNarrowStr); 126 127 // See cdm::SubsampleEntry 128 struct MediaFoundationSubsampleEntry { 129 uint32_t mClearBytes; 130 uint32_t mCipherBytes; 131 }; 132 133 template <typename T> 134 class ScopedCoMem { 135 public: 136 ScopedCoMem() : mPtr(nullptr) {} 137 138 ~ScopedCoMem() { Reset(nullptr); } 139 140 ScopedCoMem(const ScopedCoMem&) = delete; 141 ScopedCoMem& operator=(const ScopedCoMem&) = delete; 142 143 T** operator&() { // NOLINT 144 MOZ_ASSERT(mPtr == nullptr); // To catch memory leaks. 145 return &mPtr; 146 } 147 148 operator T*() { return mPtr; } 149 150 T* operator->() { 151 MOZ_ASSERT(mPtr != nullptr); 152 return mPtr; 153 } 154 155 const T* operator->() const { 156 MOZ_ASSERT(mPtr != nullptr); 157 return mPtr; 158 } 159 160 explicit operator bool() const { return mPtr; } 161 162 friend bool operator==(const ScopedCoMem& lhs, std::nullptr_t) { 163 return lhs.Get() == nullptr; 164 } 165 166 friend bool operator==(std::nullptr_t, const ScopedCoMem& rhs) { 167 return rhs.Get() == nullptr; 168 } 169 170 friend bool operator!=(const ScopedCoMem& lhs, std::nullptr_t) { 171 return lhs.Get() != nullptr; 172 } 173 174 friend bool operator!=(std::nullptr_t, const ScopedCoMem& rhs) { 175 return rhs.Get() != nullptr; 176 } 177 178 void Reset(T* ptr) { 179 if (mPtr) CoTaskMemFree(mPtr); 180 mPtr = ptr; 181 } 182 183 T* Get() const { return mPtr; } 184 185 private: 186 T* mPtr; 187 }; 188 189 } // namespace mozilla 190 191 namespace IPC { 192 193 template <> 194 struct ParamTraits<mozilla::MFMediaEngineError> 195 : public ContiguousEnumSerializerInclusive< 196 mozilla::MFMediaEngineError, 197 mozilla::MFMediaEngineError::MF_MEDIA_ENGINE_ERR_ABORTED, 198 mozilla::MFMediaEngineError::MF_MEDIA_ENGINE_ERR_ENCRYPTED> {}; 199 200 template <> 201 struct ParamTraits<mozilla::MFMediaEngineEvent> 202 : public ContiguousEnumSerializerInclusive< 203 mozilla::MFMediaEngineEvent, 204 mozilla::MFMediaEngineEvent::MF_MEDIA_ENGINE_EVENT_LOADSTART, 205 mozilla::MFMediaEngineEvent:: 206 MF_MEDIA_ENGINE_EVENT_AUDIOENDPOINTCHANGE> {}; 207 208 } // namespace IPC 209 210 #endif // DOM_MEDIA_IPC_MFMEDIAENGINECHILD_H_