From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../libwebrtc/modules/desktop_capture/BUILD.gn | 658 ++++++++++++ third_party/libwebrtc/modules/desktop_capture/DEPS | 19 + .../libwebrtc/modules/desktop_capture/OWNERS | 2 + .../blank_detector_desktop_capturer_wrapper.cc | 139 +++ .../blank_detector_desktop_capturer_wrapper.h | 83 ++ ...k_detector_desktop_capturer_wrapper_unittest.cc | 165 +++ .../desktop_capture/cropped_desktop_frame.cc | 66 ++ .../desktop_capture/cropped_desktop_frame.h | 33 + .../cropped_desktop_frame_unittest.cc | 115 +++ .../desktop_capture/cropping_window_capturer.cc | 135 +++ .../desktop_capture/cropping_window_capturer.h | 84 ++ .../cropping_window_capturer_win.cc | 335 +++++++ .../delegated_source_list_controller.h | 70 ++ .../desktop_capture/desktop_and_cursor_composer.cc | 286 ++++++ .../desktop_capture/desktop_and_cursor_composer.h | 100 ++ .../desktop_and_cursor_composer_unittest.cc | 479 +++++++++ .../desktop_capture_differ_sse2_gn/moz.build | 156 +++ .../desktop_capture/desktop_capture_gn/moz.build | 679 +++++++++++++ .../desktop_capture/desktop_capture_metadata.h | 31 + .../desktop_capture_metrics_helper.cc | 57 ++ .../desktop_capture_metrics_helper.h | 22 + .../desktop_capture_objc_gn/moz.build | 77 ++ .../desktop_capture/desktop_capture_options.cc | 61 ++ .../desktop_capture/desktop_capture_options.h | 271 +++++ .../desktop_capture/desktop_capture_types.h | 75 ++ .../modules/desktop_capture/desktop_capturer.cc | 142 +++ .../modules/desktop_capture/desktop_capturer.h | 224 +++++ .../desktop_capturer_differ_wrapper.cc | 232 +++++ .../desktop_capturer_differ_wrapper.h | 72 ++ .../desktop_capturer_differ_wrapper_unittest.cc | 291 ++++++ .../desktop_capture/desktop_capturer_wrapper.cc | 60 ++ .../desktop_capture/desktop_capturer_wrapper.h | 48 + .../modules/desktop_capture/desktop_frame.cc | 224 +++++ .../modules/desktop_capture/desktop_frame.h | 234 +++++ .../desktop_capture/desktop_frame_generator.cc | 184 ++++ .../desktop_capture/desktop_frame_generator.h | 121 +++ .../desktop_capture/desktop_frame_rotation.cc | 117 +++ .../desktop_capture/desktop_frame_rotation.h | 52 + .../desktop_frame_rotation_unittest.cc | 449 +++++++++ .../desktop_capture/desktop_frame_unittest.cc | 369 +++++++ .../modules/desktop_capture/desktop_frame_win.cc | 73 ++ .../modules/desktop_capture/desktop_frame_win.h | 49 + .../modules/desktop_capture/desktop_geometry.cc | 79 ++ .../modules/desktop_capture/desktop_geometry.h | 169 ++++ .../desktop_capture/desktop_geometry_unittest.cc | 106 ++ .../modules/desktop_capture/desktop_region.cc | 567 +++++++++++ .../modules/desktop_capture/desktop_region.h | 169 ++++ .../desktop_capture/desktop_region_unittest.cc | 834 ++++++++++++++++ .../modules/desktop_capture/differ_block.cc | 76 ++ .../modules/desktop_capture/differ_block.h | 42 + .../desktop_capture/differ_block_unittest.cc | 89 ++ .../modules/desktop_capture/differ_vector_sse2.cc | 102 ++ .../modules/desktop_capture/differ_vector_sse2.h | 31 + .../desktop_capture/fake_desktop_capturer.cc | 84 ++ .../desktop_capture/fake_desktop_capturer.h | 76 ++ .../fallback_desktop_capturer_wrapper.cc | 183 ++++ .../fallback_desktop_capturer_wrapper.h | 64 ++ .../fallback_desktop_capturer_wrapper_unittest.cc | 207 ++++ .../full_screen_application_handler.cc | 31 + .../full_screen_application_handler.h | 50 + .../desktop_capture/full_screen_window_detector.cc | 85 ++ .../desktop_capture/full_screen_window_detector.h | 83 ++ .../linux/wayland/base_capturer_pipewire.cc | 244 +++++ .../linux/wayland/base_capturer_pipewire.h | 98 ++ .../desktop_capture/linux/wayland/egl_dmabuf.cc | 781 +++++++++++++++ .../desktop_capture/linux/wayland/egl_dmabuf.h | 74 ++ .../linux/wayland/mouse_cursor_monitor_pipewire.cc | 59 ++ .../linux/wayland/mouse_cursor_monitor_pipewire.h | 44 + .../linux/wayland/portal_request_response.h | 17 + .../linux/wayland/restore_token_manager.cc | 35 + .../linux/wayland/restore_token_manager.h | 46 + .../desktop_capture/linux/wayland/scoped_glib.h | 17 + .../wayland/screen_capture_portal_interface.cc | 127 +++ .../wayland/screen_capture_portal_interface.h | 76 ++ .../linux/wayland/screencast_portal.cc | 471 +++++++++ .../linux/wayland/screencast_portal.h | 219 ++++ .../linux/wayland/screencast_stream_utils.cc | 133 +++ .../linux/wayland/screencast_stream_utils.h | 53 + .../linux/wayland/shared_screencast_stream.cc | 1047 ++++++++++++++++++++ .../linux/wayland/shared_screencast_stream.h | 99 ++ .../wayland/shared_screencast_stream_unittest.cc | 181 ++++ .../test/test_screencast_stream_provider.cc | 363 +++++++ .../wayland/test/test_screencast_stream_provider.h | 93 ++ .../linux/wayland/xdg_desktop_portal_utils.h | 17 + .../linux/wayland/xdg_session_details.h | 17 + .../linux/x11/mouse_cursor_monitor_x11.cc | 258 +++++ .../linux/x11/mouse_cursor_monitor_x11.h | 68 ++ .../linux/x11/screen_capturer_x11.cc | 517 ++++++++++ .../linux/x11/screen_capturer_x11.h | 147 +++ .../desktop_capture/linux/x11/shared_x_display.cc | 112 +++ .../desktop_capture/linux/x11/shared_x_display.h | 88 ++ .../linux/x11/window_capturer_x11.cc | 257 +++++ .../linux/x11/window_capturer_x11.h | 78 ++ .../desktop_capture/linux/x11/window_finder_x11.cc | 52 + .../desktop_capture/linux/x11/window_finder_x11.h | 35 + .../desktop_capture/linux/x11/window_list_utils.cc | 198 ++++ .../desktop_capture/linux/x11/window_list_utils.h | 56 ++ .../desktop_capture/linux/x11/x_atom_cache.cc | 51 + .../desktop_capture/linux/x11/x_atom_cache.h | 45 + .../desktop_capture/linux/x11/x_error_trap.cc | 70 ++ .../desktop_capture/linux/x11/x_error_trap.h | 51 + .../linux/x11/x_server_pixel_buffer.cc | 370 +++++++ .../linux/x11/x_server_pixel_buffer.h | 89 ++ .../desktop_capture/linux/x11/x_window_property.cc | 43 + .../desktop_capture/linux/x11/x_window_property.h | 63 ++ .../desktop_capture/mac/desktop_configuration.h | 96 ++ .../desktop_capture/mac/desktop_configuration.mm | 189 ++++ .../mac/desktop_configuration_monitor.cc | 73 ++ .../mac/desktop_configuration_monitor.h | 55 + .../desktop_capture/mac/desktop_frame_cgimage.h | 58 ++ .../desktop_capture/mac/desktop_frame_cgimage.mm | 108 ++ .../desktop_capture/mac/desktop_frame_iosurface.h | 45 + .../desktop_capture/mac/desktop_frame_iosurface.mm | 61 ++ .../desktop_capture/mac/desktop_frame_provider.h | 59 ++ .../desktop_capture/mac/desktop_frame_provider.mm | 70 ++ .../desktop_capture/mac/desktop_frame_utils.cc | 22 + .../desktop_capture/mac/desktop_frame_utils.h | 27 + .../mac/full_screen_mac_application_handler.cc | 238 +++++ .../mac/full_screen_mac_application_handler.h | 25 + .../desktop_capture/mac/screen_capturer_mac.h | 127 +++ .../desktop_capture/mac/screen_capturer_mac.mm | 552 +++++++++++ .../desktop_capture/mac/window_list_utils.cc | 430 ++++++++ .../desktop_capture/mac/window_list_utils.h | 120 +++ .../mock_desktop_capturer_callback.cc | 23 + .../mock_desktop_capturer_callback.h | 39 + .../modules/desktop_capture/mouse_cursor.cc | 36 + .../modules/desktop_capture/mouse_cursor.h | 49 + .../modules/desktop_capture/mouse_cursor_monitor.h | 111 +++ .../desktop_capture/mouse_cursor_monitor_linux.cc | 65 ++ .../desktop_capture/mouse_cursor_monitor_mac.mm | 213 ++++ .../desktop_capture/mouse_cursor_monitor_null.cc | 38 + .../desktop_capture/mouse_cursor_monitor_win.cc | 215 ++++ .../desktop_capture/primitives_gn/moz.build | 217 ++++ .../modules/desktop_capture/resolution_tracker.cc | 34 + .../modules/desktop_capture/resolution_tracker.h | 34 + .../modules/desktop_capture/rgba_color.cc | 61 ++ .../libwebrtc/modules/desktop_capture/rgba_color.h | 59 ++ .../modules/desktop_capture/rgba_color_unittest.cc | 45 + .../desktop_capture/screen_capture_frame_queue.h | 75 ++ .../desktop_capture/screen_capturer_darwin.mm | 33 + .../desktop_capture/screen_capturer_fuchsia.cc | 391 ++++++++ .../desktop_capture/screen_capturer_fuchsia.h | 63 ++ .../desktop_capture/screen_capturer_helper.cc | 89 ++ .../desktop_capture/screen_capturer_helper.h | 91 ++ .../screen_capturer_helper_unittest.cc | 193 ++++ .../screen_capturer_integration_test.cc | 345 +++++++ .../desktop_capture/screen_capturer_linux.cc | 44 + .../screen_capturer_mac_unittest.cc | 101 ++ .../desktop_capture/screen_capturer_null.cc | 21 + .../desktop_capture/screen_capturer_unittest.cc | 220 ++++ .../modules/desktop_capture/screen_capturer_win.cc | 59 ++ .../modules/desktop_capture/screen_drawer.cc | 30 + .../modules/desktop_capture/screen_drawer.h | 79 ++ .../modules/desktop_capture/screen_drawer_linux.cc | 185 ++++ .../desktop_capture/screen_drawer_lock_posix.cc | 59 ++ .../desktop_capture/screen_drawer_lock_posix.h | 39 + .../modules/desktop_capture/screen_drawer_mac.cc | 30 + .../desktop_capture/screen_drawer_unittest.cc | 160 +++ .../modules/desktop_capture/screen_drawer_win.cc | 209 ++++ .../desktop_capture/shared_desktop_frame.cc | 59 ++ .../modules/desktop_capture/shared_desktop_frame.h | 65 ++ .../modules/desktop_capture/shared_memory.cc | 24 + .../modules/desktop_capture/shared_memory.h | 82 ++ .../modules/desktop_capture/test_utils.cc | 50 + .../libwebrtc/modules/desktop_capture/test_utils.h | 27 + .../modules/desktop_capture/test_utils_unittest.cc | 110 ++ .../modules/desktop_capture/win/cursor.cc | 233 +++++ .../libwebrtc/modules/desktop_capture/win/cursor.h | 25 + .../win/cursor_test_data/1_24bpp.cur | Bin 0 -> 3262 bytes .../win/cursor_test_data/1_32bpp.cur | Bin 0 -> 4286 bytes .../win/cursor_test_data/1_8bpp.cur | Bin 0 -> 2238 bytes .../win/cursor_test_data/2_1bpp.cur | Bin 0 -> 326 bytes .../win/cursor_test_data/2_32bpp.cur | Bin 0 -> 4286 bytes .../win/cursor_test_data/3_32bpp.cur | Bin 0 -> 4286 bytes .../win/cursor_test_data/3_4bpp.cur | Bin 0 -> 766 bytes .../modules/desktop_capture/win/cursor_unittest.cc | 91 ++ .../win/cursor_unittest_resources.h | 24 + .../win/cursor_unittest_resources.rc | 28 + .../modules/desktop_capture/win/d3d_device.cc | 100 ++ .../modules/desktop_capture/win/d3d_device.h | 59 ++ .../modules/desktop_capture/win/desktop.cc | 111 +++ .../modules/desktop_capture/win/desktop.h | 65 ++ .../desktop_capture/win/desktop_capture_utils.cc | 32 + .../desktop_capture/win/desktop_capture_utils.h | 29 + .../win/display_configuration_monitor.cc | 66 ++ .../win/display_configuration_monitor.h | 53 + .../desktop_capture/win/dxgi_adapter_duplicator.cc | 185 ++++ .../desktop_capture/win/dxgi_adapter_duplicator.h | 92 ++ .../modules/desktop_capture/win/dxgi_context.cc | 33 + .../modules/desktop_capture/win/dxgi_context.h | 62 ++ .../win/dxgi_duplicator_controller.cc | 515 ++++++++++ .../win/dxgi_duplicator_controller.h | 257 +++++ .../modules/desktop_capture/win/dxgi_frame.cc | 77 ++ .../modules/desktop_capture/win/dxgi_frame.h | 63 ++ .../desktop_capture/win/dxgi_output_duplicator.cc | 423 ++++++++ .../desktop_capture/win/dxgi_output_duplicator.h | 154 +++ .../modules/desktop_capture/win/dxgi_texture.cc | 81 ++ .../modules/desktop_capture/win/dxgi_texture.h | 73 ++ .../desktop_capture/win/dxgi_texture_mapping.cc | 58 ++ .../desktop_capture/win/dxgi_texture_mapping.h | 47 + .../desktop_capture/win/dxgi_texture_staging.cc | 132 +++ .../desktop_capture/win/dxgi_texture_staging.h | 68 ++ .../win/full_screen_win_application_handler.cc | 294 ++++++ .../win/full_screen_win_application_handler.h | 25 + .../desktop_capture/win/scoped_gdi_object.h | 91 ++ .../desktop_capture/win/scoped_thread_desktop.cc | 54 + .../desktop_capture/win/scoped_thread_desktop.h | 55 + .../desktop_capture/win/screen_capture_utils.cc | 206 ++++ .../desktop_capture/win/screen_capture_utils.h | 79 ++ .../win/screen_capture_utils_unittest.cc | 81 ++ .../win/screen_capturer_win_directx.cc | 246 +++++ .../win/screen_capturer_win_directx.h | 108 ++ .../win/screen_capturer_win_directx_unittest.cc | 41 + .../desktop_capture/win/screen_capturer_win_gdi.cc | 240 +++++ .../desktop_capture/win/screen_capturer_win_gdi.h | 83 ++ .../win/screen_capturer_win_magnifier.cc | 390 ++++++++ .../win/screen_capturer_win_magnifier.h | 140 +++ .../desktop_capture/win/selected_window_context.cc | 59 ++ .../desktop_capture/win/selected_window_context.h | 45 + .../win/test_support/test_window.cc | 104 ++ .../desktop_capture/win/test_support/test_window.h | 51 + .../desktop_capture/win/wgc_capture_session.cc | 591 +++++++++++ .../desktop_capture/win/wgc_capture_session.h | 154 +++ .../desktop_capture/win/wgc_capture_source.cc | 227 +++++ .../desktop_capture/win/wgc_capture_source.h | 146 +++ .../win/wgc_capture_source_unittest.cc | 148 +++ .../desktop_capture/win/wgc_capturer_win.cc | 365 +++++++ .../modules/desktop_capture/win/wgc_capturer_win.h | 169 ++++ .../win/wgc_capturer_win_unittest.cc | 572 +++++++++++ .../desktop_capture/win/wgc_desktop_frame.cc | 25 + .../desktop_capture/win/wgc_desktop_frame.h | 46 + .../desktop_capture/win/window_capture_utils.cc | 486 +++++++++ .../desktop_capture/win/window_capture_utils.h | 136 +++ .../win/window_capture_utils_unittest.cc | 153 +++ .../desktop_capture/win/window_capturer_win_gdi.cc | 403 ++++++++ .../desktop_capture/win/window_capturer_win_gdi.h | 78 ++ .../desktop_capture/window_capturer_linux.cc | 44 + .../modules/desktop_capture/window_capturer_mac.mm | 220 ++++ .../desktop_capture/window_capturer_null.cc | 70 ++ .../desktop_capture/window_capturer_unittest.cc | 105 ++ .../modules/desktop_capture/window_capturer_win.cc | 48 + .../modules/desktop_capture/window_finder.cc | 20 + .../modules/desktop_capture/window_finder.h | 65 ++ .../modules/desktop_capture/window_finder_mac.h | 37 + .../modules/desktop_capture/window_finder_mac.mm | 52 + .../desktop_capture/window_finder_unittest.cc | 178 ++++ .../modules/desktop_capture/window_finder_win.cc | 46 + .../modules/desktop_capture/window_finder_win.h | 30 + 248 files changed, 33994 insertions(+) create mode 100644 third_party/libwebrtc/modules/desktop_capture/BUILD.gn create mode 100644 third_party/libwebrtc/modules/desktop_capture/DEPS create mode 100644 third_party/libwebrtc/modules/desktop_capture/OWNERS create mode 100644 third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/delegated_source_list_controller.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_differ_sse2_gn/moz.build create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_gn/moz.build create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_metadata.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_objc_gn/moz.build create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capture_types.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer_wrapper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_capturer_wrapper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_generator.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_generator.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_rotation.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_rotation.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_rotation_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_frame_win.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_geometry.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_geometry.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_geometry_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_region.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_region.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/desktop_region_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/differ_block.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/differ_block.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/differ_block_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/differ_vector_sse2.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/differ_vector_sse2.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/fake_desktop_capturer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/fake_desktop_capturer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/portal_request_response.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/scoped_glib.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/xdg_desktop_portal_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/wayland/xdg_session_details.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration_monitor.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_cgimage.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_cgimage.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_iosurface.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_iosurface.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_provider.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_provider.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mock_desktop_capturer_callback.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mock_desktop_capturer_callback.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_null.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/primitives_gn/moz.build create mode 100644 third_party/libwebrtc/modules/desktop_capture/resolution_tracker.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/resolution_tracker.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/rgba_color.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/rgba_color.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/rgba_color_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capture_frame_queue.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_darwin.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_fuchsia.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_fuchsia.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_integration_test.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_null.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_linux.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_lock_posix.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_lock_posix.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_mac.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/screen_drawer_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/shared_desktop_frame.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/shared_desktop_frame.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/shared_memory.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/shared_memory.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/test_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/test_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/test_utils_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/1_24bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/1_32bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/1_8bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/2_1bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/2_32bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/3_32bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_test_data/3_4bpp.cur create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_unittest_resources.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/cursor_unittest_resources.rc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/d3d_device.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/d3d_device.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/desktop.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/desktop.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/desktop_capture_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/desktop_capture_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/display_configuration_monitor.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/display_configuration_monitor.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_context.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_context.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_duplicator_controller.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_frame.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_frame.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_mapping.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_staging.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_staging.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/scoped_gdi_object.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/scoped_thread_desktop.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/scoped_thread_desktop.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/selected_window_context.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/selected_window_context.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/test_support/test_window.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/test_support/test_window.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_source.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_source.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_source_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_desktop_frame.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/wgc_desktop_frame.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/window_capture_utils.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/window_capture_utils.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/window_capture_utils_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/window_capturer_win_gdi.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/win/window_capturer_win_gdi.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_capturer_mac.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_capturer_null.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_capturer_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_capturer_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder_mac.h create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder_mac.mm create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder_unittest.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder_win.cc create mode 100644 third_party/libwebrtc/modules/desktop_capture/window_finder_win.h (limited to 'third_party/libwebrtc/modules/desktop_capture') diff --git a/third_party/libwebrtc/modules/desktop_capture/BUILD.gn b/third_party/libwebrtc/modules/desktop_capture/BUILD.gn new file mode 100644 index 0000000000..0634e0e9c4 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/BUILD.gn @@ -0,0 +1,658 @@ +# Copyright (c) 2014 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. + +import("//build/config/linux/gtk/gtk.gni") +import("//build/config/ui.gni") +import("../../webrtc.gni") + +use_desktop_capture_differ_sse2 = target_cpu == "x86" || target_cpu == "x64" + +config("x11_config") { + if (rtc_use_x11_extensions) { + defines = [ "WEBRTC_USE_X11" ] + } +} + +rtc_library("primitives") { + visibility = [ "*" ] + sources = [ + "desktop_capture_types.h", + "desktop_frame.cc", + "desktop_frame.h", + "desktop_geometry.cc", + "desktop_geometry.h", + "desktop_region.cc", + "desktop_region.h", + "shared_desktop_frame.cc", + "shared_desktop_frame.h", + "shared_memory.cc", + "shared_memory.h", + ] + + deps = [ + "../../api:scoped_refptr", + "../../rtc_base:checks", + "../../rtc_base:refcount", + "../../rtc_base/system:rtc_export", + "//third_party/libyuv", + ] +} + +if (rtc_include_tests) { + rtc_library("desktop_capture_modules_tests") { + testonly = true + + defines = [] + sources = [] + deps = [ + ":desktop_capture", + "../../api:function_view", + "../../api:scoped_refptr", + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../rtc_base:platform_thread", + "../../rtc_base:random", + "../../rtc_base:timeutils", + ] + if (rtc_desktop_capture_supported) { + deps += [ + ":desktop_capture_mock", + ":primitives", + ":screen_drawer", + "../../rtc_base/third_party/base64", + "../../system_wrappers", + "../../test:test_support", + "../../test:video_test_support", + ] + sources += [ + "screen_capturer_integration_test.cc", + "screen_drawer_unittest.cc", + "window_finder_unittest.cc", + ] + + if ((is_linux || is_chromeos) && rtc_use_pipewire) { + configs += [ "../portal:gio" ] + } + + public_configs = [ ":x11_config" ] + + if (is_win) { + deps += [ "../../rtc_base/win:windows_version" ] + } + } + } + + if ((is_linux || is_chromeos) && rtc_use_pipewire) { + rtc_test("shared_screencast_stream_test") { + testonly = true + + sources = [ + "linux/wayland/shared_screencast_stream_unittest.cc", + "linux/wayland/test/test_screencast_stream_provider.cc", + "linux/wayland/test/test_screencast_stream_provider.h", + ] + + configs += [ "../portal:pipewire_all" ] + + deps = [ + ":desktop_capture", + ":desktop_capture_mock", + ":primitives", + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../rtc_base:random", + "../../rtc_base:timeutils", + "../portal", + + # TODO(bugs.webrtc.org/9987): Remove this dep on rtc_base:rtc_base once + # rtc_base:threading is fully defined. + "../../rtc_base:task_queue_for_test", + "../../rtc_base:threading", + "../../system_wrappers", + "../../test:test_main", + "../../test:test_support", + "//api/units:time_delta", + "//rtc_base:rtc_event", + ] + + data = [ "../../third_party/pipewire" ] + public_configs = [ "../portal:pipewire_config" ] + } + } + + rtc_library("desktop_capture_unittests") { + testonly = true + + defines = [] + sources = [ + "blank_detector_desktop_capturer_wrapper_unittest.cc", + "cropped_desktop_frame_unittest.cc", + "desktop_and_cursor_composer_unittest.cc", + "desktop_capturer_differ_wrapper_unittest.cc", + "desktop_frame_rotation_unittest.cc", + "desktop_frame_unittest.cc", + "desktop_geometry_unittest.cc", + "desktop_region_unittest.cc", + "differ_block_unittest.cc", + "fallback_desktop_capturer_wrapper_unittest.cc", + "rgba_color_unittest.cc", + "test_utils.cc", + "test_utils.h", + "test_utils_unittest.cc", + ] + + if ((is_linux || is_chromeos) && rtc_use_pipewire) { + configs += [ "../portal:gio" ] + } + + deps = [ + ":desktop_capture", + ":desktop_capture_mock", + ":primitives", + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../rtc_base:macromagic", + "../../rtc_base:random", + "../../rtc_base:timeutils", + + # TODO(bugs.webrtc.org/9987): Remove this dep on rtc_base:rtc_base once + # rtc_base:threading is fully defined. + "../../rtc_base:task_queue_for_test", + "../../rtc_base:threading", + "../../system_wrappers", + "../../test:test_support", + ] + + if (is_win) { + sources += [ + "win/cursor_unittest.cc", + "win/cursor_unittest_resources.h", + "win/cursor_unittest_resources.rc", + "win/screen_capture_utils_unittest.cc", + "win/screen_capturer_win_directx_unittest.cc", + "win/test_support/test_window.cc", + "win/test_support/test_window.h", + "win/window_capture_utils_unittest.cc", + ] + deps += [ + "../../rtc_base/win:scoped_com_initializer", + "../../rtc_base/win:windows_version", + ] + } + + if (rtc_desktop_capture_supported) { + sources += [ + "screen_capturer_helper_unittest.cc", + "screen_capturer_unittest.cc", + "window_capturer_unittest.cc", + ] + if (is_mac) { + sources += [ "screen_capturer_mac_unittest.cc" ] + } + if (rtc_enable_win_wgc) { + sources += [ + "win/wgc_capture_source_unittest.cc", + "win/wgc_capturer_win_unittest.cc", + ] + } + deps += [ + ":desktop_capture_mock", + "../../system_wrappers:metrics", + ] + public_configs = [ ":x11_config" ] + } + } + + rtc_library("screen_drawer") { + testonly = true + + sources = [ + "screen_drawer.cc", + "screen_drawer.h", + ] + + if (is_linux || is_chromeos) { + sources += [ "screen_drawer_linux.cc" ] + libs = [ "X11" ] + } + + if (is_mac) { + sources += [ "screen_drawer_mac.cc" ] + } + + if (is_win) { + sources += [ "screen_drawer_win.cc" ] + } + + deps = [ + ":desktop_capture", + ":primitives", + "../../api:scoped_refptr", + "../../rtc_base:checks", + "../../rtc_base:logging", + "../../system_wrappers", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] + + if (is_posix || is_fuchsia) { + sources += [ + "screen_drawer_lock_posix.cc", + "screen_drawer_lock_posix.h", + ] + } + } + + rtc_library("desktop_capture_mock") { + testonly = true + + sources = [ + "mock_desktop_capturer_callback.cc", + "mock_desktop_capturer_callback.h", + ] + + if ((is_linux || is_chromeos) && rtc_use_pipewire) { + configs += [ "../portal:gio" ] + } + + deps = [ + ":desktop_capture", + ":primitives", + "../../test:test_support", + ] + } +} + +# TODO(bugs.webrtc.org/14187): remove when all users are gone +if ((is_linux || is_chromeos) && rtc_use_pipewire) { + config("pipewire_config") { + configs = [ "../portal:pipewire_config" ] + } +} + +rtc_library("desktop_capture") { + visibility = [ "*" ] + defines = [] + deps = [] + public_configs = [ ":x11_config" ] + sources = [ + "blank_detector_desktop_capturer_wrapper.cc", + "blank_detector_desktop_capturer_wrapper.h", + "cropped_desktop_frame.cc", + "cropped_desktop_frame.h", + "cropping_window_capturer.cc", + "cropping_window_capturer.h", + "delegated_source_list_controller.h", + "desktop_and_cursor_composer.cc", + "desktop_and_cursor_composer.h", + "desktop_capture_metrics_helper.cc", + "desktop_capture_metrics_helper.h", + "desktop_capture_options.cc", + "desktop_capture_options.h", + "desktop_capturer.cc", + "desktop_capturer.h", + "desktop_capturer_differ_wrapper.cc", + "desktop_capturer_differ_wrapper.h", + "desktop_capturer_wrapper.cc", + "desktop_capturer_wrapper.h", + "desktop_frame_generator.cc", + "desktop_frame_generator.h", + "desktop_frame_rotation.cc", + "desktop_frame_rotation.h", + "differ_block.cc", + "differ_block.h", + "fake_desktop_capturer.cc", + "fake_desktop_capturer.h", + "fallback_desktop_capturer_wrapper.cc", + "fallback_desktop_capturer_wrapper.h", + "full_screen_application_handler.cc", + "full_screen_application_handler.h", + "full_screen_window_detector.cc", + "full_screen_window_detector.h", + "mouse_cursor.cc", + "mouse_cursor.h", + "mouse_cursor_monitor.h", + "resolution_tracker.cc", + "resolution_tracker.h", + "rgba_color.cc", + "rgba_color.h", + "screen_capture_frame_queue.h", + "screen_capturer_helper.cc", + "screen_capturer_helper.h", + "window_finder.cc", + "window_finder.h", + ] + if (is_linux && !is_castos && rtc_use_pipewire) { + sources += [ "desktop_capture_metadata.h" ] + } + if (is_mac) { + sources += [ + "mac/desktop_configuration.h", + "mac/desktop_configuration_monitor.cc", + "mac/desktop_configuration_monitor.h", + "mac/desktop_frame_utils.cc", + "mac/desktop_frame_utils.h", + "mac/full_screen_mac_application_handler.cc", + "mac/full_screen_mac_application_handler.h", + "mac/window_list_utils.cc", + "mac/window_list_utils.h", + ] + deps += [ ":desktop_capture_objc" ] + } + if (rtc_use_x11_extensions || rtc_use_pipewire) { + sources += [ + "mouse_cursor_monitor_linux.cc", + "screen_capturer_linux.cc", + "window_capturer_linux.cc", + ] + } + + if (rtc_use_x11_extensions) { + sources += [ + "linux/x11/mouse_cursor_monitor_x11.cc", + "linux/x11/mouse_cursor_monitor_x11.h", + "linux/x11/screen_capturer_x11.cc", + "linux/x11/screen_capturer_x11.h", + "linux/x11/shared_x_display.cc", + "linux/x11/shared_x_display.h", + "linux/x11/window_capturer_x11.cc", + "linux/x11/window_capturer_x11.h", + "linux/x11/window_finder_x11.cc", + "linux/x11/window_finder_x11.h", + "linux/x11/window_list_utils.cc", + "linux/x11/window_list_utils.h", + "linux/x11/x_atom_cache.cc", + "linux/x11/x_atom_cache.h", + "linux/x11/x_error_trap.cc", + "linux/x11/x_error_trap.h", + "linux/x11/x_server_pixel_buffer.cc", + "linux/x11/x_server_pixel_buffer.h", + "linux/x11/x_window_property.cc", + "linux/x11/x_window_property.h", + ] + libs = [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrender", + "Xrandr", + "Xtst", + ] + if (build_with_mozilla) { + libs -= [ "Xtst" ] + } + } + + if (!is_win && !is_mac && !rtc_use_x11_extensions && !rtc_use_pipewire && + !is_fuchsia) { + sources += [ + "mouse_cursor_monitor_null.cc", + "screen_capturer_null.cc", + "window_capturer_null.cc", + ] + } + + deps += [ + ":primitives", + "../../api:function_view", + "../../api:make_ref_counted", + "../../api:refcountedbase", + "../../api:scoped_refptr", + "../../api:sequence_checker", + "../../rtc_base:checks", + "../../rtc_base:event_tracer", + "../../rtc_base:logging", + "../../rtc_base:macromagic", + "../../rtc_base:random", + "../../rtc_base:stringutils", + "../../rtc_base:timeutils", + "../../rtc_base/synchronization:mutex", + "../../rtc_base/system:arch", + "../../rtc_base/system:no_unique_address", + "../../rtc_base/system:rtc_export", + "../../system_wrappers", + "../../system_wrappers:metrics", + ] + + if (is_fuchsia) { + sources += [ + "mouse_cursor_monitor_null.cc", + "screen_capturer_fuchsia.cc", + "screen_capturer_fuchsia.h", + "window_capturer_null.cc", + ] + deps += [ + "../../rtc_base:divide_round", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.composition", + "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.scenic", + "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp", + "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", + ] + } + + if (is_win) { + sources += [ + "cropping_window_capturer_win.cc", + "desktop_frame_win.cc", + "desktop_frame_win.h", + "mouse_cursor_monitor_win.cc", + "screen_capturer_win.cc", + "win/cursor.cc", + "win/cursor.h", + "win/d3d_device.cc", + "win/d3d_device.h", + "win/desktop.cc", + "win/desktop.h", + "win/desktop_capture_utils.cc", + "win/desktop_capture_utils.h", + "win/display_configuration_monitor.cc", + "win/display_configuration_monitor.h", + "win/dxgi_adapter_duplicator.cc", + "win/dxgi_adapter_duplicator.h", + "win/dxgi_context.cc", + "win/dxgi_context.h", + "win/dxgi_duplicator_controller.cc", + "win/dxgi_duplicator_controller.h", + "win/dxgi_frame.cc", + "win/dxgi_frame.h", + "win/dxgi_output_duplicator.cc", + "win/dxgi_output_duplicator.h", + "win/dxgi_texture.cc", + "win/dxgi_texture.h", + "win/dxgi_texture_mapping.cc", + "win/dxgi_texture_mapping.h", + "win/dxgi_texture_staging.cc", + "win/dxgi_texture_staging.h", + "win/full_screen_win_application_handler.cc", + "win/full_screen_win_application_handler.h", + "win/scoped_gdi_object.h", + "win/scoped_thread_desktop.cc", + "win/scoped_thread_desktop.h", + "win/screen_capture_utils.cc", + "win/screen_capture_utils.h", + "win/screen_capturer_win_directx.cc", + "win/screen_capturer_win_directx.h", + "win/screen_capturer_win_gdi.cc", + "win/screen_capturer_win_gdi.h", + "win/screen_capturer_win_magnifier.cc", + "win/screen_capturer_win_magnifier.h", + "win/selected_window_context.cc", + "win/selected_window_context.h", + "win/window_capture_utils.cc", + "win/window_capture_utils.h", + "win/window_capturer_win_gdi.cc", + "win/window_capturer_win_gdi.h", + "window_capturer_win.cc", + "window_finder_win.cc", + "window_finder_win.h", + ] + libs = [ + "d3d11.lib", + "dxgi.lib", + "shcore.lib", + ] + deps += [ + "../../rtc_base:win32", + "../../rtc_base/containers:flat_map", + "../../rtc_base/win:create_direct3d_device", + "../../rtc_base/win:get_activation_factory", + "../../rtc_base/win:windows_version", + ] + } + + absl_deps = [ + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/types:optional", + ] + + if (rtc_use_x11_extensions) { + deps += [ "../../rtc_base:sanitizer" ] + } + + deps += [ "//third_party/libyuv" ] + + if (use_desktop_capture_differ_sse2) { + deps += [ ":desktop_capture_differ_sse2" ] + } + + if (rtc_use_pipewire) { + sources += [ + "linux/wayland/base_capturer_pipewire.cc", + "linux/wayland/base_capturer_pipewire.h", + "linux/wayland/egl_dmabuf.cc", + "linux/wayland/egl_dmabuf.h", + "linux/wayland/mouse_cursor_monitor_pipewire.cc", + "linux/wayland/mouse_cursor_monitor_pipewire.h", + "linux/wayland/portal_request_response.h", + "linux/wayland/restore_token_manager.cc", + "linux/wayland/restore_token_manager.h", + "linux/wayland/scoped_glib.h", + "linux/wayland/screen_capture_portal_interface.cc", + "linux/wayland/screen_capture_portal_interface.h", + "linux/wayland/screencast_portal.cc", + "linux/wayland/screencast_portal.h", + "linux/wayland/screencast_stream_utils.cc", + "linux/wayland/screencast_stream_utils.h", + "linux/wayland/shared_screencast_stream.cc", + "linux/wayland/shared_screencast_stream.h", + "linux/wayland/xdg_desktop_portal_utils.h", + "linux/wayland/xdg_session_details.h", + ] + + configs += [ "../portal:pipewire_all" ] + + public_configs += [ "../portal:pipewire_config" ] + + deps += [ + "../../rtc_base:sanitizer", + "../portal", + ] + } + + if (rtc_enable_win_wgc) { + sources += [ + "win/wgc_capture_session.cc", + "win/wgc_capture_session.h", + "win/wgc_capture_source.cc", + "win/wgc_capture_source.h", + "win/wgc_capturer_win.cc", + "win/wgc_capturer_win.h", + "win/wgc_desktop_frame.cc", + "win/wgc_desktop_frame.h", + ] + libs += [ "dwmapi.lib" ] + deps += [ + "../../rtc_base:rtc_event", + "../../rtc_base/win:hstring", + ] + } +} + +if (is_mac) { + rtc_library("desktop_capture_objc") { + # This target, needs to be separated from ":desktop_capture" because + # that is the C++ part of the target while this one is the Obj-C++ part. + # Aside from this, both represent a "desktop_capture" target. + # This target separation based on programming languages introduces a + # dependency cycle between ":desktop_capture" and + # ":desktop_capture_objc". + # To break this, ":desktop_capture_objc" shares some .h files with + # ":desktop_capture" but when external targets need one of these + # headers, they should depend on ":desktop_capture" and consider + # this target as private. + visibility = [ ":desktop_capture" ] + sources = [ + "delegated_source_list_controller.h", + "desktop_capture_options.h", + "desktop_capturer.h", + "full_screen_application_handler.h", + "full_screen_window_detector.h", + "mac/desktop_configuration.h", + "mac/desktop_configuration.mm", + "mac/desktop_configuration_monitor.h", + "mac/desktop_frame_cgimage.h", + "mac/desktop_frame_cgimage.mm", + "mac/desktop_frame_iosurface.h", + "mac/desktop_frame_iosurface.mm", + "mac/desktop_frame_provider.h", + "mac/desktop_frame_provider.mm", + "mac/screen_capturer_mac.h", + "mac/screen_capturer_mac.mm", + "mac/window_list_utils.h", + "mouse_cursor.h", + "mouse_cursor_monitor.h", + "mouse_cursor_monitor_mac.mm", + "screen_capture_frame_queue.h", + "screen_capturer_darwin.mm", + "screen_capturer_helper.h", + "window_capturer_mac.mm", + "window_finder.h", + "window_finder_mac.h", + "window_finder_mac.mm", + ] + deps = [ + ":primitives", + "../../api:function_view", + "../../api:refcountedbase", + "../../api:scoped_refptr", + "../../api:sequence_checker", + "../../rtc_base:checks", + "../../rtc_base:event_tracer", + "../../rtc_base:logging", + "../../rtc_base:macromagic", + "../../rtc_base:timeutils", + "../../rtc_base/synchronization:mutex", + "../../rtc_base/system:rtc_export", + "../../sdk:helpers_objc", + ] + frameworks = [ + "AppKit.framework", + "IOKit.framework", + "IOSurface.framework", + ] + } +} + +if (use_desktop_capture_differ_sse2) { + # Have to be compiled as a separate target because it needs to be compiled + # with SSE2 enabled. + rtc_library("desktop_capture_differ_sse2") { + visibility = [ ":*" ] + sources = [ + "differ_vector_sse2.cc", + "differ_vector_sse2.h", + ] + + if (is_posix || is_fuchsia) { + cflags = [ "-msse2" ] + } + } +} diff --git a/third_party/libwebrtc/modules/desktop_capture/DEPS b/third_party/libwebrtc/modules/desktop_capture/DEPS new file mode 100644 index 0000000000..8c894c4430 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/DEPS @@ -0,0 +1,19 @@ +include_rules = [ + "+system_wrappers", + "+third_party/libyuv", +] + +specific_include_rules = { + "desktop_frame_cgimage\.h": [ + "+sdk/objc", + ], + "desktop_frame_iosurface\.h": [ + "+sdk/objc", + ], + "desktop_frame_provider\.h": [ + "+sdk/objc", + ], + "screen_capturer_mac\.mm": [ + "+sdk/objc", + ], +} diff --git a/third_party/libwebrtc/modules/desktop_capture/OWNERS b/third_party/libwebrtc/modules/desktop_capture/OWNERS new file mode 100644 index 0000000000..e3bc32ee5c --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/OWNERS @@ -0,0 +1,2 @@ +alcooper@chromium.org +mfoltz@chromium.org diff --git a/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc new file mode 100644 index 0000000000..8e56ffc3fd --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2017 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/blank_detector_desktop_capturer_wrapper.h" + +#include + +#include + +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/desktop_region.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/metrics.h" + +namespace webrtc { + +BlankDetectorDesktopCapturerWrapper::BlankDetectorDesktopCapturerWrapper( + std::unique_ptr capturer, + RgbaColor blank_pixel, + bool check_per_capture) + : capturer_(std::move(capturer)), + blank_pixel_(blank_pixel), + check_per_capture_(check_per_capture) { + RTC_DCHECK(capturer_); +} + +BlankDetectorDesktopCapturerWrapper::~BlankDetectorDesktopCapturerWrapper() = + default; + +void BlankDetectorDesktopCapturerWrapper::Start( + DesktopCapturer::Callback* callback) { + callback_ = callback; + capturer_->Start(this); +} + +void BlankDetectorDesktopCapturerWrapper::SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) { + capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); +} + +void BlankDetectorDesktopCapturerWrapper::CaptureFrame() { + RTC_DCHECK(callback_); + capturer_->CaptureFrame(); +} + +void BlankDetectorDesktopCapturerWrapper::SetExcludedWindow(WindowId window) { + capturer_->SetExcludedWindow(window); +} + +bool BlankDetectorDesktopCapturerWrapper::GetSourceList(SourceList* sources) { + return capturer_->GetSourceList(sources); +} + +bool BlankDetectorDesktopCapturerWrapper::SelectSource(SourceId id) { + if (check_per_capture_) { + // If we start capturing a new source, we must reset these members + // so we don't short circuit the blank detection logic. + is_first_frame_ = true; + non_blank_frame_received_ = false; + } + + return capturer_->SelectSource(id); +} + +bool BlankDetectorDesktopCapturerWrapper::FocusOnSelectedSource() { + return capturer_->FocusOnSelectedSource(); +} + +bool BlankDetectorDesktopCapturerWrapper::IsOccluded(const DesktopVector& pos) { + return capturer_->IsOccluded(pos); +} + +void BlankDetectorDesktopCapturerWrapper::OnCaptureResult( + Result result, + std::unique_ptr frame) { + RTC_DCHECK(callback_); + if (result != Result::SUCCESS || non_blank_frame_received_) { + callback_->OnCaptureResult(result, std::move(frame)); + return; + } + + if (!frame) { + // Capturer can call the blank detector with empty frame. Blank + // detector regards it as a blank frame. + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, + std::unique_ptr()); + return; + } + + // If nothing has been changed in current frame, we do not need to check it + // again. + if (!frame->updated_region().is_empty() || is_first_frame_) { + last_frame_is_blank_ = IsBlankFrame(*frame); + is_first_frame_ = false; + } + RTC_HISTOGRAM_BOOLEAN("WebRTC.DesktopCapture.BlankFrameDetected", + last_frame_is_blank_); + if (!last_frame_is_blank_) { + non_blank_frame_received_ = true; + callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); + return; + } + + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, + std::unique_ptr()); +} + +bool BlankDetectorDesktopCapturerWrapper::IsBlankFrame( + const DesktopFrame& frame) const { + // We will check 7489 pixels for a frame with 1024 x 768 resolution. + for (int i = 0; i < frame.size().width() * frame.size().height(); i += 105) { + const int x = i % frame.size().width(); + const int y = i / frame.size().width(); + if (!IsBlankPixel(frame, x, y)) { + return false; + } + } + + // We are verifying the pixel in the center as well. + return IsBlankPixel(frame, frame.size().width() / 2, + frame.size().height() / 2); +} + +bool BlankDetectorDesktopCapturerWrapper::IsBlankPixel( + const DesktopFrame& frame, + int x, + int y) const { + uint8_t* pixel_data = frame.GetFrameDataAtPos(DesktopVector(x, y)); + return RgbaColor(pixel_data) == blank_pixel_; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h new file mode 100644 index 0000000000..d10f9cf725 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017 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_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ +#define MODULES_DESKTOP_CAPTURE_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ + +#include + +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/rgba_color.h" +#include "modules/desktop_capture/shared_memory.h" + +namespace webrtc { + +// A DesktopCapturer wrapper detects the return value of its owned +// DesktopCapturer implementation. If sampled pixels returned by the +// DesktopCapturer implementation all equal to the blank pixel, this wrapper +// returns ERROR_TEMPORARY. If the DesktopCapturer implementation fails for too +// many times, this wrapper returns ERROR_PERMANENT. +class BlankDetectorDesktopCapturerWrapper final + : public DesktopCapturer, + public DesktopCapturer::Callback { + public: + // Creates BlankDetectorDesktopCapturerWrapper. BlankDesktopCapturerWrapper + // takes ownership of `capturer`. The `blank_pixel` is the unmodified color + // returned by the `capturer`. + BlankDetectorDesktopCapturerWrapper(std::unique_ptr capturer, + RgbaColor blank_pixel, + bool check_per_capture = false); + ~BlankDetectorDesktopCapturerWrapper() override; + + // DesktopCapturer interface. + void Start(DesktopCapturer::Callback* callback) override; + void SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) override; + void CaptureFrame() override; + void SetExcludedWindow(WindowId window) override; + bool GetSourceList(SourceList* sources) override; + bool SelectSource(SourceId id) override; + bool FocusOnSelectedSource() override; + bool IsOccluded(const DesktopVector& pos) override; + + private: + // DesktopCapturer::Callback interface. + void OnCaptureResult(Result result, + std::unique_ptr frame) override; + + bool IsBlankFrame(const DesktopFrame& frame) const; + + // Detects whether pixel at (x, y) equals to `blank_pixel_`. + bool IsBlankPixel(const DesktopFrame& frame, int x, int y) const; + + const std::unique_ptr capturer_; + const RgbaColor blank_pixel_; + + // Whether a non-blank frame has been received. + bool non_blank_frame_received_ = false; + + // Whether the last frame is blank. + bool last_frame_is_blank_ = false; + + // Whether current frame is the first frame. + bool is_first_frame_ = true; + + // Blank inspection is made per capture instead of once for all + // screens or windows. + bool check_per_capture_ = false; + + DesktopCapturer::Callback* callback_ = nullptr; +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_BLANK_DETECTOR_DESKTOP_CAPTURER_WRAPPER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc new file mode 100644 index 0000000000..25a81edd89 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper_unittest.cc @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017 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/blank_detector_desktop_capturer_wrapper.h" + +#include +#include + +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_frame_generator.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/desktop_region.h" +#include "modules/desktop_capture/fake_desktop_capturer.h" +#include "test/gtest.h" + +namespace webrtc { + +class BlankDetectorDesktopCapturerWrapperTest + : public ::testing::Test, + public DesktopCapturer::Callback { + public: + BlankDetectorDesktopCapturerWrapperTest(); + ~BlankDetectorDesktopCapturerWrapperTest() override; + + protected: + void PerfTest(DesktopCapturer* capturer); + + const int frame_width_ = 1024; + const int frame_height_ = 768; + std::unique_ptr wrapper_; + DesktopCapturer* capturer_ = nullptr; + BlackWhiteDesktopFramePainter painter_; + int num_frames_captured_ = 0; + DesktopCapturer::Result last_result_ = DesktopCapturer::Result::SUCCESS; + std::unique_ptr last_frame_; + + private: + // DesktopCapturer::Callback interface. + void OnCaptureResult(DesktopCapturer::Result result, + std::unique_ptr frame) override; + + PainterDesktopFrameGenerator frame_generator_; +}; + +BlankDetectorDesktopCapturerWrapperTest:: + BlankDetectorDesktopCapturerWrapperTest() { + frame_generator_.size()->set(frame_width_, frame_height_); + frame_generator_.set_desktop_frame_painter(&painter_); + std::unique_ptr capturer(new FakeDesktopCapturer()); + FakeDesktopCapturer* fake_capturer = + static_cast(capturer.get()); + fake_capturer->set_frame_generator(&frame_generator_); + capturer_ = fake_capturer; + wrapper_.reset(new BlankDetectorDesktopCapturerWrapper( + std::move(capturer), RgbaColor(0, 0, 0, 0))); + wrapper_->Start(this); +} + +BlankDetectorDesktopCapturerWrapperTest:: + ~BlankDetectorDesktopCapturerWrapperTest() = default; + +void BlankDetectorDesktopCapturerWrapperTest::OnCaptureResult( + DesktopCapturer::Result result, + std::unique_ptr frame) { + last_result_ = result; + last_frame_ = std::move(frame); + num_frames_captured_++; +} + +void BlankDetectorDesktopCapturerWrapperTest::PerfTest( + DesktopCapturer* capturer) { + for (int i = 0; i < 10000; i++) { + capturer->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, i + 1); + } +} + +TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldDetectBlankFrame) { + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 1); + ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY); + ASSERT_FALSE(last_frame_); +} + +TEST_F(BlankDetectorDesktopCapturerWrapperTest, ShouldPassBlankDetection) { + painter_.updated_region()->AddRect(DesktopRect::MakeXYWH(0, 0, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 1); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + + painter_.updated_region()->AddRect( + DesktopRect::MakeXYWH(frame_width_ - 100, frame_height_ - 100, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 2); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + + painter_.updated_region()->AddRect( + DesktopRect::MakeXYWH(0, frame_height_ - 100, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 3); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + + painter_.updated_region()->AddRect( + DesktopRect::MakeXYWH(frame_width_ - 100, 0, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 4); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + + painter_.updated_region()->AddRect(DesktopRect::MakeXYWH( + (frame_width_ >> 1) - 50, (frame_height_ >> 1) - 50, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 5); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); +} + +TEST_F(BlankDetectorDesktopCapturerWrapperTest, + ShouldNotCheckAfterANonBlankFrameReceived) { + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 1); + ASSERT_EQ(last_result_, DesktopCapturer::Result::ERROR_TEMPORARY); + ASSERT_FALSE(last_frame_); + + painter_.updated_region()->AddRect( + DesktopRect::MakeXYWH(frame_width_ - 100, 0, 100, 100)); + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, 2); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + + for (int i = 0; i < 100; i++) { + wrapper_->CaptureFrame(); + ASSERT_EQ(num_frames_captured_, i + 3); + ASSERT_EQ(last_result_, DesktopCapturer::Result::SUCCESS); + ASSERT_TRUE(last_frame_); + } +} + +// There is no perceptible impact by using BlankDetectorDesktopCapturerWrapper. +// i.e. less than 0.2ms per frame. +// [ OK ] DISABLED_Performance (10210 ms) +// [ OK ] DISABLED_PerformanceComparison (8791 ms) +TEST_F(BlankDetectorDesktopCapturerWrapperTest, DISABLED_Performance) { + PerfTest(wrapper_.get()); +} + +TEST_F(BlankDetectorDesktopCapturerWrapperTest, + DISABLED_PerformanceComparison) { + capturer_->Start(this); + PerfTest(capturer_); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.cc b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.cc new file mode 100644 index 0000000000..54488b7d62 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.cc @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014 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/cropped_desktop_frame.h" + +#include +#include + +#include "modules/desktop_capture/desktop_region.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +// A DesktopFrame that is a sub-rect of another DesktopFrame. +class CroppedDesktopFrame : public DesktopFrame { + public: + CroppedDesktopFrame(std::unique_ptr frame, + const DesktopRect& rect); + + CroppedDesktopFrame(const CroppedDesktopFrame&) = delete; + CroppedDesktopFrame& operator=(const CroppedDesktopFrame&) = delete; + + private: + const std::unique_ptr frame_; +}; + +std::unique_ptr CreateCroppedDesktopFrame( + std::unique_ptr frame, + const DesktopRect& rect) { + RTC_DCHECK(frame); + + DesktopRect intersection = DesktopRect::MakeSize(frame->size()); + intersection.IntersectWith(rect); + if (intersection.is_empty()) { + return nullptr; + } + + if (frame->size().equals(rect.size())) { + return frame; + } + + return std::unique_ptr( + new CroppedDesktopFrame(std::move(frame), intersection)); +} + +CroppedDesktopFrame::CroppedDesktopFrame(std::unique_ptr frame, + const DesktopRect& rect) + : DesktopFrame(rect.size(), + frame->stride(), + frame->GetFrameDataAtPos(rect.top_left()), + frame->shared_memory()), + frame_(std::move(frame)) { + MoveFrameInfoFrom(frame_.get()); + set_top_left(frame_->top_left().add(rect.top_left())); + mutable_updated_region()->IntersectWith(rect); + mutable_updated_region()->Translate(-rect.left(), -rect.top()); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.h b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.h new file mode 100644 index 0000000000..5c672c7d32 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014 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_CROPPED_DESKTOP_FRAME_H_ +#define MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_ + +#include + +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// Creates a DesktopFrame to contain only the area of `rect` in the original +// `frame`. +// `frame` should not be nullptr. `rect` is in `frame` coordinate, i.e. +// `frame`->top_left() does not impact the area of `rect`. +// Returns nullptr frame if `rect` is not contained by the bounds of `frame`. +std::unique_ptr RTC_EXPORT +CreateCroppedDesktopFrame(std::unique_ptr frame, + const DesktopRect& rect); + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame_unittest.cc new file mode 100644 index 0000000000..9becf69636 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame_unittest.cc @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017 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/cropped_desktop_frame.h" + +#include +#include + +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/shared_desktop_frame.h" +#include "test/gtest.h" + +namespace webrtc { + +std::unique_ptr CreateTestFrame() { + return std::make_unique(DesktopSize(10, 20)); +} + +TEST(CroppedDesktopFrameTest, DoNotCreateWrapperIfSizeIsNotChanged) { + std::unique_ptr original = CreateTestFrame(); + // owned by `original` and CroppedDesktopFrame. + DesktopFrame* raw_original = original.get(); + std::unique_ptr cropped = CreateCroppedDesktopFrame( + std::move(original), DesktopRect::MakeWH(10, 20)); + ASSERT_EQ(cropped.get(), raw_original); +} + +TEST(CroppedDesktopFrameTest, CropWhenPartiallyOutOfBounds) { + std::unique_ptr cropped = + CreateCroppedDesktopFrame(CreateTestFrame(), DesktopRect::MakeWH(11, 10)); + ASSERT_NE(nullptr, cropped); + ASSERT_EQ(cropped->size().width(), 10); + ASSERT_EQ(cropped->size().height(), 10); + ASSERT_EQ(cropped->top_left().x(), 0); + ASSERT_EQ(cropped->top_left().y(), 0); +} + +TEST(CroppedDesktopFrameTest, ReturnNullIfCropRegionIsOutOfBounds) { + std::unique_ptr frame = CreateTestFrame(); + frame->set_top_left(DesktopVector(100, 200)); + ASSERT_EQ(nullptr, + CreateCroppedDesktopFrame( + std::move(frame), DesktopRect::MakeLTRB(101, 203, 109, 218))); +} + +TEST(CroppedDesktopFrameTest, CropASubArea) { + std::unique_ptr cropped = CreateCroppedDesktopFrame( + CreateTestFrame(), DesktopRect::MakeLTRB(1, 2, 9, 19)); + ASSERT_EQ(cropped->size().width(), 8); + ASSERT_EQ(cropped->size().height(), 17); + ASSERT_EQ(cropped->top_left().x(), 1); + ASSERT_EQ(cropped->top_left().y(), 2); +} + +TEST(CroppedDesktopFrameTest, SetTopLeft) { + std::unique_ptr frame = CreateTestFrame(); + frame->set_top_left(DesktopVector(100, 200)); + frame = CreateCroppedDesktopFrame(std::move(frame), + DesktopRect::MakeLTRB(1, 3, 9, 18)); + ASSERT_EQ(frame->size().width(), 8); + ASSERT_EQ(frame->size().height(), 15); + ASSERT_EQ(frame->top_left().x(), 101); + ASSERT_EQ(frame->top_left().y(), 203); +} + +TEST(CroppedDesktopFrameTest, InitializedWithZeros) { + std::unique_ptr frame = CreateTestFrame(); + const DesktopVector frame_origin = frame->top_left(); + const DesktopSize frame_size = frame->size(); + std::unique_ptr cropped = CreateCroppedDesktopFrame( + std::move(frame), DesktopRect::MakeOriginSize(frame_origin, frame_size)); + for (int j = 0; j < cropped->size().height(); ++j) { + for (int i = 0; i < cropped->stride(); ++i) { + ASSERT_EQ(cropped->data()[i + j * cropped->stride()], 0); + } + } +} + +TEST(CroppedDesktopFrameTest, IccProfile) { + const uint8_t fake_icc_profile_data_array[] = {0x1a, 0x00, 0x2b, 0x00, + 0x3c, 0x00, 0x4d}; + const std::vector icc_profile( + fake_icc_profile_data_array, + fake_icc_profile_data_array + sizeof(fake_icc_profile_data_array)); + + std::unique_ptr frame = CreateTestFrame(); + EXPECT_EQ(frame->icc_profile().size(), 0UL); + + frame->set_icc_profile(icc_profile); + EXPECT_EQ(frame->icc_profile().size(), 7UL); + EXPECT_EQ(frame->icc_profile(), icc_profile); + + frame = CreateCroppedDesktopFrame(std::move(frame), + DesktopRect::MakeLTRB(2, 2, 8, 18)); + EXPECT_EQ(frame->icc_profile().size(), 7UL); + EXPECT_EQ(frame->icc_profile(), icc_profile); + + std::unique_ptr shared = + SharedDesktopFrame::Wrap(std::move(frame)); + EXPECT_EQ(shared->icc_profile().size(), 7UL); + EXPECT_EQ(shared->icc_profile(), icc_profile); + + std::unique_ptr shared_other = shared->Share(); + EXPECT_EQ(shared_other->icc_profile().size(), 7UL); + EXPECT_EQ(shared_other->icc_profile(), icc_profile); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.cc b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.cc new file mode 100644 index 0000000000..5e0faaade9 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.cc @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2014 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/cropping_window_capturer.h" + +#include + +#include + +#include "modules/desktop_capture/cropped_desktop_frame.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +CroppingWindowCapturer::CroppingWindowCapturer( + const DesktopCaptureOptions& options) + : options_(options), + callback_(NULL), + window_capturer_(DesktopCapturer::CreateRawWindowCapturer(options)), + selected_window_(kNullWindowId), + excluded_window_(kNullWindowId) {} + +CroppingWindowCapturer::~CroppingWindowCapturer() {} + +void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) { + callback_ = callback; + window_capturer_->Start(callback); +} + +void CroppingWindowCapturer::SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) { + window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); +} + +void CroppingWindowCapturer::CaptureFrame() { + if (ShouldUseScreenCapturer()) { + if (!screen_capturer_.get()) { + screen_capturer_ = DesktopCapturer::CreateRawScreenCapturer(options_); + if (excluded_window_) { + screen_capturer_->SetExcludedWindow(excluded_window_); + } + screen_capturer_->Start(this); + } + screen_capturer_->CaptureFrame(); + } else { + window_capturer_->CaptureFrame(); + } +} + +void CroppingWindowCapturer::SetExcludedWindow(WindowId window) { + excluded_window_ = window; + if (screen_capturer_.get()) { + screen_capturer_->SetExcludedWindow(window); + } +} + +bool CroppingWindowCapturer::GetSourceList(SourceList* sources) { + return window_capturer_->GetSourceList(sources); +} + +bool CroppingWindowCapturer::SelectSource(SourceId id) { + if (window_capturer_->SelectSource(id)) { + selected_window_ = id; + return true; + } + return false; +} + +bool CroppingWindowCapturer::FocusOnSelectedSource() { + return window_capturer_->FocusOnSelectedSource(); +} + +void CroppingWindowCapturer::OnCaptureResult( + DesktopCapturer::Result result, + std::unique_ptr screen_frame) { + if (!ShouldUseScreenCapturer()) { + RTC_LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes"; + window_capturer_->CaptureFrame(); + return; + } + + if (result != Result::SUCCESS) { + RTC_LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame"; + callback_->OnCaptureResult(result, nullptr); + return; + } + + DesktopRect window_rect = GetWindowRectInVirtualScreen(); + if (window_rect.is_empty()) { + RTC_LOG(LS_WARNING) << "Window rect is empty"; + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); + return; + } + + std::unique_ptr cropped_frame = + CreateCroppedDesktopFrame(std::move(screen_frame), window_rect); + + if (!cropped_frame) { + RTC_LOG(LS_WARNING) << "Window is outside of the captured display"; + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); + return; + } + + callback_->OnCaptureResult(Result::SUCCESS, std::move(cropped_frame)); +} + +bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) { + // Returns true if either capturer returns true. + if (window_capturer_->IsOccluded(pos)) { + return true; + } + if (screen_capturer_ != nullptr && screen_capturer_->IsOccluded(pos)) { + return true; + } + return false; +} + +#if !defined(WEBRTC_WIN) +// CroppingWindowCapturer is implemented only for windows. On other platforms +// the regular window capturer is used. +// static +std::unique_ptr CroppingWindowCapturer::CreateCapturer( + const DesktopCaptureOptions& options) { + return DesktopCapturer::CreateWindowCapturer(options); +} +#endif + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.h b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.h new file mode 100644 index 0000000000..56478030b1 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014 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_CROPPING_WINDOW_CAPTURER_H_ +#define MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_ + +#include + +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/shared_memory.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// WindowCapturer implementation that uses a screen capturer to capture the +// whole screen and crops the video frame to the window area when the captured +// window is on top. +class RTC_EXPORT CroppingWindowCapturer : public DesktopCapturer, + public DesktopCapturer::Callback { + public: + static std::unique_ptr CreateCapturer( + const DesktopCaptureOptions& options); + + ~CroppingWindowCapturer() override; + + // DesktopCapturer implementation. + void Start(DesktopCapturer::Callback* callback) override; + void SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) override; + void CaptureFrame() override; + void SetExcludedWindow(WindowId window) override; + bool GetSourceList(SourceList* sources) override; + bool SelectSource(SourceId id) override; + bool FocusOnSelectedSource() override; + bool IsOccluded(const DesktopVector& pos) override; + + // DesktopCapturer::Callback implementation, passed to `screen_capturer_` to + // intercept the capture result. + void OnCaptureResult(DesktopCapturer::Result result, + std::unique_ptr frame) override; + + protected: + explicit CroppingWindowCapturer(const DesktopCaptureOptions& options); + + // The platform implementation should override these methods. + + // Returns true if it is OK to capture the whole screen and crop to the + // selected window, i.e. the selected window is opaque, rectangular, and not + // occluded. + virtual bool ShouldUseScreenCapturer() = 0; + + // Returns the window area relative to the top left of the virtual screen + // within the bounds of the virtual screen. This function should return the + // DesktopRect in full desktop coordinates, i.e. the top-left monitor starts + // from (0, 0). + virtual DesktopRect GetWindowRectInVirtualScreen() = 0; + + WindowId selected_window() const { return selected_window_; } + WindowId excluded_window() const { return excluded_window_; } + DesktopCapturer* window_capturer() const { return window_capturer_.get(); } + + private: + DesktopCaptureOptions options_; + DesktopCapturer::Callback* callback_; + std::unique_ptr window_capturer_; + std::unique_ptr screen_capturer_; + SourceId selected_window_; + WindowId excluded_window_; +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer_win.cc b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer_win.cc new file mode 100644 index 0000000000..ab2f807d33 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer_win.cc @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2014 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/cropping_window_capturer.h" +#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" +#include "modules/desktop_capture/win/screen_capture_utils.h" +#include "modules/desktop_capture/win/selected_window_context.h" +#include "modules/desktop_capture/win/window_capture_utils.h" +#include "rtc_base/logging.h" +#include "rtc_base/trace_event.h" +#include "rtc_base/win/windows_version.h" + +namespace webrtc { + +namespace { + +// Used to pass input data for verifying the selected window is on top. +struct TopWindowVerifierContext : public SelectedWindowContext { + TopWindowVerifierContext(HWND selected_window, + HWND excluded_window, + DesktopRect selected_window_rect, + WindowCaptureHelperWin* window_capture_helper) + : SelectedWindowContext(selected_window, + selected_window_rect, + window_capture_helper), + excluded_window(excluded_window) { + RTC_DCHECK_NE(selected_window, excluded_window); + } + + // Determines whether the selected window is on top (not occluded by any + // windows except for those it owns or any excluded window). + bool IsTopWindow() { + if (!IsSelectedWindowValid()) { + return false; + } + + // Enumerate all top-level windows above the selected window in Z-order, + // checking whether any overlaps it. This uses FindWindowEx rather than + // EnumWindows because the latter excludes certain system windows (e.g. the + // Start menu & other taskbar menus) that should be detected here to avoid + // inadvertent capture. + int num_retries = 0; + while (true) { + HWND hwnd = nullptr; + while ((hwnd = FindWindowEx(nullptr, hwnd, nullptr, nullptr))) { + if (hwnd == selected_window()) { + // Windows are enumerated in top-down Z-order, so we can stop + // enumerating upon reaching the selected window & report it's on top. + return true; + } + + // Ignore the excluded window. + if (hwnd == excluded_window) { + continue; + } + + // Ignore windows that aren't visible on the current desktop. + if (!window_capture_helper()->IsWindowVisibleOnCurrentDesktop(hwnd)) { + continue; + } + + // Ignore Chrome notification windows, especially the notification for + // the ongoing window sharing. Notes: + // - This only works with notifications from Chrome, not other Apps. + // - All notifications from Chrome will be ignored. + // - This may cause part or whole of notification window being cropped + // into the capturing of the target window if there is overlapping. + if (window_capture_helper()->IsWindowChromeNotification(hwnd)) { + continue; + } + + // Ignore windows owned by the selected window since we want to capture + // them. + if (IsWindowOwnedBySelectedWindow(hwnd)) { + continue; + } + + // Check whether this window intersects with the selected window. + if (IsWindowOverlappingSelectedWindow(hwnd)) { + // If intersection is not empty, the selected window is not on top. + return false; + } + } + + DWORD lastError = GetLastError(); + if (lastError == ERROR_SUCCESS) { + // The enumeration completed successfully without finding the selected + // window (which may have been closed). + RTC_LOG(LS_WARNING) << "Failed to find selected window (only expected " + "if it was closed)"; + RTC_DCHECK(!IsWindow(selected_window())); + return false; + } else if (lastError == ERROR_INVALID_WINDOW_HANDLE) { + // This error may occur if a window is closed around the time it's + // enumerated; retry the enumeration in this case up to 10 times + // (this should be a rare race & unlikely to recur). + if (++num_retries <= 10) { + RTC_LOG(LS_WARNING) << "Enumeration failed due to race with a window " + "closing; retrying - retry #" + << num_retries; + continue; + } else { + RTC_LOG(LS_ERROR) + << "Exhausted retry allowance around window enumeration failures " + "due to races with windows closing"; + } + } + + // The enumeration failed with an unexpected error (or more repeats of + // an infrequently-expected error than anticipated). After logging this & + // firing an assert when enabled, report that the selected window isn't + // topmost to avoid inadvertent capture of other windows. + RTC_LOG(LS_ERROR) << "Failed to enumerate windows: " << lastError; + RTC_DCHECK_NOTREACHED(); + return false; + } + } + + const HWND excluded_window; +}; + +class CroppingWindowCapturerWin : public CroppingWindowCapturer { + public: + explicit CroppingWindowCapturerWin(const DesktopCaptureOptions& options) + : CroppingWindowCapturer(options), + enumerate_current_process_windows_( + options.enumerate_current_process_windows()), + full_screen_window_detector_(options.full_screen_window_detector()) {} + + void CaptureFrame() override; + + private: + bool ShouldUseScreenCapturer() override; + DesktopRect GetWindowRectInVirtualScreen() override; + + // Returns either selected by user sourceId or sourceId provided by + // FullScreenWindowDetector + WindowId GetWindowToCapture() const; + + // The region from GetWindowRgn in the desktop coordinate if the region is + // rectangular, or the rect from GetWindowRect if the region is not set. + DesktopRect window_region_rect_; + + WindowCaptureHelperWin window_capture_helper_; + + bool enumerate_current_process_windows_; + + rtc::scoped_refptr full_screen_window_detector_; + + // Used to make sure that we only log the usage of fullscreen detection once. + mutable bool fullscreen_usage_logged_ = false; +}; + +void CroppingWindowCapturerWin::CaptureFrame() { + DesktopCapturer* win_capturer = window_capturer(); + if (win_capturer) { + // Feed the actual list of windows into full screen window detector. + if (full_screen_window_detector_) { + full_screen_window_detector_->UpdateWindowListIfNeeded( + selected_window(), [this](DesktopCapturer::SourceList* sources) { + // Get the list of top level windows, including ones with empty + // title. win_capturer_->GetSourceList can't be used here + // cause it filters out the windows with empty titles and + // it uses responsiveness check which could lead to performance + // issues. + SourceList result; + int window_list_flags = + enumerate_current_process_windows_ + ? GetWindowListFlags::kNone + : GetWindowListFlags::kIgnoreCurrentProcessWindows; + + if (!webrtc::GetWindowList(window_list_flags, &result)) + return false; + + // Filter out windows not visible on current desktop + auto it = std::remove_if( + result.begin(), result.end(), [this](const auto& source) { + HWND hwnd = reinterpret_cast(source.id); + return !window_capture_helper_ + .IsWindowVisibleOnCurrentDesktop(hwnd); + }); + result.erase(it, result.end()); + + sources->swap(result); + return true; + }); + } + win_capturer->SelectSource(GetWindowToCapture()); + } + + CroppingWindowCapturer::CaptureFrame(); +} + +bool CroppingWindowCapturerWin::ShouldUseScreenCapturer() { + if (rtc::rtc_win::GetVersion() < rtc::rtc_win::Version::VERSION_WIN8 && + window_capture_helper_.IsAeroEnabled()) { + return false; + } + + const HWND selected = reinterpret_cast(GetWindowToCapture()); + // Check if the window is visible on current desktop. + if (!window_capture_helper_.IsWindowVisibleOnCurrentDesktop(selected)) { + return false; + } + + // Check if the window is a translucent layered window. + const LONG window_ex_style = GetWindowLong(selected, GWL_EXSTYLE); + if (window_ex_style & WS_EX_LAYERED) { + COLORREF color_ref_key = 0; + BYTE alpha = 0; + DWORD flags = 0; + + // GetLayeredWindowAttributes fails if the window was setup with + // UpdateLayeredWindow. We have no way to know the opacity of the window in + // that case. This happens for Stiky Note (crbug/412726). + if (!GetLayeredWindowAttributes(selected, &color_ref_key, &alpha, &flags)) + return false; + + // UpdateLayeredWindow is the only way to set per-pixel alpha and will cause + // the previous GetLayeredWindowAttributes to fail. So we only need to check + // the window wide color key or alpha. + if ((flags & LWA_COLORKEY) || ((flags & LWA_ALPHA) && (alpha < 255))) { + return false; + } + } + + if (!GetWindowRect(selected, &window_region_rect_)) { + return false; + } + + DesktopRect content_rect; + if (!GetWindowContentRect(selected, &content_rect)) { + return false; + } + + DesktopRect region_rect; + // Get the window region and check if it is rectangular. + const int region_type = + GetWindowRegionTypeWithBoundary(selected, ®ion_rect); + + // Do not use the screen capturer if the region is empty or not rectangular. + if (region_type == COMPLEXREGION || region_type == NULLREGION) { + return false; + } + + if (region_type == SIMPLEREGION) { + // The `region_rect` returned from GetRgnBox() is always in window + // coordinate. + region_rect.Translate(window_region_rect_.left(), + window_region_rect_.top()); + // MSDN: The window region determines the area *within* the window where the + // system permits drawing. + // https://msdn.microsoft.com/en-us/library/windows/desktop/dd144950(v=vs.85).aspx. + // + // `region_rect` should always be inside of `window_region_rect_`. So after + // the intersection, `window_region_rect_` == `region_rect`. If so, what's + // the point of the intersecting operations? Why cannot we directly retrieve + // `window_region_rect_` from GetWindowRegionTypeWithBoundary() function? + // TODO(zijiehe): Figure out the purpose of these intersections. + window_region_rect_.IntersectWith(region_rect); + content_rect.IntersectWith(region_rect); + } + + // Check if the client area is out of the screen area. When the window is + // maximized, only its client area is visible in the screen, the border will + // be hidden. So we are using `content_rect` here. + if (!GetFullscreenRect().ContainsRect(content_rect)) { + return false; + } + + // Check if the window is occluded by any other window, excluding the child + // windows, context menus, and `excluded_window_`. + // `content_rect` is preferred, see the comments on + // IsWindowIntersectWithSelectedWindow(). + TopWindowVerifierContext context(selected, + reinterpret_cast(excluded_window()), + content_rect, &window_capture_helper_); + return context.IsTopWindow(); +} + +DesktopRect CroppingWindowCapturerWin::GetWindowRectInVirtualScreen() { + TRACE_EVENT0("webrtc", + "CroppingWindowCapturerWin::GetWindowRectInVirtualScreen"); + DesktopRect window_rect; + HWND hwnd = reinterpret_cast(GetWindowToCapture()); + if (!GetCroppedWindowRect(hwnd, /*avoid_cropping_border*/ false, &window_rect, + /*original_rect*/ nullptr)) { + RTC_LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); + return window_rect; + } + window_rect.IntersectWith(window_region_rect_); + + // Convert `window_rect` to be relative to the top-left of the virtual screen. + DesktopRect screen_rect(GetFullscreenRect()); + window_rect.IntersectWith(screen_rect); + window_rect.Translate(-screen_rect.left(), -screen_rect.top()); + return window_rect; +} + +WindowId CroppingWindowCapturerWin::GetWindowToCapture() const { + const auto selected_source = selected_window(); + const auto full_screen_source = + full_screen_window_detector_ + ? full_screen_window_detector_->FindFullScreenWindow(selected_source) + : 0; + if (full_screen_source && full_screen_source != selected_source && + !fullscreen_usage_logged_) { + fullscreen_usage_logged_ = true; + LogDesktopCapturerFullscreenDetectorUsage(); + } + return full_screen_source ? full_screen_source : selected_source; +} + +} // namespace + +// static +std::unique_ptr CroppingWindowCapturer::CreateCapturer( + const DesktopCaptureOptions& options) { + std::unique_ptr capturer( + new CroppingWindowCapturerWin(options)); + if (capturer && options.detect_updated_region()) { + capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); + } + + return capturer; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/delegated_source_list_controller.h b/third_party/libwebrtc/modules/desktop_capture/delegated_source_list_controller.h new file mode 100644 index 0000000000..cada7dc817 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/delegated_source_list_controller.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 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_DELEGATED_SOURCE_LIST_CONTROLLER_H_ +#define MODULES_DESKTOP_CAPTURE_DELEGATED_SOURCE_LIST_CONTROLLER_H_ + +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// A controller to be implemented and returned by +// GetDelegatedSourceListController in capturers that require showing their own +// source list and managing user selection there. Apart from ensuring the +// visibility of the source list, these capturers should largely be interacted +// with the same as a normal capturer, though there may be some caveats for +// some DesktopCapturer methods. See GetDelegatedSourceListController for more +// information. +class RTC_EXPORT DelegatedSourceListController { + public: + // Notifications that can be used to help drive any UI that the consumer may + // want to show around this source list (e.g. if an consumer shows their own + // UI in addition to the delegated source list). + class Observer { + public: + // Called after the user has made a selection in the delegated source list. + // Note that the consumer will still need to get the source out of the + // capturer by calling GetSourceList. + virtual void OnSelection() = 0; + + // Called when there is any user action that cancels the source selection. + virtual void OnCancelled() = 0; + + // Called when there is a system error that cancels the source selection. + virtual void OnError() = 0; + + protected: + virtual ~Observer() {} + }; + + // Observer must remain valid until the owning DesktopCapturer is destroyed. + // Only one Observer is allowed at a time, and may be cleared by passing + // nullptr. + virtual void Observe(Observer* observer) = 0; + + // Used to prompt the capturer to show the delegated source list. If the + // source list is already visible, this will be a no-op. Must be called after + // starting the DesktopCapturer. + // + // Note that any selection from a previous invocation of the source list may + // be cleared when this method is called. + virtual void EnsureVisible() = 0; + + // Used to prompt the capturer to hide the delegated source list. If the + // source list is already hidden, this will be a no-op. + virtual void EnsureHidden() = 0; + + protected: + virtual ~DelegatedSourceListController() {} +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DELEGATED_SOURCE_LIST_CONTROLLER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc new file mode 100644 index 0000000000..91aea58628 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2013 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/desktop_and_cursor_composer.h" + +#include +#include + +#include +#include + +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/mouse_cursor.h" +#include "modules/desktop_capture/mouse_cursor_monitor.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +namespace { + +// Global reference counter which is increased when a DesktopFrameWithCursor is +// created and decreased when the same object is destructed. Only used for +// debugging purposes to ensure that we never end up in state where +// `g_ref_count` is larger than one since that could indicate a flickering +// cursor (cursor-less version of the frame is not restored properly and it can +// can lead to visible trails of old cursors). +// See https://crbug.com/1421656#c99 for more details. +int g_ref_count = 0; + +uint64_t g_num_flicker_warnings = 0; + +// Helper function that blends one image into another. Source image must be +// pre-multiplied with the alpha channel. Destination is assumed to be opaque. +void AlphaBlend(uint8_t* dest, + int dest_stride, + const uint8_t* src, + int src_stride, + const DesktopSize& size) { + for (int y = 0; y < size.height(); ++y) { + for (int x = 0; x < size.width(); ++x) { + uint32_t base_alpha = 255 - src[x * DesktopFrame::kBytesPerPixel + 3]; + if (base_alpha == 255) { + continue; + } else if (base_alpha == 0) { + memcpy(dest + x * DesktopFrame::kBytesPerPixel, + src + x * DesktopFrame::kBytesPerPixel, + DesktopFrame::kBytesPerPixel); + } else { + dest[x * DesktopFrame::kBytesPerPixel] = + dest[x * DesktopFrame::kBytesPerPixel] * base_alpha / 255 + + src[x * DesktopFrame::kBytesPerPixel]; + dest[x * DesktopFrame::kBytesPerPixel + 1] = + dest[x * DesktopFrame::kBytesPerPixel + 1] * base_alpha / 255 + + src[x * DesktopFrame::kBytesPerPixel + 1]; + dest[x * DesktopFrame::kBytesPerPixel + 2] = + dest[x * DesktopFrame::kBytesPerPixel + 2] * base_alpha / 255 + + src[x * DesktopFrame::kBytesPerPixel + 2]; + } + } + src += src_stride; + dest += dest_stride; + } +} + +// DesktopFrame wrapper that draws mouse on a frame and restores original +// content before releasing the underlying frame. +class DesktopFrameWithCursor : public DesktopFrame { + public: + // Takes ownership of `frame`. + DesktopFrameWithCursor(std::unique_ptr frame, + const MouseCursor& cursor, + const DesktopVector& position, + const DesktopRect& previous_cursor_rect, + bool cursor_changed); + ~DesktopFrameWithCursor() override; + + DesktopFrameWithCursor(const DesktopFrameWithCursor&) = delete; + DesktopFrameWithCursor& operator=(const DesktopFrameWithCursor&) = delete; + + DesktopRect cursor_rect() const { return cursor_rect_; } + + private: + const std::unique_ptr original_frame_; + + DesktopVector restore_position_; + std::unique_ptr restore_frame_; + DesktopRect cursor_rect_; +}; + +DesktopFrameWithCursor::DesktopFrameWithCursor( + std::unique_ptr frame, + const MouseCursor& cursor, + const DesktopVector& position, + const DesktopRect& previous_cursor_rect, + bool cursor_changed) + : DesktopFrame(frame->size(), + frame->stride(), + frame->data(), + frame->shared_memory()), + original_frame_(std::move(frame)) { + ++g_ref_count; + MoveFrameInfoFrom(original_frame_.get()); + + DesktopVector image_pos = position.subtract(cursor.hotspot()); + cursor_rect_ = DesktopRect::MakeSize(cursor.image()->size()); + cursor_rect_.Translate(image_pos); + DesktopVector cursor_origin = cursor_rect_.top_left(); + cursor_rect_.IntersectWith(DesktopRect::MakeSize(size())); + + if (!previous_cursor_rect.equals(cursor_rect_)) { + mutable_updated_region()->AddRect(cursor_rect_); + // TODO(crbug:1323241) Update this code to properly handle the case where + // |previous_cursor_rect| is outside of the boundaries of |frame|. + // Any boundary check has to take into account the fact that + // |previous_cursor_rect| can be in DPI or in pixels, based on the platform + // we're running on. + mutable_updated_region()->AddRect(previous_cursor_rect); + } else if (cursor_changed) { + mutable_updated_region()->AddRect(cursor_rect_); + } + + if (cursor_rect_.is_empty()) + return; + + // Copy original screen content under cursor to `restore_frame_`. + restore_position_ = cursor_rect_.top_left(); + restore_frame_.reset(new BasicDesktopFrame(cursor_rect_.size())); + restore_frame_->CopyPixelsFrom(*this, cursor_rect_.top_left(), + DesktopRect::MakeSize(restore_frame_->size())); + + // Blit the cursor. + uint8_t* cursor_rect_data = + reinterpret_cast(data()) + cursor_rect_.top() * stride() + + cursor_rect_.left() * DesktopFrame::kBytesPerPixel; + DesktopVector origin_shift = cursor_rect_.top_left().subtract(cursor_origin); + AlphaBlend(cursor_rect_data, stride(), + cursor.image()->data() + + origin_shift.y() * cursor.image()->stride() + + origin_shift.x() * DesktopFrame::kBytesPerPixel, + cursor.image()->stride(), cursor_rect_.size()); +} + +DesktopFrameWithCursor::~DesktopFrameWithCursor() { + if (--g_ref_count > 0) { + ++g_num_flicker_warnings; + RTC_LOG(LS_WARNING) << "Cursor might be flickering; number of warnings=" + << g_num_flicker_warnings; + } + // Restore original content of the frame. + if (restore_frame_) { + DesktopRect target_rect = DesktopRect::MakeSize(restore_frame_->size()); + target_rect.Translate(restore_position_); + CopyPixelsFrom(restore_frame_->data(), restore_frame_->stride(), + target_rect); + } +} + +} // namespace + +DesktopAndCursorComposer::DesktopAndCursorComposer( + std::unique_ptr desktop_capturer, + const DesktopCaptureOptions& options) + : DesktopAndCursorComposer(desktop_capturer.release(), + MouseCursorMonitor::Create(options).release()) {} + +DesktopAndCursorComposer::DesktopAndCursorComposer( + DesktopCapturer* desktop_capturer, + MouseCursorMonitor* mouse_monitor) + : desktop_capturer_(desktop_capturer), mouse_monitor_(mouse_monitor) { + RTC_DCHECK(desktop_capturer_); +} + +DesktopAndCursorComposer::~DesktopAndCursorComposer() = default; + +std::unique_ptr +DesktopAndCursorComposer::CreateWithoutMouseCursorMonitor( + std::unique_ptr desktop_capturer) { + return std::unique_ptr( + new DesktopAndCursorComposer(desktop_capturer.release(), nullptr)); +} + +void DesktopAndCursorComposer::Start(DesktopCapturer::Callback* callback) { + callback_ = callback; + if (mouse_monitor_) + mouse_monitor_->Init(this, MouseCursorMonitor::SHAPE_AND_POSITION); + desktop_capturer_->Start(this); +} + +void DesktopAndCursorComposer::SetMaxFrameRate(uint32_t max_frame_rate) { + desktop_capturer_->SetMaxFrameRate(max_frame_rate); +} + +void DesktopAndCursorComposer::SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) { + desktop_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); +} + +void DesktopAndCursorComposer::CaptureFrame() { + if (mouse_monitor_) + mouse_monitor_->Capture(); + desktop_capturer_->CaptureFrame(); +} + +void DesktopAndCursorComposer::SetExcludedWindow(WindowId window) { + desktop_capturer_->SetExcludedWindow(window); +} + +bool DesktopAndCursorComposer::GetSourceList(SourceList* sources) { + return desktop_capturer_->GetSourceList(sources); +} + +bool DesktopAndCursorComposer::SelectSource(SourceId id) { + return desktop_capturer_->SelectSource(id); +} + +bool DesktopAndCursorComposer::FocusOnSelectedSource() { + return desktop_capturer_->FocusOnSelectedSource(); +} + +bool DesktopAndCursorComposer::IsOccluded(const DesktopVector& pos) { + return desktop_capturer_->IsOccluded(pos); +} + +#if defined(WEBRTC_USE_GIO) +DesktopCaptureMetadata DesktopAndCursorComposer::GetMetadata() { + return desktop_capturer_->GetMetadata(); +} +#endif // defined(WEBRTC_USE_GIO) + +void DesktopAndCursorComposer::OnFrameCaptureStart() { + callback_->OnFrameCaptureStart(); +} + +void DesktopAndCursorComposer::OnCaptureResult( + DesktopCapturer::Result result, + std::unique_ptr frame) { + if (frame && cursor_) { + if (!frame->may_contain_cursor() && + frame->rect().Contains(cursor_position_) && + !desktop_capturer_->IsOccluded(cursor_position_)) { + DesktopVector relative_position = + cursor_position_.subtract(frame->top_left()); +#if defined(WEBRTC_MAC) || defined(CHROMEOS) + // On OSX, the logical(DIP) and physical coordinates are used mixingly. + // For example, the captured cursor has its size in physical pixels(2x) + // and location in logical(DIP) pixels on Retina monitor. This will cause + // problem when the desktop is mixed with Retina and non-Retina monitors. + // So we use DIP pixel for all location info and compensate with the scale + // factor of current frame to the `relative_position`. + const float scale = frame->scale_factor(); + relative_position.set(relative_position.x() * scale, + relative_position.y() * scale); +#endif + auto frame_with_cursor = std::make_unique( + std::move(frame), *cursor_, relative_position, previous_cursor_rect_, + cursor_changed_); + previous_cursor_rect_ = frame_with_cursor->cursor_rect(); + cursor_changed_ = false; + frame = std::move(frame_with_cursor); + frame->set_may_contain_cursor(true); + } + } + + callback_->OnCaptureResult(result, std::move(frame)); +} + +void DesktopAndCursorComposer::OnMouseCursor(MouseCursor* cursor) { + cursor_changed_ = true; + cursor_.reset(cursor); +} + +void DesktopAndCursorComposer::OnMouseCursorPosition( + const DesktopVector& position) { + cursor_position_ = position; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.h b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.h new file mode 100644 index 0000000000..28ea25c8c9 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013 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_DESKTOP_AND_CURSOR_COMPOSER_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_ + +#include +#if defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_metadata.h" +#endif // defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/mouse_cursor.h" +#include "modules/desktop_capture/mouse_cursor_monitor.h" +#include "modules/desktop_capture/shared_memory.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// A wrapper for DesktopCapturer that also captures mouse using specified +// MouseCursorMonitor and renders it on the generated streams. +class RTC_EXPORT DesktopAndCursorComposer + : public DesktopCapturer, + public DesktopCapturer::Callback, + public MouseCursorMonitor::Callback { + public: + // Creates a new composer that captures mouse cursor using + // MouseCursorMonitor::Create(options) and renders it into the frames + // generated by `desktop_capturer`. + DesktopAndCursorComposer(std::unique_ptr desktop_capturer, + const DesktopCaptureOptions& options); + + ~DesktopAndCursorComposer() override; + + DesktopAndCursorComposer(const DesktopAndCursorComposer&) = delete; + DesktopAndCursorComposer& operator=(const DesktopAndCursorComposer&) = delete; + + // Creates a new composer that relies on an external source for cursor shape + // and position information via the MouseCursorMonitor::Callback interface. + static std::unique_ptr + CreateWithoutMouseCursorMonitor( + std::unique_ptr desktop_capturer); + + // DesktopCapturer interface. + void Start(DesktopCapturer::Callback* callback) override; + void SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) override; + void CaptureFrame() override; + void SetExcludedWindow(WindowId window) override; + bool GetSourceList(SourceList* sources) override; + bool SelectSource(SourceId id) override; + bool FocusOnSelectedSource() override; + bool IsOccluded(const DesktopVector& pos) override; + void SetMaxFrameRate(uint32_t max_frame_rate) override; +#if defined(WEBRTC_USE_GIO) + DesktopCaptureMetadata GetMetadata() override; +#endif // defined(WEBRTC_USE_GIO) + + // MouseCursorMonitor::Callback interface. + void OnMouseCursor(MouseCursor* cursor) override; + void OnMouseCursorPosition(const DesktopVector& position) override; + + private: + // Allows test cases to use a fake MouseCursorMonitor implementation. + friend class DesktopAndCursorComposerTest; + + // Constructor to delegate both deprecated and new constructors and allows + // test cases to use a fake MouseCursorMonitor implementation. + DesktopAndCursorComposer(DesktopCapturer* desktop_capturer, + MouseCursorMonitor* mouse_monitor); + + // DesktopCapturer::Callback interface. + void OnFrameCaptureStart() override; + void OnCaptureResult(DesktopCapturer::Result result, + std::unique_ptr frame) override; + + const std::unique_ptr desktop_capturer_; + const std::unique_ptr mouse_monitor_; + + DesktopCapturer::Callback* callback_; + + std::unique_ptr cursor_; + DesktopVector cursor_position_; + DesktopRect previous_cursor_rect_; + bool cursor_changed_ = false; +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_AND_CURSOR_COMPOSER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc new file mode 100644 index 0000000000..179e002bc5 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2013 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/desktop_and_cursor_composer.h" + +#include +#include + +#include +#include +#include + +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/mouse_cursor.h" +#include "modules/desktop_capture/shared_desktop_frame.h" +#include "rtc_base/arraysize.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { + +namespace { + +using testing::ElementsAre; + +const int kFrameXCoord = 100; +const int kFrameYCoord = 200; +const int kScreenWidth = 100; +const int kScreenHeight = 100; +const int kCursorWidth = 10; +const int kCursorHeight = 10; + +const int kTestCursorSize = 3; +const uint32_t kTestCursorData[kTestCursorSize][kTestCursorSize] = { + { + 0xffffffff, + 0x99990000, + 0xaa222222, + }, + { + 0x88008800, + 0xaa0000aa, + 0xaa333333, + }, + { + 0x00000000, + 0xaa0000aa, + 0xaa333333, + }, +}; + +uint32_t GetFakeFramePixelValue(const DesktopVector& p) { + uint32_t r = 100 + p.x(); + uint32_t g = 100 + p.y(); + uint32_t b = 100 + p.x() + p.y(); + return b + (g << 8) + (r << 16) + 0xff000000; +} + +uint32_t GetFramePixel(const DesktopFrame& frame, const DesktopVector& pos) { + return *reinterpret_cast(frame.GetFrameDataAtPos(pos)); +} + +// Blends two pixel values taking into account alpha. +uint32_t BlendPixels(uint32_t dest, uint32_t src) { + uint8_t alpha = 255 - ((src & 0xff000000) >> 24); + uint32_t r = + ((dest & 0x00ff0000) >> 16) * alpha / 255 + ((src & 0x00ff0000) >> 16); + uint32_t g = + ((dest & 0x0000ff00) >> 8) * alpha / 255 + ((src & 0x0000ff00) >> 8); + uint32_t b = (dest & 0x000000ff) * alpha / 255 + (src & 0x000000ff); + return b + (g << 8) + (r << 16) + 0xff000000; +} + +DesktopFrame* CreateTestFrame(int width = kScreenWidth, + int height = kScreenHeight) { + DesktopFrame* frame = new BasicDesktopFrame(DesktopSize(width, height)); + uint32_t* data = reinterpret_cast(frame->data()); + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + *(data++) = GetFakeFramePixelValue(DesktopVector(x, y)); + } + } + return frame; +} + +MouseCursor* CreateTestCursor(DesktopVector hotspot) { + std::unique_ptr image( + new BasicDesktopFrame(DesktopSize(kCursorWidth, kCursorHeight))); + uint32_t* data = reinterpret_cast(image->data()); + // Set four pixels near the hotspot and leave all other blank. + for (int y = 0; y < kTestCursorSize; ++y) { + for (int x = 0; x < kTestCursorSize; ++x) { + data[(hotspot.y() + y) * kCursorWidth + (hotspot.x() + x)] = + kTestCursorData[y][x]; + } + } + return new MouseCursor(image.release(), hotspot); +} + +class FakeScreenCapturer : public DesktopCapturer { + public: + FakeScreenCapturer() {} + + void Start(Callback* callback) override { callback_ = callback; } + + void CaptureFrame() override { + callback_->OnCaptureResult( + next_frame_ ? Result::SUCCESS : Result::ERROR_TEMPORARY, + std::move(next_frame_)); + } + + void SetNextFrame(std::unique_ptr next_frame) { + next_frame_ = std::move(next_frame); + } + + bool IsOccluded(const DesktopVector& pos) override { return is_occluded_; } + + void set_is_occluded(bool value) { is_occluded_ = value; } + + private: + Callback* callback_ = nullptr; + + std::unique_ptr next_frame_; + bool is_occluded_ = false; +}; + +class FakeMouseMonitor : public MouseCursorMonitor { + public: + FakeMouseMonitor() : changed_(true) {} + + void SetState(CursorState state, const DesktopVector& pos) { + state_ = state; + position_ = pos; + } + + void SetHotspot(const DesktopVector& hotspot) { + if (!hotspot_.equals(hotspot)) + changed_ = true; + hotspot_ = hotspot; + } + + void Init(Callback* callback, Mode mode) override { callback_ = callback; } + + void Capture() override { + if (changed_) { + callback_->OnMouseCursor(CreateTestCursor(hotspot_)); + } + callback_->OnMouseCursorPosition(position_); + } + + private: + Callback* callback_; + CursorState state_; + DesktopVector position_; + DesktopVector hotspot_; + bool changed_; +}; + +void VerifyFrame(const DesktopFrame& frame, + MouseCursorMonitor::CursorState state, + const DesktopVector& pos) { + // Verify that all other pixels are set to their original values. + DesktopRect image_rect = + DesktopRect::MakeWH(kTestCursorSize, kTestCursorSize); + image_rect.Translate(pos); + + for (int y = 0; y < kScreenHeight; ++y) { + for (int x = 0; x < kScreenWidth; ++x) { + DesktopVector p(x, y); + if (state == MouseCursorMonitor::INSIDE && image_rect.Contains(p)) { + EXPECT_EQ(BlendPixels(GetFakeFramePixelValue(p), + kTestCursorData[y - pos.y()][x - pos.x()]), + GetFramePixel(frame, p)); + } else { + EXPECT_EQ(GetFakeFramePixelValue(p), GetFramePixel(frame, p)); + } + } + } +} + +} // namespace + +bool operator==(const DesktopRect& left, const DesktopRect& right) { + return left.equals(right); +} + +std::ostream& operator<<(std::ostream& out, const DesktopRect& rect) { + out << "{" << rect.left() << "+" << rect.top() << "-" << rect.width() << "x" + << rect.height() << "}"; + return out; +} + +class DesktopAndCursorComposerTest : public ::testing::Test, + public DesktopCapturer::Callback { + public: + explicit DesktopAndCursorComposerTest(bool include_cursor = true) + : fake_screen_(new FakeScreenCapturer()), + fake_cursor_(include_cursor ? new FakeMouseMonitor() : nullptr), + blender_(fake_screen_, fake_cursor_) { + blender_.Start(this); + } + + // DesktopCapturer::Callback interface + void OnCaptureResult(DesktopCapturer::Result result, + std::unique_ptr frame) override { + frame_ = std::move(frame); + } + + protected: + // Owned by `blender_`. + FakeScreenCapturer* fake_screen_; + FakeMouseMonitor* fake_cursor_; + + DesktopAndCursorComposer blender_; + std::unique_ptr frame_; +}; + +class DesktopAndCursorComposerNoCursorMonitorTest + : public DesktopAndCursorComposerTest { + public: + DesktopAndCursorComposerNoCursorMonitorTest() + : DesktopAndCursorComposerTest(false) {} +}; + +TEST_F(DesktopAndCursorComposerTest, CursorShouldBeIgnoredIfNoFrameCaptured) { + struct { + int x, y; + int hotspot_x, hotspot_y; + bool inside; + } tests[] = { + {0, 0, 0, 0, true}, {50, 50, 0, 0, true}, {100, 50, 0, 0, true}, + {50, 100, 0, 0, true}, {100, 100, 0, 0, true}, {0, 0, 2, 5, true}, + {1, 1, 2, 5, true}, {50, 50, 2, 5, true}, {100, 100, 2, 5, true}, + {0, 0, 5, 2, true}, {50, 50, 5, 2, true}, {100, 100, 5, 2, true}, + {0, 0, 0, 0, false}, + }; + + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(i); + + DesktopVector hotspot(tests[i].hotspot_x, tests[i].hotspot_y); + fake_cursor_->SetHotspot(hotspot); + + MouseCursorMonitor::CursorState state = tests[i].inside + ? MouseCursorMonitor::INSIDE + : MouseCursorMonitor::OUTSIDE; + DesktopVector pos(tests[i].x, tests[i].y); + fake_cursor_->SetState(state, pos); + + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + + blender_.CaptureFrame(); + // If capturer captured nothing, then cursor should be ignored, not matter + // its state or position. + EXPECT_EQ(frame_, nullptr); + } +} + +TEST_F(DesktopAndCursorComposerTest, CursorShouldBeIgnoredIfFrameMayContainIt) { + // We can't use a shared frame because we need to detect modifications + // compared to a control. + std::unique_ptr control_frame(CreateTestFrame()); + control_frame->set_top_left(DesktopVector(kFrameXCoord, kFrameYCoord)); + + struct { + int x; + int y; + bool may_contain_cursor; + } tests[] = { + {100, 200, true}, + {100, 200, false}, + {150, 250, true}, + {150, 250, false}, + }; + + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(i); + + std::unique_ptr frame(CreateTestFrame()); + frame->set_top_left(DesktopVector(kFrameXCoord, kFrameYCoord)); + frame->set_may_contain_cursor(tests[i].may_contain_cursor); + fake_screen_->SetNextFrame(std::move(frame)); + + const DesktopVector abs_pos(tests[i].x, tests[i].y); + fake_cursor_->SetState(MouseCursorMonitor::INSIDE, abs_pos); + blender_.CaptureFrame(); + + // If the frame may already have contained the cursor, then `CaptureFrame()` + // should not have modified it, so it should be the same as the control. + EXPECT_TRUE(frame_); + const DesktopVector rel_pos(abs_pos.subtract(control_frame->top_left())); + if (tests[i].may_contain_cursor) { + EXPECT_EQ( + *reinterpret_cast(frame_->GetFrameDataAtPos(rel_pos)), + *reinterpret_cast( + control_frame->GetFrameDataAtPos(rel_pos))); + + } else { + // `CaptureFrame()` should have modified the frame to have the cursor. + EXPECT_NE( + *reinterpret_cast(frame_->GetFrameDataAtPos(rel_pos)), + *reinterpret_cast( + control_frame->GetFrameDataAtPos(rel_pos))); + EXPECT_TRUE(frame_->may_contain_cursor()); + } + } +} + +TEST_F(DesktopAndCursorComposerTest, + CursorShouldBeIgnoredIfItIsOutOfDesktopFrame) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + frame->set_top_left(DesktopVector(kFrameXCoord, kFrameYCoord)); + // The frame covers (100, 200) - (200, 300). + + struct { + int x; + int y; + } tests[] = { + {0, 0}, {50, 50}, {50, 150}, {100, 150}, {50, 200}, + {99, 200}, {100, 199}, {200, 300}, {200, 299}, {199, 300}, + {-1, -1}, {-10000, -10000}, {10000, 10000}, + }; + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(i); + + fake_screen_->SetNextFrame(frame->Share()); + // The CursorState is ignored when using absolute cursor position. + fake_cursor_->SetState(MouseCursorMonitor::OUTSIDE, + DesktopVector(tests[i].x, tests[i].y)); + blender_.CaptureFrame(); + VerifyFrame(*frame_, MouseCursorMonitor::OUTSIDE, DesktopVector(0, 0)); + } +} + +TEST_F(DesktopAndCursorComposerTest, IsOccludedShouldBeConsidered) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + frame->set_top_left(DesktopVector(kFrameXCoord, kFrameYCoord)); + // The frame covers (100, 200) - (200, 300). + + struct { + int x; + int y; + } tests[] = { + {100, 200}, {101, 200}, {100, 201}, {101, 201}, {150, 250}, {199, 299}, + }; + fake_screen_->set_is_occluded(true); + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(i); + + fake_screen_->SetNextFrame(frame->Share()); + // The CursorState is ignored when using absolute cursor position. + fake_cursor_->SetState(MouseCursorMonitor::OUTSIDE, + DesktopVector(tests[i].x, tests[i].y)); + blender_.CaptureFrame(); + VerifyFrame(*frame_, MouseCursorMonitor::OUTSIDE, DesktopVector()); + } +} + +TEST_F(DesktopAndCursorComposerTest, CursorIncluded) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + frame->set_top_left(DesktopVector(kFrameXCoord, kFrameYCoord)); + // The frame covers (100, 200) - (200, 300). + + struct { + int x; + int y; + } tests[] = { + {100, 200}, {101, 200}, {100, 201}, {101, 201}, {150, 250}, {199, 299}, + }; + for (size_t i = 0; i < arraysize(tests); i++) { + SCOPED_TRACE(i); + + const DesktopVector abs_pos(tests[i].x, tests[i].y); + const DesktopVector rel_pos(abs_pos.subtract(frame->top_left())); + + fake_screen_->SetNextFrame(frame->Share()); + // The CursorState is ignored when using absolute cursor position. + fake_cursor_->SetState(MouseCursorMonitor::OUTSIDE, abs_pos); + blender_.CaptureFrame(); + VerifyFrame(*frame_, MouseCursorMonitor::INSIDE, rel_pos); + + // Verify that the cursor is erased before the frame buffer is returned to + // the screen capturer. + frame_.reset(); + VerifyFrame(*frame, MouseCursorMonitor::OUTSIDE, DesktopVector()); + } +} + +TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, + UpdatedRegionIncludesOldAndNewCursorRectsIfMoved) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + DesktopRect first_cursor_rect; + { + // Block to scope test_cursor, which is invalidated by OnMouseCursor. + MouseCursor* test_cursor = CreateTestCursor(DesktopVector(0, 0)); + first_cursor_rect = DesktopRect::MakeSize(test_cursor->image()->size()); + blender_.OnMouseCursor(test_cursor); + } + blender_.OnMouseCursorPosition(DesktopVector(0, 0)); + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + + DesktopVector cursor_move_offset(1, 1); + DesktopRect second_cursor_rect = first_cursor_rect; + second_cursor_rect.Translate(cursor_move_offset); + blender_.OnMouseCursorPosition(cursor_move_offset); + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + + EXPECT_TRUE(frame->updated_region().is_empty()); + DesktopRegion expected_region; + expected_region.AddRect(first_cursor_rect); + expected_region.AddRect(second_cursor_rect); + EXPECT_TRUE(frame_->updated_region().Equals(expected_region)); +} + +TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, + UpdatedRegionIncludesOldAndNewCursorRectsIfShapeChanged) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + DesktopRect first_cursor_rect; + { + // Block to scope test_cursor, which is invalidated by OnMouseCursor. + MouseCursor* test_cursor = CreateTestCursor(DesktopVector(0, 0)); + first_cursor_rect = DesktopRect::MakeSize(test_cursor->image()->size()); + blender_.OnMouseCursor(test_cursor); + } + blender_.OnMouseCursorPosition(DesktopVector(0, 0)); + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + + // Create a second cursor, the same shape as the first. Since the code doesn't + // compare the cursor pixels, this is sufficient, and avoids needing two test + // cursor bitmaps. + DesktopRect second_cursor_rect; + { + MouseCursor* test_cursor = CreateTestCursor(DesktopVector(0, 0)); + second_cursor_rect = DesktopRect::MakeSize(test_cursor->image()->size()); + blender_.OnMouseCursor(test_cursor); + } + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + + EXPECT_TRUE(frame->updated_region().is_empty()); + DesktopRegion expected_region; + expected_region.AddRect(first_cursor_rect); + expected_region.AddRect(second_cursor_rect); + EXPECT_TRUE(frame_->updated_region().Equals(expected_region)); +} + +TEST_F(DesktopAndCursorComposerNoCursorMonitorTest, + UpdatedRegionUnchangedIfCursorUnchanged) { + std::unique_ptr frame( + SharedDesktopFrame::Wrap(CreateTestFrame())); + blender_.OnMouseCursor(CreateTestCursor(DesktopVector(0, 0))); + blender_.OnMouseCursorPosition(DesktopVector(0, 0)); + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + fake_screen_->SetNextFrame(frame->Share()); + blender_.CaptureFrame(); + + EXPECT_TRUE(frame->updated_region().is_empty()); + EXPECT_TRUE(frame_->updated_region().is_empty()); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_differ_sse2_gn/moz.build b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_differ_sse2_gn/moz.build new file mode 100644 index 0000000000..e02d815614 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_differ_sse2_gn/moz.build @@ -0,0 +1,156 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + + ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ### + ### DO NOT edit it by hand. ### + +COMPILE_FLAGS["OS_INCLUDES"] = [] +AllowCompilerWarnings() + +DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1" +DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True +DEFINES["RTC_ENABLE_VP9"] = True +DEFINES["WEBRTC_ENABLE_AVX2"] = True +DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0" +DEFINES["WEBRTC_LIBRARY_IMPL"] = True +DEFINES["WEBRTC_MOZILLA_BUILD"] = True +DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0" +DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0" + +FINAL_LIBRARY = "webrtc" + + +LOCAL_INCLUDES += [ + "!/ipc/ipdl/_ipdlheaders", + "!/third_party/libwebrtc/gen", + "/ipc/chromium/src", + "/third_party/libwebrtc/", + "/third_party/libwebrtc/third_party/abseil-cpp/", + "/tools/profiler/public" +] + +UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/differ_vector_sse2.cc" +] + +if not CONFIG["MOZ_DEBUG"]: + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0" + DEFINES["NDEBUG"] = True + DEFINES["NVALGRIND"] = True + +if CONFIG["MOZ_DEBUG"] == "1": + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1" + +if CONFIG["OS_TARGET"] == "Darwin": + + CXXFLAGS += [ + "-msse2" + ] + + DEFINES["WEBRTC_MAC"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True + DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0" + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_AURA"] = "1" + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_NSS_CERTS"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_UDEV"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_GNU_SOURCE"] = True + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "OpenBSD": + + CXXFLAGS += [ + "-msse2" + ] + + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_BSD"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True + DEFINES["NOMINMAX"] = True + DEFINES["NTDDI_VERSION"] = "0x0A000000" + DEFINES["PSAPI_VERSION"] = "2" + DEFINES["RTC_ENABLE_WIN_WGC"] = True + DEFINES["UNICODE"] = True + DEFINES["USE_AURA"] = "1" + DEFINES["WEBRTC_WIN"] = True + DEFINES["WIN32"] = True + DEFINES["WIN32_LEAN_AND_MEAN"] = True + DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP" + DEFINES["WINVER"] = "0x0A00" + DEFINES["_ATL_NO_OPENGL"] = True + DEFINES["_CRT_RAND_S"] = True + DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True + DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True + DEFINES["_HAS_EXCEPTIONS"] = "0" + DEFINES["_HAS_NODISCARD"] = True + DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True + DEFINES["_SECURE_ATL"] = True + DEFINES["_UNICODE"] = True + DEFINES["_WIN32_WINNT"] = "0x0A00" + DEFINES["_WINDOWS"] = True + DEFINES["__STD_C"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0" + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_X11"] = "1" + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86": + + CXXFLAGS += [ + "-msse2", + "-msse2" + ] + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86_64": + + CXXFLAGS += [ + "-msse2" + ] + +Library("desktop_capture_differ_sse2_gn") diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_gn/moz.build b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_gn/moz.build new file mode 100644 index 0000000000..3f0146acbf --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_gn/moz.build @@ -0,0 +1,679 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + + ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ### + ### DO NOT edit it by hand. ### +if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": + CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"] + +COMPILE_FLAGS["OS_INCLUDES"] = [] +AllowCompilerWarnings() + +DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1" +DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True +DEFINES["RTC_ENABLE_VP9"] = True +DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0" +DEFINES["WEBRTC_LIBRARY_IMPL"] = True +DEFINES["WEBRTC_MOZILLA_BUILD"] = True +DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0" +DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0" + +FINAL_LIBRARY = "webrtc" + + +LOCAL_INCLUDES += [ + "!/ipc/ipdl/_ipdlheaders", + "!/third_party/libwebrtc/gen", + "/ipc/chromium/src", + "/media/libyuv/", + "/media/libyuv/libyuv/include/", + "/third_party/libwebrtc/", + "/third_party/libwebrtc/third_party/abseil-cpp/", + "/tools/profiler/public" +] + +SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/fallback_desktop_capturer_wrapper.cc" +] + +UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc", + "/third_party/libwebrtc/modules/desktop_capture/cropped_desktop_frame.cc", + "/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_and_cursor_composer.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_wrapper.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_frame_generator.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_frame_rotation.cc", + "/third_party/libwebrtc/modules/desktop_capture/differ_block.cc", + "/third_party/libwebrtc/modules/desktop_capture/fake_desktop_capturer.cc", + "/third_party/libwebrtc/modules/desktop_capture/full_screen_application_handler.cc", + "/third_party/libwebrtc/modules/desktop_capture/full_screen_window_detector.cc", + "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor.cc", + "/third_party/libwebrtc/modules/desktop_capture/resolution_tracker.cc", + "/third_party/libwebrtc/modules/desktop_capture/rgba_color.cc", + "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_helper.cc", + "/third_party/libwebrtc/modules/desktop_capture/window_finder.cc" +] + +if not CONFIG["MOZ_DEBUG"]: + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0" + DEFINES["NDEBUG"] = True + DEFINES["NVALGRIND"] = True + +if CONFIG["MOZ_DEBUG"] == "1": + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1" + +if CONFIG["OS_TARGET"] == "Darwin": + + DEFINES["WEBRTC_MAC"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True + DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0" + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration_monitor.cc", + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/mac/full_screen_mac_application_handler.cc", + "/third_party/libwebrtc/modules/desktop_capture/mac/window_list_utils.cc" + ] + +if CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_AURA"] = "1" + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_NSS_CERTS"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_UDEV"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + + OS_LIBS += [ + "rt" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc", + "/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc" + ] + +if CONFIG["OS_TARGET"] == "OpenBSD": + + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_BSD"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["WEBRTC_USE_X11"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc", + "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc", + "/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc" + ] + +if CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True + DEFINES["NOMINMAX"] = True + DEFINES["NTDDI_VERSION"] = "0x0A000000" + DEFINES["PSAPI_VERSION"] = "2" + DEFINES["RTC_ENABLE_WIN_WGC"] = True + DEFINES["UNICODE"] = True + DEFINES["USE_AURA"] = "1" + DEFINES["WEBRTC_WIN"] = True + DEFINES["WIN32"] = True + DEFINES["WIN32_LEAN_AND_MEAN"] = True + DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP" + DEFINES["WINVER"] = "0x0A00" + DEFINES["_ATL_NO_OPENGL"] = True + DEFINES["_CRT_RAND_S"] = True + DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True + DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True + DEFINES["_HAS_EXCEPTIONS"] = "0" + DEFINES["_HAS_NODISCARD"] = True + DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True + DEFINES["_SECURE_ATL"] = True + DEFINES["_UNICODE"] = True + DEFINES["_WIN32_WINNT"] = "0x0A00" + DEFINES["_WINDOWS"] = True + DEFINES["__STD_C"] = True + + OS_LIBS += [ + "crypt32", + "d3d11", + "dwmapi", + "dxgi", + "iphlpapi", + "secur32", + "shcore", + "winmm" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/cropping_window_capturer_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/desktop_frame_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/cursor.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/d3d_device.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/desktop.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/desktop_capture_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/display_configuration_monitor.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_adapter_duplicator.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_context.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_duplicator_controller.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_frame.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_mapping.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/dxgi_texture_staging.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/full_screen_win_application_handler.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/scoped_thread_desktop.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/screen_capture_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/selected_window_context.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_session.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/wgc_capture_source.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/wgc_capturer_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/wgc_desktop_frame.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/window_capture_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/win/window_capturer_win_gdi.cc", + "/third_party/libwebrtc/modules/desktop_capture/window_capturer_win.cc", + "/third_party/libwebrtc/modules/desktop_capture/window_finder_win.cc" + ] + +if CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["WEBRTC_ARCH_ARM64"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["TARGET_CPU"] == "arm": + + CXXFLAGS += [ + "-mfpu=neon" + ] + + DEFINES["WEBRTC_ARCH_ARM"] = True + DEFINES["WEBRTC_ARCH_ARM_V7"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["TARGET_CPU"] == "mips32": + + DEFINES["MIPS32_LE"] = True + DEFINES["MIPS_FPU_LE"] = True + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["TARGET_CPU"] == "mips64": + + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["TARGET_CPU"] == "ppc64": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["TARGET_CPU"] == "x86": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +if CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0" + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "riscv64": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86": + + CXXFLAGS += [ + "-msse2" + ] + + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["WEBRTC_USE_PIPEWIRE"] = True + DEFINES["_GNU_SOURCE"] = True + + LOCAL_INCLUDES += [ + "/gfx/angle/checkout/include/", + "/third_party/drm/drm/", + "/third_party/drm/drm/include/", + "/third_party/drm/drm/include/libdrm/", + "/third_party/gbm/gbm/", + "/third_party/libepoxy/libepoxy/include/", + "/third_party/pipewire/" + ] + + SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/egl_dmabuf.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/mouse_cursor_monitor_pipewire.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/restore_token_manager.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screen_capture_portal_interface.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_portal.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/screencast_stream_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "arm": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "mips32": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "mips64": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_USE_X11"] = True + + OS_LIBS += [ + "X11", + "Xcomposite", + "Xdamage", + "Xext", + "Xfixes", + "Xrandr", + "Xrender" + ] + + UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/mouse_cursor_monitor_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/screen_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/shared_x_display.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_capturer_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_finder_x11.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/window_list_utils.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_atom_cache.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_error_trap.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_server_pixel_buffer.cc", + "/third_party/libwebrtc/modules/desktop_capture/linux/x11/x_window_property.cc" + ] + +Library("desktop_capture_gn") diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metadata.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metadata.h new file mode 100644 index 0000000000..49a20e729c --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metadata.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 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_DESKTOP_CAPTURE_METADATA_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_METADATA_H_ + +#if defined(WEBRTC_USE_GIO) +#include "modules/portal/xdg_session_details.h" +#endif // defined(WEBRTC_USE_GIO) + +namespace webrtc { + +// Container for the metadata associated with a desktop capturer. +struct DesktopCaptureMetadata { +#if defined(WEBRTC_USE_GIO) + // Details about the XDG desktop session handle (used by wayland + // implementation in remoting) + xdg_portal::SessionDetails session_details; +#endif // defined(WEBRTC_USE_GIO) +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_METADATA_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc new file mode 100644 index 0000000000..9f20b56c35 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 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/desktop_capture_metrics_helper.h" + +#include "modules/desktop_capture/desktop_capture_types.h" +#include "system_wrappers/include/metrics.h" + +namespace webrtc { +namespace { +// This enum is logged via UMA so entries should not be reordered or have their +// values changed. This should also be kept in sync with the values in the +// DesktopCapturerId namespace. +enum class SequentialDesktopCapturerId { + kUnknown = 0, + kWgcCapturerWin = 1, + // kScreenCapturerWinMagnifier = 2, + kWindowCapturerWinGdi = 3, + kScreenCapturerWinGdi = 4, + kScreenCapturerWinDirectx = 5, + kMaxValue = kScreenCapturerWinDirectx +}; +} // namespace + +void RecordCapturerImpl(uint32_t capturer_id) { + SequentialDesktopCapturerId sequential_id; + switch (capturer_id) { + case DesktopCapturerId::kWgcCapturerWin: + sequential_id = SequentialDesktopCapturerId::kWgcCapturerWin; + break; + case DesktopCapturerId::kWindowCapturerWinGdi: + sequential_id = SequentialDesktopCapturerId::kWindowCapturerWinGdi; + break; + case DesktopCapturerId::kScreenCapturerWinGdi: + sequential_id = SequentialDesktopCapturerId::kScreenCapturerWinGdi; + break; + case DesktopCapturerId::kScreenCapturerWinDirectx: + sequential_id = SequentialDesktopCapturerId::kScreenCapturerWinDirectx; + break; + case DesktopCapturerId::kUnknown: + default: + sequential_id = SequentialDesktopCapturerId::kUnknown; + } + RTC_HISTOGRAM_ENUMERATION( + "WebRTC.DesktopCapture.Win.DesktopCapturerImpl", + static_cast(sequential_id), + static_cast(SequentialDesktopCapturerId::kMaxValue)); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.h new file mode 100644 index 0000000000..37542b84bb --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_metrics_helper.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 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_DESKTOP_CAPTURE_METRICS_HELPER_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_METRICS_HELPER_H_ + +#include + +namespace webrtc { + +void RecordCapturerImpl(uint32_t capturer_id); + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_METRICS_HELPER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_objc_gn/moz.build b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_objc_gn/moz.build new file mode 100644 index 0000000000..3b34c0cc8b --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_objc_gn/moz.build @@ -0,0 +1,77 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + + ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ### + ### DO NOT edit it by hand. ### + +CMMFLAGS += [ + "-fobjc-arc" +] + +COMPILE_FLAGS["OS_INCLUDES"] = [] +AllowCompilerWarnings() + +DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1" +DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True +DEFINES["RTC_ENABLE_VP9"] = True +DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0" +DEFINES["WEBRTC_LIBRARY_IMPL"] = True +DEFINES["WEBRTC_MAC"] = True +DEFINES["WEBRTC_MOZILLA_BUILD"] = True +DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0" +DEFINES["WEBRTC_POSIX"] = True +DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0" +DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True +DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0" +DEFINES["__STDC_CONSTANT_MACROS"] = True +DEFINES["__STDC_FORMAT_MACROS"] = True + +FINAL_LIBRARY = "webrtc" + + +LOCAL_INCLUDES += [ + "!/ipc/ipdl/_ipdlheaders", + "!/third_party/libwebrtc/gen", + "/ipc/chromium/src", + "/third_party/libwebrtc/", + "/third_party/libwebrtc/sdk/objc/", + "/third_party/libwebrtc/sdk/objc/base/", + "/third_party/libwebrtc/third_party/abseil-cpp/", + "/tools/profiler/public" +] + +UNIFIED_SOURCES += [ + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_configuration.mm", + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_cgimage.mm", + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_iosurface.mm", + "/third_party/libwebrtc/modules/desktop_capture/mac/desktop_frame_provider.mm", + "/third_party/libwebrtc/modules/desktop_capture/mac/screen_capturer_mac.mm", + "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_mac.mm", + "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_darwin.mm", + "/third_party/libwebrtc/modules/desktop_capture/window_capturer_mac.mm", + "/third_party/libwebrtc/modules/desktop_capture/window_finder_mac.mm" +] + +if not CONFIG["MOZ_DEBUG"]: + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0" + DEFINES["NDEBUG"] = True + DEFINES["NVALGRIND"] = True + +if CONFIG["MOZ_DEBUG"] == "1": + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1" + DEFINES["_DEBUG"] = True + +if CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["WEBRTC_ARCH_ARM64"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +Library("desktop_capture_objc_gn") diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc new file mode 100644 index 0000000000..22c59ef4cc --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013 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/desktop_capture_options.h" + +#include "api/make_ref_counted.h" + +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) +#include "modules/desktop_capture/mac/full_screen_mac_application_handler.h" +#elif defined(WEBRTC_WIN) +#include "modules/desktop_capture/win/full_screen_win_application_handler.h" +#endif +#if defined(WEBRTC_USE_PIPEWIRE) +#include "modules/desktop_capture/linux/wayland/shared_screencast_stream.h" +#endif + +namespace webrtc { + +DesktopCaptureOptions::DesktopCaptureOptions() {} +DesktopCaptureOptions::DesktopCaptureOptions( + const DesktopCaptureOptions& options) = default; +DesktopCaptureOptions::DesktopCaptureOptions(DesktopCaptureOptions&& options) = + default; +DesktopCaptureOptions::~DesktopCaptureOptions() {} + +DesktopCaptureOptions& DesktopCaptureOptions::operator=( + const DesktopCaptureOptions& options) = default; +DesktopCaptureOptions& DesktopCaptureOptions::operator=( + DesktopCaptureOptions&& options) = default; + +// static +DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() { + DesktopCaptureOptions result; +#if defined(WEBRTC_USE_X11) + result.set_x_display(SharedXDisplay::CreateDefault()); +#endif +#if defined(WEBRTC_USE_PIPEWIRE) + result.set_screencast_stream(SharedScreenCastStream::CreateDefault()); +#endif +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) + result.set_configuration_monitor( + rtc::make_ref_counted()); + result.set_full_screen_window_detector( + rtc::make_ref_counted( + CreateFullScreenMacApplicationHandler)); +#elif defined(WEBRTC_WIN) + result.set_full_screen_window_detector( + rtc::make_ref_counted( + CreateFullScreenWinApplicationHandler)); +#endif + return result; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h new file mode 100644 index 0000000000..ee823d296f --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2013 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_DESKTOP_CAPTURE_OPTIONS_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ + +#include "api/scoped_refptr.h" +#include "rtc_base/system/rtc_export.h" + +#if defined(WEBRTC_USE_X11) +#include "modules/desktop_capture/linux/x11/shared_x_display.h" +#endif + +#if defined(WEBRTC_USE_PIPEWIRE) +#include "modules/desktop_capture/linux/wayland/shared_screencast_stream.h" +#endif + +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) +#include "modules/desktop_capture/mac/desktop_configuration_monitor.h" +#endif + +#include "modules/desktop_capture/full_screen_window_detector.h" + +namespace webrtc { + +// An object that stores initialization parameters for screen and window +// capturers. +class RTC_EXPORT DesktopCaptureOptions { + public: + // Returns instance of DesktopCaptureOptions with default parameters. On Linux + // also initializes X window connection. x_display() will be set to null if + // X11 connection failed (e.g. DISPLAY isn't set). + static DesktopCaptureOptions CreateDefault(); + + DesktopCaptureOptions(); + DesktopCaptureOptions(const DesktopCaptureOptions& options); + DesktopCaptureOptions(DesktopCaptureOptions&& options); + ~DesktopCaptureOptions(); + + DesktopCaptureOptions& operator=(const DesktopCaptureOptions& options); + DesktopCaptureOptions& operator=(DesktopCaptureOptions&& options); + +#if defined(WEBRTC_USE_X11) + const rtc::scoped_refptr& x_display() const { + return x_display_; + } + void set_x_display(rtc::scoped_refptr x_display) { + x_display_ = x_display; + } +#endif + +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) + // TODO(zijiehe): Remove both DesktopConfigurationMonitor and + // FullScreenChromeWindowDetector out of DesktopCaptureOptions. It's not + // reasonable for external consumers to set these two parameters. + const rtc::scoped_refptr& configuration_monitor() + const { + return configuration_monitor_; + } + // If nullptr is set, ScreenCapturer won't work and WindowCapturer may return + // inaccurate result from IsOccluded() function. + void set_configuration_monitor( + rtc::scoped_refptr m) { + configuration_monitor_ = m; + } + + bool allow_iosurface() const { return allow_iosurface_; } + void set_allow_iosurface(bool allow) { allow_iosurface_ = allow; } +#endif + + const rtc::scoped_refptr& + full_screen_window_detector() const { + return full_screen_window_detector_; + } + void set_full_screen_window_detector( + rtc::scoped_refptr detector) { + full_screen_window_detector_ = detector; + } + + // Flag indicating that the capturer should use screen change notifications. + // Enables/disables use of XDAMAGE in the X11 capturer. + bool use_update_notifications() const { return use_update_notifications_; } + void set_use_update_notifications(bool use_update_notifications) { + use_update_notifications_ = use_update_notifications; + } + + // Flag indicating if desktop effects (e.g. Aero) should be disabled when the + // capturer is active. Currently used only on Windows. + bool disable_effects() const { return disable_effects_; } + void set_disable_effects(bool disable_effects) { + disable_effects_ = disable_effects; + } + + // Flag that should be set if the consumer uses updated_region() and the + // capturer should try to provide correct updated_region() for the frames it + // generates (e.g. by comparing each frame with the previous one). + bool detect_updated_region() const { return detect_updated_region_; } + void set_detect_updated_region(bool detect_updated_region) { + detect_updated_region_ = detect_updated_region; + } + + // Indicates that the capturer should try to include the cursor in the frame. + // If it is able to do so it will set `DesktopFrame::may_contain_cursor()`. + // Not all capturers will support including the cursor. If this value is false + // or the cursor otherwise cannot be included in the frame, then cursor + // metadata will be sent, though the capturer may choose to always send cursor + // metadata. + bool prefer_cursor_embedded() const { return prefer_cursor_embedded_; } + void set_prefer_cursor_embedded(bool prefer_cursor_embedded) { + prefer_cursor_embedded_ = prefer_cursor_embedded; + } + +#if defined(WEBRTC_WIN) + // Enumerating windows owned by the current process on Windows has some + // complications due to |GetWindowText*()| APIs potentially causing a + // deadlock (see the comments in the `GetWindowListHandler()` function in + // window_capture_utils.cc for more details on the deadlock). + // To avoid this issue, consumers can either ensure that the thread that runs + // their message loop never waits on `GetSourceList()`, or they can set this + // flag to false which will prevent windows running in the current process + // from being enumerated and included in the results. Consumers can still + // provide the WindowId for their own windows to `SelectSource()` and capture + // them. + bool enumerate_current_process_windows() const { + return enumerate_current_process_windows_; + } + void set_enumerate_current_process_windows( + bool enumerate_current_process_windows) { + enumerate_current_process_windows_ = enumerate_current_process_windows; + } + + // Allowing directx based capturer or not, this capturer works on windows 7 + // with platform update / windows 8 or upper. + bool allow_directx_capturer() const { return allow_directx_capturer_; } + void set_allow_directx_capturer(bool enabled) { + allow_directx_capturer_ = enabled; + } + + // Flag that may be set to allow use of the cropping window capturer (which + // captures the screen & crops that to the window region in some cases). An + // advantage of using this is significantly higher capture frame rates than + // capturing the window directly. A disadvantage of using this is the + // possibility of capturing unrelated content (e.g. overlapping windows that + // aren't detected properly, or neighboring regions when moving/resizing the + // captured window). Note: this flag influences the behavior of calls to + // DesktopCapturer::CreateWindowCapturer; calls to + // CroppingWindowCapturer::CreateCapturer ignore the flag (treat it as true). + bool allow_cropping_window_capturer() const { + return allow_cropping_window_capturer_; + } + void set_allow_cropping_window_capturer(bool allow) { + allow_cropping_window_capturer_ = allow; + } + +#if defined(RTC_ENABLE_WIN_WGC) + // This flag enables the WGC capturer for capturing the screen. + // This capturer should offer similar or better performance than the cropping + // capturer without the disadvantages listed above. However, the WGC capturer + // is only available on Windows 10 version 1809 (Redstone 5) and up. This flag + // will have no affect on older versions. + // If set, and running a supported version of Win10, this flag will take + // precedence over the cropping, directx, and magnification flags. + bool allow_wgc_screen_capturer() const { return allow_wgc_screen_capturer_; } + void set_allow_wgc_screen_capturer(bool allow) { + allow_wgc_screen_capturer_ = allow; + } + + // This flag has the same effect as allow_wgc_screen_capturer but it only + // enables or disables WGC for window capturing (not screen). + bool allow_wgc_window_capturer() const { return allow_wgc_window_capturer_; } + void set_allow_wgc_window_capturer(bool allow) { + allow_wgc_window_capturer_ = allow; + } + + // This flag enables the WGC capturer for fallback capturer. + // The flag is useful when the first capturer (eg. WindowCapturerWinGdi) is + // unreliable in certain devices where WGC is supported, but not used by + // default. + bool allow_wgc_capturer_fallback() const { + return allow_wgc_capturer_fallback_; + } + void set_allow_wgc_capturer_fallback(bool allow) { + allow_wgc_capturer_fallback_ = allow; + } + + // This flag enables 0Hz mode in combination with the WGC capturer. + // The flag has no effect if the allow_wgc_capturer flag is false. + bool allow_wgc_zero_hertz() const { return allow_wgc_zero_hertz_; } + void set_allow_wgc_zero_hertz(bool allow) { allow_wgc_zero_hertz_ = allow; } +#endif // defined(RTC_ENABLE_WIN_WGC) +#endif // defined(WEBRTC_WIN) + +#if defined(WEBRTC_USE_PIPEWIRE) + bool allow_pipewire() const { return allow_pipewire_; } + void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } + + const rtc::scoped_refptr& screencast_stream() const { + return screencast_stream_; + } + void set_screencast_stream( + rtc::scoped_refptr stream) { + screencast_stream_ = stream; + } + + void set_width(uint32_t width) { width_ = width; } + uint32_t get_width() const { return width_; } + + void set_height(uint32_t height) { height_ = height; } + uint32_t get_height() const { return height_; } + + void set_pipewire_use_damage_region(bool use_damage_regions) { + pipewire_use_damage_region_ = use_damage_regions; + } + bool pipewire_use_damage_region() const { + return pipewire_use_damage_region_; + } +#endif + + private: +#if defined(WEBRTC_USE_X11) + rtc::scoped_refptr x_display_; +#endif +#if defined(WEBRTC_USE_PIPEWIRE) + // An instance of shared PipeWire ScreenCast stream we share between + // BaseCapturerPipeWire and MouseCursorMonitorPipeWire as cursor information + // is sent together with screen content. + rtc::scoped_refptr screencast_stream_; +#endif +#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) + rtc::scoped_refptr configuration_monitor_; + bool allow_iosurface_ = false; +#endif + + rtc::scoped_refptr full_screen_window_detector_; + +#if defined(WEBRTC_WIN) + bool enumerate_current_process_windows_ = true; + bool allow_directx_capturer_ = false; + bool allow_cropping_window_capturer_ = false; +#if defined(RTC_ENABLE_WIN_WGC) + bool allow_wgc_screen_capturer_ = false; + bool allow_wgc_window_capturer_ = false; + bool allow_wgc_capturer_fallback_ = false; + bool allow_wgc_zero_hertz_ = false; +#endif +#endif +#if defined(WEBRTC_USE_X11) + bool use_update_notifications_ = false; +#else + bool use_update_notifications_ = true; +#endif + bool disable_effects_ = true; + bool detect_updated_region_ = false; + bool prefer_cursor_embedded_ = false; +#if defined(WEBRTC_USE_PIPEWIRE) + bool allow_pipewire_ = false; + bool pipewire_use_damage_region_ = true; + uint32_t width_ = 0; + uint32_t height_ = 0; +#endif +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_types.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_types.h new file mode 100644 index 0000000000..e777a45f92 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_types.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013 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_DESKTOP_CAPTURE_TYPES_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_TYPES_H_ + +#include + +#ifdef XP_WIN // Moving this into the global namespace +typedef int pid_t; // matching what used to be in +#endif // video_capture_defines.h + +namespace webrtc { + +enum class CaptureType { kWindow, kScreen, kAnyScreenContent }; + +// Type used to identify windows on the desktop. Values are platform-specific: +// - On Windows: HWND cast to intptr_t. +// - On Linux (with X11): X11 Window (unsigned long) type cast to intptr_t. +// - On OSX: integer window number. +typedef intptr_t WindowId; + +const WindowId kNullWindowId = 0; + +const int64_t kInvalidDisplayId = -1; + +// Type used to identify screens on the desktop. Values are platform-specific: +// - On Windows: integer display device index. +// - On OSX: CGDirectDisplayID cast to intptr_t. +// - On Linux (with X11): TBD. +// - On ChromeOS: display::Display::id() is an int64_t. +// On Windows, ScreenId is implementation dependent: sending a ScreenId from one +// implementation to another usually won't work correctly. +#if defined(CHROMEOS) +typedef int64_t ScreenId; +#else +typedef intptr_t ScreenId; +#endif + +// The screen id corresponds to all screen combined together. +const ScreenId kFullDesktopScreenId = -1; + +const ScreenId kInvalidScreenId = -2; + +// Integers to attach to each DesktopFrame to differentiate the generator of +// the frame. The entries in this namespace should remain in sync with the +// SequentialDesktopCapturerId enum, which is logged via UMA. +// `kScreenCapturerWinGdi` and `kScreenCapturerWinDirectx` values are preserved +// to maintain compatibility +namespace DesktopCapturerId { +constexpr uint32_t CreateFourCC(char a, char b, char c, char d) { + return ((static_cast(a)) | (static_cast(b) << 8) | + (static_cast(c) << 16) | (static_cast(d) << 24)); +} + +constexpr uint32_t kUnknown = 0; +constexpr uint32_t kWgcCapturerWin = 1; +constexpr uint32_t kScreenCapturerWinMagnifier = 2; +constexpr uint32_t kWindowCapturerWinGdi = 3; +constexpr uint32_t kScreenCapturerWinGdi = CreateFourCC('G', 'D', 'I', ' '); +constexpr uint32_t kScreenCapturerWinDirectx = CreateFourCC('D', 'X', 'G', 'I'); +constexpr uint32_t kX11CapturerLinux = CreateFourCC('X', '1', '1', ' '); +constexpr uint32_t kWaylandCapturerLinux = CreateFourCC('W', 'L', ' ', ' '); +} // namespace DesktopCapturerId + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_TYPES_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.cc new file mode 100644 index 0000000000..a52a76c262 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.cc @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2016 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/desktop_capturer.h" + +#include +#include + +#include +#include + +#include "modules/desktop_capture/cropping_window_capturer.h" +#include "modules/desktop_capture/desktop_capture_options.h" +#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" +#include "system_wrappers/include/metrics.h" + +#if defined(RTC_ENABLE_WIN_WGC) +#include "modules/desktop_capture/win/wgc_capturer_win.h" +#include "rtc_base/win/windows_version.h" +#endif // defined(RTC_ENABLE_WIN_WGC) + +#if defined(WEBRTC_USE_PIPEWIRE) +#include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" +#endif + +namespace webrtc { + +void LogDesktopCapturerFullscreenDetectorUsage() { + RTC_HISTOGRAM_BOOLEAN("WebRTC.Screenshare.DesktopCapturerFullscreenDetector", + true); +} + +DesktopCapturer::~DesktopCapturer() = default; + +DelegatedSourceListController* +DesktopCapturer::GetDelegatedSourceListController() { + return nullptr; +} + +void DesktopCapturer::SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) {} + +void DesktopCapturer::SetExcludedWindow(WindowId window) {} + +bool DesktopCapturer::GetSourceList(SourceList* sources) { + return true; +} + +bool DesktopCapturer::SelectSource(SourceId id) { + return false; +} + +bool DesktopCapturer::FocusOnSelectedSource() { + return false; +} + +bool DesktopCapturer::IsOccluded(const DesktopVector& pos) { + return false; +} + +// static +std::unique_ptr DesktopCapturer::CreateWindowCapturer( + const DesktopCaptureOptions& options) { +#if defined(RTC_ENABLE_WIN_WGC) + if (options.allow_wgc_window_capturer() && + IsWgcSupported(CaptureType::kWindow)) { + return WgcCapturerWin::CreateRawWindowCapturer(options); + } +#endif // defined(RTC_ENABLE_WIN_WGC) + +#if defined(WEBRTC_WIN) + if (options.allow_cropping_window_capturer()) { + return CroppingWindowCapturer::CreateCapturer(options); + } +#endif // defined(WEBRTC_WIN) + + std::unique_ptr capturer = CreateRawWindowCapturer(options); + if (capturer && options.detect_updated_region()) { + capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); + } + + return capturer; +} + +// static +std::unique_ptr DesktopCapturer::CreateScreenCapturer( + const DesktopCaptureOptions& options) { +#if defined(RTC_ENABLE_WIN_WGC) + if (options.allow_wgc_screen_capturer() && + IsWgcSupported(CaptureType::kScreen)) { + return WgcCapturerWin::CreateRawScreenCapturer(options); + } +#endif // defined(RTC_ENABLE_WIN_WGC) + + std::unique_ptr capturer = CreateRawScreenCapturer(options); + if (capturer && options.detect_updated_region()) { + capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); + } + + return capturer; +} + +// static +std::unique_ptr DesktopCapturer::CreateGenericCapturer( + const DesktopCaptureOptions& options) { + std::unique_ptr capturer; + +#if defined(WEBRTC_USE_PIPEWIRE) + if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { + capturer = std::make_unique( + options, CaptureType::kAnyScreenContent); + } + + if (capturer && options.detect_updated_region()) { + capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); + } +#endif // defined(WEBRTC_USE_PIPEWIRE) + + return capturer; +} + +#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) +bool DesktopCapturer::IsRunningUnderWayland() { + const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); + if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0) + return false; + + if (!(getenv("WAYLAND_DISPLAY"))) + return false; + + return true; +} +#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.h new file mode 100644 index 0000000000..2c9c419bcd --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2013 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_DESKTOP_CAPTURER_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ + +#include +#include + +#include +#include +#include +#include + +// TODO(alcooper): Update include usage in downstream consumers and then change +// this to a forward declaration. +#include "modules/desktop_capture/delegated_source_list_controller.h" +#if defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_metadata.h" +#endif // defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/shared_memory.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +void RTC_EXPORT LogDesktopCapturerFullscreenDetectorUsage(); + +class DesktopCaptureOptions; +class DesktopFrame; + +// Abstract interface for screen and window capturers. +class RTC_EXPORT DesktopCapturer { + public: + enum class Result { + // The frame was captured successfully. + SUCCESS, + + // There was a temporary error. The caller should continue calling + // CaptureFrame(), in the expectation that it will eventually recover. + ERROR_TEMPORARY, + + // Capture has failed and will keep failing if the caller tries calling + // CaptureFrame() again. + ERROR_PERMANENT, + + MAX_VALUE = ERROR_PERMANENT + }; + + // Interface that must be implemented by the DesktopCapturer consumers. + class Callback { + public: + // Called before a frame capture is started. + virtual void OnFrameCaptureStart() {} + + // Called after a frame has been captured. `frame` is not nullptr if and + // only if `result` is SUCCESS. + virtual void OnCaptureResult(Result result, + std::unique_ptr frame) = 0; + + protected: + virtual ~Callback() {} + }; + +#if defined(CHROMEOS) + typedef int64_t SourceId; +#else + typedef intptr_t SourceId; +#endif + + static_assert(std::is_same::value, + "SourceId should be a same type as ScreenId."); + + struct Source { + // The unique id to represent a Source of current DesktopCapturer. + SourceId id; + pid_t pid; + + // Title of the window or screen in UTF-8 encoding, maybe empty. This field + // should not be used to identify a source. + std::string title; + +#if defined(CHROMEOS) + // TODO(https://crbug.com/1369162): Remove or refactor this value. + WindowId in_process_id = kNullWindowId; +#endif + + // The display's unique ID. If no ID is defined, it will hold the value + // kInvalidDisplayId. + int64_t display_id = kInvalidDisplayId; + }; + + typedef std::vector SourceList; + + virtual ~DesktopCapturer(); + + // Called at the beginning of a capturing session. `callback` must remain + // valid until capturer is destroyed. + virtual void Start(Callback* callback) = 0; + + // Sets max frame rate for the capturer. This is best effort and may not be + // supported by all capturers. This will only affect the frequency at which + // new frames are available, not the frequency at which you are allowed to + // capture the frames. + virtual void SetMaxFrameRate(uint32_t max_frame_rate) {} + + // Returns a valid pointer if the capturer requires the user to make a + // selection from a source list provided by the capturer. + // Returns nullptr if the capturer does not provide a UI for the user to make + // a selection. + // + // Callers should not take ownership of the returned pointer, but it is + // guaranteed to be valid as long as the desktop_capturer is valid. + // Note that consumers should still use GetSourceList and SelectSource, but + // their behavior may be modified if this returns a value. See those methods + // for a more in-depth discussion of those potential modifications. + virtual DelegatedSourceListController* GetDelegatedSourceListController(); + + // Sets SharedMemoryFactory that will be used to create buffers for the + // captured frames. The factory can be invoked on a thread other than the one + // where CaptureFrame() is called. It will be destroyed on the same thread. + // Shared memory is currently supported only by some DesktopCapturer + // implementations. + virtual void SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory); + + // Captures next frame, and involve callback provided by Start() function. + // Pending capture requests are canceled when DesktopCapturer is deleted. + virtual void CaptureFrame() = 0; + + // Sets the window to be excluded from the captured image in the future + // Capture calls. Used to exclude the screenshare notification window for + // screen capturing. + virtual void SetExcludedWindow(WindowId window); + + // TODO(zijiehe): Following functions should be pure virtual. The default + // implementations are for backward compatibility only. Remove default + // implementations once all DesktopCapturer implementations in Chromium have + // implemented these functions. + + // Gets a list of sources current capturer supports. Returns false in case of + // a failure. + // For DesktopCapturer implementations to capture screens, this function + // should return monitors. + // For DesktopCapturer implementations to capture windows, this function + // should only return root windows owned by applications. + // + // Note that capturers who use a delegated source list will return a + // SourceList with exactly one value, but it may not be viable for capture + // (e.g. CaptureFrame will return ERROR_TEMPORARY) until a selection has been + // made. + virtual bool GetSourceList(SourceList* sources); + + // Selects a source to be captured. Returns false in case of a failure (e.g. + // if there is no source with the specified type and id.) + // + // Note that some capturers with delegated source lists may also support + // selecting a SourceID that is not in the returned source list as a form of + // restore token. + virtual bool SelectSource(SourceId id); + + // Brings the selected source to the front and sets the input focus on it. + // Returns false in case of a failure or no source has been selected or the + // implementation does not support this functionality. + virtual bool FocusOnSelectedSource(); + + // Returns true if the `pos` on the selected source is covered by other + // elements on the display, and is not visible to the users. + // `pos` is in full desktop coordinates, i.e. the top-left monitor always + // starts from (0, 0). + // The return value if `pos` is out of the scope of the source is undefined. + virtual bool IsOccluded(const DesktopVector& pos); + + // Creates a DesktopCapturer instance which targets to capture windows. + static std::unique_ptr CreateWindowCapturer( + const DesktopCaptureOptions& options); + + // Creates a DesktopCapturer instance which targets to capture screens. + static std::unique_ptr CreateScreenCapturer( + const DesktopCaptureOptions& options); + + // Creates a DesktopCapturer instance which targets to capture windows and + // screens. + static std::unique_ptr CreateGenericCapturer( + const DesktopCaptureOptions& options); + +#if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + static bool IsRunningUnderWayland(); + + virtual void UpdateResolution(uint32_t width, uint32_t height) {} +#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) + +#if defined(WEBRTC_USE_GIO) + // Populates implementation specific metadata into the passed in pointer. + // Classes can choose to override it or use the default no-op implementation. + virtual DesktopCaptureMetadata GetMetadata() { return {}; } +#endif // defined(WEBRTC_USE_GIO) + + protected: + // CroppingWindowCapturer needs to create raw capturers without wrappers, so + // the following two functions are protected. + + // Creates a platform specific DesktopCapturer instance which targets to + // capture windows. + static std::unique_ptr CreateRawWindowCapturer( + const DesktopCaptureOptions& options); + + // Creates a platform specific DesktopCapturer instance which targets to + // capture screens. + static std::unique_ptr CreateRawScreenCapturer( + const DesktopCaptureOptions& options); +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc new file mode 100644 index 0000000000..77543e4060 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.cc @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2016 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/desktop_capturer_differ_wrapper.h" + +#include +#include + +#include + +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/desktop_region.h" +#include "modules/desktop_capture/differ_block.h" +#include "rtc_base/checks.h" +#include "rtc_base/time_utils.h" + +namespace webrtc { + +namespace { + +// Returns true if (0, 0) - (`width`, `height`) vector in `old_buffer` and +// `new_buffer` are equal. `width` should be less than 32 +// (defined by kBlockSize), otherwise BlockDifference() should be used. +bool PartialBlockDifference(const uint8_t* old_buffer, + const uint8_t* new_buffer, + int width, + int height, + int stride) { + RTC_DCHECK_LT(width, kBlockSize); + const int width_bytes = width * DesktopFrame::kBytesPerPixel; + for (int i = 0; i < height; i++) { + if (memcmp(old_buffer, new_buffer, width_bytes) != 0) { + return true; + } + old_buffer += stride; + new_buffer += stride; + } + return false; +} + +// Compares columns in the range of [`left`, `right`), in a row in the +// range of [`top`, `top` + `height`), starts from `old_buffer` and +// `new_buffer`, and outputs updated regions into `output`. `stride` is the +// DesktopFrame::stride(). +void CompareRow(const uint8_t* old_buffer, + const uint8_t* new_buffer, + const int left, + const int right, + const int top, + const int bottom, + const int stride, + DesktopRegion* const output) { + const int block_x_offset = kBlockSize * DesktopFrame::kBytesPerPixel; + const int width = right - left; + const int height = bottom - top; + const int block_count = (width - 1) / kBlockSize; + const int last_block_width = width - block_count * kBlockSize; + RTC_DCHECK_GT(last_block_width, 0); + RTC_DCHECK_LE(last_block_width, kBlockSize); + + // The first block-column in a continuous dirty area in current block-row. + int first_dirty_x_block = -1; + + // We always need to add dirty area into `output` in the last block, so handle + // it separatedly. + for (int x = 0; x < block_count; x++) { + if (BlockDifference(old_buffer, new_buffer, height, stride)) { + if (first_dirty_x_block == -1) { + // This is the first dirty block in a continuous dirty area. + first_dirty_x_block = x; + } + } else if (first_dirty_x_block != -1) { + // The block on the left is the last dirty block in a continuous + // dirty area. + output->AddRect( + DesktopRect::MakeLTRB(first_dirty_x_block * kBlockSize + left, top, + x * kBlockSize + left, bottom)); + first_dirty_x_block = -1; + } + old_buffer += block_x_offset; + new_buffer += block_x_offset; + } + + bool last_block_diff; + if (last_block_width < kBlockSize) { + // The last one is a partial vector. + last_block_diff = PartialBlockDifference(old_buffer, new_buffer, + last_block_width, height, stride); + } else { + last_block_diff = BlockDifference(old_buffer, new_buffer, height, stride); + } + if (last_block_diff) { + if (first_dirty_x_block == -1) { + first_dirty_x_block = block_count; + } + output->AddRect(DesktopRect::MakeLTRB( + first_dirty_x_block * kBlockSize + left, top, right, bottom)); + } else if (first_dirty_x_block != -1) { + output->AddRect( + DesktopRect::MakeLTRB(first_dirty_x_block * kBlockSize + left, top, + block_count * kBlockSize + left, bottom)); + } +} + +// Compares `rect` area in `old_frame` and `new_frame`, and outputs dirty +// regions into `output`. +void CompareFrames(const DesktopFrame& old_frame, + const DesktopFrame& new_frame, + DesktopRect rect, + DesktopRegion* const output) { + RTC_DCHECK(old_frame.size().equals(new_frame.size())); + RTC_DCHECK_EQ(old_frame.stride(), new_frame.stride()); + rect.IntersectWith(DesktopRect::MakeSize(old_frame.size())); + + const int y_block_count = (rect.height() - 1) / kBlockSize; + const int last_y_block_height = rect.height() - y_block_count * kBlockSize; + // Offset from the start of one block-row to the next. + const int block_y_stride = old_frame.stride() * kBlockSize; + const uint8_t* prev_block_row_start = + old_frame.GetFrameDataAtPos(rect.top_left()); + const uint8_t* curr_block_row_start = + new_frame.GetFrameDataAtPos(rect.top_left()); + + int top = rect.top(); + // The last row may have a different height, so we handle it separately. + for (int y = 0; y < y_block_count; y++) { + CompareRow(prev_block_row_start, curr_block_row_start, rect.left(), + rect.right(), top, top + kBlockSize, old_frame.stride(), output); + top += kBlockSize; + prev_block_row_start += block_y_stride; + curr_block_row_start += block_y_stride; + } + CompareRow(prev_block_row_start, curr_block_row_start, rect.left(), + rect.right(), top, top + last_y_block_height, old_frame.stride(), + output); +} + +} // namespace + +DesktopCapturerDifferWrapper::DesktopCapturerDifferWrapper( + std::unique_ptr base_capturer) + : base_capturer_(std::move(base_capturer)) { + RTC_DCHECK(base_capturer_); +} + +DesktopCapturerDifferWrapper::~DesktopCapturerDifferWrapper() {} + +void DesktopCapturerDifferWrapper::Start(DesktopCapturer::Callback* callback) { + callback_ = callback; + base_capturer_->Start(this); +} + +void DesktopCapturerDifferWrapper::SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) { + base_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory)); +} + +void DesktopCapturerDifferWrapper::CaptureFrame() { + base_capturer_->CaptureFrame(); +} + +void DesktopCapturerDifferWrapper::SetExcludedWindow(WindowId window) { + base_capturer_->SetExcludedWindow(window); +} + +bool DesktopCapturerDifferWrapper::GetSourceList(SourceList* sources) { + return base_capturer_->GetSourceList(sources); +} + +bool DesktopCapturerDifferWrapper::SelectSource(SourceId id) { + return base_capturer_->SelectSource(id); +} + +bool DesktopCapturerDifferWrapper::FocusOnSelectedSource() { + return base_capturer_->FocusOnSelectedSource(); +} + +bool DesktopCapturerDifferWrapper::IsOccluded(const DesktopVector& pos) { + return base_capturer_->IsOccluded(pos); +} + +#if defined(WEBRTC_USE_GIO) +DesktopCaptureMetadata DesktopCapturerDifferWrapper::GetMetadata() { + return base_capturer_->GetMetadata(); +} +#endif // defined(WEBRTC_USE_GIO) + +void DesktopCapturerDifferWrapper::OnCaptureResult( + Result result, + std::unique_ptr input_frame) { + int64_t start_time_nanos = rtc::TimeNanos(); + if (!input_frame) { + callback_->OnCaptureResult(result, nullptr); + return; + } + RTC_DCHECK(result == Result::SUCCESS); + + std::unique_ptr frame = + SharedDesktopFrame::Wrap(std::move(input_frame)); + if (last_frame_ && (last_frame_->size().width() != frame->size().width() || + last_frame_->size().height() != frame->size().height() || + last_frame_->stride() != frame->stride())) { + last_frame_.reset(); + } + + if (last_frame_) { + DesktopRegion hints; + hints.Swap(frame->mutable_updated_region()); + for (DesktopRegion::Iterator it(hints); !it.IsAtEnd(); it.Advance()) { + CompareFrames(*last_frame_, *frame, it.rect(), + frame->mutable_updated_region()); + } + } else { + frame->mutable_updated_region()->SetRect( + DesktopRect::MakeSize(frame->size())); + } + last_frame_ = frame->Share(); + + frame->set_capture_time_ms(frame->capture_time_ms() + + (rtc::TimeNanos() - start_time_nanos) / + rtc::kNumNanosecsPerMillisec); + callback_->OnCaptureResult(result, std::move(frame)); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h new file mode 100644 index 0000000000..6ebb5d7bc3 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 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_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ +#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ + +#include +#if defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_metadata.h" +#endif // defined(WEBRTC_USE_GIO) +#include "modules/desktop_capture/desktop_capture_types.h" +#include "modules/desktop_capture/desktop_capturer.h" +#include "modules/desktop_capture/desktop_frame.h" +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/shared_desktop_frame.h" +#include "modules/desktop_capture/shared_memory.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// DesktopCapturer wrapper that calculates updated_region() by comparing frames +// content. This class always expects the underlying DesktopCapturer +// implementation returns a superset of updated regions in DestkopFrame. If a +// DesktopCapturer implementation does not know the updated region, it should +// set updated_region() to full frame. +// +// This class marks entire frame as updated if the frame size or frame stride +// has been changed. +class RTC_EXPORT DesktopCapturerDifferWrapper + : public DesktopCapturer, + public DesktopCapturer::Callback { + public: + // Creates a DesktopCapturerDifferWrapper with a DesktopCapturer + // implementation, and takes its ownership. + explicit DesktopCapturerDifferWrapper( + std::unique_ptr base_capturer); + + ~DesktopCapturerDifferWrapper() override; + + // DesktopCapturer interface. + void Start(DesktopCapturer::Callback* callback) override; + void SetSharedMemoryFactory( + std::unique_ptr shared_memory_factory) override; + void CaptureFrame() override; + void SetExcludedWindow(WindowId window) override; + bool GetSourceList(SourceList* screens) override; + bool SelectSource(SourceId id) override; + bool FocusOnSelectedSource() override; + bool IsOccluded(const DesktopVector& pos) override; +#if defined(WEBRTC_USE_GIO) + DesktopCaptureMetadata GetMetadata() override; +#endif // defined(WEBRTC_USE_GIO) + private: + // DesktopCapturer::Callback interface. + void OnCaptureResult(Result result, + std::unique_ptr frame) override; + + const std::unique_ptr base_capturer_; + DesktopCapturer::Callback* callback_; + std::unique_ptr last_frame_; +}; + +} // namespace webrtc + +#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_DIFFER_WRAPPER_H_ diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper_unittest.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper_unittest.cc new file mode 100644 index 0000000000..9ccef3cc10 --- /dev/null +++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capturer_differ_wrapper_unittest.cc @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2016 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/desktop_capturer_differ_wrapper.h" + +#include +#include +#include +#include + +#include "modules/desktop_capture/desktop_geometry.h" +#include "modules/desktop_capture/desktop_region.h" +#include "modules/desktop_capture/differ_block.h" +#include "modules/desktop_capture/fake_desktop_capturer.h" +#include "modules/desktop_capture/mock_desktop_capturer_callback.h" +#include "rtc_base/random.h" +#include "rtc_base/time_utils.h" +#include "system_wrappers/include/cpu_features_wrapper.h" +#include "test/gtest.h" + +namespace webrtc { + +namespace { + +// Compares and asserts `frame`.updated_region() equals to `rects`. This +// function does not care about the order of the `rects` and it does not expect +// DesktopRegion to return an exact area for each rectangle in `rects`. +template