| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2015 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 | #ifndef _ACAMERA_DEVICE_H | 
|  | 17 | #define _ACAMERA_DEVICE_H | 
|  | 18 |  | 
|  | 19 | #include <memory> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 20 | #include <map> | 
|  | 21 | #include <set> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 22 | #include <atomic> | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 23 | #include <utility> | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 24 | #include <vector> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 25 | #include <utils/StrongPointer.h> | 
|  | 26 | #include <utils/Mutex.h> | 
|  | 27 | #include <utils/String8.h> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 28 | #include <utils/List.h> | 
|  | 29 | #include <utils/Vector.h> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 30 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 31 | #include <android/hardware/camera2/BnCameraDeviceCallbacks.h> | 
|  | 32 | #include <android/hardware/camera2/ICameraDeviceUser.h> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 33 | #include <media/stagefright/foundation/ALooper.h> | 
|  | 34 | #include <media/stagefright/foundation/AHandler.h> | 
|  | 35 | #include <media/stagefright/foundation/AMessage.h> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 36 | #include <camera/CaptureResult.h> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 37 | #include <camera/camera2/OutputConfiguration.h> | 
| Shuzhen Wang | 24810e7 | 2019-03-18 10:55:01 -0700 | [diff] [blame] | 38 | #include <camera/camera2/SessionConfiguration.h> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 39 | #include <camera/camera2/CaptureRequest.h> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 40 |  | 
| Emilian Peev | 40ead60 | 2017-09-26 15:46:36 +0100 | [diff] [blame] | 41 | #include <camera/NdkCameraManager.h> | 
|  | 42 | #include <camera/NdkCameraCaptureSession.h> | 
| Jayant Chowdhary | a8bf1c6 | 2019-09-26 08:50:17 -0700 | [diff] [blame] | 43 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 44 | #include "ACameraMetadata.h" | 
|  | 45 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 46 | namespace android { | 
| Jayant Chowdhary | 6df2607 | 2018-11-06 23:55:12 -0800 | [diff] [blame] | 47 | namespace acam { | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 48 |  | 
| Yin-Chia Yeh | d21c46b | 2017-10-10 11:59:46 -0700 | [diff] [blame] | 49 | // Wrap ACameraCaptureFailure so it can be ref-counted | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 50 | struct CameraCaptureFailure : public RefBase, public ACameraCaptureFailure {}; | 
|  | 51 |  | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 52 | // Wrap PhysicalCaptureResultInfo so that it can be ref-counted | 
|  | 53 | struct ACameraPhysicalCaptureResultInfo: public RefBase { | 
|  | 54 | ACameraPhysicalCaptureResultInfo(const std::vector<PhysicalCaptureResultInfo>& info, | 
|  | 55 | int64_t frameNumber) : | 
|  | 56 | mPhysicalResultInfo(info), mFrameNumber(frameNumber) {} | 
|  | 57 |  | 
|  | 58 | std::vector<PhysicalCaptureResultInfo> mPhysicalResultInfo; | 
|  | 59 | int64_t mFrameNumber; | 
|  | 60 | }; | 
|  | 61 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 62 | class CameraDevice final : public RefBase { | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 63 | public: | 
|  | 64 | CameraDevice(const char* id, ACameraDevice_StateCallbacks* cb, | 
| Yin-Chia Yeh | dd045bf | 2018-08-20 12:39:19 -0700 | [diff] [blame] | 65 | sp<ACameraMetadata> chars, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 66 | ACameraDevice* wrapper); | 
|  | 67 | ~CameraDevice(); | 
|  | 68 |  | 
|  | 69 | inline const char* getId() const { return mCameraId.string(); } | 
|  | 70 |  | 
|  | 71 | camera_status_t createCaptureRequest( | 
|  | 72 | ACameraDevice_request_template templateId, | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 73 | const ACameraIdList* physicalIdList, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 74 | ACaptureRequest** request) const; | 
|  | 75 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 76 | camera_status_t createCaptureSession( | 
|  | 77 | const ACaptureSessionOutputContainer*       outputs, | 
| Emilian Peev | 5fbe0ba | 2017-10-20 15:45:45 +0100 | [diff] [blame] | 78 | const ACaptureRequest* sessionParameters, | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 79 | const ACameraCaptureSession_stateCallbacks* callbacks, | 
|  | 80 | /*out*/ACameraCaptureSession** session); | 
|  | 81 |  | 
| Shuzhen Wang | 24810e7 | 2019-03-18 10:55:01 -0700 | [diff] [blame] | 82 | camera_status_t isSessionConfigurationSupported( | 
|  | 83 | const ACaptureSessionOutputContainer* sessionOutputContainer) const; | 
|  | 84 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 85 | // Callbacks from camera service | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 86 | class ServiceCallback : public hardware::camera2::BnCameraDeviceCallbacks { | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 87 | public: | 
| Chih-Hung Hsieh | d19d994 | 2016-08-29 14:21:14 -0700 | [diff] [blame] | 88 | explicit ServiceCallback(CameraDevice* device) : mDevice(device) {} | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 89 | binder::Status onDeviceError(int32_t errorCode, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 90 | const CaptureResultExtras& resultExtras) override; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 91 | binder::Status onDeviceIdle() override; | 
|  | 92 | binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 93 | int64_t timestamp) override; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 94 | binder::Status onResultReceived(const CameraMetadata& metadata, | 
| Shuzhen Wang | 5c22c15 | 2017-12-31 17:12:25 -0800 | [diff] [blame] | 95 | const CaptureResultExtras& resultExtras, | 
|  | 96 | const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) override; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 97 | binder::Status onPrepared(int streamId) override; | 
| Shuzhen Wang | 9d06601 | 2016-09-30 11:30:20 -0700 | [diff] [blame] | 98 | binder::Status onRequestQueueEmpty() override; | 
| Yin-Chia Yeh | 8ca23dc | 2017-09-05 18:15:56 -0700 | [diff] [blame] | 99 | binder::Status onRepeatingRequestError(int64_t lastFrameNumber, | 
|  | 100 | int32_t stoppedSequenceId) override; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 101 | private: | 
|  | 102 | const wp<CameraDevice> mDevice; | 
|  | 103 | }; | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 104 | inline sp<hardware::camera2::ICameraDeviceCallbacks> getServiceCallback() { | 
|  | 105 | return mServiceCallback; | 
|  | 106 | }; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 107 |  | 
|  | 108 | // Camera device is only functional after remote being set | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 109 | void setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote); | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 110 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 111 | inline ACameraDevice* getWrapper() const { return mWrapper; }; | 
|  | 112 |  | 
| Jayant Chowdhary | a8488c9 | 2019-06-21 12:45:34 -0700 | [diff] [blame] | 113 | // Stop the looper thread and unregister the handler | 
| Jayant Chowdhary | a8bf1c6 | 2019-09-26 08:50:17 -0700 | [diff] [blame] | 114 | void stopLooperAndDisconnect(); | 
| Jayant Chowdhary | a8488c9 | 2019-06-21 12:45:34 -0700 | [diff] [blame] | 115 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 116 | private: | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 117 | friend ACameraCaptureSession; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 118 | camera_status_t checkCameraClosedOrErrorLocked() const; | 
|  | 119 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 120 | // device goes into fatal error state after this | 
|  | 121 | void setCameraDeviceErrorLocked(camera_status_t error); | 
|  | 122 |  | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 123 | void disconnectLocked(sp<ACameraCaptureSession>& session); // disconnect from camera service | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 124 |  | 
|  | 125 | camera_status_t stopRepeatingLocked(); | 
|  | 126 |  | 
| Yin-Chia Yeh | 309d05d | 2016-03-28 10:15:31 -0700 | [diff] [blame] | 127 | camera_status_t flushLocked(ACameraCaptureSession*); | 
|  | 128 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 129 | camera_status_t waitUntilIdleLocked(); | 
|  | 130 |  | 
|  | 131 |  | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 132 | template<class T> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 133 | camera_status_t captureLocked(sp<ACameraCaptureSession> session, | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 134 | /*optional*/T* cbs, | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 135 | int numRequests, ACaptureRequest** requests, | 
|  | 136 | /*optional*/int* captureSequenceId); | 
|  | 137 |  | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 138 | template<class T> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 139 | camera_status_t setRepeatingRequestsLocked(sp<ACameraCaptureSession> session, | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 140 | /*optional*/T* cbs, | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 141 | int numRequests, ACaptureRequest** requests, | 
|  | 142 | /*optional*/int* captureSequenceId); | 
|  | 143 |  | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 144 | template<class T> | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 145 | camera_status_t submitRequestsLocked( | 
|  | 146 | sp<ACameraCaptureSession> session, | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 147 | /*optional*/T* cbs, | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 148 | int numRequests, ACaptureRequest** requests, | 
|  | 149 | /*out*/int* captureSequenceId, | 
|  | 150 | bool isRepeating); | 
|  | 151 |  | 
| Yin-Chia Yeh | 4dfa4cc | 2017-11-10 20:00:09 -0800 | [diff] [blame] | 152 | camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output); | 
| Emilian Peev | 40ead60 | 2017-09-26 15:46:36 +0100 | [diff] [blame] | 153 |  | 
| Yin-Chia Yeh | 4dfa4cc | 2017-11-10 20:00:09 -0800 | [diff] [blame] | 154 | camera_status_t allocateCaptureRequest( | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 155 | const ACaptureRequest* request, sp<CaptureRequest>& outReq); | 
|  | 156 |  | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 157 | static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req, | 
|  | 158 | const std::string& deviceId); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 159 | static void freeACaptureRequest(ACaptureRequest*); | 
|  | 160 |  | 
|  | 161 | // only For session to hold device lock | 
|  | 162 | // Always grab device lock before grabbing session lock | 
|  | 163 | void lockDeviceForSessionOps() const { mDeviceLock.lock(); }; | 
|  | 164 | void unlockDevice() const { mDeviceLock.unlock(); }; | 
|  | 165 |  | 
|  | 166 | // For capture session to notify its end of life | 
|  | 167 | void notifySessionEndOfLifeLocked(ACameraCaptureSession* session); | 
|  | 168 |  | 
| Emilian Peev | 5fbe0ba | 2017-10-20 15:45:45 +0100 | [diff] [blame] | 169 | camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs, | 
|  | 170 | const ACaptureRequest* sessionParameters); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 171 |  | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 172 | // Input message will be posted and cleared after this returns | 
|  | 173 | void postSessionMsgAndCleanup(sp<AMessage>& msg); | 
|  | 174 |  | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 175 | static camera_status_t getIGBPfromAnw( | 
|  | 176 | ANativeWindow* anw, sp<IGraphicBufferProducer>& out); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 177 |  | 
|  | 178 | static camera_status_t getSurfaceFromANativeWindow( | 
|  | 179 | ANativeWindow* anw, sp<Surface>& out); | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 180 |  | 
|  | 181 | mutable Mutex mDeviceLock; | 
|  | 182 | const String8 mCameraId;                          // Camera ID | 
|  | 183 | const ACameraDevice_StateCallbacks mAppCallbacks; // Callback to app | 
| Yin-Chia Yeh | dd045bf | 2018-08-20 12:39:19 -0700 | [diff] [blame] | 184 | const sp<ACameraMetadata> mChars;                 // Camera characteristics | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 185 | const sp<ServiceCallback> mServiceCallback; | 
|  | 186 | ACameraDevice* mWrapper; | 
|  | 187 |  | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 188 | // stream id -> pair of (ANW* from application, OutputConfiguration used for camera service) | 
|  | 189 | std::map<int, std::pair<ANativeWindow*, OutputConfiguration>> mConfiguredOutputs; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 190 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 191 | // TODO: maybe a bool will suffice for synchronous implementation? | 
|  | 192 | std::atomic_bool mClosing; | 
|  | 193 | inline bool isClosed() { return mClosing; } | 
|  | 194 |  | 
| Yin-Chia Yeh | 309d05d | 2016-03-28 10:15:31 -0700 | [diff] [blame] | 195 | bool mInError = false; | 
|  | 196 | camera_status_t mError = ACAMERA_OK; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 197 | void onCaptureErrorLocked( | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 198 | int32_t errorCode, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 199 | const CaptureResultExtras& resultExtras); | 
|  | 200 |  | 
| Yin-Chia Yeh | 309d05d | 2016-03-28 10:15:31 -0700 | [diff] [blame] | 201 | bool mIdle = true; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 202 | // This will avoid a busy session being deleted before it's back to idle state | 
|  | 203 | sp<ACameraCaptureSession> mBusySession; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 204 |  | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 205 | sp<hardware::camera2::ICameraDeviceUser> mRemote; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 206 |  | 
|  | 207 | // Looper thread to handle callback to app | 
|  | 208 | sp<ALooper> mCbLooper; | 
|  | 209 | // definition of handler and message | 
|  | 210 | enum { | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 211 | // Device state callbacks | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 212 | kWhatOnDisconnected,   // onDisconnected | 
|  | 213 | kWhatOnError,          // onError | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 214 | // Session state callbacks | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 215 | kWhatSessionStateCb,   // onReady, onActive | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 216 | // Capture callbacks | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 217 | kWhatCaptureStart,     // onCaptureStarted | 
|  | 218 | kWhatCaptureResult,    // onCaptureProgressed, onCaptureCompleted | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 219 | kWhatLogicalCaptureResult, // onLogicalCameraCaptureCompleted | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 220 | kWhatCaptureFail,      // onCaptureFailed | 
| Emilian Peev | edec62d | 2019-03-19 17:59:24 -0700 | [diff] [blame] | 221 | kWhatLogicalCaptureFail, // onLogicalCameraCaptureFailed | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 222 | kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted | 
|  | 223 | kWhatCaptureSeqAbort,  // onCaptureSequenceAborted | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 224 | kWhatCaptureBufferLost,// onCaptureBufferLost | 
|  | 225 | // Internal cleanup | 
|  | 226 | kWhatCleanUpSessions   // Cleanup cached sp<ACameraCaptureSession> | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 227 | }; | 
|  | 228 | static const char* kContextKey; | 
|  | 229 | static const char* kDeviceKey; | 
|  | 230 | static const char* kErrorCodeKey; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 231 | static const char* kCallbackFpKey; | 
|  | 232 | static const char* kSessionSpKey; | 
|  | 233 | static const char* kCaptureRequestKey; | 
|  | 234 | static const char* kTimeStampKey; | 
|  | 235 | static const char* kCaptureResultKey; | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 236 | static const char* kPhysicalCaptureResultKey; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 237 | static const char* kCaptureFailureKey; | 
|  | 238 | static const char* kSequenceIdKey; | 
|  | 239 | static const char* kFrameNumberKey; | 
| Yin-Chia Yeh | e081c59 | 2016-03-29 18:26:44 -0700 | [diff] [blame] | 240 | static const char* kAnwKey; | 
| Emilian Peev | edec62d | 2019-03-19 17:59:24 -0700 | [diff] [blame] | 241 | static const char* kFailingPhysicalCameraId; | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 242 |  | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 243 | class CallbackHandler : public AHandler { | 
|  | 244 | public: | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 245 | explicit CallbackHandler(const char* id); | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 246 | void onMessageReceived(const sp<AMessage> &msg) override; | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 247 |  | 
|  | 248 | private: | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 249 | std::string mId; | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 250 | // This handler will cache all capture session sp until kWhatCleanUpSessions | 
|  | 251 | // is processed. This is used to guarantee the last session reference is always | 
|  | 252 | // being removed in callback thread without holding camera device lock | 
|  | 253 | Vector<sp<ACameraCaptureSession>> mCachedSessions; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 254 | }; | 
|  | 255 | sp<CallbackHandler> mHandler; | 
|  | 256 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 257 | /*********************************** | 
|  | 258 | * Capture session related members * | 
|  | 259 | ***********************************/ | 
|  | 260 | // The current active session | 
| Yin-Chia Yeh | 6e2353b | 2017-10-24 16:35:20 -0700 | [diff] [blame] | 261 | wp<ACameraCaptureSession> mCurrentSession; | 
| Yin-Chia Yeh | 309d05d | 2016-03-28 10:15:31 -0700 | [diff] [blame] | 262 | bool mFlushing = false; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 263 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 264 | int mNextSessionId = 0; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 265 | // TODO: might need another looper/handler to handle callbacks from service | 
|  | 266 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 267 | static const int REQUEST_ID_NONE = -1; | 
|  | 268 | int mRepeatingSequenceId = REQUEST_ID_NONE; | 
|  | 269 |  | 
| Shuzhen Wang | b7b4265 | 2020-05-07 11:59:02 -0700 | [diff] [blame] | 270 | // sequence id -> last frame number holder map | 
|  | 271 | struct RequestLastFrameNumberHolder { | 
|  | 272 | int64_t lastFrameNumber; | 
|  | 273 | // Whether the current sequence is completed (capture results are | 
|  | 274 | // generated). May be set to true, but | 
|  | 275 | // not removed from the map if not all inflight requests in the sequence | 
|  | 276 | // have been completed. | 
|  | 277 | bool isSequenceCompleted = false; | 
|  | 278 | // Whether all inflight requests in the sequence are completed | 
|  | 279 | // (capture results and buffers are generated). May be | 
|  | 280 | // set to true, but not removed from the map yet if the capture results | 
|  | 281 | // haven't been delivered to the app yet. | 
|  | 282 | bool isInflightCompleted = false; | 
|  | 283 | RequestLastFrameNumberHolder(int64_t lastFN) : | 
|  | 284 | lastFrameNumber(lastFN) {} | 
|  | 285 | }; | 
|  | 286 | std::map<int, RequestLastFrameNumberHolder> mSequenceLastFrameNumberMap; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 287 |  | 
|  | 288 | struct CallbackHolder { | 
|  | 289 | CallbackHolder(sp<ACameraCaptureSession>          session, | 
|  | 290 | const Vector<sp<CaptureRequest> >& requests, | 
|  | 291 | bool                               isRepeating, | 
|  | 292 | ACameraCaptureSession_captureCallbacks* cbs); | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 293 | CallbackHolder(sp<ACameraCaptureSession>          session, | 
|  | 294 | const Vector<sp<CaptureRequest> >& requests, | 
|  | 295 | bool                               isRepeating, | 
|  | 296 | ACameraCaptureSession_logicalCamera_captureCallbacks* lcbs); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 297 |  | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 298 | template <class T> | 
|  | 299 | void initCaptureCallbacks(T* cbs) { | 
|  | 300 | mContext = nullptr; | 
|  | 301 | mOnCaptureStarted = nullptr; | 
|  | 302 | mOnCaptureProgressed = nullptr; | 
|  | 303 | mOnCaptureCompleted = nullptr; | 
|  | 304 | mOnLogicalCameraCaptureCompleted = nullptr; | 
| Emilian Peev | edec62d | 2019-03-19 17:59:24 -0700 | [diff] [blame] | 305 | mOnLogicalCameraCaptureFailed = nullptr; | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 306 | mOnCaptureFailed = nullptr; | 
|  | 307 | mOnCaptureSequenceCompleted = nullptr; | 
|  | 308 | mOnCaptureSequenceAborted = nullptr; | 
|  | 309 | mOnCaptureBufferLost = nullptr; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 310 | if (cbs != nullptr) { | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 311 | mContext = cbs->context; | 
|  | 312 | mOnCaptureStarted = cbs->onCaptureStarted; | 
|  | 313 | mOnCaptureProgressed = cbs->onCaptureProgressed; | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 314 | mOnCaptureSequenceCompleted = cbs->onCaptureSequenceCompleted; | 
|  | 315 | mOnCaptureSequenceAborted = cbs->onCaptureSequenceAborted; | 
|  | 316 | mOnCaptureBufferLost = cbs->onCaptureBufferLost; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 317 | } | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 318 | } | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 319 | sp<ACameraCaptureSession>   mSession; | 
|  | 320 | Vector<sp<CaptureRequest> > mRequests; | 
|  | 321 | const bool                  mIsRepeating; | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 322 | const bool                  mIsLogicalCameraCallback; | 
|  | 323 |  | 
|  | 324 | void*                       mContext; | 
|  | 325 | ACameraCaptureSession_captureCallback_start mOnCaptureStarted; | 
|  | 326 | ACameraCaptureSession_captureCallback_result mOnCaptureProgressed; | 
|  | 327 | ACameraCaptureSession_captureCallback_result mOnCaptureCompleted; | 
|  | 328 | ACameraCaptureSession_logicalCamera_captureCallback_result mOnLogicalCameraCaptureCompleted; | 
| Emilian Peev | edec62d | 2019-03-19 17:59:24 -0700 | [diff] [blame] | 329 | ACameraCaptureSession_logicalCamera_captureCallback_failed mOnLogicalCameraCaptureFailed; | 
| Shuzhen Wang | 0ff9ae3 | 2018-12-05 18:06:12 -0800 | [diff] [blame] | 330 | ACameraCaptureSession_captureCallback_failed mOnCaptureFailed; | 
|  | 331 | ACameraCaptureSession_captureCallback_sequenceEnd mOnCaptureSequenceCompleted; | 
|  | 332 | ACameraCaptureSession_captureCallback_sequenceAbort mOnCaptureSequenceAborted; | 
|  | 333 | ACameraCaptureSession_captureCallback_bufferLost mOnCaptureBufferLost; | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 334 | }; | 
|  | 335 | // sequence id -> callbacks map | 
|  | 336 | std::map<int, CallbackHolder> mSequenceCallbackMap; | 
|  | 337 |  | 
|  | 338 | static const int64_t NO_FRAMES_CAPTURED = -1; | 
|  | 339 | class FrameNumberTracker { | 
|  | 340 | public: | 
|  | 341 | // TODO: Called in onResultReceived and onCaptureErrorLocked | 
|  | 342 | void updateTracker(int64_t frameNumber, bool isError); | 
|  | 343 | inline int64_t getCompletedFrameNumber() { return mCompletedFrameNumber; } | 
|  | 344 | private: | 
|  | 345 | void update(); | 
|  | 346 | void updateCompletedFrameNumber(int64_t frameNumber); | 
|  | 347 |  | 
|  | 348 | int64_t mCompletedFrameNumber = NO_FRAMES_CAPTURED; | 
|  | 349 | List<int64_t> mSkippedFrameNumbers; | 
|  | 350 | std::set<int64_t> mFutureErrorSet; | 
|  | 351 | }; | 
|  | 352 | FrameNumberTracker mFrameNumberTracker; | 
|  | 353 |  | 
|  | 354 | void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber); | 
|  | 355 | void checkAndFireSequenceCompleteLocked(); | 
| Shuzhen Wang | b7b4265 | 2020-05-07 11:59:02 -0700 | [diff] [blame] | 356 | void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber); | 
| Shuzhen Wang | acae264 | 2020-12-21 17:11:37 -0800 | [diff] [blame] | 357 | void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 358 |  | 
|  | 359 | // Misc variables | 
|  | 360 | int32_t mShadingMapSize[2];   // const after constructor | 
|  | 361 | int32_t mPartialResultCount;  // const after constructor | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 362 | std::vector<std::string> mPhysicalIds; // const after constructor | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 363 |  | 
|  | 364 | }; | 
|  | 365 |  | 
| Jayant Chowdhary | 6df2607 | 2018-11-06 23:55:12 -0800 | [diff] [blame] | 366 | } // namespace acam; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 367 | } // namespace android; | 
|  | 368 |  | 
|  | 369 | /** | 
|  | 370 | * ACameraDevice opaque struct definition | 
|  | 371 | * Leave outside of android namespace because it's NDK struct | 
|  | 372 | */ | 
|  | 373 | struct ACameraDevice { | 
|  | 374 | ACameraDevice(const char* id, ACameraDevice_StateCallbacks* cb, | 
| Yin-Chia Yeh | dd045bf | 2018-08-20 12:39:19 -0700 | [diff] [blame] | 375 | sp<ACameraMetadata> chars) : | 
| Jayant Chowdhary | 6df2607 | 2018-11-06 23:55:12 -0800 | [diff] [blame] | 376 | mDevice(new android::acam::CameraDevice(id, cb, chars, this)) {} | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 377 |  | 
| Jayant Chowdhary | a8488c9 | 2019-06-21 12:45:34 -0700 | [diff] [blame] | 378 | ~ACameraDevice(); | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 379 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 380 | /******************* | 
|  | 381 | * NDK public APIs * | 
|  | 382 | *******************/ | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 383 | inline const char* getId() const { return mDevice->getId(); } | 
|  | 384 |  | 
|  | 385 | camera_status_t createCaptureRequest( | 
|  | 386 | ACameraDevice_request_template templateId, | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 387 | const ACameraIdList* physicalCameraIdList, | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 388 | ACaptureRequest** request) const { | 
| Shuzhen Wang | 6c17e21 | 2019-02-19 14:51:47 -0800 | [diff] [blame] | 389 | return mDevice->createCaptureRequest(templateId, physicalCameraIdList, request); | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 390 | } | 
|  | 391 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 392 | camera_status_t createCaptureSession( | 
|  | 393 | const ACaptureSessionOutputContainer*       outputs, | 
| Emilian Peev | 5fbe0ba | 2017-10-20 15:45:45 +0100 | [diff] [blame] | 394 | const ACaptureRequest* sessionParameters, | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 395 | const ACameraCaptureSession_stateCallbacks* callbacks, | 
|  | 396 | /*out*/ACameraCaptureSession** session) { | 
| Emilian Peev | 5fbe0ba | 2017-10-20 15:45:45 +0100 | [diff] [blame] | 397 | return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session); | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 398 | } | 
|  | 399 |  | 
| Shuzhen Wang | 24810e7 | 2019-03-18 10:55:01 -0700 | [diff] [blame] | 400 | camera_status_t isSessionConfigurationSupported( | 
|  | 401 | const ACaptureSessionOutputContainer* sessionOutputContainer) const { | 
|  | 402 | return mDevice->isSessionConfigurationSupported(sessionOutputContainer); | 
|  | 403 | } | 
|  | 404 |  | 
| Yin-Chia Yeh | ead9146 | 2016-01-06 16:45:08 -0800 | [diff] [blame] | 405 | /*********************** | 
|  | 406 | * Device interal APIs * | 
|  | 407 | ***********************/ | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 408 | inline android::sp<android::hardware::camera2::ICameraDeviceCallbacks> getServiceCallback() { | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 409 | return mDevice->getServiceCallback(); | 
|  | 410 | }; | 
|  | 411 |  | 
|  | 412 | // Camera device is only functional after remote being set | 
| Eino-Ville Talvala | d56db1d | 2015-12-17 16:50:35 -0800 | [diff] [blame] | 413 | inline void setRemoteDevice(android::sp<android::hardware::camera2::ICameraDeviceUser> remote) { | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 414 | mDevice->setRemoteDevice(remote); | 
|  | 415 | } | 
|  | 416 |  | 
|  | 417 | private: | 
| Jayant Chowdhary | 6df2607 | 2018-11-06 23:55:12 -0800 | [diff] [blame] | 418 | android::sp<android::acam::CameraDevice> mDevice; | 
| Yin-Chia Yeh | 0dea57f | 2015-12-09 16:46:07 -0800 | [diff] [blame] | 419 | }; | 
|  | 420 |  | 
|  | 421 | #endif // _ACAMERA_DEVICE_H |