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 // Helper methods 116 Status constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata); 117 118 bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration, 119 camera3_stream_configuration_t *stream_list /*out*/, 120 hidl_vec<camera3_stream_t*> *streams /*out*/); 121 void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration); 122 123 protected: 124 125 // protecting mClosed/mDisconnected/mInitFail 126 mutable Mutex mStateLock; 127 // device is closed either 128 // - closed by user 129 // - init failed 130 // - camera disconnected 131 bool mClosed = false; 132 133 // Set by CameraDevice (when external camera is disconnected) 134 bool mDisconnected = false; 135 136 struct AETriggerCancelOverride { 137 bool applyAeLock; 138 uint8_t aeLock; 139 bool applyAePrecaptureTrigger; 140 uint8_t aePrecaptureTrigger; 141 }; 142 143 camera3_device_t* mDevice; 144 const uint32_t mDeviceVersion; 145 bool mIsAELockAvailable; 146 bool mDerivePostRawSensKey; 147 uint32_t mNumPartialResults; 148 // Stream ID -> Camera3Stream cache 149 std::map<int, Camera3Stream> mStreamMap; 150 151 mutable Mutex mInflightLock; // protecting mInflightBuffers and mCirculatingBuffers 152 // (streamID, frameNumber) -> inflight buffer cache 153 std::map<std::pair<int, uint32_t>, camera3_stream_buffer_t> mInflightBuffers; 154 155 // (frameNumber, AETriggerOverride) -> inflight request AETriggerOverrides 156 std::map<uint32_t, AETriggerCancelOverride> mInflightAETriggerOverrides; 157 ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenResult; 158 std::map<uint32_t, bool> mInflightRawBoostPresent; 159 ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest; 160 161 // buffers currently ciculating between HAL and camera service 162 // key: bufferId sent via HIDL interface 163 // value: imported buffer_handle_t 164 // Buffer will be imported during process_capture_request and will be freed 165 // when the its stream is deleted or camera device session is closed 166 typedef std::unordered_map<uint64_t, buffer_handle_t> CirculatingBuffers; 167 // Stream ID -> circulating buffers map 168 std::map<int, CirculatingBuffers> mCirculatingBuffers; 169 170 static HandleImporter sHandleImporter; 171 172 bool mInitFail; 173 bool mFirstRequest = false; 174 175 common::V1_0::helper::CameraMetadata mDeviceInfo; 176 177 using RequestMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; 178 std::unique_ptr<RequestMetadataQueue> mRequestMetadataQueue; 179 using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>; 180 std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; 181 182 class ResultBatcher { 183 public: 184 ResultBatcher(const sp<ICameraDeviceCallback>& callback); 185 void setNumPartialResults(uint32_t n); 186 void setBatchedStreams(const std::vector<int>& streamsToBatch); 187 void setResultMetadataQueue(std::shared_ptr<ResultMetadataQueue> q); 188 189 void registerBatch(uint32_t frameNumber, uint32_t batchSize); 190 void notify(NotifyMsg& msg); 191 void processCaptureResult(CaptureResult& result); 192 193 protected: 194 struct InflightBatch { 195 // Protect access to entire struct. Acquire this lock before read/write any data or 196 // calling any methods. processCaptureResult and notify will compete for this lock 197 // HIDL IPCs might be issued while the lock is held 198 Mutex mLock; 199 200 bool allDelivered() const; 201 202 uint32_t mFirstFrame; 203 uint32_t mLastFrame; 204 uint32_t mBatchSize; 205 206 bool mShutterDelivered = false; 207 std::vector<NotifyMsg> mShutterMsgs; 208 209 struct BufferBatch { BufferBatchCameraDeviceSession::InflightBatch::BufferBatch210 BufferBatch(uint32_t batchSize) { 211 mBuffers.reserve(batchSize); 212 } 213 bool mDelivered = false; 214 // This currently assumes every batched request will output to the batched stream 215 // and since HAL must always send buffers in order, no frameNumber tracking is 216 // needed 217 std::vector<StreamBuffer> mBuffers; 218 }; 219 // Stream ID -> VideoBatch 220 std::unordered_map<int, BufferBatch> mBatchBufs; 221 222 struct MetadataBatch { 223 // (frameNumber, metadata) 224 std::vector<std::pair<uint32_t, CameraMetadata>> mMds; 225 }; 226 // Partial result IDs that has been delivered to framework 227 uint32_t mNumPartialResults; 228 uint32_t mPartialResultProgress = 0; 229 // partialResult -> MetadataBatch 230 std::map<uint32_t, MetadataBatch> mResultMds; 231 232 // Set to true when batch is removed from mInflightBatches 233 // processCaptureResult and notify must check this flag after acquiring mLock to make 234 // sure this batch isn't removed while waiting for mLock 235 bool mRemoved = false; 236 }; 237 238 239 // Get the batch index and pointer to InflightBatch (nullptrt if the frame is not batched) 240 // Caller must acquire the InflightBatch::mLock before accessing the InflightBatch 241 // It's possible that the InflightBatch is removed from mInflightBatches before the 242 // InflightBatch::mLock is acquired (most likely caused by an error notification), so 243 // caller must check InflightBatch::mRemoved flag after the lock is acquried. 244 // This method will hold ResultBatcher::mLock briefly 245 std::pair<int, std::shared_ptr<InflightBatch>> getBatch(uint32_t frameNumber); 246 247 static const int NOT_BATCHED = -1; 248 249 // move/push function avoids "hidl_handle& operator=(hidl_handle&)", which clones native 250 // handle 251 void moveStreamBuffer(StreamBuffer&& src, StreamBuffer& dst); 252 void pushStreamBuffer(StreamBuffer&& src, std::vector<StreamBuffer>& dst); 253 254 void sendBatchMetadataLocked( 255 std::shared_ptr<InflightBatch> batch, uint32_t lastPartialResultIdx); 256 257 // Check if the first batch in mInflightBatches is ready to be removed, and remove it if so 258 // This method will hold ResultBatcher::mLock briefly 259 void checkAndRemoveFirstBatch(); 260 261 // The following sendXXXX methods must be called while the InflightBatch::mLock is locked 262 // HIDL IPC methods will be called during these methods. 263 void sendBatchShutterCbsLocked(std::shared_ptr<InflightBatch> batch); 264 // send buffers for all batched streams 265 void sendBatchBuffersLocked(std::shared_ptr<InflightBatch> batch); 266 // send buffers for specified streams 267 void sendBatchBuffersLocked( 268 std::shared_ptr<InflightBatch> batch, const std::vector<int>& streams); 269 // End of sendXXXX methods 270 271 // helper methods 272 void freeReleaseFences(hidl_vec<CaptureResult>&); 273 void notifySingleMsg(NotifyMsg& msg); 274 void processOneCaptureResult(CaptureResult& result); 275 void invokeProcessCaptureResultCallback(hidl_vec<CaptureResult> &results, bool tryWriteFmq); 276 277 // Protect access to mInflightBatches, mNumPartialResults and mStreamsToBatch 278 // processCaptureRequest, processCaptureResult, notify will compete for this lock 279 // Do NOT issue HIDL IPCs while holding this lock (except when HAL reports error) 280 mutable Mutex mLock; 281 std::deque<std::shared_ptr<InflightBatch>> mInflightBatches; 282 uint32_t mNumPartialResults; 283 std::vector<int> mStreamsToBatch; 284 const sp<ICameraDeviceCallback> mCallback; 285 std::shared_ptr<ResultMetadataQueue> mResultMetadataQueue; 286 287 // Protect against invokeProcessCaptureResultCallback() 288 Mutex mProcessCaptureResultLock; 289 290 } mResultBatcher; 291 292 std::vector<int> mVideoStreamIds; 293 294 bool initialize(); 295 296 Status initStatus() const; 297 298 // Validate and import request's input buffer and acquire fence 299 Status importRequest( 300 const CaptureRequest& request, 301 hidl_vec<buffer_handle_t*>& allBufPtrs, 302 hidl_vec<int>& allFences); 303 304 static void cleanupInflightFences( 305 hidl_vec<int>& allFences, size_t numFences); 306 307 void cleanupBuffersLocked(int id); 308 309 void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove); 310 311 android_dataspace mapToLegacyDataspace( 312 android_dataspace dataSpace) const; 313 314 bool handleAePrecaptureCancelRequestLocked( 315 const camera3_capture_request_t &halRequest, 316 android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/, 317 AETriggerCancelOverride *override /*out*/); 318 319 void overrideResultForPrecaptureCancelLocked( 320 const AETriggerCancelOverride &aeTriggerCancelOverride, 321 ::android::hardware::camera::common::V1_0::helper::CameraMetadata *settings /*out*/); 322 323 Status processOneCaptureRequest(const CaptureRequest& request); 324 /** 325 * Static callback forwarding methods from HAL to instance 326 */ 327 static callbacks_process_capture_result_t sProcessCaptureResult; 328 static callbacks_notify_t sNotify; 329 330 status_t constructCaptureResult(CaptureResult& result, 331 const camera3_capture_result *hal_result); 332 333 // Static helper method to copy/shrink capture result metadata sent by HAL 334 // Temporarily allocated metadata copy will be hold in mds 335 static void sShrinkCaptureResult( 336 camera3_capture_result* dst, const camera3_capture_result* src, 337 std::vector<::android::hardware::camera::common::V1_0::helper::CameraMetadata>* mds, 338 std::vector<const camera_metadata_t*>* physCamMdArray, 339 bool handlePhysCam); 340 static bool sShouldShrink(const camera_metadata_t* md); 341 static camera_metadata_t* sCreateCompactCopy(const camera_metadata_t* src); 342 343 private: 344 345 struct TrampolineSessionInterface_3_2 : public ICameraDeviceSession { TrampolineSessionInterface_3_2CameraDeviceSession::TrampolineSessionInterface_3_2346 TrampolineSessionInterface_3_2(sp<CameraDeviceSession> parent) : 347 mParent(parent) {} 348 constructDefaultRequestSettingsCameraDeviceSession::TrampolineSessionInterface_3_2349 virtual Return<void> constructDefaultRequestSettings( 350 V3_2::RequestTemplate type, 351 V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override { 352 return mParent->constructDefaultRequestSettings(type, _hidl_cb); 353 } 354 configureStreamsCameraDeviceSession::TrampolineSessionInterface_3_2355 virtual Return<void> configureStreams( 356 const V3_2::StreamConfiguration& requestedConfiguration, 357 V3_2::ICameraDeviceSession::configureStreams_cb _hidl_cb) override { 358 return mParent->configureStreams(requestedConfiguration, _hidl_cb); 359 } 360 processCaptureRequestCameraDeviceSession::TrampolineSessionInterface_3_2361 virtual Return<void> processCaptureRequest(const hidl_vec<V3_2::CaptureRequest>& requests, 362 const hidl_vec<V3_2::BufferCache>& cachesToRemove, 363 V3_2::ICameraDeviceSession::processCaptureRequest_cb _hidl_cb) override { 364 return mParent->processCaptureRequest(requests, cachesToRemove, _hidl_cb); 365 } 366 getCaptureRequestMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2367 virtual Return<void> getCaptureRequestMetadataQueue( 368 V3_2::ICameraDeviceSession::getCaptureRequestMetadataQueue_cb _hidl_cb) override { 369 return mParent->getCaptureRequestMetadataQueue(_hidl_cb); 370 } 371 getCaptureResultMetadataQueueCameraDeviceSession::TrampolineSessionInterface_3_2372 virtual Return<void> getCaptureResultMetadataQueue( 373 V3_2::ICameraDeviceSession::getCaptureResultMetadataQueue_cb _hidl_cb) override { 374 return mParent->getCaptureResultMetadataQueue(_hidl_cb); 375 } 376 flushCameraDeviceSession::TrampolineSessionInterface_3_2377 virtual Return<Status> flush() override { 378 return mParent->flush(); 379 } 380 closeCameraDeviceSession::TrampolineSessionInterface_3_2381 virtual Return<void> close() override { 382 return mParent->close(); 383 } 384 385 private: 386 sp<CameraDeviceSession> mParent; 387 }; 388 }; 389 390 } // namespace implementation 391 } // namespace V3_2 392 } // namespace device 393 } // namespace camera 394 } // namespace hardware 395 } // namespace android 396 397 #endif // ANDROID_HARDWARE_CAMERA_DEVICE_V3_2_CAMERADEVICE3SESSION_H 398