WMFUtils.h (6031B)
1 /* 2 * Copyright 2013, Mozilla Foundation and contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __WMFUtils_h__ 18 #define __WMFUtils_h__ 19 20 #include <assert.h> 21 #include <mfapi.h> 22 #include <mferror.h> 23 #include <mfobjects.h> 24 #include <mftransform.h> 25 #include <wmcodecdsp.h> 26 27 #include <cstdint> 28 #include <string> 29 30 #include "VideoLimits.h" 31 #include "content_decryption_module.h" 32 #include "gmp-platform.h" 33 #include "mozilla/Attributes.h" 34 35 void LOG(const char* format, ...); 36 37 #ifdef LOG_SAMPLE_DECODE 38 # define SAMPLE_LOG LOG 39 #else 40 # define SAMPLE_LOG(...) 41 #endif 42 43 #ifndef CLSID_CMSAACDecMFT 44 # define WMF_MUST_DEFINE_AAC_MFT_CLSID 45 extern "C" const CLSID CLSID_CMSAACDecMFT; 46 #endif 47 48 extern "C" const CLSID CLSID_CMSH264DecMFT; 49 50 namespace wmf { 51 52 // Reimplementation of CComPtr to reduce dependence on system 53 // shared libraries. 54 template <class T> 55 class CComPtr { 56 public: 57 CComPtr(CComPtr&& aOther) : mPtr(aOther.Detach()) {} 58 CComPtr& operator=(CComPtr&& other) { mPtr = other.Detach(); } 59 60 CComPtr(const CComPtr& aOther) : mPtr(nullptr) { Set(aOther.Get()); } 61 CComPtr() : mPtr(nullptr) {} 62 MOZ_IMPLICIT CComPtr(T* const& aPtr) : mPtr(nullptr) { Set(aPtr); } 63 MOZ_IMPLICIT CComPtr(const std::nullptr_t& aNullPtr) : mPtr(aNullPtr) {} 64 T** operator&() { return &mPtr; } 65 T* operator->() { return mPtr; } 66 operator T*() { return mPtr; } 67 T* operator=(T* const& aPtr) { return Set(aPtr); } 68 T* operator=(const std::nullptr_t& aPtr) { return mPtr = aPtr; } 69 70 T* Get() const { return mPtr; } 71 72 T* Detach() { 73 T* tmp = mPtr; 74 mPtr = nullptr; 75 return tmp; 76 } 77 78 ~CComPtr() { 79 if (mPtr) { 80 mPtr->Release(); 81 } 82 mPtr = nullptr; 83 } 84 85 private: 86 T* Set(T* aPtr) { 87 if (mPtr == aPtr) { 88 return aPtr; 89 } 90 if (mPtr) { 91 mPtr->Release(); 92 } 93 mPtr = aPtr; 94 if (mPtr) { 95 mPtr->AddRef(); 96 } 97 return mPtr; 98 } 99 100 T* mPtr; 101 }; 102 103 class IntRect { 104 public: 105 IntRect(int32_t _x, int32_t _y, int32_t _w, int32_t _h) 106 : x(_x), y(_y), width(_w), height(_h) {} 107 IntRect() : x(0), y(0), width(0), height(0) {} 108 int32_t x; 109 int32_t y; 110 int32_t width; 111 int32_t height; 112 }; 113 114 typedef int64_t Microseconds; 115 116 #ifdef ENSURE 117 # undef ENSURE 118 #endif 119 120 #define ENSURE(condition, ret) \ 121 { \ 122 if (!(condition)) { \ 123 LOG("##condition## FAILED %S:%d\n", __FILE__, __LINE__); \ 124 return ret; \ 125 } \ 126 } 127 128 inline bool STATUS_SUCCEEDED(cdm::Status status) { 129 return status == cdm::Status::kSuccess; 130 } 131 inline bool STATUS_FAILED(cdm::Status status) { 132 return !STATUS_SUCCEEDED(status); 133 } 134 135 #define MFPLAT_FUNC(_func, _dllname) extern decltype(::_func)* _func; 136 #include "WMFSymbols.h" 137 #undef MFPLAT_FUNC 138 139 bool EnsureLibs(); 140 141 HRESULT 142 GetPictureRegion(IMFMediaType* aMediaType, IntRect& aOutPictureRegion); 143 144 HRESULT 145 GetDefaultStride(IMFMediaType* aType, uint32_t* aOutStride); 146 147 // Converts from microseconds to hundreds of nanoseconds. 148 // We use microseconds for our timestamps, whereas WMF uses 149 // hundreds of nanoseconds. 150 inline int64_t UsecsToHNs(int64_t aUsecs) { return aUsecs * 10; } 151 152 // Converts from hundreds of nanoseconds to microseconds. 153 // We use microseconds for our timestamps, whereas WMF uses 154 // hundreds of nanoseconds. 155 inline int64_t HNsToUsecs(int64_t hNanoSecs) { return hNanoSecs / 10; } 156 157 inline std::string narrow(std::wstring& wide) { 158 std::string ns(wide.begin(), wide.end()); 159 return ns; 160 } 161 162 inline std::wstring widen(std::string& narrow) { 163 std::wstring ws(narrow.begin(), narrow.end()); 164 return ws; 165 } 166 167 #define ARRAY_LENGTH(array_) (sizeof(array_) / sizeof(array_[0])) 168 169 template <class Type> 170 class AutoPtr { 171 public: 172 AutoPtr() : mPtr(nullptr) {} 173 174 AutoPtr(AutoPtr<Type>& aPtr) : mPtr(aPtr.Forget()) {} 175 176 explicit AutoPtr(Type* aPtr) : mPtr(aPtr) {} 177 178 ~AutoPtr() { 179 if (mPtr) { 180 delete mPtr; 181 } 182 } 183 184 Type* Forget() { 185 Type* rv = mPtr; 186 mPtr = nullptr; 187 return rv; 188 } 189 190 AutoPtr<Type>& operator=(Type* aOther) { 191 Assign(aOther); 192 return *this; 193 } 194 195 AutoPtr<Type>& operator=(AutoPtr<Type>& aOther) { 196 Assign(aOther.Forget()); 197 return *this; 198 } 199 200 Type* Get() const { return mPtr; } 201 202 Type* operator->() const { 203 assert(mPtr); 204 return Get(); 205 } 206 207 operator Type*() const { return Get(); } 208 209 Type** Receive() { return &mPtr; } 210 211 private: 212 void Assign(Type* aPtr) { 213 if (mPtr) { 214 delete mPtr; 215 } 216 mPtr = aPtr; 217 } 218 219 Type* mPtr; 220 }; 221 222 // Video frame microseconds are (currently) in 90kHz units, as used by RTP. 223 // Use this to convert to microseconds... 224 inline Microseconds RTPTimeToMicroseconds(int64_t rtptime) { 225 return (rtptime * 1000000) / 90000; 226 } 227 228 inline uint32_t MicrosecondsToRTPTime(Microseconds us) { 229 return uint32_t(0xffffffff & (us * 90000) / 1000000); 230 } 231 232 void dump(const uint8_t* data, uint32_t len, const char* filename); 233 234 HRESULT 235 CreateMFT(const CLSID& clsid, const char* aDllName, 236 CComPtr<IMFTransform>& aOutMFT); 237 238 // Returns the name of the DLL that is needed to decode H.264 on 239 // the given windows version we're running on. 240 inline const char* WMFDecoderDllName() { return "msmpeg2vdec.dll"; } 241 242 // Returns the maximum number of threads we want WMF to use for decoding 243 // given the number of logical processors available. 244 int32_t GetNumThreads(int32_t aCoreCount); 245 246 } // namespace wmf 247 248 #endif // __WMFUtils_h__