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