summaryrefslogtreecommitdiffstats
path: root/media/video/capture/screen
diff options
context:
space:
mode:
Diffstat (limited to 'media/video/capture/screen')
-rw-r--r--media/video/capture/screen/screen_capturer_mac.mm163
-rw-r--r--media/video/capture/screen/screen_capturer_win.cc131
-rw-r--r--media/video/capture/screen/screen_capturer_x11.cc3
3 files changed, 161 insertions, 136 deletions
diff --git a/media/video/capture/screen/screen_capturer_mac.mm b/media/video/capture/screen/screen_capturer_mac.mm
index b90364c..158775a 100644
--- a/media/video/capture/screen/screen_capturer_mac.mm
+++ b/media/video/capture/screen/screen_capturer_mac.mm
@@ -10,17 +10,13 @@
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <OpenGL/CGLMacro.h>
#include <OpenGL/OpenGL.h>
+#include <sys/utsname.h>
#include <stddef.h>
#include <set>
-#include "base/files/file_path.h"
#include "base/logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
-#include "base/scoped_native_library.h"
#include "base/synchronization/waitable_event.h"
-#include "base/time.h"
#include "media/video/capture/screen/mac/desktop_configuration.h"
#include "media/video/capture/screen/mac/scoped_pixel_buffer_object.h"
#include "media/video/capture/screen/mouse_cursor_shape.h"
@@ -82,6 +78,36 @@ void CopyRect(const uint8* src_plane,
}
}
+int GetDarwinVersion() {
+ struct utsname uname_info;
+ if (uname(&uname_info) != 0) {
+ LOG(ERROR) << "uname failed";
+ return 0;
+ }
+
+ if (strcmp(uname_info.sysname, "Darwin") != 0)
+ return 0;
+
+ char* dot;
+ int result = strtol(uname_info.release, &dot, 10);
+ if (*dot != '.') {
+ LOG(ERROR) << "Failed to parse version";
+ return 0;
+ }
+
+ return result;
+}
+
+bool IsOSLionOrLater() {
+ static int darwin_version = GetDarwinVersion();
+
+ // Verify that the version has been parsed correctly.
+ CHECK(darwin_version >= 6);
+
+ // Darwin major version 11 corresponds to OSX 10.7.
+ return darwin_version >= 11;
+}
+
// The amount of time allowed for displays to reconfigure.
const int64 kDisplayConfigurationEventTimeoutInSeconds = 10;
@@ -151,8 +177,8 @@ class ScreenCapturerMac : public ScreenCapturer {
// recently captured screen.
ScreenCapturerHelper helper_;
- // Image of the last cursor that we sent to the client.
- base::mac::ScopedCFTypeRef<CGImageRef> current_cursor_;
+ // The last cursor that we sent to the client.
+ MouseCursorShape last_cursor_;
// Contains an invalid region from the previous capture.
webrtc::DesktopRegion last_invalid_region_;
@@ -172,11 +198,11 @@ class ScreenCapturerMac : public ScreenCapturer {
IOPMAssertionID power_assertion_id_user_;
// Dynamically link to deprecated APIs for Mac OS X 10.6 support.
- base::ScopedNativeLibrary app_services_library_;
+ void* app_services_library_;
CGDisplayBaseAddressFunc cg_display_base_address_;
CGDisplayBytesPerRowFunc cg_display_bytes_per_row_;
CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_;
- base::ScopedNativeLibrary opengl_library_;
+ void* opengl_library_;
CGLSetFullScreenFunc cgl_set_full_screen_;
DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac);
@@ -202,9 +228,11 @@ ScreenCapturerMac::ScreenCapturerMac()
display_configuration_capture_event_(false, true),
power_assertion_id_display_(kIOPMNullAssertionID),
power_assertion_id_user_(kIOPMNullAssertionID),
+ app_services_library_(NULL),
cg_display_base_address_(NULL),
cg_display_bytes_per_row_(NULL),
cg_display_bits_per_pixel_(NULL),
+ opengl_library_(NULL),
cgl_set_full_screen_(NULL) {
}
@@ -222,9 +250,11 @@ ScreenCapturerMac::~ScreenCapturerMac() {
UnregisterRefreshAndMoveHandlers();
CGError err = CGDisplayRemoveReconfigurationCallback(
ScreenCapturerMac::DisplaysReconfiguredCallback, this);
- if (err != kCGErrorSuccess) {
+ if (err != kCGErrorSuccess)
LOG(ERROR) << "CGDisplayRemoveReconfigurationCallback " << err;
- }
+
+ dlclose(app_services_library_);
+ dlclose(opengl_library_);
}
bool ScreenCapturerMac::Init() {
@@ -303,7 +333,7 @@ void ScreenCapturerMac::Capture(
webrtc::DesktopFrame* current_frame = queue_.current_frame();
bool flip = false; // GL capturers need flipping.
- if (base::mac::IsOSLionOrLater()) {
+ if (IsOSLionOrLater()) {
// Lion requires us to use their new APIs for doing screen capture. These
// APIS currently crash on 10.6.8 if there is no monitor attached.
CgBlitPostLion(*current_frame, region);
@@ -352,10 +382,12 @@ void ScreenCapturerMac::SetMouseShapeObserver(
}
void ScreenCapturerMac::CaptureCursor() {
+ if (!mouse_shape_observer_)
+ return;
+
NSCursor* cursor = [NSCursor currentSystemCursor];
- if (cursor == nil) {
+ if (cursor == nil)
return;
- }
NSImage* nsimage = [cursor image];
NSPoint hotspot = [cursor hotSpot];
@@ -363,9 +395,8 @@ void ScreenCapturerMac::CaptureCursor() {
CGImageRef image = [nsimage CGImageForProposedRect:NULL
context:nil
hints:nil];
- if (image == nil) {
+ if (image == nil)
return;
- }
if (CGImageGetBitsPerPixel(image) != 32 ||
CGImageGetBytesPerRow(image) != (size.width * 4) ||
@@ -373,46 +404,11 @@ void ScreenCapturerMac::CaptureCursor() {
return;
}
- // Compare the current cursor with the last one we sent to the client
- // and exit if the cursor is the same.
- if (current_cursor_.get() != NULL) {
- CGImageRef current = current_cursor_.get();
- if (CGImageGetWidth(image) == CGImageGetWidth(current) &&
- CGImageGetHeight(image) == CGImageGetHeight(current) &&
- CGImageGetBitsPerPixel(image) == CGImageGetBitsPerPixel(current) &&
- CGImageGetBytesPerRow(image) == CGImageGetBytesPerRow(current) &&
- CGImageGetBitsPerComponent(image) ==
- CGImageGetBitsPerComponent(current)) {
- CGDataProviderRef provider_new = CGImageGetDataProvider(image);
- base::mac::ScopedCFTypeRef<CFDataRef> data_ref_new(
- CGDataProviderCopyData(provider_new));
- CGDataProviderRef provider_current = CGImageGetDataProvider(current);
- base::mac::ScopedCFTypeRef<CFDataRef> data_ref_current(
- CGDataProviderCopyData(provider_current));
-
- if (data_ref_new.get() != NULL && data_ref_current.get() != NULL) {
- int data_size = CFDataGetLength(data_ref_new);
- CHECK(data_size == CFDataGetLength(data_ref_current));
- const uint8* data_new = CFDataGetBytePtr(data_ref_new);
- const uint8* data_current = CFDataGetBytePtr(data_ref_current);
- if (memcmp(data_new, data_current, data_size) == 0) {
- return;
- }
- }
- }
- }
-
- // Record the last cursor image.
- current_cursor_.reset(CGImageCreateCopy(image));
-
- VLOG(3) << "Sending cursor: " << size.width << "x" << size.height;
-
CGDataProviderRef provider = CGImageGetDataProvider(image);
- base::mac::ScopedCFTypeRef<CFDataRef> image_data_ref(
- CGDataProviderCopyData(provider));
- if (image_data_ref.get() == NULL) {
+ CFDataRef image_data_ref = CGDataProviderCopyData(provider);
+ if (image_data_ref == NULL)
return;
- }
+
const char* cursor_src_data =
reinterpret_cast<const char*>(CFDataGetBytePtr(image_data_ref));
int data_size = CFDataGetLength(image_data_ref);
@@ -424,8 +420,21 @@ void ScreenCapturerMac::CaptureCursor() {
cursor_shape->hotspot.set(hotspot.x, hotspot.y);
cursor_shape->data.assign(cursor_src_data, cursor_src_data + data_size);
- if (mouse_shape_observer_)
- mouse_shape_observer_->OnCursorShapeChanged(cursor_shape.Pass());
+ CFRelease(image_data_ref);
+
+ // Compare the current cursor with the last one we sent to the client. If
+ // they're the same, then don't bother sending the cursor again.
+ if (last_cursor_.size.equals(cursor_shape->size) &&
+ last_cursor_.hotspot.equals(cursor_shape->hotspot) &&
+ last_cursor_.data == cursor_shape->data) {
+ return;
+ }
+
+ // Record the last cursor image that we sent to the client.
+ last_cursor_ = *cursor_shape;
+
+ VLOG(3) << "Sending cursor: " << size.width << "x" << size.height;
+ mouse_shape_observer_->OnCursorShapeChanged(cursor_shape.Pass());
}
void ScreenCapturerMac::GlBlitFast(const webrtc::DesktopFrame& frame,
@@ -596,17 +605,14 @@ void ScreenCapturerMac::CgBlitPostLion(const webrtc::DesktopFrame& frame,
copy_region.Translate(-display_bounds.left(), -display_bounds.top());
// Create an image containing a snapshot of the display.
- base::mac::ScopedCFTypeRef<CGImageRef> image(
- CGDisplayCreateImage(display_config.id));
- if (image.get() == NULL)
+ CGImageRef image = CGDisplayCreateImage(display_config.id);
+ if (image == NULL)
continue;
// Request access to the raw pixel data via the image's DataProvider.
CGDataProviderRef provider = CGImageGetDataProvider(image);
- base::mac::ScopedCFTypeRef<CFDataRef> data(
- CGDataProviderCopyData(provider));
- if (data.get() == NULL)
- continue;
+ CFDataRef data = CGDataProviderCopyData(provider);
+ CHECK(data);
const uint8* display_base_address = CFDataGetBytePtr(data);
int src_bytes_per_row = CGImageGetBytesPerRow(image);
@@ -627,6 +633,9 @@ void ScreenCapturerMac::CgBlitPostLion(const webrtc::DesktopFrame& frame,
src_bytes_per_pixel,
i.rect());
}
+
+ CFRelease(data);
+ CFRelease(image);
}
}
@@ -653,33 +662,29 @@ void ScreenCapturerMac::ScreenConfigurationChanged() {
// contents. Although the API exists in OS 10.6, it crashes the caller if
// the machine has no monitor connected, so we fall back to depcreated APIs
// when running on 10.6.
- if (base::mac::IsOSLionOrLater()) {
+ if (IsOSLionOrLater()) {
LOG(INFO) << "Using CgBlitPostLion.";
// No need for any OpenGL support on Lion
return;
}
// Dynamically link to the deprecated pre-Lion capture APIs.
- std::string app_services_library_error;
- base::FilePath app_services_path(kApplicationServicesLibraryName);
- app_services_library_.Reset(
- base::LoadNativeLibrary(app_services_path, &app_services_library_error));
- CHECK(app_services_library_.is_valid()) << app_services_library_error;
-
- std::string opengl_library_error;
- base::FilePath opengl_path(kOpenGlLibraryName);
- opengl_library_.Reset(
- base::LoadNativeLibrary(opengl_path, &opengl_library_error));
- CHECK(opengl_library_.is_valid()) << opengl_library_error;
+ app_services_library_ = dlopen(kApplicationServicesLibraryName,
+ RTLD_LAZY);
+ CHECK(app_services_library_)
+ << "Failed to open " << kApplicationServicesLibraryName;
+
+ opengl_library_ = dlopen(kOpenGlLibraryName, RTLD_LAZY);
+ CHECK(opengl_library_) << "Failed to open " << kOpenGlLibraryName;
cg_display_base_address_ = reinterpret_cast<CGDisplayBaseAddressFunc>(
- app_services_library_.GetFunctionPointer("CGDisplayBaseAddress"));
+ dlsym(app_services_library_, "CGDisplayBaseAddress"));
cg_display_bytes_per_row_ = reinterpret_cast<CGDisplayBytesPerRowFunc>(
- app_services_library_.GetFunctionPointer("CGDisplayBytesPerRow"));
+ dlsym(app_services_library_, "CGDisplayBytesPerRow"));
cg_display_bits_per_pixel_ = reinterpret_cast<CGDisplayBitsPerPixelFunc>(
- app_services_library_.GetFunctionPointer("CGDisplayBitsPerPixel"));
+ dlsym(app_services_library_, "CGDisplayBitsPerPixel"));
cgl_set_full_screen_ = reinterpret_cast<CGLSetFullScreenFunc>(
- opengl_library_.GetFunctionPointer("CGLSetFullScreen"));
+ dlsym(opengl_library_, "CGLSetFullScreen"));
CHECK(cg_display_base_address_ && cg_display_bytes_per_row_ &&
cg_display_bits_per_pixel_ && cgl_set_full_screen_);
diff --git a/media/video/capture/screen/screen_capturer_win.cc b/media/video/capture/screen/screen_capturer_win.cc
index 05ec931..9ba115f 100644
--- a/media/video/capture/screen/screen_capturer_win.cc
+++ b/media/video/capture/screen/screen_capturer_win.cc
@@ -6,24 +6,15 @@
#include <windows.h>
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/scoped_native_library.h"
-#include "base/stl_util.h"
#include "base/time.h"
-#include "base/utf_string_conversions.h"
-#include "base/win/scoped_gdi_object.h"
-#include "base/win/scoped_hdc.h"
#include "media/video/capture/screen/differ.h"
#include "media/video/capture/screen/mouse_cursor_shape.h"
#include "media/video/capture/screen/screen_capture_frame_queue.h"
#include "media/video/capture/screen/screen_capturer_helper.h"
#include "media/video/capture/screen/win/desktop.h"
#include "media/video/capture/screen/win/scoped_thread_desktop.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame_win.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
@@ -38,13 +29,17 @@ const UINT DWM_EC_ENABLECOMPOSITION = 1;
typedef HRESULT (WINAPI * DwmEnableCompositionFunc)(UINT);
-const char kDwmapiLibraryName[] = "dwmapi";
+const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll";
// Pixel colors used when generating cursor outlines.
const uint32 kPixelBgraBlack = 0xff000000;
const uint32 kPixelBgraWhite = 0xffffffff;
const uint32 kPixelBgraTransparent = 0x00000000;
+uint8_t AlphaMul(uint8_t v, uint8_t alpha) {
+ return (static_cast<uint16_t>(v) * alpha) >> 8;
+}
+
// ScreenCapturerWin captures 32bit RGB using GDI.
//
// ScreenCapturerWin is double-buffered as required by ScreenCapturer.
@@ -88,19 +83,19 @@ class ScreenCapturerWin : public ScreenCapturer {
ScopedThreadDesktop desktop_;
// GDI resources used for screen capture.
- scoped_ptr<base::win::ScopedGetDC> desktop_dc_;
- base::win::ScopedCreateDC memory_dc_;
+ HDC desktop_dc_;
+ HDC memory_dc_;
// Queue of the frames buffers.
ScreenCaptureFrameQueue queue_;
// Rectangle describing the bounds of the desktop device context.
- SkIRect desktop_dc_rect_;
+ webrtc::DesktopRect desktop_dc_rect_;
// Class to calculate the difference between two screen bitmaps.
scoped_ptr<Differ> differ_;
- base::ScopedNativeLibrary dwmapi_library_;
+ HMODULE dwmapi_library_;
DwmEnableCompositionFunc composition_func_;
// Used to suppress duplicate logging of SetThreadExecutionState errors.
@@ -112,29 +107,35 @@ class ScreenCapturerWin : public ScreenCapturer {
ScreenCapturerWin::ScreenCapturerWin(bool disable_aero)
: callback_(NULL),
mouse_shape_observer_(NULL),
- desktop_dc_rect_(SkIRect::MakeEmpty()),
+ desktop_dc_(NULL),
+ memory_dc_(NULL),
+ dwmapi_library_(NULL),
composition_func_(NULL),
set_thread_execution_state_failed_(false) {
if (disable_aero) {
// Load dwmapi.dll dynamically since it is not available on XP.
- if (!dwmapi_library_.is_valid()) {
- base::FilePath path(base::GetNativeLibraryName(
- UTF8ToUTF16(kDwmapiLibraryName)));
- dwmapi_library_.Reset(base::LoadNativeLibrary(path, NULL));
- }
+ if (!dwmapi_library_)
+ dwmapi_library_ = LoadLibrary(kDwmapiLibraryName);
- if (dwmapi_library_.is_valid() && composition_func_ == NULL) {
+ if (dwmapi_library_) {
composition_func_ = reinterpret_cast<DwmEnableCompositionFunc>(
- dwmapi_library_.GetFunctionPointer("DwmEnableComposition"));
+ GetProcAddress(dwmapi_library_, "DwmEnableComposition"));
}
}
}
ScreenCapturerWin::~ScreenCapturerWin() {
+ if (desktop_dc_)
+ ReleaseDC(NULL, desktop_dc_);
+ if (memory_dc_)
+ DeleteDC(memory_dc_);
+
// Restore Aero.
- if (composition_func_ != NULL) {
+ if (composition_func_)
(*composition_func_)(DWM_EC_ENABLECOMPOSITION);
- }
+
+ if (dwmapi_library_)
+ FreeLibrary(dwmapi_library_);
}
void ScreenCapturerWin::Capture(const webrtc::DesktopRegion& region) {
@@ -187,8 +188,8 @@ void ScreenCapturerWin::Capture(const webrtc::DesktopRegion& region) {
// Emit the current frame.
webrtc::DesktopFrame* frame = queue_.current_frame()->Share();
frame->set_dpi(webrtc::DesktopVector(
- GetDeviceCaps(*desktop_dc_, LOGPIXELSX),
- GetDeviceCaps(*desktop_dc_, LOGPIXELSY)));
+ GetDeviceCaps(desktop_dc_, LOGPIXELSX),
+ GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
frame->mutable_updated_region()->Clear();
helper_.TakeInvalidRegion(frame->mutable_updated_region());
frame->set_capture_time_ms(
@@ -216,9 +217,8 @@ void ScreenCapturerWin::Start(Callback* callback) {
// Vote to disable Aero composited desktop effects while capturing. Windows
// will restore Aero automatically if the process exits. This has no effect
// under Windows 8 or higher. See crbug.com/124018.
- if (composition_func_ != NULL) {
+ if (composition_func_)
(*composition_func_)(DWM_EC_DISABLECOMPOSITION);
- }
}
void ScreenCapturerWin::PrepareCaptureResources() {
@@ -227,8 +227,15 @@ void ScreenCapturerWin::PrepareCaptureResources() {
scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop();
if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
// Release GDI resources otherwise SetThreadDesktop will fail.
- desktop_dc_.reset();
- memory_dc_.Set(NULL);
+ if (desktop_dc_) {
+ ReleaseDC(NULL, desktop_dc_);
+ desktop_dc_ = NULL;
+ }
+
+ if (memory_dc_) {
+ DeleteDC(memory_dc_);
+ memory_dc_ = NULL;
+ }
// If SetThreadDesktop() fails, the thread is still assigned a desktop.
// So we can continue capture screen bits, just from the wrong desktop.
@@ -243,23 +250,31 @@ void ScreenCapturerWin::PrepareCaptureResources() {
// If the display bounds have changed then recreate GDI resources.
// TODO(wez): Also check for pixel format changes.
- SkIRect screen_rect(SkIRect::MakeXYWH(
+ webrtc::DesktopRect screen_rect(webrtc::DesktopRect::MakeXYWH(
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN)));
- if (screen_rect != desktop_dc_rect_) {
- desktop_dc_.reset();
- memory_dc_.Set(NULL);
- desktop_dc_rect_.setEmpty();
+ if (!screen_rect.equals(desktop_dc_rect_)) {
+ if (desktop_dc_) {
+ ReleaseDC(NULL, desktop_dc_);
+ desktop_dc_ = NULL;
+ }
+ if (memory_dc_) {
+ DeleteDC(memory_dc_);
+ memory_dc_ = NULL;
+ }
+ desktop_dc_rect_ = webrtc::DesktopRect();
}
- if (desktop_dc_.get() == NULL) {
- DCHECK(memory_dc_.Get() == NULL);
+ if (desktop_dc_ == NULL) {
+ DCHECK(memory_dc_ == NULL);
// Create GDI device contexts to capture from the desktop into memory.
- desktop_dc_.reset(new base::win::ScopedGetDC(NULL));
- memory_dc_.Set(CreateCompatibleDC(*desktop_dc_));
+ desktop_dc_ = GetDC(NULL);
+ CHECK(desktop_dc_);
+ memory_dc_ = CreateCompatibleDC(desktop_dc_);
+ CHECK(memory_dc_);
desktop_dc_rect_ = screen_rect;
// Make sure the frame buffers will be reallocated.
@@ -274,8 +289,8 @@ void ScreenCapturerWin::CaptureImage() {
// Note that we can't reallocate other buffers at this point, since the caller
// may still be reading from them.
if (!queue_.current_frame()) {
- DCHECK(desktop_dc_.get() != NULL);
- DCHECK(memory_dc_.Get() != NULL);
+ DCHECK(desktop_dc_ != NULL);
+ DCHECK(memory_dc_ != NULL);
webrtc::DesktopSize size = webrtc::DesktopSize(
desktop_dc_rect_.width(), desktop_dc_rect_.height());
@@ -285,7 +300,7 @@ void ScreenCapturerWin::CaptureImage() {
webrtc::SharedMemory* shared_memory =
callback_->CreateSharedMemory(buffer_size);
scoped_ptr<webrtc::DesktopFrameWin> buffer(
- webrtc::DesktopFrameWin::Create(size, shared_memory, *desktop_dc_));
+ webrtc::DesktopFrameWin::Create(size, shared_memory, desktop_dc_));
queue_.ReplaceCurrentFrame(buffer.PassAs<webrtc::DesktopFrame>());
}
@@ -297,8 +312,8 @@ void ScreenCapturerWin::CaptureImage() {
if (previous_object != NULL) {
BitBlt(memory_dc_,
0, 0, desktop_dc_rect_.width(), desktop_dc_rect_.height(),
- *desktop_dc_,
- desktop_dc_rect_.x(), desktop_dc_rect_.y(),
+ desktop_dc_,
+ desktop_dc_rect_.left(), desktop_dc_rect_.top(),
SRCCOPY | CAPTUREBLT);
// Select back the previously selected object to that the device contect
@@ -348,15 +363,15 @@ void ScreenCapturerWin::CaptureCursor() {
int hotspot_y = iinfo.yHotspot;
// Get the cursor bitmap.
- base::win::ScopedBitmap hbitmap;
+ HBITMAP hbitmap;
BITMAP bitmap;
bool color_bitmap;
if (iinfo.hbmColor) {
// Color cursor bitmap.
color_bitmap = true;
- hbitmap.Set((HBITMAP)CopyImage(iinfo.hbmColor, IMAGE_BITMAP, 0, 0,
- LR_CREATEDIBSECTION));
- if (!hbitmap.Get()) {
+ hbitmap = reinterpret_cast<HBITMAP>(
+ CopyImage(iinfo.hbmColor, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION));
+ if (!hbitmap) {
VLOG(3) << "Unable to copy color cursor image. Error = "
<< GetLastError();
return;
@@ -368,11 +383,12 @@ void ScreenCapturerWin::CaptureCursor() {
} else {
// Black and white (xor) cursor.
color_bitmap = false;
- hbitmap.Set(iinfo.hbmMask);
+ hbitmap = iinfo.hbmMask;
}
- if (!GetObject(hbitmap.Get(), sizeof(BITMAP), &bitmap)) {
+ if (!GetObject(hbitmap, sizeof(BITMAP), &bitmap)) {
VLOG(3) << "Unable to get cursor bitmap. Error = " << GetLastError();
+ DeleteObject(hbitmap);
return;
}
@@ -389,13 +405,14 @@ void ScreenCapturerWin::CaptureCursor() {
scoped_ptr<MouseCursorShape> cursor(new MouseCursorShape());
cursor->data.resize(data_size);
uint8* cursor_dst_data =
- reinterpret_cast<uint8*>(string_as_array(&cursor->data));
+ reinterpret_cast<uint8*>(&*(cursor->data.begin()));
// Copy/convert cursor bitmap into format needed by chromotocol.
int row_bytes = bitmap.bmWidthBytes;
if (color_bitmap) {
if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 32) {
VLOG(3) << "Unsupported color cursor format. Error = " << GetLastError();
+ DeleteObject(hbitmap);
return;
}
@@ -408,9 +425,9 @@ void ScreenCapturerWin::CaptureCursor() {
uint8* dst = cursor_dst_data;
for (int row = 0; row < height; ++row) {
for (int column = 0; column < width; ++column) {
- dst[0] = SkAlphaMul(src[0], src[3]);
- dst[1] = SkAlphaMul(src[1], src[3]);
- dst[2] = SkAlphaMul(src[2], src[3]);
+ dst[0] = AlphaMul(src[0], src[3]);
+ dst[1] = AlphaMul(src[1], src[3]);
+ dst[2] = AlphaMul(src[2], src[3]);
dst[3] = src[3];
dst += webrtc::DesktopFrame::kBytesPerPixel;
src += webrtc::DesktopFrame::kBytesPerPixel;
@@ -420,14 +437,16 @@ void ScreenCapturerWin::CaptureCursor() {
} else {
if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 1) {
VLOG(3) << "Unsupported cursor mask format. Error = " << GetLastError();
+ DeleteObject(hbitmap);
return;
}
// x2 because there are 2 masks in the bitmap: AND and XOR.
int mask_bytes = height * row_bytes * 2;
scoped_ptr<uint8[]> mask(new uint8[mask_bytes]);
- if (!GetBitmapBits(hbitmap.Get(), mask_bytes, mask.get())) {
+ if (!GetBitmapBits(hbitmap, mask_bytes, mask.get())) {
VLOG(3) << "Unable to get cursor mask bits. Error = " << GetLastError();
+ DeleteObject(hbitmap);
return;
}
uint8* and_mask = mask.get();
@@ -467,6 +486,8 @@ void ScreenCapturerWin::CaptureCursor() {
}
}
+ DeleteObject(hbitmap);
+
cursor->size.set(width, height);
cursor->hotspot.set(hotspot_x, hotspot_y);
diff --git a/media/video/capture/screen/screen_capturer_x11.cc b/media/video/capture/screen/screen_capturer_x11.cc
index 7d1ee78..775151c 100644
--- a/media/video/capture/screen/screen_capturer_x11.cc
+++ b/media/video/capture/screen/screen_capturer_x11.cc
@@ -14,7 +14,6 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
#include "media/video/capture/screen/differ.h"
#include "media/video/capture/screen/mouse_cursor_shape.h"
#include "media/video/capture/screen/screen_capture_frame_queue.h"
@@ -345,7 +344,7 @@ void ScreenCapturerLinux::CaptureCursor() {
// Xlib stores 32-bit data in longs, even if longs are 64-bits long.
unsigned long* src = img->pixels;
- uint32* dst = reinterpret_cast<uint32*>(string_as_array(&cursor->data));
+ uint32* dst = reinterpret_cast<uint32*>(&*(cursor->data.begin()));
uint32* dst_end = dst + (img->width * img->height);
while (dst < dst_end) {
*dst++ = static_cast<uint32>(*src++);