Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 1 | // Copyright 2018 The Chromium OS Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef MEDIA_PERCEPTION_MOJO_CONNECTOR_H_ |
| 6 | #define MEDIA_PERCEPTION_MOJO_CONNECTOR_H_ |
| 7 | |
Luke Sorenson | 13e2827 | 2018-11-09 14:43:16 -0500 | [diff] [blame] | 8 | #include <map> |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 9 | #include <memory> |
| 10 | #include <string> |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 11 | #include <vector> |
| 12 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 13 | #include <base/bind.h> |
| 14 | #include <base/single_thread_task_runner.h> |
| 15 | #include <base/threading/thread.h> |
Qijiang Fan | cbd3de1 | 2019-12-06 16:52:15 +0900 | [diff] [blame] | 16 | #include <mojo/core/embedder/scoped_ipc_support.h> |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 17 | #include <mojo/public/cpp/bindings/binding.h> |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 18 | |
Luke Sorenson | 523b292 | 2018-12-26 11:09:53 -0500 | [diff] [blame] | 19 | #include "media_perception/chrome_audio_service_client.h" |
Luke Sorenson | 81a5fa0 | 2018-10-29 16:36:16 -0400 | [diff] [blame] | 20 | #include "media_perception/device_management.pb.h" |
Luke Sorenson | d7e058f | 2018-09-12 11:33:16 -0400 | [diff] [blame] | 21 | #include "media_perception/media_perception_service_impl.h" |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 22 | #include "media_perception/producer_impl.h" |
Luke Sorenson | 9155956 | 2019-12-26 18:26:39 -0500 | [diff] [blame] | 23 | #include "media_perception/video_frame_handler_impl.h" |
Luke Sorenson | 13e2827 | 2018-11-09 14:43:16 -0500 | [diff] [blame] | 24 | #include "media_perception/rtanalytics.h" |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 25 | #include "media_perception/video_capture_service_client.h" |
Luke Sorenson | d7e058f | 2018-09-12 11:33:16 -0400 | [diff] [blame] | 26 | #include "mojom/media_perception_service.mojom.h" |
Qijiang Fan | b833a32 | 2020-05-26 02:15:32 +0900 | [diff] [blame^] | 27 | #include "mojom/video_source.mojom.h" |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 28 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 29 | namespace mri { |
| 30 | |
Hidehiko Abe | 3474edc | 2018-10-24 18:57:31 +0900 | [diff] [blame] | 31 | class MojoConnector { |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 32 | public: |
| 33 | MojoConnector(); |
| 34 | ~MojoConnector() {} |
| 35 | // Uses a file descriptor to establish a Mojo connection. |
| 36 | void ReceiveMojoInvitationFileDescriptor(int fd_int); |
| 37 | |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 38 | // Set a shared pointer member variable of the video capture service client |
| 39 | // object. |
| 40 | void SetVideoCaptureServiceClient( |
| 41 | std::shared_ptr<VideoCaptureServiceClient> video_capture_service_client); |
| 42 | |
Luke Sorenson | 523b292 | 2018-12-26 11:09:53 -0500 | [diff] [blame] | 43 | // Set a shared pointer member variable of the chrome audio service client |
| 44 | // object. |
| 45 | void SetChromeAudioServiceClient( |
| 46 | std::shared_ptr<ChromeAudioServiceClient> chrome_audio_service_client); |
| 47 | |
Luke Sorenson | 13e2827 | 2018-11-09 14:43:16 -0500 | [diff] [blame] | 48 | // Set a shared pointer member variable of the rtanalytics object. |
| 49 | void SetRtanalytics( |
| 50 | std::shared_ptr<Rtanalytics> rtanalytics); |
| 51 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 52 | // Use the Mojo connector to ensure the video capture servicec is started in |
| 53 | // Chrome and get access to the video capture service Mojo API. |
| 54 | void ConnectToVideoCaptureService(); |
| 55 | |
Brandon Mayer | facb67a | 2018-10-11 16:25:45 -0400 | [diff] [blame] | 56 | // Check the connection state. |
| 57 | bool IsConnectedToVideoCaptureService(); |
| 58 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 59 | // Get the list of video devices from the video capture service. |
| 60 | void GetDevices( |
| 61 | const VideoCaptureServiceClient::GetDevicesCallback& callback); |
| 62 | |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 63 | // Attempts to acquire access to a video device. |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 64 | void OpenDevice( |
| 65 | const std::string& device_id, |
Luke Sorenson | 6393cc8 | 2019-04-25 11:55:38 -0400 | [diff] [blame] | 66 | bool force_reopen_with_settings, |
Luke Sorenson | 9155956 | 2019-12-26 18:26:39 -0500 | [diff] [blame] | 67 | std::shared_ptr<VideoFrameHandlerImpl> video_frame_handler_impl, |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 68 | const VideoStreamParams& capture_format, |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 69 | const VideoCaptureServiceClient::OpenDeviceCallback& callback); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 70 | |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 71 | bool ActivateDevice(const std::string& device_id); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 72 | |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 73 | // Stops video capture on the specified active device. |
| 74 | void StopVideoCapture(const std::string& device_id); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 75 | |
| 76 | // Creates a new virtual device that frames can be fed into. |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 77 | void CreateVirtualDevice( |
Luke Sorenson | ef34f39 | 2018-09-26 15:00:55 -0400 | [diff] [blame] | 78 | const VideoDevice& video_device, |
| 79 | std::shared_ptr<ProducerImpl> producer_impl, |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 80 | const VideoCaptureServiceClient::VirtualDeviceCallback& callback); |
| 81 | |
Luke Sorenson | ef34f39 | 2018-09-26 15:00:55 -0400 | [diff] [blame] | 82 | void PushFrameToVirtualDevice(std::shared_ptr<ProducerImpl> producer_impl, |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 83 | base::TimeDelta timestamp, |
| 84 | std::unique_ptr<const uint8_t[]> data, |
| 85 | int data_size, PixelFormat pixel_format, |
| 86 | int frame_width, int frame_height); |
| 87 | |
| 88 | private: |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 89 | // Returns a string with an obfuscated device id based on a counter. |
| 90 | std::string GetObfuscatedDeviceId( |
| 91 | const std::string& device_id, |
| 92 | const std::string& display_name); |
| 93 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 94 | // Handler for when the Mojo connection is closed or errors out. |
| 95 | void OnConnectionErrorOrClosed(); |
| 96 | |
Brandon Mayer | facb67a | 2018-10-11 16:25:45 -0400 | [diff] [blame] | 97 | // Handler for when device pointer connection is closed or errors out. |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 98 | void OnVideoSourceProviderConnectionErrorOrClosed(); |
Brandon Mayer | facb67a | 2018-10-11 16:25:45 -0400 | [diff] [blame] | 99 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 100 | void AcceptConnectionOnIpcThread(base::ScopedFD fd); |
| 101 | |
| 102 | void ConnectToVideoCaptureServiceOnIpcThread(); |
| 103 | |
| 104 | void GetDevicesOnIpcThread( |
| 105 | const VideoCaptureServiceClient::GetDevicesCallback& callback); |
| 106 | |
| 107 | void OnDeviceInfosReceived( |
| 108 | const VideoCaptureServiceClient::GetDevicesCallback& callback, |
Hidehiko Abe | 31bb963 | 2018-11-23 02:49:56 +0900 | [diff] [blame] | 109 | std::vector<media::mojom::VideoCaptureDeviceInfoPtr> infos); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 110 | |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 111 | void OpenDeviceOnIpcThread( |
| 112 | const std::string& device_id, |
Luke Sorenson | 6393cc8 | 2019-04-25 11:55:38 -0400 | [diff] [blame] | 113 | bool force_reopen_with_settings, |
Luke Sorenson | 9155956 | 2019-12-26 18:26:39 -0500 | [diff] [blame] | 114 | std::shared_ptr<VideoFrameHandlerImpl> video_frame_handler_impl, |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 115 | const VideoStreamParams& capture_format, |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 116 | const VideoCaptureServiceClient::OpenDeviceCallback& callback); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 117 | |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 118 | void OnCreatePushSubscriptionCallback( |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 119 | const std::string& device_id, |
| 120 | const VideoCaptureServiceClient::OpenDeviceCallback& callback, |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 121 | video_capture::mojom::CreatePushSubscriptionResultCode code, |
| 122 | media::mojom::VideoCaptureParamsPtr settings_opened_with); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 123 | |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 124 | void StopVideoCaptureOnIpcThread(const std::string& device_id); |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 125 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 126 | void CreateVirtualDeviceOnIpcThread( |
Luke Sorenson | ef34f39 | 2018-09-26 15:00:55 -0400 | [diff] [blame] | 127 | const VideoDevice& video_device, |
| 128 | std::shared_ptr<ProducerImpl> producer_impl, |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 129 | const VideoCaptureServiceClient::VirtualDeviceCallback& callback); |
| 130 | |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 131 | void PushFrameToVirtualDeviceOnIpcThread( |
Luke Sorenson | ef34f39 | 2018-09-26 15:00:55 -0400 | [diff] [blame] | 132 | std::shared_ptr<ProducerImpl> producer_impl, base::TimeDelta timestamp, |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 133 | std::unique_ptr<const uint8_t[]> data, int data_size, |
| 134 | PixelFormat pixel_format, int frame_width, int frame_height); |
| 135 | |
| 136 | // Separate thread for doing IPC via Mojo because Mojo is asynchronous |
| 137 | // by default. |
| 138 | base::Thread ipc_thread_; |
| 139 | |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 140 | // Stores pointer to the video capture service client object. |
| 141 | std::shared_ptr<VideoCaptureServiceClient> video_capture_service_client_; |
| 142 | |
Luke Sorenson | 523b292 | 2018-12-26 11:09:53 -0500 | [diff] [blame] | 143 | // Stores pointer to the chrome audio service client object. |
| 144 | std::shared_ptr<ChromeAudioServiceClient> chrome_audio_service_client_; |
| 145 | |
Luke Sorenson | 13e2827 | 2018-11-09 14:43:16 -0500 | [diff] [blame] | 146 | // Stores pointer to the rtanalytics object. |
| 147 | std::shared_ptr<Rtanalytics> rtanalytics_; |
| 148 | |
Luke Sorenson | d7e058f | 2018-09-12 11:33:16 -0400 | [diff] [blame] | 149 | // Implementation for the media perception service Mojo interface. |
| 150 | std::unique_ptr<MediaPerceptionServiceImpl> media_perception_service_impl_; |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 151 | |
| 152 | // Entry point Mojo object for talking to the video capture service API. |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 153 | video_capture::mojom::VideoSourceProviderPtr video_source_provider_; |
| 154 | |
| 155 | struct VideoSourceAndPushSubscription { |
| 156 | video_capture::mojom::VideoSourcePtr video_source; |
| 157 | video_capture::mojom::PushVideoStreamSubscriptionPtr |
| 158 | push_video_stream_subscription; |
| 159 | }; |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 160 | |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 161 | // Store a map from device ids to active devices. |
| 162 | std::map<std::string /* obfuscated device_id */, |
Luke Sorenson | 813a108 | 2019-03-15 13:29:33 -0400 | [diff] [blame] | 163 | VideoSourceAndPushSubscription /* active_device */> |
Luke Sorenson | c3de601 | 2018-11-28 17:17:20 -0500 | [diff] [blame] | 164 | device_id_to_active_device_map_; |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 165 | |
Luke Sorenson | 3abab66 | 2018-10-31 15:21:26 -0400 | [diff] [blame] | 166 | int unique_device_counter_; |
| 167 | |
| 168 | // Maps unique ids for devices (device_id + display_name) to an obfuscated |
| 169 | // device id, which is generated by a counter. |
| 170 | std::map< |
| 171 | std::string /* device_id + display_name */, |
| 172 | std::string /* obfuscated device_id */> unique_id_map_; |
| 173 | |
| 174 | // Map to store obfuscated device ids and their associated real device ids. |
| 175 | // Makes it so that clients of the service do not know or need to know the |
| 176 | // real id of connected devices. |
| 177 | std::map< |
| 178 | std::string /* obfuscated device_id */, |
| 179 | std::string /* device_id */> obfuscated_device_id_map_; |
| 180 | |
Qijiang Fan | cbd3de1 | 2019-12-06 16:52:15 +0900 | [diff] [blame] | 181 | std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_; |
| 182 | |
Brandon Mayer | facb67a | 2018-10-11 16:25:45 -0400 | [diff] [blame] | 183 | std::mutex vcs_connection_state_mutex_; |
| 184 | bool is_connected_to_vcs_ = false; |
Luke Sorenson | 1261c43 | 2018-09-07 16:01:41 -0400 | [diff] [blame] | 185 | }; |
| 186 | |
| 187 | } // namespace mri |
| 188 | |
| 189 | #endif // MEDIA_PERCEPTION_MOJO_CONNECTOR_H_ |