• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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