tor-browser

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

device_info_impl.cc (8662B)


      1 /*
      2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/video_capture/device_info_impl.h"
     12 
     13 #include <cstdint>
     14 #include <cstdlib>
     15 
     16 #include "absl/strings/match.h"
     17 #include "absl/strings/string_view.h"
     18 #include "api/video/video_rotation.h"
     19 #include "common_video/libyuv/include/webrtc_libyuv.h"
     20 #include "modules/video_capture/video_capture_defines.h"
     21 #include "rtc_base/checks.h"
     22 #include "rtc_base/logging.h"
     23 #include "rtc_base/synchronization/mutex.h"
     24 
     25 #ifndef abs
     26 #define abs(a) (a >= 0 ? a : -a)
     27 #endif
     28 
     29 namespace webrtc {
     30 namespace videocapturemodule {
     31 
     32 DeviceInfoImpl::DeviceInfoImpl()
     33    : _lastUsedDeviceName(nullptr), _lastUsedDeviceNameLength(0) {}
     34 
     35 DeviceInfoImpl::~DeviceInfoImpl(void) {
     36  MutexLock lock(&_apiLock);
     37  free(_lastUsedDeviceName);
     38 }
     39 
     40 int32_t DeviceInfoImpl::NumberOfCapabilities(const char* deviceUniqueIdUTF8) {
     41  if (!deviceUniqueIdUTF8)
     42    return -1;
     43 
     44  MutexLock lock(&_apiLock);
     45 
     46  // Is it the same device that is asked for again.
     47  if (absl::EqualsIgnoreCase(
     48          deviceUniqueIdUTF8,
     49          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
     50    return static_cast<int32_t>(_captureCapabilities.size());
     51  }
     52 
     53  int32_t ret = CreateCapabilityMap(deviceUniqueIdUTF8);
     54  return ret;
     55 }
     56 
     57 int32_t DeviceInfoImpl::GetCapability(const char* deviceUniqueIdUTF8,
     58                                      const uint32_t deviceCapabilityNumber,
     59                                      VideoCaptureCapability& capability) {
     60  RTC_DCHECK(deviceUniqueIdUTF8);
     61 
     62  MutexLock lock(&_apiLock);
     63 
     64  if (!absl::EqualsIgnoreCase(
     65          deviceUniqueIdUTF8,
     66          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
     67    if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) {
     68      return -1;
     69    }
     70  }
     71 
     72  // Make sure the number is valid
     73  if (deviceCapabilityNumber >= (unsigned int)_captureCapabilities.size()) {
     74    RTC_LOG(LS_ERROR) << deviceUniqueIdUTF8 << " Invalid deviceCapabilityNumber "
     75                      << deviceCapabilityNumber << ">= number of capabilities ("
     76                      << _captureCapabilities.size() << ").";
     77    return -1;
     78  }
     79 
     80  capability = _captureCapabilities[deviceCapabilityNumber];
     81  return 0;
     82 }
     83 
     84 int32_t DeviceInfoImpl::GetBestMatchedCapability(
     85    const char* deviceUniqueIdUTF8,
     86    const VideoCaptureCapability& requested,
     87    VideoCaptureCapability& resulting) {
     88  if (!deviceUniqueIdUTF8)
     89    return -1;
     90 
     91  MutexLock lock(&_apiLock);
     92  if (!absl::EqualsIgnoreCase(
     93          deviceUniqueIdUTF8,
     94          absl::string_view(_lastUsedDeviceName, _lastUsedDeviceNameLength))) {
     95    if (-1 == CreateCapabilityMap(deviceUniqueIdUTF8)) {
     96      return -1;
     97    }
     98  }
     99 
    100  int32_t bestformatIndex = -1;
    101  int32_t bestWidth = 0;
    102  int32_t bestHeight = 0;
    103  int32_t bestFrameRate = 0;
    104  VideoType bestVideoType = VideoType::kUnknown;
    105 
    106  const int32_t numberOfCapabilies =
    107      static_cast<int32_t>(_captureCapabilities.size());
    108 
    109  bool hasNonRGB24Capability = false;
    110  for (int32_t tmp = 0; tmp < numberOfCapabilies;
    111       ++tmp)  // Loop through all capabilities
    112  {
    113    VideoCaptureCapability& capability = _captureCapabilities[tmp];
    114    if (capability.videoType != VideoType::kRGB24) {
    115      hasNonRGB24Capability = true;
    116    }
    117  }
    118 
    119  for (int32_t tmp = 0; tmp < numberOfCapabilies;
    120       ++tmp)  // Loop through all capabilities
    121  {
    122    VideoCaptureCapability& capability = _captureCapabilities[tmp];
    123    if (hasNonRGB24Capability && capability.videoType == VideoType::kRGB24) {
    124      continue;
    125    }
    126 
    127    const int32_t diffWidth = capability.width - requested.width;
    128    const int32_t diffHeight = capability.height - requested.height;
    129    const int32_t diffFrameRate = capability.maxFPS - requested.maxFPS;
    130 
    131    const int32_t currentbestDiffWith = bestWidth - requested.width;
    132    const int32_t currentbestDiffHeight = bestHeight - requested.height;
    133    const int32_t currentbestDiffFrameRate = bestFrameRate - requested.maxFPS;
    134 
    135    if ((diffHeight >= 0 &&
    136         diffHeight <= abs(currentbestDiffHeight))  // Height better or equalt
    137                                                    // that previouse.
    138        || (currentbestDiffHeight < 0 && diffHeight >= currentbestDiffHeight)) {
    139      if (diffHeight ==
    140          currentbestDiffHeight)  // Found best height. Care about the width)
    141      {
    142        if ((diffWidth >= 0 &&
    143             diffWidth <= abs(currentbestDiffWith))  // Width better or equal
    144            || (currentbestDiffWith < 0 && diffWidth >= currentbestDiffWith)) {
    145          if (diffWidth == currentbestDiffWith &&
    146              diffHeight == currentbestDiffHeight)  // Same size as previously
    147          {
    148            // Also check the best frame rate if the diff is the same as
    149            // previouse
    150            if (((diffFrameRate >= 0 &&
    151                  diffFrameRate <=
    152                      currentbestDiffFrameRate)  // Frame rate to high but
    153                                                 // better match than previouse
    154                                                 // and we have not selected IUV
    155                 || (currentbestDiffFrameRate < 0 &&
    156                     diffFrameRate >=
    157                         currentbestDiffFrameRate))  // Current frame rate is
    158                                                     // lower than requested.
    159                                                     // This is better.
    160            ) {
    161              if ((currentbestDiffFrameRate ==
    162                   diffFrameRate)  // Same frame rate as previous  or frame rate
    163                                   // allready good enough
    164                  || (currentbestDiffFrameRate >= 0)) {
    165                if (bestVideoType != requested.videoType &&
    166                    requested.videoType != VideoType::kUnknown &&
    167                    (capability.videoType == requested.videoType ||
    168                     capability.videoType == VideoType::kI420 ||
    169                     capability.videoType == VideoType::kYUY2 ||
    170                     capability.videoType == VideoType::kYV12 ||
    171                     capability.videoType == VideoType::kNV12)) {
    172                  bestVideoType = capability.videoType;
    173                  bestformatIndex = tmp;
    174                }
    175                // If width height and frame rate is full filled we can use the
    176                // camera for encoding if it is supported.
    177                if (capability.height == requested.height &&
    178                    capability.width == requested.width &&
    179                    capability.maxFPS >= requested.maxFPS) {
    180                  bestVideoType = capability.videoType;
    181                  bestformatIndex = tmp;
    182                }
    183              } else  // Better frame rate
    184              {
    185                bestWidth = capability.width;
    186                bestHeight = capability.height;
    187                bestFrameRate = capability.maxFPS;
    188                bestVideoType = capability.videoType;
    189                bestformatIndex = tmp;
    190              }
    191            }
    192          } else  // Better width than previously
    193          {
    194            bestWidth = capability.width;
    195            bestHeight = capability.height;
    196            bestFrameRate = capability.maxFPS;
    197            bestVideoType = capability.videoType;
    198            bestformatIndex = tmp;
    199          }
    200        }     // else width no good
    201      } else  // Better height
    202      {
    203        bestWidth = capability.width;
    204        bestHeight = capability.height;
    205        bestFrameRate = capability.maxFPS;
    206        bestVideoType = capability.videoType;
    207        bestformatIndex = tmp;
    208      }
    209    }  // else height not good
    210  }    // end for
    211 
    212  RTC_LOG(LS_VERBOSE) << "Best camera format: " << bestWidth << "x"
    213                      << bestHeight << "@" << bestFrameRate
    214                      << "fps, color format: "
    215                      << static_cast<int>(bestVideoType);
    216 
    217  // Copy the capability
    218  if (bestformatIndex < 0)
    219    return -1;
    220  resulting = _captureCapabilities[bestformatIndex];
    221  return bestformatIndex;
    222 }
    223 
    224 // Default implementation. This should be overridden by Mobile implementations.
    225 int32_t DeviceInfoImpl::GetOrientation(const char* /* deviceUniqueIdUTF8 */,
    226                                       VideoRotation& orientation) {
    227  orientation = kVideoRotation_0;
    228  return -1;
    229 }
    230 }  // namespace videocapturemodule
    231 }  // namespace webrtc