• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
18 #define ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
19 
20 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
21 #include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
22 #include <fmq/MessageQueue.h>
23 #include <hidl/MQDescriptor.h>
24 #include <hidl/Status.h>
25 #include <include/convert.h>
26 #include <deque>
27 #include <map>
28 #include <unordered_map>
29 #include "CameraMetadata.h"
30 #include "HandleImporter.h"
31 #include "hardware/camera3.h"
32 #include "hardware/camera_common.h"
33 #include "utils/Mutex.h"
34 
35 namespace android {
36 namespace hardware {
37 namespace camera {
38 namespace device {
39 namespace V3_2 {
40 namespace implementation {
41 
42 using ::android::hardware::camera::device::V3_2::CaptureRequest;
43 using ::android::hardware::camera::device::V3_2::HalStreamConfiguration;
44 using ::android::hardware::camera::device::V3_2::StreamConfiguration;
45 using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
46 using ::android::hardware::camera::common::V1_0::Status;
47 using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
48 using ::android::hardware::kSynchronizedReadWrite;
49 using ::android::hardware::MessageQueue;
50 using ::android::hardware::MQDescriptorSync;
51 using ::android::hardware::Return;
52 using ::android::hardware::Void;
53 using ::android::hardware::hidl_vec;
54 using ::android::hardware::hidl_string;
55 using ::android::sp;
56 using ::android::Mutex;
57 
58 struct Camera3Stream;
59 
60 /**
61  * Function pointer types with C calling convention to
62  * use for HAL callback functions.
63  */
64 extern "C" {
65     typedef void (callbacks_process_capture_result_t)(
66         const struct camera3_callback_ops *,
67         const camera3_capture_result_t *);
68 
69     typedef void (callbacks_notify_t)(
70         const struct camera3_callback_ops *,
71         const camera3_notify_msg_t *);
72 }
73 
74 struct CameraDeviceSession : public virtual RefBase, protected camera3_callback_ops  {
75 
76     CameraDeviceSession(camera3_device_t*,
77                         const camera_metadata_t* deviceInfo,
78                         const sp<ICameraDeviceCallback>&);
79     virtual ~CameraDeviceSession();
80     // Call by CameraDevice to dump active device states
81     void dumpState(const native_handle_t* fd);
82     // Caller must use this method to check if CameraDeviceSession ctor failed
isInitFailedCameraDeviceSession83     bool isInitFailed() { return mInitFail; }
84     // Used by CameraDevice to signal external camera disconnected
85     void disconnect();
86     bool isClosed();
87 
88     // Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
89     // dealing with minor version revs and simultaneous implementation and interface inheritance
getInterfaceCameraDeviceSession90     virtual sp<ICameraDeviceSession> getInterface() {
91         return new TrampolineSessionInterface_3_2(this);
92     }
93 
94 protected:
95 
96     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
97 
98     Return<void> constructDefaultRequestSettings(
99             RequestTemplate type,
100             ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
101     Return<void> configureStreams(
102             const StreamConfiguration& requestedConfiguration,
103             ICameraDeviceSession::configureStreams_cb _hidl_cb);
104     Return<void> getCaptureRequestMetadataQueue(
105         ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb);
106     Return<void> getCaptureResultMetadataQueue(
107         ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb);
108     Return<void> processCaptureRequest(
109             const hidl_vec<CaptureRequest>& requests,
110             const hidl_vec<BufferCache>& cachesToRemove,
111             ICameraDeviceSession::processCaptureRequest_cb _hidl_cb);
112     Return<Status> flush();
113     Return<void> close();
114 
115 protected:
116 
117     // protecting mClosed/mDisconnected/mInitFail
118     mutable Mutex mStateLock;
119     // device is closed either
120     //    - closed by user
121     //    - init failed
122     //    - camera disconnected
123     bool mClosed = false;
124 
125     // Set by CameraDevice (when external camera is disconnected)
126     bool mDisconnected = false;
127 
128     struct AETriggerCancelOverride {
129         bool applyAeLock;
130         uint8_t aeLock;
131         bool applyAePrecaptureTrigger;
132         uint8_t aePrecaptureTrigger;
133     };
134 
135     camera3_device_t* mDevice;
136     uint32_t mDeviceVersion;
137     bool mIsAELockAvailable;
138     bool mDerivePostRawSensKey;
139     uint32_t mNumPartialResults;
140     // Stream ID -> Camera3Stream cache
141     std::map<int, Camera3Stream> mStreamMap;
142 
143     mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers
144     // (streamID, frameNumber) -> inflight buffer cache
145     std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t>  mInflightBuffers;
146 
147     // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides
148     std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides;
149     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult;
150     std::map<uint32_t, bool> mInflightRawBoostPresent;
151     ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;
152 
153     // buffers currently ciculating between HAL and camera service
154     // key: bufferId sent via HIDL interface
155     // value: imported buffer_handle_t
156     // Buffer will be imported during process_capture_request and will be freed
157     // when the its stream is deleted or camera device session is closed
158     typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers;
159     // Stream ID -> circulating buffers map
160     std::map<int, CirculatingBuffers> mCirculatingBuffers;
161 
162     static HandleImporter sHandleImporter;
163 
164     bool mInitFail;
165     bool mFirstRequest = false;
166 
167     common::V1_0::helper::CameraMetadata mDeviceInfo;
168 
169     using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
170     std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue;
171     using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
172     std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
173 
174     class ResultBatcher {
175     public:
176         ResultBatcher(const sp<ICameraDeviceCallback>& callback);
177         void setNumPartialResults(uint32_t n);
178         void setBatchedStreams(const std::vector<int>& streamsToBatch);
179         void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q);
180 
181         void registerBatch(const hidl_vec<CaptureRequest>& requests);
182         void notify(NotifyMsg& msg);
183         void processCaptureResult(CaptureResult& result);
184 
185     private:
186         struct InflightBatch {
187             // Protect access to entire struct. Acquire this lock before read/write any data or
188             // calling any methods. processCaptureResult and notify will compete for this lock
189             // HIDL IPCs might be issued while the lock is held
190             Mutex mLock;
191 
192             bool allDelivered() const;
193 
194             uint32_t mFirstFrame;
195             uint32_t mLastFrame;
196             uint32_t mBatchSize;
197 
198             bool mShutterDelivered = false;
199             std::vector<NotifyMsg> mShutterMsgs;
200 
201             struct BufferBatch {
BufferBatchCameraDeviceSession::InflightBatch::BufferBatch202                 BufferBatch(uint32_t batchSize) {
203                     mBuffers.reserve(batchSize);
204                 }
205                 bool mDelivered = false;
206                 // This currently assumes every batched request will output to the batched stream
207                 // and since HAL must always send buffers in order, no frameNumber tracking is
208                 // needed
209                 std::vector<StreamBuffer> mBuffers;
210             };
211             // Stream ID -> VideoBatch
212             std::unordered_map<int, BufferBatch> mBatchBufs;
213 
214             struct MetadataBatch {
215                 //                   (frameNumber, metadata)
216                 std::vector<std::pair<uint32_t, CameraMetadata>> mMds;
217             };
218             // Partial result IDs that has been delivered to framework
219             uint32_t mNumPartialResults;
220             uint32_t mPartialResultProgress = 0;
221             // partialResult -> MetadataBatch
222             std::map<uint32_t, MetadataBatch> mResultMds;
223 
224             // Set to true when batch is removed from mInflightBatches
225             // processCaptureResult and notify must check this flag after acquiring mLock to make
226             // sure this batch isn't removed while waiting for mLock
227             bool mRemoved = false;
228         };
229 
230         static const int NOT_BATCHED = -1;
231 
232         // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched)
233         // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch
234         // It's possible that the InflightBatch is removed from mInflightBatches before the
235         // InflightBatch::mLock is acquired (most likely caused by an error notification), so
236         // caller must check InflightBatch::mRemoved flag after the lock is acquried.
237         // This method will hold ResultBatcher::mLock briefly
238         std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber);
239 
240         // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so
241         // This method will hold ResultBatcher::mLock briefly
242         void checkAndRemoveFirstBatch();
243 
244         // The following sendXXXX methods must be called while the InflightBatch::mLock is locked
245         // HIDL IPC methods will be called during these methods.
246         void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch);
247         // send buffers for all batched streams
248         void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch);
249         // send buffers for specified streams
250         void sendBatchBuffersLocked(
251                 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams);
252         void sendBatchMetadataLocked(
253                 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx);
254         // End of sendXXXX methods
255 
256         // helper methods
257         void freeReleaseFences(hidl_vec<CaptureResult>&);
258         void notifySingleMsg(NotifyMsg& msg);
259         void processOneCaptureResult(CaptureResult& result);
260         void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq);
261 
262         // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native
263         // handle
264         void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst);
265         void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst);
266 
267         // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch
268         // processCaptureRequest, processCaptureResult, notify will compete for this lock
269         // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error)
270         mutable Mutex mLock;
271         std::deque<std::shared_ptr<InflightBatch>> mInflightBatches;
272         uint32_t mNumPartialResults;
273         std::vector<int> mStreamsToBatch;
274         const sp<ICameraDeviceCallback> mCallback;
275         std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue;
276 
277         // Protect against invokeProcessCaptureResultCallback()
278         Mutex mProcessCaptureResultLock;
279 
280     } mResultBatcher;
281 
282     std::vector<int> mVideoStreamIds;
283 
284     bool initialize();
285 
286     Status initStatus() const;
287 
288     // Validate and import request's input buffer and acquire fence
289     Status importRequest(
290             const CaptureRequest& request,
291             hidl_vec<buffer_handle_t*>& allBufPtrs,
292             hidl_vec<int>& allFences);
293 
294     static void cleanupInflightFences(
295             hidl_vec<int>& allFences, size_t numFences);
296 
297     void cleanupBuffersLocked(int id);
298 
299     void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);
300 
301     android_dataspace mapToLegacyDataspace(
302             android_dataspace dataSpace) const;
303 
304     bool handleAePrecaptureCancelRequestLocked(
305             const camera3_capture_request_t &halRequest,
306             android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/,
307             AETriggerCancelOverride *override /*out*/);
308 
309     void overrideResultForPrecaptureCancelLocked(
310             const AETriggerCancelOverride &aeTriggerCancelOverride,
311             ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/);
312 
313     Status processOneCaptureRequest(const CaptureRequest& request);
314     /**
315      * Static callback forwarding methods from HAL to instance
316      */
317     static callbacks_process_capture_result_t sProcessCaptureResult;
318     static callbacks_notify_t sNotify;
319 
320 private:
321 
322     struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession {
TrampolineSessionInterface_3_2CameraDeviceSession::TrampolineSessionInterface_3_2323         TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) :
324                 mParent(parent) {}
325 
constructDefaultRequestSettingsCameraDeviceSession::TrampolineSessionInterface_3_2326         virtual Return<void> constructDefaultRequestSettings(
327                 V3_2::RequestTemplate type,
328                 V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
329             return mParent->constructDefaultRequestSettings(type, _hidl_cb);
330         }
331 
configureStreamsCameraDeviceSession::TrampolineSessionInterface_3_2332         virtual Return<void> configureStreams(
333                 const V3_2::StreamConfiguration& requestedConfiguration,
334                 V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override {
335             return mParent->configureStreams(requestedConfiguration, _hidl_cb);
336         }
337 
processCaptureRequestCameraDeviceSession::TrampolineSessionInterface_3_2338         virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests,
339                 const hidl_vec<V3_2::BufferCache>& cachesToRemove,
340                 V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override {
341             return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb);
342         }
343 
getCaptureRequestMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2344         virtual Return<void> getCaptureRequestMetadataQueue(
345                 V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override  {
346             return mParent->getCaptureRequestMetadataQueue(_hidl_cb);
347         }
348 
getCaptureResultMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2349         virtual Return<void> getCaptureResultMetadataQueue(
350                 V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override  {
351             return mParent->getCaptureResultMetadataQueue(_hidl_cb);
352         }
353 
flushCameraDeviceSession::TrampolineSessionInterface_3_2354         virtual Return<Status> flush() override {
355             return mParent->flush();
356         }
357 
closeCameraDeviceSession::TrampolineSessionInterface_3_2358         virtual Return<void> close() override {
359             return mParent->close();
360         }
361 
362     private:
363         sp<CameraDeviceSession> mParent;
364     };
365 };
366 
367 }  // namespace implementation
368 }  // namespace V3_2
369 }  // namespace device
370 }  // namespace camera
371 }  // namespace hardware
372 }  // namespace android
373 
374 #endif  // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H
375