tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WMFUtils.cpp (6788B)


      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 #include "WMFUtils.h"
     18 
     19 #define INITGUID
     20 #include <guiddef.h>
     21 #include <stdio.h>
     22 #include <versionhelpers.h>
     23 
     24 #include <algorithm>
     25 
     26 #include "ClearKeyUtils.h"
     27 
     28 #ifndef __MINGW32__
     29 #  pragma comment(lib, "mfuuid.lib")
     30 #  pragma comment(lib, "wmcodecdspuuid")
     31 #endif
     32 
     33 void LOG(const char* format, ...) {
     34 #ifdef WMF_DECODER_LOG
     35  va_list args;
     36  va_start(args, format);
     37  vprintf(format, args);
     38 #endif
     39 }
     40 
     41 DEFINE_GUID(CLSID_CMSH264DecMFT, 0x62CE7E72, 0x4C71, 0x4d20, 0xB1, 0x5D, 0x45,
     42            0x28, 0x31, 0xA8, 0x7D, 0x9D);
     43 
     44 namespace wmf {
     45 
     46 #define MFPLAT_FUNC(_func, _dllname) decltype(::_func)* _func;
     47 #include "WMFSymbols.h"
     48 #undef MFPLAT_FUNC
     49 
     50 static bool LinkMfplat() {
     51  static bool sInitDone = false;
     52  static bool sInitOk = false;
     53  if (!sInitDone) {
     54    sInitDone = true;
     55    HMODULE handle;
     56 
     57 #define MFPLAT_FUNC(_func, _dllname)                                  \
     58  handle = GetModuleHandleA(_dllname);                                \
     59  if (!(_func = (decltype(_func))(GetProcAddress(handle, #_func)))) { \
     60    return false;                                                     \
     61  }
     62 
     63 #include "WMFSymbols.h"
     64 #undef MFPLAT_FUNC
     65    sInitOk = true;
     66  }
     67  return sInitOk;
     68 }
     69 
     70 bool EnsureLibs() {
     71  static bool sInitDone = false;
     72  static bool sInitOk = false;
     73  if (!sInitDone) {
     74    sInitOk = LinkMfplat() && !!GetModuleHandleA(WMFDecoderDllName());
     75    sInitDone = true;
     76  }
     77  return sInitOk;
     78 }
     79 
     80 int32_t MFOffsetToInt32(const MFOffset& aOffset) {
     81  return int32_t(aOffset.value + (aOffset.fract / 65536.0f));
     82 }
     83 
     84 // Gets the sub-region of the video frame that should be displayed.
     85 // See:
     86 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb530115(v=vs.85).aspx
     87 HRESULT
     88 GetPictureRegion(IMFMediaType* aMediaType, IntRect& aOutPictureRegion) {
     89  // Determine if "pan and scan" is enabled for this media. If it is, we
     90  // only display a region of the video frame, not the entire frame.
     91  BOOL panScan =
     92      MFGetAttributeUINT32(aMediaType, MF_MT_PAN_SCAN_ENABLED, FALSE);
     93 
     94  // If pan and scan mode is enabled. Try to get the display region.
     95  HRESULT hr = E_FAIL;
     96  MFVideoArea videoArea;
     97  memset(&videoArea, 0, sizeof(MFVideoArea));
     98  if (panScan) {
     99    hr = aMediaType->GetBlob(MF_MT_PAN_SCAN_APERTURE, (UINT8*)&videoArea,
    100                             sizeof(MFVideoArea), NULL);
    101  }
    102 
    103  // If we're not in pan-and-scan mode, or the pan-and-scan region is not set,
    104  // check for a minimimum display aperture.
    105  if (!panScan || hr == MF_E_ATTRIBUTENOTFOUND) {
    106    hr = aMediaType->GetBlob(MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8*)&videoArea,
    107                             sizeof(MFVideoArea), NULL);
    108  }
    109 
    110  if (hr == MF_E_ATTRIBUTENOTFOUND) {
    111    // Minimum display aperture is not set, for "backward compatibility with
    112    // some components", check for a geometric aperture.
    113    hr = aMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE, (UINT8*)&videoArea,
    114                             sizeof(MFVideoArea), NULL);
    115  }
    116 
    117  if (SUCCEEDED(hr)) {
    118    // The media specified a picture region, return it.
    119    IntRect picture = IntRect(MFOffsetToInt32(videoArea.OffsetX),
    120                              MFOffsetToInt32(videoArea.OffsetY),
    121                              videoArea.Area.cx, videoArea.Area.cy);
    122    ENSURE(picture.width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL);
    123    ENSURE(picture.height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL);
    124    aOutPictureRegion = picture;
    125    return S_OK;
    126  }
    127 
    128  // No picture region defined, fall back to using the entire video area.
    129  UINT32 width = 0, height = 0;
    130  hr = MFGetAttributeSize(aMediaType, MF_MT_FRAME_SIZE, &width, &height);
    131  ENSURE(SUCCEEDED(hr), hr);
    132  ENSURE(width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL);
    133  ENSURE(height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL);
    134  aOutPictureRegion = IntRect(0, 0, width, height);
    135  return S_OK;
    136 }
    137 
    138 HRESULT
    139 GetDefaultStride(IMFMediaType* aType, uint32_t* aOutStride) {
    140  // Try to get the default stride from the media type.
    141  UINT32 stride = 0;
    142  HRESULT hr = aType->GetUINT32(MF_MT_DEFAULT_STRIDE, &stride);
    143  if (SUCCEEDED(hr)) {
    144    ENSURE(stride <= mozilla::MAX_VIDEO_WIDTH, E_FAIL);
    145    *aOutStride = stride;
    146    return S_OK;
    147  }
    148 
    149  // Stride attribute not set, calculate it.
    150  GUID subtype = GUID_NULL;
    151  uint32_t width = 0;
    152  uint32_t height = 0;
    153 
    154  hr = aType->GetGUID(MF_MT_SUBTYPE, &subtype);
    155  ENSURE(SUCCEEDED(hr), hr);
    156 
    157  hr = MFGetAttributeSize(aType, MF_MT_FRAME_SIZE, &width, &height);
    158  ENSURE(SUCCEEDED(hr), hr);
    159  ENSURE(width <= mozilla::MAX_VIDEO_WIDTH, E_FAIL);
    160  ENSURE(height <= mozilla::MAX_VIDEO_HEIGHT, E_FAIL);
    161 
    162  LONG lstride = 0;
    163  hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lstride);
    164  ENSURE(SUCCEEDED(hr), hr);
    165  ENSURE(lstride <= mozilla::MAX_VIDEO_WIDTH, E_FAIL);
    166  ENSURE(lstride >= 0, E_FAIL);
    167  *aOutStride = lstride;
    168 
    169  return hr;
    170 }
    171 
    172 void dump(const uint8_t* data, uint32_t len, const char* filename) {
    173  FILE* f = 0;
    174  fopen_s(&f, filename, "wb");
    175  fwrite(data, len, 1, f);
    176  fclose(f);
    177 }
    178 
    179 HRESULT
    180 CreateMFT(const CLSID& clsid, const char* aDllName,
    181          CComPtr<IMFTransform>& aOutMFT) {
    182  HMODULE module = ::GetModuleHandleA(aDllName);
    183  if (!module) {
    184    LOG("Failed to get %S\n", aDllName);
    185    return E_FAIL;
    186  }
    187 
    188  typedef HRESULT(WINAPI * DllGetClassObjectFnPtr)(
    189      const CLSID& clsid, const IID& iid, void** object);
    190 
    191  DllGetClassObjectFnPtr GetClassObjPtr =
    192      reinterpret_cast<DllGetClassObjectFnPtr>(
    193          GetProcAddress(module, "DllGetClassObject"));
    194  if (!GetClassObjPtr) {
    195    LOG("Failed to get DllGetClassObject\n");
    196    return E_FAIL;
    197  }
    198 
    199  CComPtr<IClassFactory> classFactory;
    200  HRESULT hr = GetClassObjPtr(
    201      clsid, __uuidof(IClassFactory),
    202      reinterpret_cast<void**>(static_cast<IClassFactory**>(&classFactory)));
    203  if (FAILED(hr)) {
    204    LOG("Failed to get H264 IClassFactory\n");
    205    return E_FAIL;
    206  }
    207 
    208  hr = classFactory->CreateInstance(
    209      NULL, __uuidof(IMFTransform),
    210      reinterpret_cast<void**>(static_cast<IMFTransform**>(&aOutMFT)));
    211  if (FAILED(hr)) {
    212    LOG("Failed to get create MFT\n");
    213    return E_FAIL;
    214  }
    215 
    216  return S_OK;
    217 }
    218 
    219 int32_t GetNumThreads(int32_t aCoreCount) {
    220  return aCoreCount > 4 ? -1 : (std::max)(aCoreCount - 1, 1);
    221 }
    222 
    223 }  // namespace wmf