1 /*
2  * Copyright (C) 2022 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 #ifndef CPP_EVS_MANAGER_AIDL_INCLUDE_VIRTUALCAMERA_H
18 #define CPP_EVS_MANAGER_AIDL_INCLUDE_VIRTUALCAMERA_H
19 
20 #include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
21 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
22 #include <aidl/android/hardware/automotive/evs/CameraDesc.h>
23 #include <aidl/android/hardware/automotive/evs/CameraParam.h>
24 #include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
25 #include <aidl/android/hardware/automotive/evs/EvsResult.h>
26 #include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h>
27 #include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
28 #include <aidl/android/hardware/automotive/evs/ParameterRange.h>
29 #include <aidl/android/hardware/automotive/evs/Stream.h>
30 #include <android-base/thread_annotations.h>
31 
32 #include <condition_variable>
33 #include <deque>
34 #include <set>
35 #include <thread>  // NO_LINT
36 #include <unordered_map>
37 
38 namespace aidl::android::automotive::evs::implementation {
39 
40 namespace aidlevs = ::aidl::android::hardware::automotive::evs;
41 
42 class HalCamera;  // From HalCamera.h
43 
44 // This class represents an EVS camera to the client application.  As such it presents
45 // the IEvsCamera interface, and also proxies the frame delivery to the client's
46 // IEvsCameraStream object.
47 class VirtualCamera : public ::aidl::android::hardware::automotive::evs::BnEvsCamera {
48 public:
49     // Methods from ::android::hardware::automotive::evs::IEvsCamera follow.
50     ::ndk::ScopedAStatus doneWithFrame(const std::vector<aidlevs::BufferDesc>& buffers) override;
51     ::ndk::ScopedAStatus forcePrimaryClient(
52             const std::shared_ptr<aidlevs::IEvsDisplay>& display) override;
53     ::ndk::ScopedAStatus getCameraInfo(aidlevs::CameraDesc* _aidl_return) override;
54     ::ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier,
55                                          std::vector<uint8_t>* value) override;
56     ::ndk::ScopedAStatus getIntParameter(aidlevs::CameraParam id,
57                                          std::vector<int32_t>* value) override;
58     ::ndk::ScopedAStatus getIntParameterRange(aidlevs::CameraParam id,
59                                               aidlevs::ParameterRange* _aidl_return) override;
60     ::ndk::ScopedAStatus getParameterList(std::vector<aidlevs::CameraParam>* _aidl_return) override;
61     ::ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId,
62                                                aidlevs::CameraDesc* _aidl_return) override;
63     ::ndk::ScopedAStatus importExternalBuffers(const std::vector<aidlevs::BufferDesc>& buffers,
64                                                int32_t* _aidl_return) override;
65     ::ndk::ScopedAStatus pauseVideoStream() override;
66     ::ndk::ScopedAStatus resumeVideoStream() override;
67     ::ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier,
68                                          const std::vector<uint8_t>& opaqueValue) override;
69     ::ndk::ScopedAStatus setIntParameter(aidlevs::CameraParam id, int32_t value,
70                                          std::vector<int32_t>* effectiveValue) override;
71     ::ndk::ScopedAStatus setPrimaryClient() override;
72     ::ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override;
73     ::ndk::ScopedAStatus startVideoStream(
74             const std::shared_ptr<aidlevs::IEvsCameraStream>& receiver) override;
75     ::ndk::ScopedAStatus stopVideoStream() override;
76     ::ndk::ScopedAStatus unsetPrimaryClient() override;
77 
78     explicit VirtualCamera(const std::vector<std::shared_ptr<HalCamera>>& halCameras);
79     virtual ~VirtualCamera();
80 
getAllowedBuffers()81     unsigned getAllowedBuffers() { return mFramesAllowed; };
isStreaming()82     bool isStreaming() {
83         std::lock_guard lock(mMutex);
84         return mStreamState == RUNNING;
85     }
86     std::vector<std::shared_ptr<HalCamera>> getHalCameras();
setDescriptor(aidlevs::CameraDesc * desc)87     void setDescriptor(aidlevs::CameraDesc* desc) { mDesc = desc; }
88 
89     // Proxy to receive frames and forward them to the client's stream
90     bool notify(const aidlevs::EvsEventDesc& event);
91     bool deliverFrame(const aidlevs::BufferDesc& bufDesc);
92 
93     // Dump current status to a given file descriptor
94     std::string toString(const char* indent = "") const NO_THREAD_SAFETY_ANALYSIS;
95 
96 private:
97     void shutdown();
isLogicalCamera()98     bool isLogicalCamera() const { return mHalCamera.size() > 1; }
isValid()99     bool isValid() const { return !mHalCamera.empty(); }
100 
101     // The low level camera interface that backs this proxy
102     std::unordered_map<std::string, std::weak_ptr<HalCamera>> mHalCamera;
103 
104     std::shared_ptr<aidlevs::IEvsCameraStream> mStream;
105 
106     unsigned mFramesAllowed = 1;
107     enum {
108         STOPPED,
109         RUNNING,
110         STOPPING,
111     } mStreamState GUARDED_BY(mMutex) = STOPPED;
112 
113     std::unordered_map<std::string, std::deque<aidlevs::BufferDesc>> mFramesHeld GUARDED_BY(mMutex);
114     std::unordered_map<std::string, std::deque<aidlevs::BufferDesc>> mFramesUsed GUARDED_BY(mMutex);
115     std::thread mCaptureThread;
116     std::thread mReturnThread;
117     aidlevs::CameraDesc* mDesc;
118 
119     mutable std::mutex mMutex;
120     std::condition_variable mFramesReadySignal;
121     std::condition_variable mReturnFramesSignal;
122     std::set<std::string> mSourceCameras;
123 };
124 
125 }  // namespace aidl::android::automotive::evs::implementation
126 
127 #endif  // CPP_EVS_MANAGER_AIDL_INCLUDE_VIRTUALCAMERA_H
128