diff options
Diffstat (limited to 'media/video/capture/screen')
-rw-r--r-- | media/video/capture/screen/screen_capturer_mac.mm | 163 | ||||
-rw-r--r-- | media/video/capture/screen/screen_capturer_win.cc | 131 | ||||
-rw-r--r-- | media/video/capture/screen/screen_capturer_x11.cc | 3 |
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++); |