xref: /aosp_15_r20/hardware/interfaces/camera/device/default/ExternalCameraDeviceSession.h (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #ifndef HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
18*4d7e907cSAndroid Build Coastguard Worker #define HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
19*4d7e907cSAndroid Build Coastguard Worker 
20*4d7e907cSAndroid Build Coastguard Worker #include <ExternalCameraUtils.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <SimpleThread.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/camera/common/Status.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/camera/device/BnCameraDeviceSession.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/camera/device/BufferRequest.h>
25*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/hardware/camera/device/Stream.h>
26*4d7e907cSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
27*4d7e907cSAndroid Build Coastguard Worker #include <android/hardware/graphics/mapper/2.0/IMapper.h>
28*4d7e907cSAndroid Build Coastguard Worker #include <android/hardware/graphics/mapper/3.0/IMapper.h>
29*4d7e907cSAndroid Build Coastguard Worker #include <android/hardware/graphics/mapper/4.0/IMapper.h>
30*4d7e907cSAndroid Build Coastguard Worker #include <fmq/AidlMessageQueue.h>
31*4d7e907cSAndroid Build Coastguard Worker #include <utils/Thread.h>
32*4d7e907cSAndroid Build Coastguard Worker #include <deque>
33*4d7e907cSAndroid Build Coastguard Worker #include <list>
34*4d7e907cSAndroid Build Coastguard Worker 
35*4d7e907cSAndroid Build Coastguard Worker namespace android {
36*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
37*4d7e907cSAndroid Build Coastguard Worker namespace camera {
38*4d7e907cSAndroid Build Coastguard Worker namespace device {
39*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
40*4d7e907cSAndroid Build Coastguard Worker 
41*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::common::Status;
42*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::BnCameraDeviceSession;
43*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::BufferCache;
44*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::BufferRequest;
45*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::CameraMetadata;
46*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::CameraOfflineSessionInfo;
47*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::CaptureRequest;
48*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::HalStream;
49*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::ICameraDeviceCallback;
50*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::ICameraOfflineSession;
51*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::RequestTemplate;
52*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::Stream;
53*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::camera::device::StreamConfiguration;
54*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::MQDescriptor;
55*4d7e907cSAndroid Build Coastguard Worker using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
56*4d7e907cSAndroid Build Coastguard Worker using ::android::AidlMessageQueue;
57*4d7e907cSAndroid Build Coastguard Worker using ::android::base::unique_fd;
58*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::camera::common::helper::SimpleThread;
59*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::camera::external::common::ExternalCameraConfig;
60*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::camera::external::common::SizeHasher;
61*4d7e907cSAndroid Build Coastguard Worker using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
62*4d7e907cSAndroid Build Coastguard Worker using ::ndk::ScopedAStatus;
63*4d7e907cSAndroid Build Coastguard Worker 
64*4d7e907cSAndroid Build Coastguard Worker class ExternalCameraDeviceSession : public BnCameraDeviceSession, public OutputThreadInterface {
65*4d7e907cSAndroid Build Coastguard Worker   public:
66*4d7e907cSAndroid Build Coastguard Worker     ExternalCameraDeviceSession(const std::shared_ptr<ICameraDeviceCallback>&,
67*4d7e907cSAndroid Build Coastguard Worker                                 const ExternalCameraConfig& cfg,
68*4d7e907cSAndroid Build Coastguard Worker                                 const std::vector<SupportedV4L2Format>& sortedFormats,
69*4d7e907cSAndroid Build Coastguard Worker                                 const CroppingType& croppingType,
70*4d7e907cSAndroid Build Coastguard Worker                                 const common::V1_0::helper::CameraMetadata& chars,
71*4d7e907cSAndroid Build Coastguard Worker                                 const std::string& cameraId, unique_fd v4l2Fd);
72*4d7e907cSAndroid Build Coastguard Worker     ~ExternalCameraDeviceSession() override;
73*4d7e907cSAndroid Build Coastguard Worker 
74*4d7e907cSAndroid Build Coastguard Worker     // Caller must use this method to check if CameraDeviceSession ctor failed
75*4d7e907cSAndroid Build Coastguard Worker     bool isInitFailed();
76*4d7e907cSAndroid Build Coastguard Worker     bool isClosed();
77*4d7e907cSAndroid Build Coastguard Worker 
78*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus close() override;
79*4d7e907cSAndroid Build Coastguard Worker 
80*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus configureStreams(const StreamConfiguration& in_requestedConfiguration,
81*4d7e907cSAndroid Build Coastguard Worker                                    std::vector<HalStream>* _aidl_return) override;
82*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus constructDefaultRequestSettings(RequestTemplate in_type,
83*4d7e907cSAndroid Build Coastguard Worker                                                   CameraMetadata* _aidl_return) override;
84*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus flush() override;
85*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus getCaptureRequestMetadataQueue(
86*4d7e907cSAndroid Build Coastguard Worker             MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
87*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus getCaptureResultMetadataQueue(
88*4d7e907cSAndroid Build Coastguard Worker             MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) override;
89*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus isReconfigurationRequired(const CameraMetadata& in_oldSessionParams,
90*4d7e907cSAndroid Build Coastguard Worker                                             const CameraMetadata& in_newSessionParams,
91*4d7e907cSAndroid Build Coastguard Worker                                             bool* _aidl_return) override;
92*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus processCaptureRequest(const std::vector<CaptureRequest>& in_requests,
93*4d7e907cSAndroid Build Coastguard Worker                                         const std::vector<BufferCache>& in_cachesToRemove,
94*4d7e907cSAndroid Build Coastguard Worker                                         int32_t* _aidl_return) override;
95*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus signalStreamFlush(const std::vector<int32_t>& in_streamIds,
96*4d7e907cSAndroid Build Coastguard Worker                                     int32_t in_streamConfigCounter) override;
97*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus switchToOffline(const std::vector<int32_t>& in_streamsToKeep,
98*4d7e907cSAndroid Build Coastguard Worker                                   CameraOfflineSessionInfo* out_offlineSessionInfo,
99*4d7e907cSAndroid Build Coastguard Worker                                   std::shared_ptr<ICameraOfflineSession>* _aidl_return) override;
100*4d7e907cSAndroid Build Coastguard Worker     ScopedAStatus repeatingRequestEnd(int32_t in_frameNumber,
101*4d7e907cSAndroid Build Coastguard Worker                                       const std::vector<int32_t>& in_streamIds) override;
102*4d7e907cSAndroid Build Coastguard Worker 
103*4d7e907cSAndroid Build Coastguard Worker     Status importBuffer(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
104*4d7e907cSAndroid Build Coastguard Worker                         buffer_handle_t** outBufPtr) override;
105*4d7e907cSAndroid Build Coastguard Worker 
106*4d7e907cSAndroid Build Coastguard Worker     void notifyError(int32_t frameNumber, int32_t streamId, ErrorCode ec) override;
107*4d7e907cSAndroid Build Coastguard Worker 
108*4d7e907cSAndroid Build Coastguard Worker     Status processCaptureRequestError(const std::shared_ptr<HalRequest>& ptr,
109*4d7e907cSAndroid Build Coastguard Worker                                       std::vector<NotifyMsg>* msgs,
110*4d7e907cSAndroid Build Coastguard Worker                                       std::vector<CaptureResult>* results) override;
111*4d7e907cSAndroid Build Coastguard Worker 
112*4d7e907cSAndroid Build Coastguard Worker     Status processCaptureResult(std::shared_ptr<HalRequest>& ptr) override;
113*4d7e907cSAndroid Build Coastguard Worker     ssize_t getJpegBufferSize(int32_t width, int32_t height) const override;
114*4d7e907cSAndroid Build Coastguard Worker 
115*4d7e907cSAndroid Build Coastguard Worker     // Called by CameraDevice to dump active device states
116*4d7e907cSAndroid Build Coastguard Worker     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
117*4d7e907cSAndroid Build Coastguard Worker 
118*4d7e907cSAndroid Build Coastguard Worker     static Status isStreamCombinationSupported(
119*4d7e907cSAndroid Build Coastguard Worker             const StreamConfiguration& config,
120*4d7e907cSAndroid Build Coastguard Worker             const std::vector<SupportedV4L2Format>& supportedFormats,
121*4d7e907cSAndroid Build Coastguard Worker             const ExternalCameraConfig& devCfg);
122*4d7e907cSAndroid Build Coastguard Worker 
123*4d7e907cSAndroid Build Coastguard Worker     static const int kMaxProcessedStream = 2;
124*4d7e907cSAndroid Build Coastguard Worker     static const int kMaxStallStream = 1;
125*4d7e907cSAndroid Build Coastguard Worker     static const uint32_t kMaxBytesPerPixel = 3;
126*4d7e907cSAndroid Build Coastguard Worker 
127*4d7e907cSAndroid Build Coastguard Worker     class BufferRequestThread : public SimpleThread {
128*4d7e907cSAndroid Build Coastguard Worker       public:
129*4d7e907cSAndroid Build Coastguard Worker         BufferRequestThread(std::weak_ptr<OutputThreadInterface> parent,
130*4d7e907cSAndroid Build Coastguard Worker                             std::shared_ptr<ICameraDeviceCallback> callbacks);
131*4d7e907cSAndroid Build Coastguard Worker 
132*4d7e907cSAndroid Build Coastguard Worker         int requestBufferStart(const std::vector<HalStreamBuffer>&);
133*4d7e907cSAndroid Build Coastguard Worker         int waitForBufferRequestDone(
134*4d7e907cSAndroid Build Coastguard Worker                 /*out*/ std::vector<HalStreamBuffer>*);
135*4d7e907cSAndroid Build Coastguard Worker 
136*4d7e907cSAndroid Build Coastguard Worker         bool threadLoop() override;
137*4d7e907cSAndroid Build Coastguard Worker 
138*4d7e907cSAndroid Build Coastguard Worker       private:
139*4d7e907cSAndroid Build Coastguard Worker         void waitForNextRequest();
140*4d7e907cSAndroid Build Coastguard Worker 
141*4d7e907cSAndroid Build Coastguard Worker         const std::weak_ptr<OutputThreadInterface> mParent;
142*4d7e907cSAndroid Build Coastguard Worker         const std::shared_ptr<ICameraDeviceCallback> mCallbacks;
143*4d7e907cSAndroid Build Coastguard Worker 
144*4d7e907cSAndroid Build Coastguard Worker         std::mutex mLock;
145*4d7e907cSAndroid Build Coastguard Worker         bool mRequestingBuffer = false;
146*4d7e907cSAndroid Build Coastguard Worker 
147*4d7e907cSAndroid Build Coastguard Worker         std::vector<HalStreamBuffer> mBufferReqs;
148*4d7e907cSAndroid Build Coastguard Worker         std::vector<HalStreamBuffer> mPendingReturnBufferReqs;
149*4d7e907cSAndroid Build Coastguard Worker         // mHalBufferReqs is not under mLock protection during the HIDL transaction
150*4d7e907cSAndroid Build Coastguard Worker         std::vector<BufferRequest> mHalBufferReqs;
151*4d7e907cSAndroid Build Coastguard Worker 
152*4d7e907cSAndroid Build Coastguard Worker         // request buffers takes much less time in steady state, but can take much longer
153*4d7e907cSAndroid Build Coastguard Worker         // when requesting 1st buffer from a stream.
154*4d7e907cSAndroid Build Coastguard Worker         // TODO: consider a separate timeout for new vs. steady state?
155*4d7e907cSAndroid Build Coastguard Worker         // TODO: or make sure framework is warming up the pipeline during configure new stream?
156*4d7e907cSAndroid Build Coastguard Worker         static const int kReqProcTimeoutMs = 66;
157*4d7e907cSAndroid Build Coastguard Worker 
158*4d7e907cSAndroid Build Coastguard Worker         static const int kReqWaitTimeoutMs = 33;
159*4d7e907cSAndroid Build Coastguard Worker         static const int kReqWaitTimesWarn = 90;   // 33ms * 90 ~= 3 sec
160*4d7e907cSAndroid Build Coastguard Worker         std::condition_variable mRequestCond;      // signaled when a new buffer request incoming
161*4d7e907cSAndroid Build Coastguard Worker         std::condition_variable mRequestDoneCond;  // signaled when a request is done
162*4d7e907cSAndroid Build Coastguard Worker     };
163*4d7e907cSAndroid Build Coastguard Worker 
164*4d7e907cSAndroid Build Coastguard Worker     class OutputThread : public SimpleThread {
165*4d7e907cSAndroid Build Coastguard Worker       public:
166*4d7e907cSAndroid Build Coastguard Worker         OutputThread(std::weak_ptr<OutputThreadInterface> parent, CroppingType,
167*4d7e907cSAndroid Build Coastguard Worker                      const common::V1_0::helper::CameraMetadata&,
168*4d7e907cSAndroid Build Coastguard Worker                      std::shared_ptr<BufferRequestThread> bufReqThread);
169*4d7e907cSAndroid Build Coastguard Worker         ~OutputThread();
170*4d7e907cSAndroid Build Coastguard Worker 
171*4d7e907cSAndroid Build Coastguard Worker         Status allocateIntermediateBuffers(const Size& v4lSize, const Size& thumbSize,
172*4d7e907cSAndroid Build Coastguard Worker                                            const std::vector<Stream>& streams,
173*4d7e907cSAndroid Build Coastguard Worker                                            uint32_t blobBufferSize);
174*4d7e907cSAndroid Build Coastguard Worker         Status submitRequest(const std::shared_ptr<HalRequest>&);
175*4d7e907cSAndroid Build Coastguard Worker         void flush();
176*4d7e907cSAndroid Build Coastguard Worker         void dump(int fd);
177*4d7e907cSAndroid Build Coastguard Worker         bool threadLoop() override;
178*4d7e907cSAndroid Build Coastguard Worker 
179*4d7e907cSAndroid Build Coastguard Worker         void setExifMakeModel(const std::string& make, const std::string& model);
180*4d7e907cSAndroid Build Coastguard Worker 
181*4d7e907cSAndroid Build Coastguard Worker         // The remaining request list is returned for offline processing
182*4d7e907cSAndroid Build Coastguard Worker         std::list<std::shared_ptr<HalRequest>> switchToOffline();
183*4d7e907cSAndroid Build Coastguard Worker 
184*4d7e907cSAndroid Build Coastguard Worker       protected:
185*4d7e907cSAndroid Build Coastguard Worker         static const int kFlushWaitTimeoutSec = 3;  // 3 sec
186*4d7e907cSAndroid Build Coastguard Worker         static const int kReqWaitTimeoutMs = 33;    // 33ms
187*4d7e907cSAndroid Build Coastguard Worker         static const int kReqWaitTimesMax = 90;     // 33ms * 90 ~= 3 sec
188*4d7e907cSAndroid Build Coastguard Worker 
189*4d7e907cSAndroid Build Coastguard Worker         // Methods to request output buffer in parallel
190*4d7e907cSAndroid Build Coastguard Worker         int requestBufferStart(const std::vector<HalStreamBuffer>&);
191*4d7e907cSAndroid Build Coastguard Worker         int waitForBufferRequestDone(
192*4d7e907cSAndroid Build Coastguard Worker                 /*out*/ std::vector<HalStreamBuffer>*);
193*4d7e907cSAndroid Build Coastguard Worker 
194*4d7e907cSAndroid Build Coastguard Worker         void waitForNextRequest(std::shared_ptr<HalRequest>* out);
195*4d7e907cSAndroid Build Coastguard Worker         void signalRequestDone();
196*4d7e907cSAndroid Build Coastguard Worker 
197*4d7e907cSAndroid Build Coastguard Worker         int cropAndScaleLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
198*4d7e907cSAndroid Build Coastguard Worker                                YCbCrLayout* out);
199*4d7e907cSAndroid Build Coastguard Worker 
200*4d7e907cSAndroid Build Coastguard Worker         int cropAndScaleThumbLocked(std::shared_ptr<AllocatedFrame>& in, const Size& outSize,
201*4d7e907cSAndroid Build Coastguard Worker                                     YCbCrLayout* out);
202*4d7e907cSAndroid Build Coastguard Worker 
203*4d7e907cSAndroid Build Coastguard Worker         int createJpegLocked(HalStreamBuffer& halBuf,
204*4d7e907cSAndroid Build Coastguard Worker                              const common::V1_0::helper::CameraMetadata& settings);
205*4d7e907cSAndroid Build Coastguard Worker 
206*4d7e907cSAndroid Build Coastguard Worker         void clearIntermediateBuffers();
207*4d7e907cSAndroid Build Coastguard Worker 
208*4d7e907cSAndroid Build Coastguard Worker         const std::weak_ptr<OutputThreadInterface> mParent;
209*4d7e907cSAndroid Build Coastguard Worker         const CroppingType mCroppingType;
210*4d7e907cSAndroid Build Coastguard Worker         const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
211*4d7e907cSAndroid Build Coastguard Worker 
212*4d7e907cSAndroid Build Coastguard Worker         mutable std::mutex mRequestListLock;       // Protect access to mRequestList,
213*4d7e907cSAndroid Build Coastguard Worker                                                    // mProcessingRequest and mProcessingFrameNumber
214*4d7e907cSAndroid Build Coastguard Worker         std::condition_variable mRequestCond;      // signaled when a new request is submitted
215*4d7e907cSAndroid Build Coastguard Worker         std::condition_variable mRequestDoneCond;  // signaled when a request is done processing
216*4d7e907cSAndroid Build Coastguard Worker         std::list<std::shared_ptr<HalRequest>> mRequestList;
217*4d7e907cSAndroid Build Coastguard Worker         bool mProcessingRequest = false;
218*4d7e907cSAndroid Build Coastguard Worker         uint32_t mProcessingFrameNumber = 0;
219*4d7e907cSAndroid Build Coastguard Worker 
220*4d7e907cSAndroid Build Coastguard Worker         // V4L2 frameIn
221*4d7e907cSAndroid Build Coastguard Worker         // (MJPG decode)-> mYu12Frame
222*4d7e907cSAndroid Build Coastguard Worker         // (Scale)-> mScaledYu12Frames
223*4d7e907cSAndroid Build Coastguard Worker         // (Format convert) -> output gralloc frames
224*4d7e907cSAndroid Build Coastguard Worker         mutable std::mutex mBufferLock;  // Protect access to intermediate buffers
225*4d7e907cSAndroid Build Coastguard Worker         std::shared_ptr<AllocatedFrame> mYu12Frame;
226*4d7e907cSAndroid Build Coastguard Worker         std::shared_ptr<AllocatedFrame> mYu12ThumbFrame;
227*4d7e907cSAndroid Build Coastguard Worker         std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mIntermediateBuffers;
228*4d7e907cSAndroid Build Coastguard Worker         std::unordered_map<Size, std::shared_ptr<AllocatedFrame>, SizeHasher> mScaledYu12Frames;
229*4d7e907cSAndroid Build Coastguard Worker         YCbCrLayout mYu12FrameLayout;
230*4d7e907cSAndroid Build Coastguard Worker         YCbCrLayout mYu12ThumbFrameLayout;
231*4d7e907cSAndroid Build Coastguard Worker         std::vector<uint8_t> mMuteTestPatternFrame;
232*4d7e907cSAndroid Build Coastguard Worker         uint32_t mTestPatternData[4] = {0, 0, 0, 0};
233*4d7e907cSAndroid Build Coastguard Worker         bool mCameraMuted = false;
234*4d7e907cSAndroid Build Coastguard Worker         uint32_t mBlobBufferSize = 0;  // 0 -> HAL derive buffer size, else: use given size
235*4d7e907cSAndroid Build Coastguard Worker 
236*4d7e907cSAndroid Build Coastguard Worker         std::string mExifMake;
237*4d7e907cSAndroid Build Coastguard Worker         std::string mExifModel;
238*4d7e907cSAndroid Build Coastguard Worker 
239*4d7e907cSAndroid Build Coastguard Worker         const std::shared_ptr<BufferRequestThread> mBufferRequestThread;
240*4d7e907cSAndroid Build Coastguard Worker     };
241*4d7e907cSAndroid Build Coastguard Worker 
242*4d7e907cSAndroid Build Coastguard Worker   private:
243*4d7e907cSAndroid Build Coastguard Worker     bool initialize();
244*4d7e907cSAndroid Build Coastguard Worker     // To init/close different version of output thread
245*4d7e907cSAndroid Build Coastguard Worker     void initOutputThread();
246*4d7e907cSAndroid Build Coastguard Worker     void closeOutputThread();
247*4d7e907cSAndroid Build Coastguard Worker     void closeBufferRequestThread();
248*4d7e907cSAndroid Build Coastguard Worker 
249*4d7e907cSAndroid Build Coastguard Worker     void closeImpl();
250*4d7e907cSAndroid Build Coastguard Worker     Status initStatus() const;
251*4d7e907cSAndroid Build Coastguard Worker     status_t initDefaultRequests();
252*4d7e907cSAndroid Build Coastguard Worker 
253*4d7e907cSAndroid Build Coastguard Worker     status_t fillCaptureResult(common::V1_0::helper::CameraMetadata& md, nsecs_t timestamp);
254*4d7e907cSAndroid Build Coastguard Worker     int configureV4l2StreamLocked(const SupportedV4L2Format& fmt, double fps = 0.0);
255*4d7e907cSAndroid Build Coastguard Worker     int v4l2StreamOffLocked();
256*4d7e907cSAndroid Build Coastguard Worker 
257*4d7e907cSAndroid Build Coastguard Worker     int setV4l2FpsLocked(double fps);
258*4d7e907cSAndroid Build Coastguard Worker 
259*4d7e907cSAndroid Build Coastguard Worker     std::unique_ptr<V4L2Frame> dequeueV4l2FrameLocked(
260*4d7e907cSAndroid Build Coastguard Worker             /*out*/ nsecs_t* shutterTs);  // Called with mLock held
261*4d7e907cSAndroid Build Coastguard Worker 
262*4d7e907cSAndroid Build Coastguard Worker     void enqueueV4l2Frame(const std::shared_ptr<V4L2Frame>&);
263*4d7e907cSAndroid Build Coastguard Worker 
264*4d7e907cSAndroid Build Coastguard Worker     // Check if input Stream is one of supported stream setting on this device
265*4d7e907cSAndroid Build Coastguard Worker     static bool isSupported(const Stream& stream,
266*4d7e907cSAndroid Build Coastguard Worker                             const std::vector<SupportedV4L2Format>& supportedFormats,
267*4d7e907cSAndroid Build Coastguard Worker                             const ExternalCameraConfig& cfg);
268*4d7e907cSAndroid Build Coastguard Worker 
269*4d7e907cSAndroid Build Coastguard Worker     Status importBufferLocked(int32_t streamId, uint64_t bufId, buffer_handle_t buf,
270*4d7e907cSAndroid Build Coastguard Worker                               /*out*/ buffer_handle_t** outBufPtr);
271*4d7e907cSAndroid Build Coastguard Worker     static void cleanupInflightFences(std::vector<int>& allFences, size_t numFences);
272*4d7e907cSAndroid Build Coastguard Worker     void cleanupBuffersLocked(int id);
273*4d7e907cSAndroid Build Coastguard Worker 
274*4d7e907cSAndroid Build Coastguard Worker     void updateBufferCaches(const std::vector<BufferCache>& cachesToRemove);
275*4d7e907cSAndroid Build Coastguard Worker 
276*4d7e907cSAndroid Build Coastguard Worker     Status processOneCaptureRequest(const CaptureRequest& request);
277*4d7e907cSAndroid Build Coastguard Worker     void notifyShutter(int32_t frameNumber, nsecs_t shutterTs);
278*4d7e907cSAndroid Build Coastguard Worker 
279*4d7e907cSAndroid Build Coastguard Worker     void invokeProcessCaptureResultCallback(std::vector<CaptureResult>& results, bool tryWriteFmq);
280*4d7e907cSAndroid Build Coastguard Worker     Size getMaxJpegResolution() const;
281*4d7e907cSAndroid Build Coastguard Worker 
282*4d7e907cSAndroid Build Coastguard Worker     Size getMaxThumbResolution() const;
283*4d7e907cSAndroid Build Coastguard Worker 
284*4d7e907cSAndroid Build Coastguard Worker     int waitForV4L2BufferReturnLocked(std::unique_lock<std::mutex>& lk);
285*4d7e907cSAndroid Build Coastguard Worker 
286*4d7e907cSAndroid Build Coastguard Worker     // Main body of switchToOffline. This method does not invoke any callbacks
287*4d7e907cSAndroid Build Coastguard Worker     // but instead returns the necessary callbacks in output arguments so callers
288*4d7e907cSAndroid Build Coastguard Worker     // can callback later without holding any locks
289*4d7e907cSAndroid Build Coastguard Worker     Status switchToOffline(const std::vector<int32_t>& offlineStreams,
290*4d7e907cSAndroid Build Coastguard Worker                            /*out*/ std::vector<NotifyMsg>* msgs,
291*4d7e907cSAndroid Build Coastguard Worker                            /*out*/ std::vector<CaptureResult>* results,
292*4d7e907cSAndroid Build Coastguard Worker                            /*out*/ CameraOfflineSessionInfo* info,
293*4d7e907cSAndroid Build Coastguard Worker                            /*out*/ std::shared_ptr<ICameraOfflineSession>* session);
294*4d7e907cSAndroid Build Coastguard Worker 
295*4d7e907cSAndroid Build Coastguard Worker     bool supportOfflineLocked(int32_t streamId);
296*4d7e907cSAndroid Build Coastguard Worker 
297*4d7e907cSAndroid Build Coastguard Worker     // Whether a request can be completely dropped when switching to offline
298*4d7e907cSAndroid Build Coastguard Worker     bool canDropRequest(const std::vector<int32_t>& offlineStreams,
299*4d7e907cSAndroid Build Coastguard Worker                         std::shared_ptr<HalRequest> halReq);
300*4d7e907cSAndroid Build Coastguard Worker 
301*4d7e907cSAndroid Build Coastguard Worker     void fillOfflineSessionInfo(const std::vector<int32_t>& offlineStreams,
302*4d7e907cSAndroid Build Coastguard Worker                                 std::deque<std::shared_ptr<HalRequest>>& offlineReqs,
303*4d7e907cSAndroid Build Coastguard Worker                                 const std::map<int, CirculatingBuffers>& circulatingBuffers,
304*4d7e907cSAndroid Build Coastguard Worker                                 /*out*/ CameraOfflineSessionInfo* info);
305*4d7e907cSAndroid Build Coastguard Worker 
306*4d7e907cSAndroid Build Coastguard Worker     // Protect (most of) HIDL interface methods from synchronized-entering
307*4d7e907cSAndroid Build Coastguard Worker     mutable Mutex mInterfaceLock;
308*4d7e907cSAndroid Build Coastguard Worker 
309*4d7e907cSAndroid Build Coastguard Worker     mutable Mutex mLock;  // Protect all private members except otherwise noted
310*4d7e907cSAndroid Build Coastguard Worker     const std::shared_ptr<ICameraDeviceCallback> mCallback;
311*4d7e907cSAndroid Build Coastguard Worker     const ExternalCameraConfig& mCfg;
312*4d7e907cSAndroid Build Coastguard Worker     const common::V1_0::helper::CameraMetadata mCameraCharacteristics;
313*4d7e907cSAndroid Build Coastguard Worker     const std::vector<SupportedV4L2Format> mSupportedFormats;
314*4d7e907cSAndroid Build Coastguard Worker     const CroppingType mCroppingType;
315*4d7e907cSAndroid Build Coastguard Worker     const std::string mCameraId;
316*4d7e907cSAndroid Build Coastguard Worker 
317*4d7e907cSAndroid Build Coastguard Worker     // Not protected by mLock, this is almost a const.
318*4d7e907cSAndroid Build Coastguard Worker     // Setup in constructor, reset in close() after OutputThread is joined
319*4d7e907cSAndroid Build Coastguard Worker     unique_fd mV4l2Fd;
320*4d7e907cSAndroid Build Coastguard Worker 
321*4d7e907cSAndroid Build Coastguard Worker     // device is closed either
322*4d7e907cSAndroid Build Coastguard Worker     //    - closed by user
323*4d7e907cSAndroid Build Coastguard Worker     //    - init failed
324*4d7e907cSAndroid Build Coastguard Worker     //    - camera disconnected
325*4d7e907cSAndroid Build Coastguard Worker     bool mClosed = false;
326*4d7e907cSAndroid Build Coastguard Worker     bool mInitialized = false;
327*4d7e907cSAndroid Build Coastguard Worker     bool mInitFail = false;
328*4d7e907cSAndroid Build Coastguard Worker     bool mFirstRequest = false;
329*4d7e907cSAndroid Build Coastguard Worker     common::V1_0::helper::CameraMetadata mLatestReqSetting;
330*4d7e907cSAndroid Build Coastguard Worker 
331*4d7e907cSAndroid Build Coastguard Worker     bool mV4l2Streaming = false;
332*4d7e907cSAndroid Build Coastguard Worker     SupportedV4L2Format mV4l2StreamingFmt;
333*4d7e907cSAndroid Build Coastguard Worker     double mV4l2StreamingFps = 0.0;
334*4d7e907cSAndroid Build Coastguard Worker     size_t mV4L2BufferCount = 0;
335*4d7e907cSAndroid Build Coastguard Worker 
336*4d7e907cSAndroid Build Coastguard Worker     static const int kBufferWaitTimeoutSec = 3;  // TODO: handle long exposure (or not allowing)
337*4d7e907cSAndroid Build Coastguard Worker     std::mutex mV4l2BufferLock;                  // protect the buffer count and condition below
338*4d7e907cSAndroid Build Coastguard Worker     std::condition_variable mV4L2BufferReturned;
339*4d7e907cSAndroid Build Coastguard Worker     size_t mNumDequeuedV4l2Buffers = 0;
340*4d7e907cSAndroid Build Coastguard Worker     uint32_t mMaxV4L2BufferSize = 0;
341*4d7e907cSAndroid Build Coastguard Worker 
342*4d7e907cSAndroid Build Coastguard Worker     // Not protected by mLock (but might be used when mLock is locked)
343*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<OutputThread> mOutputThread;
344*4d7e907cSAndroid Build Coastguard Worker 
345*4d7e907cSAndroid Build Coastguard Worker     // Stream ID -> Stream cache
346*4d7e907cSAndroid Build Coastguard Worker     std::unordered_map<int, Stream> mStreamMap;
347*4d7e907cSAndroid Build Coastguard Worker 
348*4d7e907cSAndroid Build Coastguard Worker     std::mutex mInflightFramesLock;  // protect mInflightFrames
349*4d7e907cSAndroid Build Coastguard Worker     std::unordered_set<uint32_t> mInflightFrames;
350*4d7e907cSAndroid Build Coastguard Worker 
351*4d7e907cSAndroid Build Coastguard Worker     // Stream ID -> circulating buffers map
352*4d7e907cSAndroid Build Coastguard Worker     std::map<int, CirculatingBuffers> mCirculatingBuffers;
353*4d7e907cSAndroid Build Coastguard Worker     // Protect mCirculatingBuffers, must not lock mLock after acquiring this lock
354*4d7e907cSAndroid Build Coastguard Worker     mutable Mutex mCbsLock;
355*4d7e907cSAndroid Build Coastguard Worker 
356*4d7e907cSAndroid Build Coastguard Worker     std::mutex mAfTriggerLock;  // protect mAfTrigger
357*4d7e907cSAndroid Build Coastguard Worker     bool mAfTrigger = false;
358*4d7e907cSAndroid Build Coastguard Worker 
359*4d7e907cSAndroid Build Coastguard Worker     uint32_t mBlobBufferSize = 0;
360*4d7e907cSAndroid Build Coastguard Worker 
361*4d7e907cSAndroid Build Coastguard Worker     static HandleImporter sHandleImporter;
362*4d7e907cSAndroid Build Coastguard Worker 
363*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<BufferRequestThread> mBufferRequestThread;
364*4d7e907cSAndroid Build Coastguard Worker 
365*4d7e907cSAndroid Build Coastguard Worker     /* Beginning of members not changed after initialize() */
366*4d7e907cSAndroid Build Coastguard Worker     using RequestMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
367*4d7e907cSAndroid Build Coastguard Worker     std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
368*4d7e907cSAndroid Build Coastguard Worker     using ResultMetadataQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
369*4d7e907cSAndroid Build Coastguard Worker     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
370*4d7e907cSAndroid Build Coastguard Worker 
371*4d7e907cSAndroid Build Coastguard Worker     // Protect against invokeProcessCaptureResultCallback()
372*4d7e907cSAndroid Build Coastguard Worker     Mutex mProcessCaptureResultLock;
373*4d7e907cSAndroid Build Coastguard Worker 
374*4d7e907cSAndroid Build Coastguard Worker     // tracks last seen stream config counter
375*4d7e907cSAndroid Build Coastguard Worker     int32_t mLastStreamConfigCounter = -1;
376*4d7e907cSAndroid Build Coastguard Worker 
377*4d7e907cSAndroid Build Coastguard Worker     std::unordered_map<RequestTemplate, CameraMetadata> mDefaultRequests;
378*4d7e907cSAndroid Build Coastguard Worker 
379*4d7e907cSAndroid Build Coastguard Worker     const Size mMaxThumbResolution;
380*4d7e907cSAndroid Build Coastguard Worker     const Size mMaxJpegResolution;
381*4d7e907cSAndroid Build Coastguard Worker 
382*4d7e907cSAndroid Build Coastguard Worker     std::string mExifMake;
383*4d7e907cSAndroid Build Coastguard Worker     std::string mExifModel;
384*4d7e907cSAndroid Build Coastguard Worker     /* End of members not changed after initialize() */
385*4d7e907cSAndroid Build Coastguard Worker 
386*4d7e907cSAndroid Build Coastguard Worker     // The max tolerant lag between the dequeued v4l2 buffer and current capture request.
387*4d7e907cSAndroid Build Coastguard Worker     uint64_t mMaxLagNs;
388*4d7e907cSAndroid Build Coastguard Worker };
389*4d7e907cSAndroid Build Coastguard Worker 
390*4d7e907cSAndroid Build Coastguard Worker }  // namespace implementation
391*4d7e907cSAndroid Build Coastguard Worker }  // namespace device
392*4d7e907cSAndroid Build Coastguard Worker }  // namespace camera
393*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
394*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
395*4d7e907cSAndroid Build Coastguard Worker 
396*4d7e907cSAndroid Build Coastguard Worker #endif  // HARDWARE_INTERFACES_CAMERA_DEVICE_DEFAULT_EXTERNALCAMERADEVICESESSION_H_
397