tor-browser

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

desktop_frame_iosurface.mm (3984B)


      1 /*
      2 *  Copyright (c) 2018 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/desktop_capture/mac/desktop_frame_iosurface.h"
     12 
     13 #include "rtc_base/checks.h"
     14 #include "rtc_base/logging.h"
     15 #include "rtc_base/numerics/safe_conversions.h"
     16 
     17 namespace webrtc {
     18 
     19 // static
     20 std::unique_ptr<DesktopFrameIOSurface> DesktopFrameIOSurface::Wrap(
     21    webrtc::ScopedCFTypeRef<IOSurfaceRef> io_surface, CGRect rect) {
     22  if (!io_surface) {
     23    return nullptr;
     24  }
     25 
     26  IOSurfaceIncrementUseCount(io_surface.get());
     27  IOReturn status =
     28      IOSurfaceLock(io_surface.get(), kIOSurfaceLockReadOnly, nullptr);
     29  if (status != kIOReturnSuccess) {
     30    RTC_LOG(LS_ERROR) << "Failed to lock the IOSurface with status " << status;
     31    IOSurfaceDecrementUseCount(io_surface.get());
     32    return nullptr;
     33  }
     34 
     35  // Verify that the image has 32-bit depth.
     36  int bytes_per_pixel = IOSurfaceGetBytesPerElement(io_surface.get());
     37  if (bytes_per_pixel != DesktopFrame::kBytesPerPixel) {
     38    RTC_LOG(LS_ERROR) << "CGDisplayStream handler returned IOSurface with "
     39                      << (8 * bytes_per_pixel)
     40                      << " bits per pixel. Only 32-bit depth is supported.";
     41    IOSurfaceUnlock(io_surface.get(), kIOSurfaceLockReadOnly, nullptr);
     42    IOSurfaceDecrementUseCount(io_surface.get());
     43    return nullptr;
     44  }
     45 
     46  const size_t surface_width = IOSurfaceGetWidth(io_surface.get());
     47  const size_t surface_height = IOSurfaceGetHeight(io_surface.get());
     48  const int32_t stride =
     49      checked_cast<int32_t>(IOSurfaceGetBytesPerRow(io_surface.get()));
     50  uint8_t* const data =
     51      static_cast<uint8_t*>(IOSurfaceGetBaseAddress(io_surface.get()));
     52  int32_t width = checked_cast<int32_t>(surface_width);
     53  int32_t height = checked_cast<int32_t>(surface_height);
     54  ptrdiff_t offset = 0;
     55  ptrdiff_t offset_columns = 0;
     56  ptrdiff_t offset_rows = 0;
     57  if (rect.size.width > 0 && rect.size.height > 0) {
     58    width = checked_cast<int32_t>(std::floor(rect.size.width));
     59    height = checked_cast<int32_t>(std::floor(rect.size.height));
     60    offset_columns = checked_cast<ptrdiff_t>(std::ceil(rect.origin.x));
     61    offset_rows = checked_cast<ptrdiff_t>(std::ceil(rect.origin.y));
     62    offset = stride * offset_rows + bytes_per_pixel * offset_columns;
     63  }
     64 
     65  RTC_LOG(LS_VERBOSE) << "DesktopFrameIOSurface wrapping IOSurface with size "
     66                      << surface_width << "x" << surface_height
     67                      << ". Cropping to (" << offset_columns << ","
     68                      << offset_rows << "; " << width << "x" << height
     69                      << "). Stride=" << stride / bytes_per_pixel
     70                      << ", buffer-offset-px=" << offset / bytes_per_pixel
     71                      << ", buffer-offset-bytes=" << offset;
     72 
     73  RTC_CHECK_GE(surface_width, offset_columns + width);
     74  RTC_CHECK_GE(surface_height, offset_rows + height);
     75  RTC_CHECK_GE(offset, 0);
     76  RTC_CHECK_LE(offset + ((height - 1) * stride) + (width * bytes_per_pixel) - 1,
     77               IOSurfaceGetAllocSize(io_surface.get()));
     78 
     79  return std::unique_ptr<DesktopFrameIOSurface>(new DesktopFrameIOSurface(
     80      io_surface, data + offset, width, height, stride));
     81 }
     82 
     83 DesktopFrameIOSurface::DesktopFrameIOSurface(
     84    webrtc::ScopedCFTypeRef<IOSurfaceRef> io_surface,
     85    uint8_t* data,
     86    int32_t width,
     87    int32_t height,
     88    int32_t stride)
     89    : DesktopFrame(DesktopSize(width, height), stride, data, nullptr),
     90      io_surface_(io_surface) {
     91  RTC_DCHECK(io_surface_);
     92 }
     93 
     94 DesktopFrameIOSurface::~DesktopFrameIOSurface() {
     95  IOSurfaceUnlock(io_surface_.get(), kIOSurfaceLockReadOnly, nullptr);
     96  IOSurfaceDecrementUseCount(io_surface_.get());
     97 }
     98 
     99 }  // namespace webrtc