Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/desktop_capture/screen_capturer.h" | 11 #include "webrtc/modules/desktop_capture/screen_capturer.h" |
| 12 | 12 |
| 13 #include <stddef.h> | 13 #include <stddef.h> |
| 14 | 14 |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <set> | 16 #include <set> |
| 17 #include <utility> | 17 #include <utility> |
| 18 | 18 |
| 19 #include <ApplicationServices/ApplicationServices.h> | 19 #include <ApplicationServices/ApplicationServices.h> |
| 20 #include <Cocoa/Cocoa.h> | 20 #include <Cocoa/Cocoa.h> |
| 21 #include <CoreGraphics/CoreGraphics.h> | |
| 21 #include <dlfcn.h> | 22 #include <dlfcn.h> |
| 22 #include <OpenGL/CGLMacro.h> | 23 #include <OpenGL/CGLMacro.h> |
| 23 #include <OpenGL/OpenGL.h> | 24 #include <OpenGL/OpenGL.h> |
| 24 | 25 |
| 25 #include "webrtc/base/checks.h" | 26 #include "webrtc/base/checks.h" |
| 26 #include "webrtc/base/constructormagic.h" | 27 #include "webrtc/base/constructormagic.h" |
| 27 #include "webrtc/base/macutils.h" | 28 #include "webrtc/base/macutils.h" |
| 29 #include "webrtc/base/criticalsection.h" | |
| 28 #include "webrtc/base/timeutils.h" | 30 #include "webrtc/base/timeutils.h" |
| 29 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 31 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
| 30 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 32 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
| 31 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | 33 #include "webrtc/modules/desktop_capture/desktop_geometry.h" |
| 32 #include "webrtc/modules/desktop_capture/desktop_region.h" | 34 #include "webrtc/modules/desktop_capture/desktop_region.h" |
| 33 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" | 35 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" |
| 34 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" | 36 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" |
| 35 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" | 37 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" |
| 36 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" | 38 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" |
| 37 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" | 39 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h" |
| 38 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" | 40 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" |
| 39 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" | 41 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h" |
| 40 #include "webrtc/system_wrappers/include/logging.h" | 42 #include "webrtc/system_wrappers/include/logging.h" |
| 41 | 43 |
| 42 namespace webrtc { | 44 namespace webrtc { |
| 43 | 45 |
| 44 namespace { | 46 namespace { |
| 45 | 47 |
| 48 // This container (in conjunction with g_display_stream_wrappers) has two | |
| 49 // purposes: | |
| 50 // 1) Maps from unique id to CGDisplayStreamRef, to allow destruction of the | |
| 51 // appropriate CGDisplayStreamRef from the callback. | |
| 52 // 2) Adds sufficient metadata to map ownership of active CGDisplayStreamRefs | |
| 53 // to ScreenCapturerMac. This could theoretically be done with another | |
| 54 // instance-scoped container in ScreenCapturerMac, but having a single, global | |
| 55 // container seems cleaner. | |
| 56 struct DisplayStreamWrapper { | |
| 57 // The registered CGDisplayStreamRef. | |
| 58 CGDisplayStreamRef stream = nullptr; | |
| 59 | |
| 60 // Once |stream| has been stopped, this parameter is set to false. Only after | |
| 61 // an asynchronous callback from CoreGraphics can CGDisplayStreamRef be | |
| 62 // destroyed. | |
| 63 bool active = true; | |
| 64 | |
| 65 // Metadata that allow instances of ScreenCapturerMac to determine whether | |
| 66 // they own |stream|. | |
| 67 void* owner = nullptr; | |
|
Sergey Ulanov
2016/10/06 23:51:33
Maybe make this ScreenCapturerMac*?
erikchen
2016/10/07 17:56:19
Rewrote to use a self-owned manager rather than a
| |
| 68 }; | |
| 69 | |
| 70 // CGDisplayStreamRef needs to be destroyed asynchronously, after a callback | |
| 71 // with status kCGDisplayStreamFrameStatusStopped. There's no guarantee that | |
| 72 // ScreenCapturerMac will still be around, so we need a global to maintain the | |
| 73 // mapping from callback to CGDisplayStreamRef. | |
| 74 static std::map<int, DisplayStreamWrapper> g_display_stream_wrappers; | |
| 75 static int g_unique_id_generator = 0; | |
| 76 static rtc::CriticalSection g_display_stream_critical_section; | |
|
Sergey Ulanov
2016/10/06 23:51:33
This and g_display_stream_wrappers will require st
erikchen
2016/10/07 17:56:19
no more statics and globals. :)
| |
| 77 | |
| 46 // Definitions used to dynamic-link to deprecated OS 10.6 functions. | 78 // Definitions used to dynamic-link to deprecated OS 10.6 functions. |
| 47 const char* kApplicationServicesLibraryName = | 79 const char* kApplicationServicesLibraryName = |
| 48 "/System/Library/Frameworks/ApplicationServices.framework/" | 80 "/System/Library/Frameworks/ApplicationServices.framework/" |
| 49 "ApplicationServices"; | 81 "ApplicationServices"; |
| 50 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); | 82 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); |
| 51 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); | 83 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); |
| 52 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); | 84 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); |
| 53 const char* kOpenGlLibraryName = | 85 const char* kOpenGlLibraryName = |
| 54 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; | 86 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; |
| 55 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); | 87 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 bool CgBlitPostLion(const DesktopFrame& frame, | 243 bool CgBlitPostLion(const DesktopFrame& frame, |
| 212 const DesktopRegion& region); | 244 const DesktopRegion& region); |
| 213 | 245 |
| 214 // Called when the screen configuration is changed. | 246 // Called when the screen configuration is changed. |
| 215 void ScreenConfigurationChanged(); | 247 void ScreenConfigurationChanged(); |
| 216 | 248 |
| 217 bool RegisterRefreshAndMoveHandlers(); | 249 bool RegisterRefreshAndMoveHandlers(); |
| 218 void UnregisterRefreshAndMoveHandlers(); | 250 void UnregisterRefreshAndMoveHandlers(); |
| 219 | 251 |
| 220 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); | 252 void ScreenRefresh(CGRectCount count, const CGRect *rect_array); |
| 221 void ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 253 void ScreenUpdateMove(CGFloat delta_x, |
| 254 CGFloat delta_y, | |
| 222 size_t count, | 255 size_t count, |
| 223 const CGRect *rect_array); | 256 const CGRect* rect_array); |
| 224 static void ScreenRefreshCallback(CGRectCount count, | 257 void ScreenRefreshCallback(CGRectCount count, const CGRect* rect_array); |
| 225 const CGRect *rect_array, | |
| 226 void *user_parameter); | |
| 227 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, | |
| 228 size_t count, | |
| 229 const CGRect *rect_array, | |
| 230 void *user_parameter); | |
| 231 void ReleaseBuffers(); | 258 void ReleaseBuffers(); |
| 232 | 259 |
| 233 std::unique_ptr<DesktopFrame> CreateFrame(); | 260 std::unique_ptr<DesktopFrame> CreateFrame(); |
| 234 | 261 |
| 235 Callback* callback_ = nullptr; | 262 Callback* callback_ = nullptr; |
| 236 | 263 |
| 237 CGLContextObj cgl_context_ = nullptr; | 264 CGLContextObj cgl_context_ = nullptr; |
| 238 ScopedPixelBufferObject pixel_buffer_object_; | 265 ScopedPixelBufferObject pixel_buffer_object_; |
| 239 | 266 |
| 240 // Queue of the frames buffers. | 267 // Queue of the frames buffers. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 : desktop_config_monitor_(desktop_config_monitor) {} | 331 : desktop_config_monitor_(desktop_config_monitor) {} |
| 305 | 332 |
| 306 ScreenCapturerMac::~ScreenCapturerMac() { | 333 ScreenCapturerMac::~ScreenCapturerMac() { |
| 307 ReleaseBuffers(); | 334 ReleaseBuffers(); |
| 308 UnregisterRefreshAndMoveHandlers(); | 335 UnregisterRefreshAndMoveHandlers(); |
| 309 dlclose(app_services_library_); | 336 dlclose(app_services_library_); |
| 310 dlclose(opengl_library_); | 337 dlclose(opengl_library_); |
| 311 } | 338 } |
| 312 | 339 |
| 313 bool ScreenCapturerMac::Init() { | 340 bool ScreenCapturerMac::Init() { |
| 341 desktop_config_monitor_->Lock(); | |
| 342 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | |
| 343 desktop_config_monitor_->Unlock(); | |
| 314 if (!RegisterRefreshAndMoveHandlers()) { | 344 if (!RegisterRefreshAndMoveHandlers()) { |
| 315 return false; | 345 return false; |
| 316 } | 346 } |
| 317 desktop_config_monitor_->Lock(); | |
| 318 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | |
| 319 desktop_config_monitor_->Unlock(); | |
| 320 ScreenConfigurationChanged(); | 347 ScreenConfigurationChanged(); |
| 321 return true; | 348 return true; |
| 322 } | 349 } |
| 323 | 350 |
| 324 void ScreenCapturerMac::ReleaseBuffers() { | 351 void ScreenCapturerMac::ReleaseBuffers() { |
| 325 if (cgl_context_) { | 352 if (cgl_context_) { |
| 326 pixel_buffer_object_.Release(); | 353 pixel_buffer_object_.Release(); |
| 327 CGLDestroyContext(cgl_context_); | 354 CGLDestroyContext(cgl_context_); |
| 328 cgl_context_ = nullptr; | 355 cgl_context_ = nullptr; |
| 329 } | 356 } |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 (*cgl_set_full_screen_)(cgl_context_); | 868 (*cgl_set_full_screen_)(cgl_context_); |
| 842 CGLSetCurrentContext(cgl_context_); | 869 CGLSetCurrentContext(cgl_context_); |
| 843 | 870 |
| 844 size_t buffer_size = screen_pixel_bounds_.width() * | 871 size_t buffer_size = screen_pixel_bounds_.width() * |
| 845 screen_pixel_bounds_.height() * | 872 screen_pixel_bounds_.height() * |
| 846 sizeof(uint32_t); | 873 sizeof(uint32_t); |
| 847 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 874 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
| 848 } | 875 } |
| 849 | 876 |
| 850 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { | 877 bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() { |
| 851 CGError err = CGRegisterScreenRefreshCallback( | 878 desktop_config_ = desktop_config_monitor_->desktop_configuration(); |
| 852 ScreenCapturerMac::ScreenRefreshCallback, this); | 879 for (const auto& config : desktop_config_.displays) { |
| 853 if (err != kCGErrorSuccess) { | 880 size_t pixel_width = config.pixel_bounds.width(); |
| 854 LOG(LS_ERROR) << "CGRegisterScreenRefreshCallback " << err; | 881 size_t pixel_height = config.pixel_bounds.height(); |
| 855 return false; | 882 if (pixel_width == 0 || pixel_height == 0) |
| 856 } | 883 continue; |
| 884 int unique_id = 0; | |
| 885 { | |
| 886 rtc::CritScope scoper(&g_display_stream_critical_section); | |
| 887 unique_id = ++g_unique_id_generator; | |
| 888 } | |
| 889 CGDirectDisplayID display_id = config.id; | |
| 890 CGDisplayStreamFrameAvailableHandler handler = | |
| 891 ^(CGDisplayStreamFrameStatus status, uint64_t display_time, | |
| 892 IOSurfaceRef frame_surface, CGDisplayStreamUpdateRef updateRef) { | |
|
Sergey Ulanov
2016/10/06 23:51:33
nit: one argument per line in function definition
erikchen
2016/10/07 17:56:20
this is from clang-format.
| |
| 893 if (status == kCGDisplayStreamFrameStatusStopped) { | |
| 894 rtc::CritScope scoper(&g_display_stream_critical_section); | |
| 895 auto it = g_display_stream_wrappers.find(unique_id); | |
| 896 assert(it != g_display_stream_wrappers.end()); | |
|
Sergey Ulanov
2016/10/06 23:51:33
Please use RTC_DCHECK() instead of assert()
erikchen
2016/10/07 17:56:19
I switched to RTC_CHECK. I think these should not
| |
| 897 assert(!it->second.active); | |
| 898 CFRelease(it->second.stream); | |
| 899 g_display_stream_wrappers.erase(it); | |
| 900 return; | |
| 901 } | |
| 857 | 902 |
| 858 err = CGScreenRegisterMoveCallback( | 903 // Only pay attention to frame updates. |
| 859 ScreenCapturerMac::ScreenUpdateMoveCallback, this); | 904 if (status != kCGDisplayStreamFrameStatusFrameComplete) |
| 860 if (err != kCGErrorSuccess) { | 905 return; |
| 861 LOG(LS_ERROR) << "CGScreenRegisterMoveCallback " << err; | 906 |
| 862 return false; | 907 size_t count = 0; |
| 908 const CGRect* rects = CGDisplayStreamUpdateGetRects( | |
| 909 updateRef, kCGDisplayStreamUpdateMovedRects, &count); | |
|
Sergey Ulanov
2016/10/06 23:51:33
I think you can use kCGDisplayStreamUpdateDirtyRec
erikchen
2016/10/07 17:56:19
Yes, but then we can't distinguish between the two
Sergey Ulanov
2016/10/10 21:03:51
We don't need to distinguish between them. In both
| |
| 910 if (count != 0) { | |
| 911 CGFloat dx = 0; | |
| 912 CGFloat dy = 0; | |
| 913 CGDisplayStreamUpdateGetMovedRectsDelta(updateRef, &dx, &dy); | |
| 914 ScreenUpdateMove(dx, dy, count, rects); | |
| 915 } | |
| 916 | |
| 917 count = 0; | |
| 918 rects = CGDisplayStreamUpdateGetRects( | |
| 919 updateRef, kCGDisplayStreamUpdateRefreshedRects, &count); | |
| 920 if (count != 0) { | |
| 921 // According to CGDisplayStream.h, it's safe to call | |
| 922 // CGDisplayStreamStop() from within the callback. | |
| 923 ScreenRefreshCallback(count, rects); | |
| 924 } | |
| 925 }; | |
| 926 CGDisplayStreamRef display_stream = CGDisplayStreamCreate( | |
| 927 display_id, pixel_width, pixel_height, 'BGRA', nullptr, handler); | |
| 928 if (display_stream) { | |
| 929 DisplayStreamWrapper wrapper; | |
| 930 wrapper.stream = display_stream; | |
| 931 wrapper.owner = this; | |
| 932 { | |
| 933 rtc::CritScope scoper(&g_display_stream_critical_section); | |
| 934 assert(g_display_stream_wrappers.find(unique_id) == | |
| 935 g_display_stream_wrappers.end()); | |
| 936 g_display_stream_wrappers[unique_id] = wrapper; | |
| 937 } | |
| 938 CGDisplayStreamStart(display_stream); | |
| 939 } | |
| 863 } | 940 } |
| 864 | 941 |
| 865 return true; | 942 return true; |
| 866 } | 943 } |
| 867 | 944 |
| 868 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { | 945 void ScreenCapturerMac::UnregisterRefreshAndMoveHandlers() { |
| 869 CGUnregisterScreenRefreshCallback( | 946 rtc::CritScope scoper(&g_display_stream_critical_section); |
| 870 ScreenCapturerMac::ScreenRefreshCallback, this); | 947 for (auto& pair : g_display_stream_wrappers) { |
| 871 CGScreenUnregisterMoveCallback( | 948 DisplayStreamWrapper& wrapper = pair.second; |
| 872 ScreenCapturerMac::ScreenUpdateMoveCallback, this); | 949 if (wrapper.active && wrapper.owner == this) { |
| 950 wrapper.active = false; | |
| 951 CGDisplayStreamStop(wrapper.stream); | |
| 952 } | |
| 953 } | |
| 873 } | 954 } |
| 874 | 955 |
| 875 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, | 956 void ScreenCapturerMac::ScreenRefresh(CGRectCount count, |
| 876 const CGRect* rect_array) { | 957 const CGRect* rect_array) { |
| 877 if (screen_pixel_bounds_.is_empty()) | 958 if (screen_pixel_bounds_.is_empty()) |
| 878 return; | 959 return; |
| 879 | 960 |
| 880 DesktopRegion region; | 961 DesktopRegion region; |
| 881 DesktopVector translate_vector = | 962 DesktopVector translate_vector = |
| 882 DesktopVector().subtract(screen_pixel_bounds_.top_left()); | 963 DesktopVector().subtract(screen_pixel_bounds_.top_left()); |
| 883 for (CGRectCount i = 0; i < count; ++i) { | 964 for (CGRectCount i = 0; i < count; ++i) { |
| 884 // Convert from Density-Independent Pixel to physical pixel coordinates. | 965 // Convert from Density-Independent Pixel to physical pixel coordinates. |
| 885 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); | 966 DesktopRect rect = ScaleAndRoundCGRect(rect_array[i], dip_to_pixel_scale_); |
| 886 // Translate from local desktop to capturer framebuffer coordinates. | 967 // Translate from local desktop to capturer framebuffer coordinates. |
| 887 rect.Translate(translate_vector); | 968 rect.Translate(translate_vector); |
| 888 region.AddRect(rect); | 969 region.AddRect(rect); |
| 889 } | 970 } |
| 890 | 971 |
| 891 helper_.InvalidateRegion(region); | 972 helper_.InvalidateRegion(region); |
| 892 } | 973 } |
| 893 | 974 |
| 894 void ScreenCapturerMac::ScreenUpdateMove(CGScreenUpdateMoveDelta delta, | 975 void ScreenCapturerMac::ScreenUpdateMove(CGFloat delta_x, |
| 976 CGFloat delta_y, | |
| 895 size_t count, | 977 size_t count, |
| 896 const CGRect* rect_array) { | 978 const CGRect* rect_array) { |
| 897 // Translate |rect_array| to identify the move's destination. | 979 // Translate |rect_array| to identify the move's destination. |
| 898 CGRect refresh_rects[count]; | 980 CGRect refresh_rects[count]; |
| 899 for (CGRectCount i = 0; i < count; ++i) { | 981 for (CGRectCount i = 0; i < count; ++i) { |
| 900 refresh_rects[i] = CGRectOffset(rect_array[i], delta.dX, delta.dY); | 982 refresh_rects[i] = CGRectOffset(rect_array[i], delta_x, delta_y); |
| 901 } | 983 } |
| 902 | 984 |
| 903 // Currently we just treat move events the same as refreshes. | 985 // Currently we just treat move events the same as refreshes. |
| 904 ScreenRefresh(count, refresh_rects); | 986 ScreenRefresh(count, refresh_rects); |
| 905 } | 987 } |
| 906 | 988 |
| 907 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, | 989 void ScreenCapturerMac::ScreenRefreshCallback(CGRectCount count, |
| 908 const CGRect* rect_array, | 990 const CGRect* rect_array) { |
| 909 void* user_parameter) { | 991 if (screen_pixel_bounds_.is_empty()) |
| 910 ScreenCapturerMac* capturer = | 992 ScreenConfigurationChanged(); |
| 911 reinterpret_cast<ScreenCapturerMac*>(user_parameter); | 993 ScreenRefresh(count, rect_array); |
| 912 if (capturer->screen_pixel_bounds_.is_empty()) | |
| 913 capturer->ScreenConfigurationChanged(); | |
| 914 capturer->ScreenRefresh(count, rect_array); | |
| 915 } | |
| 916 | |
| 917 void ScreenCapturerMac::ScreenUpdateMoveCallback( | |
| 918 CGScreenUpdateMoveDelta delta, | |
| 919 size_t count, | |
| 920 const CGRect* rect_array, | |
| 921 void* user_parameter) { | |
| 922 ScreenCapturerMac* capturer = | |
| 923 reinterpret_cast<ScreenCapturerMac*>(user_parameter); | |
| 924 capturer->ScreenUpdateMove(delta, count, rect_array); | |
| 925 } | 994 } |
| 926 | 995 |
| 927 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { | 996 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() { |
| 928 std::unique_ptr<DesktopFrame> frame( | 997 std::unique_ptr<DesktopFrame> frame( |
| 929 new BasicDesktopFrame(screen_pixel_bounds_.size())); | 998 new BasicDesktopFrame(screen_pixel_bounds_.size())); |
| 930 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, | 999 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, |
| 931 kStandardDPI * dip_to_pixel_scale_)); | 1000 kStandardDPI * dip_to_pixel_scale_)); |
| 932 return frame; | 1001 return frame; |
| 933 } | 1002 } |
| 934 | 1003 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 946 } | 1015 } |
| 947 | 1016 |
| 948 if (options.detect_updated_region()) { | 1017 if (options.detect_updated_region()) { |
| 949 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); | 1018 capturer.reset(new ScreenCapturerDifferWrapper(std::move(capturer))); |
| 950 } | 1019 } |
| 951 | 1020 |
| 952 return capturer.release(); | 1021 return capturer.release(); |
| 953 } | 1022 } |
| 954 | 1023 |
| 955 } // namespace webrtc | 1024 } // namespace webrtc |
| OLD | NEW |