mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-18 16:17:50 +01:00
Add DesktopFrameCGImage
No functional change. This makes the code more generic and this reduces the size of screen_capturer_mac.mm Bug: webrtc:8652 Change-Id: I37743ba385fea5e1b40df3b094bfc321b8d796ae Reviewed-on: https://webrtc-review.googlesource.com/65082 Commit-Queue: Julien Isorce <julien.isorce@chromium.org> Commit-Queue: Zijie He <zijiehe@chromium.org> Reviewed-by: Zijie He <zijiehe@chromium.org> Cr-Commit-Position: refs/heads/master@{#22684}
This commit is contained in:
parent
9d6f73bfb2
commit
c0719cedac
5 changed files with 129 additions and 21 deletions
|
@ -175,6 +175,8 @@ if (is_mac) {
|
|||
visibility = [ ":desktop_capture" ]
|
||||
sources = [
|
||||
"mac/desktop_configuration.mm",
|
||||
"mac/desktop_frame_cgimage.h",
|
||||
"mac/desktop_frame_cgimage.mm",
|
||||
"mac/screen_capturer_mac.h",
|
||||
"mac/screen_capturer_mac.mm",
|
||||
"mouse_cursor_monitor_mac.mm",
|
||||
|
|
|
@ -4,6 +4,9 @@ include_rules = [
|
|||
]
|
||||
|
||||
specific_include_rules = {
|
||||
"desktop_frame_cgimage\.h": [
|
||||
"+sdk/objc",
|
||||
],
|
||||
"screen_capturer_mac\.mm": [
|
||||
"+sdk/objc",
|
||||
],
|
||||
|
|
48
modules/desktop_capture/mac/desktop_frame_cgimage.h
Normal file
48
modules/desktop_capture/mac/desktop_frame_cgimage.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_FRAME_CGIMAGE_H_
|
||||
#define MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_FRAME_CGIMAGE_H_
|
||||
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "modules/desktop_capture/desktop_frame.h"
|
||||
#include "sdk/objc/Framework/Classes/Common/scoped_cftyperef.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class DesktopFrameCGImage final : public DesktopFrame {
|
||||
public:
|
||||
// Create an image containing a snapshot of the display at the time this is
|
||||
// being called.
|
||||
static std::unique_ptr<DesktopFrameCGImage> CreateForDisplay(
|
||||
CGDirectDisplayID display_id);
|
||||
|
||||
~DesktopFrameCGImage() override;
|
||||
|
||||
private:
|
||||
// This constructor expects |cg_image| to hold a non-null CGImageRef.
|
||||
DesktopFrameCGImage(DesktopSize size,
|
||||
int stride,
|
||||
uint8_t* data,
|
||||
rtc::ScopedCFTypeRef<CGImageRef> cg_image,
|
||||
rtc::ScopedCFTypeRef<CFDataRef> cg_data);
|
||||
|
||||
const rtc::ScopedCFTypeRef<CGImageRef> cg_image_;
|
||||
const rtc::ScopedCFTypeRef<CFDataRef> cg_data_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrameCGImage);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_DESKTOP_CAPTURE_MAC_DESKTOP_FRAME_CGIMAGE_H_
|
67
modules/desktop_capture/mac/desktop_frame_cgimage.mm
Normal file
67
modules/desktop_capture/mac/desktop_frame_cgimage.mm
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/desktop_capture/mac/desktop_frame_cgimage.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
std::unique_ptr<DesktopFrameCGImage> DesktopFrameCGImage::CreateForDisplay(
|
||||
CGDirectDisplayID display_id) {
|
||||
// Create an image containing a snapshot of the display.
|
||||
rtc::ScopedCFTypeRef<CGImageRef> cg_image(CGDisplayCreateImage(display_id));
|
||||
if (!cg_image) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Verify that the image has 32-bit depth.
|
||||
int bits_per_pixel = CGImageGetBitsPerPixel(cg_image.get());
|
||||
if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) {
|
||||
RTC_LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " << bits_per_pixel
|
||||
<< " bits per pixel. Only 32-bit depth is supported.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Request access to the raw pixel data via the image's DataProvider.
|
||||
CGDataProviderRef cg_provider = CGImageGetDataProvider(cg_image.get());
|
||||
RTC_DCHECK(cg_provider);
|
||||
|
||||
// CGDataProviderCopyData returns a new data object containing a copy of the provider’s
|
||||
// data.
|
||||
rtc::ScopedCFTypeRef<CFDataRef> cg_data(CGDataProviderCopyData(cg_provider));
|
||||
RTC_DCHECK(cg_data);
|
||||
|
||||
// CFDataGetBytePtr returns a read-only pointer to the bytes of a CFData object.
|
||||
uint8_t* data = const_cast<uint8_t*>(CFDataGetBytePtr(cg_data.get()));
|
||||
RTC_DCHECK(data);
|
||||
|
||||
DesktopSize size(CGImageGetWidth(cg_image.get()), CGImageGetHeight(cg_image.get()));
|
||||
int stride = CGImageGetBytesPerRow(cg_image.get());
|
||||
|
||||
return std::unique_ptr<DesktopFrameCGImage>(
|
||||
new DesktopFrameCGImage(size, stride, data, cg_image, cg_data));
|
||||
}
|
||||
|
||||
DesktopFrameCGImage::DesktopFrameCGImage(DesktopSize size,
|
||||
int stride,
|
||||
uint8_t* data,
|
||||
rtc::ScopedCFTypeRef<CGImageRef> cg_image,
|
||||
rtc::ScopedCFTypeRef<CFDataRef> cg_data)
|
||||
: DesktopFrame(size, stride, data, nullptr), cg_image_(cg_image), cg_data_(cg_data) {
|
||||
RTC_DCHECK(cg_image_);
|
||||
RTC_DCHECK(cg_data_);
|
||||
}
|
||||
|
||||
DesktopFrameCGImage::~DesktopFrameCGImage() = default;
|
||||
|
||||
} // namespace webrtc
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "modules/desktop_capture/mac/screen_capturer_mac.h"
|
||||
|
||||
#include "modules/desktop_capture/mac/desktop_frame_cgimage.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
@ -405,32 +406,19 @@ bool ScreenCapturerMac::CgBlit(const DesktopFrame& frame, const DesktopRegion& r
|
|||
}
|
||||
}
|
||||
|
||||
// Create an image containing a snapshot of the display.
|
||||
rtc::ScopedCFTypeRef<CGImageRef> image(CGDisplayCreateImage(display_config.id));
|
||||
if (!image) {
|
||||
std::unique_ptr<DesktopFrameCGImage> frame_source =
|
||||
DesktopFrameCGImage::CreateForDisplay(display_config.id);
|
||||
if (!frame_source) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Verify that the image has 32-bit depth.
|
||||
int bits_per_pixel = CGImageGetBitsPerPixel(image.get());
|
||||
if (bits_per_pixel / 8 != DesktopFrame::kBytesPerPixel) {
|
||||
RTC_LOG(LS_ERROR) << "CGDisplayCreateImage() returned imaged with " << bits_per_pixel
|
||||
<< " bits per pixel. Only 32-bit depth is supported.";
|
||||
return false;
|
||||
}
|
||||
const uint8_t* display_base_address = frame_source->data();
|
||||
int src_bytes_per_row = frame_source->stride();
|
||||
RTC_DCHECK(display_base_address);
|
||||
|
||||
// Request access to the raw pixel data via the image's DataProvider.
|
||||
CGDataProviderRef provider = CGImageGetDataProvider(image.get());
|
||||
rtc::ScopedCFTypeRef<CFDataRef> data(CGDataProviderCopyData(provider));
|
||||
RTC_DCHECK(data);
|
||||
|
||||
const uint8_t* display_base_address = CFDataGetBytePtr(data.get());
|
||||
int src_bytes_per_row = CGImageGetBytesPerRow(image.get());
|
||||
|
||||
// |image| size may be different from display_bounds in case the screen was
|
||||
// |frame_source| size may be different from display_bounds in case the screen was
|
||||
// resized recently.
|
||||
copy_region.IntersectWith(
|
||||
DesktopRect::MakeWH(CGImageGetWidth(image.get()), CGImageGetHeight(image.get())));
|
||||
copy_region.IntersectWith(frame_source->rect());
|
||||
|
||||
// Copy the dirty region from the display buffer into our desktop buffer.
|
||||
uint8_t* out_ptr = frame.GetFrameDataAtPos(display_bounds.top_left());
|
||||
|
|
Loading…
Reference in a new issue