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_SAMPLEDRIVER_AIDL_INCLUDE_EVSV4LCAMERA_H
18 #define CPP_EVS_SAMPLEDRIVER_AIDL_INCLUDE_EVSV4LCAMERA_H
19 
20 #include "ConfigManager.h"
21 #include "VideoCapture.h"
22 
23 #include <aidl/android/hardware/automotive/evs/BnEvsCamera.h>
24 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
25 #include <aidl/android/hardware/automotive/evs/CameraDesc.h>
26 #include <aidl/android/hardware/automotive/evs/CameraParam.h>
27 #include <aidl/android/hardware/automotive/evs/EvsResult.h>
28 #include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h>
29 #include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
30 #include <aidl/android/hardware/automotive/evs/ParameterRange.h>
31 #include <aidl/android/hardware/automotive/evs/Stream.h>
32 #include <android-base/result.h>
33 #include <android/hardware_buffer.h>
34 #include <ui/GraphicBuffer.h>
35 
36 #include <functional>
37 #include <thread>
38 
39 namespace aidl::android::hardware::automotive::evs::implementation {
40 
41 namespace aidlevs = ::aidl::android::hardware::automotive::evs;
42 
43 class EvsV4lCamera : public ::aidl::android::hardware::automotive::evs::BnEvsCamera {
44 public:
45     // Methods from ::android::hardware::automotive::aidlevs::IEvsCamera follow.
46     ::ndk::ScopedAStatus doneWithFrame(const std::vector<aidlevs::BufferDesc>& buffers) override;
47     ::ndk::ScopedAStatus forcePrimaryClient(
48             const std::shared_ptr<aidlevs::IEvsDisplay>& display) override;
49     ::ndk::ScopedAStatus getCameraInfo(aidlevs::CameraDesc* _aidl_return) override;
50     ::ndk::ScopedAStatus getExtendedInfo(int32_t opaqueIdentifier,
51                                          std::vector<uint8_t>* value) override;
52     ::ndk::ScopedAStatus getIntParameter(aidlevs::CameraParam id,
53                                          std::vector<int32_t>* value) override;
54     ::ndk::ScopedAStatus getIntParameterRange(aidlevs::CameraParam id,
55                                               aidlevs::ParameterRange* _aidl_return) override;
56     ::ndk::ScopedAStatus getParameterList(std::vector<aidlevs::CameraParam>* _aidl_return) override;
57     ::ndk::ScopedAStatus getPhysicalCameraInfo(const std::string& deviceId,
58                                                aidlevs::CameraDesc* _aidl_return) override;
59     ::ndk::ScopedAStatus importExternalBuffers(const std::vector<aidlevs::BufferDesc>& buffers,
60                                                int32_t* _aidl_return) override;
61     ::ndk::ScopedAStatus pauseVideoStream() override;
62     ::ndk::ScopedAStatus resumeVideoStream() override;
63     ::ndk::ScopedAStatus setExtendedInfo(int32_t opaqueIdentifier,
64                                          const std::vector<uint8_t>& opaqueValue) override;
65     ::ndk::ScopedAStatus setIntParameter(aidlevs::CameraParam id, int32_t value,
66                                          std::vector<int32_t>* effectiveValue) override;
67     ::ndk::ScopedAStatus setPrimaryClient() override;
68     ::ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override;
69     ::ndk::ScopedAStatus startVideoStream(
70             const std::shared_ptr<aidlevs::IEvsCameraStream>& receiver) override;
71     ::ndk::ScopedAStatus stopVideoStream() override;
72     ::ndk::ScopedAStatus unsetPrimaryClient() override;
73 
74     static std::shared_ptr<EvsV4lCamera> Create(const char* deviceName);
75     static std::shared_ptr<EvsV4lCamera> Create(const char* deviceName,
76                                                 std::unique_ptr<ConfigManager::CameraInfo>& camInfo,
77                                                 const aidlevs::Stream* streamCfg = nullptr);
78     EvsV4lCamera(const EvsV4lCamera&) = delete;
79     EvsV4lCamera& operator=(const EvsV4lCamera&) = delete;
80 
81     virtual ~EvsV4lCamera() override;
82     void shutdown();
83 
getDesc()84     const aidlevs::CameraDesc& getDesc() { return mDescription; }
85 
86     // Dump captured frames to the filesystem
87     ::android::base::Result<void> startDumpFrames(const std::string& path);
88     ::android::base::Result<void> stopDumpFrames();
89 
90     // Constructors
91     EvsV4lCamera(const char* deviceName, std::unique_ptr<ConfigManager::CameraInfo>& camInfo);
92 
93 private:
94     // These three functions are expected to be called while mAccessLock is held
95     bool setAvailableFrames_Locked(unsigned bufferCount);
96     unsigned increaseAvailableFrames_Locked(unsigned numToAdd);
97     unsigned decreaseAvailableFrames_Locked(unsigned numToRemove);
98 
99     void forwardFrame(imageBuffer* tgt, void* data);
100     inline bool convertToV4l2CID(aidlevs::CameraParam id, uint32_t& v4l2cid);
101 
102     // The callback used to deliver each frame
103     std::shared_ptr<aidlevs::IEvsCameraStream> mStream;
104 
105     // Interface to the v4l device
106     VideoCapture mVideo = {};
107 
108     // The properties of this camera
109     aidlevs::CameraDesc mDescription = {};
110 
111     uint32_t mFormat = 0;  // Values from android_pixel_format_t
112     uint32_t mUsage = 0;   // Values from from Gralloc.h
113     uint32_t mStride = 0;  // Pixels per row (may be greater than image width)
114 
115     struct BufferRecord {
116         buffer_handle_t handle;
117         bool inUse;
118 
BufferRecordBufferRecord119         explicit BufferRecord(buffer_handle_t h) : handle(h), inUse(false) {};
120     };
121 
122     // Graphics buffers to transfer images
123     std::vector<BufferRecord> mBuffers;
124     // How many buffers are we currently using
125     unsigned mFramesAllowed;
126     // How many buffers are currently outstanding
127     unsigned mFramesInUse;
128 
129     std::set<uint32_t> mCameraControls;  // Available camera controls
130 
131     // Which format specific function we need to use to move camera imagery into our output buffers
132     void (*mFillBufferFromVideo)(const aidlevs::BufferDesc& tgtBuff, uint8_t* tgt, void* imgData,
133                                  unsigned imgStride);
134 
135     aidlevs::EvsResult doneWithFrame_impl(const aidlevs::BufferDesc& bufferDesc);
136     aidlevs::EvsResult doneWithFrame_impl(uint32_t id, buffer_handle_t handle);
137 
138     // Synchronization necessary to deconflict the capture thread from the main service thread
139     // Note that the service interface remains single threaded (ie: not reentrant)
140     mutable std::mutex mAccessLock;
141 
142     // Static camera module information
143     std::unique_ptr<ConfigManager::CameraInfo>& mCameraInfo;
144 
145     // Extended information
146     std::unordered_map<uint32_t, std::vector<uint8_t>> mExtInfo;
147 
148     // Dump captured frames
149     std::atomic<bool> mDumpFrame = false;
150 
151     // Path to store captured frames
152     std::string mDumpPath;
153 
154     // Frame counter
155     uint64_t mFrameCounter = 0;
156 };
157 
158 }  // namespace aidl::android::hardware::automotive::evs::implementation
159 
160 #endif  // CPP_EVS_SAMPLEDRIVER_AIDL_INCLUDE_EVSV4LCAMERA_H
161