diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /media/gmp-clearkey/0.1/WMFUtils.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'media/gmp-clearkey/0.1/WMFUtils.cpp')
-rw-r--r-- | media/gmp-clearkey/0.1/WMFUtils.cpp | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/media/gmp-clearkey/0.1/WMFUtils.cpp b/media/gmp-clearkey/0.1/WMFUtils.cpp new file mode 100644 index 000000000..cb3cfe9fc --- /dev/null +++ b/media/gmp-clearkey/0.1/WMFUtils.cpp @@ -0,0 +1,276 @@ +/* + * Copyright 2013, Mozilla Foundation and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "WMFUtils.h" +#include "ClearKeyUtils.h" +#include <versionhelpers.h> + +#include <algorithm> +#include <stdio.h> + +#define INITGUID +#include <guiddef.h> + +#pragma comment(lib, "mfuuid.lib") +#pragma comment(lib, "wmcodecdspuuid") + +void LOG(const char* format, ...) +{ +#ifdef WMF_DECODER_LOG + va_list args; + va_start(args, format); + vprintf(format, args); +#endif +} + +#ifdef WMF_MUST_DEFINE_AAC_MFT_CLSID +// Some SDK versions don't define the AAC decoder CLSID. +// {32D186A7-218F-4C75-8876-DD77273A8999} +DEFINE_GUID(CLSID_CMSAACDecMFT, 0x32D186A7, 0x218F, 0x4C75, 0x88, 0x76, 0xDD, 0x77, 0x27, 0x3A, 0x89, 0x99); +#endif + +DEFINE_GUID(CLSID_CMSH264DecMFT, 0x62CE7E72, 0x4C71, 0x4d20, 0xB1, 0x5D, 0x45, 0x28, 0x31, 0xA8, 0x7D, 0x9D); + +namespace wmf { + + +#define MFPLAT_FUNC(_func, _dllname) \ + decltype(::_func)* _func; +#include "WMFSymbols.h" +#undef MFPLAT_FUNC + +static bool +LinkMfplat() +{ + static bool sInitDone = false; + static bool sInitOk = false; + if (!sInitDone) { + sInitDone = true; + HMODULE handle; + +#define MFPLAT_FUNC(_func, _dllname) \ + handle = GetModuleHandleA(_dllname); \ + if (!(_func = (decltype(_func))(GetProcAddress(handle, #_func)))) { \ + return false; \ + } + +#include "WMFSymbols.h" +#undef MFPLAT_FUNC + sInitOk = true; + } + return sInitOk; +} + +const char* +WMFDecoderDllNameFor(CodecType aCodec) +{ + if (aCodec == H264) { + // For H.264 decoding, we need msmpeg2vdec.dll on Win 7 & 8, + // and mfh264dec.dll on Vista. + if (IsWindows7OrGreater()) { + return "msmpeg2vdec.dll"; + } else { + return "mfh264dec.dll"; + } + } else if (aCodec == AAC) { + // For AAC decoding, we need to use msauddecmft.dll on Win8, + // msmpeg2adec.dll on Win7, and msheaacdec.dll on Vista. + if (IsWindows8OrGreater()) { + return "msauddecmft.dll"; + } else if (IsWindows7OrGreater()) { + return "msmpeg2adec.dll"; + } else { + return "mfheaacdec.dll"; + } + } else { + return ""; + } +} + + +bool +EnsureLibs() +{ + static bool sInitDone = false; + static bool sInitOk = false; + if (!sInitDone) { + sInitOk = LinkMfplat() && + !!GetModuleHandleA(WMFDecoderDllNameFor(AAC)) && + !!GetModuleHandleA(WMFDecoderDllNameFor(H264)); + sInitDone = true; + } + return sInitOk; +} + +int32_t +MFOffsetToInt32(const MFOffset& aOffset) +{ + return int32_t(aOffset.value + (aOffset.fract / 65536.0f)); +} + +// Gets the sub-region of the video frame that should be displayed. +// See: http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx +HRESULT +GetPictureRegion(IMFMediaType* aMediaType, IntRect& aOutPictureRegion) +{ + // Determine if "pan and scan" is enabled for this media. If it is, we + // only display a region of the video frame, not the entire frame. + BOOL panScan = MFGetAttributeUINT32(aMediaType, MF_MT_PAN_SCAN_ENABLED, FALSE); + + // If pan and scan mode is enabled. Try to get the display region. + HRESULT hr = E_FAIL; + MFVideoArea videoArea; + memset(&videoArea, 0, sizeof(MFVideoArea)); + if (panScan) { + hr = aMediaType->GetBlob(MF_MT_PAN_SCAN_APERTURE, + (UINT8*)&videoArea, + sizeof(MFVideoArea), + NULL); + } + + // If we're not in pan-and-scan mode, or the pan-and-scan region is not set, + // check for a minimimum display aperture. + if (!panScan || hr == MF_E_ATTRIBUTENOTFOUND) { + hr = aMediaType->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, + (UINT8*)&videoArea, + sizeof(MFVideoArea), + NULL); + } + + if (hr == MF_E_ATTRIBUTENOTFOUND) { + // Minimum display aperture is not set, for "backward compatibility with + // some components", check for a geometric aperture. + hr = aMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE, + (UINT8*)&videoArea, + sizeof(MFVideoArea), + NULL); + } + + if (SUCCEEDED(hr)) { + // The media specified a picture region, return it. + IntRect picture = IntRect(MFOffsetToInt32(videoArea.OffsetX), + MFOffsetToInt32(videoArea.OffsetY), + videoArea.Area.cx, + videoArea.Area.cy); + ENSURE(picture.width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL); + ENSURE(picture.height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL); + aOutPictureRegion = picture; + return S_OK; + } + + // No picture region defined, fall back to using the entire video area. + UINT32 width = 0, height = 0; + hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height); + ENSURE(SUCCEEDED(hr), hr); + ENSURE(width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL); + ENSURE(height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL); + aOutPictureRegion = IntRect(0, 0, width, height); + return S_OK; +} + + +HRESULT +GetDefaultStride(IMFMediaType *aType, uint32_t* aOutStride) +{ + // Try to get the default stride from the media type. + UINT32 stride = 0; + HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, &stride); + if (SUCCEEDED(hr)) { + ENSURE(stride <= mozilla::MAX_VIDEO_WIDTH, E_FAIL); + *aOutStride = stride; + return S_OK; + } + + // Stride attribute not set, calculate it. + GUID subtype = GUID_NULL; + uint32_t width = 0; + uint32_t height = 0; + + hr = aType->GetGUID(MF_MT_SUBTYPE, &subtype); + ENSURE(SUCCEEDED(hr), hr); + + hr = MFGetAttributeSize(aType, MF_MT_FRAME_SIZE, &width, &height); + ENSURE(SUCCEEDED(hr), hr); + ENSURE(width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL); + ENSURE(height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL); + + LONG lstride = 0; + hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lstride); + ENSURE(SUCCEEDED(hr), hr); + ENSURE(lstride <= mozilla::MAX_VIDEO_WIDTH, E_FAIL); + ENSURE(lstride >= 0, E_FAIL); + *aOutStride = lstride; + + return hr; +} + +void dump(const uint8_t* data, uint32_t len, const char* filename) +{ + FILE* f = 0; + fopen_s(&f, filename, "wb"); + fwrite(data, len, 1, f); + fclose(f); +} + +HRESULT +CreateMFT(const CLSID& clsid, + const char* aDllName, + CComPtr<IMFTransform>& aOutMFT) +{ + HMODULE module = ::GetModuleHandleA(aDllName); + if (!module) { + LOG("Failed to get %S\n", aDllName); + return E_FAIL; + } + + typedef HRESULT (WINAPI* DllGetClassObjectFnPtr)(const CLSID& clsid, + const IID& iid, + void** object); + + DllGetClassObjectFnPtr GetClassObjPtr = + reinterpret_cast<DllGetClassObjectFnPtr>(GetProcAddress(module, "DllGetClassObject")); + if (!GetClassObjPtr) { + LOG("Failed to get DllGetClassObject\n"); + return E_FAIL; + } + + CComPtr<IClassFactory> classFactory; + HRESULT hr = GetClassObjPtr(clsid, + __uuidof(IClassFactory), + reinterpret_cast<void**>(static_cast<IClassFactory**>(&classFactory))); + if (FAILED(hr)) { + LOG("Failed to get H264 IClassFactory\n"); + return E_FAIL; + } + + hr = classFactory->CreateInstance(NULL, + __uuidof(IMFTransform), + reinterpret_cast<void**>(static_cast<IMFTransform**>(&aOutMFT))); + if (FAILED(hr)) { + LOG("Failed to get create MFT\n"); + return E_FAIL; + } + + return S_OK; +} + +int32_t +GetNumThreads(int32_t aCoreCount) +{ + return aCoreCount > 4 ? -1 : (std::max)(aCoreCount - 1, 1); +} + +} // namespace |