WMFClearKeyUtils.h (7103B)
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_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H 6 #define DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H 7 8 #include <initguid.h> 9 #include <mfidl.h> 10 #include <mutex> 11 #include <thread> 12 #include <windows.h> 13 #include <wrl.h> 14 #include <sstream> 15 #include <stdio.h> 16 17 #include "MFCDMExtra.h" 18 #include "mozilla/Assertions.h" 19 20 namespace mozilla { 21 22 inline constexpr WCHAR kCLEARKEY_SYSTEM_NAME[] = L"org.w3.clearkey"; 23 24 #define WMF_CLEARKEY_DEBUG 0 25 26 #if WMF_CLEARKEY_DEBUG 27 # define LOG(msg, ...) \ 28 printf(("[Thread %lu]: D/WMFClearKey " msg "\n"), \ 29 static_cast<unsigned long>( \ 30 std::hash<std::thread::id>{}(std::this_thread::get_id())), \ 31 ##__VA_ARGS__) 32 #else 33 # define LOG(msg, ...) 34 #endif 35 36 #define PRETTY_FUNC \ 37 ([&]() -> std::string { \ 38 std::string prettyFunction(__PRETTY_FUNCTION__); \ 39 std::size_t pos1 = prettyFunction.find("::"); \ 40 std::size_t pos2 = prettyFunction.find("(", pos1); \ 41 return prettyFunction.substr(0, pos2); \ 42 })() \ 43 .c_str() 44 45 // We can't reuse the definition in the `MediaEngineUtils.h` due to the 46 // restriction of not being able to use XPCOM string in the external library. 47 #ifndef RETURN_IF_FAILED 48 # define RETURN_IF_FAILED(x) \ 49 do { \ 50 HRESULT rv = x; \ 51 if (FAILED(rv)) { \ 52 LOG("(" #x ") failed, rv=%lx", rv); \ 53 return rv; \ 54 } \ 55 } while (false) 56 #endif 57 58 #ifndef NOT_IMPLEMENTED 59 # define NOT_IMPLEMENTED() \ 60 do { \ 61 LOG("WARNING : '%s' NOT IMPLEMENTED!", PRETTY_FUNC); \ 62 } while (0) 63 #endif 64 65 #ifndef ENTRY_LOG 66 # define ENTRY_LOG(...) \ 67 do { \ 68 LOG("%s [%p]", PRETTY_FUNC, this); \ 69 } while (0) 70 # define ENTRY_LOG_ARGS(fmt, ...) \ 71 do { \ 72 LOG("%s [%p]: " fmt, PRETTY_FUNC, this, ##__VA_ARGS__); \ 73 (void)(0, ##__VA_ARGS__); \ 74 } while (0) 75 #endif 76 77 // TODO : should we use Microsoft's definition or Chromium's defintion? 78 79 // This is defined in Microsoft's sample code 80 // https://github.com/microsoft/media-foundation/blob/dc81175a3e893c7c58fcbf1a943ac342e39f172c/samples/storecdm/clearkeyStoreCDM/clearkeydll/guids.h#L17-L18C14 81 // DEFINE_GUID(CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID, 0x9b0ff3ca, 0x1378, 82 // 0x4f28, 0x96, 0x65, 0x18, 0x9e, 0x15, 0x30, 0x2a, 0x71); 83 84 // Media Foundation Clear Key protection system ID from Chromium 85 // {E4E94971-696A-447E-96E4-93FDF3A57A7A} 86 // https://source.chromium.org/chromium/chromium/src/+/main:media/cdm/win/test/media_foundation_clear_key_guids.h;l=16-29?q=CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID&ss=chromium%2Fchromium%2Fsrc 87 DEFINE_GUID(CLEARKEY_GUID_CLEARKEY_PROTECTION_SYSTEM_ID, 0xe4e94971, 0x696a, 88 0x447e, 0x96, 0xe4, 0x93, 0xfd, 0xf3, 0xa5, 0x7a, 0x7a); 89 90 // Media Foundation Clear Key content enabler type 91 // {C262FD73-2F13-41C2-94E7-4CAF087AE1D1} 92 DEFINE_GUID(MEDIA_FOUNDATION_CLEARKEY_GUID_CONTENT_ENABLER_TYPE, 0xc262fd73, 93 0x2f13, 0x41c2, 0x94, 0xe7, 0x4c, 0xaf, 0x8, 0x7a, 0xe1, 0xd1); 94 95 // https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:media/cdm/win/test/media_foundation_clear_key_guids.h;l=46;drc=fcefb4563e8ea5b2036ecde882f4f228dd1e4338 96 #define PLAYREADY_GUID_MEDIA_PROTECTION_SYSTEM_ID_STRING \ 97 L"{F4637010-03C3-42CD-B932-B48ADF3A6A54}" 98 99 // A PROPVARIANT that is automatically initialized and cleared upon respective 100 // construction and destruction of this class. 101 class AutoPropVar final { 102 public: 103 AutoPropVar() { PropVariantInit(&mVar); } 104 105 ~AutoPropVar() { Reset(); } 106 107 AutoPropVar(const AutoPropVar&) = delete; 108 AutoPropVar& operator=(const AutoPropVar&) = delete; 109 bool operator==(const AutoPropVar&) const = delete; 110 bool operator!=(const AutoPropVar&) const = delete; 111 112 // Returns a pointer to the underlying PROPVARIANT for use as an out param 113 // in a function call. 114 PROPVARIANT* Receive() { 115 MOZ_ASSERT(mVar.vt == VT_EMPTY); 116 return &mVar; 117 } 118 119 // Clears the instance to prepare it for re-use (e.g., via Receive). 120 void Reset() { 121 if (mVar.vt != VT_EMPTY) { 122 HRESULT hr = PropVariantClear(&mVar); 123 MOZ_ASSERT(SUCCEEDED(hr)); 124 (void)hr; 125 } 126 } 127 128 const PROPVARIANT& get() const { return mVar; } 129 const PROPVARIANT* ptr() const { return &mVar; } 130 131 private: 132 PROPVARIANT mVar; 133 }; 134 135 template <typename T> 136 class ScopedCoMem final { 137 public: 138 ScopedCoMem() : mPtr(nullptr) {} 139 140 ~ScopedCoMem() { Reset(nullptr); } 141 142 ScopedCoMem(const ScopedCoMem&) = delete; 143 ScopedCoMem& operator=(const ScopedCoMem&) = delete; 144 145 T** operator&() { // NOLINT 146 MOZ_ASSERT(mPtr == nullptr); // To catch memory leaks. 147 return &mPtr; 148 } 149 150 operator T*() { return mPtr; } 151 152 T* operator->() { 153 MOZ_ASSERT(mPtr != nullptr); 154 return mPtr; 155 } 156 157 const T* operator->() const { 158 MOZ_ASSERT(mPtr != nullptr); 159 return mPtr; 160 } 161 162 explicit operator bool() const { return mPtr; } 163 164 friend bool operator==(const ScopedCoMem& lhs, std::nullptr_t) { 165 return lhs.Get() == nullptr; 166 } 167 168 friend bool operator==(std::nullptr_t, const ScopedCoMem& rhs) { 169 return rhs.Get() == nullptr; 170 } 171 172 friend bool operator!=(const ScopedCoMem& lhs, std::nullptr_t) { 173 return lhs.Get() != nullptr; 174 } 175 176 friend bool operator!=(std::nullptr_t, const ScopedCoMem& rhs) { 177 return rhs.Get() != nullptr; 178 } 179 180 void Reset(T* ptr) { 181 if (mPtr) { 182 CoTaskMemFree(mPtr); 183 } 184 mPtr = ptr; 185 } 186 187 T* Get() const { return mPtr; } 188 189 private: 190 T* mPtr; 191 }; 192 193 template <typename T> 194 class DataMutex final { 195 public: 196 DataMutex() = default; 197 198 template <typename... Args> 199 explicit DataMutex(Args&&... args) : mData(std::forward<Args>(args)...) {} 200 201 class AutoLock { 202 public: 203 AutoLock(std::unique_lock<std::mutex>&& lock, DataMutex<T>* mutex) 204 : mLock(std::move(lock)), mMutex(mutex) {} 205 T& operator*() { return ref(); } 206 T* operator->() { return &ref(); } 207 T& ref() const& { return mMutex->mData; } 208 operator T*() const& { return &ref(); } 209 ~AutoLock() { mMutex = nullptr; } 210 211 private: 212 std::unique_lock<std::mutex> mLock; 213 DataMutex<T>* mMutex; 214 }; 215 216 AutoLock Lock() { 217 return AutoLock(std::unique_lock<std::mutex>(mMutex), this); 218 } 219 220 private: 221 std::mutex mMutex; 222 T mData; 223 }; 224 225 } // namespace mozilla 226 227 #endif // DOM_MEDIA_PLATFORM_WMF_CLEARKEY_WMFCLEARKEYCDMUTILS_H