1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <Buffer.h> 20 #include <DeviceAsWebcamServiceManager.h> 21 #include <FrameProvider.h> 22 #include <Utils.h> 23 #include <android-base/unique_fd.h> 24 #include <android/hardware_buffer.h> 25 #include <linux/usb/g_uvc.h> 26 #include <linux/usb/video.h> 27 #include <atomic> 28 #include <thread> 29 #include <vector> 30 #include <unordered_set> 31 32 namespace android { 33 namespace webcam { 34 35 typedef std::vector<struct epoll_event> Events; 36 37 using android::base::unique_fd; 38 39 class EpollW { 40 public: 41 Status init(); 42 Status add(int fd, uint32_t events); 43 Status modify(int fd, uint32_t events); 44 Status remove(int fd); 45 Events waitForEvents(); 46 47 private: 48 unique_fd mEpollFd; 49 }; 50 51 struct ConfigFrame { 52 uint32_t index = 0; 53 uint32_t width = 0; 54 uint32_t height = 0; 55 std::vector<uint32_t> intervals; 56 }; 57 58 struct ConfigFormat { 59 uint32_t formatIndex = 0; 60 uint32_t fcc; 61 std::vector<ConfigFrame> frames; 62 }; 63 64 struct ConfigEndPoint { 65 uint32_t streamingInterval = 0; 66 uint32_t streamingMaxPacketSize = 0; 67 uint32_t streamingMaxBurst = 0; 68 }; 69 70 struct ConfigStreaming { 71 ConfigEndPoint ep; 72 std::vector<ConfigFormat> formats; 73 uint32_t interfaceNumber = 0; 74 }; 75 76 struct UVCProperties { 77 std::string videoNode; 78 std::string udc; 79 ConfigStreaming streaming; 80 uint32_t controlInterfaceNumber = 0; 81 }; 82 83 // This struct has the information needed to uniquely identify a 'chosen' format : the format index 84 // which indexes into the format list advertised by the UVC V4L2 node, the frame index which indexes 85 // the frame size in the frame size list per format, and finally the frame interval for the 86 // particular format and size chosen. 87 struct FormatTriplet { 88 // Note: These are '1' indexed. 89 uint8_t formatIndex = 1; 90 uint8_t frameSizeIndex = 1; 91 uint32_t frameInterval = 0; FormatTripletFormatTriplet92 FormatTriplet(uint8_t formatIndex, uint8_t frameSizeIndex, uint32_t frameInterval) 93 : formatIndex(formatIndex), frameSizeIndex(frameSizeIndex), frameInterval(frameInterval) {} 94 }; 95 96 // This class manages all things related to UVC event handling. 97 class UVCProvider : public std::enable_shared_from_this<UVCProvider> { 98 public: 99 static std::string getVideoNode(const std::unordered_set<std::string>& ignoredNodes); 100 101 UVCProvider() = default; 102 ~UVCProvider(); 103 104 Status init(); 105 // Start listening for UVC events 106 Status startService(const std::unordered_set<std::string>& ignoredNodes); 107 108 void stopService(); 109 110 int encodeImage(AHardwareBuffer* hardwareBuffer, long timestamp, jint rotation); 111 112 void watchStreamEvent(); 113 114 private: 115 // Created after a UVC_SETUP event has been received and processed by UVCProvider 116 // This class manages stream related events UVC_STREAMON / STREAMOFF and queries by the host 117 // for probing and committing controls. 118 class UVCDevice : public BufferCreatorAndDestroyer { 119 public: 120 explicit UVCDevice(std::weak_ptr<UVCProvider> parent, 121 const std::unordered_set<std::string>& ignoredNodes); 122 ~UVCDevice() override = default; 123 void closeUVCFd(); 124 [[nodiscard]] bool isInited() const; getUVCFd()125 int getUVCFd() { return mUVCFd.get(); } getINotifyFd()126 int getINotifyFd() { return mINotifyFd.get(); } getCurrentVideoNode()127 const char* getCurrentVideoNode() { return mVideoNode.c_str(); } 128 void processSetupEvent(const struct usb_ctrlrequest* request, 129 struct uvc_request_data* response); 130 void processSetupControlEvent(const struct usb_ctrlrequest* request, 131 struct uvc_request_data* response); 132 void processSetupStreamingEvent(const struct usb_ctrlrequest* request, 133 struct uvc_request_data* response); 134 135 void processSetupClassEvent(const struct usb_ctrlrequest* request, 136 struct uvc_request_data* response); 137 void processDataEvent(const struct uvc_request_data*); 138 void processStreamOnEvent(); 139 void processStreamOffEvent(); 140 void processStreamEvent(); 141 Status encodeImage(AHardwareBuffer* buffer, long timestamp, int rotation); 142 143 // BufferCreatorAndDestroyer overrides 144 Status allocateAndMapBuffers( 145 std::shared_ptr<Buffer>* consumerBuffer, 146 std::vector<std::shared_ptr<Buffer>>* producerBuffers) override; 147 void destroyBuffers(std::shared_ptr<Buffer>& consumerBuffer, 148 std::vector<std::shared_ptr<Buffer>>& producerBuffers) override; 149 150 private: 151 std::shared_ptr<UVCProperties> parseUvcProperties(); 152 std::vector<ConfigFormat> getFormats(); 153 154 void getFrameIntervals(ConfigFrame* frame, ConfigFormat* format); 155 void getFormatFrames(ConfigFormat* format); 156 157 Status openV4L2DeviceAndSubscribe(const std::string& videoNode); 158 void setStreamingControl(struct uvc_streaming_control* streamingControl, 159 const FormatTriplet* req); 160 void commitControls(); 161 162 std::shared_ptr<Buffer> mapBuffer(uint32_t i); 163 static Status unmapBuffer(std::shared_ptr<Buffer>& buffer); 164 165 Status getFrameAndQueueBufferToGadgetDriver(bool firstBuffer = false); 166 167 struct uvc_streaming_control mProbe {}; 168 struct uvc_streaming_control mCommit {}; 169 uint8_t mCurrentControlState = UVC_VS_CONTROL_UNDEFINED; 170 std::weak_ptr<UVCProvider> mParent; 171 std::shared_ptr<UVCProperties> mUVCProperties; 172 std::shared_ptr<BufferManager> mBufferManager; 173 std::shared_ptr<FrameProvider> mFrameProvider; 174 175 unique_fd mUVCFd; 176 unique_fd mINotifyFd; 177 178 // Path to /dev/video*, this is the node we open up and poll the fd for uvc / v4l2 events. 179 std::string mVideoNode; 180 struct v4l2_format mV4l2Format {}; 181 uint32_t mFps = 0; 182 bool mInited = false; 183 }; 184 185 void stopAndWaitForUVCListenerThread(); 186 void startUVCListenerThread(); 187 void ListenToUVCFds(); 188 189 void processUVCEvent(); 190 // returns true if service is stopped. false otherwise. 191 bool processINotifyEvent(); 192 193 std::shared_ptr<UVCDevice> mUVCDevice; 194 std::thread mUVCListenerThread; 195 volatile bool mListenToUVCFds = true; 196 EpollW mEpollW; 197 }; 198 199 } // namespace webcam 200 } // namespace android 201